CLIENT GUI Framework
[vnfsdk/refrepo.git] / portal-catalog / src / main / webapp / catalog / js / template / topoUtil.js
1 /*\r
2  * Copyright 2016-2017 ZTE Corporation.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 var topoUtil = {};\r
17 topoUtil.topoDatas=[];\r
18 topoUtil.svgOffsetWidth = 0;\r
19 \r
20 /**\r
21  * recursive generate tree structure of the topology graph data\r
22  * @param  {[type]} rootName [description]\r
23  * @param  {[type]} rootNode [description]\r
24  * @return {[type]}          [description]\r
25  */\r
26 topoUtil.generateSortData = function(rootName,rootNode) {\r
27     for(var i=0;i<topoUtil.topoDatas.length;i++) {\r
28                 if(topoUtil.topoDatas[i].containIn == rootName){\r
29                         rootNode["children"].push(topoUtil.topoDatas[i]);       \r
30                         var currentNum = rootNode["children"].length-1; \r
31                         topoUtil.generateSortData(topoUtil.topoDatas[i].id, rootNode["children"][currentNum])\r
32                 }\r
33     }\r
34 }\r
35 \r
36 /**\r
37  * generate CP data, CP is inserted into the VDU or VNF child nodes\r
38  * @param  {[type]} cpNode   [description]\r
39  * @param  {[type]} rootNode [description]\r
40  * @return {[type]}          [description]\r
41  */\r
42 topoUtil.generateCpData = function(cpNode, rootNode) {\r
43     for(var i=0;i<cpNode.length;i++){\r
44                 for(var j=0;j<rootNode.length;j++) {\r
45                         var node = rootNode[j];\r
46                         if(cpNode[i].virtualbindsto == node.id) {\r
47                                 rootNode[j].cp.push(cpNode[i]);\r
48                                 break;\r
49                         }                                       \r
50                 }\r
51     }\r
52 }\r
53 \r
54 /**\r
55  * generate NETWORK and VL data, VL is inserted into the NETWORK child nodes\r
56  * @param  {[type]} rootNode [description]\r
57  * @return {[type]}          [description]\r
58  */\r
59 topoUtil.generateNetworkData = function(vlanNode, networkNode) {\r
60         if(networkNode.length == 0) {\r
61                 //no NETWORK, just VL\r
62                 var network = {\r
63                         subnets : vlanNode\r
64                 }\r
65                 networkNode.push(network);\r
66         } else {\r
67                 //NETWORK and VL\r
68                 for(var i=0;i<networkNode.length;i++) {\r
69                         networkNode[i].subnets = [];\r
70                         for(var j=0;j<vlanNode.length;j++){\r
71                                 var network = vlanNode[j].virtuallinksto;\r
72                                 if(network == networkNode[i].id) {\r
73                                         networkNode[i].subnets.push(vlanNode[j]);\r
74                                 }\r
75                     }\r
76                 }\r
77         }\r
78 }\r
79 \r
80 /**\r
81  * initialize topology graph data\r
82  * @param  {[type]} resp             [description]\r
83  * @param  {[type]} nodeInstanceData [description]\r
84  * @return {[type]}                  [description]\r
85  */\r
86 topoUtil.initTopoData = function(resp, nodeInstanceData) {\r
87         if(resp && resp.length > 0) {\r
88                 var datas = resp;\r
89                 var boxData = [];\r
90                 var networks = [];\r
91                 var vlanData = [];\r
92                 var cpData = [];\r
93         for(var i=0;i<datas.length;i++){        \r
94                 if (datas[i]["containIn"] == "") {\r
95                         datas[i]["containIn"] = "--";\r
96                 }\r
97                 //add the property of children for all nodes\r
98             datas[i]["children"] = [];\r
99             datas[i]["cp"] = [];\r
100             //count instances number\r
101             if (nodeInstanceData) {\r
102                 datas[i]["num"] = topoUtil.getInstanceNum(datas[i], nodeInstanceData);\r
103             }\r
104             //empty currentLinkNum\r
105             datas[i]["currentLinkNum"] = 0; \r
106             //distinguish VL, CP, NETWORK, VNF, VDU, VNFC from nodes to display topology graph\r
107             var type = datas[i]["type"];\r
108                         if (type.toUpperCase().indexOf(".VL") > -1) {\r
109                                 vlanData.push(datas[i]);\r
110                         } else if (type.toUpperCase().indexOf(".CP") > -1) {\r
111                                 cpData.push(datas[i]);\r
112                         } else if(type.toUpperCase().indexOf(".NETWORK") > -1) {\r
113                                 networks.push(datas[i]);\r
114                         } else if ((type.toUpperCase().indexOf(".VNF") > -1) || (type.toUpperCase().indexOf(".VDU") > -1) \r
115                                 || (type.toUpperCase().indexOf(".VNFC") > -1)) {\r
116                                 boxData.push(datas[i]);\r
117                         } else {\r
118                                 boxData.push(datas[i]);\r
119                         }\r
120         }\r
121         \r
122                 //generate CP nodes\r
123                 topoUtil.generateCpData(cpData, boxData);\r
124                 //generate VNF/NS tree data\r
125         var rootNode = {"children":[]};\r
126         topoUtil.topoDatas = boxData;\r
127                 topoUtil.generateSortData("--", rootNode);\r
128                 vm.topologyTab.boxTopoDatas = rootNode.children;\r
129                 //generate NETWORK and VL nodes\r
130                 topoUtil.generateNetworkData(vlanData, networks);\r
131                 vm.topologyTab.networkTopoDatas = networks;\r
132 \r
133         //draw topology graph\r
134         topoUtil.topoDatas = datas;\r
135         setTimeout("topoUtil.generateLine()", 100);\r
136         //bind window object events\r
137         topoUtil.initWindowEvent();\r
138         }\r
139 }\r
140 \r
141 /**\r
142  * get node instances number\r
143  * @param  {[type]} nodeTemplate     [description]\r
144  * @param  {[type]} nodeInstanceData [description]\r
145  * @return {[type]}                  [description]\r
146  */\r
147 topoUtil.getInstanceNum = function(nodeTemplate, nodeInstanceData) {\r
148         var num = 0;\r
149         var id;\r
150         if(nodeTemplate.properties && nodeTemplate.properties.vnfdid) {\r
151                 id = nodeTemplate.properties.vnfdid;\r
152         } else {\r
153                 id = nodeTemplate.id;\r
154         }\r
155         \r
156         if(nodeInstanceData && nodeInstanceData.length > 0) {\r
157                 for (var j=0;j<nodeInstanceData.length;j++) {\r
158                         if(nodeInstanceData[j].nodeTemplateId == id) {\r
159                                 num++;\r
160                         }\r
161                 }\r
162         }\r
163         return num;\r
164 }\r
165 \r
166 topoUtil.getLineOffset = function(index) {\r
167         return  index*15;\r
168 }\r
169 /**\r
170  * get node y coordinate offset, it is based on the total number of connections and the number of connections to \r
171  * calculate the Y coordinate offset current connection\r
172  * here's the connection refers connectsto relationship between VNC and VNC\r
173  * @param  {[type]} node   current node object\r
174  * @param  {[type]} height current DOM object cliengtHeight\r
175  * @return {[type]}        Y coordinate offset\r
176  */\r
177 topoUtil.getNodeOffset = function(node, height) {\r
178         var toNodeLinkNum = ++node.currentLinkNum;\r
179         var totalLinkNum = node.inLinks.length + node.outLinks.length;\r
180         totalLinkNum++;\r
181         return (height/totalLinkNum)*toNodeLinkNum;\r
182 }\r
183 /**\r
184  * get node object by name\r
185  * @param  {[type]} name node name\r
186  * @return {[type]}      node object data\r
187  */\r
188 topoUtil.getTopoDataById = function(id) {\r
189         var node;\r
190         for(var i=0;i<topoUtil.topoDatas.length;i++) {\r
191                 if(id == topoUtil.topoDatas[i].id) {\r
192                         node = topoUtil.topoDatas[i];\r
193                 }\r
194         }\r
195         return  node;\r
196 }\r
197 \r
198 topoUtil.pageX = function(elem) {\r
199         return  elem.offsetParent ? (elem.offsetLeft + topoUtil.pageX(elem.offsetParent)) : elem.offsetLeft;\r
200 }\r
201 \r
202 topoUtil.pageY = function(elem) {\r
203         return  elem.offsetParent ? (elem.offsetTop + topoUtil.pageY(elem.offsetParent)) : elem.offsetTop;\r
204 }\r
205 \r
206 topoUtil.getHorizontalOffset = function(elem, elemArray) {\r
207         var horizontalOffset = 0;\r
208         for(var i=0;i<elemArray.length;i++) {\r
209                 var nodeTop = topoUtil.pageY(elemArray[i]);\r
210                 var fromTop = topoUtil.pageY(elem);\r
211                 if(fromTop == nodeTop) {\r
212                         horizontalOffset = topoUtil.getLineOffset(++horizontalIndex);\r
213                 }\r
214         }\r
215         return horizontalOffset;\r
216 }\r
217 \r
218 topoUtil.getParentNode = function(elem) {\r
219         return elem.className == "app" ? topoUtil.getParentNode(elem.offsetParent) : elem.offsetParent;\r
220 }\r
221 \r
222 topoUtil.initElementSize = function() {\r
223         var height=$(".bpContainer").height();\r
224     $(".vlan").height() < height ? $(".vlan").height(height) : height;\r
225 \r
226     var networkWidth = $("#networks").width();\r
227     var topoWidth = $("#topo").width();\r
228     var bodyWidth = $("body").width();\r
229     (networkWidth+topoWidth+50) > bodyWidth ? $("body").width(networkWidth+topoWidth+topoUtil.svgOffsetWidth+10) : $("body").width($("html").width());\r
230 \r
231     var containerHeight=$(".container-fluid").height();\r
232     $(".coordinates").height(containerHeight).width($("body").width());\r
233 }\r
234 \r
235 /**\r
236  * get the widest VDU or VNF node to generate connect lines\r
237  * @return {[type]} [description]\r
238  */\r
239 topoUtil.getMaxNodeRight = function() {\r
240         var maxNode = {offsetWidth : 0};\r
241         for(var i=0;i<topoUtil.topoDatas.length;i++) {\r
242                 var node = document.getElementById(topoUtil.topoDatas[i].id);\r
243                 if(node && (maxNode.offsetWidth < node.offsetWidth)) {\r
244                         maxNode = node;\r
245                 }\r
246         }\r
247         return topoUtil.pageX(maxNode) + maxNode.offsetWidth;\r
248 }\r
249 \r
250 topoUtil.initWindowEvent = function() {\r
251         $(window.frameElement).attr('scrolling', 'auto');\r
252         $('body').css('overflow', 'scroll');\r
253         $(window).scroll(function(){\r
254                 $("#right-menu").css("top",$(window).scrollTop()); //vertical scroll\r
255                 $("#right-menu").css("right",-1*$(window).scrollLeft()); //horizontal scroll\r
256         }).unload(function(){\r
257                 $(window.frameElement).attr('scrolling', 'no');\r
258         });\r
259         //$(window).resize(topoUtil.generateLine);\r
260 }\r
261 \r
262 /**\r
263  * generate topology attachment\r
264  * connectedto represent the connection between the VNFC and VNFC, virtuallinksto represent the connection between the VLAN and VDU\r
265  * @return {[type]} [description]\r
266  */\r
267 topoUtil.generateLine = function() { \r
268         topoUtil.initElementSize();\r
269         var vduPath='';\r
270         var vlPath='';\r
271         var vduIndex=0;\r
272         var vlIndex=0;\r
273         var fromNodeArray = [];\r
274         var horizontalIndex = 0;\r
275         var maxNodeParentRight = topoUtil.getMaxNodeRight();\r
276         for(var i=0;i<topoUtil.topoDatas.length;i++) {\r
277                 //connectedto\r
278                 if(topoUtil.topoDatas[i].connectedto !=""){                     \r
279                         var fromNode = document.getElementById(topoUtil.topoDatas[i].id); \r
280                         var horizontalOffset = 0;\r
281                         for(var k=0;k<fromNodeArray.length;k++) {\r
282                                 //VNFC node in the same VDU, coordinate offset\r
283                                 var nodeTop = topoUtil.pageY(fromNodeArray[k]);\r
284                                 var fromTop = topoUtil.pageY(fromNode);\r
285                                 if(fromTop == nodeTop) {\r
286                                         horizontalOffset = topoUtil.getLineOffset(++horizontalIndex);\r
287                                 }\r
288                         }\r
289                         fromNodeArray.push(fromNode);                   \r
290                         var fromNodeParent = topoUtil.getParentNode(fromNode);\r
291                         var toArray = topoUtil.topoDatas[i].connectedto.split(",");                     \r
292                         for (var j=0;j<toArray.length;j++) {                            \r
293                                 var toNode = document.getElementById(toArray[j]); \r
294                                 var toNodeParent = topoUtil.getParentNode(toNode);\r
295                                 //Computing connection point and the connection point Y coordinate offset\r
296                                 var fromNodeOffset = topoUtil.getNodeOffset(topoUtil.topoDatas[i], fromNode.clientHeight); \r
297                                 var toNodeTopoData = topoUtil.getTopoDataById(toArray[j]);\r
298                                 var toNodeOffset = topoUtil.getNodeOffset(toNodeTopoData, toNode.clientHeight); \r
299                                 //X coordinate offset calculation link\r
300                                 var xLineOffset = topoUtil.getLineOffset(++vduIndex); \r
301                                 //Get the largest X coordinate offset is used to set the width of the body\r
302                                 topoUtil.svgOffsetWidth = Math.max(xLineOffset, topoUtil.svgOffsetWidth);\r
303                                                                 \r
304                                 var fromNodeLeft = topoUtil.pageX(fromNode);                            \r
305                                 var fromNodeRight = topoUtil.pageX(fromNode) + fromNode.offsetWidth;\r
306                                 var fromNodeTop = topoUtil.pageY(fromNode);\r
307 \r
308                                 var toNodeLeft = topoUtil.pageX(toNode);\r
309                                 var toNodeRight = topoUtil.pageX(toNode) + toNode.offsetWidth;\r
310                                 var toNodeTop = topoUtil.pageY(toNode);                         \r
311 \r
312                                 var coord = '';\r
313                                 if(fromNodeTop == toNodeTop) {\r
314                                         if(fromNodeLeft < toNodeLeft) {\r
315                                                 coord = "M"+fromNodeRight+","+(fromNodeTop+horizontalOffset+fromNodeOffset)\r
316                                                         +" L"+toNodeLeft+","+(fromNodeTop+horizontalOffset+fromNodeOffset)\r
317                                         } else {\r
318                                                 coord = "M"+fromNodeLeft+","+(fromNodeTop+horizontalOffset+fromNodeOffset)                                                      \r
319                                                         +" L"+toNodeRight+","+(fromNodeTop+horizontalOffset+fromNodeOffset);\r
320                                         }\r
321                                 } else {\r
322                                         var nodeRight = maxNodeParentRight + xLineOffset;\r
323                                         coord = "M"+fromNodeRight+","+(fromNodeTop+horizontalOffset+fromNodeOffset)\r
324                                                         +" L"+nodeRight+","+(fromNodeTop+horizontalOffset+fromNodeOffset)\r
325                                                         +" L"+nodeRight+","+(toNodeTop+toNodeOffset)\r
326                                                         +" L"+toNodeRight+","+(toNodeTop+toNodeOffset);                         \r
327                                 }\r
328                                 vduPath +='<path d="'+coord+'" marker-end="url(#arrowhead)" fill="none" stroke-dasharray="5,5" stroke="#7A7A7A" stroke-width="3px" shape-rendering="geometricPrecision"></path>';       \r
329                         }\r
330                 }\r
331 \r
332                 //virtuallinksto                \r
333                 if(topoUtil.topoDatas[i].virtuallinksto !=""){\r
334                         var fromNode = document.getElementById(topoUtil.topoDatas[i].id); \r
335                         var toArray = topoUtil.topoDatas[i].virtuallinksto.split(",");                  \r
336                         for (var j=0;j<toArray.length;j++) {\r
337                                 var toNode = document.getElementById(toArray[j]);\r
338                                 if(toNode) {\r
339                                         var yLineOffset = topoUtil.getLineOffset(j); \r
340                                         var xLineOffset = topoUtil.getLineOffset(++vlIndex); \r
341 \r
342                                         var fromNodeLeft = topoUtil.pageX(fromNode);\r
343                                         var fromNodeTop = topoUtil.pageY(fromNode);\r
344 \r
345                                         var toNodeRight = topoUtil.pageX(toNode) + toNode.offsetWidth;\r
346                                         var toNodeTop = topoUtil.pageY(toNode);\r
347 \r
348                                         var coord = "";\r
349                                         if(fromNodeTop == toNodeTop) {\r
350                                                 coord = "M"+fromNodeLeft+","+(fromNodeTop+fromNode.clientHeight/2+xLineOffset)\r
351                                                         +" L"+toNodeRight+","+(fromNodeTop+fromNode.clientHeight/2+xLineOffset);\r
352                                         } else {\r
353                                                 coord = "M"+fromNodeLeft+","+(fromNodeTop+fromNode.clientHeight/2+yLineOffset)\r
354                                                         +" L"+toNodeRight+","+(fromNodeTop+fromNode.clientHeight/2+yLineOffset);\r
355                                         }\r
356                                         vlPath +='<path d="'+coord+'" fill="none" stroke="'+toNode.style.backgroundColor+'" stroke-width="4px"></path>';\r
357                                 }                                       \r
358                         }\r
359                 }\r
360         }\r
361         \r
362         $("#svg_vdu g").html(vduPath);\r
363         $("#svg_vl g").html(vlPath);\r
364 }\r
365 \r
366 /**\r
367  * generate node table data\r
368  * @param  {[type]} data [description]\r
369  * @return {[type]}      [description]\r
370  */\r
371 topoUtil.generateNodeTemplate = function(data) {\r
372         var nodeTemplate = {};\r
373         nodeTemplate.id = data.id;\r
374         nodeTemplate.name = data.name;\r
375         nodeTemplate.type = data.type;\r
376         nodeTemplate.parentType = data.parentType;\r
377         nodeTemplate.vnfdid = ""; //only nested VNF node has value\r
378         nodeTemplate.properties = data.properties;\r
379         nodeTemplate.flavors = data.flavors;     \r
380         nodeTemplate.containIn = ""; //containIn relation which the front-end custom is used to display the topo relations of the graph\r
381         nodeTemplate.containedin = ""; //the relation between VNF and VNFC\r
382         nodeTemplate.deployedon = ""; //the relation between VDU and VNFC\r
383         nodeTemplate.connectedto = ""; //the relation between VNFC and VNFC\r
384         nodeTemplate.virtuallinksto = ""; //the relation between VL and CP or between VL and VDU\r
385         nodeTemplate.virtualbindsto = ""; //the relation between CP and VDU\r
386         nodeTemplate.outLinks = []; //a collection of connected nodes connectedto\r
387         nodeTemplate.inLinks = []; //nodes are connected connectedto relationship collection\r
388         nodeTemplate.currentLinkNum = 0;\r
389         var relationShips = data.relationShips || []; //some nodes may not have relationships\r
390         $.each(relationShips, function(index, obj){\r
391                 if (obj.sourceNodeId == data.name) {\r
392                         switch(obj.type) {\r
393                                 case "containedIn" :\r
394                                 case "tosca.relationships.nfv.ContainedIn" :\r
395                                 case "tosca.relationships.nfv.BelongTo" :\r
396                                         nodeTemplate.containedin = obj.targetNodeId;\r
397                                         break;\r
398                                 case "deployedOn" :\r
399                                 case "tosca.relationships.nfv.DeployedOn" :\r
400                                         nodeTemplate.deployedon = obj.targetNodeId;\r
401                                         break;\r
402                                 case "connectedTo" : \r
403                                 case "tosca.relationships.nfv.ConnectsTo" :\r
404                                         nodeTemplate.connectedto += "," + obj.targetNodeId;\r
405                                         nodeTemplate.outLinks.push(obj.targetNodeId);\r
406                                         break;\r
407                                 case "virtualLinksTo" :\r
408                                 case "tosca.relationships.nfv.VirtualLinksTo" :\r
409                                         nodeTemplate.virtuallinksto += "," + obj.targetNodeId;\r
410                                         break;\r
411                                 case "virtualBindsTo" :\r
412                                 case "tosca.relationships.nfv.VirtualBindsTo" :\r
413                                         nodeTemplate.virtualbindsto += "," + obj.targetNodeId;\r
414                                         break;\r
415                         }\r
416                 }\r
417                 if (obj.targetNodeId == data.name) {\r
418                         switch(obj.type) {\r
419                                 case "connectedTo" : \r
420                                 case "tosca.relationships.nfv.ConnectsTo" :\r
421                                         nodeTemplate.inLinks.push(obj.sourceNodeId);\r
422                                         break;\r
423                         }\r
424                 }\r
425         });\r
426         nodeTemplate.connectedto = nodeTemplate.connectedto.substring(1);\r
427         nodeTemplate.virtuallinksto = nodeTemplate.virtuallinksto.substring(1);\r
428         nodeTemplate.virtualbindsto = nodeTemplate.virtualbindsto.substring(1);\r
429 \r
430         if(topoUtil.isVNFType(data.type)) {\r
431         $.each(data.properties, function(key, value) {\r
432             if(key == "vnfdid" && value) {\r
433                 nodeTemplate.vnfdid = value;\r
434             }\r
435         });\r
436         }\r
437         return nodeTemplate;\r
438 }\r
439 \r
440 /**\r
441  * generate topology data\r
442  * deployedon is used to display the relation between VNFC and VDU\r
443  * containedin is used to display the relation between VNFC and VNF\r
444  * transform relations between VDU and VNF, containIn is used to display the relation between VDU and VNF\r
445  * @param  {[type]} data [description]\r
446  * @return {[type]}      [description]\r
447  */\r
448 topoUtil.generateTopoTemplate = function(data) {\r
449         for(var i=0;i<data.length;i++) {\r
450                 if(data[i].containedin){\r
451                         //assignment is designed to compatible with no VDU, only VNF and VNFC situations\r
452                         data[i].containIn = data[i].containedin;\r
453                         for(var j=0;j<data.length;j++) {\r
454                                 if(data[i].deployedon == data[j].id) {\r
455                                         data[j].containIn = data[i].containedin;\r
456                                         break;\r
457                                 }\r
458                         }\r
459                 }\r
460                 //the relationship between VNFC and VDU deployedon replace with containIn\r
461                 if(data[i].deployedon){\r
462                         data[i].containIn = data[i].deployedon;\r
463                 }\r
464         }\r
465         return data;    \r
466 }\r
467 \r
468 /**\r
469  * generate nodetemplate detail\r
470  * @param  {[type]} data [description]\r
471  * @return {[type]}      [description]\r
472  */\r
473 topoUtil.generateNodeTemplateDetail = function(data) {\r
474         var nodeTemplateDetail = {};\r
475         nodeTemplateDetail.properties = [];\r
476         var properties = data.properties;\r
477         for(var key in properties) {\r
478                 var property = {};\r
479                 property.key = key;\r
480                 property.value = properties[key];\r
481                 nodeTemplateDetail.properties.push(property);\r
482         }\r
483         //add flavor to nodetempalte properties\r
484         var flavors = data.flavors;\r
485         if(flavors && flavors.length) {\r
486                 var flavor = flavors[0];\r
487                 for(var key in flavor) {\r
488                         var property = {};\r
489                         property.key = key;\r
490                         property.value = flavor[key];\r
491                         nodeTemplateDetail.properties.push(property);\r
492                 }\r
493         }\r
494 \r
495         nodeTemplateDetail.relationShips = data.relationShips;  \r
496 \r
497         nodeTemplateDetail.general = [];\r
498         var general = {};\r
499         general.key = "name";\r
500         general.value = data.name;\r
501         nodeTemplateDetail.general.push(general);\r
502         var general = {};\r
503         general.key = "type";\r
504         general.value = data.type;\r
505         nodeTemplateDetail.general.push(general);\r
506 \r
507         return nodeTemplateDetail;\r
508 }\r
509 \r
510 topoUtil.getCurrentDetailData = function(detailDatas, nodetemplateid) {\r
511     var data;\r
512     for(var i=0; i<detailDatas.length; i++) {\r
513         if (detailDatas[i].id == nodetemplateid) {\r
514             data = topoUtil.generateNodeTemplateDetail(detailDatas[i]);\r
515             break;\r
516         }\r
517     }\r
518     return data;\r
519 }\r
520 \r
521 /**\r
522  * generate node instance detail\r
523  * a node template may correspond to multiple node instances, their properties are not the same\r
524  * @param  {[type]} data [description]\r
525  * @return {[type]}      [description]\r
526  */\r
527 topoUtil.generateNodeInstanceDetail = function(data) {\r
528         var nodeInstanceDetail = [];\r
529         nodeInstanceDetail.properties = [];\r
530         nodeInstanceDetail.general = [];        \r
531 \r
532         var properties = data.properties;\r
533         for(var i=0;i<properties.length;i++) {\r
534                 var nodeDetail = {};\r
535                 var name = data.name;           \r
536                 for(var key in properties[i]) {\r
537                         var property = {};\r
538                         property.key = key;\r
539                         property.value = properties[i][key];                    \r
540                         nodeDetail.properties.push(property);\r
541 \r
542                         if(key == "name") {\r
543                                 name = properties[i][key];\r
544                         }\r
545                 }\r
546                 var general = {};\r
547                 general.key = "name";\r
548                 general.value = name;\r
549                 nodeDetail.general.push(general);\r
550                 var general = {};\r
551                 general.key = "type";\r
552                 general.value = data.type;\r
553                 nodeDetail.general.push(general);\r
554 \r
555                 nodeDetail.relationShips = data.relationShips;\r
556                 nodeInstanceDetail.push(nodeDetail);\r
557         }\r
558         return nodeInstanceDetail;\r
559 }\r
560 \r
561 topoUtil.getCurrentNodeInstanceDetail = function(detailDatas, nodetemplateid) {\r
562     var data;\r
563     for(var i=0; i<detailDatas.length; i++) {\r
564         if (detailDatas[i].id == nodetemplateid) {\r
565             data = topoUtil.generateNodeInstanceDetail(detailDatas[i]);\r
566             break;\r
567         }\r
568     }\r
569     return data;\r
570 }\r
571 \r
572 topoUtil.getCidr = function(properties) {\r
573         for(var key in properties) {\r
574         if(key == "cidr") {\r
575                 return properties[key];\r
576         }\r
577     }\r
578 }\r
579 \r
580 topoUtil.getColor = function(index) {\r
581         var colors = ['#1F77B4','#FF7F0E','#2CA02C','#D62728','#9467BD','#8C564B','#4b6c8b','#550000','#dc322f','#FF6600'];\r
582         return colors[index%10];\r
583 }\r
584 \r
585 topoUtil.getCpTop = function(index, parentBoxId) {\r
586     var newTop = "";\r
587     var height = 0;\r
588     if(index == 0) {\r
589         var circle_top = $(".circle").css("top");\r
590         var circle_height = $(".circle").css("height");\r
591         var top = circle_top.substring(0, circle_top.length-2) - 0;\r
592         height = circle_height.substring(0, circle_height.length-2) - 0;\r
593         newTop = (top+height+10);\r
594     } else {\r
595         var circle_top = $(".smallCircle").css("top");\r
596         var circle_height = $(".smallCircle").css("height");\r
597         var top = circle_top.substring(0, circle_top.length-2) - 0;\r
598         height = circle_height.substring(0, circle_height.length-2) - 0;\r
599         newTop = (top+height*(index));\r
600     }\r
601     //if the length of cp over the box which cp is virtualbindsto, set the box min-heght attribute\r
602     var $box = $("#" + parentBoxId);\r
603         var min_height = $box.css("min-height");\r
604         var box_min_height = min_height.substring(0, min_height.length-2) - 0;\r
605         var cp_height = newTop + height;\r
606         if(cp_height > box_min_height) {\r
607                 $box.css("min-height", cp_height);\r
608         }\r
609 \r
610     return newTop + "px";\r
611 }\r
612 \r
613 topoUtil.isVNFType = function(type) {\r
614         if((type.toUpperCase().indexOf(".VNF") > -1) && (type.toUpperCase().indexOf(".VNFC") < 0)) {\r
615                 return true;\r
616         }\r
617         return false;\r
618 }