我们可以为循环边缘类型或子父边缘选择另一种边缘形式吗?
Can we choose another edge form for loop edge type or child-parent edge?
示例 1:
elements: [{
data: {
id: 'a'
}
},
{
data: {
id: 'b',
parent: 'a'
}
},
{
data: {
id: 'ab',
source: 'b',
target: 'a'
}
}
],
style: [{
selector: 'edge',
css: {
'curve-style': 'bezier',
'target-arrow-shape': 'triangle'
}
}]
我正在尝试绘制从节点到其父节点的边。
我希望从节点到外部框架有一条直线,如下所示:
但是我得到了这样的曲线:
示例 2:
如果我试图用相同的源和目标制作一条边,它的形式总是一条曲线(就像边类型演示中的循环边类型)。
即使我选择这样的曲线风格:
cy.add([{
data: {
"source": guid,
"target": guid,
},
style: {
"curve-style": "bezier",
"source-endpoint": '0% 0%',
"target-endpoint": '0% -80%'
},
}])
我得到这样的曲线:
同样适用于直线曲线样式。
如何为循环绘制另一种边缘形式?
不确定是否可以不分叉 cytoscape.js,但我可能是错的。
https://codepen.io/Raven0us/pen/yLYZbJx
这里有一个解决方法,使用永远不会显示的幽灵节点。
cy.$('edge.with-compound').forEach((edge, i) => {
// parent node is edge source
let position = calculateGhostNodePosition(edge.source());
// ghost node id needs to keep a reference to the node that was used to calculate its position
let ghostNodeId = `ghost-${edge.source().id}`;
cy.add({
group: 'nodes',
data: {
id: ghostNodeId
},
position: {
x: position.x,
y: position.y
},
classes: ['ghost-node']
});
cy.add({
group: 'edges',
data: {
id: `${ghostNodeId}-edge`,
source: edge.data('target'),
target: ghostNodeId,
classes: ['ghost-node-connector']
}
})
})
cy.$('node[parent]').on('position', e => {
let node = e.target;
let targetGhostNode = cy.$(`node[id="ghost-${node.id}"]`);
let position = calculateGhostNodePosition(node);
targetGhostNode.position({
x: position.x,
y: position.y
})
})
/**
*
* @param sourceNode
* @returns {{x: number | SVGAnimatedLength, y: *}}
*/
function calculateGhostNodePosition(sourceNode) {
let boundingBox = sourceNode.boundingBox();
// you need to actually calculate these and take node size in account
let x = boundingBox.x1;
let y = boundingBox.y1 + ((boundingBox.y2 - boundingBox.y1) / 2) + 8;
return {
x: x,
y: y
}
}
幽灵节点位置计算不正确,可以从复合节点边界框获取。
这样,您就可以完全控制边缘。此外,在导出网络时,您应该考虑丢弃 "assisting edges",因为根据网络的数据,您应该始终能够重绘这些。
PS - 如果复合节点被拖来拖去,您还需要重新计算幽灵节点的位置。
示例 1:
elements: [{
data: {
id: 'a'
}
},
{
data: {
id: 'b',
parent: 'a'
}
},
{
data: {
id: 'ab',
source: 'b',
target: 'a'
}
}
],
style: [{
selector: 'edge',
css: {
'curve-style': 'bezier',
'target-arrow-shape': 'triangle'
}
}]
我正在尝试绘制从节点到其父节点的边。 我希望从节点到外部框架有一条直线,如下所示:
但是我得到了这样的曲线:
示例 2:
如果我试图用相同的源和目标制作一条边,它的形式总是一条曲线(就像边类型演示中的循环边类型)。
即使我选择这样的曲线风格:
cy.add([{
data: {
"source": guid,
"target": guid,
},
style: {
"curve-style": "bezier",
"source-endpoint": '0% 0%',
"target-endpoint": '0% -80%'
},
}])
我得到这样的曲线:
同样适用于直线曲线样式。
如何为循环绘制另一种边缘形式?
不确定是否可以不分叉 cytoscape.js,但我可能是错的。
https://codepen.io/Raven0us/pen/yLYZbJx
这里有一个解决方法,使用永远不会显示的幽灵节点。
cy.$('edge.with-compound').forEach((edge, i) => {
// parent node is edge source
let position = calculateGhostNodePosition(edge.source());
// ghost node id needs to keep a reference to the node that was used to calculate its position
let ghostNodeId = `ghost-${edge.source().id}`;
cy.add({
group: 'nodes',
data: {
id: ghostNodeId
},
position: {
x: position.x,
y: position.y
},
classes: ['ghost-node']
});
cy.add({
group: 'edges',
data: {
id: `${ghostNodeId}-edge`,
source: edge.data('target'),
target: ghostNodeId,
classes: ['ghost-node-connector']
}
})
})
cy.$('node[parent]').on('position', e => {
let node = e.target;
let targetGhostNode = cy.$(`node[id="ghost-${node.id}"]`);
let position = calculateGhostNodePosition(node);
targetGhostNode.position({
x: position.x,
y: position.y
})
})
/**
*
* @param sourceNode
* @returns {{x: number | SVGAnimatedLength, y: *}}
*/
function calculateGhostNodePosition(sourceNode) {
let boundingBox = sourceNode.boundingBox();
// you need to actually calculate these and take node size in account
let x = boundingBox.x1;
let y = boundingBox.y1 + ((boundingBox.y2 - boundingBox.y1) / 2) + 8;
return {
x: x,
y: y
}
}
幽灵节点位置计算不正确,可以从复合节点边界框获取。 这样,您就可以完全控制边缘。此外,在导出网络时,您应该考虑丢弃 "assisting edges",因为根据网络的数据,您应该始终能够重绘这些。
PS - 如果复合节点被拖来拖去,您还需要重新计算幽灵节点的位置。