vue + echarts两条线条时的拖拽功能

全文以本人真实代码进行截取有点乱,有很多自用组件,懒得改了

反正不耽误阅读

x轴使用value格式或者默认(必须这样,否则拖拽会出问题)

如果是时间段,可以转化为时间戳格式

let timeArray = []
this.allChartData.forEach(item => {
    timeArray.push(item.tm)
})
// 得到时间段的最小与最大
let min = Math.min.apply(null, timeArray)
let max = Math.max.apply(null, timeArray)
// 得到时间差
let tm_diff = 72 - ((max - min) / 1000 / 60 / 60)
// 如果大于72小时则两边各补一小时
let diff = Math.ceil((tm_diff > 0 ? tm_diff : 2) / 2)
// 时间范围72小时 最小与最大都延长一天吧
let xAxisMin = this.$utils.dateUtil.getDateAdd(new Date(min), 'HOUR', (0 - diff))
let xAxisMax = this.$utils.dateUtil.getDateAdd(new Date(max), 'HOUR', diff)

Y轴设置最大最小值:

      let key = this.actSttp.toLowerCase()
      // 得到Y轴数据
      let y_array = []
      let z_data = []
      let q_data = []
      this.def_z_data = []
      this.def_q_data = []
      this.allChartData.forEach(item => {
        let { tm, z, q } = item
        z_data.push(Number(z))
        q_data.push(Number(q))
        this.def_z_data.push([tm, Number(z)])
        this.def_q_data.push([tm, Number(q)])
      })
      switch (key) {
        case 'z':
          y_array = z_data
          break
        case 'q':
          y_array = q_data
          break
        case 'all':
          y_array = [...z_data, ...q_data]
          break
      }
      let yMin = Math.min.apply(null, y_array) > 0 ? 0 : Math.min.apply(null, y_array)
      let yMax = Math.max.apply(null, y_array)
      let y_min = yMin < -100 ? Math.floor(yMin / 100) * 100 : Math.floor(yMin / 10) * 10
      let y_max = yMax > 100 ? Math.ceil(yMax / 100) * 100 : Math.ceil(yMax / 10) * 10
      // 带上x轴
      let x_min = new Date(xAxisMin).getTime()
      let x_max = new Date(xAxisMax).getTime()

现在得到X轴和Y轴的区间范围,以及def_z_data,def_q_data这两条线条可以开始画chart图了:

let _this = this
      let key = _this.actSttp.toLowerCase()
      let series = []
      let def_series = {
        type: 'line',
        smooth: 0.5, // 开启平滑,0-1
        symbol: 'circle',
        symbolSize: 7,
        connectNulls: false,
        silent: true,
        lineStyle: {
          width: 2,
          shadowColor: 'rgba(0, 0, 0, 0.3)',
          shadowBlur: 10
        }
      }
      // 水位
      let z_obj = {
        ...def_series,
        id: 'z',
        name: '水位',
        color: '#0954ad',
        data: this.def_z_data
      }
      // 流量
      let q_obj = {
        ...def_series,
        id: 'q',
        name: '流量',
        color: '#36bc9b',
        data: this.def_q_data
      }
      switch (key) {
        case 'z':
          series.push(z_obj)
          break
        case 'q':
          series.push(q_obj)
          break
        case 'all':
          series.push(z_obj)
          series.push(q_obj)
          break
      }
      let option = {
        grid: {
          top: '5%',
          left: '7%',
          right: '1%',
          bottom: 30
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            lineStyle: {
              type: 'dashed'
            }
          },
          backgroundColor: '#fff',
          borderColor: '#1877ed',
          borderWidth: 1,
          borderRadius: 2,
          padding: [
            5, // 上
            10, // 右
            5, // 下
            10 // 左
          ],
          formatter: (params) => {
            let pm = params[0]
            let { value } = pm
            let tm = this.$utils.dateUtil.getFormatDate(new Date(value[0]), 'yyyy-MM-dd hh:mm')
            let spanContent = `<p style="color: #929da9">${tm}</p>`
            params.forEach(param => {
              let { seriesName, value, color, seriesId } = param
              spanContent += `
                <div class='df_ac' style="padding: 0 0 0 0;">
                  <p style='display: block; width: 16px;height: 3px;background-color: ${color};'></p>
                  <p style="color:#333;margin-left:5px;">
                    <span>${seriesName}:</span>
                    <b>${value[1]}</b>
                    <span>${seriesId === 'z' ? 'm' : 'm³/s'}</span>
                  </p>
                </div>
                `
            })
            return spanContent
          },
          textStyle: {
            fontSize: 14
          }
        },
        xAxis: {
          min: x_min,
          max: x_max,
          type: 'time',
          boundaryGap: false,
          axisTick: {
            show: false
          },
          splitLine: {
            show: false
          },
          axisLine: { show: false, onZero: false },
          axisLabel: {
            showMinLabel: false,
            showMaxLabel: false,
            fontSize: 13,
            formatter: function(value) {
              let tm = new Date(value)
              return _this.$utils.dateUtil.getFormatDate(tm, 'MM-dd hh:mm')
            }
          }
        },
        yAxis: {
          min: y_min,
          max: y_max,
          axisLabel: {
            inside: false,
            verticalAlign: 'middle',
            fontSize: 13,
            fontWeight: 700,
            formatter: function(value) {
              return Math.round(value)
            }
          },
          splitLine: {
            show: true,
            lineStyle: {
              type: 'dashed'
            }
          },
          axisLine: {
            show: false,
            onZero: false
          },
          axisTick: {
            show: false,
            inside: true
          }
          // type: 'value',
          // axisLine: { onZero: false }
        },
        series
      }
      this.chartOption = option
      this.$nextTick(() => {
        // 综合的时候不拖拽
        if (this.$refs.charts && key !== 'all') {
          this.draRestChart()
        }
      })

