2014-11-20 5 views
0

Я планирую создать структуру дерева, предназначенную для узлов динамически созданного набора данных, и хотел бы установить координаты оси y всех узлов для ориентированного по силе графа. Другими словами, я хотел бы, чтобы узлы располагались на уровнях (например, древовидной структуре), тогда как узлы могут свободно перемещаться и оптимизироваться по оси x.параметризированное позиционирование узла ориентированного ориентированного графства D3js

Конечным результатом должно быть дерево, где узлы располагаются на выделенных уровнях вместо радиально, как и по умолчанию. Соединения братьев и сестер не должны пересекаться и быть как можно короче (логическая группировка, поэтому требуется сделать это с помощью графика силы).
Если у кого-то есть решение, которое проще, то я все уши.

код экстракт:

ldLinks = [ 
{source: "root", target: "1", source_level: 0, target_level: 1}, 
{source: "root", target: "2", source_level: 0, target_level: 1}, 
{source: "root", target: "3", source_level: 0, target_level: 1}, 
{source: "root", target: "4", source_level: 0, target_level: 1}, 
{source: "1", target: "1.1", source_level: 1, target_level: 2}, 
{source: "1", target: "1.2", source_level: 1, target_level: 2}, 
{source: "2", target: "2.1", source_level: 1, target_level: 3}, 
{source: "2", target: "2.2", source_level: 1, target_level: 3}, 
{source: "3", target: "3.1", source_level: 1, target_level: 3}, 
{source: "4", target: "3.2", source_level: 1, target_level: 3}, 
{source: "4", target: "3.3", source_level: 1, target_level: 3}, 
{source: "3", target: "3.2", source_level: 2, target_level: 3}, 
{source: "3", target: "4.1", source_level: 2, target_level: 3}, 
{source: "2.1", target: "5.1", source_level: 3, target_level: 4}, 
{source: "3.1", target: "5.1", source_level: 3, target_level: 4}, 
{source: "1", target: "5", source_level: 1, target_level: 4}, 
]; 

var dNodes = {}; 

// Compute the distinct dNodes from the ldLinks. 
ldLinks.forEach(function(link) { 
    link.source = dNodes[link.source] || (dNodes[link.source] = {name: link.source, level: link.source_level}); 
    link.target = dNodes[link.target] || (dNodes[link.target] = {name: link.target, level: link.target_level}); 
}); 

//parameterize nodes 
for (var sNodeName in dNodes) { 
    //dNodes[sNodeName].fixed = (only fixed along y-axis) 
    dNodes[sNodeName].y = (dNodes[sNodeName].level * 50) 
} 

ответ

0

ура!

Спасибо Limin's comment от this answer!

Я установил force.gravity(0), а затем добавили границы (.attr("cx/cy")) к node в tick() функции:

function tick() { 
    link 
     .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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) 
     .attr("cx", function(d) { return d.x = Math.max(8, Math.min(width - 8, d.x)); }) 
     .attr("cy", function(d) { return d.y = Math.max(100*d.level, Math.min(100*d.level, d.y)); }); 
}