在树,群集,径向树和径向群集布局之间平滑过渡 [英] Smooth transitioning between tree, cluster, radial tree, and radial cluster layouts

查看:565
本文介绍了在树,群集,径向树和径向群集布局之间平滑过渡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于项目,我需要交互式更改可视化的分层数据布局,而不会对基础数据进行任何更改。能够在它们之间切换的布局应该是树,簇,径向树和径向簇。



我认为这是一个相对容易的任务, D3 。我开始,但我失去了翻译和旋转,数据绑定等类似,所以我要求你的帮助。也许,我可能是在做一些不是D3的精神,这是坏的,因为我寻求一个干净的解决方案。



我把一个。 / p>

更新2:





{doom-duba-doom}





这里是一个更新的jsfiddle

解决方案

我不明白为什么只要你的所有布局都具有相同的链接路径,圆节点和文本标签的整体结构,这将是困难的。



只要确保所有对象(包括您的链接路径)都具有与布局函数创建的数据属性无关的良好数据键。然后对于每个转换,用适当的布局函数的结果更新数据并绘制该布局。



我已经实现了到径向树的过渡: http://jsfiddle.net/YV2XX/5/



键码:

  //径向树布局// 
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),//重新计算布局
links = radialTree.links(nodes)

svg.transition()。duration(1500)
.attr(transform,translate(+(diameter / 2)
+,+ / 2)+));
//设置适当的翻译(在svg中间的原点)

link.data(links,function(d){
return d.source.name + d.target。 name;})
.transition()。duration(1500)
.attr(d,radialDiagonal); //获取新的径向路径

node.data(nodes,function(d){
return d.name;})
.transition
.attr(transform,function(d){returnrotate(+(dx - 90)+)translate(+ dy +);})

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 dx< 180?start:end;})
.attr(transform,function(d){return dx< 180 ?translate(8):rotate(180)translate(-8);});
};

布局代码全部来自 http://bl.ocks.org/mbostock/4063550 ,我刚刚将其更改为更新而不是初始化。



还要注意,我已经移动了数据读取方法之外的 root 的变量声明,因此可以通过转换重新访问功能。



布局仍然需要一些精巧,但是你的想法。



你想要的转换之一是一个分区,树形图或其他布局,不使用节点链接结构,它变得更复杂...


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:

Here is updated jsfiddle.

UPDATE 2:

Now with circles: (excuse my choice of colors)

{doom-duba-doom}

Here is one more updated jsfiddle.

解决方案

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...

这篇关于在树,群集,径向树和径向群集布局之间平滑过渡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