2015-01-22 4 views
3

У меня есть эта D3jsfiddle что производит следующие диаграммы:D3 сила раскладки: Прямая линия вместо кривых ссылок (но только для некоторых ссылок)

enter image description here

Единственное, что беспокоит меня об этой диаграмме что, если есть только одна связь между двумя узлами, она рисуется как кривая. Я думаю, было бы намного лучше, если бы такие ссылки были просто прямыми (стрела была бы в порядке). Скажем, между Microsoft и Amazon должна быть только прямая линия (со стрелкой). То же самое между Oracle и Google, Sony и LG и т. Д.

Как достичь этого?

ответ

5

Это очень просто. В вашем методе linkArc(d) просто установите параметр dr равным 0, если есть только 1 ребенок или по умолчанию, если их больше. Таким образом, между узлами не будет никакой кривой.

Первым шагом, однако, будет определение количества соседей. Простой способ будет выглядеть следующим образом сразу после определения узлов из ссылок, хотя он не является оптимальным.

links.forEach(function(d) { 
    if (nodes[d.source.name].children==undefined) { 
     nodes[d.source.name].children=0; 
    } 
    nodes[d.source.name].children++ 
}); 

После того, как вы сделаете это, вы можете настроить кривую линии следующим образом:

function linkArc(d) { 
    var dx = d.target.x - d.source.x, 
     dy = d.target.y - d.source.y, 
     dr = (nodes[d.target.name].children>1 & nodes[d.source.name].children>1)?Math.sqrt(dx * dx + dy * dy):0; 
    return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; 
} 

Результат будет выглядеть следующим образом:

here

Я уверен, что есть намного лучшие способы справиться с этим, но это начало. Надеюсь, это поможет.

+0

Спасибо, но мне нужно сохранить кривые, если между узлами существует несколько соединений. Кажется, ваше решение сделает все прямые линии. – VividD

+0

Извинения, было непонятно, что вы предпочитаете прямые линии только тогда, когда есть только одна пара. – Nikos

+0

Без проблем, я дам +1, так как ваш ответ может быть полезен, если кому-то еще нужны такие вещи, пожалуйста, держите ответ. – VividD

0

Это основано на @Nikos ответ:

links.forEach(function(d) { 
    d.straight = 1; 
    links.forEach(function(d1) { 
     if ((d.source == d1.target) && (d1.source == d.target)) 
      d.straight = 0; 
    }); 
}); 

и

function linkArc(d) { 
    var dx = d.target.x - d.source.x, 
     dy = d.target.y - d.source.y, 
     dr = (d.straight == 0)?Math.sqrt(dx * dx + dy * dy):0; 
    return "M" + d.source.x + "," + d.source.y + 
     "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; 
} 

выход исправить схему: (по отношению к прямолинейности соединений)

enter image description here

jsfiddle

+0

Спасибо за сообщение! Вы можете выбрать свой ответ как правильный, без проблем на моей стороне :) – Nikos

 Смежные вопросы

  • Нет связанных вопросов^_^