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

时间:2018-07-02 01:09:09

标签: javascript d3.js force-layout

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

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();

1 个答案:

答案 0 :(得分:2)

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

之前:

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);