Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
569 views
in Technique[技术] by (71.8m points)

d3.js - Smooth transitioning between tree, cluster, radial tree, and radial cluster layouts

For a project, I need to interactively change hierarchical data layout of a visualization - without any change of the underlying data whatsoever. The layouts capable of switching between themselves should be tree, cluster, radial tree, and radial cluster. And transitioning should be preferably an animation.

I thought that would be relatively easy task with D3. I started, but I got lost in translations and rotations, data bindings, and similar, so I am asking you for help. Also, probably I am doing something not in the spirit of D3, which is bad since I am seeking a clean solution.

I put together a jsfidle, but it is just a starting point, with added radio buttons, convenient small data set, and initial cluster layout - just to help anybody who wants to take a look at this. Thanks in advance!

UPDATE:

I wanted to focus on links only, so I temporary disabled other elements. Building on @AmeliaBR method, following animations are obtained:

enter image description here

Here is updated jsfiddle.

UPDATE 2:

Now with circles: (excuse my choice of colors)

{doom-duba-doom}

enter image description here

Here is one more updated jsfiddle.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't see why it would be that hard so long as all your layouts have the same overall structure of link-paths, circle nodes and text labels.

Just make sure all your objects, including your link paths, have a good data-key that is independent of the data attributes created by the layout functions. Then for each transition, update the data with the results of the appropriate layout function and draw that layout.

I've got the transition to radial tree implemented here: http://jsfiddle.net/YV2XX/5/

Key code:

//Radial Tree layout//
var diameter = 500;
var radialTree = d3.layout.tree()
    .size([360, diameter / 2 ])
    .separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });
var radialDiagonal = d3.svg.diagonal.radial()
    .projection(function(d) { return [d.y, d.x / 180 * Math.PI]; });
function transitionToRadialTree() {
  var nodes = radialTree.nodes(root), //recalculate layout
      links = radialTree.links(nodes);

    svg.transition().duration(1500)
       .attr("transform", "translate(" + (diameter/2)
                 + "," + (diameter/2) + ")");
             //set appropriate translation (origin in middle of svg)

    link.data(links, function(d){
              return d.source.name + d.target.name;})
      .transition().duration(1500)
      .attr("d", radialDiagonal); //get the new radial path

  node.data(nodes, function(d){
              return d.name ;})
      .transition().duration(1500)
      .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; }) 

  node.select("circle")
      .transition().duration(1500)
      .attr("r", 4.5);

  node.select("text")
      .transition().duration(1500)
      .attr("dy", ".31em")
      .attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
      .attr("transform", function(d) { return d.x < 180 ? "translate(8)" : "rotate(180)translate(-8)"; });
};

The layout code is all from http://bl.ocks.org/mbostock/4063550, I've just changed it to be an update instead of an initialization.

Also note that I have moved the variable declaration for root outside of the data-reading method, so it can be re-accessed by the transition functions.

Layout still needs some finessing, but you get the idea.

Now, if you wanted one of the transitions to be a partition, treemap or other layout that doesn't use the node-link structure, they it gets more complicated...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...