其實能真正體現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);
}
}
},

現在,就算有再多復雜的連線,也可以快速將自己關心的清晰顯示出來
