這是基于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/