这篇博文主要是利用echarts实现两条以及多条可拖动节点的曲线,demo脱胎于官方demo,在官方demo的基础上添加了另一条曲线。因为之前写过一篇在vue中使用echarts实现可拖动节点的折线图,并可配置拖动方向及拖动上下限,所以本篇文章以最简单的方式说明如何实现多条曲线的可拖动,故不再实现其他配置,如果对上下限和拖动方向需要控制的同学可以参考我的另一篇博文:https://www.cnblogs.com/p-l-u-m/p/10691684.html;同时如果有问题或建议欢迎留言探讨。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="https://cdn.bootcss.com/echarts/4.3.0/echarts-en.common.min.js"></script> </head> <body> <!-- 为ECharts准备一个具备大小(宽高)的Dom --> <div id="main" style="width: 600px;height:400px;"></div> <script> // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('main')); var symbolSize = 20; var data1 = [[-90, -10], [-30, -10], [10, -20], [30, -10], [60, -10]]; // 第一条线 var data2 = [[-90, 10], [-30, 10], [10, 20], [30, 10], [60, 10]]; // 第二条线,多天线类推 var option = { // 基本配置,画曲线 title: { text: 'Try Dragging these Points' }, /* tooltip: { triggerOn: 'none', formatter: function (params) { return 'X: ' + params.data[0].toFixed(2) + '<br>Y: ' + params.data[1].toFixed(2); } }, */ grid: { }, xAxis: { min: -100, max: 80, type: 'value', axisLine: { onZero: false } }, yAxis: { min: -30, max: 60, type: 'value', axisLine: { onZero: false } }, dataZoom: [ { type: 'slider', xAxisIndex: 0, filterMode: 'empty' }, { type: 'slider', yAxisIndex: 0, filterMode: 'empty' }, { type: 'inside', xAxisIndex: 0, filterMode: 'empty' }, { type: 'inside', yAxisIndex: 0, filterMode: 'empty' } ], series: [ { id: 'a', type: 'line', smooth: true, symbolSize: symbolSize, data: data1 }, { id: 'b', type: 'line', smooth: true, symbolSize: symbolSize, data: data2 } ] }; myChart.setOption(option) setTimeout(function () { // 在图上添加图层 myChart.setOption({ graphic: echarts.util.map(data1.concat(data2), function (item, dataIndex) { // 此处需要把两条曲线的数组拼成一个数组进行遍历,多条曲线类似 return { type: 'circle', position: myChart.convertToPixel('grid', item), shape: { cx: 0, cy: 0, r: symbolSize / 2 }, invisible: true, draggable: true, ondrag: echarts.util.curry(onPointDragging, dataIndex), // 添加拖动的回调 // onmousemove: echarts.util.curry(showTooltip, dataIndex), // onmouseout: echarts.util.curry(hideTooltip, dataIndex), z: 100 }; }) }); }, 0); myChart.on('dataZoom', updatePosition); // 这是放大缩小,与本例要说明的无关 function updatePosition() { myChart.setOption({ graphic: echarts.util.map(data1, function (item, dataIndex) { return { position: myChart.convertToPixel('grid', item) }; }) }); } function showTooltip(dataIndex) { myChart.dispatchAction({ type: 'showTip', seriesIndex: 0, dataIndex: dataIndex }); } function hideTooltip(dataIndex) { myChart.dispatchAction({ type: 'hideTip' }); } // 拖动的处理函数,因为把所有的曲线数组拼成了一个数组,所以添加的图层是一个整体,此处需要拆分图层,还原为两条曲线 function onPointDragging(dataIndex, dx, dy) { if (dataIndex <= (data1.length - 1)) { // 通过索引判断此圆圈覆盖的是哪条曲线 data1[dataIndex] = myChart.convertFromPixel('grid', this.position); // 将坐标值(x, y)还原为数组的项[a,b] // 更新图表 myChart.setOption({ series: [{ id: 'a', data: data1 }] }); } else { data2[dataIndex - (data1.length - 1)] = myChart.convertFromPixel('grid', this.position); myChart.setOption({ series: [{ id: 'b', data: data2 }] }); } } function onPointDragging2(dataIndex, dx, dy) { data2[dataIndex] = myChart.convertFromPixel('grid', this.position); // Update data myChart.setOption({ series: [{ id: 'b', data: data2 }] }); } </script> </body> </html>