繁体   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