D3 桑基图:添加新节点和 Link 与过渡

D3 Sankey Diagram: Adding New Node and Link with Transition

我正在使用 D3 创建桑基图。我正在尝试使用附加节点和 link 重新绘制图表,并使用过渡将以前的图表动画化为新图表。我能够添加新节点和 link 但旧节点和 links 没有改变位置。由于新节点和 link 可以添加到图中的任何位置,我不想清除和重绘整个 svg,而是使用转换从旧图到新图。绘制桑基图的代码是这样的:

function draw(data){
    // Set the sankey diagram properties
    var sankey = d3sankey()
        .nodeWidth(17)
        .nodePadding(27)
        .size([width, height]);

    var path = sankey.link();
    var graph = data;

    sankey.nodes(graph.nodes)
        .links(graph.links)
        .layout(32);

    sankey.relayout();

    // add in the links
    link.selectAll(".link")
        .data(graph.links)
        .enter().append("path")
        .attr("class", "link")
        .attr("d", path)
        .style("fill", "none")
        .style("stroke", function(d){
            return "grey";
        })
        .style("stroke-opacity", "0.4")
        .on("mouseover", function() { d3.select(this).style("stroke-opacity", "0.7") } )
        .on("mouseout", function() { d3.select(this).style("stroke-opacity", "0.4") } )
        .style("stroke-width", function (d) {
            return Math.max(1, d.dy);
        })
        .sort(function (a, b) {
            return b.dy - a.dy;
        });

    link.transition().duration(750);
    //link.exit();

    // add in the nodes
    var node = nodes.selectAll(".node")
        .data(graph.nodes)
        .enter().append("g")
        .attr("class", "node")
        .attr("transform", function (d) {
            return "translate(" + d.x + "," + d.y + ")";
        });

    // add the rectangles for the nodes
    node.append("rect")
        .attr("height", function (d) {
            return d.dy;
        })
        .attr("width", sankey.nodeWidth())
        .style("fill", function (d) {
            return d.color = color(d.name.replace(/ .*/, ""));
        })
        .style("fill-opacity", ".9")
        .style("shape-rendering", "crispEdges")
        .style("stroke", function (d) {
            return d3.rgb(d.color).darker(2);
        })
        .append("title")
        .text(function (d) {
            return d.name + "\n" + format(d.value);
        });

    // add in the title for the nodes
    node.append("text")
        .attr("x", -6)
        .attr("y", function (d) {
            return d.dy / 2;
        })
        .attr("dy", ".35em")
        .attr("text-anchor", "end")
        .attr("text-shadow", "0 1px 0 #fff")
        .attr("transform", null)
        .text(function (d) {
            return d.name;
        })
        .filter(function (d) {
            return d.x < width / 2;
        })
        .attr("x", 6 + sankey.nodeWidth())
        .attr("text-anchor", "start");

    node.transition().duration(750);

}

JSFiddle

是否可以使用转换添加新节点和link并重新定位 旧节点和 links?

谢谢!

我能够通过将节点和链接移动到新位置来做到这一点。代码是:

var nodes = d3.selectAll(".node")
                .transition().duration(750)
                .attr('opacity', 1.0)
                .attr("transform", function (d) {
                    if(d.node == 3){
                        console.log(d.x, d.y);
                    }
                    return "translate(" + d.x + "," + d.y + ")";
                });

var nodeRects = d3.selectAll(".node rect")
    .attr("height", function (d) {
        if(d.node == 3){
            console.log(d.dy);
        }
        return d.dy;
    })


var links = d3.selectAll(".link")
                .transition().duration(750)
                .attr('d', path)
                .attr('opacity', 1.0)

已更新JSFiddle