blob: a479717f7af33ec1250cd092afa59c37c75fa114 [file] [log] [blame]
Matteo Scandolodf35ca92016-02-25 09:19:41 -08001'use strict';
2
3angular.module('xos.mcordTopology', [
4 'ngResource',
5 'ngCookies',
6 'ngLodash',
7 'ui.router',
8 'xos.helpers'
9])
10.config(($stateProvider) => {
11 $stateProvider
12 .state('topology', {
13 url: '/',
14 template: '<m-cord-topology></m-cord-topology>'
15 });
16})
17.config(function($httpProvider){
18 $httpProvider.interceptors.push('NoHyperlinks');
19})
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);
26 });
27 return deferred.promise;
28 }
29})
Matteo Scandolodf35ca92016-02-25 09:19:41 -080030.directive('mCordTopology', function(){
31 return {
32 restrict: 'E',
33 scope: {},
34 bindToController: true,
35 controllerAs: 'vm',
36 template: '',
Matteo Scandolo97646d62016-03-07 14:14:00 -080037 controller: function($element, $interval, $rootScope, XosApi, lodash, TopologyElements, NodeDrawer, Traffic){
Matteo Scandolodf35ca92016-02-25 09:19:41 -080038
39 const el = $element[0];
40
41 let nodes = [];
42 let links = [];
Matteo Scandolo97646d62016-03-07 14:14:00 -080043 let traffic = 0;
44 let linkWidth = 1;
Matteo Scandolo0ddc2572016-03-07 15:05:24 -080045 let trafficCorrection = 5;
Matteo Scandolodf35ca92016-02-25 09:19:41 -080046
47 const filterBBU = (instances) => {
48 return lodash.filter(instances, i => i.name.indexOf('BBU') >= 0);
49 };
50
51 const filterOthers = (instances) => {
Matteo Scandolo89667d32016-03-07 13:34:05 -080052 return TopologyElements.fakedInstance;
Matteo Scandolodf35ca92016-02-25 09:19:41 -080053 };
54
55 // retrieving instances list
56 const getData = () => {
57
Matteo Scandolodab95002016-02-26 13:50:45 -080058 d3.select('svg')
59 .style('width', `${el.clientWidth}px`)
60 .style('height', `${el.clientHeight}px`);
61
Matteo Scandolodf35ca92016-02-25 09:19:41 -080062 nodes = TopologyElements.nodes;
63 links = TopologyElements.links;
64
Matteo Scandolo97646d62016-03-07 14:14:00 -080065 Traffic.get()
Matteo Scandolo0ddc2572016-03-07 15:05:24 -080066 .then((newTraffic) => {
Matteo Scandolo97646d62016-03-07 14:14:00 -080067
Matteo Scandolo0ddc2572016-03-07 15:05:24 -080068 // calculating link size
69 // it should change between 1 and 10
70 if(!traffic){
71 linkWidth = 2;
72 }
73 else if(newTraffic === traffic){
74 linkWidth = linkWidth;
75 }
76 else{
77 let delta = newTraffic - traffic;
78
79 if(delta > 0){
80 linkWidth = linkWidth + (delta / trafficCorrection);
81 }
82 else{
83 linkWidth = linkWidth - ((delta * -1) / trafficCorrection);
84 }
85
Matteo Scandolo97646d62016-03-07 14:14:00 -080086 }
87
Matteo Scandolo0ddc2572016-03-07 15:05:24 -080088 if(linkWidth < 0.2){
89 linkWidth = 0.2
90 };
91
92 traffic = newTraffic;
93
Matteo Scandolo97646d62016-03-07 14:14:00 -080094 return XosApi.Instance_List_GET()
95 })
Matteo Scandolodf35ca92016-02-25 09:19:41 -080096 .then((instances) => {
97 addBbuNodes(filterBBU(instances));
98 addOtherNodes(filterOthers(instances));
99
100 draw(svg, nodes, links);
101 })
102 .catch((e) => {
103 throw new Error(e);
104 });
105 };
106
107 const force = d3.layout.force();
108
109 // create svg elements
110 const svg = d3.select(el)
111 .append('svg')
112 .style('width', `${el.clientWidth}px`)
113 .style('height', `${el.clientHeight}px`);
114
115 const linkContainer = svg.append('g')
116 .attr({
117 class: 'link-container'
118 });
119
120 const nodeContainer = svg.append('g')
121 .attr({
122 class: 'node-container'
123 });
124
125 // replace human readable ids with d3 ids
126 // NOTE now ids are not manatined on update...
127 const buildLinks = (links, nodes) => {
128 return links.map((l) => {
129
130
131 let source = lodash.findIndex(nodes, {id: l.source});
132 let target = lodash.findIndex(nodes, {id: l.target});
133 // console.log(`link-${source}-${target}`, source, target);
134 return {
135 source: source,
136 target: target,
137 value: 1,
138 id: `link-${source}-${target}`,
139 type: l.source.indexOf('fabric') >= 0 ? 'big':'small'
140 };
141
142 });
143 };
144
145 // find fabric nodes and center horizontally
146 const positionFabricNodes = (nodes) => {
147 return lodash.map(nodes, n => {
148 if(n.type !== 'fabric'){
149 return n;
150 }
151
152 n.x = n.x * hStep;
153 n.y = n.y * vStep;
154
155 return n;
156 });
157 };
158
159 const addBbuNodes = (instances) => {
160
161 // calculate bbu hStep
162 let bbuHStep = ((el.clientWidth / 2) / (instances.length + 1));
163
164 // create nodes
165 let bbuNodes = instances.map((n, i) => {
166 return {
167 type: 'bbu',
168 name: n.name,
169 id: `bbu-${n.id}`,
170 fixed: true,
171 y: vStep * 3,
172 x: bbuHStep * (i + 1)
173 };
174 });
175
176 // create links
177 let bbuLinks = bbuNodes.map(n => {
178 return {
179 source: n.id,
Matteo Scandoloaa3cc502016-03-09 17:58:51 -0800180 target: 'fabric4'
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800181 };
182 });
183
184 // fake RRU nodes and links
185 instances.forEach((n, i) => {
186 bbuNodes.push({
187 type: 'rru',
188 name: 'rru',
189 id: `rru-${n.id}`,
190 fixed: true,
191 y: vStep * 4,
192 x: bbuHStep * (i + 1)
193 });
194
195 bbuLinks.push({
196 source: `rru-${n.id}`,
197 target: `bbu-${n.id}`
198 });
199 })
200
201 nodes = nodes.concat(bbuNodes);
202
203
204 links = links.concat(bbuLinks);
205 };
206
207 // add MME, PGW, SGW nodes
208 const addOtherNodes = (instances) => {
209 let hStep = ((el.clientWidth / 2) / (instances.length + 1));
210
211 // create nodes
212 let otherNodes = instances.map((n, i) => {
213 return {
214 type: n.name.substring(0, 3),
215 name: n.name,
216 id: `${n.name.substring(0, 3)}-${n.id}`,
217 fixed: true,
218 y: vStep * 3,
219 x: (el.clientWidth / 2) + (hStep * (i + 1))
220 };
221 });
222
223 // create links
224 let otherLinks = otherNodes.map(n => {
225 return {
226 source: n.id,
227 target: 'fabric4'
228 };
229 });
230
231
232 nodes = nodes.concat(otherNodes);
233 links = links.concat(otherLinks);
234 }
235
236 let hStep, vStep;
237
238 hStep = el.clientWidth / 3;
239 vStep = el.clientHeight / 5;
240
241 const draw = (svg, nodes, links) => {
242
243 hStep = el.clientWidth / 3;
244 vStep = el.clientHeight / 5;
245
246 links = buildLinks(links, nodes);
247
248 nodes = positionFabricNodes(nodes);
249
Matteo Scandoloaa3cc502016-03-09 17:58:51 -0800250 console.log(nodes);
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800251 // start force layout
252 force
253 .nodes(nodes)
254 .links(links)
255 .size([el.clientWidth, el.clientHeight])
256 .charge(-20)
257 .chargeDistance(200)
258 .linkDistance(80)
259 .linkStrength(0.1)
260 .start();
261
262
263 const linkContainer = d3.select('.link-container');
264 const nodeContainer = d3.select('.node-container');
265
266 NodeDrawer.drawFabricBox(nodeContainer, hStep, vStep);
267
268 // draw links
269 var link = linkContainer.selectAll('.link')
270 .data(links, d => d.id);
271
272 link.enter().append('line')
273 .attr({
Matteo Scandolo97646d62016-03-07 14:14:00 -0800274 class: d => `link ${d.type}`,
275 'stroke-width': linkWidth,
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800276 id: d => d.id,
Matteo Scandolo97646d62016-03-07 14:14:00 -0800277 opacity: 0
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800278 })
279 .transition()
280 .duration(1000)
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800281 .attr({
282 opacity: 1
283 });
284
Matteo Scandolo97646d62016-03-07 14:14:00 -0800285 link
286 .transition()
287 .duration(1000)
288 .attr({
289 'stroke-width': linkWidth,
290 opacity: 1
291 });
292
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800293 link.exit()
294 .remove();
295
296 //draw nodes
297 var node = nodeContainer.selectAll('.node')
298 .data(nodes, d => {
299 return d.id
300 });
301
302 // append a group for any new node
303 var enter = node.enter()
304 .append('g', d => d.interfaceCfgIdentifier)
305 .attr({
306 class: d => `${d.type} node`,
307 transform: d => `translate(${d.x}, ${d.y})`
308 });
309
310 // draw nodes
311 NodeDrawer.drawBbus(enter.filter('.bbu'))
312 NodeDrawer.drawRrus(enter.filter('.rru'))
313 NodeDrawer.drawFabric(enter.filter('.fabric'))
314 NodeDrawer.drawOthers(enter.filter(d => {
Matteo Scandolo89667d32016-03-07 13:34:05 -0800315 console.log(d.type);
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800316 return (
317 d.type === 'MME' ||
318 d.type === 'SGW' ||
Matteo Scandolo89667d32016-03-07 13:34:05 -0800319 d.type === 'PGW' ||
320 d.type === 'Vid'
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800321 )
322 }));
323
324 // remove nodes
325 var exit = node.exit();
326
327 NodeDrawer.removeElements(exit);
328
329 force.on('tick', function() {
330 link
331 .attr('x1', d => d.source.x )
332 .attr('y1', d => d.source.y )
333 .attr('x2', d => d.target.x )
334 .attr('y2', d => d.target.y );
335
336 node.attr('transform', (d) => `translate(${d.x},${d.y})`);
337 });
338 };
339
Matteo Scandoloaa3cc502016-03-09 17:58:51 -0800340 // $interval(() => {
341 // getData();
342 // }, 3000);
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800343 getData();
344
345
346 }
347 };
348});