首页 > 其他分享 >echarts可拖拽折线图,拐点拖拽/点击定位/整体平移

echarts可拖拽折线图,拐点拖拽/点击定位/整体平移

时间:2024-04-08 15:29:05浏览次数:10  
标签:00 15 myChart echarts let dataIndex 折线图 data 拖拽

1.拐点拖拽 ,只有点击拐点才可以拖拽, 并且限制了只能在当前X轴进行拖拽

// chart
				myChart(){
					const that = this
					let symbolSize = 20;
					let data = new Array();
					let dataReal = new Array();
					//this.real
					let list = this.plan;
					let realList = this.real;
						for (var k = 0; k < 96; k++) {
							var itemdata = new Array();
							itemdata.push(k * 1);
							itemdata.push(list[k]);
							data.push(itemdata);
						}
						for (var k = 0; k < 96; k++) {
							var itemdata = new Array();
							itemdata.push(k * 1);
							itemdata.push(realList[k]);
							dataReal.push(itemdata);
						}
					let myChart = echarts.init(document.getElementById('chart'));
					// 定义折线路径颜色
					let color = 'rgba(135, 206, 250, 0.7)';
					myChart.setOption({
						legend:{
							data: ['实际','预测'],
							top: 'top',
							center: 'center'
						},
						grid: {
							left: '10%',
							right: '10%',
							top: '20%',
							bottom: '20%',
						},
						// tooltip: {
						// 	formatter: function(params) {
						// 		return params.seriesName+': ' + params.data[1].toFixed(3) + '<br>时间' +  ': '+ params.name;
						// 	}
						// },
						xAxis: {
							type: 'category',
							splitNumber: 96, // 设置轴线的刻度数量
							data: ['00:15', '00:30', '00:45', '01:00', '01:15', '01:30', '01:45', '02:00', '02:15', '02:30', '02:45',
								'03:00', '03:15', '03:30', '03:45', '04:00', '04:15', '04:30', '04:45', '05:00', '05:15', '05:30', '05:45',
								'06:00', '06:15', '06:30', '06:45', '07:00', '07:15', '07:30', '07:45', '08:00', '08:15', '08:30', '08:45',
								'09:00', '09:15', '09:30', '09:45', '10:00', '10:15', '10:30', '10:45', '11:00', '11:15', '11:30', '11:45',
								'12:00', '12:15', '12:30', '12:45', '13:00', '13:15', '13:30', '13:45', '14:00', '14:15', '14:30', '14:45',
								'15:00', '15:15', '15:30', '15:45', '16:00', '16:15', '16:30', '16:45', '17:00', '17:15', '17:30', '17:45',
								'18:00', '18:15', '18:30', '18:45', '19:00', '19:15', '19:30', '19:45', '20:00', '20:15','20:30','20:45',
								'21:00','21:15','21:30','21:45','22:00','22:15','22:30','22:45','23:00','23:15','23:30','23:45','24:00'],
						},
						yAxis: {
							name : 'MW',
							minInterval : 1,
							type: 'value',
							axisLine: {
								onZero: false
							}
						},
						series: [
								{
									name:'预测',
									id: 'a',
									type: 'line',
									data: data,
									markPoint: {
										data: [],
										symbol: true,
										symbolSize: symbolSize,
										draggable: true,
									},
									tooltip: {
										show: false  // 禁用 pictorialBar 系列的 tooltip
									},
								},
							{
								name:'实际',
								id: 'b',
								type: 'line',
								data: dataReal,
								markPoint: {
									data: [],
									symbol: true,
									symbolSize: symbolSize,
									draggable: true,
								},
								tooltip: {
									show: false  // 禁用 pictorialBar 系列的 tooltip
								},
							},

						]
					});
					setTimeout(function() {
						myChart.setOption({
							graphic: echarts.util.map(data, function(item, dataIndex) {
								return {
									type: 'circle',
									position: myChart.convertToPixel('grid', item),
									shape: {
										r: symbolSize / 2
									},
									invisible: true,
									draggable: true,
									ondrag: echarts.util.curry(onPointDragging, dataIndex),
									// onm ousemove: echarts.util.curry(showTooltip, dataIndex),
									// onm ouseout: echarts.util.curry(hideTooltip, dataIndex),
									z: 100
								};
							})
						});
					}, 0);
					window.addEventListener('resize', updatePosition);
					myChart.on('dataZoom', updatePosition);

					function updatePosition() {
						myChart.setOption({
							graphic: echarts.util.map(data, function(item, dataIndex) {
								return {
									position: myChart.convertToPixel({ seriesIndex: 0 }, [dataIndex, item])
								};
							})
						});
					}

					function onPointDragging(dataIndex, dx, dy) {
						// console.log(this.position);
						//让X轴保持不变
						var x = data[dataIndex][0]; //去掉这个相关的就是X,Y都变了
						data[dataIndex] = myChart.convertFromPixel('grid', this.position);
						data[dataIndex][0] = x;
						myChart.setOption({
							series: [{
								id: 'a',
								data: data
							}]
						});
						let list = []
						data.forEach(item=>{
							list.push(item[1])
						})
						that.planData = data[dataIndex][1].toFixed(3) + 'MW'
						that.planDate = that.timeData[dataIndex]
						that.realData = that.real[dataIndex].toFixed(3) + 'MW'
						that.realDate = that.timeData[dataIndex]
						setTimeout(()=>{
							that.changeData = list
						},200)
					}

					myChart.getZr().on('click', (params)=> {
						const pointInPixel = [params.offsetX, params.offsetY];

						// 使用 convertFromPixel 方法转换像素坐标值到逻辑坐标系上的点
						let pointInGrid = myChart.convertFromPixel({seriesIndex: 0}, pointInPixel);
						let pointInGrid2 = myChart.convertFromPixel({seriesIndex: 1}, pointInPixel);

						// X 轴数据的索引值
						let xIndex = pointInGrid[0];
						// Y 轴坐标点数值
						let yIndex = pointInGrid2[1];

						// 使用 getOption() 获取图表的 option
						let myOption = myChart.getOption();

						// 获取点击位置的 x 轴对应坐标的名称和 y 轴对应的数据
						let xAxisData = myOption.xAxis[0].data[xIndex];
						let seriesData = myOption.series[0].data[xIndex];
						let seriesRealData = myOption.series[1].data[xIndex];
						this.planData = seriesData[1].toFixed(3) + 'MW'
						this.realData = seriesRealData[1].toFixed(3) + 'MW'
						this.planDate = xAxisData
						this.realDate = xAxisData
					})
				}

