0

I was inspired by the wonderful series of D3 maps displayed here from maptimelex. I am trying to replicate it, but using a map of the country of Haiti instead of the state of Kentucky.

Please see my JSFiddle here.

I am using a JSON file with the simple borders of Haiti. It doesn't include any administrative boundaries (departments, communes, etc.). The map doesn't seem to render properly and I am not sure what the problem is.

I get errors suggesting that the JSON file is not loading or rendering properly. One error says: "XMLHttpRequest cannot load: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource." Another error says: "Uncaught TypeError: Cannot read property 'coordinates' of null".

Here is my JavaScript code:

// set height and width of viz    
var width = window.innerWidth,
    height = window.innerHeight;

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

// define JSON map data
d3.json("https://gist.github.com/29a1f4a91c1c8d615595.git", function (json) {

    // create a first guess for the projection
    var center = d3.geo.centroid(json);
    var scale = 150;
    var offset = [width / 2, height / 2];

    var projection = d3.geo.mercator()
        .center(center)
        .rotate([85.8, 0])
        .scale(scale)
        .translate(offset);

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

    svg.append("g")
        .selectAll("path")
        .data(json.coordinates)
        .enter()
        .append("path")
        .attr("d", geoPath);
});
matt
  • 97
  • 3
  • 18

2 Answers2

1

The error is saying that you cant load https://gist.github.com/29a1f4a91c1c8d615595.git becuase it comes from a different origin and does not support CORS. You could try downloading the JSON file locally and pointing your script to that file instead of the remote location.

noveyak
  • 3,240
  • 1
  • 19
  • 19
  • My mistake - now it is loading the JSON from this link https://rawgit.com/mattbowlby/29a1f4a91c1c8d615595/raw/9aac80c757f6af814ad425c45e130bec25e68354/haiti.json – matt Jul 04 '15 at 17:20
  • But the map is still not rendering properly. Any ideas? – matt Jul 04 '15 at 17:20
1

In addtion to @noveyak's answer, your JSON contains a GeometryCollection and as such has a property of .geometries not .coordinates. Also, your scale is too small and the rotate is unnecessary.

Putting this together:

// create a first guess for the projection
var center = d3.geo.centroid(json);

var scale = 8000;
var offset = [width / 2, height / 2];

var projection = d3.geo.mercator()
  .center(center)
  .scale(scale)
  .translate(offset);

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

svg.append("g")
  .selectAll("path")
  .data(json.geometries) //<-- geometries
  .enter()
  .append("path")
  .attr("d", geoPath);

Updated example.

Mark
  • 106,305
  • 20
  • 172
  • 230
  • This works great - thanks. I see now. However, I still have a problem if I try and load the JSON locally (i.e. haiti.json in the same directory as haiti.html). I get the error message in the JS console: "XMLHttpRequest cannot load file:///Users/matt/Desktop/haiti/haiti.json. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource." If I link to a JSON stored on a server (i.e. http://), then it works. Any idea why that is and how I can make it work with locally stored JSON? – matt Jul 05 '15 at 00:10
  • 1
    @mattbowlby, sounds like you are just running this off a local drive. You need to serve the content from a webserver. See further explanation [here](http://stackoverflow.com/questions/20041656/xmlhttprequest-cannot-load-file-cross-origin-requests-are-only-supported-for-ht) – Mark Jul 05 '15 at 13:15