Search code examples
svgd3.jstransformprojectiontranslate

D3 Projection_Transform attr


I've got Uncaught TypeError: Cannot read property 'join' of null in the line translate(${projection([longitude, latitude]).join(",")}). I've already checked that my var locations has data in it:

enter image description here

So, can't understand where is the problem?

Full js-code:

import * as d3 from "d3";
import * as topojson from "topojson-client";
import us from "./us.json";
import data from "./wm.json"; 

const width = 975;
const height = 610;

const projection = d3
  .geoAlbersUsa()
  .scale(1300)
  .translate(width / 2, height / 2);

const path = d3.geoPath();
const svg = d3.create("svg").attr("height", height).attr("width", width);

const worldMap = svg
  .append("path")
  .attr("fill", "#ddd")
  .attr("d", path(topojson.feature(us, us.objects.nation)));

const worldBorders = svg
  .append("path")
  .attr("fill", "none")
  .attr("stroke", "#fff")
  .attr("stroke-linejoin", "round")
  .attr("stroke-linecap", "round")
  .attr("d", path(topojson.feature(us, us.objects.states)));

const locations = svg
  .selectAll("g")
  .attr("text-anchor", "middle")
  .attr("font-family", "sans-serif")
  .attr("font-size", 10)
  .data(data)
  .join("g");
console.log(locations);
const locationGroups = locations
  .append("g")
  .attr(
    "transform",
    ({ longitude, latitude }) =>
      `translate(${projection([longitude, latitude]).join(",")})`
  );

document.body.appendChild(svg.node());

Output for console.log(us.objects) has type and geometries both fot states and nation: enter image description here


Solution

  • Problem was in scoping variable projection:

    const projection = d3
      .geoAlbersUsa()
      .scale(1300)
      .translate(width / 2, height / 2);
    

    I checked with console.log(projection(-86.300568, 32.377716)) and in output was null. So I changed

    `translate(${projection([longitude, latitude]).join(",")})`
    

    to

    `translate(${d3
          .geoAlbersUsa()
          .scale(1300)
          .translate([width / 2, height / 2])([longitude, latitude])
          .join(",")})`
    

    And it works now! 😃

    But there is still question of how to make variable projection be visible in the scope? 🤔