2016-10-26 16 views
9

几个月前,我试图combining Hierarchical Edge Bundling and Radial Reingold–Tilford Tree using d3.jsD3.js添加(分级边缘捆绑元素)的径向树元素之间的链接

enter image description here

我从HEB开始并试图使之成为一个树。 事情并没有按照我想要的方式工作,我意识到从不同的角度开始从可折叠的径向树(不是Reingold Tilford)可能会更好。

enter image description here

Here is a JSFiddle of the radial tree

数据模型也发生了变化,因为现在的元素有一个名字,儿童和进口(链接)。

var flare = 
{ 
    "name": "root", 
    "children": [ 
     { 
      "name": "test1.parent1","children": [ 
       {"name": "test1.child11","children": [ 
        {"name": "test1.child111"}, 
        {"name": "test1.child112"} 
       ]} 
      ],"imports": ["test2.parent2","test3.parent3","test4.parent4"] 
     }, 
     { 
      "name": "test2.parent2","children": [ 
       {"name": "test2.child21"}, 
       {"name": "test2.child22"}, 
       {"name": "test2.child28","children":[ 
        {"name": "test2.child281"}, 
        {"name": "test2.child282"} 
       ]} 
      ],"imports": ["test3.parent3"] 
     }, 
     {"name": "test3.parent3","imports": ["test4.parent4"]}, 
     { 
      "name": "test4.parent4","children": [ 
       {"name": "test4.child41"}, 
       {"name": "test4.child42"} 
      ] 
     } 
    ] 
}; 

慢慢来,我想给non-interactive Hierarchical edge bundling从迈克·博斯托克与当前JSFiddle结合,但牢记的互动将成为它的一部分以后。

而且,只有第一层必须有链接(父父链接),如下图所示(我想要的结果):

enter image description here

我现在最大的问题是,HEB没有“根”,但树从一个项目开始。所以我迄今为止所尝试的所有东西都导致了树中心的大乱。

请注意,在树的中心有一个圆圈来覆盖根级别1的链接,所以树从级别1(父母)开始。

var circle = svg.append("circle") 
    .attr("cx", 0) 
    .attr("cy", 0) 
    .attr("r", diameter - 725.3) 
    .style("fill", "#F3F5F6") 
    .style("stroke-width", 0.2) 
    .style("stroke", "black"); 

理想的情况下,家长之间的联系有更新时的水平为(UN)倒塌,像它的节点和层次之间的联系,但可以晚一点,可能不是最初后难获得第一级链接显示。另外,如有必要,数据模板可能会更改,但所有3条信息都很重要(名称,子级和导入)。

另一种方法可以将数据更改为不包含根部分,并且其行为与现在完全相同 也可以部分回答。

+0

绝对不是重复的,但似乎与[this](http://stackoverflow.com/q/30653093/1586231)相关。 –

回答

0

我设法增加使用由迈克·博斯托克原来的阶层边缘捆绑发现部分代码在此的jsfiddle要素之间的联系,并加入他们径向可折叠树的版本。但是,折叠或扩展孩子时不会更新!

var bundle = d3.layout.bundle(); 

var line = d3.svg.line.radial() 
    .interpolate("bundle") 
    .tension(.85) 
    .radius(function(d) { return d.y; }) 
    .angle(function(d) { return d.x/180 * Math.PI; }); 

然后在update(source)

var middleLinks = packageImports(root); 

svg.selectAll("path.middleLink") 
      .data(bundle(middleLinks)) 
     .enter().append("path") 
      .attr("class", "middleLink") 
      .attr("d", line); 

的 “packageImport” 功能可以在底部。

function packageImports(json) { 
     var map = {}, 
      imports = []; 

     console.log(json.children); 

     // Compute a map from name to node. 
     json.children.forEach(function(d) { 
     console.log(d.name) 
     map[d.name] = d; 
     }); 

     // For each import, construct a link from the source to target node. 
     json.children.forEach(function(d) { 
     if (d.imports) d.imports.forEach(function(i) { 
      imports.push({source: map[d.name], target: map[i]}); 
     }); 
     }); 

     console.log(imports); 
     return imports; 
    } 
0

我目前最大的问题是HEB没有“根”,但树开始时只有一个项目。所以我迄今为止所尝试的所有东西都导致了树中心的大乱。

考虑到你有一个根,为什么不把它设置为中心“节点”并使它成为径向树,如this?另一个例子是Here,但具有多个根。

这就是说,你没有要求一棵径向树,即使它听起来像会回答你的问题。如果你决定把事情安排在不同半径的圆圈中,那么可能要解决的问题是看起来如此“杂乱”的线条纵横交错。如果是这样的话,那么不同的排序算法可能会诀窍。 Here是一篇文章,它扩展了在与D3.js类似的场景中使用不同的排序算法。 D3布局算法也是open source online

我能找到最适合你的资源是this Stack Mathematics Answer。有几点比较突出,我在里面:

  1. 您可以连接/分支机构的一塌糊涂,但是如果当你将鼠标悬停在该节点它的互动和树枝,并从一个特定节点亮起来,那么它仍然可以是可读/可用的图。
  2. 你可以尝试不同的排序算法,直到找到一个与您的数据效果很好。
  3. 你可以有圆圈内一个或多个节点,在这种情况下把根节点,中间可能使有很大的意义。

这不是一个实用的答案,因为它是在数学,但我认为它的基本理论和技术的解释是有用的。

如果不想将树的根部放在中心,那么可能更具艺术性的方法是从父母到根父母的所有分支都是半透明的,也可能是不同的颜色。

(Sorry for the low-quality photoshop)

希望这有助于!

+1

问题是,我确实希望在中间的所有链接。所有我想要的是我已经有了,并根据数据(相同的链接,作为阶层边缘捆绑),在中间的“简单”添加这些链接的径向树。当我说:“乱在中间的”我的意思大多只是填充和点击,而不是常规的树时,清空一个小圆圈。我不需要一种新的数据排序方式,我只需要这些链接,他们将不得不在更新崩溃等。除此之外,我拥有的树与您建议的第一棵树相同,只能折叠。 – MorganFR