记录一下自定义 Echarts 中的一些问题

 先上最终效果图;

我们的需求是,输入车牌和日期后,展示出该车辆在不通时间下的停车记录。

首先拿到原型和效果图先要画出上面的时间:

{
          type: 'custom',
          renderItem: function(params, api){
            console.log()
            let x = ( ((that.chartW - 100) / 48) * (api.value(0) -  1)) + 45;  // 绘制时间的位置
            let children = [
              {
                type: 'text',
                style: {
                    x: x,
                    y: 30,
                    text: api.value(1) < 10 ? '0' + api.value(1) : api.value(1),
                    textVerticalAlign: 'bottom',
                    textAlign: 'center',
                    textFill: '#333'
                }
              }
            ]
            // 到时候要换成数据的length;   绘制每个时间下面的竖着的虚线
            for(let i=0;i< 7; i++){
              let obj = {
                type: 'polyline',
                z2: 10,
                x: 52,
                y: 50,
                style: {
                    fill: '#DCDCDC',
                    stroke: '#DCDCDC',
                    lineWidth: 1
                },
                shape: {
                  points: [[x-52, 20 + (50 * i)], [x-52, 50 + (50 * i)]]
                }
              }
              children.push(obj)
            }

            return {
              type: 'group',
              position: [
                x,
                10
              ],
              children: children
            }
          },
          encode: {
              x: -20,
              y: 0
          },
          data: [
            [1, '00'],
            [2, '01'],
            [3, '02'],
            [4, '03'],
            [5, '04'],
            [6, '05'],
            [7, '06'],
            [8, '07'],
            [9, '08'],
            [10, '09'],
            [11, '10'],
            [12, '11'],
            [13, '12'],
            [14, '13'],
            [15, '14'],
            [16, '15'],
            [17, '16'],
            [18, '17'],
            [19, '18'],
            [20, '19'],
            [21, '20'],
            [22, '21'],
            [23, '22'],
            [24, '23'],
            [25, '24'],
          ]
 }    

这样先把上面的时间画出来了

 然后画左边Y轴的时间,和横着的线

{
          type: 'custom',
          renderItem: function(params, api){
            let y =(that.dataLenght.length - api.value(0)) * 50 + 50;
            let x = ( ((that.chartW - 100) / 48) * (api.value(0) -  1)) + 45   // 根据数据条数判断Echart容器的高度,然后判断每个条目的位置
            return {
              type: 'group',
              position: [
                10,
                y
              ],
              children: [
                {
                  type: 'text',
                  style: {
                      x: 24,
                      y: 50,
                      text: api.value(1),
                      textVerticalAlign: 'bottom',
                      textAlign: 'center',
                      textFill: '#333'
                  }
                },
                {
                  type: 'line',
                  z2: 10,
                  x: 52,
                  y: 50,
                  style: {
                      fill: '#DCDCDC',
                      stroke: '#DCDCDC',
                      // fill: 'red',
                      // stroke: 'red',
                      lineWidth: 1
                  },
                  shape: {
                    x1: 30,
                    y1: -7,
                    x2: that.chartW - 70,
                    y2: -7
                  }
                }
              ]
            }
          },
          // dimensions: _rawData.parkingApron.dimensions,
          encode: {
              x: -20, // Then this series will not controlled by x.
              y: 0
          },
          data: [
            [7, '2012-07-03'],
            [6, '2012-07-02'],
            [5, '2012-07-01'],
            [4, '2012-06-30'],
            [3, '2012-06-29'],
            [2, '2012-06-28'],
            [1, '2012-06-27']
          ]
}

这样Y轴时间和横线就出来了

 接下来就是根据时间画停车记录了

