微信小程序中封装Echarts中国地图组件,并实现动态更新地图数据

一、效果图

  主要在微信小程序中模仿头条的国内疫情数据详情界面,点击页面按钮可以动态切换“现有确诊”和“累计确诊”数据,先上效果图。

现有确诊
累计确诊

二、微信中引入Echarts

  为了兼容小程序 Canvas,echarts官方提供了一个小程序的组件,用这种方式可以方便地使用 ECharts。
(1)、下载 GitHub 上的 ecomfe/echarts-for-weixin 项目。
(2)、ec-canvas 是官方提供的组件,其他文件是如何使用该组件的示例。
(3)、ec-canvas 目录下有一个 echarts.js,默认会在每次 echarts-for-weixin 项目发版的时候替换成最新版的 ECharts。如有必要,可以自行从 ECharts 项目中下载最新发布版,或者从官网自定义构建以减小文件大小。

官网地址

https://echarts.apache.org/

github地址

https://github.com/ecomfe/echarts-for-weixin

小程序demo地址

https://github.com/ecomfe/echarts-examples

三、具体实现步骤

1、新建一个微信小程序项目,详情见微信公众平台官方文档。然后将ecomfe/echarts-for-weixin中的ec-canvas文件夹拷贝到我们建立的小程序项目中,如图所示:

ec-canvas
自己项目结构

2、建立放组件的文件夹components,然后里面建立chinamap组件,并在组件中加入echarts提供的中国地图数据china.js,如图所示:

3、获取地图数据china.js
  通过官方提供的地图demo中mapData.js地图数据,发现地图数据js其实为直接exports出来一串json字符串,经分析,该段json字符串即为echarts提供的各个地区的echarts中地图的json数据,如图所示为我改造得来的china.js:


tips(网上获取的地图数据往往不是最新的,下面是我觉得比较方便的一个方法):
  建立一个vue项目,然后npm i echarts安装echarts的依赖,在依赖node_modules文件夹中找echarts文件,其中的map中就有全国各地的地图数据json,如图所示:

  建立china.js,里面直module.exports导出中国地图的json的字符串即可。

module.exports = {地图数据json字符串}

4、小程序页面json、wxml和wxss中的代码
chinmap.json
  因建立的是组件,需设置component为true。

{
  "component": true, //因建立的是组件,需设置component为true
  "usingComponents": {
    "ec-canvas": "../../ec-canvas/ec-canvas"
  }
}

chinmap.wxml
  需设置外层的view包裹<ec-canvas>组件,同时设置<ec-canvas>组件的id,其中 ec 是一个我们在 chinmap.js 中定义的对象,它使得图表能够在页面加载后被初始化并设置。

<view class="container-map">
  <ec-canvas id="mychart-dom-area" canvas-id="mychart-area" ec="{{ ec }}"></ec-canvas>
</view>

chinmap.wxss
  ec-cavas的宽高需要设置,看自己的要求可以适当修改样式。

.container-map {
  height: 700rpx;
  width: 100%;
  margin-top: 40rpx;
} 
ec-canvas {
  width: 100%;
  height: 100%;
}

5、小程序chinamap.js
引入echarts和地图数据

import * as echarts from '../../ec-canvas/echarts';
import geoJson from './china.js';

data和properties设置

Component({
  data: {
    ec: {
      lazyLoad: true  //设置图表懒加载
    }
  },

  properties: {
    dataList : {       // 地图中展示的数据
      type: Array,
      value: []
    },
    dataPoint: {    // 为地图某个位置标点,本例中来实现,地图中某个省份清零后,为其省份插上小红旗
      type: Array,
      value: []
    }
  },
)}

methods中设置

