Question

I'm trying to make a rollover map in D3 that allows me to use a standard world GeoJSON file and a CSV that matches up with ISO ids. I'm able to match everything when it comes to highlighting the countries and coloring them differently, but I can't seem to reference the values when it comes to populating a text field. Here a selection from my code:

    function setUpChoropleth(error, json, _csv) {
      csv = _csv;

      svg.append("g")
      .selectAll("path")
        .data(topojson.feature(json, json.objects.countries).features)
      .enter().append("svg:path")
        .attr("d", path)
          .on("mouseover", function(d,i) {
            var mouse = d3.mouse(svg.node()).map( function(d) { return parseInt(d); } );
            d3.select("#map1 h2 span").text(d);
          });

      states2.selectAll("path")
          .data(topojson.feature(json, json.objects.countries).features)
        .enter().append("svg:path")
          .attr("d", path)
          .attr("class", function(d,i) { return "country" + d.id; });
      states3.selectAll("path")
          .data(topojson.feature(json, json.objects.countries).features)
        .enter().append("svg:path")
          .attr("d", path)
          .attr("class", function(d,i) { return "country" + d.id; });

    } 

    function drawTierI() {
      csv.forEach(function(d) { tierById.set(d.id, +d.tier_i); });

      function ready(error, json, _csv) {
        svg.selectAll("path")
            .attr("class", function(d) { return quantize(tierById.get(d.id)); })
            .attr("d", path)
            .on("mouseover", function(d) {
              d3.select("#map1 .panel h3").text(d.id);
            });
      }
      ready();
    }

    $('button#tier_i').click(function (e) {
      drawTierI();
      d3.select("#map1 .panel-title").text("Countries equipped with drones")
      d3.select("#map1 .panel-body").text("These countries are equipped with drones.")
    });

I also have a demo here: http://newamericafoundation.github.io/worldofdrones/map.html

When you click on the "Has drones" link and rollover the countries, the only variables I have access to are the variables in the GeoJSON. Is it possible to use the same join I used to highlight the CSV data on the map to bring in data from that same spreasheet, wod.csv?

Please help me, even a clue would help!

Thanks!

Was it helpful?

Solution

Both Lar's and my idea involve iterating through the data and matching ids. Lars would do this on the fly, so whenever you hovered over an element the relevant text would pop up in the reporting tab. In mine on the the other hand you pre processes the data just after it's loaded so the csv data is joined to the geojson data. This might save you a lot of time depending on how much data you have as the join is only done once.

The data joining occurs in a function like this:

    csv.forEach(function(d, i) {
        geojson.forEach(function(e, j) {
            if (d.id === e.id) {
                e.name = d.name
            }
        })
    })

This code expects that there is a column in the csv that has a list of id's that match some property in the json file which I have assumed is also called id. The code has two loops, the outer loop is for the csv data and the inner loop is for the geojson data. The outer loop selects the first id value in the csv and then checks against the id values in the json and when it finds one that matches it creates a new variable in the json called name and adds the corresponding name value from the csv file.

And you can see it in action here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top