blob: 4b66991bfca65103c41a8e7614cf4103260fc6cf [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 Scandolodf35ca92016-02-25 09:19:41 -080045
46 const filterBBU = (instances) => {
47 return lodash.filter(instances, i => i.name.indexOf('BBU') >= 0);
48 };
49
50 const filterOthers = (instances) => {
Matteo Scandolo89667d32016-03-07 13:34:05 -080051 return TopologyElements.fakedInstance;
Matteo Scandolodf35ca92016-02-25 09:19:41 -080052 };
53
54 // retrieving instances list
55 const getData = () => {
56
Matteo Scandolodab95002016-02-26 13:50:45 -080057 d3.select('svg')
58 .style('width', `${el.clientWidth}px`)
59 .style('height', `${el.clientHeight}px`);
60
Matteo Scandolodf35ca92016-02-25 09:19:41 -080061 nodes = TopologyElements.nodes;
62 links = TopologyElements.links;
63
Matteo Scandolo97646d62016-03-07 14:14:00 -080064 Traffic.get()
65 .then((_traffic) => {
66 let delta = (_traffic - traffic);
67 traffic = _traffic
68 linkWidth = _traffic / (delta || traffic);
69
70 if(linkWidth < 1){
71 linkWidth = 1;
72 }
73
74 console.log(`traffic: ${_traffic}`, `linkWidth: ${linkWidth}`);
75 return XosApi.Instance_List_GET()
76 })
Matteo Scandolodf35ca92016-02-25 09:19:41 -080077 .then((instances) => {
78 addBbuNodes(filterBBU(instances));
79 addOtherNodes(filterOthers(instances));
80
81 draw(svg, nodes, links);
82 })
83 .catch((e) => {
84 throw new Error(e);
85 });
86 };
87
88 const force = d3.layout.force();
89
90 // create svg elements
91 const svg = d3.select(el)
92 .append('svg')
93 .style('width', `${el.clientWidth}px`)
94 .style('height', `${el.clientHeight}px`);
95
96 const linkContainer = svg.append('g')
97 .attr({
98 class: 'link-container'
99 });
100
101 const nodeContainer = svg.append('g')
102 .attr({
103 class: 'node-container'
104 });
105
106 // replace human readable ids with d3 ids
107 // NOTE now ids are not manatined on update...
108 const buildLinks = (links, nodes) => {
109 return links.map((l) => {
110
111
112 let source = lodash.findIndex(nodes, {id: l.source});
113 let target = lodash.findIndex(nodes, {id: l.target});
114 // console.log(`link-${source}-${target}`, source, target);
115 return {
116 source: source,
117 target: target,
118 value: 1,
119 id: `link-${source}-${target}`,
120 type: l.source.indexOf('fabric') >= 0 ? 'big':'small'
121 };
122
123 });
124 };
125
126 // find fabric nodes and center horizontally
127 const positionFabricNodes = (nodes) => {
128 return lodash.map(nodes, n => {
129 if(n.type !== 'fabric'){
130 return n;
131 }
132
133 n.x = n.x * hStep;
134 n.y = n.y * vStep;
135
136 return n;
137 });
138 };
139
140 const addBbuNodes = (instances) => {
141
142 // calculate bbu hStep
143 let bbuHStep = ((el.clientWidth / 2) / (instances.length + 1));
144
145 // create nodes
146 let bbuNodes = instances.map((n, i) => {
147 return {
148 type: 'bbu',
149 name: n.name,
150 id: `bbu-${n.id}`,
151 fixed: true,
152 y: vStep * 3,
153 x: bbuHStep * (i + 1)
154 };
155 });
156
157 // create links
158 let bbuLinks = bbuNodes.map(n => {
159 return {
160 source: n.id,
161 target: 'fabric2'
162 };
163 });
164
165 // fake RRU nodes and links
166 instances.forEach((n, i) => {
167 bbuNodes.push({
168 type: 'rru',
169 name: 'rru',
170 id: `rru-${n.id}`,
171 fixed: true,
172 y: vStep * 4,
173 x: bbuHStep * (i + 1)
174 });
175
176 bbuLinks.push({
177 source: `rru-${n.id}`,
178 target: `bbu-${n.id}`
179 });
180 })
181
182 nodes = nodes.concat(bbuNodes);
183
184
185 links = links.concat(bbuLinks);
186 };
187
188 // add MME, PGW, SGW nodes
189 const addOtherNodes = (instances) => {
190 let hStep = ((el.clientWidth / 2) / (instances.length + 1));
191
192 // create nodes
193 let otherNodes = instances.map((n, i) => {
194 return {
195 type: n.name.substring(0, 3),
196 name: n.name,
197 id: `${n.name.substring(0, 3)}-${n.id}`,
198 fixed: true,
199 y: vStep * 3,
200 x: (el.clientWidth / 2) + (hStep * (i + 1))
201 };
202 });
203
204 // create links
205 let otherLinks = otherNodes.map(n => {
206 return {
207 source: n.id,
208 target: 'fabric4'
209 };
210 });
211
212
213 nodes = nodes.concat(otherNodes);
214 links = links.concat(otherLinks);
215 }
216
217 let hStep, vStep;
218
219 hStep = el.clientWidth / 3;
220 vStep = el.clientHeight / 5;
221
222 const draw = (svg, nodes, links) => {
223
224 hStep = el.clientWidth / 3;
225 vStep = el.clientHeight / 5;
226
227 links = buildLinks(links, nodes);
228
229 nodes = positionFabricNodes(nodes);
230
231
232 // start force layout
233 force
234 .nodes(nodes)
235 .links(links)
236 .size([el.clientWidth, el.clientHeight])
237 .charge(-20)
238 .chargeDistance(200)
239 .linkDistance(80)
240 .linkStrength(0.1)
241 .start();
242
243
244 const linkContainer = d3.select('.link-container');
245 const nodeContainer = d3.select('.node-container');
246
247 NodeDrawer.drawFabricBox(nodeContainer, hStep, vStep);
248
249 // draw links
250 var link = linkContainer.selectAll('.link')
251 .data(links, d => d.id);
252
253 link.enter().append('line')
254 .attr({
Matteo Scandolo97646d62016-03-07 14:14:00 -0800255 class: d => `link ${d.type}`,
256 'stroke-width': linkWidth,
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800257 id: d => d.id,
Matteo Scandolo97646d62016-03-07 14:14:00 -0800258 opacity: 0
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800259 })
260 .transition()
261 .duration(1000)
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800262 .attr({
263 opacity: 1
264 });
265
Matteo Scandolo97646d62016-03-07 14:14:00 -0800266 link
267 .transition()
268 .duration(1000)
269 .attr({
270 'stroke-width': linkWidth,
271 opacity: 1
272 });
273
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800274 link.exit()
275 .remove();
276
277 //draw nodes
278 var node = nodeContainer.selectAll('.node')
279 .data(nodes, d => {
280 return d.id
281 });
282
283 // append a group for any new node
284 var enter = node.enter()
285 .append('g', d => d.interfaceCfgIdentifier)
286 .attr({
287 class: d => `${d.type} node`,
288 transform: d => `translate(${d.x}, ${d.y})`
289 });
290
291 // draw nodes
292 NodeDrawer.drawBbus(enter.filter('.bbu'))
293 NodeDrawer.drawRrus(enter.filter('.rru'))
294 NodeDrawer.drawFabric(enter.filter('.fabric'))
295 NodeDrawer.drawOthers(enter.filter(d => {
Matteo Scandolo89667d32016-03-07 13:34:05 -0800296 console.log(d.type);
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800297 return (
298 d.type === 'MME' ||
299 d.type === 'SGW' ||
Matteo Scandolo89667d32016-03-07 13:34:05 -0800300 d.type === 'PGW' ||
301 d.type === 'Vid'
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800302 )
303 }));
304
305 // remove nodes
306 var exit = node.exit();
307
308 NodeDrawer.removeElements(exit);
309
310 force.on('tick', function() {
311 link
312 .attr('x1', d => d.source.x )
313 .attr('y1', d => d.source.y )
314 .attr('x2', d => d.target.x )
315 .attr('y2', d => d.target.y );
316
317 node.attr('transform', (d) => `translate(${d.x},${d.y})`);
318 });
319 };
320
321 $interval(() => {
322 getData();
Matteo Scandolo97646d62016-03-07 14:14:00 -0800323 }, 3000);
Matteo Scandolodf35ca92016-02-25 09:19:41 -0800324 getData();
325
326
327 }
328 };
329});