其實能真正體現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); } } },
現在,就算有再多復雜的連線,也可以快速將自己關心的清晰顯示出來