小程序f2图表绘制 antv wx-f2

422 阅读3分钟

antv f2的api地址: f2.antv.antgroup.com/api/f2

在原生小程序里使用f2绘制图表可太恶心了,一大堆问题,有时候就像玄学一样,同样的写法同样的数据绘制的图表还会有差异,但代码是最客观的,不存在玄学,只是我太菜而已,所以记录一下最近开发的几种f2图表

曲线图

<f2 id="complexChartNew" class="chart-view__f2" onInit="{{onInitOCCLineChart}}"></f2>


//初始化配置
Page({
  /**
   * 页面的初始数据
   */
  data: {
    // 经营趋势曲线图
    complexChart: {
      //图表数据
      data: [],
      // 是否已渲染
      rendered: false,
      // 渲染图表 interval 标识
      updateInterval: -1
    },
    // 经营趋势曲线图配置
    onInitOCCLineChart(F2, config) {
      const data = [];  //图表数据
      config.appendPadding = [20, 14, 25, 11]; //图表的内边距
      const chart = new F2.Chart(config); 
      // 配置数据和坐标轴
      chart.source([], {
        date: { //日期 X轴
          type: 'cat', //x轴数据格式(identity`、`linear`、`cat`、`timeCat`)
          range: [0, 1], //数据范围
          tickCount: 6 //x轴个数
        },
        value: { //数据 y轴
          tickCount: 8,
        },
      });   
      // 配置 tooltip (示数据气泡提示)
       chart.tooltip({
          showItemMarker: true, 
          showTitle: true,
          layout: 'vertical', //设置垂直显示
          offsetY: 50, //设置居中展示
          onShow(obj) { //自定义tooltip数据展示格式
              const items = obj.items;
              let flag = items[0].name === '出租率' ? '%' : ''
              items[0].name = items[0].name || '';
              items[0].value = items[0].value + flag;
              if(items[1]) {
                  items[1].name = items[1].name;
                  items[1].value =items[1].value + (items[1].name === '平均房价' ? '' : flag);
              }
        },
      })
          // 配置绘制图形
          chart.line().position('date*value').color('#5B8FF9').shape('smooth');
          return chart;
    },
  }
})


   /**
   * 渲染曲线图
   * @param {Arrary} data 
   */
  renderCharts(data) {
    let complexChart = this.data.complexChart;
    // 是否已渲染
    const rendered = complexChart.rendered;
    complexChart.rendered = true;
    complexChart.data = data;
    clearInterval(complexChart.updateInterval);
    complexChart.updateInterval = -1;
    this.setData({ complexChart });
    // 获取 chart 实例
    const chartIns = this.selectComponent('#complexChartNew');
    chartIns?.chart?.guide()?.clear();
    // 初次加载可能存在 chartIns.chart 实例不存在问题,循环判断在正确获取到实例后渲染
    let updateInterval = setInterval(() => {
      if (chartIns && chartIns.chart) {
        chartIns.chart.changeData(data);
        if(this.data.realTime) {
          //实时数据有预测部分
          const futureData = data.filter(item => item.predict);
          futureData.forEach(obj => {
            // 预测数据点添加point和label
            chartIns.chart.guide().point({ // 预测 数据 原点
              position: [ obj.date, obj.value ],
              style: {
                stroke: '#1890ff',
                lineWidth: 1,
                fill: '#fff',
                r: ['去年同期', '上周此时'].includes(obj.name) ? 0 : 2
              }
            })
          })

        } else {
          chartIns.chart.guide().clear();
        }
        chartIns.chart.legend({
          position: 'bottom',
          align: 'center',
        });
        if (rendered) {
          chartIns.chart.repaint();
        } else {
          chartIns.chart.render();
        }
        clearInterval(updateInterval);
        complexChart.updateInterval = -1;
      }
    }, 300);
    complexChart.updateInterval = updateInterval;
  },

结果展示:

企业微信截图_17026242664448.png

环形图