2.点击定位,鼠标点击echarts的画布内,自动会将当前鼠标悬停的X轴内的拐点定位到鼠标悬停的位置,实现效果形成一个鼠标直接点击后移动直接绘制的效果。

// 点击定位
chart() {
      this.myChart = echarts.init(document.getElementById('chart'))
      let yValue
      let yValue2
      let dragFlag = false
      document.onmousedown = function(ev) {
        dragFlag = true
      }
      document.onmouseup = function(ev) {
        dragFlag = false
      }
      this.chartOption = {
        title: {
          show: true,
          text: '',
          left: 'center',
          top: 10
        },
        legend: {
          data: ['预测']
        },
        tooltip: {
          trigger: 'axis',
          showContent: true,
          axisPointer: {
            type: 'cross',
            axis: 'x',
            label: {
              backgroundColor: '#283b56',
              formatter: function(params) {
                let html = ''
                if (params.axisDimension === 'y' && params.seriesData.length < 2) {
                  yValue = params.value
                  let temp = parseFloat(yValue).toFixed(3)
                  return temp
                }

                if (params.axisDimension === 'x' && params.seriesData.length < 2) {
                  let value = params.seriesData[0].value
                  let temp = parseFloat(value).toFixed(3)
                  return '预测曲线:' + temp + '\n时间:' + params.value
                } else {
                  let plan
                  let otherLineStr = ''
                  for (let i = 1; i < params.seriesData.length; i++) {
                    plan = parseFloat(params.seriesData[0].data).toFixed(3)
                    let temp = parseFloat(params.seriesData[i].data).toFixed(3)
                    otherLineStr += ('\n' + '对比曲线' + (i) + ':' + temp)
                  }
                  return '预测曲线:' + plan + '\n时间:' + params.value + otherLineStr
                }
              }
            }
          },
          formatter: function(params) {
            if (dragFlag) {
              dragRefresh(params[0].dataIndex, yValue)
            }
          }
        },
        color: this.colors[0],
        grid: {
          left: '3%',
          top: '17%',
          right: '3%',
          bottom: '24%'
        },
        xAxis: {
          data: this.xDataTime,
          splitLine: {
            show: false,
            interval: 0
          }
        },
        yAxis: {
          type: 'value',
          z: 2,
          name: '出力(MW)',
          max: this.yDataMax,
          min: 0,
          nameGap: 35,
          splitLine: {
            lineStyle: {
              color: '#DBDBDB',
              type: 'dashed'
            }
          },
          axisLine: {
            show: true
          },
          axisTick: {
            show: false
          }
        },
        series: [
          {
            id: 'aaa',
            name: '预测',
            data: this.changePlan,
            type: 'line',
            smooth: true,
            symbolSize: 2,
            z: 3,
            width: 3,
            itemStyle: {
              color: this.colors[0],
              emphasis: {
                radius: '30%' // 放大半径,控制为30%即可
              }
            }
          }
        ]
      }

      /**
       * 图形刷新
       * @param index 预测数据索引
       * @param value 预测数据数值
       */
      const dragRefresh = (index, value) => {
        if (value) {
          this.changePlan[index] = Number(value).toFixed(3)
          refresh()
        }
      }

      /**
       * 图形刷新
       */
      const refresh = () => {
        setTimeout(() => {
          this.myChart.setOption({
            series: [{
              id: 'aaa',
              data: this.changePlan,
              itemStyle: {
                color: this.colors[0]
              }
            }
            ]
          })
        })
      }

      this.chartOption && this.myChart.setOption(this.chartOption, true)
      window.addEventListener('resize', () => {
        this.myChart.resize()
      })

    }

