Cytoscape.js 网络图

这是基于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的实例
Cytoscape.js 网络图_第1张图片
以上是完整的网络图实例,下面介绍下关于网络图自己用过的其他方法。

//获取视口的范围,这是模型坐标中的一个边界框,它允许您知道在视口中可见的模型位置。
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/

你可能感兴趣的:(原创,Cytoscape.js,vue,js)