微信小程序运用 echarts 的技巧与方法

why 1388 2024-07-17

人在家中坐,锅从天上来。

半个月前本来在家写着一个项目,还没来得及提测,领导突然一个电话,需要立刻去支援另一个项目,一打听,一个烂尾半年的项目,纵使内心不愿意,还是要去啊。因为鲁迅说过,生活就像强*,既然不能反抗,那就好好享受吧。

这个项目分为PC端、用户端小程序和商家端小程序,这里主要讲讲在商家端中的某个模块,需要用到数据统计图表,当时觉得有两个插件不错:

  • 百度 echarts

  • 阿里 AntV

因为之前在项目中使用echarts比较多,所以最终选择了echarts作为项目中的图表插件

echarts的引入

我是按照echarts官网教程来引入的,很简单,不多说。传送门

echarts中使用多个图表

wxml代码如下:

1

2

3

4

<!--图表1--><view class="echarts-container" hidden="{{!isShoweyes || !echartsData.totalRecentRansactions.allTotalMoney}}">

    <ec-canvas id="mychart-dom-turnover" canvas-id="mychart-turnover" ec="{{ turnoverEc }}"></ec-canvas></view><!--图表2--><view class="echarts-container" hidden="{{!isShoweyes || !echartsData.shopNewCustomerRespVo.allNewCustomer}}">

    <ec-canvas id="mychart-dom-customer" canvas-id="mychart-customer" ec="{{ customerEc }}"></ec-canvas></view><!--图表3--><view class="echarts-container" hidden="{{!isShoweyes || !echartsData.customerOrderAverageRespVo.customerAverage}}">

    <ec-canvas id="mychart-dom-price" canvas-id="mychart-price" ec="{{ priceEc }}"></ec-canvas></view>

js代码如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

