Cytoscape.js — 浏览器里画网络图、跑图算法的 JS 库
是什么
Cytoscape.js 是一个让浏览器里能画”点和线”组成的网络图、还能跑各种图算法的 JavaScript 库。日常类比:把人际关系图、地铁线路图、蛋白质相互作用网络这些「节点 + 连线」结构搬到网页上,既能拖、能缩、能上色,也能问它「从北京站到天安门最短几步」。
你写:
const cy = cytoscape({ container: document.getElementById('cy'), elements: [ { data: { id: 'a' } }, { data: { id: 'b' } }, { data: { id: 'e1', source: 'a', target: 'b' } } ], layout: { name: 'cose' }});浏览器里立刻出现两个圆 + 一条线,自动排好版,鼠标可拖。这就是 Cytoscape.js 的最小例子。
为什么重要
不理解 Cytoscape.js,下面这些事都没法解释:
- 为什么生物信息学论文几乎都用它画蛋白质互作网络——母项目 Cytoscape 桌面版被引超 5 万次
- 为什么很多知识图谱前端直接挑它而不是 D3——D3 要自己写碰撞检测、布局、缩放,Cytoscape.js 全内置
- 为什么它能在浏览器里跑 Dijkstra / PageRank / 介数中心性——它把图算法 API 从桌面版移植了过来
- 为什么 GitHub 上 1 万星的图可视化库里它和 Sigma.js / vis-network 三足鼎立,而它在学术圈占有率最高
核心要点
Cytoscape.js 的脑子可以拆成 四件事:
-
Element(元素):节点和边都叫 element,统一用
{ data: {...} }描述。类比:每张拼图块都贴一张身份证。 -
Selector(选择器):像 CSS 一样筛元素。
cy.$('node[weight > 50]')选所有权重大于 50 的节点。学过 jQuery 的人 5 分钟就上手。 -
Layout(布局):决定每个节点摆在哪。内置
grid/circle/concentric/breadthfirst/cose(力导向)等,扩展生态里还有dagre(树状)/klay/fcose/elk/cola,加起来上百种布局任选。 -
Algorithm(图算法):BFS、DFS、Dijkstra、A*、Floyd-Warshall、Kruskal 最小生成树、PageRank、介数中心性、社区检测——一行 API 调用。这点是学术工具的底气。
四件事打通后,Cytoscape.js 既是可视化库,也是图算法库,可在 headless 模式(不渲染只算)里当后端用。
实践案例
案例 1:知识图谱前端浏览器
把 Wikidata 抽出来的「人 - 作品 - 时代」三元组喂进去,调一个 cose-bilkent 布局,鼠标点节点展开邻居,点边看关系类型。50 行代码搞定一个迷你 graph explorer。
案例 2:跑最短路
const dijkstra = cy.elements().dijkstra({ root: '#beijing', weight: edge => edge.data('km')});const path = dijkstra.pathTo(cy.$('#tianjin'));console.log(path.map(el => el.id()));path 就是一串元素,包含节点和边交替——直接拿去高亮(加 class path-on)即可让用户看到红色路线。
案例 3:生物信息蛋白质网络
cy.add(proteinNetwork); // 几千节点 + 几万边cy.layout({ name: 'fcose' }).run();const central = cy.elements().betweennessCentrality();cy.nodes().forEach(n => { n.style('width', central.betweenness(n) * 50 + 10);});跑完介数中心性,节点大小自动反映「桥接重要性」。这是 Cytoscape 桌面版插件最经典的工作流,现在浏览器里也能跑。
踩过的坑
-
大图(>5 万节点)会卡:Canvas 渲染不分块,DOM 事件每帧触发一次 hit-test。解法:开
pixelRatio: 1+ 关textureOnViewport: false+ 用headless算完再渲染子图,或换 Sigma.js(WebGL)。 -
布局是异步的:
cy.layout({ name: 'cose' }).run()立刻返回,但节点位置还没算完。要监听layoutstop事件再操作,或await layout.promiseOn('layoutstop')。 -
样式选择器和 CSS 不完全一样:没有
:hover,要用 mouseover 事件 + class 切换;:selected是有的但要先开selectionType。新人常以为是 CSS 写错。 -
生态分两半:核心库
cytoscape体积小,但cose-bilkent/dagre/popper/cxtmenu这些扩展是另装。npm install cytoscape-cose-bilkent后还要cytoscape.use(coseBilkent)注册一次。 -
元素 id 不能改:一旦
cy.add({ data: { id: 'x' } }),id 是只读的;想换得remove再add。和数据库主键一样的语义,但文档里写得不显眼。 -
数据更新要走 API,不能直接改对象:
node.data().weight = 5不会触发样式重算,必须node.data('weight', 5)。直接赋值在内存里改了但视图没刷新。
适用 vs 不适用场景
适用:
- 中小规模网络图(< 5 万节点)的浏览器可视化
- 需要图算法 + 可视化一体的研究/教学工具
- 知识图谱、社交网络、引用网络、生物网络的快速原型
- 桌面 Cytoscape 用户想把工作流搬到网页
不适用:
- 超大规模(百万节点)→ 用 WebGL 方案:Sigma.js / Graphology + Sigma / Cosmograph
- 严格 2D 几何关系(地铁地图、电路图)→ D3 + 自定义 SVG 更灵活
- 只要画一个静态 DAG → Mermaid / Graphviz 更省事
- 3D 网络 → 用 3d-force-graph / threejs
历史小故事(可跳过)
- 2002 年:以色列人 Gary Bader 在多伦多大学搭出 Cytoscape 桌面版(Java),生物学家用它画蛋白质网络,论文成了 Bioinformatics 史上最常被引的软件论文之一。
- 2013 年:Bader 实验室的 Max Franz 想让网页里也能用,重写出 Cytoscape.js。第一版只有布局和渲染,没有算法。
- 2016 年:Bioinformatics 上正式发表论文,把图算法 API 补齐,从此学术圈有了「浏览器里也能跑图分析」的标配。
- 2024 年至今:核心库由 Max Franz 继续维护,扩展生态由社区贡献,已支撑 KEGG / Reactome / WikiPathways / NDEx 等大型生物数据库的网页前端。
学到什么
- 可视化和算法可以共用一份数据结构——Cytoscape.js 的 Collection 既能画也能算,省去前后端两次建模
- 选择器抽象让操作图就像操作 DOM,门槛比直接写 D3 低一截
- 布局是搜索/优化问题,不是简单几何——力导向、层次化、正交各有所长,没万能方案
- 学术软件的传播力靠两点:跨平台(浏览器 > 桌面 Java)+ 友好 API。Cytoscape.js 两条都占了
- headless 模式让一个”画图库”能在 Node.js 里当批处理算图工具,复用同一套 API——边界设计的胜利
延伸阅读
- 官网交互教程:js.cytoscape.org(10 分钟把核心概念跑一遍)
- 论文 3 页:Bioinformatics 2016(极简,主要看 API 总览)
- 扩展索引:blog.js.cytoscape.org/extensions(选布局/右键菜单/工具提示前先看)
- graphrag —— 知识图谱 + RAG,前端常用 Cytoscape.js 展示检索路径
- d3 —— 更底层、更灵活,但要自己造很多轮子
一句话上手清单
如果今天就要起一个 Cytoscape.js 项目,按这五步走最少坑:
npm i cytoscape装核心,先跑通官网最小例子- 选定布局:树状选
dagre,自由网络选fcose或cose-bilkent,分层无环选elk - 把数据规范化成
{ nodes: [...], edges: [...] }两份数组,再合并喂给elements - 样式用「选择器 + 属性」批量定义,不要给每个元素单独设 style
- 算法和渲染分开:先 headless 算完中心性/路径,再把结果当数据回写到节点上驱动样式
关联
- graphrag —— GraphRAG 的可视化层经常用 Cytoscape.js
- memgraph —— Memgraph Lab 等图数据库 GUI 的网页端常基于 Cytoscape.js
- observable-framework —— 数据笔记本里嵌图谱可视化的常见组合
- chaitin-graph-coloring —— 图算法的另一面:寄存器分配里的着色问题
反向链接
- chaitin-graph-coloring —— Chaitin 图染色寄存器分配 — 把硬件资源问题翻译成数学问题
- d3 —— D3.js — 不是图表库,是写图表库的乐高
- graphrag —— GraphRAG — 微软的知识图谱 + RAG