Cytoscape.js简介
-
历史:Cytoscape 创建于多伦多大学并发表在牛津生物信息学(2016 年、2023 年)。
-
Cytoscape 和 Cytoscape.js :从长远来看,Cytoscape 和 Cytoscape.js 将集成得更加紧密。Cytoscape 现在支持读写 Cytoscape.js 的网络和表 JSON 文件。另外,Cytoscape 可以将样式转换为 Cytoscape.js 的样式对象。来源。
-
特点:轻量级的图网络库,专为绘制复杂的网络图而设计,支持节点和边的可视化。
-
交互功能:内置放缩、平移、拖动、点击交互、选择节点等功能。还支持复杂的样式和动画效果。
-
适用场景:知识图谱、社交网络分析、生物网络可视化等。
-
优点:开箱即用,功能强大,支持多种布局算法(如力导向布局、同心圆布局)。
-
官网:Cytoscape.js
-
以下是 Cytoscape 支持的常用布局:
布局名称 | 特点 | 常用参数 | 适用场景 |
---|---|---|---|
Grid | 网格状排列节点 | rows , cols |
规则分布的图表 |
Circle | 节点排列成圆形 | radius , startAngle , endAngle |
环形关系、闭环网络 |
Concentric | 同心圆排列,按节点属性分层 | minNodeSpacing , levelWidth |
分层结构、中心-外围关系图 |
Breadthfirst | 基于广度优先搜索的层次布局 | root , spacingFactor , directed |
树形结构、层次关系图 |
Dagre | DAG(有向无环图)布局 | rankDir , nodeSep , rankSep |
流程图、依赖关系图 |
Cose | 力导向布局,基于物理力学模型 | idealEdgeLength , nodeRepulsion , gravity |
复杂网络、社交关系图 |
Klay | 层次化布局(需要插件) | direction , spacing , edgeSpacingFactor |
大型有向图、流程图 |
简单示例代码
运行效果
- Cytoscape 实例:
containerRef
用于引用<div>
容器。cytoscape()
函数初始化 Cytoscape 实例,并设置容器、节点和边、样式、以及布局。elements
定义了 4 个节点(A
,B
,C
,D
)和 4 条边。
- 样式:
- 节点( selector: ‘node’):蓝色背景、白色标签、圆形节点。
- 边(selector: ‘edge’):灰色线条,带箭头的曲线。
- 布局:使用
grid
布局自动排列节点。
完整代码
- 在项目中安装
cytoscape
:
npm install cytoscape
import React, { useEffect, useRef } from 'react';
import cytoscape from 'cytoscape';
const CytoscapeExample = () => {
const containerRef = useRef(null);
useEffect(() => {
// 初始化 Cytoscape 实例
const cy = cytoscape({
container: containerRef.current, // 绑定容器
elements: [
// 定义节点
{ data: { id: 'A', label: 'Node A' } },
{ data: { id: 'B', label: 'Node B' } },
{ data: { id: 'C', label: 'Node C' } },
{ data: { id: 'D', label: 'Node D' } },
// 定义边
{ data: { source: 'A', target: 'B' } },
{ data: { source: 'A', target: 'C' } },
{ data: { source: 'B', target: 'D' } },
{ data: { source: 'C', target: 'D' } }
],
style: [
{
selector: 'node',
style: {
// 'shape': 'rectangle', // 设置节点为方形
'background-color': '#007bff',
'label': 'data(label)',
'color': '#fff',
'text-valign': 'center',
'text-halign': 'center',
'width': 50,
'height': 50,
'font-size': '12px',
'border-width': 2,
'border-color': '#0056b3'
}
},
{
selector: 'edge',
style: {
'width': 2,
'line-color': '#999',
'target-arrow-shape': 'triangle',
'target-arrow-color': '#999',
'curve-style': 'bezier'
}
}
],
layout: {
name: 'grid', // 使用网格布局
rows: 2
}
});
// 清理 Cytoscape 实例
return () => {
cy.destroy();
};
}, []);
return (
<div
ref={containerRef}
style={
{ width: '100%', height: '500px', backgroundColor: '#f8f9fa' }}
/>
);
};
export default CytoscapeExample;
显示节点其他信息+点击事件
运行效果
- 节点属性:为每个节点添加了
ip
、port
、status
等属性。 - Tooltip 功能:
- 创建一个
div
元素作为 Tooltip。 - 监听
mouseover
事件来显示节点的属性。 - 监听
mousemove
事件调整 Tooltip 位置,使其跟随鼠标。 - 监听
mouseout
事件隐藏 Tooltip。
- 创建一个
完整代码
import React, { useEffect, useRef } from 'react';
import cytoscape from 'cytoscape';
const CytoscapeExample = () => {
const containerRef = useRef(null);
useEffect(() => {
// 初始化 Cytoscape 实例
const cy = cytoscape({
container: containerRef.current, // 绑定容器
elements: [
// 定义节点,包含更多属性
{ data: { id: 'A', label: 'Node A', ip: '192.168.0.1', port: 8080, status: 'online' } },
{ data: { id: 'B', label: 'Node B', ip: '192.168.0.2', port: 8081, status: 'offline' } },
{ data: { id: 'C', label: 'Node C', ip: '192.168.0.3', port: 8082, status: 'online' } },
{ data: { id: 'D', label: 'Node D', ip: '192.168.0.4', port: 8083, status: 'online' } },
// 定义边
{ data: { source: 'A', target: 'B' } },
{ data: { source: 'A', target: 'C' } },
{ data: { source: 'B', target: 'D' } },
{ data: { source: 'C', target: 'D' } }
],
style: [
{
selector: 'node',
style: {
'background-color': '#007bff',
'label': 'data(label)',
'color': '#fff',
'text-valign': 'center',
'text-halign': 'center',
'width': 50,
'height': 50,
'font-size': '12px',
'border-width': 2,
'border-color': '#0056b3'
}
},
{
selector: 'edge',
style: {
'width': 2,
'line-color': '#999',
'target-arrow-shape': 'triangle',
'target-arrow-color': '#999',
'curve-style': 'bezier'
}
}
],
layout: {
name: 'grid', // 使用网格布局
rows: 2
}
});
// 添加 Tooltip 功能
const tooltip = document.createElement('div');
tooltip.style.position = 'absolute';
tooltip.style.padding = '8px';
tooltip.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
tooltip.style.color = '#fff';
tooltip.style.borderRadius = '4px';
tooltip.style.fontSize = '12px';
tooltip.style.display = 'none';
tooltip.s