Component({
  methods: {
    // 设置图表所需的option
    setOption(chart, dataList, dataPoint) {
 
      const option = {
        tooltip : {
          trigger: 'item',
          formatter: function(e, t, n) {
            return '地区:' + e.data.name + '\n确诊:' + e.data.value
          },
          textStyle:{
            align:'left'
          }
        },
    
        title: {
          text: '中国疫情地图',
          subtext: '*数据为假数据,仅供学习演示使用',
          textStyle: {
            color: '#000',
            fontSize: 15
        },
          x: 'center'
        },
    
        visualMap: {
          // type: 'piecewise',
          min: 0,
          itemWidth: 8,
          itemHeight: 8,
          textStyle: {
            fontSize: 8
          },
          textGap: 5,
          left: 10,
          bottom: 5,
          showLabel: !0,
          text: ['高', '低'],
          pieces: [{
            gt: 100,
            label: '> 100 人',
            color: '#7f1100',
            symbol: 'roundRect'
          }, {
            gte: 10,
            lte: 100,
            label: '10 - 100 人',
            color: '#ff5428'
          }, {
            gte: 1,
            lt: 10,
            label: '1 - 9 人',
            color: '#ff8c71'
          }, {
            value: 0,
            label: '0 人',
            color: 'rgb(248, 248, 248)',
            symbol: 'roundRect'
          }
        ],
          show: !0
        },
       
        series: [{
          type: 'map',
          map: 'china',
          label: {
            normal: {
              show: true,
              fontSize: 8
            },
            emphasis: {
              textStyle: {
                color: '#000'
              }
            }
          },
          itemStyle: {
            normal: {
              borderColor: '#000',
              areaColor: '#fff',
              borderWidth: .2
            },
            emphasis: {
              areaColor: '#fff',
              borderWidth: 0.2
            }
          },
          animation: false,
          markPoint: { //标记点
            symbol: 'path://M852.8 365c-71.6 11.8-188.4 15-266-132.2-83.2-158.2-217.6-163-296.2-148.6-38.2 7-66.8 39-66.8 70l0 393.2c22.6 8.6 46.8-0.4 53-1.6 1.6-0.4 3-0.6 4.8-1 50-11 102.8-16.2 233.6 46.6 164 78.6 307.6-66.2 363.2-167 4-7 17.4-40.4 17.4-72.4C876.4 360 852.8 365 852.8 365z M176 64 144 64c-8.8 0-16 7.2-16 16l0 864c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16L192 80C192 71.2 184.8 64 176 64z',
            symbolSize: 6, //图形大小
            label: {
              normal: {
                formatter: function(params) {
                  console.log(params);
                  return params.name;
                },
                show: false,
              },
              emphasis: {
                show: false,
              }
            },
            data: dataPoint
          },
          data: dataList
        }],
       };
      chart.setOption(option);
    },
   // 初始化图表
  init_one(dataList, dataPoint) {           //初始化图表
      this.oneComponent.init((canvas, width, height, dpr) => {
        const chart = echarts.init(canvas, null, {
          width: width,
          height: height,
          devicePixelRatio: dpr // new
        });
        canvas.setChart(chart);
        echarts.registerMap('china', geoJson);
        this.setOption(chart, dataList, dataPoint)  //赋值给echart图表
        chart.dispatchAction({
          type: 'showTip',
          seriesIndex:0,  // 显示第几个series
          dataIndex: 28 // 显示第几个数据
        })
        this.chart = chart
        return chart
      });
    },
 //初始化图表封装了一层
 getOneOption(){
      this.init_one(this.data.dataList, this.data.dataPoint)
    },
  }
)}

组件生命函数中的设置

lifetimes: {
    attached: function() {
      // 在组件实例进入页面节点树时执行
      // 获取echarts组件,并赋值给变量,然后初始化图表
      this.oneComponent = this.selectComponent('#mychart-dom-area');
      this.getOneOption();
    },
    detached: function() {
      // 在组件实例被从页面节点树移除时执行
    },
  }

四、页面中使用自定义echarts地图组件,并可以动态赋值
  页面中使用地图组件,需先在页面json中引入自定义echarts地图组件。

 "usingComponents": {
    "chinamap" : "/components/chinamap/chinamap"
  },

  页面的wxml中使用自定义echarts地图组件,dataList和dataPoint为需要的数据,同时需设置组件id。

