Refactor frontend JS
[controller.git] / opendaylight / 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"] == "swtch") {
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 : 'Native',
102                     onShow : function(tip, node) {
103                         if (node.name != undefined)
104                             tip.innerHTML = "";
105                         // tipsOnShow(tip, node);
106                     }
107                 },
108                 Events : {
109                     enable : true,
110                     type : 'Native',
111                     onMouseEnter : function(node, eventInfo, e) {
112                         // if node
113                         if (node.id != undefined) {
114                             one.topology.graph.canvas.getElement().style.cursor = 'move';
115                         } else if (eventInfo.edge != undefined
116                                 && eventInfo.edge.nodeTo.data["$type"] == "swtch"
117                                 && eventInfo.edge.nodeFrom.data["$type"] == "swtch") {
118                             one.topology.graph.canvas.getElement().style.cursor = 'pointer';
119                         }
120                     },
121                     onMouseLeave : function(node, eventInfo, e) {
122                         one.topology.graph.canvas.getElement().style.cursor = '';
123                     },
124                     // Update node positions when dragged
125                     onDragMove : function(node, eventInfo, e) {
126                         var pos = eventInfo.getPos();
127                         node.pos.setc(pos.x, pos.y);
128                         one.topology.graph.plot();
129                         one.topology.graph.canvas.getElement().style.cursor = 'crosshair';
130                     },
131                     // Implement the same handler for touchscreens
132                     onTouchMove : function(node, eventInfo, e) {
133                         $jit.util.event.stop(e); // stop default touchmove
134                         // event
135                         this.onDragMove(node, eventInfo, e);
136                     },
137                     onDragEnd : function(node, eventInfo, e) {
138                         var ps = eventInfo.getPos();
139                         var did = node.id;
140                         var data = {};
141                         data['x'] = ps.x;
142                         data['y'] = ps.y;
143                         $.post('/controller/web/topology/node/' + did, data);
144                     },
145                     onClick : function(node, eventInfo, e) {
146                         if (one.f.topology === undefined) {
147                             return false;
148                         } else {
149                             one.f.topology.Events.onClick(node, eventInfo);
150                         }
151                     }
152                 },
153                 iterations : 200,
154                 levelDistance : 130,
155                 onCreateLabel : function(domElement, node) {
156                     var nameContainer = document.createElement('span'), closeButton = document
157                             .createElement('span'), style = nameContainer.style;
158                     nameContainer.className = 'name';
159                     var nodeDesc = node.data["$desc"];
160                     if (nodeDesc == "None" || nodeDesc == ""
161                             || nodeDesc == "undefined" || nodeDesc == undefined) {
162                         nameContainer.innerHTML = "<small>" + node.name
163                                 + "</small>";
164                     } else {
165                         nameContainer.innerHTML = nodeDesc;
166                     }
167                     domElement.appendChild(nameContainer);
168                     style.fontSize = "1.0em";
169                     style.color = "#000";
170                     style.fontWeight = "bold";
171                     style.width = "100%";
172                     style.padding = "1.5px 4px";
173                     style.display = "block";
174
175                     one.topology.option.label(style, node);
176                 },
177                 onPlaceLabel : function(domElement, node) {
178                     var style = domElement.style;
179                     var left = parseInt(style.left);
180                     var top = parseInt(style.top);
181                     var w = domElement.offsetWidth;
182                     style.left = (left - w / 2) + 'px';
183                     style.top = (top - 15) + 'px';
184                     style.display = '';
185                     style.minWidth = "28px";
186                     style.width = "auto";
187                     style.height = "28px";
188                     style.textAlign = "center";
189                 }
190             });
191
192     one.topology.graph.loadJSON(json);
193     // compute positions incrementally and animate.
194     one.topology.graph.computeIncremental({
195         iter : 40,
196         property : 'end',
197         onStep : function(perc) {
198             console.log(perc + '% loaded');
199         },
200         onComplete : function() {
201             for ( var idx in one.topology.graph.graph.nodes) {
202                 var node = one.topology.graph.graph.nodes[idx];
203                 if (node.getData("x") && node.getData("y")) {
204                     var x = node.getData("x");
205                     var y = node.getData("y");
206                     node.setPos(new $jit.Complex(x, y), "end");
207                 }
208             }
209             console.log('done');
210             one.topology.graph.animate({
211                 modes : [ 'linear' ],
212                 transition : $jit.Trans.Elastic.easeOut,
213                 duration : 0
214             });
215         }
216     });
217     one.topology.graph.canvas.setZoom(0.8, 0.8);
218 }
219
220 one.topology.update = function() {
221     $('#topology').empty();
222     $.getJSON(one.global.remoteAddress + "controller/web/topology/visual.json",
223             function(data) {
224                 one.topology.init(data);
225             });
226 }
227
228 /** INIT */
229 $.getJSON(one.global.remoteAddress + "controller/web/topology/visual.json",
230         function(data) {
231             one.topology.init(data);
232         });