2016-10-26 1 views
9

Пару месяцев назад я попытался combining Hierarchical Edge Bundling and Radial Reingold–Tilford Tree using d3.jsD3.js Добавление связей между элементами в радиальном дерево (иерархический край пакетирования элементов)

enter image description here

Я начал с СЭП и попытался сделать это в дерево. Вещи не сработали так, как я хотел, и я понял, что лучше начать с складного радиального дерева (не Рейнгольда Тилфорда) под другим углом.

enter image description here

Here is a JSFiddle of the radial tree

Модель данных также изменилась, поскольку элементы теперь имеют имя, дети и импорт (ссылки).

var flare = 
{ 
    "name": "root", 
    "children": [ 
     { 
      "name": "test1.parent1","children": [ 
       {"name": "test1.child11","children": [ 
        {"name": "test1.child111"}, 
        {"name": "test1.child112"} 
       ]} 
      ],"imports": ["test2.parent2","test3.parent3","test4.parent4"] 
     }, 
     { 
      "name": "test2.parent2","children": [ 
       {"name": "test2.child21"}, 
       {"name": "test2.child22"}, 
       {"name": "test2.child28","children":[ 
        {"name": "test2.child281"}, 
        {"name": "test2.child282"} 
       ]} 
      ],"imports": ["test3.parent3"] 
     }, 
     {"name": "test3.parent3","imports": ["test4.parent4"]}, 
     { 
      "name": "test4.parent4","children": [ 
       {"name": "test4.child41"}, 
       {"name": "test4.child42"} 
      ] 
     } 
    ] 
}; 

Чтобы начать медленно, я хотел бы объединить non-interactive Hierarchical edge bundling от Майка Босток с текущим JSFiddle, но имея в виду, что взаимодействие будет часть его в дальнейшем.

Кроме того, только первый уровень должен иметь ссылки (родитель-родитель ссылку), как показано ниже (в результате чего я хочу):

enter image description here

Моей текущей самая большая проблема не в том, что ГЭБ не имеет «root», но дерево начинается с одного элемента. Итак, все, что я пробовал до сих пор, привело к большому беспорядку в центре дерева.

Обратите внимание, что в центре дерева есть круг, чтобы покрыть корни до уровня 1, поэтому дерево начинается с уровня 1 (родители).

var circle = svg.append("circle") 
    .attr("cx", 0) 
    .attr("cy", 0) 
    .attr("r", diameter - 725.3) 
    .style("fill", "#F3F5F6") 
    .style("stroke-width", 0.2) 
    .style("stroke", "black"); 

В идеале, связи между родителями должны обновлять, когда уровень (не) разрушилась, как это делает для узлов и связей между уровнями, но это может прийти позже и может быть не так трудно после первоначального получение ссылок первого уровня для показа. Кроме того, при необходимости шаблон данных может измениться, но важны все 3 части информации (имя, дети и импорт).

Другим способом сделать это было бы возможность изменить данные, чтобы не включать корневую часть, и что она ведет себя точно так же, как сейчас. Частичные ответы также приветствуются.

+0

Определенно не дубликат, но кажется связанным с [этим] (http://stackoverflow.com/q/30653093/1586231). –

ответ

0

Мне удалось добавить ссылки между элементами в этом JSFiddle, используя части кода, найденные в исходном иерархическом наборе кромок Майком Бостоком, и добавили их в радиальную версию сбрасываемого дерева. Тем не менее, они не обновляются, когда рушатся или расширяются дети!

var bundle = d3.layout.bundle(); 

var line = d3.svg.line.radial() 
    .interpolate("bundle") 
    .tension(.85) 
    .radius(function(d) { return d.y; }) 
    .angle(function(d) { return d.x/180 * Math.PI; }); 

тогда в update(source):

var middleLinks = packageImports(root); 

svg.selectAll("path.middleLink") 
      .data(bundle(middleLinks)) 
     .enter().append("path") 
      .attr("class", "middleLink") 
      .attr("d", line); 

Функция "packageImport" можно найти в нижней части.

function packageImports(json) { 
     var map = {}, 
      imports = []; 

     console.log(json.children); 

     // Compute a map from name to node. 
     json.children.forEach(function(d) { 
     console.log(d.name) 
     map[d.name] = d; 
     }); 

     // For each import, construct a link from the source to target node. 
     json.children.forEach(function(d) { 
     if (d.imports) d.imports.forEach(function(i) { 
      imports.push({source: map[d.name], target: map[i]}); 
     }); 
     }); 

     console.log(imports); 
     return imports; 
    } 
0

Моя самая большая проблема в том, что HEB не имеет «root», но дерево начинается с одного элемента. Итак, все, что я пробовал до сих пор, привело к большому беспорядку в центре дерева.

Учитывая, что у вас есть корень, почему бы не установить его как центр «узел» и сделать его радиальным деревом, например this? Here - еще один пример, но с несколькими корнями.

Тем не менее, вы не запрашивали радиальное дерево, даже если это звучит так, что ответит на ваш вопрос. Если вы настроены на то, чтобы держать вещи в кругах различного радиона, возможно, проблема, которую нужно решить, - это пересечение линий, выглядящих так «грязными». Если это так, то другой способ сортировки может сделать трюк. Here - статья, которая расширяется при использовании различных алгоритмов сортировки в аналогичном сценарии с D3.js. Алгоритмы компоновки D3 также являются open source online.

Лучший ресурс, который я смог найти, был this Stack Mathematics Answer. Несколько пунктов, особенно выделяются для меня в нем:

  1. Вы можете иметь полный беспорядок соединений/ветвей, но если это интерактивный и ветви и от конкретного узла загораются при наведении мыши на этом узле, то он все равно может быть читаемым/полезным графом.
  2. Вы можете попробовать различные алгоритмы сортировки, пока не найдете тот, который хорошо работает с вашими данными.
  3. У вас может быть один или несколько узлов внутри круга, и в этом случае размещение корневого узла посередине может иметь большой смысл.

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

Возможно, более художественный подход, если вы не хотите вставлять корень дерева в центр, состоит в том, чтобы сделать все ветви от родителей родительским корнем полупрозрачным и, возможно, другим цветом.

(Sorry for the low-quality photoshop)

Надеется, что это помогает!

+1

Проблема в том, что мне нужны эти ссылки посередине, все они. Все, что я хочу, это лучевое дерево, которое у меня уже есть, и «просто» добавить эти ссылки посередине в соответствии с данными (теми же ссылками, что и иерархическое связывание краев). Когда я сказал «беспорядок в середине», я в основном имею в виду только один маленький круг, который заполняется и опустошается при нажатии вместо обычного дерева. Мне не нужен новый способ сортировки данных, мне просто нужны эти ссылки, и они должны будут обновиться после краха и т. Д. Помимо этого, дерево, которое у меня есть, такое же, как и первое, которое вы предложили, только разборное. – MorganFR

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