簡體   English   中英

D3.js在徑向樹中的元素之間添加鏈接(分層邊緣捆綁元素)

[英]D3.js Adding links between elements in a radial tree (Hierarchical edge bundling elements)

幾個月前,我嘗試使用d3.js組合Hierarchical Edge Bundling和Radial Reingold-Tilford Tree

在此輸入圖像描述

我從HEB開始嘗試將它變成一棵樹。 事情並沒有按照我想要的方式解決,我意識到從一個可折疊的徑向樹(不是Reingold Tilford)開始,可能會有更好的角度。

在此輸入圖像描述

這是徑向樹的JSFiddle

數據模型也發生了變化,因為元素現在有了名稱,子項和導入(鏈接)。

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"}
            ]
        }
    ]
};

為了慢慢開始,我想將Mike Bostock的非交互式Hierarchical邊緣捆綁與當前的JSFiddle結合起來 ,但請記住,以后交互將成為其中的一部分。

此外,只有第一級必須有鏈接(父 - 父鏈接),如下所示(我想要的結果):

在此輸入圖像描述

我目前最大的問題是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條信息都很重要(名稱,子項和導入)。

另一種方法是能夠將數據更改為不包括根部分,並且它的行為與現在完全相同,也歡迎部分答案。

我目前最大的問題是HEB沒有“根”,但樹開始時只有一個項目。 所以到目前為止我所嘗試的一切都導致了樹的中心一團糟。

鑒於您有一個根,為什么不將其設置為中心“節點”並使其成為徑向樹,像這樣 是另一個例子,但有多個根。

也就是說,你沒有要求一個徑向樹,即使它聽起來會回答你的問題。 如果你決心把東西排列成不同鐳的圓圈,那么要解決的問題可能是看起來如此“混亂”的線條縱橫交錯。 如果是這種情況,則可以使用不同的排序算法。 這里是在與D3.js.類似的情況使用不同的排序算法膨脹的制品 D3布局算法也是在線開源的

我能找到的最好的資源就是Stack Mathematics Answer 有幾點特別突出:

  1. 您可以完全混亂連接/分支,但如果它是交互式的,當您將鼠標懸停在該節點上時,指向特定節點的分支會亮起,那么它仍然可以是可讀/可用的圖形。
  2. 您可以嘗試不同的排序算法,直到找到適合您的數據的算法。
  3. 您可以在圓圈內部放置一個或多個節點,在這種情況下,將根節點放在中間位置可能很有意義。

它不是一個實際可用的答案,因為它在Mathematica中,但我認為它對基礎理論和技術的解釋是有用的。

如果你不想把樹的根放在中心,或許更具藝術性的方法,那就是讓從父母到根父母的所有分支都是半透明的,可能是不同的顏色。

(抱歉,低質量的photoshop)

希望這可以幫助!

我已經設法在這個JSFiddle中的元素之間添加鏈接,使用Mike Bostock在原始分層邊緣捆綁中找到的部分代碼,並將它們添加到可折疊樹的徑向版本中。 但是,在折疊或擴展孩子時,他們不會更新!

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;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM