Saturday, 20 March 2021

D3.js, Global Chloropleth / Heat Map . Make Legend Horizontal and Add Black Borders Around Countries

I've been playing around with d3.js for the first time and have managed to create a basic chloropleth map.

enter image description here

In essence there are 3 things remaining that i'd like to do, but am not familiar enough with d3 or Javascript to do them:

  1. Make legend horizontal and move it below the coast of Africa

  2. Add thin black border to all of the countries.

  3. Perhaps automatically crop out antartica? This can be done in post processing if not possible

Not sure if these tasks are impossible or easy as I have not worked much with d3.js and wasn't making much headway.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  @import url(//fonts.googleapis.com/css?family=Times+New+Roman);




  .countries {
    fill: none;
    stroke: #fff;
    stroke-linejoin: round;
  }
  .legendThreshold {
      font-size: 12px;
      font-family: sans-serif;
  }
  .caption {
      fill: #000;
      text-anchor: start;
      font-size: 14px;
  }
  /*      font-weight: bold;*/

  .anchorNode {
       font-family: "Times New Roman";
      font-size: 2px;
  }
  .legendLinear text.label {
     fill: '#fff'
       font-family: "Times New Roman";
      font-size: 2px;
}

  .legendThreshold text.label {
     fill: '#fff'
       font-family: "Times New Roman";
     font-size: 12px;

}
* {
 font-family: "Times New Roman", Times, serif;

}



/* font-size: 100%;*/

</style>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.js"></script>
<script>
// The svg
var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height");

// Map and projection
var path = d3.geoPath();
var projection = d3.geoMercator()
    .scale(width / 2 / Math.PI)
    .translate([width / 2, height / 2])
var path = d3.geoPath()
    .projection(projection);

// Data and color scale
var data = d3.map();
var colorScheme = d3.schemeReds[6];
colorScheme.unshift("#eee")
var colorScale = d3.scaleThreshold()
    .domain([1, 3, 5, 10, 20, 100])
    .range(colorScheme);

// Legend
var g = svg.append("g")
    
    .attr("class", "legendThreshold")
    .attr("transform", "translate(190,300)");

g.append("text")
    .attr("class", "caption")
    .attr("x", 0)
    .attr("y", -6)
    .style("font-size","12px")

    .text("Subscribers");
var labels = ['0', '1-3', '3-5', '5-10', '10-20', '20-100', '> 100'];
var legend = d3.legendColor()
    .labels(function (d) { return labels[d.i]; })
    .shapePadding(0)
    .scale(colorScale);
svg.select(".legendThreshold")
    .call(legend);

// Load external data and boot
d3.queue()
    .defer(d3.json, "http://enjalot.github.io/wwsd/data/world/world-110m.geojson")
    .defer(d3.csv, "https://gist.githubusercontent.com/palewire/d2906de347a160f38bc0b7ca57721328/raw/3429696a8d51ae43867633ffe438128f8c396998/mooc-countries.csv", function(d) { data.set(d.code, +d.total); })
    .await(ready);

function ready(error, topo) {
    if (error) throw error;

    // Draw the map
    svg.append("g")
        .attr("class", "countries")
        .selectAll("path")
        .data(topo.features)
        .enter().append("path")
            .attr("fill", function (d){
                // Pull data for this country
                d.total = data.get(d.id) || 0;
                // Set the color
                return colorScale(d.total);
            })
            .attr("d", path);
}
</script>


from D3.js, Global Chloropleth / Heat Map . Make Legend Horizontal and Add Black Borders Around Countries

No comments:

Post a Comment