配置可拖拽:

      let _this = this
      let key = _this.actSttp.toLowerCase()
      let myChart = _this.$refs.charts.chart
      let all_data = []
      switch (key) {
        // case 'all':
        //   all_data = [...this.def_z_data, ...this.def_q_data]
        //   break
        case 'z':
          all_data = this.def_z_data
          break
        case 'q':
          all_data = this.def_q_data
          break
      }
      myChart.setOption({
        // 多条曲线时需要把两条曲线的数组拼成一个数组进行遍历
        graphic: all_data.map(function(item, dataIndex) {
          return {
            type: 'circle',
            position: myChart.convertToPixel('grid', item),
            shape: {
              cx: 0,
              cy: 0,
              r: 10
            },
            invisible: true,
            draggable: true,
            // 此处必须用匿名函数,不能用箭头函数,否则拿不到拖动的坐标
            ondrag: function() {
              switch (key) {
                case 'z':
                  _this.zPointDragging(dataIndex, this.position)
                  break
                case 'q':
                  _this.qPointDragging(dataIndex, this.position)
                  break
              }
            },
            z: 100
          }
        })
      })

拖拽两条线条的时候:

    onPointDragging(dataIndex, pos) {
      let z_length = this.def_z_data.length
      // 通过索引判断此圆圈覆盖的是哪条曲线
      if (dataIndex <= (z_length - 1)) {
        this.zPointDragging(dataIndex, pos)
      } else {
        let q_index = dataIndex - z_length
        this.qPointDragging(q_index, pos)
      }
    }

    zPointDragging(dataIndex, pos) {
      let length = this.def_z_data.length - 1
      let start_tmV = this.def_z_data[0][0]
      let end_tmV = this.def_z_data[length][0]
      // 起点不能拖
      if (!dataIndex) return
      let myChart = this.$refs.charts.chart
      let drg_data = myChart.convertFromPixel('grid', pos)
      // 不得超过起始时间范围
      if (drg_data[0] <= start_tmV) return
      if (drg_data[0] >= end_tmV) return
      // 结束时间只能上下拖拽
      if (dataIndex === length) {
        this.def_z_data[dataIndex] = [end_tmV, drg_data[1]]
      } else {
        this.def_z_data[dataIndex] = drg_data
      }
      myChart.setOption({
        series: [{
          id: 'z',
          data: this.def_z_data
        }]
      })
    }

拖拽单线条:

      let myChart = this.$refs.charts.chart
      // 更改原始数据并重绘
      this.def_z_data[dataIndex] = myChart.convertFromPixel('grid', pos)
      
      myChart.setOption({
        series: [{
          id: 'z',
          data: this.def_z_data
        }]
      })

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值