这是基于vue框架的网络图案例,只实现了一部分功能,要想深入了解参考:Cytoscape.js
1、安装cytoscape.js
npm : npm install cytoscape
npm : npm install cytoscape-panzoom
2、在main.js里面配置:
import cytoscape from 'cytoscape'
import panzoom from 'cytoscape-panzoom'
panzoom(cytoscape)
一、创建一个展示网络图的窗口,html代码。
// html页面
<div :id='this.id' :style="idBackground"></div>
// 网络图数据
data() {
return {
id:'netWorkId',
idBackground: {backgroundColor: "white", height: "650px"},
filter:0.5, // edge数据展示的控制
clusterInfo:{},
networkData:{},
cy: {},
}
}
二、数据的获取
1、假数据的格式
let NetWorkData = {
data:{
"clusterInfo":['1','2'],
"nodes":[{ "id": "1", "name": "TCGA-CN-6022-01", "cluster": "2" }, { "id": "2", "name": "TCGA-CQ-5327-01", "cluster": "1" }],
"edges":[{ "id": "1_2", "source": "1", "target": "2", "edge_weight": "1" }, { "id": "1_2", "source": "1", "target": "2", "edge_weight": "1" },]
}
}
2、数据的获取和赋值
// 初始化这个方法
show(){
this.networkData = {nodes: NetWorkData.data.nodes, edges: NetWorkData.data.edges};
this.clusterInfo = NetWorkData.data.clusterInfo;
this.drawNetwork();
}
二、网络图创建的必要方法
drawNetwork(){
var elements = this.formatCoexpression(this.filter)
this.cy = this.generateCyto(elements, this.id);
// 图注的添加。样式的设置是设置classes,位置的设置是position
this.cy.add([{
group: "nodes",
data: {id: 'legend1', name: 'Cluster1', width: 30},
position: {x: 50, y: 50},
classes: 'legend1',
locked: true,
grabbable: false,
},{
group: "nodes",
data: {id: 'legend2', name: 'Cluster2', width: 30},
position: {x: 50, y: 100},
classes: 'legend2',
locked: true,
grabbable: false,
}]);
// A panzoom UI widget
this.cy.panzoom({
zoomFactor: 0.05, // zoom factor per zoom tick
zoomDelay: 45, // how many ms between zoom ticks
minZoom: 0.1, // min zoom level
maxZoom: 10, // max zoom level
fitPadding: 50, // padding when fitting
panSpeed: 10, // how many ms in between pan ticks
panDistance: 10, // max pan distance per tick
panDragAreaSize: 75, // the length of the pan drag box in which the vector for panning is calculated (bigger = finer control of pan speed and direction)
panMinPercentSpeed: 0.25, // the slowest speed we can pan by (as a percent of panSpeed)
panInactiveArea: 8, // radius of inactive area in pan drag box
panIndicatorMinOpacity: 0.5, // min opacity of pan indicator (the draggable nib); scales from this to 1.0
zoomOnly: false, // a minimal version of the ui only with zooming (useful on systems with bad mousewheel resolution)
fitSelector: undefined, // selector of elements to fit
animateOnFit: function () { // whether to animate on fit
return false;
},
fitAnimationDuration: 1000, // duration of animation on fit
// icon class names
//sliderHandleIcon: 'fa fa-minus',
sliderHandleIcon: 'ivu-icon ivu-icon-ios-remove',
zoomInIcon: 'ivu-icon ivu-icon-ios-add',
//zoomOutIcon: 'fa fa-minus',
zoomOutIcon: 'ivu-icon ivu-icon-ios-remove"',
//resetIcon: 'fa fa-expand'
resetIcon: 'ivu-icon ivu-icon-ios-resize'
})
}
generateCyto()方法:
generateCyto(elements, containerId) {
return cytoscape({
container: document.getElementById(containerId),
style: cytoscape.stylesheet().selector('node').css({
'content': 'data(name)'
}).selector('node').css({
'height': 'data(width)',
'width': 'data(width)',
'text-halign': "center",
'text-valign': "center",
'font-size':'12px',
'text-opacity':1,
'background-fit': 'cover'
}).selector('node.cluster1').css({
'background-color': '#ff9f03',
'cursor': 'pointer'
}).selector('node.cluster2').css({
'background-color': '#0075b0',
}).selector('node.legend1').css({
'background-color': '#ff9f03',
}).selector('node.legend2').css({
'background-color': '#0075b0',
}).selector('node.positiveNodeSelect').css({
'background-color': '#00FF00'
}).selector('node.negativeNodeSelect').css({
'background-color': '#FF0000'
}).selector('edge').css({
'target-arrow-shape': 'none',
'curve-style': 'bezier',
'control-point-step-size': 20,
'line-color': '#B2B2B2',
'width': 'data(weight)'
}),
elements: elements,
layout: {
name: cose, // 算法的不同展示方法
padding: 20,
boundingBox: {x1: 0, y1: 0, w: 550, h: 650},
fit: true,
},
// zoomingEnabled:false,
zoom: 1,
minZoom: 0.5,
maxZoom: 2,
ready: function () {
}
})
},
要是需要处理数据,执行例一,不需要处理数据直接把数值赋值element就可以了。
下面是处理数据的方法。 formatCoexpression()方法:
//例一
formatCoexpression() {
let elements = [];
var tempObj = {}
// 对node的处理,包括复合节点的动态添加,就是下面父节点和子节点的代码片段
if (this.networkData.nodes[0].node_number) {//自己加的判断,没有用可以删除
this.networkData.nodes.forEach(item => {
tempObj = {
id: item["id"],
name: item["name"],
cluster: item["cluster"],
node_number: item["node_number"],
width: item["node_number"] / 5,
}
elements.push({
data: tempObj,
classes: "cluster" + item["cluster"]
})
})
} else {
//父节点
this.clusterInfo.forEach(clusterItem=>{
tempObj = {
id: `cluster${clusterItem}`,
name: clusterNameMap[clusterItem],
width: 30,
height: 50
}
elements.push({
data: tempObj,
classes: "clusterParent" + clusterItem
})
});
//子节点
this.networkData.nodes.forEach(item => {
tempObj = {
id: item["id"],
name: item["name"],
//cluster: item["cluster"],
parent: `cluster${item["cluster"]}`,
width: 30
};
elements.push({
data: tempObj,
classes: "cluster" + item["cluster"]
})
})
}
// 对edge的处理,根据filter控制线显示的数据多少。
this.networkData.edges.forEach(item => {
let tempObj = {
id: item["source"] + "_" + item["target"],
source: item["source"],
target: item["target"],
weight: item["edge_weight"] * 2,
edgeWeight: item['edge_weight'],
}
if (item["edge_weight"] > this.filter) {
elements.push({
data: tempObj,
//classes:"cluster"+item["cluster"]
})
}
})
return elements
},
结果展示:
红色框内展示的是panzoom的实例
以上是完整的网络图实例,下面介绍下关于网络图自己用过的其他方法。
//获取视口的范围,这是模型坐标中的一个边界框,它允许您知道在视口中可见的模型位置。
1、this.cy.extent();
// node的点击事件
2、this.cy.nodes().on(‘click’, e => {});
//重构网络图页面的方法,得到一个新的布局,它可以用来在图中对节点进行算法定位
3、this.cy.layout({
name: cose, //数据的排列算法
boundingBox: {x1: 0, y1: 0, w: 550, h: 650}, //限制视图的展示范围。
}).run();
//对edge数据的处理
4、this.cy.edges();
//对点的样式的处理方法
5、this.cy.nodes(’.’ + this.classes).style({
‘background-color’: red;
});
//获取node样式
this.cy.nodes(’.’ + this.classes).style();
// 线的样式的处理
6、this.cy.edges().style({
// 样式
})
//获取edge样式
this.cy.edges().style();
git地址:https://github.com/Li-gm/cytoscape_Test
参考网址:https://js.cytoscape.org/