Advertisement
Guest User

Untitled

a guest
Jan 20th, 2018
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import * as d3 from 'd3';
  2. import * as topojson from 'topojson';
  3. import dataService from '../services/dataService'
  4. import './map.css';
  5.  
  6. export default function () {
  7.     let initialData;
  8.  
  9.     let width = 960,
  10.         height = 500,
  11.         margin = { top: 0, right: 10, bottom: 0, left: 10 },
  12.         svg,
  13.         div,
  14.         updateData,
  15.         applyProjection,
  16.         mouseoverLegend,
  17.         mouseoutLegend;
  18.  
  19.     function chart(selection) {
  20.         selection.each(async function (d) {
  21.             div = d3.select('body').append('div')
  22.                 .attr('class', 'tooltip')
  23.                 .style('opacity', 0);
  24.             svg = selection.append('svg')
  25.                 .attr('width', width + margin.left + margin.right)
  26.                 .attr('height', height + margin.top + margin.bottom);
  27.  
  28.             const projection = d3.geoAlbersUsa();
  29.             const path = d3.geoPath().projection(projection);
  30.  
  31.             try {
  32.                 const data = await dataService.getUSA();
  33.                 const airports = applyProjection(initialData.airports, projection);
  34.                 const states = topojson.feature(data, data.objects.states);
  35.  
  36.                 const countries = svg.selectAll('path.state')
  37.                     .data(states.features).enter();
  38.  
  39.                 countries.insert('path', '.graticule')
  40.                     .attr('class', d => `state-${d.id}`)
  41.                     .style('fill', '#ccc')
  42.                     .attr('d', path)
  43.                     .on('mouseover', mouseoverLegend).on('mouseout', mouseoutLegend)
  44.                     .on('click', (d) => console.log('click ', d));
  45.  
  46.                 countries
  47.                     .append('svg:text')
  48.                     .attr('class', d => `state-${d.id}-label info`)
  49.                     .attr('transform', d => `translate(${width - 6 * d.properties.name.length}, 15)`)
  50.                     .attr('dy', '.35em')
  51.                     .append('svg:tspan')
  52.                     .attr('x', 0)
  53.                     .attr('dy', 5)
  54.                     .text(d => d.properties.name);
  55.  
  56.                 svg.selectAll('circle')
  57.                     .data(airports).enter()
  58.                     .append('circle')
  59.                     .attr('cx', d => d.x)
  60.                     .attr('cy', d => d.y)
  61.                     .attr('r', '1px')
  62.                     .attr('fill', 'red')
  63.  
  64.  
  65.                 // todo add a line between the flight’s origin/destination points
  66.                 // svg.selectAll("line")
  67.                 //     .data(airportsAsDots).enter()
  68.                 //     .append('line')
  69.                 //     .style("stroke", "black")  // colour the line
  70.                 //     .attr("x1", 100)     // x position of the first end of the line
  71.                 //     .attr("y1", 50)      // y position of the first end of the line
  72.                 //     .attr("x2", 300)     // x position of the second end of the line
  73.                 //     .attr("y2", 150);
  74.  
  75.             } catch (err) {
  76.                 console.error('Error in MapChart: ' + err);
  77.             }
  78.  
  79.             updateData = () => {
  80.                 console.log('update map');
  81.                 const airports = applyProjection(initialData.airports, projection);
  82.                 const airportsSelection = svg
  83.                     .selectAll('circle')
  84.                     .data(airports);
  85.                 airportsSelection.exit().remove();
  86.                 airportsSelection.enter()
  87.                     .append('circle')
  88.                     .merge(airportsSelection)
  89.                     .attr('cx', d => d.x)
  90.                     .attr('cy', d => d.y)
  91.                     .attr('r', '1px')
  92.                     .attr('fill', 'red')
  93.  
  94.             };
  95.         });
  96.     }
  97.  
  98.     chart.width = function (value) {
  99.         if (!arguments.length) return width;
  100.         width = value;
  101.         return chart;
  102.     };
  103.  
  104.     chart.height = function (value) {
  105.         if (!arguments.length) return height;
  106.         height = value;
  107.         return chart;
  108.     };
  109.  
  110.     chart.update = (data) => {
  111.         if (!data) {
  112.             return initialData;
  113.         }
  114.         initialData = data;
  115.         updateData();
  116.  
  117.         return chart;
  118.     };
  119.  
  120.     chart.load = (data) => {
  121.         if (!data) {
  122.             return initialData;
  123.         }
  124.         initialData = data;
  125.         return chart;
  126.     };
  127.  
  128.     applyProjection = (airports, projection) => {
  129.         return airports.reduce((acc, airport) => {
  130.             const proj = projection([+airport.long, +airport.lat]);
  131.             if (proj) {
  132.                 return acc.concat({x: proj[0], y: proj[1]});
  133.             }
  134.             return acc;
  135.         }, []);
  136.     };
  137.  
  138.     mouseoverLegend = (d) => {
  139.         console.log('mouseoverLegend ', d);
  140.         d3.selectAll(`.state-${d.id}`)
  141.             .style('fill', '#cc6699');
  142.  
  143.         d3.selectAll(`.state-${d.id}-label`)
  144.             .style('display', 'inline-block');
  145.  
  146.         div.transition()
  147.             .duration(200)
  148.             .style('opacity', .9);
  149.  
  150.         div.html(d.properties.name)
  151.             .style('left', (d3.event.pageX) + 'px')
  152.             .style('top', (d3.event.pageY - 28) + 'px')
  153.             .style('width', 8 * d.properties.name.length + 'px');
  154.     };
  155.  
  156.     mouseoutLegend = (d) => {
  157.         d3.selectAll(`.state-${d.id}`)
  158.             .style('fill', '#ccc');
  159.  
  160.         d3.selectAll(`.state-${d.id}-label`)
  161.             .style('display', 'none');
  162.  
  163.         div.transition()
  164.             .duration(500)
  165.             .style('opacity', 0);
  166.     };
  167.  
  168.     return chart;
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement