Как использовать JointJS Directed Graph, когда ячейки встроены?
Сегодня вечером я попытался выполнить ориентированный граф на примере с сайта JointJS. Смотрите пример дискретного события:
http://resources.jointjs.com/demos/devs
Хотя ссылка на исходный код не отображается правильно, я нашел ее здесь:
https://raw.githubusercontent.com/clientIO/joint/master/demo/devs/src/shapes.devs.js
Я нахожусь в ситуации, когда не могу предсказать, в какую позицию помещать объекты, как в демоверсии. Поэтому я полагаюсь на DirectedGraph, чтобы сделать работу. Итак, в качестве простого примера я просто помещаю следующее в конец кода, чтобы посмотреть, что произойдет:
joint.layout.DirectedGraph.layout(graph, {
setLinkVertices: false
});
Уведомление в консоли выдает ошибку:
"Uncaught TypeError: Невозможно установить свойство 'rank' из undefined" - dare.core.js 3085
Это именно та проблема, с которой я столкнулся в своем программном обеспечении. Единственное решение, которое я нашел, - это удалить все встроенные ячейки. Это ошибка или демо-версия устарела? Я искал документацию с небольшим успехом. У кого-нибудь была эта проблема? Кто-нибудь может заставить демо работать с DirectedGraph?
1 ответ
Это известная проблема Dagre-D3: автоматическая разметка не работает на иерархических диаграммах со связями с родителем.
Чтобы заставить его работать, вы можете либо опустить ссылки между элементами встраивания при вызове joint.layout.DirectedGraph.layout()
или вы можете использовать более сложный обходной путь, как предложено здесь:
- Размещайте каждую группу дочерних элементов отдельно.
- Для каждого родителя создайте вспомогательный родительский клон.
- Установите соответствующие элементы для их клонированного родителя.
- Подгоните каждого клонированного родителя к размеру его потомков и измените размер исходного родителя по размеру клонированного родителя.
- Разметить график.
- Переведите клонированных родителей в положение их исходного родителя (дети будут переведены соответствующим образом).
- Удалите клонированных родителей и установите детей в исходные родители.
Не используйте встраивание. Вы могли бы скорее создать собственный элемент:
const CustomCircle = joint.dia.Element.define(
'CustomCircle',
{
attrs: {
outer: {
refR: 0.5,
refCx: 0.5,
refCy: 0.5,
},
inner: {
refR: 0.3,
refCx: 0.5,
refCy: 0.5,
},
// outline: {
// refX: 0,
// refY: 0,
// refWidth: '100%',
// refHeight: '100%',
// strokeWidth: 1,
// stroke: '#000000',
// strokeDasharray: '5 5',
// strokeDashoffset: 2.5,
// fill: 'none'
// }
}
},
{
markup: [
{
tagName: 'circle',
selector: 'outer'
},
{
tagName: 'circle',
selector: 'inner'
},
// {
// tagName: 'rect',
// selector: 'outline'
// }
]
}
);
const circle = new CustomCircle();
circle.attr({
outer: {
class: 'class1 class2',
},
inner: {
class: 'class3 class4'
},
});
circle.resize(40, 40);