簡體   English   中英

D3圖形布局-具有多個父級的樹結構

[英]D3 Graph Layout - Tree Structure With multiple Parent

首先,我要說我對D3和Java完全陌生。 經過一點點的實驗,我試圖開發一個像樹一樣的結構,其中的節點可以有多個父級。

輸入:

帶有節點鏈接信息的Json,

 var graph = {
    "nodes": [  { "id" : 0},
                { "id" : 1},
                { "id" : 2},
                { "id" : 3},
                { "id" : 4},
                { "id" : 5}
            ],
    "links": [  { "target": 5, "source":  1 },
                { "target":  2, "source":  0 },
                { "target": 3, "source":  4 },
                { "target": 1, "source":  2},
                { "target":  1, "source":  0 },

            ]
    };

注意:這僅供參考,因為我有數據,它可能是數千個節點。

輸出:

我希望輸出像樹結構一樣,有點像這樣 ,也就是說必須以深度/級別類似的結構來繪制節點,並且根在最上層,而相同級別的節點必須以最小化鏈接重疊的方式排列。

編輯:上面提供的輸入的輸出是 這個 假設零是根。

我面臨的問題:

  1. 因為只給我節點及其源和目標,而不是坐標,所以我必須解析整個列表以計算級別,然后根據該級別划分高度,然后繪制節點。 解決此類問題的最有效方法是什么? 我應該深入研究算法解決方案嗎?

要么

  1. D3中是否有一些圖形繪制函數將這個JSON作為輸入,其余的工作呢?

請不要因為這些節點可以有多個父節點,而我的主要重點是按照正確/分層的順序繪制這些節點,所以我面臨的主要問題是為僅給出輸入的所有節點計算X / Y坐標以上。

請幫助我更好地理解該主題,謝謝。

一整天都在考慮這個問題。 對於內置的d3構造,我認為與您將要達到的目標差不多。 我已將您的數據轉換為第4版示例:

 <!DOCTYPE html> <meta charset="utf-8"> <style> .links line { stroke: #aaa; stroke-width: 5px; } .nodes circle { pointer-events: all; stroke: none; } </style> <svg width="600" height="300"></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script> var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"); var simulation = d3.forceSimulation() .force("link", d3.forceLink().id(function(d) { return d.id; })) .force("charge", d3.forceManyBody()) .force("center", d3.forceCenter(width / 2, height / 2)) .force("y", d3.forceY()) var graph = { "nodes": [{ "id": 0 }, { "id": 1 }, { "id": 2 }, { "id": 3 }, { "id": 4 }, { "id": 5 }], "links": [{ "target": 5, "source": 1 }, { "target": 2, "source": 0 }, { "target": 3, "source": 4 }, { "target": 1, "source": 2 }, { "target": 1, "source": 0 }, ] }; var link = svg.append("g") .attr("class", "links") .selectAll("line") .data(graph.links) .enter().append("line"); var node = svg.append("g") .attr("class", "nodes") .selectAll("circle") .data(graph.nodes) .enter().append("circle") .attr("r", 10); node.append("title") .text(function(d) { return d.id; }); simulation .nodes(graph.nodes) .on("tick", ticked); simulation.force("link") .links(graph.links); function ticked() { var k = 6 * simulation.alpha(); // Push sources up and targets down to form a weak tree. link .each(function(d) { d.source.y -= k, d.target.y += k; }) .attr("x1", function(d) { return d.source.x; }) .attr("y1", function(d) { return d.source.y; }) .attr("x2", function(d) { return d.target.x; }) .attr("y2", function(d) { return d.target.y; }); node .attr("cx", function(d) { return dx; }) .attr("cy", function(d) { return dy; }); } </script> 

如果您不希望移動和穩定效果,則可以預先計算布局以使其為static


我還嘗試將您的數據轉換為可與d3.tree一起使用的分層格式,但復制圖像的運氣並不好:

 <!DOCTYPE html> <meta charset="utf-8"> <style> .node circle { fill: #999; } .node text { font: 10px sans-serif; } .node--internal circle { fill: #555; } .node--internal text { text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff; } .link { fill: none; stroke: #555; stroke-opacity: 0.4; stroke-width: 1.5px; } </style> <svg width="300" height="300"></svg> <script src="//d3js.org/d3.v4.min.js"></script> <script> var graph = { "nodes": [{ "id": 0 }, { "id": 1 }, { "id": 2 }, { "id": 3 }, { "id": 4 }, { "id": 5 }], "links": [{ "target": 5, "source": 1 },{ "target": 2, "source": 0 }, { "target": 3, "source": 4 }, { "target": 1, "source": 2 }, { "target": 1, "source": 0 }] }; var root = { id: 0, data: graph.nodes[0], children: [] } function recurChild(obj) { graph.links.forEach(function(d) { if (d.source === obj.id) { var c = { id: d.target, data: graph.nodes[d.target], children: [] }; obj.children.push(c); recurChild(c); } }); } recurChild(root); root = d3.hierarchy(root); var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"), g = svg.append("g").attr("transform", "translate(40,0)"); var tree = d3.tree() .size([height, width - 160]); tree(root); console.log(root.descendants()) var link = g.selectAll(".link") .data(root.descendants().slice(1)) .enter().append("path") .attr("class", "link") .attr("d", function(d) { return "M" + dy + "," + dx + "C" + (dy + d.parent.y) / 2 + "," + dx + " " + (dy + d.parent.y) / 2 + "," + d.parent.x + " " + d.parent.y + "," + d.parent.x; }); var node = g.selectAll(".node") .data(root.descendants()) .enter().append("g") .attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); }) .attr("transform", function(d) { return "translate(" + dy + "," + dx + ")"; }) node.append("circle") .attr("r", 2.5); node.append("text") .attr("dy", 3) .attr("x", function(d) { return d.children ? -8 : 8; }) .style("text-anchor", function(d) { return d.children ? "end" : "start"; }) .text(function(d) { return d.data.id; }); </script> 

d3.hierarchy實際上意味着沒有多個父級結構的直接層次結構。

暫無
暫無

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

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