D3.js v4.0.0-alpha.35转换不起作用

Tek*_*ill 3 d3.js d3v4 d3.js-v4

我尝试使用最新版本的d3.js 模仿这个可折叠的树,但是我遇到了一些问题.

nodeEnter代码的一部分执行得很好,但无论出于何种原因nodeUpdate,代码的转换部分都不会执行.我查看控制台以确保它不仅仅是一个可见性问题,我没有错误,没有...坐标保持与它们由nodeEnter代码部分启动时相同.我唯一的猜测是,新版本的d3.js发生了变化,我遗漏了一些东西......

var t = d3.transition()
.duration(750)
.ease(d3.easeLinear);

var tree = d3.tree()
  .size([height, width]);

function updateDisplay(source){
  
  var treeData = tree(root).descendants(),
      linkData = treeData.slice(1); 
  
  treeData.forEach(function(d) {
    
    /*Normalize for fixed-depth between levels, so that y value 
    **  stays the same through transition as opposed to being 
    **  an even division of the svg width. */
    d.y = d.depth *180;
    
  });
  
                            
  var node = svg.selectAll("g.node")
                .data(treeData);

  var nodeEnter = node.enter()
                      .append("g")
                        .attr("class", function(d) {return "node" + (d.children ? " node--internal" : " node--leaf");})
                        .attr("transform", function(d) {return "translate(" + source.y0 + "," + source.x0 + ")";});
  
  console.log(nodeEnter);
  
  nodeEnter.append("rect")
            .attr("x", 3)
            .attr("y", -10)
            .attr("rx", 1e-6)//goes to 8 after transition
            .attr("ry", 1e-6)//goes to 8 after transition
            .attr("width", 1e-6)
            .attr("height", 1e-6)
            .attr("transform", function(d) {return d.children ? "scale(-1,1) translate(-20,0)" : "";})
            .attr("style", "fill:#EEEEEE;filter:url(#dropshadow)");

  nodeEnter.append("text")
            .attr("dy", 3)
            .attr("x", function(d) {return d.children ? -8 : 30;})
            .style("text-anchor", function(d) {return d.children ? "end" : "start";})
            .text(function(d) {return d.id;})
            .each(function(d) {d.NameWidth = this.getBBox().width;})
            .style("fill-opacity", 1e-6);
  

  var avatar = nodeEnter.append("g").attr("style", "filter:url(#dropshadow)");

  avatar.append("clipPath")
          .attr("id", "avatarClip")
          .append("circle")
            .attr("cx", 1e-6)//12.5
            .attr("cy", 1e-6)//12.5
            .attr("r", 1e-6);//12.5

  avatar.append("circle")
          .attr("cx", 1e-6)//12.5
          .attr("cy", 1e-6)//12.5
          .attr("r", 1e-6)//12.5
          .attr("style", "fill:white")
          .attr("transform", "translate(0,-12)");

  avatar.append("image")
          .attr("xlink:href", function(d) {return (d.data.img ? d.data.img : "https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-342/ic_person_black_48px.svg");})
          .attr("clip-path", "url(#avatarClip)")
          .attr("class", function(d) {return (d.children ? "avatar--manager" : "");})
          .attr("width", 25)
          .attr("height", 25)
          .attr("transform", "translate(0,-12)");  
  
  avatar.on("click", function(d) {toggle(d);});
  
  //TRANSITION OF NODES TO NEW POSITIONS
  var nodeUpdate = node.transition(t)
                        .attr("class", function(d) {return "node" + (d.children ? " node--internal" : " node--leaf");})
                        .attr("transform", function(d) {return "translate(" + d.y + "," + d.x + ")";});
  
  nodeUpdate.select("text")
    .attr("x", function(d) {return d.children ? -8 : 30;})
    .style("text-anchor", function(d) {return d.children ? "end" : "start";})
    .text(function(d) {return d.id;})
    .style("fill-opacity", 1);

  nodeUpdate.select("rect")
              .attr("transform", function(d) {return d.children ? "scale(-1,1) translate(-20,0)" : "";})
              .attr("height", 20)
              .attr("width", function(d) {return (d.NameWidth + 35);});
  
  nodeUpdate.select("clipPath")
              .attr("cx", 12.5)
              .attr("cy", 12.5)
              .attr("r", 12.5);
  
  nodeUpdate.select("circle")
             .attr("cx", 12.5)
             .attr("cy", 12.5)
             .attr("r", 12.5);

  nodeUpdate.select("image")
    .attr("xlink:href", function(d) {return (d.data.img ? d.data.img : "https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-342/ic_person_black_48px.svg");})
    .attr("clip-path", "url(#avatarClip)")
    .attr("class", function(d) {return (d.children ? "avatar--manager" : "");});
  
  //TRANSITIONING EXITING NODES
  var nodeExit = node.exit()
                     .transition(t)
                     .attr("transform", function(d) {return "translate(" + source.y + "," + source.x + ")";})
                     .remove();
  
  
 
  /*var link = svg.selectAll(".link")
                 .data(linkData);*/
  

  // Stash the old positions for transition.
   root.each(function(d) {
    d.x0 = d.x;
    d.y0 = d.y;
  });
  
}
Run Code Online (Sandbox Code Playgroud)

PS:我的代码不是上面链接的精确复制品,在设计时我把自己的旋转...

alt*_*lus 10

从v3到v4的输入和更新选择已经发生了概念上的变化.在v3中,输入选择自动合并到更新选择中,您必须selection.merge()从v4向上明确调用以获得相同的结果.

selection.enter()v3 的文档告诉我们:

在追加或插入时,输入选择会合并到更新选择中.

另一方面,v4的相同方法的文档如下:

输入选择通常仅暂时用于附加元素,并且通常在附加后与更新选择合并,使得修改可以应用于输入和更新元素.

看看这个使用v3的简化示例,它应该没有任何意外:

var update = d3.select("svg").selectAll("circle")
  .data([1]);
  
var enter = update.enter()
  .append("circle")
    .attr("cx", "50")
    .attr("cy", "50")
    .attr("r", "20")
    .attr("fill", "red");
    
 update
   .transition().duration(2000)
     .attr("fill", "blue");
 
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg></svg>
Run Code Online (Sandbox Code Playgroud)

但是,对v4执行相同操作需要稍加修改:

var update = d3.select("svg").selectAll("circle")
  .data([1]);
  
var enter = update.enter()
  .append("circle")
    .attr("cx", "50")
    .attr("cy", "50")
    .attr("r", "20")
    .attr("fill", "red");
    
 update
   .merge(enter)  // This merges both the enter and the update selection
   .transition().duration(2000)
     .attr("fill", "blue");
Run Code Online (Sandbox Code Playgroud)
<script src="https://d3js.org/d3.v4.min.js"></script>

<svg></svg>
Run Code Online (Sandbox Code Playgroud)

注释掉该.merge()行会显示您描述的效果,因为更新选择将为空,即使您之前使用输入选择输入了新元素.