3. 整体平移,折现图保持当前的插值与X轴坐标,整体上下平移,范围是根据点击拐点后Y轴移动的大小,实现效果点击折线任意一点,保持当前的折现同时上下平移

chart() {
      let that = this
      let yValue
      let yValue2
      let rawSeries = this.chartOption.series
      this.myChart.dispose()
      // const plan = [20, 21, 20, 23, 26, 25, 26, 25, 28, 29, 30, 29, 28, 27, 26, 25, 24, 23, 23, 21, 20, 21, 22, 23];

      this.myChart = echarts.init(document.getElementById('chart'))

      this.chartOption = {
        legend: {
          data: ['预测']
        },
        // animation:false,
        grid: {
          left: '3%',
          top: '17%',
          right: '3%',
          bottom: '20%'
        },
        tooltip: {
          trigger: 'axis',
          showContent: true,
          axisPointer: {
            type: 'cross',
            axis: 'x',
            label: {
              backgroundColor: '#283b56'
            }
          }
        },
        xAxis: {
          type: 'category',
          data: this.xDataTime
        },
        yAxis: {
          type: 'value',
          name: '出力(MW)',
          max: this.yDataMax,
          min: 0,
          nameGap: 35,
          splitLine: {
            lineStyle: {
              color: '#DBDBDB',
              type: 'dashed'
            }
          },
          axisLine: {
            show: true
          },
          axisTick: {
            show: false
          }
        },
        series: null
      }

      this.chartOption.series = rawSeries
      this.myChart.setOption(this.chartOption, true)

      // 拖拽
      setTimeout(function() {
        that.myChart.setOption({
          graphic: echarts.util.map(that.changePlan, function(item, dataIndex) {
            let position = that.myChart.convertToPixel({ seriesIndex: 0 }, [dataIndex, item])
            return {
              id: dataIndex,
              type: 'circle',
              position: position,
              shape: {
                r: 5
              },
              invisible: true,
              draggable: true,
              ondrag: echarts.util.curry(onPointDragging, dataIndex),
              onm ousemove: echarts.util.curry(showTooltip, dataIndex),
              onm ouseout: echarts.util.curry(hideTooltip, dataIndex),
              ondragend: echarts.util.curry(onPointDragEnd, dataIndex),
              z: 100
            }
          })
        })
      }, 0)
      window.addEventListener('resize', updatePosition)
      that.myChart.on('dataZoom', updatePosition)

      function updatePosition() {
        that.myChart.setOption({
          graphic: echarts.util.map(that.changePlan, function(item, dataIndex) {
            return {
              position: that.myChart.convertToPixel({ seriesIndex: 0 }, [dataIndex, item])
            }
          })
        })
      }

      function showTooltip(dataIndex) {
        that.myChart.dispatchAction({
          type: 'showTip',
          seriesIndex: 0,
          dataIndex: dataIndex
        })
      }

      function hideTooltip(dataIndex) {
        that.myChart.dispatchAction({
          type: 'hideTip'
        })
      }

      function onPointDragging(dataIndex, dx, dy) {
        let math = Number(that.changePlan[dataIndex] - that.myChart.convertFromPixel({ seriesIndex: 0 }, this.position)[1]).toFixed(3)
        for (let i = 0; i < that.changePlan.length; i++) {
          if (math < 0) {
            that.changePlan[i] = (Number(that.changePlan[i]) + Math.abs(Number(math))) >= that.yDataMax ? that.yDataMax : Number(that.changePlan[i]) + Math.abs(Number(math))
          } else {
            that.changePlan[i] = (Number(that.changePlan[i]) - math) <= 0 ? 0 : Number(that.changePlan[i]) - math
          }
        }

        that.myChart.setOption({
          series: [{
            id: 'aaa',
            data: that.changePlan.map(item => {
              return Number(item).toFixed(3)
            })
          }]
        })
      }

      function onPointDragEnd(dataIndex, dx, dy) {
        that.myChart.setOption({
          graphic: echarts.util.map(that.changePlan, function(item, dataIndex) {
            return {
              id: dataIndex,
              position: that.myChart.convertToPixel({ seriesIndex: 0 }, [dataIndex, item])
            }
          })
        })
      }

      window.addEventListener('resize', () => {
        this.myChart.resize()
      })
    }

