D3具有多種佈局向圖有嚴格的樹木,如下列:如何佈置一個非樹層次結構與D3
A
|\
B C
/\
D E
我需要繪製節點的層次結構,是不是一棵樹,但是是一個有向無環圖。這是一個樹佈局的問題,因爲幾個分支會聚:
A
|\
B C
\|
D
有人知道D3佈局的一般層次?或者,對現有的treelayout進行一些巧妙的修改?我注意到GraphVis很好地處理了這種情況,但是D3產生了一個更適合這裏需求的圖。
D3具有多種佈局向圖有嚴格的樹木,如下列:如何佈置一個非樹層次結構與D3
A
|\
B C
/\
D E
我需要繪製節點的層次結構,是不是一棵樹,但是是一個有向無環圖。這是一個樹佈局的問題,因爲幾個分支會聚:
A
|\
B C
\|
D
有人知道D3佈局的一般層次?或者,對現有的treelayout進行一些巧妙的修改?我注意到GraphVis很好地處理了這種情況,但是D3產生了一個更適合這裏需求的圖。
一般說到的樹木和數據層次,你只需要擁有「d」在孩子列表B和C.
創建您的節點列表,請確保您有返回,這樣一個獨特的ID 「D」不會出現兩次。
vis.selectAll("g.node").data(nodes, function(d) { return d.id; });
然後當你調用
var links = tree.links(nodes)
你應該得到d顯示爲「目標」兩次(B和C爲「源」分別),這導致兩行到單個節點「d」。
我能夠以您描述的方式組裝樹,但TreeLayout似乎無法處理它。我有機會以某種方式搞砸了;你有幸得到一個佈局運行這種方式?與此同時,我在服務器端使用GraphViz管理了一個非常合適的解決方法。 GraphViz將爲每個節點以(x,y)位置進行DOT格式的很好的分層佈局和輸出。從那裏,將這些信息打包到頁面並使用D3進行繪製相對比較容易。 感謝您的幫助,我感謝您的努力! –
我玩過它,它很瘋狂。根據父母的不同,它有時會在d3內失敗:「vom未定義:6444」和其他時候會渲染,但是把孩子放在一個醜陋的地方。所以簡短的回答是,你是對的。案件中的樹形佈局是問題所在。 – Glenn
您可以創建自己的代碼,而不必依靠D3佈局來完成它。我提供了example in a jsFiddle。這個例子非常簡單,需要稍加處理以適應更復雜的例子。
這個例子可以重新處理,以相對較少的努力來處理分層數據。
這是我在的jsfiddle使用的代碼:
// Sample data set
var json = {
nodes: [{
name: 'A'},
{
name: 'B'},
{
name: 'C'},
{
name: 'D'}],
links: [{
source: 'A',
target: 'B'},
{
source: 'A',
target: 'C'},
{
source: 'B',
target: 'D'},
{
source: 'C',
target: 'D'}
]
};
var vis = d3.select('#vis').attr('transform', 'translate(20, 20)');
// Build initial link elements - Build first so they are under the nodes
var links = vis.selectAll('line.link').data(json.links);
links.enter().append('line').attr('class', 'link').attr('stroke', '#000');
// Build initial node elements
var nodes = vis.selectAll('g.node').data(json.nodes);
nodes.enter().append('g').attr('class', 'node').append('circle').attr('r', 10).append('title').text(function(d) {
return d.name;
});
// Store nodes in a hash by name
var nodesByName = {};
nodes.each(function(d) {
nodesByName[d.name] = d;
});
// Convert link references to objects
links.each(function(link) {
link.source = nodesByName[link.source];
link.target = nodesByName[link.target];
if (!link.source.links) {
link.source.links = [];
}
link.source.links.push(link.target);
if (!link.target.links) {
link.target.links = [];
}
link.target.links.push(link.source);
});
// Compute positions based on distance from root
var setPosition = function(node, i, depth) {
if (!depth) {
depth = 0;
}
if (!node.x) {
node.x = (i + 1) * 40;
node.y = (depth + 1) * 40;
if (depth <= 1) {
node.links.each(function(d, i2) {
setPosition(d, i2, depth + 1);
});
}
}
};
nodes.each(setPosition);
// Update inserted elements with computed positions
nodes.attr('transform', function(d) {
return 'translate(' + d.x + ', ' + d.y + ')';
});
links.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;
});
感謝這個例子,菲爾!我結束了一些非常相似的事情。事實證明,我真正想要的佈局算法是在GraphViz中實現的。它有python綁定,但它們不起作用。相反,我做了以下內容: 1)型圖形爲DOT語言(http://www.graphviz.org/content/dot-language) 2)通圖通過命令行的graphviz的圓點命令,這的確佈局和看跌期權(X,Y)座標轉換成DOT 3)重新格式化成DOT javascript對象,嵌入到 第4頁)使用D3放置節點根據(X,Y)座標中DOT。 這個作品真的很好用非常大的圖形。 –
正如這個例子:「Force Directed Trees」說明存在,往往工作的伎倆。在這個例子中,力的方向的行爲是在每個滴答時進行調整的,以便節點根據鏈接的方向稍微向上或向下漂移。如圖所示,這對樹木來說是一項很好的工作,但我發現它也適用於非循環圖。沒有承諾,但可能有所幫助。
您可能想看看有力的圖形佈局。 –