blob: f93c3148bde1a56ec04c8cd0e389493efbfa8086 [file] [log] [blame]
Rizwan Haider8e5f4772016-08-17 18:04:35 -04001/**
2 * © OpenCORD
3 *
4 * Visit http://guide.xosproject.org/devguide/addview/ for more information
5 *
6 * Created by teone on 6/28/16.
7 */
8
9(function () {
10 'use strict';
11
12 angular.module('xos.ecordTopology')
13 .directive('elanMap', function(){
14 return {
15 restrict: 'E',
16 scope: {
17 elan: '='
18 },
19 bindToController: true,
20 controllerAs: 'vm',
21 template: '',
22 controller: function($element, $scope, $rootScope, $timeout, _, cordIcons){
23 const el = $element[0];
24 var node, projection;
25 $scope.$watch(() => this.elan, (elan) => {
26 if(elan){
27 $timeout(() => {
28 draw(angular.copy(elan));
29 }, 500)
30 }
31 }, true);
32
33 // set force layout params
34 var force = d3.layout.force();
35
36 // DRAW US MAP
37 const drawMap = () => {
38 projection = d3.geo
39 // .albersUsa()
40 .mercator()
41 .center([-122.2, 37.6])
42 .scale(28000)
43 .translate([el.clientWidth / 2, el.clientHeight / 2]);
44
45 var path = d3.geo.path()
46 .projection(projection);
47
48 var map = d3.select(el).append('svg')
49 .attr('id', 'map')
50 .attr('width', el.clientWidth)
51 .attr('height', el.clientHeight);
52
53 d3.json('/js/json/bayarea.json', function(error, ba) {
54 if (error) {
55 throw new Error(error);
56 };
57
58 //bind feature data to the map
59 map.selectAll('.subunit')
60 .data(topojson.feature(ba, ba.objects.bayareaGEO).features)
61 .enter().append('path')
62 .attr('class', function(d, i) {
63 return 'subunit ' + `_${i}`;
64 })
65 .attr('d', path);
66
67
68 });
69 };
70 // END MAP
71
72 const draw = (elan) => {
73 if (!elan[0]){
74 return;
75 }
76 // set size values
77 force
78 .size([el.clientWidth, el.clientHeight])
79 .charge(-20)
80 .chargeDistance(200)
81 // .linkDistance(80)
82 .linkStrength(0.1);
83
84 // clean svg
85 angular.element(el).children().remove();
86 drawMap();
87
88 // create svg elements
89 const svg = d3.select(el)
90 .append('svg')
91 .style('width', `${el.clientWidth}px`)
92 .style('height', `${el.clientHeight}px`)
93
94
95 var nodes = [];
96 var links = [];
97 var d3id = 0;
98 var unis_i = 0;
99 var latlng_val, lat_val, lng_val;
100
101 // cicle trough E-LINE and create nodes/links
102 _.forEach(elan, (eline) => {
103
104 let isOnMap = _.find(nodes, {id: eline.uni1.pid});
105
106 if(!isOnMap){
107 eline.uni1.fixed = true;
108 try {
109
110 //convert latlng value into array for eline.uni1
111 var uni1_latlng = eline.uni1.latlng;
112 if (typeof uni1_latlng === 'string' || uni1_latlng instanceof String){
113 latlng_val = eline.uni1.latlng;
114 lat_val = latlng_val.substring(1, latlng_val.indexOf(',') - 1);
115 lat_val = lat_val.trim();
116 lng_val = latlng_val.substring(latlng_val.indexOf(',') + 1, latlng_val.length - 1);
117 lng_val = lng_val.trim()
118 eline.uni1.latlng = [lat_val, lng_val];
119 }
120
121 let ps = projection([eline.uni1.latlng[0], eline.uni1.latlng[1]]);
122 eline.uni1.x = ps[0];
123 eline.uni1.y = ps[1];
124 eline.uni1.pid = eline.uni1.pid || d3id++;
125 nodes.push(eline.uni1)
126 }
127 catch(e){
128 throw new Error(e);
129 }
130 }
131 else {
132 eline.uni1.pid = isOnMap.id;
133 }
134
135 isOnMap = _.find(nodes, {id: eline.uni2.pid});
136 if(!isOnMap){
137 eline.uni2.fixed = true;
138 try {
139
140 //convert latlng value into array for eline.uni2
141 var uni2_latlng = eline.uni2.latlng;
142 if (typeof uni2_latlng === 'string' || uni2_latlng instanceof String){
143 latlng_val = eline.uni2.latlng;
144 lat_val = latlng_val.substring(1, latlng_val.indexOf(',') - 1);
145 lat_val = lat_val.trim();
146 lng_val = latlng_val.substring(latlng_val.indexOf(',') + 1, latlng_val.length - 1);
147 lng_val = lng_val.trim()
148 eline.uni2.latlng = [lat_val, lng_val];
149 }
150
151 let ps = projection([eline.uni2.latlng[0], eline.uni2.latlng[1]]);
152 eline.uni2.x = ps[0];
153 eline.uni2.y = ps[1];
154 eline.uni2.pid = eline.uni2.pid || d3id++;
155 nodes.push(eline.uni2)
156 }
157 catch(e){
158 throw new Error(e);
159 }
160 }
161 else {
162 eline.uni2.pid = isOnMap.id;
163 }
164
165 links.push({
166 source: _.findIndex(nodes, eline.uni1),
167 target: _.findIndex(nodes, eline.uni2),
168 value: 1
169 });
170
171 });
172
173 // start force layout
174 force
175 .nodes(nodes)
176 .links(links)
177 .start();
178
179 // draw links
180 var link = svg.selectAll('.link')
181 .data(links)
182 .enter().append('line')
183 .attr({
184 class: 'link',
185 });
186
187 //draw nodes
188 node = svg.selectAll('.node')
189 .data(nodes)
190 .enter()
191 .append('g', d => d.scaEthFppUniN.interfaceCfgIdentifier)
192 .attr({
193 class: d => `node ${d.type ? d.type : 'uni'}`
194 });
195
196 node.append('rect')
197 .attr({
198 class: d => d.type ? d.type : 'uni',
199 width: 24,
200 height: 24,
201 x: -12,
202 y: -12
203 });
204
205 node.append('path')
206 .attr({
207 d: cordIcons.cordLogo,
208 transform: 'translate(-10, -10),scale(0.18)'
209 });
210
211 node.append('text')
212 .attr({
213 x: 0,
214 y: 25,
215 'text-anchor': 'middle'
216 })
217 .text(d => {
218 return d.pid
219 });
220
221
222 force.on('tick', function() {
223 link
224 .attr('x1', function(d) { return d.source.x; })
225 .attr('y1', function(d) { return d.source.y; })
226 .attr('x2', function(d) { return d.target.x; })
227 .attr('y2', function(d) { return d.target.y; });
228
229 node.attr('transform', (d) => `translate(${d.x},${d.y})`);
230 });
231 };
232
233 }
234 }
235 });
236})();
237