近期在Vue项目中使用jTopo来制作集群节点拓扑图,官网http://www.jtopo.com/
使用vue-cli搭建的模块化开发项目,使用第三方库最好的方式就是通过npm install xxx
安装,然后在项目
里import
xxx
来使用;但是在JTopo
官网上并没有发现有该库的npm
包,但是无论是什么项目,最终通过打包后
跑在浏览器上的肯定是一个html
文件,在Vue
中就是根目录下的index.html
,在该文件中会将webpack
打包后的
build.js
文件通过<script>
标签方式引入。同理可以认为jtopo.js
就是webpack
打包输出的文件,将其手动在
index.html
文件中通过<script>
标签方式引入即可 (万变不离其宗。。想想html引入jQuery)!!!
initTopo:function(servlist,portlist,servType,canvas) {var stage = new JTopo.Stage(canvas);var scene = new JTopo.Scene();scene.background = 'static/img/saturation.png';stage.add(scene);var cloudNode = new JTopo.Node('Root VirtualIP');cloudNode.setSize(40, 40);cloudNode.fillColor = '255,255,0';//黄cloudNode.setLocation(360,230); cloudNode.layout = {type: 'circle', radius: 150};scene.add(cloudNode);for(var i=0; i<servlist.length; i++){var node = new JTopo.CircleNode(servlist[i]);node.fillStyle = '200,255,0';node.fillColor = '0,255,255';//青node.radius = 15;node.setLocation(scene.width * Math.random(), scene.height * Math.random());node.layout = {type: 'circle', radius: 80};// var port=portlist[i]; //Hbuilder 此处(闭包前)必须要加分号 (function(index){node.click(function(event){// 渲染服务版本信息var servInfos=gobalVue.versionInfos;for(var j=0;j<servInfos.length;j++){if(servInfos[j].serverName==servlist[index]){gobalVue.$router.push({name: 'serviceDetail',params:{'servType': servType,'servPort':portlist[index],'servInfo':servInfos[j]}})}else{gobalVue.$router.push({name: 'serviceDetail',params:{'servType': servType,'servPort':portlist[index]}})}} });})(i)scene.add(node); var link = new JTopo.Link(cloudNode, node);scene.add(link);/** 此处 vue-resource与axios的区别在于 vue-resource进行了 同步设置(此处必须同步)* * */$.ajaxSettings.async = false;$.post('/nodeServController/findNodesByServPort',{'servType':servType,'servPort':portlist[i]}, function(result) {var list=result.data.content;if(list!=null && list.length>0){for(var j=0; j<list.length; j++){var vmNode = new JTopo.CircleNode(list[j].nodeName+"::"+list[j].nodeIp);vmNode.radius = 10;vmNode.fillStyle = '255,255,0';vmNode.setLocation(scene.width * Math.random(), scene.height * Math.random());if (list[j].connectState) {var info=list[j];info.lastUpdate=gobalVue.renderTime(info.lastUpdate)vmNode.fillColor = '0,255,0'; //绿vmNode.click(function(event){gobalVue.$router.push({name: 'ShowNode', params:{node: info}})});} else{vmNode.fillColor = '255,0,0';//红vmNode.click(function(event){alert('节点已断开')});}scene.add(vmNode);scene.add(new JTopo.Link(node, vmNode)); }}},"json");}JTopo.layout.layoutNode(scene, cloudNode, true);scene.addEventListener('mouseup', function(e){if(e.target && e.target.layout){JTopo.layout.layoutNode(scene, e.target, true); }});$.ajaxSettings.async = true;}
示意图:(只是测试,不要在意红配绿赛。。哦)
在此功能中总结一下问题:
1. 闭包
(function(index){node.click(function(event){// 渲染服务版本信息var servInfos=gobalVue.versionInfos;for(var j=0;j<servInfos.length;j++){if(servInfos[j].serverName==servlist[index]){gobalVue.$router.push({name: 'serviceDetail',params:{'servType': servType,'servPort':portlist[index],'servInfo':servInfos[j]}})}else{gobalVue.$router.push({name: 'serviceDetail',params:{'servType': servType,'servPort':portlist[index]}})}} });
})(i)
在为多个节点渲染点击事件时利用foreach循环,但无法将节点的点击事件进行动态渲染,只能将最后一次循环的数
据代入点击事件,此时利用到闭包:将函数内部和函数外部连接起来的桥梁 将外部参数 i 传入点击事件。
2. 此处 $post多组数据 为保证数据展示一致,使用vue-recourse 并设置同步:
// 先设置为同步,再改为异步$.ajaxSettings.async = false;$.post('/nodeServController/findNodesByServPort',{'servType':servType,'servPort':portlist[i]}, function(result) {// 请求处理},"json");$.ajaxSettings.async = true;
3. this 对象
正常情况下this对象指向全局Vue实例对象,但在node-click处和$post处 this却指向 jTopo实例 及 vue-recourse
$post 实例,所以须在全局进行重新赋值( this善变须格外注意!!!):
var gobalVue=this; // vue实例
4. 对于不同场景切换问题
要将舞台Stage设置多个Scene对象,统一渲染数据后,切换为某个场景即可设置某个Scene.visible=true;其他为
false实现。
var scene = new JTopo.Scene();
scene.visible=true; // 切换选中
scene.visible=false;