stormblessed97
stormblessed97

Reputation: 25

Correct attribute "d" doesn't seem to be added to "path" using d3.geoPath(projection)

I am trying to create a map of the United States for a project. To do this, I am using d3.geoAlbersUsa() as the projection and d3.geoPath(projection) as the path function. However, when appending "path" to my svg, it looks like the "d" attribute isn't getting set.

// Projection from geoAlbersUsa
let projection = d3.geoAlbersUsa()
                    .translate(width/2,height/2)
                    .scale(10000);

// Path from geoPath with the previous projection
let path = d3.geoPath().projection(projection);

let svg = d3.select("#svg");

// Load in csv and json data
d3.csv("state_results.csv", data => {
  d3.json("states.json", json => {

    // Process data from csv file and json file
    ...
    ...
    ...

    // Selecting 'g' element in svg and appending 'path'
    d3.select("#map").selectAll("path")
                .data(json.features)
                .enter()
                .append("path")
                .attr("d", path)
                .style("fill", d => {
                    return d.properties.party;
                });

When I start up my sever, this is what shows when I inspect the svg element: enter image description here

Any ideas on why the "d" attribute isn't getting set correctly in each path?


Below is one element from the json.features array: {"type":"Feature","id":"49","properties":{"name":"Utah","density":34.30},"geometry":{"type":"Polygon","coordinates":[[[-112.164359,41.995232],[-111.047063,42.000709],[-111.047063,40.998429],[-109.04798,40.998429],[-109.053457,39.125316],[-109.058934,38.27639],[-109.042503,38.166851],[-109.042503,37.000263],[-110.499369,37.00574],[-114.048427,37.000263],[-114.04295,41.995232],[-112.164359,41.995232]]]}},

Upvotes: 0

Views: 259

Answers (1)

Ruben Helsloot
Ruben Helsloot

Reputation: 13129

I've made it work with the example data you gave. You need to put brackets around the numbers in .translate([width / 2, height / 2]). Other than that, I just had to make the scale a little bit smaller to make it fit on the screen.

const jsonFeatures = [{
  "type": "Feature",
  "id": "49",
  "properties": {
    "name": "Utah",
    "density": 34.30
  },
  "geometry": {
    "type": "Polygon",
    "coordinates": [
      [
        [-112.164359, 41.995232],
        [-111.047063, 42.000709],
        [-111.047063, 40.998429],
        [-109.04798, 40.998429],
        [-109.053457, 39.125316],
        [-109.058934, 38.27639],
        [-109.042503, 38.166851],
        [-109.042503, 37.000263],
        [-110.499369, 37.00574],
        [-114.048427, 37.000263],
        [-114.04295, 41.995232],
        [-112.164359, 41.995232]
      ]
    ]
  }
}];

let width = 500,
  height = 300;

// Projection from geoAlbersUsa
let projection = d3.geoAlbersUsa()
  .translate([width / 2, height / 2])
  .scale(1000);

// Path from geoPath with the previous projection
let path = d3.geoPath().projection(projection);

let svg = d3.select("svg").attr("width", width).attr("height", height);

svg.selectAll("path")
  .data(jsonFeatures)
  .enter()
  .append("path")
  .attr("d", path)
  .style("fill", d => {
    return d.properties.party;
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.js"></script>
<svg></svg>

Upvotes: 1

Related Questions