zoukankan      html  css  js  c++  java
  • 如何在微信小程序中使用Echarts

    前言:

    之前因为疫情,看到有许多做疫情动态的小程序,自己也跟着做了一个

    总的来说,不难,就是有接口,拿到数据之后,就进行展现就好

    不过其中比较难的,就是疫情地图部分,使用的是Echarts的可视化地图

    先上张图,这里只讲这个map组件(数据滞后,不要当真)

    我使用的时候遇到很多坑,而且看文档和博客,对在小程序中使用Echarts的一些介绍比较少

    所以我做出来了,就想详细写一写

    不过因为有事一直耽搁了,过得时间有点长了,我主要是想说一些需要注意的点,具体完整代码可看我github连接

    正文:

    首先,建议还是自己上官网看看 Echarts

    其实基本的使用就已经交代清楚了,可以自己先尝试

    对于第一次使用的小白,我建议的步骤就是:

    1. 先在下载 GitHub 上的 ecomfe/echarts-for-weixin 项目

    2. 找到你想用的图表,看它提供的代码,大概知道怎么使用的

    3. 将示例中的ec-canvas文件夹拷贝到你的小程序项目中的components文件夹下

    4. 它提供的示例是每个图表是一个page,但是显然我们自己实际开发是作为一个component,所以新建一个component,灵活拷贝你想做的图表的相关内容即可

    以上没有任何技术含量,CV解决,对于初次使用,这样简单粗暴的方式,至少能保证你的引入是没有问题的,而且也好排除错在哪

    如果看到图表正常显示,恭喜你会使用Echarts了,是恭喜你完成了第一步

    之后就是根据我们自己的需求,进行修改了。

    更具体的修改使用,我将以我做的疫情地图为例,用的是map这一组件

    我先介绍几个的主体部分,然后介绍修改

    首先,在index.json的useingComponents中引入ec-canvas组件

    "usingComponents": {
        "ec-canvas": "../../ec-canvas/ec-canvas"
      }

    其次,在index.wxml中使用组件

    <view class="mapWrap" hidden="{{isLoadingMap}}"> 
       <ec-canvas id="mychart-dom-area" canvas-id="mychart-area" ec="{{ ec }}" class="map" bindlongpress='saveImg'></ec-canvas>
    </view>
    • id是为了js中获取到该实例使用的,命名不一定,规范即可
    • class是为了样式设置使用的,一般是在wxss中设置图表的宽高
    • bindlongpress就是长按事件,我这里做的就是长按地图保存该地图图片,后会详述

    至于ec,就是关键了

    如果你拷贝时没有出错,可以看到组件中的data中有个属性,ec

    它的值是一个配置对象,其中有一个配置为初始化图表的,onInit为键,配置对象的键名是不能修改;initChart为值,是我们要定义的初始化函数。

    ec: {
      onInit: initChart
    }

    ec将传会给ec-canvas组件,根据其不同的配置进行不同的处理,具体可看源码

    总之在这里传initChart函数,就是会在组件created生命周期进行初始化图表

    我们要根据自己需求展现图表,最主要的就是在修改initChart这个函数了

    如果只是静态数据,就按下面的写法即可

    function initChart(canvas, width, height, dpr) {
      // 1.固定写法不用管
      const chart = echarts.init(canvas, null, {
         width,
        height: height,
        devicePixelRatio: dpr // new
      });
      canvas.setChart(chart);
      // 2.注册地图
      echarts.registerMap('henan', geoJson);
      // 3.设置option
      const option = {...}
      chart.setOption(option);
      // 4. 返回echarts
      return chart;
    }

    主要修改的就是步骤2和3

    修改步骤2:

    我做的是中国疫情地图,所以需要引入的是中国地图,是一个js文件,是对各个省份的一些配置信息。

    从网上看到别的博主提供的文件,链接下载,放入你的小程序组件文件夹下,可以不修改,import引入,然后修改步骤二

    import geoJson from './china'
    
    // 注册地图
    echarts.registerMap('china',geoJson)

    修改步骤3:

    其实挺关键的,这是图表的一个配置项,配置你所希望展现的一切

    但是内容太多了,例如有配置  tooltip(提示框组件)、visualMap(视觉映射组件)、toolbox(工具栏)、series(系列列表)... ...

    这里就不详述了,文档很多也很全的。用过Echarts的很快就会用了,就算没用过的,对着文档耐心改改就知道了,

    不过还是有一些需要注意的

    series中

    type: 'map',  //类型是地图,用于地理数据可视化
    mapType: 'china', //注册的地图
    data  //数据源

    其中的data,若是静态数据,写好引入就好了,到这里基本一个中国疫情地图就做完了。

    但是通常情况下,data都是动态的,我们基本上都是发送请求获取到的

    所以上面的写法就带来了一个问题:前面讲到intiChart会在created就触发了,如果是异步获取数据,往往initChart调用后,其中setOption中的data还没有获取到

    这就会只显示了个地图,但是地图没有数据,同时也会报错

    所以我们要考虑的就是异步加载组件,当时在网上没看到相关参考后,我就去看了源码,自己琢磨了

    但是后来发现,它提供的示例中就有异步加载的示例,看着示例很快就知道怎么改了

    这就给我一个教训,一定要好好看它的示例,不过吧,虽然花了不少时间,但是看了源码是更好理解它为什么这么用了

    废话说太多了,接下来讲讲我是怎么使用异步组件的

    首先,关键在ec,不再是配置onInit了,而是设置lazyload为true,这就可以异步加载组件了,之后可以动态进行初始化

    ec: {
          // 将lazyLoad设为true后,就可手动初始化了
          lazyLoad:true
    }

    定义 初始化Echart的函数,之前我们在component外部定义的,这会可以把其放在methods中,可访问到this

    和上面的initChart差不多,为以下5步

        initChart(){
          // 1.首先获取组件,可在父组件里调用 this.selectComponent ,获取子组件的实例对象。
          const ecComponent = this.selectComponent('#mychart-dom-area');
          ecComponent.init((canvas, width, height, dpr) =>{
            // 2.这个不用管,固定写法
            const chart = echarts.init(canvas, null, {
              width,
              height:height,
              devicePixelRatio: dpr // new
            });
            canvas.setChart(chart);
            // 3.注册地图
            echarts.registerMap('china',geoJson)
            // 4.设置option
            this.setOption(chart);
            // 5.最后一定要返回chart
            return chart;
          })
        },

    区别在于多了第1步,和第4步中data不再是静态资源了,而是需要向后台获取的:

    第1步,通过之前定义的id,获取到该echart组件实例,通过调用该实例的init方法初始化

    第4步是我另外定义的一个函数调用,主要是为看着更清楚些,不想在initChart这个函数中写太多,主要为

    setOption(chart){
          // 1.provinceData是父组件从后台获取,然后传给这个map组件中的
          // 要进行一些处理,name和china.js中对应,value就是要呈现的值,这里就是当前确诊人数
          const data = this.data.provinceData.map((item,index) => {
            return {
              name:item.provinceShortName,
              value:item.currentConfirmedCount
            }
          })
          // 2.地图内容配置
          const option = {
            // 提示框组件
            tooltip: {...},
            // 视觉映射组件
            visualMap: {...},
            // 工具栏
            toolbox: {...},
            // 系列列表。每个系列通过 type 决定自己的图表类型
            series: [{
              top:0,
              type: 'map',  //类型是地图,用于地理数据可视化
              mapType: 'china', //注册的地图
              // 标签(标签位置在china.js文件中的properties中的cp修改)
              label: {...},
              itemStyle: {...},
              animation: false,
              data
            }],
          };
      // 调用函数传入的chart的setOption方法,将该option设置 chart.setOption(option); },

    option中的一些配置项为...,是我省略没粘贴上,完整的看我的github上都有

    接下来就是要在合适的时机调用 initChart 方法就可

    在这里是父组件异步获取数据后,传给map组件的,所以合适的时机就在map组件获取到provinceData后

    所以就在map的属性列表properties中,该provinceData配置一个observer,开启监听,当获取到数据的时候就调用initChart函数

      properties: {
        provinceData:{
          type:Array,
          observer(news){
            if(news.length){
              this.initChart()
            }
          }
        }
      },

    这就完成了中国疫情地图啦~

    除此之外,还可自己多多拓展功能啊

    我这里就拓展了个,长按保存图片功能,就是前面说的 bindlongpress 事件

        saveImg(){
          wx.showModal({
            title: '保存地图到相册',
            content:"确认保存",
            confirmText:'保存',
            success:(res)=>{
              if (res.confirm) {
                const ecComponent = this.selectComponent('#mychart-dom-bar');
                // 先保存图片到临时的本地文件,然后存入系统相册
                ecComponent.canvasToTempFilePath({
                  success: res => {
                    console.log("tempFilePath:", res.tempFilePath)
                    // 存入系统相册
                    wx.saveImageToPhotosAlbum({
                      filePath: res.tempFilePath || '',
                      success: res => {
                        console.log("success", res)
                      },
                      fail: res => {
                        console.log("fail", res)
                      }
                    })
                  },
                  fail: res => console.log(res)
                })
              }
            }
          })
        }
      },
    转载请私聊,引用请注明出处,欢迎交流评论,但请不要发动白起大招,谢谢!
  • 相关阅读:
    搜索1011
    搜索1008(二分)
    贪心算法专题总结
    贪心算法1002
    c++笔记
    贪心算法1017
    贪心算法1008
    贪心算法1013
    Ubuntu中 sudo update与sudo upgrade的作用及区别
    requirejs 扩展,支持脚本资源预加载
  • 原文地址:https://www.cnblogs.com/nys013/p/13795512.html
Copyright © 2011-2022 走看看