Fjo*_*ten 5 javascript jointjs
我正在使用JointJS图,使用DirectedGraph来处理布局,我正在尝试实现类似于下图的内容.我需要将节点(A,B,C,D,E,F,G,H,I,J)"概括"或包含在单独的节点(Foo,Bar,Hmm)中.当我将所有元素添加到图表中时,一切都在彼此之上.但是,如果我不在区域之间添加顶点,则所有元素都会正确布局,但没有连接区域的顶点.
根据下面的代码,我做错了什么?节点(A,B,C,D,E,F,G,H,I,J)是否会导致错误,因为它们没有连接到图表的其余部分?
您提供的任何反馈都非常感谢.
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: $('#paper');
width: 2000,
height: 2000,
gridSize: 1,
model: graph
});
var regions = [ makeRegion('Foo'), makeRegion('Bar'), makeRegion('Hmm')];
var nodes = [
makeNode('A'),
makeNode('B'),
makeNode('C'),
makeNode('D'),
makeNode('F'),
makeNode('G'),
makeNode('H'),
makeNode('I'),
makeNode('J'),
];
regions[0].embed(nodes[0]).embed(nodes[1]).embed(nodes[2]);
regions[1].embed(nodes[3]).embed(nodes[4]).embed(nodes[5]);
regions[2].embed(nodes[6]).embed(nodes[7]).embed(nodes[8]);
var vertices = [
connect(regions[0], regions[1]),
connect(regions[1], regions[2]),
connect(regions[2], regions[0])
];
paper.addCells(regions.concat(nodes).concat(vertices));
joint.layout.DirectedGraph.layout(paper, {
rankDir: 'LR',
marginX: 30,
marginY: 30,
clusterPadding: {
top: 30,
left: 10,
right: 10,
bottom: 10
}
});
function makeNode(name) {
return new joint.shapes.basic.Rect({
size: {
width: 35,
height: 35
},
attrs: {
text: {
text: name
}
}
});
}
function connect(a, b) {
return new joint.shapes.fsa.Arrow({
source: { id: a.id },
target: { id: b.id }
});
}
function makeRegion(name) {
return new joint.shapes.basic.Rect({
size: {
width: 300,
height: 200
},
attrs: {
text: {
text: name
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
编辑:
虽然我从来没有找到解决这个问题的好方法,但我确实发现,通过一些额外的工作,这可以实现.它假设您的图形不是太复杂,区域之间的边缘很少.
如果我单独添加边缘,在将所有节点添加到图形之后,它将正常工作.然而,定向布局并不完全按预期工作.我joint.layout.DirectedGraph.layout()最初使用它以便它对齐内部节点,然后我重新定位out区域.最后我添加了边缘,并产生类似于上图的结果.
以下是我如何实现这一目标的大致概述:
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: $('#paper');
width: 2000,
height: 2000,
gridSize: 1,
model: graph
});
var regions = [ makeRegion('Foo'), makeRegion('Bar'), makeRegion('Hmm')];
var nodes = [
makeNode('A'),
makeNode('B'),
makeNode('C'),
makeNode('D'),
makeNode('F'),
makeNode('G'),
makeNode('H'),
makeNode('I'),
makeNode('J'),
];
regions[0].embed(nodes[0]).embed(nodes[1]).embed(nodes[2]);
regions[1].embed(nodes[3]).embed(nodes[4]).embed(nodes[5]);
regions[2].embed(nodes[6]).embed(nodes[7]).embed(nodes[8]);
paper.addCells(regions.concat(nodes));
joint.layout.DirectedGraph.layout(paper, {
rankDir: 'LR',
marginX: 30,
marginY: 30,
clusterPadding: {
top: 30,
left: 10,
right: 10,
bottom: 10
}
});
var vertices = [
connect(regions[0], regions[1]),
connect(regions[1], regions[2]),
connect(regions[2], regions[0])
];
repositionRegions();
// Add the edges after all the nodes are in their final position
graph.addCells(vertices);
function repositionRegions() {
// Move regions to where you want them
}
function makeNode(name) {
return new joint.shapes.basic.Rect({
size: {
width: 35,
height: 35
},
attrs: {
text: {
text: name
}
}
});
}
function connect(a, b) {
return new joint.shapes.fsa.Arrow({
source: { id: a.id },
target: { id: b.id }
});
}
function makeRegion(name) {
return new joint.shapes.basic.Rect({
size: {
width: 300,
height: 200
},
attrs: {
text: {
text: name
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
小智 1
这是 Dagre-D3 的一个已知问题:自动布局不适用于具有父级链接的分层图。
作为解决方法,您可以省略区域之间的链接(在您的问题版本中建议),或者您可以做一些额外的工作,这对于任意数量的节点都可以很好地工作:
分别布局每组子节点:
var fooChildren = [nodes[0], nodes[1], nodes[2]];
var barChildren = [nodes[3], nodes[4], nodes[5]];
var hmmChildren = [nodes[6], nodes[7], nodes[8]];
var children = [fooChildren, barChildren, hmmChildren];
for(var i = 0; i < children.length; i++)
joint.layout.DirectedGraph.layout(children[i]);
Run Code Online (Sandbox Code Playgroud)对于每个区域,创建一个辅助克隆区域。
var clones = [];
for(var i = 0; i < regions.length; i++) {
var clone = regions[i].clone();
graph.addCell(clone);
clones.push(clone);
}
Run Code Online (Sandbox Code Playgroud)将相应的节点设置为其克隆区域。
for(var i = 0; i < children.length; i ++)
for(var k = 0; k < children[i].length; k++)
clones[i].embed(children[i][k]);
Run Code Online (Sandbox Code Playgroud)使每个克隆区域适合其子区域的大小,并根据克隆区域的大小调整原始区域的大小。
for(var i = 0; i < clones.length; i++) {
clones[i].fitEmbeds(padding: { top: 30, left: 10, right: 10, bottom: 10 });
regions[i].resize(clones[i].getBBox().width, clones[i].getBBox().height);
}
Run Code Online (Sandbox Code Playgroud)布置图形。
joint.layout.DirectedGraph.layout(graph, {
rankDir: 'LR',
marginX: 30,
marginY: 30,
clusterPadding: {
top: 30,
left: 10,
right: 10,
bottom: 10
}
});
Run Code Online (Sandbox Code Playgroud)将克隆区域平移到其原始区域的位置(子区域将相应地平移)。
for(var i = 0; i < clones.length; i++) {
var dx = regions[i].getBBox().x - clones[i].getBBox().x;
var dy = regions[i].getBBox().y - clones[i].getBBox().y;
clones[i].translate(dx, dy);
}
Run Code Online (Sandbox Code Playgroud)删除克隆区域并将子区域设置为原始区域。
for(var i = 0; i < regions.length; i++) {
clones[i].remove();
for(var j = 0; j < children[i].length; j++)
regions[i].embed(children[i][j]);
}
Run Code Online (Sandbox Code Playgroud)希望这可以帮助提供替代解决方案。