微信小程序接入图表库 ECharts

4,044 阅读3分钟

背景

做了一个记账本的小程序,需要用到图表,调研了微信小程序上的一些图表库。说一下个人感觉吧。

ECharts

官方描述的挺全面,但是ECharts这个东西一直是一个大的东西,刚开始没敢尝试,使用的Antv。
然后啊就是各种的坑,找不到demo代码、文档少、示例版本不对,想要的效果搞不出来。
兜兜转转,又回到了ECharts,成熟的东西就是好用,各种效果也能满足。

weixin-app.jpg

Antv

阿里出的东西,体验了一下Demo效果蛮好的,驴粪蛋子表面光。

wx-chart

好像好久没有人维护了

ucharts

体验小程序打开就是广告,有点讨厌了

接入Demo

一、引入组件

二、示例Demo

1、效果截图

微信图片_20211018190816.jpg

2、json文件,引入组件
{
  "usingComponents": {
    "ec-canvas": "../../ec-canvas/ec-canvas"
  }
}
3、wxml文件 使用组件
<view class="charts-view">
  <view class="charts-tittle-line">
    <view class="charts-tittle-point"></view>
    <text class="charts-tittle-text">每日支出走势</text>
  </view>
  <!-- 折线图 -->
  <view class="charts-daily-trend">
    <ec-canvas id="mychart-daily-trend" canvas-id="mychart-daily-trend-canvas" ec="{{ ecDailyTrend }}"></ec-canvas>
  </view>

  <view class="center-line" />

  <view class="charts-tittle-line">
    <view class="charts-tittle-point"></view>
    <text class="charts-tittle-text">支出占比</text>
  </view>
  <!-- 饼图 -->
  <view class="charts-daily-trend">
    <ec-canvas id="mychart-percentage" canvas-id="mychart-percentage-canvas" ec="{{ ecPercentage }}"></ec-canvas>
  </view>

  <view class="center-line" />

  <view class="charts-tittle-line">
    <view class="charts-tittle-point"></view>
    <text class="charts-tittle-text">月度对比</text>
  </view>
  <!-- 柱状图 -->
  <view class="charts-daily-trend">
    <ec-canvas id="mychart-monthly-comparison" canvas-id="mychart-monthly-comparison-canvas"
      ec="{{ ecMonthlyComparison }}"></ec-canvas>
  </view>
</view>
4、wxss文件 设置样式
.charts-view {
  width: 750rpx;
  background: #FFFFFF;
  padding: 40rpx 30rpx 40rpx 30rpx;
  margin-top: 20rpx;
}

.charts-tittle-line {
  flex-direction: row;
  display: flex;
  align-items: center;
}

.charts-tittle-point {
  width: 4rpx;
  height: 26rpx;
  background: #44A3FC;
  border-radius: 2px;
}

.charts-tittle-text {
  font-size: 26rpx;
  font-weight: 400;
  color: #333333;
  margin-left: 10rpx;  
}

.daily-trend-chart {
  width: 100%;
  height: 500rpx;
  background: chartreuse;
}

.detail-list-layout {
  display: flex;
  flex-direction: column;
}

.detail-list-item-layout {
  display: flex;
  flex-direction: column;
}

.detail-list-item-tittle {
  width: 750rpx;
  height: 50rpx;
  background: rgba(246, 246, 246, 1);
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}

.detail-list-item-tittle-text {
  font-size: 24rpx;
  font-weight: 500;
  padding-left: 30rpx;
  padding-right: 30rpx;
  color: rgba(102, 102, 102, 1);
}

.detail-list-item-tittle-left {
  flex: 1;
}

.detail-list-item {
  height: 110rpx;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  border-width: 0rpx 0rpx 1rpx 0rpx;
  border-color: #e1e1e1;
  border-style: solid;
  padding-left: 30rpx;
  padding-right: 30rpx;
}

.detail-list-item-img {
  width: 70rpx;
  height: 70rpx;
}

.detail-list-item-text {
  flex: 1;
  font-size: 30rpx;
  font-weight: 500;
  margin-left: 20rpx;
  color: rgba(51, 51, 51, 1);
}

.detail-list-item-right-text {
  font-size: 30rpx;
  font-weight: 500;
  color: rgba(51, 51, 51, 1);
}

.detail-list-item-select-icon-bg {
  width: 70rpx;
  height: 70rpx;
  background: #fff2e3;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.detail-list-item-select-icon-text {
  color: #f78f17;
  font-size: 30rpx;
  font-style: normal;
  font-weight: 900;
}

.detail-list-item-arrow {
  width: 16rpx;
  height: 26rpx;
  margin-left: 10rpx;
}

.charts-daily-trend {
  width: 690rpx;
  height: 500rpx;
}

.center-line {
  width: 690rpx;
  height: 1rpx;
  background: #E1E1E1;
  margin-top: 50rpx;
  margin-bottom: 50rpx;
}

5、js文件 实例化图表

import * as echarts from '../../ec-canvas/echarts';
let that;

/**
 * 折线图
 */
function setDailyTrendChartOption(chart, chartData, seriesName, seriesItemStyleColor, seriesAreaStyleStartColor) {
  const option = {
    tooltip: {
      trigger: 'axis',
      formatter: params => {
        // var res = params[0].name;
        var res = '';
        for (var i = 0; i < params.length; i++) {
          res +=
            params[i].marker +
            params[i].name +
            " " +
            params[i].seriesName +
            ":" +
            params[i].data;
        }
        return res;
      }
    },

    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },

    dataZoom: [ //给x轴设置滚动条  
      {
        type: 'inside',
        show: true,
        xAxisIndex: [0],
        start: chartData.xAxis.length / 30 * 50,
        end: 100
      },
    ],

    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: chartData.xAxis
    },
    yAxis: {
      type: 'value',
      axisTick: {
        inside: true
      },
      splitLine: {
        show: false
      },
      axisLabel: {
        inside: true,
        formatter: '{value}\n'
      }
    },

    series: [{
      name: seriesName,
      type: 'line',
      smooth: true,
      symbol: 'circle',
      sampling: 'average',
      itemStyle: {
        color: seriesItemStyleColor
      },
      areaStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
          offset: 0,
          color: seriesAreaStyleStartColor
        }, {
          offset: 1,
          color: 'rgba(255, 255, 255, 1)'
        }])
      },
      data: chartData.series
    }]
  };
  chart.setOption(option);
}

/**
 * 饼图
 */
function setPercentageOption(chart, chartData, colorList) {
  const option = {
    color: colorList,
    series: [{
      type: 'pie',
      radius: ['40%', '70%'],
      itemStyle: {
        borderRadius: 2,
        borderColor: '#fff',
        borderWidth: 1
      },

      label: {
        formatter: '{name|{b}}\n{value|{c}%}',
        minMargin: 5,
        lineHeight: 15,
        rich: {
          time: {
            fontSize: 9,
            color: '#999'
          }
        }
      },

      data: chartData,
    }]
  };

  chart.setOption(option);
}

/**
 * 柱状图
 */
function setMonthlyComparisonOption(chart, chartData) {
  const option = {
    color: 'rgba(68, 163, 252, 0.5)',
    xAxis: {
      type: 'category',
      data: ['一月', '二月', '三月', '四月', '五月', '六月', '七月']
    },
    yAxis: {
      type: 'value',
      splitLine: {
        show: false
      },
      axisLabel: {
        show: false
      }
    },
    label: {
      show: true,
      position: 'top',
      color: 'rgba(68, 163, 252, 0.85)',
      formatter: '¥ {c}',
    },
    series: [{
      data: [120, {
        value: 200,
        itemStyle: {
          color: 'rgba(68, 163, 252, 0.85)'
        }
      }, 150, 80, 70, 110, 130],
      type: 'bar',
    }]
  };

  chart.setOption(option);
}

Page({

  /**
   * 页面的初始数据
   */
  data: {
    ecDailyTrend: {
      lazyLoad: true
    },

    ecPercentage: {
      lazyLoad: true
    },

    ecMonthlyComparison: {
      lazyLoad: true
    }
  },

  onLoad: function () {
    that = this

    // 获取组件
    this.ecDailyTrendComponent = this.selectComponent('#mychart-daily-trend');
    this.ecPercentageComponent = this.selectComponent('#mychart-percentage');
    this.ecMonthlyComparisonComponent = this.selectComponent('#mychart-monthly-comparison');
    
    // 关于动态加载,可以参考这里
    setTimeout(function () {
      that.initDailyTrend()
      that.initPercentage()
      that.initMonthlyComparison()
    }, 1000)
  },

  initDailyTrend: function () {
    this.ecDailyTrendComponent.init((canvas, width, height, dpr) => {
      const chart = echarts.init(canvas, null, {
        width: width,
        height: height,
        devicePixelRatio: dpr
      });

      let chartData = {
        xAxis: ['1st', '2nd', '3rd', '4th', '5th', '6th', '7th', '8th', '9th', '10th', '11st', '12nd', '13rd', '14th', '15th', '16th', '17th', '18th', '19th', '20th', '11st', '21nd', '22rd', '23th', '24th', '25th', '26th', '27th', '28th', '29th', '30th', '31th'],
        series: [120, 132, 101, 134, 90, 230, 210, 120, 132, 101, 120, 132, 101, 134, 90, 230, 210, 120, 132, 101, 120, 132, 101, 134, 90, 230, 210, 120, 132, 101, 101, 90]
      }

      setDailyTrendChartOption(chart, chartData, '支出', 'rgba(68, 163, 252, 1)', 'rgba(68, 163, 252, 0.5)');

      this.chart = chart;
      return chart;
    });
  },

  initPercentage: function () {
    this.ecPercentageComponent.init((canvas, width, height, dpr) => {
      const chart = echarts.init(canvas, null, {
        width: width,
        height: height,
        devicePixelRatio: dpr
      });

      let chartData = [
        { value: 1048, name: '搜索引擎' },
        { value: 735, name: '直接访问' },
        { value: 580, name: '邮件营销' },
        { value: 484, name: '联盟广告' },
        { value: 300, name: '视频广告' }
      ]
      let colorList = ["#44A3FC", "#7BBFFF", "#A6D4FF", "#CCE6FF", "#FFE4C5", "#FFBB6D", "#FFAF53", "#F78F17"]

      setPercentageOption(chart, chartData, colorList);

      this.chart = chart;
      return chart;
    });
  },

  initMonthlyComparison: function () {
    this.ecMonthlyComparisonComponent.init((canvas, width, height, dpr) => {
      const chart = echarts.init(canvas, null, {
        width: width,
        height: height,
        devicePixelRatio: dpr
      });

      setMonthlyComparisonOption(chart);

      this.chart = chart;
      return chart;
    });
  }
})

参考

小程序文档

示例样式(可以自己调试样式)