我正在尝试用连接线实现拖放功能。连接线有一个起点([x,y]),当点击鼠标时会收集该点,还有一个目标点([x,y]),该点跟随鼠标位置,并在拖动元素时不断更新。项目使用Vue.JS和VUEX存储,并用于连接线D3.js(linkHorizontal方法https://bl.ocks.org/shivasj/b3fb218a556bc15e36ae3152d1c7ec25)。
在主组件中,我有一个插入SVG的div:
<div id="svg_lines"></div>
在main.js文件中,我观察当前鼠标位置(targetPos),从VUEX存储中获取起始位置(sourcePos),并将其传递给connectTheDots(sourcePos,targetPos)。
new Vue({
router,
store,
render: (h) => h(App),
async created() {
window.document.addEventListener('dragover', (e) => {
e = e || window.event;
var dragX = e.pageX, dragY = e.pageY;
store.commit('setConnMousePos', {"x": dragX, "y": dragY});
let sourcePos = this.$store.getters.getConnStartPos;
let targetPos = this.$store.getters.getConnMousePos;
// draw the SVG line
connectTheDots(sourcePos, targetPos);
}, false)
},
}).$mount('#app');
connectTheDots()函数接收sourcePos和targetPos作为参数,并更新D3 linkHorizontal的目标位置。
function connectTheDots(sourcePos, targetPos) {
const offset = 2;
const shapeCoords = [{
source: [sourcePos.y + offset, sourcePos.x + offset],
target: [targetPos.y + offset, targetPos.x + offset],
}];
let svg = d3.select('#svg_lines')
.append('svg')
.attr('class', 'test_svgs');
let link = d3.linkHorizontal()
.source((d) => [d.source[1], d.source[0]])
.target((d) => [d.target[1], d.target[0]]);
function render() {
let path = svg.selectAll('path').data(shapeCoords)
path.attr('d', function (d) {
return link(d) + 'Z'
})
path.enter().append('svg:path').attr('d', function (d) {
return link(d) + 'Z'
})
path.exit().remove()
}
render();
}
我偷了/修改了这篇文章的代码How to update an svg path with d3.js,但无法让它正常工作。而不是更新路径,函数只是不断添加SVG。见附件图片:
Web app: Multiple SVGs are drawn
Console: Multiple SVGs are added to element
我错过了什么?
1条答案
按热度按时间7hiiyaii1#
@BKalra帮我解决了这个问题。
此行会不断追加新的SVG:
所以我从connectTheDots()函数中删除了它。
下面是我的解决方案:
在主组件中,我添加了一个SVG,路径为:
在connectTheDots()函数中,我不需要再追加任何内容,我只需要绘制SVG并更新其路径: