Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import * as d3 from 'd3';
- import * as topojson from 'topojson';
- import dataService from '../services/dataService'
- import './map.css';
- export default function () {
- let initialData;
- let width = 960,
- height = 500,
- margin = { top: 0, right: 10, bottom: 0, left: 10 },
- svg,
- div,
- updateData,
- applyProjection,
- mouseoverLegend,
- mouseoutLegend;
- function chart(selection) {
- selection.each(async function (d) {
- div = d3.select('body').append('div')
- .attr('class', 'tooltip')
- .style('opacity', 0);
- svg = selection.append('svg')
- .attr('width', width + margin.left + margin.right)
- .attr('height', height + margin.top + margin.bottom);
- const projection = d3.geoAlbersUsa();
- const path = d3.geoPath().projection(projection);
- try {
- const data = await dataService.getUSA();
- const airports = applyProjection(initialData.airports, projection);
- const states = topojson.feature(data, data.objects.states);
- const countries = svg.selectAll('path.state')
- .data(states.features).enter();
- countries.insert('path', '.graticule')
- .attr('class', d => `state-${d.id}`)
- .style('fill', '#ccc')
- .attr('d', path)
- .on('mouseover', mouseoverLegend).on('mouseout', mouseoutLegend)
- .on('click', (d) => console.log('click ', d));
- countries
- .append('svg:text')
- .attr('class', d => `state-${d.id}-label info`)
- .attr('transform', d => `translate(${width - 6 * d.properties.name.length}, 15)`)
- .attr('dy', '.35em')
- .append('svg:tspan')
- .attr('x', 0)
- .attr('dy', 5)
- .text(d => d.properties.name);
- svg.selectAll('circle')
- .data(airports).enter()
- .append('circle')
- .attr('cx', d => d.x)
- .attr('cy', d => d.y)
- .attr('r', '1px')
- .attr('fill', 'red')
- // todo add a line between the flight’s origin/destination points
- // svg.selectAll("line")
- // .data(airportsAsDots).enter()
- // .append('line')
- // .style("stroke", "black") // colour the line
- // .attr("x1", 100) // x position of the first end of the line
- // .attr("y1", 50) // y position of the first end of the line
- // .attr("x2", 300) // x position of the second end of the line
- // .attr("y2", 150);
- } catch (err) {
- console.error('Error in MapChart: ' + err);
- }
- updateData = () => {
- console.log('update map');
- const airports = applyProjection(initialData.airports, projection);
- const airportsSelection = svg
- .selectAll('circle')
- .data(airports);
- airportsSelection.exit().remove();
- airportsSelection.enter()
- .append('circle')
- .merge(airportsSelection)
- .attr('cx', d => d.x)
- .attr('cy', d => d.y)
- .attr('r', '1px')
- .attr('fill', 'red')
- };
- });
- }
- chart.width = function (value) {
- if (!arguments.length) return width;
- width = value;
- return chart;
- };
- chart.height = function (value) {
- if (!arguments.length) return height;
- height = value;
- return chart;
- };
- chart.update = (data) => {
- if (!data) {
- return initialData;
- }
- initialData = data;
- updateData();
- return chart;
- };
- chart.load = (data) => {
- if (!data) {
- return initialData;
- }
- initialData = data;
- return chart;
- };
- applyProjection = (airports, projection) => {
- return airports.reduce((acc, airport) => {
- const proj = projection([+airport.long, +airport.lat]);
- if (proj) {
- return acc.concat({x: proj[0], y: proj[1]});
- }
- return acc;
- }, []);
- };
- mouseoverLegend = (d) => {
- console.log('mouseoverLegend ', d);
- d3.selectAll(`.state-${d.id}`)
- .style('fill', '#cc6699');
- d3.selectAll(`.state-${d.id}-label`)
- .style('display', 'inline-block');
- div.transition()
- .duration(200)
- .style('opacity', .9);
- div.html(d.properties.name)
- .style('left', (d3.event.pageX) + 'px')
- .style('top', (d3.event.pageY - 28) + 'px')
- .style('width', 8 * d.properties.name.length + 'px');
- };
- mouseoutLegend = (d) => {
- d3.selectAll(`.state-${d.id}`)
- .style('fill', '#ccc');
- d3.selectAll(`.state-${d.id}-label`)
- .style('display', 'none');
- div.transition()
- .duration(500)
- .style('opacity', 0);
- };
- return chart;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement