【前端实践系列之三】避开各种坑!小程序中按需引入Echarts5绘制图表。

1,149 阅读3分钟

这是我参与更文挑战的第3天,活动详情查看: 更文挑战 !

👽概论

小程序中绘制图表的需求已经越来越普遍,然而以往开发小程序echarts图表往往会有各种坑,包括但不限于:

  1. canvas图表层级过高,无法被Mask组件等覆盖;
  2. 不支持2d渲染、性能堪忧;··· ··· 以上问题虽说并非没有解决方案,但老是耗费精力处理这些问题着实让人头疼。近期Echarts已经发布了新的版本,多个项目中使用下来感觉明显提升不少。

以下介绍下UniApp项目中如何使用Echats5来绘制地图。

👽模块引入

👻导入工具文件

为方便起见,我们直接在uni插件市场搜索echarts-for-wx插件导入到项目中。(该插件是基于原生封装过的,对源码感兴趣的火把可以在github的echarts微信版官方项目echarts-for-weixin中找到ec-canvas文件夹了解)。

👻精简Echarts源文件

完整的echart.js文件足有接近1M大小,即使是在压缩后对于体积要求严格的小程序也是不可忍受的。如果不是确实要用到echart的所有功能,我们可以对其进行精简,步骤如下:

  1. 前往Echarts官方定制构建网站
  2. 选择需要的模块和功能并下载;
  3. 使用下载后的文件替换项目中的echarts.js文件。

👻引入echarts组件、准备容器

<template>
    <view class="card-body region">
      <view class="region-box">
       <!-- 容器上的canvasId务必唯一 -->
        <uni-ec-canvas
          id="mychart-map"
          ref="canvas"
          canvasId="mychart-map"
          :ec="ec"
        ></uni-ec-canvas>
      </view>
    </view>
  </view>
</template>

<script>
import uniEcCanvas from '../uni-ec-canvas/uni-ec-canvas.vue';
import * as echarts from '../uni-ec-canvas/echarts';

export default {
  name: 'MapCard',
  components: {
    'uni-ec-canvas': uniEcCanvas,
  },
  data() {
    return {
      ec: {
        lazyLoad: true,//此处定义图表懒加载
        //onInit: initChart//无需懒加载时是这样的
      },
    };
  },
}

👻引入地图背景

echarts制作地图的方式有两种:其一是利用百度地图之类的接口实现,其二是利用geoJson实现。geoJson的好处在于地图简洁干净,故我们选择第二种方式。


···
<script>
···

export default {

//引入地图文件(json文件一般都很大,直接放在小程序项目中不太合适,伙伴们千万不要学我🤣)
//地图资源可以在http://datav.aliyun.com/tools/atlas/获取
import mapdata from '@/assets/json/100000_full.json';

  ···
  data() {
    return {
      ec: {
        lazyLoad: true,
      },
      mapJson: mapdata,//地图geoJSON
      
      resMapData:[], //异步获取的数据
      cookedData: [], //处理后的可直接绑定在echarts上的数据
    };
  },
  mounted(){
    this.getData()
  },
  methods: {
    //绑定echarts的option
    setOption(chart) {
      const option = {
        tooltip: {
          show: true,
          trigger: 'item',
          showContent: true,
          alwaysShowContent: true,
          backgroundColor: 'rgba(255,255,255,.9)',
          borderColor: 'transparent',
          textStyle: {
            color: '#202020',
            fontSize: '18',
          },
        },
        series: [
          {
            layoutCenter: ['50%', '50%'],
            layoutSize: '100%',
            type: 'map',
            map: '统计地图',
            itemStyle: {
              borderWidth: '0.2',
              areaColor: 'rgb(244,244,244)',
            },
            label: {
              show: false,
            },
            select: {
              label: { show: false },
              itemStyle: {
                borderWidth: '0.2',
                areaColor: 'rgb(244,244,244)',
              },
            },
            emphasis: {
              label: { show: false },
              itemStyle: {
                borderWidth: '0.2',
                areaColor: 'rgb(244,244,244)',
              },
            },
            data: this.regionData,
          },
        ],
      };
      //挂载Option
      chart.setOption(option);
    },
    
    initChart(canvas, width, height, canvasDpr) {
      // 在这里初始化图表
      const chart = echarts.init(canvas, null, {
        width: width,
        height: height,
        devicePixelRatio: canvasDpr, 
      });

      // 注册地图
      echarts.registerMap('统计地图', this.mapJson, {});
      
      //调用绑定option的方法
      this.setOption(chart);
      
      // 返回chart实例
      return chart;
    },
    
    //获取异步数据
    getData(){
      uni.request({
        url: t'xxx,
        data: {
          v: 1,
        },
        method: 'GET',
        success:(res)=> {
          this.resMapData = res.data
          this.cookData();
        },
        fail(res) {
          console.log('文件获取失败', res);
        },
      });
    
    },

    //处理异步数据
    cookData() {
      //定义data模板
      const EMPTY = {
        name: null,
        value: null,
        loanCount: null,
        itemStyle: { areaColor: '#006cff' },
        label: {
          show: false,
        },
        select: {
          label: { show: false },
          itemStyle: {
            areaColor: '#006cff',
          },
        },
        emphasis: {
          label: { show: false },
          itemStyle: {
            areaColor: '#006cff',
          },
        },
      };
      //此处务必深拷贝
      this.regionData = JSON.parse(JSON.stringify(Array(this.resMapData.length).fill(EMPTY)));

      this.resMapData.forEach((item, index) => {
        this.regionData[index].name = item.region;
        this.regionData[index].value = item.loanAmount;
        this.regionData[index].loanCount = item.loanCount;
      });
      
      this.$refs.canvas.init(this.initChart);
    },

  },
}

最终效果如图:

f8faf836577572819dcc5a0eb9eccf1.jpg

👽结语

本文只介绍uniapp项目中地图实现,其余框架及图表类型大同小异。新版echarts真心不错,大家快冲!!🙊🙊🙊