blob: f0605c3a815a4d906e61b7318ef3bd969a6d2920 [file] [log] [blame]
Matteo Scandolo50f3a732016-02-18 15:28:48 -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})
20.directive('mCordTopology', function(){
21 return {
22 restrict: 'E',
23 scope: {},
24 bindToController: true,
25 controllerAs: 'vm',
26 template: '',
27 controller: function($element, $window, XosApi, lodash, TopologyElements, NodeDrawer){
28
29 const el = $element[0];
30
31 let nodes = TopologyElements.nodes;
32 let links = TopologyElements.links;
33
34 const filterBBU = (instances) => {
35 return lodash.filter(instances, i => i.name.indexOf('BBU') >= 0);
36 };
37
38 const filterOthers = (instances) => {
39 return lodash.filter(instances, i => {
40 return (i.name.indexOf('MME') >= 0)
41 || (i.name.indexOf('SGW') >= 0)
42 || (i.name.indexOf('PGW') >= 0)
43 });
44 };
45
46 // retrieving instances list
47 XosApi.Instance_List_GET()
48 .then((instances) => {
49 addBbuNodes(filterBBU(instances));
50 addOtherNodes(filterOthers(instances));
51 draw(svg, nodes, links);
52 })
53 .catch((e) => {
54 throw new Error(e);
55 });
56
57 const force = d3.layout.force();
58
59 // create svg elements
60 const svg = d3.select(el)
61 .append('svg')
62 .style('width', `${el.clientWidth}px`)
63 .style('height', `${el.clientHeight}px`);
64
65
66 let hStep = el.clientWidth / 3;
67 let vStep = el.clientHeight / 5;
68
69 // replace human readable ids with d3 ids
70 const buildLinks = (links, nodes) => {
71 return links.map((l) => {
72 let source = lodash.findIndex(nodes, {id: l.source});
73 let target = lodash.findIndex(nodes, {id: l.target});
74 return {
75 source: source,
76 target: target,
77 value: 1
78 };
79
80 });
81 };
82
83 // find fabric nodes and center horizontally
84 const positionFabricNodes = (nodes) => {
85 return lodash.map(nodes, n => {
86 if(n.type !== 'fabric'){
87 return n;
88 }
89
90 n.x = n.x * hStep;
91 n.y = n.y * vStep;
92
93 return n;
94 });
95 };
96
97 const addBbuNodes = (instances) => {
98
99 // calculate bbu hStep
100 let bbuHStep = ((el.clientWidth / 2) / (instances.length + 1));
101
102 // create nodes
103 let bbuNodes = instances.map((n, i) => {
104 return {
105 type: 'bbu',
106 name: n.name,
107 id: `bbu-${n.id}`,
108 fixed: true,
109 y: vStep * 3,
110 x: bbuHStep * (i + 1)
111 };
112 });
113
114 // create links
115 let bbuLinks = bbuNodes.map(n => {
116 return {
117 source: n.id,
118 target: 'fabric2'
119 };
120 });
121
122 // fake RRU nodes and links
123 instances.forEach((n, i) => {
124 bbuNodes.push({
125 type: 'rru',
126 name: 'rru',
127 id: `rru-${n.id}`,
128 fixed: true,
129 y: vStep * 4,
130 x: bbuHStep * (i + 1)
131 });
132
133 bbuLinks.push({
134 source: `rru-${n.id}`,
135 target: `bbu-${n.id}`
136 });
137 })
138
139 nodes = nodes.concat(bbuNodes);
140 links = links.concat(bbuLinks);
141 };
142
143 // add MME, PGW, SGW nodes
144 const addOtherNodes = (instances) => {
145 let hStep = ((el.clientWidth / 2) / (instances.length + 1));
146
147 // create nodes
148 let otherNodes = instances.map((n, i) => {
149 return {
150 type: n.name.substring(0, 3),
151 name: n.name,
152 id: `${n.name.substring(0, 3)}-${n.id}`,
153 fixed: true,
154 y: vStep * 3,
155 x: (el.clientWidth / 2) + (hStep * (i + 1))
156 };
157 });
158
159 // create links
160 let otherLinks = otherNodes.map(n => {
161 return {
162 source: n.id,
163 target: 'fabric4'
164 };
165 });
166
167 nodes = nodes.concat(otherNodes);
168 links = links.concat(otherLinks);
169 }
170
171 // NOTE nodes get dublicated
172 const draw = (svg, nodes, links) => {
173
174 links = buildLinks(links, nodes);
175
176 nodes = positionFabricNodes(nodes);
177
178 // start force layout
179 force
180 .nodes(nodes)
181 .links(links)
182 .size([el.clientWidth, el.clientHeight])
183 .charge(-20)
184 .chargeDistance(200)
185 .linkDistance(80)
186 .linkStrength(0.1)
187 .start();
188
189 // draw links
190 var link = svg.selectAll('.link')
191 .data(links)
192 .enter().append('line')
193 .attr({
194 class: 'link',
195 });
196
197 //draw nodes
198 var node = svg.selectAll('.node')
199 .data(nodes, d => {
200 return d.id
201 });
202
203 // append a group for any new node
204 var enter = node.enter()
205 .append('g', d => d.interfaceCfgIdentifier)
206 .attr({
207 class: d => d.type,
208 transform: d => `translate(${d.x}, ${d.y})`
209 });
210
211 // draw nodes
212 NodeDrawer.drawBbus(node.filter('.bbu'))
213 NodeDrawer.drawRrus(node.filter('.rru'))
214 NodeDrawer.drawFabric(node.filter('.fabric'))
215 NodeDrawer.drawOthers(node.filter(d => {
216 return (
217 d.type === 'MME' ||
218 d.type === 'SGW' ||
219 d.type === 'PGW'
220 )
221 }));
222
223 force.on('tick', function() {
224 link
225 .attr('x1', d => d.source.x )
226 .attr('y1', d => d.source.y )
227 .attr('x2', d => d.target.x )
228 .attr('y2', d => d.target.y );
229
230 node.attr('transform', (d) => `translate(${d.x},${d.y})`);
231 });
232 };
233
234 // draw(svg, TopologyElements.nodes, TopologyElements.links);
235 }
236 };
237});