fraxture
fraxture

Reputation: 5510

Getting NaN values in svg path 'd' attr when trying to map geojson data

I have been trying, unsuccessfully, to map some GeoJSON data using d3.

The specific problem that I think that my code generates a series of path scg elements whose d attribute end up containing NaN values. Here's an example of a result I get:

<path fill="#ccc" stroke="#333" d="MNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNZ">
</path>

Here is what my code looks like:

var width = 960;
var height = 960;

var dataUrl =
  "https://gist.githubusercontent.com/ezmiller/35d6a354fa1da0bd076dfe7b74a30a7d/raw/9398ec491e0dc9b38f7f251e5c7bf90ad8b45779/2016-kings-county-pres-primary-35th.json";

var projection = d3.geoConicEqualArea()
  .parallels([73.97369384765625, 40.64664205310956])
  .rotate([89.5,0])
  .fitSize([960, 960]); 

var path = d3.geoPath().projection(projection);

var svg = d3
  .select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

var g = svg.append('g');

var mapLayer = g.append('g')
  .classed('map-layer', true);

d3.json(dataUrl, function(err, data) {
  if (err) throw err;

  mapLayer.selectAll('path')
    .data(data.features)
    .enter()
    .append('path')
    .attr("fill", "#ccc")
    .attr("stroke","#333")
    .attr("d", path);
});

(Here is a codepen)

What am I doing wrong here?

Upvotes: 2

Views: 1143

Answers (1)

Andrew Reid
Andrew Reid

Reputation: 38151

The problem is that you are not fitting the projection to anything with .fitSize

fitSize takes two parameters, an array with width and height and a geojson feature: projection.fitSize([width,height],geojson). You meed to specify what geojson feature (or feature collextion) should be fit to your specified dimensions. This method sets the scale and translate, so without a feature, these will not be set and your projection will return NaN values.

As your geojson is not loaded until your d3.json callback is triggered, this method must be invoked within the callback. Also note that the method needs a feature or feature collection, not an array of features (data, not data.features in your case):

projection.fitSize([960,960],data)

Upvotes: 3

Related Questions