基于 HTML5 Canvas 绘制的电信网络拓扑图
電信網(wǎng)結(jié)構(gòu)(telecommunication network structure)是指電信網(wǎng)各種網(wǎng)路單元按技術(shù)要求和經(jīng)濟(jì)原則進(jìn)行組合配置的組合邏輯和配置形式。組合邏輯描述網(wǎng)路功能的體系結(jié)構(gòu),配置形式描述網(wǎng)路單元的鄰接關(guān)系,即以交換中心(或節(jié)點(diǎn))和傳輸鏈路所組成的拓?fù)浣Y(jié)構(gòu)。常見(jiàn)的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)有星型結(jié)構(gòu)、總線結(jié)構(gòu)、環(huán)形結(jié)構(gòu)、樹(shù)形結(jié)構(gòu)、網(wǎng)狀結(jié)構(gòu)、混合型拓?fù)湟约胺涓C拓?fù)浣Y(jié)構(gòu)等,本文的例子主要描繪的是總線型拓?fù)?#xff0c;在顯示上相對(duì)其他的結(jié)構(gòu)類型來(lái)說(shuō)更清晰明了,繪制起來(lái)也非常容易。
雖然題目起的名字是電信網(wǎng)絡(luò)拓?fù)鋱D,幾乎所有的拓?fù)鋱D都能涵蓋,例如基本網(wǎng)絡(luò)圖,網(wǎng)絡(luò)拓?fù)鋱D,機(jī)架圖,網(wǎng)絡(luò)通信圖,3D網(wǎng)絡(luò)圖等等。
效果圖如下:
這個(gè)圖看起來(lái)挺簡(jiǎn)單的,代碼也少,但是內(nèi)容不少。
首先,機(jī)柜01、機(jī)柜02、機(jī)柜03 都是 ht.Group?“組”類型,ht.Group 類型用于作為父容器包含孩子圖元,在 GraphView 拓?fù)鋱D(http://www.hightopo.com)上可通過(guò)雙擊進(jìn)行展開(kāi)合并,合并時(shí)會(huì)自定隱藏子孫圖元節(jié)點(diǎn), 如果有子節(jié)點(diǎn)有連線連接到外部時(shí),合并的 Group 將代理進(jìn)行連接。Group 的移動(dòng)會(huì)帶動(dòng)孩子節(jié)點(diǎn)跟隨, 孩子的位置和大小變化也會(huì)影響 Group 的展開(kāi)圖形和 position 位置。
這邊提到一個(gè)代理連線的問(wèn)題,“代理”兩個(gè)字可以很好地表明代理連線意義。實(shí)際上就是如果組內(nèi)部的節(jié)點(diǎn)與組外部的節(jié)點(diǎn)有連線,那么在組合并的時(shí)候,會(huì)在這個(gè)組會(huì)“代理”與外部節(jié)點(diǎn)之間的連線,這個(gè)就是代理連線。我們拿機(jī)柜02來(lái)說(shuō)吧,機(jī)柜02內(nèi)部有一個(gè)“電腦”與“內(nèi)部網(wǎng)絡(luò)交換機(jī)”之間有兩條連線,那么當(dāng)我們雙擊機(jī)柜02合并時(shí),實(shí)際上就相當(dāng)于機(jī)柜02與“內(nèi)部網(wǎng)絡(luò)交換機(jī)”之間有兩條連線了。
那么,我們來(lái)看看如何繪制這個(gè)組以及組內(nèi)部的節(jié)點(diǎn)吧,先創(chuàng)建“機(jī)柜02”的 Group 節(jié)點(diǎn),因?yàn)檎麄€(gè)例子我創(chuàng)建了三個(gè) Group 節(jié)點(diǎn),而且創(chuàng)建的方式都類似,因此把創(chuàng)建組的代碼封裝起來(lái)復(fù)用:
function createGroup(name, x, y) {var group = new ht.Group();//組類型 實(shí)際上也是一個(gè)節(jié)點(diǎn)group.setExpanded(true);//設(shè)置展開(kāi)組group.setName(name);//設(shè)置組的名字group.s({//設(shè)置組的樣式style'group.title.background': 'rgba(14,36,117,0.80)',//組展開(kāi)后的title背景顏色,僅對(duì)group.type為空的類型起作用'group.background': 'rgba(14,36,117,0.40)',//組展開(kāi)后的背景顏色'group.title.align': 'center'//組展開(kāi)后的title文字水平對(duì)齊方式,默認(rèn)值為'left',可設(shè)置為center和right });group.setPosition(x, y);//設(shè)置組的位置group.setImage('images/服務(wù)器.json');//設(shè)置拓?fù)渖险宫F(xiàn)的圖片信息,在GraphView拓?fù)鋱D中圖片一般以position為中心繪制dataModel.add(group);//將創(chuàng)建的組節(jié)點(diǎn)添加進(jìn)數(shù)據(jù)容器中return group; }組是可以通過(guò)雙擊展開(kāi)合并的,展開(kāi)的時(shí)候顯示的是一個(gè)有標(biāo)題欄的框(當(dāng)然這些都是可以自定義的),合并的時(shí)候就顯示上面代碼中設(shè)置的 group.setImage 中的圖片。
所有機(jī)柜內(nèi)部的節(jié)點(diǎn)都是 ht.Node 類型的節(jié)點(diǎn),所以我也封裝了一下:
function createNode(image, parent, x, y) {var node = new ht.Node();//創(chuàng)建一個(gè) Node 節(jié)點(diǎn)if (image) node.setImage(image);//設(shè)置節(jié)點(diǎn)的顯示圖片if (parent) node.setParent(parent);//設(shè)置節(jié)點(diǎn)的父親if (x && y) node.setPosition(x, y);//設(shè)置節(jié)點(diǎn)的位置dataModel.add(node);//將節(jié)點(diǎn)添加進(jìn)數(shù)據(jù)容器中return node; }生成機(jī)柜02:
cabinet = createGroup('機(jī)柜02', 146, 445);//創(chuàng)建機(jī)柜02 createNode('images/正常.json', cabinet, 78, 440).s('label', '數(shù)據(jù)監(jiān)控分析系統(tǒng)');//創(chuàng)建帶有“正常”圖片的節(jié)點(diǎn),并設(shè)置這個(gè)節(jié)點(diǎn)的文字為“數(shù)據(jù)監(jiān)控分析系統(tǒng)”因?yàn)檫B線需要的是“源節(jié)點(diǎn)”以及“終節(jié)點(diǎn)”,這邊源節(jié)點(diǎn)是中間的“內(nèi)部網(wǎng)絡(luò)交換機(jī)”,我們?cè)賱?chuàng)建這個(gè)節(jié)點(diǎn):
var line = createNode();//創(chuàng)建一個(gè)節(jié)點(diǎn) line.setSize(725, 20);//設(shè)置節(jié)點(diǎn)大小 line.setPosition(310, 325);//設(shè)置節(jié)點(diǎn)位置 line.s({//設(shè)置節(jié)點(diǎn)的style屬性'shape': 'roundRect',//決定shape的形狀,默認(rèn)值為空,代表用image繪制。roundRect四周圓角矩形'shape.background': 'rgba(14,36,117,0.80)',//背景填充顏色,為null代表不填充背景'shape.border.color': '#979797',//邊框顏色'shape.corner.radius': 10,//該參數(shù)指定roundRect類型的圓角半徑,默認(rèn)為空系統(tǒng)自動(dòng)調(diào)節(jié),可設(shè)置正數(shù)值'label': '內(nèi)部網(wǎng)絡(luò)交換機(jī)', //文字內(nèi)容,默認(rèn)為空'label.position': 45,//文字內(nèi)容,默認(rèn)為空'label.offset.x': 50,//文字水平偏移,對(duì)于Edge意味著沿著連線方向水平偏移'label2': '內(nèi)部網(wǎng)絡(luò)交換機(jī)',//HT默認(rèn)除了label.*的屬性外,還提供了label2.*的屬性,用于滿足一個(gè)圖元需要顯示雙文字的情況'label2.position': 48,'label2.offset.x': 50,'label2.offset.y': 2, });不知道你們有沒(méi)有注意到,有一個(gè) label2 的樣式屬性,這個(gè)是 HT 為了能在一個(gè)節(jié)點(diǎn)上添加兩個(gè) label 文本而增加的功能,label 屬性和 label2 的屬性是完全相同的,只要在設(shè)置屬性的時(shí)候用 label 和 label2 區(qū)分開(kāi)來(lái)就可以。
源節(jié)點(diǎn)和終節(jié)點(diǎn)都具備了,可以制作連線了:
createEdge(line, createNode('images/電腦.json', cabinet, 185, 450), 'rgb(30,232,178)', -100, true); //參數(shù)1 源節(jié)點(diǎn),參數(shù)2 終節(jié)點(diǎn),參數(shù)3 連線顏色,參數(shù)4 連線起始點(diǎn)的水平偏移,參數(shù)5 是否創(chuàng)建兩條連線還有一點(diǎn)有趣的,“交換機(jī)”的部分,最左側(cè)藍(lán)色方形的節(jié)點(diǎn)和中間長(zhǎng)條的節(jié)點(diǎn)并不是一體的,而是分離的,但是我通過(guò) setHost 進(jìn)行節(jié)點(diǎn)與節(jié)點(diǎn)間的吸附,然后反吸附回來(lái),這樣操作上就相當(dāng)于這兩個(gè)節(jié)點(diǎn)是一體的:
var exchange = createNode('images/交換機(jī).json', null, -53, 313); exchange.setHost(line);//設(shè)置吸附 line.setHost(exchange);//反吸附 又設(shè)置line的吸附為exchange因?yàn)?HT 會(huì)按照節(jié)點(diǎn)添加進(jìn)數(shù)據(jù)容器中的順序來(lái)進(jìn)行層次的排列,我的交換機(jī)是在 line 的添加之后的,所以默認(rèn)交換機(jī)的節(jié)點(diǎn)會(huì)顯示在 line 之下,我們將默認(rèn)的層級(jí)顯示關(guān)閉,并設(shè)置交換機(jī) exchange 顯示在數(shù)據(jù)容器的頂部:
dataModel.setAutoAdjustIndex(false);//將自動(dòng)調(diào)整data在容器中索引順序的開(kāi)關(guān)關(guān)閉 dataModel.sendToTop(exchange);//將data在拓?fù)渖现庙?/span>?代碼就是這些,還有不懂的可以留言或者私信我也可以,大家一起探討。
轉(zhuǎn)載于:https://www.cnblogs.com/xhload3d/p/8377854.html
總結(jié)
以上是生活随笔為你收集整理的基于 HTML5 Canvas 绘制的电信网络拓扑图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 带参数的宏替换
- 下一篇: 2017年html5行业报告,云适配发布