我的细胞景观图有一条边从一个节点到另一个节点,穿过第三个节点。我该如何避免这种情况?

My cytoscape graph has an edge going from one nodes to another that crosses behind a third. How do I avoid that?

我做了一个所有边都是直的细胞景观图,布局是"breadth-first"(我只是随意选择布局),它给出了一个误导性的图表。例如,节点 RH4 应该连接到节点 E8。连接直接通过另一个节点 (RH1),因此 E8 和 RH4 看起来就像连接到 RH1 一样。事实上,他们不应该是。 这是导致此问题的代码:

var cy = cytoscape({
  container: document.getElementById('cy'),
  style: [{
    selector: 'node',
    style: {
      'background-color': 'mapData(activation, -1, 1, blue, red)',
      'label': 'data(id)'
    }
  }, {
    selector: 'edge',
    style: {
      'width': 3,
      'line-color': function(ele) {
        return ele.data('relation')
      },
      'target-arrow-color': function(ele) {
        return ele.data('relation')
      },
      'target-arrow-shape': 'triangle'
    }
  }],
  layout: {
    name: 'breadthfirst'
  },
  elements: {
    nodes: [{
        group: 'nodes',
        data: {
          id: 'E1',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E2',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E3',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E4',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E5',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E6',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E7',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E8',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'LH1',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'RH1',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'LH2',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'LH3',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'RH2',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'LH4',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'RH3',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'RH4',
          activation: 0
        }
      }
    ],
    edges: [{
        group: 'edges',
        data: {
          id: 'edge0',
          source: 'E4',
          target: 'E5',
          relation: 'green'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge1',
          source: 'E6',
          target: 'E7',
          relation: 'green'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge2',
          source: 'LH1',
          target: 'E1',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge3',
          source: 'LH1',
          target: 'RH1',
          relation: 'green'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge4',
          source: 'LH2',
          target: 'E4',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge5',
          source: 'LH3',
          target: 'E4',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge6',
          source: 'LH4',
          target: 'E6',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge7',
          source: 'RH1',
          target: 'E2',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge8',
          source: 'RH1',
          target: 'E3',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge9',
          source: 'RH2',
          target: 'E5',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge10',
          source: 'RH3',
          target: 'E7',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge11',
          source: 'RH4',
          target: 'E8',
          relation: 'red'
        }
      }
    ]
  }
});
body {
  font: 14px helvetica neue, helvetica, arial, sans-serif;
}

#cy {
  height: 100%;
  width: 100%;
  position: absolute;
  left: 0;
  top: 0;
}
<html>

<head>
  <script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
</head>

<body>
  <div id="cy"></div>
</body>

</html>

这个问题的原因是'breadthfirst'布局把节点放在特定的地方,而且边必须是直的吗?有没有办法制作不穿过其他节点的弯曲边缘?或者答案在别处?

谢谢

您使用的是广度优先布局,这就是问题所在:

As you can read here, the breadthfirst layout puts nodes in a hierarchy, based on a breadthfirst traversal of the graph. It is best suited to trees and forests in its default top-down mode, and it is best suited to DAGs in its circle mode.

您正在一组未连接的随机元素中使用此布局,这更适合像 Dagre-Layout 这样的布局:

var cy = cytoscape({
  container: document.getElementById('cy'),
  style: [{
    selector: 'node',
    style: {
      'background-color': 'mapData(activation, -1, 1, blue, red)',
      'label': 'data(id)'
    }
  }, {
    selector: 'edge',
    style: {
      'width': 3,
      'line-color': function(ele) {
        return ele.data('relation')
      },
      'target-arrow-color': function(ele) {
        return ele.data('relation')
      },
      'target-arrow-shape': 'triangle'
    }
  }],
  layout: {
    name: 'dagre'
  },
  elements: {
    nodes: [{
        group: 'nodes',
        data: {
          id: 'E1',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E2',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E3',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E4',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E5',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E6',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E7',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'E8',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'LH1',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'RH1',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'LH2',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'LH3',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'RH2',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'LH4',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'RH3',
          activation: 0
        }
      },
      {
        group: 'nodes',
        data: {
          id: 'RH4',
          activation: 0
        }
      }
    ],
    edges: [{
        group: 'edges',
        data: {
          id: 'edge0',
          source: 'E4',
          target: 'E5',
          relation: 'green'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge1',
          source: 'E6',
          target: 'E7',
          relation: 'green'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge2',
          source: 'LH1',
          target: 'E1',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge3',
          source: 'LH1',
          target: 'RH1',
          relation: 'green'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge4',
          source: 'LH2',
          target: 'E4',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge5',
          source: 'LH3',
          target: 'E4',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge6',
          source: 'LH4',
          target: 'E6',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge7',
          source: 'RH1',
          target: 'E2',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge8',
          source: 'RH1',
          target: 'E3',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge9',
          source: 'RH2',
          target: 'E5',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge10',
          source: 'RH3',
          target: 'E7',
          relation: 'red'
        }
      },
      {
        group: 'edges',
        data: {
          id: 'edge11',
          source: 'RH4',
          target: 'E8',
          relation: 'red'
        }
      }
    ]
  }
});
body {
  font: 14px helvetica neue, helvetica, arial, sans-serif;
}

#cy {
  height: 100%;
  width: 100%;
  position: absolute;
  left: 0;
  top: 0;
}
<html>

<head>
  <script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
  <script src="https://unpkg.com/dagre@0.7.4/dist/dagre.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/cytoscape-dagre@2.1.0/cytoscape-dagre.min.js"></script>
</head>

<body>
  <div id="cy"></div>
</body>

</html>

Dagre使用DAG(有向无环图)算法组织图,更适合像这样的非连通图。

PS:请重新审视您的旧问题并添加要求的答案(您作为评论发布)。谢谢