Rizwan Haider | 8e5f477 | 2016-08-17 18:04:35 -0400 | [diff] [blame] | 1 | /** |
| 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 | |