可交互式且存在多条折线分别拖动的图表
示例图如下,以下图中的每个点都可分别拖动
以下为代码
<template>
<div>
<div ref="sszs" style="height:400px;"></div>
</div>
</template>
<script>
var symbolSize = 10;
var color = [
"#c23531",
"#2f4554",
"#61a0a8",
"#d48265",
"#91c7ae",
"#749f83",
"#ca8622",
"#bda29a",
"#6e7074",
"#546570",
"#c4ccd3"
];
var data = [[0, 22], [10, 38], [20, 60], [30, 90], [40, 88]];//数据格式
let arr = [];
let dataarr = [];
for (let i = 0; i < 20; i++) {
arr.push([
[0, Math.round(Math.random() * 100)],
[10, Math.round(Math.random() * 100)],
[20, Math.round(Math.random() * 100)],
[30, Math.round(Math.random() * 100)],
[40, Math.round(Math.random() * 100)]
]);
}
arr.forEach((el, i) => {
dataarr.push({
name: "b" + i,
id: "b" + i,
type: "line",
symbol: i > 10 ? "none" : "emptyCircle",
symbolSize: symbolSize,
data: el,
lineStyle: {
width: 2,
color: i > 10 ? "#999" : color[i]
}
});
});
function reduceDimension(arr) {
return Array.prototype.concat.apply([], arr);//数据降维
}
import echarts from "echarts";
export default {
data() {
return {
option: {
title: {
text: "Try Dragging these Points"
},
//测试legend的代码,没找到合适的解决办法
// legend: {
// data: ["b0", "b1"],
// left: "center",
// // bottom: '10%',
// itemWidth: 10, //图例的宽度
// itemHeight: 10, //图例的高度
// textStyle: {
// //图例文字的样式
// color: "#999",
// fontSize: 16
// },
// formatter: function(a) {
// console.log(a, "===");
// return datax[a.split("b")[1]];
// },
// z: 2000
// },
tooltip: {
triggerOn: "none",
formatter: function(params) {
return (
"X: " +
params.data[0].toFixed(2) +
"<br>Y: " +
params.data[1].toFixed(2)
);
}
},
grid: {},
xAxis: {
type: "value",
axisLine: {
onZero: false
}
},
yAxis: {
type: "value",
axisLine: {
onZero: false
}
},
series: dataarr
},
chart: [],
obj: {}
};
},
mounted() {
let that = this;
let myChart = echarts.init(this.$refs.sszs);
function updatePosition() {
myChart.setOption({
graphic: reduceDimension(
arr.map((el, i) =>
echarts.util.map(el, function(item, dataIndex) {
return {
position: myChart.convertToPixel("grid", item)
};
})
)
)
});
}
function onPointDragend(dataIndex, i) {
arr[i][dataIndex] = myChart.convertFromPixel("grid", this.position);
//执行保存数据相关操作
}
function showTooltip(dataIndex, b) {
myChart.dispatchAction({
type: "showTip",
seriesIndex: b,
dataIndex: dataIndex
});
}
function hideTooltip(dataIndex) {
myChart.dispatchAction({
type: "hideTip"
});
}
function onPointDragging(dataIndex, dx, dy) { //dx,dy本来以为有默认参数,结果没有,但echarts demo上面有,咱也不知道是啥,也没地问
let origin = myChart.convertToPixel("grid", arr[dx][dataIndex]);
if (this.position[1] > 340) {//控制上下拖动范围 跟ref高度有关
this.position[1] = 340;
} else if (this.position[1] < 60) {
this.position[1] = 60;
}
this.position[0] = origin[0];
arr[dx][dataIndex] = myChart.convertFromPixel("grid", this.position);
myChart.setOption({//图表重绘
series: [
{
id: "b" + dx,
data: arr[dx]
}
]
});
}
window.onresize = myChart.resize;
myChart.setOption(this.option);
var num = 0;
setTimeout(function() {
// Add shadow circles (which is not visible) to enable drag.
myChart.setOption({
graphic: reduceDimension( //绘制多条线的关键!关键!关键!,自己套数据格式
arr.map((el, i) => {
if (i > 10) {//筛选拖动线的条件,可自行配置
return;
}
return echarts.util.map(el, 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, i),
ondragend: echarts.util.curry(onPointDragend, dataIndex, i),
onmousemove: echarts.util.curry(showTooltip, dataIndex, i),
onmouseout: echarts.util.curry(hideTooltip, dataIndex),
z: 100
};
});
})
)
});
}, 0);
window.addEventListener("resize", updatePosition);
}
};
</script>
指导思想即 折线和点的关联并不密切,点的坐标是通过数据确定的,所以数据格式不好轻易变动,这也是为什么有些麻烦的地方难处理的原因,重新绘制原理一样。
以上仅为鄙人拙见,如有雷同不胜荣幸,欢迎各位大佬指指点点。
存在的问题
1,legend以及x轴label不好处理 2,线条过多有明显性能问题