<!--通过lazyLoad设置图表懒加载-->data: {

    isShoweyes: true,

    turnoverEc: {

      lazyLoad: true,

    },

    customerEc: {

      lazyLoad: true,

    },

    priceEc: {

      lazyLoad: true,

    },

    echartsData: {}

  },

  <!--页面加载时创建对应的canvas面板-->onLoad: function (options) {

    this.echartsComponnet1 = this.selectComponent(&#39;#mychart-dom-turnover&#39;);

    this.echartsComponnet2 = this.selectComponent(&#39;#mychart-dom-customer&#39;);

    this.echartsComponnet3 = this.selectComponent(&#39;#mychart-dom-price&#39;);

  },

  <!--获取到数据后,初始化报表-->

  getData: function () {

    //  .... 获取数据

     

    <!--此用循环初始化几个图表-->

    for (let i = 1; i < 4; i++) {

        if (!Chart[i]) {

          this.initEcharts(i); //初始化图表

        } else {

          this.setOption(i); //更新数据

        }

      }

  },

  <!--//初始化图表-->

  initEcharts: function (i) {

    this[&#39;echartsComponnet&#39; + i].init((canvas, width, height) => {

      // 初始化图表

      Chart[i - 1] = echarts.init(canvas, null, {

        width: width,

        height: height

      });

      this.setOption(i);

      // 注意这里一定要返回 chart 实例,否则会影响事件处理等

      return Chart[i - 1];

    });

  },

  setOption: function (i) {

    Chart[i - 1].clear(); // 清除

    Chart[i - 1].setOption(this[&#39;getOption&#39; + i]()); //获取新数据

  },

   

  <!--设置报表需要的配置项-->

  getOption1() {

    let {

      echartsData

    } = this.data;

    return {

      color: [&#39;#0179FF&#39;],

      tooltip: {

        trigger: &#39;axis&#39;,

        axisPointer: { // 坐标轴指示器,坐标轴触发有效

          type: &#39;shadow&#39;, // 默认为直线,可选为:&#39;line&#39; | &#39;shadow&#39;

          shadowStyle: {

            opacity: 0.8

          }

        },

        formatter: this.formatterTooltip,

        position: this.setTooltipPositionfunction

      },

      grid: {

        left: 20,

        right: 20,

        bottom: 15,

        top: 40,

        containLabel: true

      },

      xAxis: [{

        type: &#39;category&#39;,

        axisLine: {

          lineStyle: {

            color: &#39;#999&#39;,

          }

        },

        axisLabel: {

          color: &#39;#666&#39;,

        },

        data: echartsData.totalRecentRansactions.dates,

      }

      ],

      yAxis: [{

        type: &#39;value&#39;,

        axisTick: {

          show: false

        },

        axisLine: {

          show: false,

          lineStyle: {

            color: &#39;#999&#39;,

          }

        },

        axisLabel: {

          color: &#39;#666&#39;,

          fontSize: 13

        }

      }],

      series: [{

        name: &#39;订单总额&#39;,

        type: &#39;line&#39;,

        label: {

          normal: {

            show: true,// 是否在折线点上显示数值

            position: &#39;inside&#39;

          }

        },

        data: echartsData.totalRecentRansactions.allTotalMoney

      }]

    };

  }

遇到的坑

1.Tooltip支持不好

 

虽然官网上echarts暂时不支持Tooltip,但是经过试验,还是Tooltip还是有效果的,但是,x轴对应的坐标值并不会显示在Tooltip中,需要使用Tooltip的formatter函数,自己处理需要展示的数据,代码如下:

// 格式化Tooltip

  formatterTooltip(param) {    return "日期:" + param[0].name + "\n" + param[0].seriesName + ": " + param[0].data

  },

2.当点击靠近屏幕右侧或者底部的item项时,Tooltip会溢出边界,解决办法:

给Tooltip的position函数返回一个根据点击位置计算的坐标点,(也可以给一个固定的位置,但是体验不好)

 // 更改Tooltip的位置,处理边界超出的情况

  setTooltipPositionfunction(point, params, dom, rect, size) {    //其中point为当前鼠标的位置,size中有两个属性:viewSize和contentSize,分别为外层div和tooltip提示框的大小

    // 更改提示框的显示位置

    let x = point[0];//

    let y = point[1];    // size: 包括 dom 的尺寸和 echarts 容器的当前尺寸,例如:{contentSize: [width, height], viewSize: [width, height]}

    let boxWidth = size.contentSize[0];    // let boxHeight = size.contentSize[1]; // size里面此处获取不到dom的高度,值为NAN,所以下面指定了一个固定值

    let boxHeight = 50;    let posX = 0;//x坐标位置

    let posY = 0;//y坐标位置

    if (x < boxWidth) {//左边放不开

      posX = 5;

    } else {//左边放的下

      posX = x - boxWidth;

    }    if (y < boxHeight) {//上边放不开

      posY = 5;

    } else {//上边放得下

      posY = y - boxHeight;

    }    return [posX, posY];

  },

上面需要注意的是,获取dom的高度,官方上说的是可以从position回调函数的size参数中获取到dom的高度,但是我打印出来却是NAN。

image.png

打印出来结果:

image.png

后来发现参数params中outerWidth的值和参数size中contentSize的宽度值相同,所以果断取参数params中的outerHeight作为dom的高度,最后运行的效果确实没有问题。

image.png

3.左右滑动柱状图时,柱状图画板会变空白,点一下空白又会出现柱状图,而且这个问题只有在柱状图上出现!

刚开始以为是自己代码的问题,后来自己检查了几遍,确实没什么问题,然后扫码体验了官方的小程序demo,发现也有这个问题,顿时只想对它口吐芬芳。既然是官方代码自身的问题,于是去看了下源码,如下:

1

<canvas class="ec-canvas" canvas-id="{{ canvasId }}" bindinit="init" bindtouchstart="{{ ec.disableTouch ? &#39;&#39; : &#39;touchStart&#39; }}" bindtouchmove="{{ ec.disableTouch ? &#39;&#39; : &#39;touchMove&#39; }}" bindtouchend="{{ ec.disableTouch ? &#39;&#39; : &#39;touchEnd&#39; }}"></canvas>

官方代码给画布绑定一个bindtouchmove事件

1

2

3

4

5

6

7

8

touchMove(e) {      if (this.chart && e.touches.length > 0) {        var touch = e.touches[0];        var handler = this.chart.getZr().handler;

        handler.dispatch(&#39;mousemove&#39;, {

          zrX: touch.x,

          zrY: touch.y

        });

        handler.processGesture(wrapTouch(e), &#39;change&#39;);

      }

    },

这里面又去调用了echarts.js中的方法,最后想了一个粗暴的解决办法:

删掉源码中的bindtouchmove事件

完美解决,哈哈或或红红火火恍恍惚惚~~~

以上就是我在小程序中使用echarts遇到的坑,希望能帮到后来踩坑的人。

最终效果图片

image.png


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:小程序批量删除的操作方式与技巧
下一篇:微信公众号与小程序的差异全面剖析
相关文章

 发表评论

暂时没有评论,来抢沙发吧~