gpt4 book ai didi

javascript - 更新期间不会删除 d3 图表中的旧节点

转载 作者:行者123 更新时间:2023-12-01 01:54:52 28 4
gpt4 key购买 nike

我正在尝试制作一个力定向图,其中根据需要添加和删除节点和链接。但是,虽然图表正确更新了添加/删除的链接和节点,但所有旧节点仍然可见。

Screenshot

这是更新函数。我尝试了各种教程,重新安排了代码,仔细检查了正在更新的数据是否正确(即 this.dataNodes 正在变异,但完全替换对象也不起作用)等。老实说,我不知道什么我应该继续寻找。

 // ADDING LINKS
this.link = this.linkGroup.selectAll("path")
.data(this.dataLinks, (link) => {
return link.target.id + link.source.id
});

this.link.exit().remove();

const linkEnter = this.link.enter()
.append("path")
.attr("stroke-width", 2)
.style("stroke", "#ccc")
.style('marker-start', (d) => d.sync ? 'url(#start-arrow)' : '')
.style('marker-end', (d) => 'url(#end-arrow)');


this.link = linkEnter.merge(this.link);

// ADDING NODES
this.node = this.nodeGroup.selectAll(".nodes")
.data(this.dataNodes, function (node) { return node.id });

this.node.exit().remove();

const nodeEnter = this.node.enter()
.append("g")
.call(this.dragAndDrop);

// Main circle
nodeEnter.append("circle")
.attr("r", 10)
.attr("fill", "grey")
// ADDING CHARACTER NAMES
nodeEnter.append("text")
.attr("x", 12)
.attr("dy", ".35em")
.text(function (d) {return d.title;});

this.node = nodeEnter.merge(this.node);

this.simulation.nodes(this.dataNodes).on("tick", this.tickActions );
this.simulation.force('link').links(this.dataLinks);
this.simulation.alphaTarget(1).restart();

编辑:首次创建力图时会调用此代码。 this.updateSimulation 是上面的函数,渲染没有问题。再次调用它,所有先前创建的节点都保留在图中。

this.svg = d3.select('#relationship-chart')
.append('svg')
.attr('width', this.width)
.attr('height', this.height);


// GROUPS
this.linkGroup = this.svg.append("g").attr("class", "links");
this.nodeGroup = this.svg.append("g").attr("class", "nodes");


// MAIN SIMULATION
this.link_force = d3.forceLink()
.id(function(d) { return d.id; })
.distance(100);

this.simulation = d3.forceSimulation()
.force("link", this.link_force)
.force("charge", d3.forceManyBody().strength(-200))
.force('center', d3.forceCenter(this.width / 2, this.height / 2))
//.force('collide', d3.forceCollide(25))
.force("x", d3.forceX())
.force("y", d3.forceY())
.alphaTarget(1);

// MISC DEFINTIONS
this.dragAndDrop = d3.drag()
.on("start", this.dragstarted)
.on("drag", this.dragged)
.on("end", this.dragended);

// ADDING ARROWS
this.svg.append('svg:defs').append('svg:marker')
.attr('id', 'end-arrow')
.attr('viewBox', '0 -5 10 10')
.attr('refX', 7)
.attr('markerWidth', 4)
.attr('markerHeight', 4)
.attr('orient', 'auto')
.append('svg:path')
.attr('d', 'M0,-5L10,0L0,5')
.attr('fill', '#ccc');

this.svg.append('svg:defs').append('svg:marker')
.attr('id', 'start-arrow')
.attr('viewBox', '0 -5 10 10')
.attr('refX', 1)
.attr('markerWidth', 4)
.attr('markerHeight', 4)
.attr('orient', 'auto')
.append('svg:path')
.attr('d', 'M10,-5L0,0L10,5')
.attr('fill', '#ccc');


this.updateSimulation();

最佳答案

结果我选择的是父元素类而不是子元素类。我向创建的节点添加了一个类,这解决了问题。

之前:

this.node = this.nodeGroup.selectAll(".nodes")
.data(this.dataNodes, function (node) { return node.id });

this.node.exit().remove();

const nodeEnter = this.node.enter()
.append("g")
.call(this.dragAndDrop);

之后:

this.node = this.nodeGroup.selectAll(".onenode")
.data(this.dataNodes, (node) => { return node.id });

this.node.exit().remove();

const nodeEnter = this.node.enter()
.append("g")
.attr("class", "onenode")
.call(this.dragAndDrop);

关于javascript - 更新期间不会删除 d3 图表中的旧节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51128115/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com