blob: 7ac9adc650514b4e7330bbd29eba4b712f6105c0 [file] [log] [blame]
Simon Hunt195cb382014-11-03 17:50:51 -08001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
Simon Hunt142d0032014-11-04 20:13:09 -080018 ONOS network topology viewer - version 1.1
Simon Hunt195cb382014-11-03 17:50:51 -080019
20 @author Simon Hunt
21 */
22
23(function (onos) {
24 'use strict';
25
Simon Hunt195cb382014-11-03 17:50:51 -080026 // configuration data
27 var config = {
Simon Hunt142d0032014-11-04 20:13:09 -080028 useLiveData: false,
Simon Hunt195cb382014-11-03 17:50:51 -080029 debugOn: false,
30 debug: {
31 showNodeXY: false,
32 showKeyHandler: true
33 },
34 options: {
35 layering: true,
36 collisionPrevention: true,
Simon Hunt142d0032014-11-04 20:13:09 -080037 showBackground: true
Simon Hunt195cb382014-11-03 17:50:51 -080038 },
39 backgroundUrl: 'img/us-map.png',
40 data: {
41 live: {
42 jsonUrl: 'rs/topology/graph',
43 detailPrefix: 'rs/topology/graph/',
44 detailSuffix: ''
45 },
46 fake: {
47 jsonUrl: 'json/network2.json',
48 detailPrefix: 'json/',
49 detailSuffix: '.json'
50 }
51 },
52 iconUrl: {
53 device: 'img/device.png',
54 host: 'img/host.png',
55 pkt: 'img/pkt.png',
56 opt: 'img/opt.png'
57 },
Simon Hunt195cb382014-11-03 17:50:51 -080058 force: {
Simon Hunt195cb382014-11-03 17:50:51 -080059 marginLR: 20,
60 marginTB: 20,
61 translate: function() {
62 return 'translate(' +
63 config.force.marginLR + ',' +
64 config.force.marginTB + ')';
65 }
Simon Hunt142d0032014-11-04 20:13:09 -080066 }
Simon Hunt195cb382014-11-03 17:50:51 -080067 };
68
Simon Hunt142d0032014-11-04 20:13:09 -080069 // radio buttons
70 var btnSet = [
Simon Hunt934c3ce2014-11-05 11:45:07 -080071 { text: 'All Layers', cb: showAllLayers },
72 { text: 'Packet Only', cb: showPacketLayer },
73 { text: 'Optical Only', cb: showOpticalLayer }
74 ];
75
76 // key bindings
77 var keyDispatch = {
78 Q: getUpdatedNetworkData,
79 B: toggleBg,
80 G: toggleLayout,
81 L: cycleLabels,
82 P: togglePorts,
83 U: unpin
84 };
Simon Hunt142d0032014-11-04 20:13:09 -080085
Simon Hunt195cb382014-11-03 17:50:51 -080086 // state variables
Simon Hunt934c3ce2014-11-05 11:45:07 -080087 var network = {},
Simon Hunt195cb382014-11-03 17:50:51 -080088 selected = {},
89 highlighted = null,
90 hovered = null,
91 viewMode = 'showAll',
92 portLabelsOn = false;
93
Simon Hunt934c3ce2014-11-05 11:45:07 -080094 // D3 selections
95 var svg,
96 bgImg,
97 topoG;
Simon Hunt195cb382014-11-03 17:50:51 -080098
Simon Hunt142d0032014-11-04 20:13:09 -080099 // ==============================
Simon Hunt934c3ce2014-11-05 11:45:07 -0800100 // For Debugging / Development
Simon Hunt195cb382014-11-03 17:50:51 -0800101
Simon Hunt934c3ce2014-11-05 11:45:07 -0800102 var topoPrefix = 'json/topoTest_',
103 lastFlavor = 4,
104 topoBase = true,
105 topoFlavor = 1;
Simon Hunt195cb382014-11-03 17:50:51 -0800106
Simon Hunt934c3ce2014-11-05 11:45:07 -0800107 function nextTopo() {
108 if (topoBase) {
109 topoBase = false;
110 } else {
111 topoBase = true;
112 topoFlavor = (topoFlavor === lastFlavor) ? 1 : topoFlavor + 1
Simon Hunt195cb382014-11-03 17:50:51 -0800113 }
114 }
115
Simon Hunt934c3ce2014-11-05 11:45:07 -0800116 // TODO change this to return the live data URL
117 function getTopoUrl() {
118 var suffix = topoBase ? 'base' : topoFlavor;
119 return topoPrefix + suffix + '.json';
120 }
121
122 // ==============================
123 // Key Callbacks
124
125 function getUpdatedNetworkData(view) {
126 nextTopo();
127 getNetworkData(view);
128 }
129
130 function toggleBg() {
131 var vis = bgImg.style('visibility');
132 bgImg.style('visibility', (vis === 'hidden') ? 'visible' : 'hidden');
133 }
134
135 function toggleLayout(view) {
136
137 }
138
139 function cycleLabels(view) {
140
141 }
142
143 function togglePorts(view) {
144
145 }
146
147 function unpin(view) {
148
149 }
150
151 // ==============================
152 // Radio Button Callbacks
153
Simon Hunt195cb382014-11-03 17:50:51 -0800154 function showAllLayers() {
Simon Hunt142d0032014-11-04 20:13:09 -0800155// network.node.classed('inactive', false);
156// network.link.classed('inactive', false);
157// d3.selectAll('svg .port').classed('inactive', false);
158// d3.selectAll('svg .portText').classed('inactive', false);
Simon Hunt934c3ce2014-11-05 11:45:07 -0800159 // TODO ...
160 console.log('showAllLayers()');
Simon Hunt195cb382014-11-03 17:50:51 -0800161 }
162
163 function showPacketLayer() {
Simon Hunt934c3ce2014-11-05 11:45:07 -0800164 showAllLayers();
165 // TODO ...
166 console.log('showPacketLayer()');
Simon Hunt195cb382014-11-03 17:50:51 -0800167 }
168
169 function showOpticalLayer() {
Simon Hunt934c3ce2014-11-05 11:45:07 -0800170 showAllLayers();
171 // TODO ...
172 console.log('showOpticalLayer()');
Simon Hunt195cb382014-11-03 17:50:51 -0800173 }
174
Simon Hunt142d0032014-11-04 20:13:09 -0800175 // ==============================
Simon Hunt934c3ce2014-11-05 11:45:07 -0800176 // Private functions
177
178 // set the size of the given element to that of the view
179 function setSize(el, view) {
180 el.attr({
181 width: view.width(),
182 height: view.height()
183 });
184 }
185
186
187 function getNetworkData(view) {
188 var url = getTopoUrl();
189
190 // TODO ...
191
192 }
193
194
195 // ==============================
Simon Hunt142d0032014-11-04 20:13:09 -0800196 // View life-cycle callbacks
Simon Hunt195cb382014-11-03 17:50:51 -0800197
Simon Hunt142d0032014-11-04 20:13:09 -0800198 function preload(view, ctx) {
199 var w = view.width(),
200 h = view.height(),
201 idBg = view.uid('bg'),
202 showBg = config.options.showBackground ? 'visible' : 'hidden';
Simon Hunt195cb382014-11-03 17:50:51 -0800203
Simon Hunt142d0032014-11-04 20:13:09 -0800204 // NOTE: view.$div is a D3 selection of the view's div
205 svg = view.$div.append('svg');
Simon Hunt934c3ce2014-11-05 11:45:07 -0800206 setSize(svg, view);
207
208 topoG = svg.append('g')
Simon Hunt195cb382014-11-03 17:50:51 -0800209 .attr('transform', config.force.translate());
Simon Hunt195cb382014-11-03 17:50:51 -0800210
Simon Hunt142d0032014-11-04 20:13:09 -0800211 // load the background image
212 bgImg = svg.append('svg:image')
Simon Hunt195cb382014-11-03 17:50:51 -0800213 .attr({
Simon Hunt142d0032014-11-04 20:13:09 -0800214 id: idBg,
215 width: w,
216 height: h,
Simon Hunt195cb382014-11-03 17:50:51 -0800217 'xlink:href': config.backgroundUrl
218 })
Simon Hunt142d0032014-11-04 20:13:09 -0800219 .style({
220 visibility: showBg
Simon Hunt195cb382014-11-03 17:50:51 -0800221 });
Simon Hunt195cb382014-11-03 17:50:51 -0800222 }
223
224
Simon Hunt142d0032014-11-04 20:13:09 -0800225 function load(view, ctx) {
Simon Hunt934c3ce2014-11-05 11:45:07 -0800226 view.setRadio(btnSet);
227 view.setKeys(keyDispatch);
Simon Hunt195cb382014-11-03 17:50:51 -0800228
Simon Hunt934c3ce2014-11-05 11:45:07 -0800229 getNetworkData(view);
Simon Hunt195cb382014-11-03 17:50:51 -0800230 }
231
Simon Hunt142d0032014-11-04 20:13:09 -0800232 function resize(view, ctx) {
Simon Hunt934c3ce2014-11-05 11:45:07 -0800233 setSize(svg, view);
234 setSize(bgImg, view);
Simon Hunt142d0032014-11-04 20:13:09 -0800235 }
236
237
238 // ==============================
239 // View registration
Simon Hunt195cb382014-11-03 17:50:51 -0800240
Simon Hunt25248912014-11-04 11:25:48 -0800241 onos.ui.addView('topo', {
Simon Hunt142d0032014-11-04 20:13:09 -0800242 preload: preload,
243 load: load,
244 resize: resize
Simon Hunt195cb382014-11-03 17:50:51 -0800245 });
246
Simon Hunt195cb382014-11-03 17:50:51 -0800247}(ONOS));