<chinamap dataList="{{dataList}}" dataPoint="{{dataPoint}}" id="mapComponent" />

页面js中

 data: {
    dataPoint: [{"name":"南海诸岛","coord":[130,22],"value":0},{"name":"西藏","coord":[89.132212,32.110361],"value":0}],
    dataList: [
      { name: '南海诸岛', value: 0 },
      { name: '北京', value: 54 },
      { name: '天津', value: 13 },
      { name: '上海', value: 40 },
      { name: '重庆', value: 75 },
      { name: '河北', value: 13 },
      { name: '河南', value: 83 },
      { name: '云南', value: 11 },
      { name: '辽宁', value: 19 },
      { name: '黑龙江', value: 15 },
      { name: '湖南', value: 69 },
      { name: '安徽', value: 60 },
      { name: '山东', value: 39 },
      { name: '新疆', value: 2 },
      { name: '江苏', value: 31 },
      { name: '浙江', value: 104 },
      { name: '江西', value: 36 },
      { name: '湖北', value: 1052 },
      { name: '广西', value: 33 },
      { name: '甘肃', value: 7 },
      { name: '山西', value: 9 },
      { name: '内蒙古', value: 7 },
      { name: '陕西', value: 22 },
      { name: '吉林', value: 4 },
      { name: '福建', value: 18 },
      { name: '贵州', value: 5 },
      { name: '广东', value: 98 },
      { name: '青海', value: 1 },
      { name: '西藏', value: 0 },
      { name: '四川', value: 44 },
      { name: '宁夏', value: 4 },
      { name: '海南', value: 22 },
      { name: '台湾', value: 3 },
      { name: '香港', value: 5 },
      { name: '澳门', value: 5 }
    ]
  },
/**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    //获取自定义地图组件的实例,如果页面有点击函数或者互联网请求,即可使用 this.mapComponent调用自定义echarts地图组件中定义的出事化函数(this.mapComponent.getOneOption())
    this.mapComponent = this.selectComponent('#mapComponent')
  },
/**
   * 假设页面有点击按钮,改变地图数据,对地图所需数据进行更新,然后调用this.mapComponent.getOneOption()重新初始化echarts地图即可动态赋值。
   */
hisBtnClickMap() {
    this.setData({
      btnClickIndex : 1,
      dataPoint: [{"name":"南海诸岛","coord":[130,22],"value":0},{"name":"西藏","coord":[89.132212,32.110361],"value":0}],
      dataList: [
        { name: '南海诸岛', value: 0 },
        { name: '北京', value: 0 },
        { name: '天津', value: 13 },
        { name: '上海', value: 40 },
        { name: '重庆', value: 75 },
        { name: '河北', value: 13 },
        { name: '河南', value: 830 },
        { name: '云南', value: 11 },
        { name: '辽宁', value: 19 },
        { name: '黑龙江', value: 15 },
        { name: '湖南', value: 6900 },
        { name: '安徽', value: 60 },
        { name: '山东', value: 39 },
        { name: '新疆', value: 200 },
        { name: '江苏', value: 31 },
        { name: '浙江', value: 104 },
        { name: '江西', value: 36 },
        { name: '湖北', value: 12052 },
        { name: '广西', value: 33 },
        { name: '甘肃', value: 7 },
        { name: '山西', value: 9 },
        { name: '内蒙古', value: 7 },
        { name: '陕西', value: 22 },
        { name: '吉林', value: 4 },
        { name: '福建', value: 18 },
        { name: '贵州', value: 5 },
        { name: '广东', value: 98 },
        { name: '青海', value: 0 },
        { name: '西藏', value: 33 },
        { name: '四川', value: 44 },
        { name: '宁夏', value: 4 },
        { name: '海南', value: 220 },
        { name: '台湾', value: 300 },
        { name: '香港', value: 500 },
        { name: '澳门', value: 500}
      ]
    })
    this.mapComponent.getOneOption()
  }

以上为全部代码,至此完结。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容