如何修复 d3 树的 link 转换

how to fix link transition for d3 tree

links 之间的过渡在我的 d3 树图中对我不起作用它是一个具有矩形节点的垂直树所以我编辑了 attr 来塑造 link 以适合我的图

原代码:

var link = svg.selectAll('path.link')
      .data(links, function(d) { return d.id; });

  // Enter any new links at the parent's previous position.
  var linkEnter = link.enter().insert('path', "g")
      .attr("class", "link")
      .attr('d', function(d){
        var o = {x: source.x0, y: source.y0}
        return diagonal(o, o)
      });

  // UPDATE
  var linkUpdate = linkEnter.merge(link);

  // Transition back to the parent element position
  linkUpdate.transition()
      .duration(duration)
      .attr('d', function(d){ return diagonal(d, d.parent) });

  // Remove any exiting links
  var linkExit = link.exit().transition()
      .duration(duration)
      .attr('d', function(d) {
        var o = {x: source.x, y: source.y}
        return diagonal(o, o)
      })
      .remove();

function diagonal(s, d) {

    path = `M ${s.y} ${s.x}
            C ${(s.y + d.y) / 2} ${s.x},
              ${(s.y + d.y) / 2} ${d.x},
              ${d.y} ${d.x}`

    return path
  }

已更新代码,其中包含直接添加为属性的可操作对角线:

// Update the links...
            var link = svg.selectAll('path.link')
                .data(links, function(d) { return d.id; });

            // Enter any new links at the parent's previous position.
            var linkEnter = link.enter().insert('path', "g")
                .attr("class", "link")
                .attr("d", function(d) {
                return "M" + (d.x  + rectW / 2) +  "," + (d.y + rectH / 2)
                    + "C" + (d.x  + rectW / 2) + "," + (d.y + d.parent.y) / 2
                    + " " + (d.parent.x + rectW / 2) + "," +  (d.y + d.parent.y) / 2
                    + " " + (d.parent.x + rectW / 2) + "," + (d.parent.y + rectH / 2);
                });

            // UPDATE
            var linkUpdate = linkEnter.merge(link);

            // Transition back to the parent element position
            linkUpdate.transition()
                .duration(0)
                .attr("d", function(d) {
                return "M" + (d.x  + rectW / 2) +  "," + (d.y + rectH / 2)
                    + "C" + (d.x  + rectW / 2) + "," + (d.y + d.parent.y) / 2
                    + " " + (d.parent.x + rectW / 2) + "," +  (d.y + d.parent.y) / 2
                    + " " + (d.parent.x + rectW / 2) + "," + (d.parent.y + rectH / 2);
                })

            // Remove any exiting links
            var linkExit = link.exit().transition()
                .duration(duration)
                .attr("d", function(d) {
                return "M" + (d.x  + rectW / 2) +  "," + (d.y + rectH / 2)
                    + "C" + (d.x  + rectW / 2) + "," + (d.y + d.parent.y) / 2
                    + " " + (d.parent.x + rectW / 2) + "," +  (d.y + d.parent.y) / 2
                    + " " + (d.parent.x + rectW / 2) + "," + (d.parent.y + rectH / 2);
                })
                .remove();

我注意到在我的更新代码中塑造 links 的属性对于 linkEnter、linkUpdateTransition 和 linkExit 是相同的,但对于linkUpdateTransition 的原始代码是不同的,因为我几乎通过跟踪和错误得到了我的 attr 我不确定如何调整 linkUpdateTransition attr 以实现平滑过渡

不确定这是否对任何人有帮助,但我最终弄明白了,结果证明它是我更新的代码和原始代码的组合,下面我将放置工作链接部分

            // Update the links...
            var link = svg.selectAll('path.link')
                .data(links, function(d) { return d.id; });

            // Enter any new links at the parent's previous position.
            var linkEnter = link.enter().insert('path', "g")
                .attr("class", "link")
                .attr('d', function(d) {
                    var o = {x: source.x0, y: source.y0,};
                    return diagonal(o, o);
                });

            // UPDATE
            var linkUpdate = linkEnter.merge(link);

            // Transition back to the parent element position
            linkUpdate.transition()
                .duration(duration)
                .attr('d', function(d) { return diagonal(d, d.parent); });

            // Remove any exiting links
            var linkExit = link.exit().transition()
                .duration(duration)
                .attr('d', function(d) {
                    var o = {x: source.x, y: source.y};
                    return diagonal(o, o);
                })
                .remove();

             // Creates a curved (diagonal) path from parent to the child nodes
             function diagonal(s, d) {
                path = 'M ' + (s.x + rectW / 2) + ' ' + (s.y + rectH / 2) +
                        'C ' + (s.x + rectW / 2 ) + ' ' + (s.y + d.y) / 2 +
                        ', ' + (d.x + rectW / 2) + ' ' + (s.y + d.y) / 2  +
                        ', ' + (d.x + rectW / 2) + ' ' + (d.y + rectH / 2);
                return path;
            }