{
          type: 'custom',
          renderItem: function(params, api){
            function clipRectByRect(params, rect, customParams) {
              return {...that.$echarts.graphic.clipRectByRect(rect, {
                  x: params.coordSys.x,
                  y: params.coordSys.y,
                  width: params.coordSys.width,
                  height: params.coordSys.height
              }), ...customParams};  // 传入自定义参数后面鼠标移入提示用
            }  

            const categoryIndex = api.value(0);
            
            let parkLen = that.dataLenght[categoryIndex - 1];

            let children = [];
            let x = '';
            let barLength = '';

            let totalTime = 86400000;           // 一天从0点-24点的毫秒数
            let startTimeStr = 1340985600000;   // 2012.6.30  00:00:00
            
            for(let i = 0; i < parkLen; i++){
              let startParkTime = api.value(1 + (i * 2));  // 停车记录开始时间
              let endParkTime = api.value(2 + (i * 2));    // 停车记录结束时间
              let plusVal = endParkTime - startParkTime;
              barLength = (plusVal / totalTime) * (that.chartW - 100);  // 柱状图长度
              if (barLength && barLength < 10) {    // 测试停车时长只有1分钟就出场了,时间太短,柱状图太小,看不见而且无法点击问题,增加最小长度
                barLength = 10
              }
              let plusStartTime = startParkTime - startTimeStr;
     
              x = 90 + ( plusStartTime / totalTime) * (that.chartW - 100) ;  // 柱状图起始位置
              let rectNormal = clipRectByRect(params, {
                x: x, y: (that.dataLenght.length - api.value(0)) * 50 + 83 , width: barLength, height: 20
              }, {startParkTime: startParkTime, endParkTime: endParkTime, categoryIndex: categoryIndex});
              if (rectNormal) {
                rectNormal.r = [10] // 设置圆角
              }
              let parkObj = {
                type: 'rect',
                z2: 20,
                shape: rectNormal,
                style: api.style({fill: '#69DBFF', borderRadius: 10})
              };
              
              children.push(parkObj)
              that.catchChildren.push(rectNormal)
            }
            

            return {
              type: 'group',
              children: children
            };  

          },
          encode: {
              x: [1, 2],
              y: 0,
              tooltip: [0, 1, 2]
          },
          data: [
            [7, 1341029700000, 1341029900000, 'null', 'null'],   // 12:15 - 14:48 
            [6, 1341032400000, 1341050400000, 'null', 'null'],   // 2012年6月30日 13 - 18
            [5, 1341032400000, 1341050400000, 'null', 'null'],   // 13 - 18
            [4, 1340985600000, 1341007200000, 1341057600000, 1341064800000], // 0 - 6, 20 - 22   new Date('2012-06-30 00:00:00').getTime()
            [3, 1341014400000, 1341043200000, 'null', 'null'],  // 8 -16
            [2, 1341021600000, 1341028800000, 'none', 'null'],  // 10点 - 12点
            [1, 1341032400000, 1341050400000, 'null', 'null']   // 13 - 18
          ]
}

绘制停车记录有几个坑:1是数据必须长度需要和停车记录最多的数据是一样的(否则如果第一个记录有1条停车记录,后面有多条停车记录的也只能绘制出一个)。2、是圆角要设置 ‘r’ 属性才能显示(文档里没有)

这样停车记录就出来了

 剩下就是鼠标移入显示对应数据,和显示提示框的位置

// 鼠标移入显示toolTip
    this.myChart.on('mousemove', function (event) {

      if (that.catchMoveItem && that.catchMoveItem.categoryIndex && that.catchMoveItem.categoryIndex == event.event.target.shape.categoryIndex && that.catchMoveItem.startParkTime == event.event.target.shape.startParkTime) {
        that.moveToolTipFn(event)
        return
      }

      let targetDom = event.event.target.shape;
      // 鼠标移动到自定义X,Y轴不显示提示
      if (!targetDom || targetDom.points) {
        return
      }  

      let ev = event.event;
      console.log('11111', event)
      that.myChart.dispatchAction({
        type: 'highlight',
        seriesIndex: event.seriesIndex
      })
      that.catchMoveItem = targetDom;  // 换存当前移动的对象
      that.showToolTipFn(ev.offsetX, ev.offsetY, targetDom)
 })

显示toolTip位置

showToolTipFn(x, y, obj) {
      let customOffsetX = 10;
      let customOffsetY = 20;

      // 右边界
      if (this.chartW - x < 250) {
        customOffsetX = -200
      }

      // 下边界  // 可以优化获取tip宽高
      if (400 - y < 100) {
        customOffsetY = -80
      }

      this.toolTipDom.style.left = x + customOffsetX + 'px';
      this.toolTipDom.style.top = y + customOffsetY + 'px';
      this.toolTipObj = Object.assign({}, obj)
      this.showToolTip = true;
 }

总结:通过这次自定义Echarts开发,后面发现数据可以通过{name:'', value: []}这种方式传递,后面可以进行优化。

posted @ 2021-10-27 17:56  小小的忧愁  阅读(378)  评论(0编辑  收藏  举报