Как рисовать пузыри на карте D3 с проекцией Меркатора?

Я сделал карту мира в D3 с проекцией Меркатора и попытался нарисовать круги/пузыри, но они не отображаются на карте. Я использую ту же проекцию для путей для карты, что и для кругов, чтобы вычислить проекции cx и cy, но получаю следующую ошибку в моем коде ниже:

Uncaught TypeError: не удается прочитать «координаты» свойства null

  var margin = {top: 20, right: 20, bottom: 20, left: 20};  

  var w = 1100 - margin.left - margin.right;

  var h = 900 - margin.top - margin.bottom;

  var svg = d3.select("#chart")
              .append("svg")
                .attr("width", w + margin.left + margin.right)
                .attr("height", h + margin.top + margin.bottom)
              .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var meteorsData = "https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/meteorite-strike-data.json";

var geoData = "https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json";

var geo = {};

var meteors = {};

d3.json(geoData, function(data){
//load world map data  

   geo = data.features;

   d3.json(meteorsData, function(data){

        meteors = data.features;

        var projection = d3.geo.mercator()
                     .scale(150)
                     .translate([w/2, h/2]);

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

        svg.selectAll("path")
            .data(geo)
            .enter()
            .append("path")
            .attr("fill", "#95E1D3")
            .attr("stroke", "#34495e")
            .attr("stroke-width", 0.5)
            .attr("class", "countries")
            .attr("d", path);

        svg.selectAll(".circles")
           .data(meteors)
           .enter()
           .append("circle")
           .attr("cx", function(d){ return projection(d.geometry.coordinates)[0]})
           .attr("cy", function(d){ return projection(d.geometry.coordinates)[1]})
           .attr("r", 10)
           .attr("fill", "ccc");

            })

})

Кто-нибудь может мне помочь? Спасибо


person chemook78    schedule 03.02.2017    source источник
comment
Я предполагаю, что эта часть кода d.geometry.coordinates вызывает ошибки. Похоже, ваши данные не имеют атрибута geometry.   -  person Craicerjack    schedule 03.02.2017
comment
привет, да, это набор данных: raw.githubusercontent. com/FreeCodeCamp/ProjectReferenceData/   -  person chemook78    schedule 03.02.2017
comment
Да, я просто смотрел на набор данных, но в вашем коде он кажется нулевым. если вы сделаете console.log(d) до того, как вернете свою проекцию, есть ли геометрия в зарегистрированных данных?   -  person Craicerjack    schedule 03.02.2017
comment
да есть для атрибута cx. Но странно, что это не для атрибута cy, и я понятия не имею, почему? Вот рабочий пример: codepen.io/chemok78/full/xgWYQx   -  person chemook78    schedule 03.02.2017


Ответы (1)


Итак, в данных вы использовали https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/meteorite-strike-data.json
была одна точка данных, у которой не было геометрии, и это вызывало ошибку

{
    "type": "Feature",
    "geometry": null,
    "properties": {
      "mass": "2250",
      "name": "Bulls Run",
      "reclong": null,
      "geolocation_address": null,
      "geolocation_zip": null,
      "year": "1964-01-01T00:00:00.000",
      "geolocation_state": null,
      "fall": "Fell",
      "id": "5163",
      "recclass": "Iron?",
      "reclat": null,
      "geolocation_city": null,
      "nametype": "Valid"
    }
},  

поэтому, если вы установите флажок в своих функциях cx и cy, это должно решить проблему:

.attr("cx", function(d){ 
    if (d.geometry){
        return projection(d.geometry.coordinates)[0];
    }
})
.attr("cy", function(d){ 
    if (d.geometry) { 
        return projection(d.geometry.coordinates)[1];
    }
})  

Работающий codepen здесь http://codepen.io/anon/pen/xgjrmR

person Craicerjack    schedule 03.02.2017