blob: f926df9b5ae74592eb1d1fc7f65f190cad276476 [file] [log] [blame]
Matteo Scandolodf35ca92016-02-25 09:19:41 -08001'use strict';
2
3angular.module('xos.mcordTopology', [
4 'ngResource',
5 'ngCookies',
Matteo Scandolodf35ca92016-02-25 09:19:41 -08006 'ui.router',
7 'xos.helpers'
8])
9.config(($stateProvider) => {
10 $stateProvider
11 .state('topology', {
12 url: '/',
13 template: '<m-cord-topology></m-cord-topology>'
14 });
15})
16.config(function($httpProvider){
17 $httpProvider.interceptors.push('NoHyperlinks');
18})
Matteo Scandolo1778b742016-04-22 09:47:50 -070019.factory('_', $window => $window._)
Matteo Scandolo97646d62016-03-07 14:14:00 -080020.service('Traffic', function($http, $q){
21 this.get = () => {
22 var deferred = $q.defer();
23 $http.get('videoLocal.txt')
24 .then(res => {
25 deferred.resolve(res.data);
Matteo Scandolo1778b742016-04-22 09:47:50 -070026 })
27 .catch(e => {
28 console.log(e);
29 deferred.resolve(Math.random() * 10)
Matteo Scandolo97646d62016-03-07 14:14:00 -080030 });
31 return deferred.promise;
32 }
33})
Matteo Scandolodf35ca92016-02-25 09:19:41 -080034.directive('mCordTopology', function(){
35 return {
36 restrict: 'E',
37 scope: {},
38 bindToController: true,
39 controllerAs: 'vm',
40 template: '',
Matteo Scandolo1778b742016-04-22 09:47:50 -070041 controller: function($element, $interval, $rootScope, _, $http, TopologyElements, NodeDrawer, Traffic){
Matteo Scandolodf35ca92016-02-25 09:19:41 -080042
43 const el = $element[0];
44
45 let nodes = [];
46 let links = [];
Matteo Scandolo97646d62016-03-07 14:14:00 -080047 let traffic = 0;
48 let linkWidth = 1;
Matteo Scandolo0ddc2572016-03-07 15:05:24 -080049 let trafficCorrection = 5;
Matteo Scandolodf35ca92016-02-25 09:19:41 -080050
51 const filterBBU = (instances) => {
Matteo Scandolo1778b742016-04-22 09:47:50 -070052 return _.filter(instances, i => i.name.indexOf('BBU') >= 0);
Matteo Scandolodf35ca92016-02-25 09:19:41 -080053 };
54
55 const filterOthers = (instances) => {
Matteo Scandolo89667d32016-03-07 13:34:05 -080056 return TopologyElements.fakedInstance;
Matteo Scandolodf35ca92016-02-25 09:19:41 -080057 };
58
59 // retrieving instances list
60 const getData = () => {
61
Matteo Scandolodab95002016-02-26 13:50:45 -080062 d3.select('svg')
63 .style('width', `${el.clientWidth}px`)
64 .style('height', `${el.clientHeight}px`);
65
Matteo Scandolodf35ca92016-02-25 09:19:41 -080066 nodes = TopologyElements.nodes;
67 links = TopologyElements.links;
68
Matteo Scandolo97646d62016-03-07 14:14:00 -080069 Traffic.get()
Matteo Scandolo0ddc2572016-03-07 15:05:24 -080070 .then((newTraffic) => {
Matteo Scandolo97646d62016-03-07 14:14:00 -080071
Matteo Scandolo0ddc2572016-03-07 15:05:24 -080072 // calculating link size
73 // it should change between 1 and 10
74 if(!traffic){
75 linkWidth = 2;
76 }
77 else if(newTraffic === traffic){
78 linkWidth = linkWidth;
79 }
80 else{
81 let delta = newTraffic - traffic;
82
83 if(delta > 0){
84 linkWidth = linkWidth + (delta / trafficCorrection);
85 }
86 else{
87 linkWidth = linkWidth - ((delta * -1) / trafficCorrection);
88 }
89
Matteo Scandolo97646d62016-03-07 14:14:00 -080090 }
91
Matteo Scandolo0ddc2572016-03-07 15:05:24 -080092 if(linkWidth < 0.2){
93 linkWidth = 0.2
94 };
95
96 traffic = newTraffic;
97
Matteo Scandolo1778b742016-04-22 09:47:50 -070098 return $http.get('/api/core/xos/instances');
99 // return XosApi.Instance_List_GET()
Matteo Scandolo97646d62016-03-07 14:14:00 -0800100 })
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800101 .then((instances) => {
Matteo Scandolo1778b742016-04-22 09:47:50 -0700102
103 addBbuNodes(filterBBU(instances.data));
104 addOtherNodes(filterOthers(instances.data));
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800105
106 draw(svg, nodes, links);
107 })
108 .catch((e) => {
109 throw new Error(e);
110 });
111 };
112
113 const force = d3.layout.force();
114
115 // create svg elements
116 const svg = d3.select(el)
117 .append('svg')
118 .style('width', `${el.clientWidth}px`)
119 .style('height', `${el.clientHeight}px`);
120
121 const linkContainer = svg.append('g')
122 .attr({
123 class: 'link-container'
124 });
125
126 const nodeContainer = svg.append('g')
127 .attr({
128 class: 'node-container'
129 });
130
131 // replace human readable ids with d3 ids
132 // NOTE now ids are not manatined on update...
133 const buildLinks = (links, nodes) => {
134 return links.map((l) => {
135
Matteo Scandolo1778b742016-04-22 09:47:50 -0700136 console.log(_.find);
137 let source = _.findIndex(nodes, {id: l.source});
138 let target = _.findIndex(nodes, {id: l.target});
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800139 // console.log(`link-${source}-${target}`, source, target);
140 return {
141 source: source,
142 target: target,
143 value: 1,
144 id: `link-${source}-${target}`,
145 type: l.source.indexOf('fabric') >= 0 ? 'big':'small'
146 };
147
148 });
149 };
150
151 // find fabric nodes and center horizontally
152 const positionFabricNodes = (nodes) => {
Matteo Scandolo1778b742016-04-22 09:47:50 -0700153 return _.map(nodes, n => {
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800154 if(n.type !== 'fabric'){
155 return n;
156 }
157
158 n.x = n.x * hStep;
159 n.y = n.y * vStep;
160
161 return n;
162 });
163 };
164
165 const addBbuNodes = (instances) => {
166
167 // calculate bbu hStep
168 let bbuHStep = ((el.clientWidth / 2) / (instances.length + 1));
169
170 // create nodes
171 let bbuNodes = instances.map((n, i) => {
172 return {
173 type: 'bbu',
174 name: n.name,
175 id: `bbu-${n.id}`,
176 fixed: true,
177 y: vStep * 3,
178 x: bbuHStep * (i + 1)
179 };
180 });
181
182 // create links
183 let bbuLinks = bbuNodes.map(n => {
184 return {
185 source: n.id,
Matteo Scandoloaa3cc502016-03-09 17:58:51 -0800186 target: 'fabric4'
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800187 };
188 });
189
190 // fake RRU nodes and links
191 instances.forEach((n, i) => {
192 bbuNodes.push({
193 type: 'rru',
194 name: 'rru',
195 id: `rru-${n.id}`,
196 fixed: true,
197 y: vStep * 4,
198 x: bbuHStep * (i + 1)
199 });
200
201 bbuLinks.push({
202 source: `rru-${n.id}`,
203 target: `bbu-${n.id}`
204 });
205 })
206
207 nodes = nodes.concat(bbuNodes);
208
209
210 links = links.concat(bbuLinks);
211 };
212
213 // add MME, PGW, SGW nodes
214 const addOtherNodes = (instances) => {
215 let hStep = ((el.clientWidth / 2) / (instances.length + 1));
216
217 // create nodes
218 let otherNodes = instances.map((n, i) => {
219 return {
220 type: n.name.substring(0, 3),
221 name: n.name,
222 id: `${n.name.substring(0, 3)}-${n.id}`,
223 fixed: true,
224 y: vStep * 3,
225 x: (el.clientWidth / 2) + (hStep * (i + 1))
226 };
227 });
228
229 // create links
230 let otherLinks = otherNodes.map(n => {
231 return {
232 source: n.id,
233 target: 'fabric4'
234 };
235 });
236
237
238 nodes = nodes.concat(otherNodes);
239 links = links.concat(otherLinks);
240 }
241
242 let hStep, vStep;
243
244 hStep = el.clientWidth / 3;
245 vStep = el.clientHeight / 5;
246
247 const draw = (svg, nodes, links) => {
248
249 hStep = el.clientWidth / 3;
250 vStep = el.clientHeight / 5;
251
252 links = buildLinks(links, nodes);
253
254 nodes = positionFabricNodes(nodes);
255
Matteo Scandoloaa3cc502016-03-09 17:58:51 -0800256 console.log(nodes);
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800257 // start force layout
258 force
259 .nodes(nodes)
260 .links(links)
261 .size([el.clientWidth, el.clientHeight])
262 .charge(-20)
263 .chargeDistance(200)
264 .linkDistance(80)
265 .linkStrength(0.1)
266 .start();
267
268
269 const linkContainer = d3.select('.link-container');
270 const nodeContainer = d3.select('.node-container');
271
272 NodeDrawer.drawFabricBox(nodeContainer, hStep, vStep);
273
274 // draw links
275 var link = linkContainer.selectAll('.link')
276 .data(links, d => d.id);
277
278 link.enter().append('line')
279 .attr({
Matteo Scandolo97646d62016-03-07 14:14:00 -0800280 class: d => `link ${d.type}`,
281 'stroke-width': linkWidth,
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800282 id: d => d.id,
Matteo Scandolo97646d62016-03-07 14:14:00 -0800283 opacity: 0
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800284 })
285 .transition()
286 .duration(1000)
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800287 .attr({
288 opacity: 1
289 });
290
Matteo Scandolo97646d62016-03-07 14:14:00 -0800291 link
292 .transition()
293 .duration(1000)
294 .attr({
295 'stroke-width': linkWidth,
296 opacity: 1
297 });
298
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800299 link.exit()
300 .remove();
301
302 //draw nodes
303 var node = nodeContainer.selectAll('.node')
304 .data(nodes, d => {
305 return d.id
306 });
307
308 // append a group for any new node
309 var enter = node.enter()
310 .append('g', d => d.interfaceCfgIdentifier)
311 .attr({
312 class: d => `${d.type} node`,
313 transform: d => `translate(${d.x}, ${d.y})`
314 });
315
316 // draw nodes
317 NodeDrawer.drawBbus(enter.filter('.bbu'))
318 NodeDrawer.drawRrus(enter.filter('.rru'))
319 NodeDrawer.drawFabric(enter.filter('.fabric'))
320 NodeDrawer.drawOthers(enter.filter(d => {
Matteo Scandolo89667d32016-03-07 13:34:05 -0800321 console.log(d.type);
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800322 return (
323 d.type === 'MME' ||
324 d.type === 'SGW' ||
Matteo Scandolo89667d32016-03-07 13:34:05 -0800325 d.type === 'PGW' ||
326 d.type === 'Vid'
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800327 )
328 }));
329
330 // remove nodes
331 var exit = node.exit();
332
333 NodeDrawer.removeElements(exit);
334
335 force.on('tick', function() {
336 link
337 .attr('x1', d => d.source.x )
338 .attr('y1', d => d.source.y )
339 .attr('x2', d => d.target.x )
340 .attr('y2', d => d.target.y );
341
342 node.attr('transform', (d) => `translate(${d.x},${d.y})`);
343 });
344 };
345
Matteo Scandoloaa3cc502016-03-09 17:58:51 -0800346 // $interval(() => {
347 // getData();
348 // }, 3000);
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800349 getData();
350
351
352 }
353 };
354});