Cytoscape.js 图论可视化
可视化

Cytoscape.js 图论可视化

当用户需要在浏览器中可视化并分析复杂节点—边网络,或明确要求 Cytoscape.js 时,使用此 Skill。该库擅长:有向图、无向图、混合图、自环图、多重图、复合图、随机布局图、网格图、环形图、同心圆图、广度优先层级图、CoSE 力导向图、Dagre 层级图、Cola 力导向图、知识图谱、社交网络图、依赖图、网络拓扑图。不要用于只追求超大规模 WebGL 浏览的 Sigma.js 场景、可拖拽连线的流程编辑器或普通统计图表。

yvonneyx
yvonneyx
浏览343
使用15

Skill 文件

SKILL.md
name
cytoscape-graph
title
Cytoscape.js 图论可视化
description
当用户需要在浏览器中可视化并分析复杂节点—边网络,或明确要求 Cytoscape.js 时,使用此 Skill。该库擅长:有向图、无向图、混合图、自环图、多重图、复合图、随机布局图、网格图、环形图、同心圆图、广度优先层级图、CoSE 力导向图、Dagre 层级图、Cola 力导向图、知识图谱、社交网络图、依赖图、网络拓扑图。不要用于只追求超大规模 WebGL 浏览的 Sigma.js 场景、可拖拽连线的流程编辑器或普通统计图表。

Cytoscape.js 图论可视化

在单个 HTML 文件中使用 Cytoscape.js 创建交互式图论网络。内置多种布局算法(force-directed、hierarchical、circular 等)和图论分析(最短路径、中心性、社区检测)。


核心依赖 (CDN 内联 script)

html
<​script src="https://cdn.jsdmirror.com/npm/cytoscape@3.30.4/dist/cytoscape.min.js"​><​/script​>

加载后全局可用:cytoscape 函数


HTML 模板

