树,集群,径向树和径向集群布局之间的平滑过渡

时间:2014-01-05 05:20:42

标签: d3.js hierarchy hierarchical-data dendrogram

对于项目,我需要以交互方式更改可视化的分层数据布局 - 无需任何基础数据的任何更改。能够在它们之间切换的布局应该是树,簇,径向树和径向簇。转换应该最好是一个动画。

我认为使用D3这将是相对容易的任务。我开始了,但是我在翻译和轮换,数据绑定等方面迷失了,所以我向你寻求帮助。此外,我可能正在做一些不符合D3精神的事情,因为我正在寻求一个干净的解决方案,所以这很糟糕。

我整理了一个jsfidle,但它只是一个起点,添加了单选按钮,方便的小数据集和初始群集布局 - 只是为了帮助任何想要看一眼的人。提前谢谢!

更新

我只想专注于链接,所以我暂时禁用其他元素。在@AmeliaBR方法的基础上,获得以下动画:

enter image description here

这是updated jsfiddle

更新2:

现在有了圈子:(请原谅我选择的颜色)

{末日毒霸-末日}

enter image description here

这是one more updated jsfiddle

2 个答案:

答案 0 :(得分:11)

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

确保所有对象(包括链接路径)都具有良好的数据键,该数据键独立于布局函数创建的数据属性。然后,对于每个转换,使用相应布局函数的结果更新数据并绘制该布局。

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

密码:

//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)"; });
};

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

另请注意,我已将root的变量声明移到数据读取方法之外,因此可以通过转换函数重新访问它。

布局仍然需要一些精力,但你明白了。

现在,如果你想要的转变之一是不使用节点连杆结构分区,树图或其他布局,他们就变得更为复杂...

答案 1 :(得分:5)

我没有足够的声誉发表评论......所以,我只是把这个小小的贡献作为一个伪答案。在查看了这个post之后,基于@VividD对过渡变得简单的完美评论,我只是将树垂直选项添加到此fiddle中的变换中。

添加就是这样:

var diagonalVertical = d3.svg.diagonal()
    .projection(function (d) { 
        return [d.x, d.y]; 
    });

无论如何,我已经为这种高度教学的互动添加了书签。