html5 可调整节点的线,vue+echarts实现可拖动节点的折线图(支持拖动方向和上下限的设置)...
时间: 2024-02-05 07:10:50 浏览: 159
vue+echarts实现可拖动节点的折线图(支持拖动方向和上下限的设置)
要实现可调整节点的线,可以考虑使用SVG元素和JavaScript来实现。以下是一个基本的实现步骤:
1. 创建SVG元素,包括线和圆圈节点
```html
<svg id="svg-container">
<line id="line" x1="100" y1="100" x2="300" y2="100"></line>
<circle id="start-node" cx="100" cy="100" r="6"></circle>
<circle id="end-node" cx="300" cy="100" r="6"></circle>
</svg>
```
2. 使用JavaScript获取SVG元素和节点,并添加事件监听器
```javascript
const svgContainer = document.getElementById('svg-container');
const line = document.getElementById('line');
const startNode = document.getElementById('start-node');
const endNode = document.getElementById('end-node');
startNode.addEventListener('mousedown', startDrag);
endNode.addEventListener('mousedown', startDrag);
svgContainer.addEventListener('mousemove', drag);
svgContainer.addEventListener('mouseup', endDrag);
```
3. 编写事件处理函数,实现节点拖动和线的更新
```javascript
let activeNode = null;
function startDrag(event) {
activeNode = event.target;
}
function drag(event) {
if (activeNode) {
const rect = svgContainer.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
activeNode.setAttribute('cx', x);
activeNode.setAttribute('cy', y);
updateLine();
}
}
function endDrag() {
activeNode = null;
}
function updateLine() {
const x1 = startNode.getAttribute('cx');
const y1 = startNode.getAttribute('cy');
const x2 = endNode.getAttribute('cx');
const y2 = endNode.getAttribute('cy');
line.setAttribute('x1', x1);
line.setAttribute('y1', y1);
line.setAttribute('x2', x2);
line.setAttribute('y2', y2);
}
```
4. 可以根据需求修改代码,例如添加限制条件、计算线的角度等等。
上述代码只是一个简单的示例,如果要实现更复杂的功能,可以考虑使用现有的图表库,例如ECharts。以下是一个使用Vue和ECharts实现可拖动节点的折线图的示例代码:
```vue
<template>
<div ref="chart" style="height: 400px;"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
data() {
return {
chartData: {
nodes: [
{ id: 'A', x: 100, y: 100 },
{ id: 'B', x: 300, y: 100 },
],
links: [
{ source: 'A', target: 'B' },
],
},
activeNode: null,
};
},
mounted() {
this.initChart();
},
methods: {
initChart() {
const chart = echarts.init(this.$refs.chart);
chart.setOption({
series: [
{
type: 'graph',
layout: 'none',
draggable: true,
roam: true,
symbolSize: 50,
edgeSymbol: ['none', 'arrow'],
edgeLabel: {
show: true,
},
data: this.chartData.nodes.map(node => ({
id: node.id,
x: node.x,
y: node.y,
})),
edges: this.chartData.links.map(link => ({
source: link.source,
target: link.target,
})),
lineStyle: {
width: 2,
},
},
],
});
chart.on('mousedown', this.startDrag);
chart.on('mousemove', this.drag);
chart.on('mouseup', this.endDrag);
window.addEventListener('mouseup', this.endDrag);
},
startDrag(event) {
if (event.target.dataType === 'node') {
this.activeNode = event.target;
}
},
drag(event) {
if (this.activeNode) {
const chart = this.$refs.chart.getEchartsInstance();
const node = this.chartData.nodes.find(n => n.id === this.activeNode.id);
const { offsetX, offsetY } = chart.convertFromPixel({ seriesIndex: 0 }, [event.offsetX, event.offsetY]);
node.x = offsetX;
node.y = offsetY;
this.updateLinks();
}
},
endDrag() {
this.activeNode = null;
},
updateLinks() {
const chart = this.$refs.chart.getEchartsInstance();
const nodes = chart.getOption().series[0].data;
const links = chart.getOption().series[0].edges;
this.chartData.links.forEach(link => {
const sourceNode = nodes.find(node => node.id === link.source);
const targetNode = nodes.find(node => node.id === link.target);
const [x1, y1] = chart.convertToPixel({ seriesIndex: 0 }, [sourceNode.x, sourceNode.y]);
const [x2, y2] = chart.convertToPixel({ seriesIndex: 0 }, [targetNode.x, targetNode.y]);
link.lineStyle = {
width: 2,
curveness: 0.2,
type: 'solid',
};
link.label = {
show: true,
position: 'middle',
};
link.data = [
{ coord: [x1, y1] },
{ coord: [x2, y2] },
];
});
chart.setOption({
series: [{
data: nodes,
edges: links,
}],
});
},
},
};
</script>
```
这个示例使用了ECharts的图形组件和坐标系组件,实现了可以拖动节点的折线图,并且支持拖动方向和上下限的设置。具体实现过程可以参考ECharts的官方文档和示例代码。
阅读全文