<f2 id="guestChart" class="chart-view__f2" onInit="{{onInitGuestChartLineChart}}" />
page({
    data:{
       guestChart: {
          // 分类数据
          data: [],
          // 是否已渲染
          rendered: false,
          // 渲染图表 interval 标识
          updateInterval: -1
        },
        onInitGuestChartLineChart(F2, config){
          const data = [];
          config.appendPadding = [12, 11, 8, 11];
          const chart = new F2.Chart(config);
          chart.source(data, { //设置数据格式
            value: {
              formatter: function formatter(val) {
                return val  + '%';
              }
            }
          }); 
          chart.coord('polar', { //设置为极坐标polar(分为直角坐标系和极坐标两种类型)
            transposed: true, //极坐标转置
            radius: 1.2, //实心圆的半径大小设置
            innerRadius: 0.518  // 用于空心部分的半径设置
          });
          chart.axis(false); // 关闭XY轴等线条
          // 配置 tooltip
          chart.tooltip({
            onShow(obj) {
              const items = obj.items;
              items[0].name = items[0].name.split(' ')[0];
              items[0].value = items[0].value;
            },
          });
          // 配置 legend
          chart.legend({
            position: 'right',
            align: 'center',
            // 图例项宽度根据自身的宽度计算
            itemWidth: null,
            // 图例项水平方向上的间距
            itemGap: 25,
            // marker 和文本之间的间距
            wordSpace: 10,
            nameStyle: {
              fill: '#797B82',
              fontSize: 12,
              fontWeight: 500
            },
          })

          // 配置绘制图形
          chart.interval().position('a*value').color('name', ['#945FB9','#F6BD16','#FF833C','#5B8FF9']).adjust('stack').style({
            lineWidth: 1,
            stroke: '#fff',
            lineJoin: 'round',
            lineCap: 'round'
          }).animate({
            appear: {
              duration: 1200,
              easing: 'bounceOut'
            }
          });
           return chart;
        },

    
    }
})


 /**
   * 渲染环形图
   * @param { Object } data 数据源
   */
  renderRealGuestChart:function(){
    let datas = this.data.realGuest.map(item => {
      return {
        value: item.room_rate,
        name:item.name+' '+item.room_rate+' %',
        a:'1',
      }
    })
    let guestChart = this.data.guestChart;
    // 是否已渲染
    const rendered = guestChart.rendered;
    guestChart.rendered = true;
    guestChart.data = datas;
    clearInterval(guestChart.updateInterval);
    guestChart.updateInterval = -1;
    this.setData({ guestChart });
    // 获取 chart 实例
    const chartIns = this.selectComponent('#guestChart');
    // 初次加载可能存在 chartIns.chart 实例不存在问题,循环判断在正确获取到实例后渲染
    let updateInterval = setInterval(() => {
      if (chartIns && chartIns.chart) {

        chartIns.chart.changeData(datas);
        if (rendered) {
          chartIns.chart.repaint();
        } else {
          chartIns.chart.render();
        }
        clearInterval(updateInterval);
        guestChart.updateInterval = -1;
      }
    }, 500);
    guestChart.updateInterval = updateInterval;
  },

结果展示:

企业微信截图_17026244398226.png

条形图

<f2 id="occChart" class="chart-view__f2" onInit="{{onInitOccChartLineChart}}" />
page({
    data:{
       // 出租率分析
       occChart: {
          // 分类数据
          data: [],
          // 是否已渲染
          rendered: false,
          // 渲染图表 interval 标识
          updateInterval: -1
        },
        onInitOccChartLineChart(F2, config){
          const data = [];
          config.appendPadding = [11, 11, 8, 11];
          const chart = new F2.Chart(config);
          chart.source(data, {
            room_night: {
              tickCount: 5
            }
          });
          chart.legend(false);
          chart.tooltip({
            // 不展示记录前的 marker
            showItemMarker: true,
            showTitle: true,
            layout: 'vertical',
            onShow(obj) {
              const items = obj.items;
              items[0].name = items[0].title;
              items[0].value = items[0].value
            }
          })
          chart.coord({
            transposed: true
          });

          chart.interval().position('rName*rNight');
          chart.render();
          return chart;
        },
    }
})


/**
   * 渲染“出租率分析”条形图
   */
  renderRealOccChart:function(){
    const realNs = this.data.realNights
    const len = realNs.length
    let datas = realNs?.map((item, i) => {
        item.rName = realNs[len - i - 1]?.name
        item.rNight = realNs[len - i - 1]?.room_night
        return item
    });
    let occChart = this.data.occChart;
    // 是否已渲染
    const rendered = occChart.rendered;
    occChart.rendered = true;
    occChart.data = datas;
    clearInterval(occChart.updateInterval);
    occChart.updateInterval = -1;
    this.setData({ occChart });
    // 获取 chart 实例
    const chartIns = this.selectComponent('#occChart');
    // 初次加载可能存在 chartIns.chart 实例不存在问题,循环判断在正确获取到实例后渲染
    let updateInterval = setInterval(() => {
      if (chartIns && chartIns.chart) {
        chartIns.chart.changeData(datas);
        if (rendered) {
          chartIns.chart.repaint();
        } else {
          chartIns.chart.render();
        }
        clearInterval(updateInterval);
        occChart.updateInterval = -1;
      }
    }, 500);
    occChart.updateInterval = updateInterval;

  },

结果展示:

企业微信截图_17026244775299.png