Ответ 1
По моему скромному мнению, D3.js не очень подходит для такого рода визуализации. Визуализация слишком сложна, чтобы выполнить простое сопоставление данных с SVG (и для этого D3.js в основном предназначен: для создания DOM (документов) из Data с помощью кратких сопоставлений).
Вы можете обойти эти ограничения, добавив больше логики между ними, чтобы данные не отображались напрямую, а создавались модели, выполнялись некоторые вычисления, а затем результат преобразовывался в SVG с помощью D3. Это то, что Dagre пытается сделать, и это работает довольно хорошо.
Однако у вашего графа есть некоторые специальные ограничения, которые в настоящее время не поддерживаются более простыми реализациями этого алгоритма компоновки: на последнем слое вы получаете рендеринг в стиле вилки. В "решении" -layer вы назначаете ограничения для ребер так, чтобы они оставляли слева и справа от узлов, вы также ограничиваете узлы принятия решений тем же уровнем.
Вся эта информация не видна в самой структуре графа. Для этого вам нужно аннотировать эту информацию в вашей модели и сообщить алгоритму компоновки, чтобы соблюсти эти ограничения. Насколько мне известно, только коммерческие реализации библиотек графических чертежей в настоящее время поддерживают эти расширенные функции макета.
yFiles for HTML - это такая библиотека: в этой демонстрации вы можете использовать следующий JSON, чтобы получить такой результат:
Переключитесь на запись в выпадающем списке вверху: "5 - Сложные объекты + пограничные метки"
И измените JSON в разделах "Источники узлов", "Источник краев" и "Шаблон узла" следующим образом:
Источник Узлов
{
0:{'name':'Start',color:'green'},
1:{'name':'Read A,B,C',color:'yellow'},
2:{'name':'Is B>C?',color:'green'},
3:{'name':'Is A>B?',color:'green'},
4:{'name':'Is A>C?',color:'green'},
5:{'name':'Print B',color:'green'},
6:{'name':'Print C',color:'green'},
7:{'name':'Print C',color:'green'},
8:{'name':'Print A',color:'green'},
9:{'name':'End',color:'red'}
}
Краевой Источник
[
{from:'0', to:'1', label:''},
{from:'1', to:'3', label:''},
{from:'3', to:'2', label:'No'},
{from:'3', to:'4', label:'Yes'},
{from:'2', to:'5', label:'Yes'},
{from:'2', to:'6', label:'No'},
{from:'4', to:'7', label:'No'},
{from:'4', to:'8', label:'Yes'},
{from:'5', to:'9', label:''},
{from:'6', to:'9', label:''},
{from:'7', to:'9', label:''},
{from:'8', to:'9', label:''}
]
шаблон
<rect fill='{Binding color}' stroke='LightBlue' stroke-width='2'
width='{TemplateBinding width}'
height='{TemplateBinding height}'></rect>
<text transform='translate(10 20)' data-content='{Binding name}'
style='font-size:18px; font-family:Arial; fill:#000; text-anchor: left;
dominant-baseline: central;'></text>
Обратите внимание, что использование JSON другого типа также возможно (как показано в демонстрации). Я не верю, что формат JSON вообще будет проблемой, и как вы можете видеть, вы получите достойный результат, но все же упомянутые мною ограничения не были учтены и добавлены в JSON. К сожалению, добавление этих ограничений не может быть сделано через демонстрационный интерфейс, который я использую выше прямо сейчас, но это необходимо сделать, добавив больше кода к фактическому исходному коду демонстрации. Вы можете увидеть, как эти ограничения работают в другой демонстрации (хотя и без JSON) в этой демонстрации интерактивного макета.
Собрав все части воедино, вы можете легко достичь такого результата, автоматически:
Этот же пример можно найти и опробовать в интерактивном режиме в этой демонстрации макета интерактивной потоковой диаграммы.
Отказ от ответственности: я работаю в компании, которая создает эту библиотеку, однако в SO/SE я не представляю своего работодателя. Мои посты мои.