html
<!DOCTYPE html><​html lang="zh-CN"​><​head​>  <​meta charset="UTF-8" /​>  <​meta name="viewport" content="width=device-width, initial-scale=1.0" /​>  <​title​>Cytoscape.js 网络图<​/title​>  <​script src="https://cdn.jsdmirror.com/npm/cytoscape@3.30.4/dist/cytoscape.min.js"​><​/script​>  <​style​>    * { margin: 0; padding: 0; box-sizing: border-box; }    body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }    #cy { width: 100vw; height: 100vh; }  <​/style​><​/head​><​body​>  <​div id="cy"​><​/div​>  <​script​>    const cy = cytoscape({      container: document.getElementById('cy'),
      elements: [        // 节点        { data: { id: 'a', label: '节点 A' } },        { data: { id: 'b', label: '节点 B' } },        { data: { id: 'c', label: '节点 C' } },        { data: { id: 'd', label: '节点 D' } },        // 边        { data: { source: 'a', target: 'b', label: '关系1' } },        { data: { source: 'b', target: 'c' } },        { data: { source: 'c', target: 'd' } },        { data: { source: 'd', target: 'a' } },        { data: { source: 'a', target: 'c' } },      ],
      style: [        {          selector: 'node',          style: {            'background-color': '#4A90E2',            'label': 'data(label)',            'color': '#333',            'text-valign': 'bottom',            'text-margin-y': 8,            'font-size': '12px',            'width': 40,            'height': 40,          }        },        {          selector: 'edge',          style: {            'width': 2,            'line-color': '#ccc',            'target-arrow-color': '#ccc',            'target-arrow-shape': 'triangle',            'curve-style': 'bezier',            'label': 'data(label)',            'font-size': '10px',            'text-rotation': 'autorotate',          }        },      ],
      layout: {        name: 'cose', // 力导向布局        animate: true,      },    });  <​/script​><​/body​><​/html​>

核心 API

初始化

javascript
const cy = cytoscape({  container: document.getElementById('cy'),  // DOM 容器  elements: [...],  // 节点和边数据  style: [...],     // 样式规则  layout: { name: 'cose' },  // 布局算法});

数据格式

javascript
elements: [  // 节点  { data: { id: 'n1', label: '名称', weight: 10, group: 'A' } },  // 边  { data: { id: 'e1', source: 'n1', target: 'n2', label: '边标签', weight: 5 } },]

动态操作

javascript
// 添加节点cy.add({ data: { id: 'new', label: '新节点' } });
// 添加边cy.add({ data: { source: 'a', target: 'new' } });
// 移除元素cy.getElementById('new').remove();
// 获取所有节点cy.nodes();
// 获取某节点的邻居cy.getElementById('a').neighborhood();

布局算法

布局名说明适用场景
cose力导向(内置)通用网络图
breadthfirst层次/BFS树/DAG
circle环形排列对等节点
grid网格排列均匀分布
concentric同心圆中心性排序
random随机位置调试用
javascript
// 切换布局cy.layout({ name: 'breadthfirst', directed: true }).run();
// 力导向布局参数cy.layout({  name: 'cose',  idealEdgeLength: 100,  nodeRepulsion: 400000,  animate: true,  animationDuration: 1000,}).run();

外部布局插件

html
<!-- dagre 层次布局 --><​script src="https://cdn.jsdmirror.com/npm/cytoscape-dagre@2.5.0/cytoscape-dagre.min.js"​><​/script​><​script src="https://cdn.jsdmirror.com/npm/dagre@0.8.5/dist/dagre.min.js"​><​/script​>
<!-- cola 约束布局 --><​script src="https://cdn.jsdmirror.com/npm/cytoscape-cola@2.5.1/cytoscape-cola.min.js"​><​/script​>
javascript
// dagre 层次布局cy.layout({ name: 'dagre', rankDir: 'TB' }).run();

样式系统

选择器语法

javascript
style: [  { selector: 'node', style: { ... } },                    // 所有节点  { selector: 'edge', style: { ... } },                    // 所有边  { selector: 'node[group="A"]', style: { ... } },         // data 属性筛选  { selector: 'node:selected', style: { ... } },           // 选中状态  { selector: '.highlighted', style: { ... } },            // CSS class  { selector: 'edge[weight > 5]', style: { ... } },        // 条件筛选]

常用节点样式

javascript
{  'background-color': '#4A90E2',  'border-color': '#2C3E50',  'border-width': 2,  'width': 'data(weight)',         // 数据映射  'height': 'data(weight)',  'label': 'data(label)',  'text-valign': 'center',        // center | top | bottom  'text-halign': 'center',        // center | left | right  'font-size': '12px',  'shape': 'ellipse',             // ellipse | rectangle | round-rectangle | diamond | triangle  'opacity': 0.9,}

常用边样式

javascript
{  'width': 2,  'line-color': '#ccc',  'line-style': 'solid',          // solid | dashed | dotted  'target-arrow-shape': 'triangle',  // triangle | vee | circle | none  'target-arrow-color': '#ccc',  'curve-style': 'bezier',        // bezier | straight | taxi | segments  'label': 'data(label)',}

交互事件

javascript
// 点击节点cy.on('tap', 'node', (evt) => {  const node = evt.target;  console.log('点击节点:', node.id(), node.data());});
// 悬停节点cy.on('mouseover', 'node', (evt) => {  evt.target.style('background-color', '#E74C3C');});cy.on('mouseout', 'node', (evt) => {  evt.target.style('background-color', '#4A90E2');});
// 点击空白区域cy.on('tap', (evt) => {  if (evt.target === cy) {    console.log('点击了背景');  }});

图论分析

javascript
// 最短路径 (Dijkstra)const dijkstra = cy.elements().dijkstra('#a');const pathToD = dijkstra.pathTo(cy.$('#d'));pathToD.style('line-color', 'red');
// 度中心性cy.nodes().forEach(node => {  const degree = node.degree();  node.style('width', 20 + degree * 10);});
// BFS 遍历const bfs = cy.elements().bfs({ root: '#a', directed: true });bfs.path.style('background-color', '#2ECC71');
// 连通分量const components = cy.elements().components();console.log('连通分量数:', components.length);
// PageRankconst pr = cy.elements().pageRank();cy.nodes().forEach(node => {  node.style('width', 20 + pr.rank(node) * 200);});

常见场景示例

高亮邻居

javascript
cy.on('tap', 'node', (evt) => {  cy.elements().style('opacity', 0.2);  const node = evt.target;  const neighborhood = node.closedNeighborhood();  neighborhood.style('opacity', 1);});
cy.on('tap', (evt) => {  if (evt.target === cy) {    cy.elements().style('opacity', 1);  }});

按属性着色

javascript
const colorMap = { A: '#4A90E2', B: '#E74C3C', C: '#2ECC71' };cy.nodes().forEach(node => {  const group = node.data('group');  node.style('background-color', colorMap[group] || '#999');});

导出为图片

javascript
const png = cy.png({ full: true, scale: 2 });// png 是 base64 data URLconst link = document.createElement('a');link.href = png;link.download = 'graph.png';link.click();

注意事项

  1. 容器必须有明确的宽高#cy 需要 CSS 设置具体尺寸,否则不渲染。
  2. 节点 id 必须唯一:重复 id 会导致不可预测的行为。
  3. 边必须引用已存在的节点 idsourcetarget 对应的节点必须在 elements 中。
  4. data vs style 分离data() 存业务数据,style() 控制外观,用 data(field) 做映射。
  5. 性能:万级节点以上建议使用 hideEdgesOnViewport: truetextureOnViewport: true
  6. 布局是异步的layout.run() 后使用 layout.on('layoutstop', cb) 监听完成。
Ln 1, Col 1MarkdownSpaces: 2
No errors