其实能真正体现TWaver特色的,不是之前的机柜和设备面板的绘制,而是今天要实现的端口连线。
制作连线前,首先要增加个“连线模式”的开关。方案很多种,我选择灵活简洁的
右键菜单
popupMenu.isVisible = function(menuItem) { var item = visibleGroup(lastData); var visible = menuItem.group === item; if(visible) { if(menuItem.label === '连线模式') { visible = !self._connectModle; } else if(menuItem.label === '视图模式') { visible = self._connectModle; } } return visible; }; popupMenu.onAction = function(menuItem) { if(menuItem.label === '连线模式') { self.createLinks(); } else if(menuItem.label === '视图模式') { self.deleteLinks(); } else if(menuItem.label === '删除设备') { self._box().remove(lastData); } };
通过右键菜单实现了“连线模式”和“视图模式”的切换。而且还可以进一步细化右键的针对性,比如在某设备上点击右键,展示的所有此设备端口的相关连线;在某机柜上点击右键,就是此机柜上所有设备端口的相关连线;在空白处点击右键,就是当前页面上所有机柜设备端口间的连线。
但是到现在还是无法直接创建连线,因为连线是连接在两个网元间的线,而我们的端口并不是,设备才是最小的网元。要创建连线,我们必须
创建临时端口网元
function createPortPoint(portData, type) { var portPoint = new twaver.Follower(portData.id); portPoint.setLocation(portData.x, portData.y); portPoint.setLayerId('deviceLayer'); portPoint.c('isPort', true); portPoint.setSize(0, 0); portPoint.setHost(portData.device); self._box.add(portPoint); return portPoint; }
这种连线模式临时创建端口网元,视图模式又将其删除掉的方式,看起来比较麻烦,但由于尽量减少了网元数量,使得展示效率得到了大大提高。
有了端口网元,连线就变得非常easy了
创建端口连线
function createPortPoint(portData, type) { var portPoint = new twaver.Follower(portData.id); portPoint.setLocation(portData.x, portData.y); portPoint.setLayerId('deviceLayer'); portPoint.c('isPort', true); portPoint.setSize(0, 0); portPoint.setHost(portData.device); self._box.add(portPoint); return portPoint; }
这样的连线看起来无疑有点太low,必须要添加
连线类型
setLinkStyle(link, styleType) { var lineColor; var portType = link.c('portType'); if(portType == 'network') { lineColor = '#00FFFF'; } else if(portType == 'power') { lineColor = '#FFFF00'; } var width = 1; var arrowWidth = 4; var arrowHeight = 3; var radius = 6; link.setStyle('link.width', width); link.setStyle('link.color', lineColor); link.setStyle('arrow.from', true); link.setStyle('arrow.from.width', arrowWidth); link.setStyle('arrow.from.height', arrowHeight); link.setStyle('arrow.from.color', lineColor); link.setStyle('arrow.to', true); link.setStyle('arrow.to.width', arrowWidth); link.setStyle('arrow.to.height', arrowHeight); link.setStyle('arrow.to.color', lineColor); link.setStyle('link.xradius', radius); link.setStyle('link.yradius', radius); },
现在顺眼多了,但是有个问题是同一排的端口的连线会重叠到一起,比如上图中下部的两条网络连线,所以需要
错开相同类型连线
createLinks: function() { this._connectModle = true; this._linksCount = { 'extend.left': 0, 'extend.right': 0, 'extend.top': 0, 'orthogonal.vertical': 0 }; …… },
var link = new twaver.Link(fromPortPoint, toPortPoint); link.setLayerId('linkLayer'); link.c('portType', portType); this.setLinkStyle(link, 'common'); var linkType = 'extend.top'; var count = this._linksCount[linkType]++; link.setStyle('link.type', linkType); if(linkType === 'orthogonal.vertical') { var offset = 0; link.setStyle('link.split.percent', 0.5 + offset); } else { link.setStyle('link.extend', 10 + 5 * count); } ……
尽管在尽量错开连线,但当连线很多的情况下,根本不可能避免连线的部分重合。一个解决办法是
突出显示当前连线
this.getView().addEventListener('click', function(e) { var element = self.getElementAt(e); if(element && element instanceof twaver.Link && element == self.getSelectionModel().getLastData()) { self._selectedLink = element; self.refreshLinks(); } else { self._selectedLink = null; self.refreshLinks(); } }, this);
refreshLinks: function() { if(this._links.length) { for(var i = 0; i < this._links.length; i++) { var link = this._links[i]; var styleType = 'common'; if(this._selectedLink) { styleType = 'unfocused'; if(link == this._selectedLink) { styleType = 'focus'; } } this.setLinkStyle(link, styleType); } } },
现在,就算有再多复杂的连线,也可以快速将自己关心的清晰显示出来