cytoscape.js - 我们可以为循环边缘类型或子父边缘选择其他边缘形式吗?

标签 cytoscape.js

示例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%'
    },
}])

我得到这样的曲线:

1

直线曲线样式也是如此。

如何为循环绘制另一个边缘形式?

最佳答案

不确定如果不 fork 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
    }
}

Ghost节点位置计算不正确,可以从复合节点边界框​​中获取。 这样,您就可以完全控制边缘。此外,在导出网络时,您应该考虑丢弃“辅助边”,因为根据网络的数据,您应该始终能够重新绘制这些边。

PS - 如果复合节点被拖动,您还需要重新计算幽灵节点位置。

关于cytoscape.js - 我们可以为循环边缘类型或子父边缘选择其他边缘形式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61922973/

相关文章:

javascript - 在 cytoscape.js 中操作内容样式

php - 通过 mysql 表中的主键命名 cytoscape 的节点

filter - 如何获取边缘以及我在 Cytoscape.js 中过滤的节点?

javascript - 细胞景观 : TypeError even with the tutorial

javascript - 如何在 cytoscape 中放大选定的节点

cytoscape.js - cytoscape.js 中简单树的 Dagre 布局

javascript - 在 Cytoscape.js 中设置节点位置

javascript - 如何使用 cytoscape.js 在单个动画中向特定方向移动所有节点?

javascript - 如何使用拓扑图处理 Cytoscape.js Canvas 上的鼠标滚动和按键事件