根据需求也可以将功能整合在一起,点击拖拽效果图:

保持折现平移后的效果图:

标签:00,15,myChart,echarts,let,dataIndex,折线图,data,拖拽
From: https://blog.csdn.net/BaekZh/article/details/137501490

相关文章

  • 前端全栈echarts实时制作。node.js写后端api接口。
    首先先介绍一下我这个实时可视化的流程:先写后端→写html网页结构→echarts画图→获取api接口数据→做实时可视化。总体来说就是要做一个实时可视化。不说怎么多了我直接开始操作,这次可能不会一下全部写完,但后面会接着继续完善此博客呢。一:node.js写api接口非常的简单,直接一......
  • 利用pyecharts实现地图下钻
    参考地址:利用pyecharts实现中国省与市之间的跳转_pyecharts点击地图跳转-CSDN博客代码:importcsvimportjionlpasjiofrompyechartsimportoptionsasoptsfrompyecharts.chartsimportMapfromcollectionsimportCounterimportrandomfrompyecharts.globalsimp......
  • python画带阴影折线图
    (1)#coding=gbkimportmatplotlib.pyplotaspltimportnumpyasnp#创建一些示例数据x=np.linspace(-3,3,60)y_mean=np.sin(x)y_std=np.sin(x)#画折线图b-:蓝色实线plt.plot(x,y_mean,'b-',label='Mean')#填充阴影表示标准差alpha:阴影......
  • 数据可视化高级技术Echarts(快速上手&柱状图&进阶操作)
    目录1.Echarts的配置 2.程序的编码3.柱状图的实现(入门实现)相关属性介绍(进阶):1.标记最大值/最小值2.标记平均值3.柱的宽度4.横向柱状图5.colorByseries系列(需要构造多组数据才能实现,下面有Sale和Sale1两组数据)data系列(同一组数据每个柱状图不同的显示)6.showBackgro......
  • 元素拖拽?一个vue指令搞定
    说在前面......
  • 2-29. 实现拖拽物品交换数据和在地图上生成物品
    修改InventoryManager修改SlotUI解决拖拽结束后高亮显示不正确的问题实现物品扔到地上的效果添加ItemManager修改EventHandler,添加在地图上生成物品的事件在SlotUI上触发事件ItemManager监听事件此外还要在01.Field场景中添加一个ItemParent对象,它的T......
  • 2-28. 创建 DragItem 实现物品拖拽跟随显示
    开始实现拖拽功能添加接口添加DragCanvas另外记得把RaycastTarget取消勾选另外DragItemImage默认可以显示,但是图片需要关闭修改InventoryUI修改Slot_Bag预制体把Image、Amount、Highlight的RaycastTarget关掉这样做的目的是因为后面在拖拽结束的......
  • Avalonia无边框窗体拖拽问题
    一般个人开发都会选择无边框的窗体作为登陆界面,然后在鼠标按下的事件中调用拖拽函数,在WPF中是这样的。但是在Avalonia中按照以上思路之后发现界面上的ComboBox不能用了。。。奇奇怪怪的bug。解决方法如下:无边框窗体实现一下方法:PointerPressed="InputElement_OnPointerPressed......
  • 什么是拖拽式工作流引擎?优点有什么?
    想要提高工作效率,做好企业内部数据资源管理,那么就需要了解当下较为流行和实用的低代码技术平台。随着社会和进步和行业的发展,越来越多的中小企业看到了数字化转型带来了巨大变化和发展优势,借助于低代码技术平台、拖拽式工作引擎的优势特点,可以帮助客户实现发展愿望。那么,什么是拖......
  • Echarts绘制多雷达图
    其实模板和之前发的作品一样,只有一些关键点使它变成了雷达图,我们只需要添加数据和和每个点需要显示的名称,type肯定是要变的下面这个是设置碰到雷达图里的数据就会加粗变亮这个是设置线条颜色的,你可以设置多种线条<!DOCTYPEhtml><html><head><metacharset="utf......