| /** |
| * © OpenCORD |
| * |
| * Visit http://guide.xosproject.org/devguide/addview/ for more information |
| * |
| * Created by teone on 6/28/16. |
| */ |
| |
| (function () { |
| 'use strict'; |
| |
| angular.module('xos.ecordTopology') |
| .directive('elanMap', function(){ |
| return { |
| restrict: 'E', |
| scope: { |
| elan: '=' |
| }, |
| bindToController: true, |
| controllerAs: 'vm', |
| template: '', |
| controller: function($element, $scope, $rootScope, $timeout, _, cordIcons){ |
| const el = $element[0]; |
| var node, projection; |
| $scope.$watch(() => this.elan, (elan) => { |
| if(elan){ |
| $timeout(() => { |
| draw(angular.copy(elan)); |
| }, 500) |
| } |
| }, true); |
| |
| // set force layout params |
| var force = d3.layout.force(); |
| |
| // DRAW US MAP |
| const drawMap = () => { |
| projection = d3.geo |
| // .albersUsa() |
| .mercator() |
| .center([-122.2, 37.6]) |
| .scale(28000) |
| .translate([el.clientWidth / 2, el.clientHeight / 2]); |
| |
| var path = d3.geo.path() |
| .projection(projection); |
| |
| var map = d3.select(el).append('svg') |
| .attr('id', 'map') |
| .attr('width', el.clientWidth) |
| .attr('height', el.clientHeight); |
| |
| d3.json('/js/json/bayarea.json', function(error, ba) { |
| if (error) { |
| throw new Error(error); |
| }; |
| |
| //bind feature data to the map |
| map.selectAll('.subunit') |
| .data(topojson.feature(ba, ba.objects.bayareaGEO).features) |
| .enter().append('path') |
| .attr('class', function(d, i) { |
| return 'subunit ' + `_${i}`; |
| }) |
| .attr('d', path); |
| |
| |
| }); |
| }; |
| // END MAP |
| |
| const draw = (elan) => { |
| if (!elan[0]){ |
| return; |
| } |
| // set size values |
| force |
| .size([el.clientWidth, el.clientHeight]) |
| .charge(-20) |
| .chargeDistance(200) |
| // .linkDistance(80) |
| .linkStrength(0.1); |
| |
| // clean svg |
| angular.element(el).children().remove(); |
| drawMap(); |
| |
| // create svg elements |
| const svg = d3.select(el) |
| .append('svg') |
| .style('width', `${el.clientWidth}px`) |
| .style('height', `${el.clientHeight}px`) |
| |
| |
| var nodes = []; |
| var links = []; |
| var d3id = 0; |
| var unis_i = 0; |
| var latlng_val, lat_val, lng_val; |
| |
| // cicle trough E-LINE and create nodes/links |
| _.forEach(elan, (eline) => { |
| |
| let isOnMap = _.find(nodes, {id: eline.uni1.pid}); |
| |
| if(!isOnMap){ |
| eline.uni1.fixed = true; |
| try { |
| |
| //convert latlng value into array for eline.uni1 |
| var uni1_latlng = eline.uni1.latlng; |
| if (typeof uni1_latlng === 'string' || uni1_latlng instanceof String){ |
| latlng_val = eline.uni1.latlng; |
| lat_val = latlng_val.substring(1, latlng_val.indexOf(',') - 1); |
| lat_val = lat_val.trim(); |
| lng_val = latlng_val.substring(latlng_val.indexOf(',') + 1, latlng_val.length - 1); |
| lng_val = lng_val.trim() |
| eline.uni1.latlng = [lat_val, lng_val]; |
| } |
| |
| let ps = projection([eline.uni1.latlng[0], eline.uni1.latlng[1]]); |
| eline.uni1.x = ps[0]; |
| eline.uni1.y = ps[1]; |
| eline.uni1.pid = eline.uni1.pid || d3id++; |
| nodes.push(eline.uni1) |
| } |
| catch(e){ |
| throw new Error(e); |
| } |
| } |
| else { |
| eline.uni1.pid = isOnMap.id; |
| } |
| |
| isOnMap = _.find(nodes, {id: eline.uni2.pid}); |
| if(!isOnMap){ |
| eline.uni2.fixed = true; |
| try { |
| |
| //convert latlng value into array for eline.uni2 |
| var uni2_latlng = eline.uni2.latlng; |
| if (typeof uni2_latlng === 'string' || uni2_latlng instanceof String){ |
| latlng_val = eline.uni2.latlng; |
| lat_val = latlng_val.substring(1, latlng_val.indexOf(',') - 1); |
| lat_val = lat_val.trim(); |
| lng_val = latlng_val.substring(latlng_val.indexOf(',') + 1, latlng_val.length - 1); |
| lng_val = lng_val.trim() |
| eline.uni2.latlng = [lat_val, lng_val]; |
| } |
| |
| let ps = projection([eline.uni2.latlng[0], eline.uni2.latlng[1]]); |
| eline.uni2.x = ps[0]; |
| eline.uni2.y = ps[1]; |
| eline.uni2.pid = eline.uni2.pid || d3id++; |
| nodes.push(eline.uni2) |
| } |
| catch(e){ |
| throw new Error(e); |
| } |
| } |
| else { |
| eline.uni2.pid = isOnMap.id; |
| } |
| |
| links.push({ |
| source: _.findIndex(nodes, eline.uni1), |
| target: _.findIndex(nodes, eline.uni2), |
| value: 1 |
| }); |
| |
| }); |
| |
| // start force layout |
| force |
| .nodes(nodes) |
| .links(links) |
| .start(); |
| |
| // draw links |
| var link = svg.selectAll('.link') |
| .data(links) |
| .enter().append('line') |
| .attr({ |
| class: 'link', |
| }); |
| |
| //draw nodes |
| node = svg.selectAll('.node') |
| .data(nodes) |
| .enter() |
| .append('g', d => d.scaEthFppUniN.interfaceCfgIdentifier) |
| .attr({ |
| class: d => `node ${d.type ? d.type : 'uni'}` |
| }); |
| |
| node.append('rect') |
| .attr({ |
| class: d => d.type ? d.type : 'uni', |
| width: 24, |
| height: 24, |
| x: -12, |
| y: -12 |
| }); |
| |
| node.append('path') |
| .attr({ |
| d: cordIcons.cordLogo, |
| transform: 'translate(-10, -10),scale(0.18)' |
| }); |
| |
| node.append('text') |
| .attr({ |
| x: 0, |
| y: 25, |
| 'text-anchor': 'middle' |
| }) |
| .text(d => { |
| return d.pid |
| }); |
| |
| |
| force.on('tick', function() { |
| link |
| .attr('x1', function(d) { return d.source.x; }) |
| .attr('y1', function(d) { return d.source.y; }) |
| .attr('x2', function(d) { return d.target.x; }) |
| .attr('y2', function(d) { return d.target.y; }); |
| |
| node.attr('transform', (d) => `translate(${d.x},${d.y})`); |
| }); |
| }; |
| |
| } |
| } |
| }); |
| })(); |
| |