Merge "Move adsal into its own subdirectory."
[controller.git] / opendaylight / adsal / web / root / src / main / resources / js / open-topology.js
1 /** COMMON * */
2 var labelType, useGradients, nativeTextSupport, animate;
3
4 (function() {
5     var ua = navigator.userAgent, iStuff = ua.match(/iPhone/i)
6             || ua.match(/iPad/i), typeOfCanvas = typeof HTMLCanvasElement, nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'), textSupport = nativeCanvasSupport
7             && (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
8     // I'm setting this based on the fact that ExCanvas provides text support
9     // for IE
10     // and that as of today iPhone/iPad current text support is lame
11     labelType = (!nativeCanvasSupport || (textSupport && !iStuff)) ? 'Native'
12             : 'HTML';
13     nativeTextSupport = labelType == 'Native';
14     useGradients = nativeCanvasSupport;
15     animate = !(iStuff || !nativeCanvasSupport);
16 })();
17
18 /** TOPOLOGY * */
19 one.topology = {};
20
21 one.topology.option = {
22     navigation : function(enable, panning, zooming) {
23         var option = {};
24         option["enable"] = enable;
25         option["panning"] = panning;
26         option["zooming"] = zooming;
27         return option;
28     },
29     node : function(overridable, color, height, dim) {
30         var option = {};
31         option["overridable"] = overridable;
32         option["color"] = color;
33         option["height"] = height;
34         option["dim"] = dim;
35         return option;
36     },
37     edge : function(overridable, color, lineWidth, epsilon) {
38         var option = {};
39         option["overridable"] = overridable;
40         option["color"] = color;
41         option["lineWidth"] = lineWidth;
42         if (epsilon != undefined)
43             option["epsilon"] = epsilon;
44         return option;
45     },
46     label : function(style, node) {
47         var marginTop, minWidth;
48         if (node.data["$type"] == "switch") {
49             marginTop = "42px";
50             minWidth = "65px";
51         } else if (node.data["$type"] == "host") {
52             marginTop = "48px";
53             minWidth = "";
54         } else if (node.data["$type"].indexOf("monitor") == 0) {
55             marginTop = "52px";
56             minWidth = "";
57         }
58         style.marginTop = marginTop;
59         style.minWidth = minWidth;
60         style.background = "rgba(68,68,68,0.7)";
61         style.borderRadius = "4px";
62         style.color = "#fff";
63         style.cursor = "default";
64     }
65 };
66
67 one.topology.init = function(json) {
68     if (json.length == 0) {
69         $div = $(document.createElement('div'));
70         $img = $(document.createElement('div'));
71         $img.css('height', '128px');
72         $img.css('width', '128px');
73         $img.css('background-image', 'url(/img/topology_view_1033_128.png)');
74         $img.css('clear', 'both');
75         $img.css('margin', '0 auto');
76         $p = $(document.createElement('p'));
77         $p.addClass('text-center');
78         $p.addClass('text-info');
79         $p.css('width', '100%');
80         $p.css('padding', '10px 0');
81         $p.css('cursor', 'default');
82         $p.append('No Network Elements Connected');
83         $div.css('position', 'absolute');
84         $div.css('top', '25%');
85         $div.css('margin', '0 auto');
86         $div.css('width', '100%');
87         $div.css('text-align', 'center');
88         $div.append($img).append($p);
89         $("#topology").append($div);
90         return false;
91     }
92     one.topology.graph = new $jit.MultiTopology(
93             {
94                 injectInto : 'topology',
95                 Navigation : one.topology.option.navigation(true,
96                         'avoid nodes', 10),
97                 Node : one.topology.option.node(true, '#444', 25, 27),
98                 Edge : one.topology.option.edge(true, '23A4FF', 1.5),
99                 Tips : {
100                     enable : true,
101                     type : 'auto',
102                     offsetX: 15,
103                     offsetY: 15,
104                     onShow : function(tip, node) {
105                         if (node.name != undefined)
106                             tip.innerHTML = "Name : " + node.name + "<br>";
107                         if(node.data["$type"]!=undefined)
108                             tip.innerHTML = tip.innerHTML + "Type : " + node.data["$type"] + "<br>";
109                         if(node.data["$desc"]!=undefined)
110                             tip.innerHTML = tip.innerHTML + "Description : " + node.data["$desc"];
111                     }
112                 },
113                 Events : {
114                     enable : true,
115                     type : 'Native',
116                     onMouseEnter : function(node, eventInfo, e) {
117                         // if node
118                         if (node.id != undefined) {
119                             one.topology.graph.canvas.getElement().style.cursor = 'move';
120                         } else if (eventInfo.edge != undefined
121                                 && eventInfo.edge.nodeTo.data["$type"] == "switch"
122                                 && eventInfo.edge.nodeFrom.data["$type"] == "switch") {
123                             one.topology.graph.canvas.getElement().style.cursor = 'pointer';
124                         }
125                     },
126                     onMouseLeave : function(node, eventInfo, e) {
127                         one.topology.graph.canvas.getElement().style.cursor = '';
128                     },
129                     // Update node positions when dragged
130                     onDragMove : function(node, eventInfo, e) {
131                         var pos = eventInfo.getPos();
132                         node.pos.setc(pos.x, pos.y);
133                         one.topology.graph.plot();
134                         one.topology.graph.canvas.getElement().style.cursor = 'crosshair';
135                     },
136                     // Implement the same handler for touchscreens
137                     onTouchMove : function(node, eventInfo, e) {
138                         $jit.util.event.stop(e); // stop default touchmove
139                         // event
140                         this.onDragMove(node, eventInfo, e);
141                     },
142                     onDragEnd : function(node, eventInfo, e) {
143                         var ps = eventInfo.getPos();
144                         var did = node.id;
145                         var data = {};
146                         data['x'] = ps.x;
147                         data['y'] = ps.y;
148                         $.post('/controller/web/topology/node/' + did, data);
149                     },
150                     onClick : function(node, eventInfo, e) {
151                         if (one.f.topology === undefined) {
152                             return false;
153                         } else {
154                             one.f.topology.Events.onClick(node, eventInfo);
155                         }
156                     }
157                 },
158                 iterations : 200,
159                 levelDistance : 130,
160                 onCreateLabel : function(domElement, node) {
161                     var nameContainer = document.createElement('span'), closeButton = document
162                             .createElement('span'), style = nameContainer.style;
163                     nameContainer.className = 'name';
164                     var nodeDesc = node.data["$desc"];
165                     if (nodeDesc == "None" || nodeDesc == ""
166                             || nodeDesc == "undefined" || nodeDesc == undefined) {
167                         nameContainer.innerHTML = "<small>" + node.name
168                                 + "</small>";
169                     } else {
170                         nameContainer.innerHTML = nodeDesc;
171                     }
172                     domElement.appendChild(nameContainer);
173                     style.fontSize = "1.0em";
174                     style.color = "#000";
175                     style.fontWeight = "bold";
176                     style.width = "100%";
177                     style.padding = "1.5px 4px";
178                     style.display = "block";
179
180                     one.topology.option.label(style, node);
181                 },
182                 onPlaceLabel : function(domElement, node) {
183                     var style = domElement.style;
184                     var left = parseInt(style.left);
185                     var top = parseInt(style.top);
186                     var w = domElement.offsetWidth;
187                     style.left = (left - w / 2) + 'px';
188                     style.top = (top - 15) + 'px';
189                     style.display = '';
190                     style.minWidth = "28px";
191                     style.width = "auto";
192                     style.height = "28px";
193                     style.textAlign = "center";
194                 }
195             });
196
197     one.topology.graph.loadJSON(json);
198     // compute positions incrementally and animate.
199     one.topology.graph.computeIncremental({
200         iter : 40,
201         property : 'end',
202         onStep : function(perc) {
203             console.log(perc + '% loaded');
204         },
205         onComplete : function() {
206             for ( var idx in one.topology.graph.graph.nodes) {
207                 var node = one.topology.graph.graph.nodes[idx];
208                 if (node.getData("x") && node.getData("y")) {
209                     var x = node.getData("x");
210                     var y = node.getData("y");
211                     node.setPos(new $jit.Complex(x, y), "end");
212                 }
213             }
214             console.log('done');
215             one.topology.graph.animate({
216                 modes : [ 'linear' ],
217                 transition : $jit.Trans.Elastic.easeOut,
218                 duration : 0
219             });
220         }
221     });
222     one.topology.graph.canvas.setZoom(0.8, 0.8);
223 }
224
225 one.topology.update = function() {
226     $('#topology').empty();
227     $.getJSON(one.global.remoteAddress + "controller/web/topology/visual.json",
228             function(data) {
229                 one.topology.init(data);
230             });
231 }
232
233 /** INIT */
234 $.getJSON(one.global.remoteAddress + "controller/web/topology/visual.json",
235         function(data) {
236             one.topology.init(data);
237         });