D3.js,全球叶绿素/热图。使图例水平并在国家周围添加黑色边框

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

我第一次使用 d3.js 并成功创建了基本的叶绿素图。

本质上还有 3 件事我想做,但我对 d3 或 Javascript 不够熟悉,无法完成它们:

  1. 水平放置图例并将其移动到非洲海岸下方

  2. 为所有国家/地区添加黑色细边框。

  3. 也许会自动裁剪出南极洲?如果不可能,这可以在 post 处理中完成

不确定这些任务是不可能还是容易,因为我在 d3.js 方面工作不多,也没有取得太大进展。

<!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>

前两个是微不足道的。 1 只是改变图例翻译位置的问题 并使其水平只是通过查看 d3-legend 文档 (https://d3-legend.susielu.com/#color-linear):

var g = svg.append("g")
    .attr("class", "legendThreshold")
    .attr("transform", "translate(440,440)");

...and jump ahead for next bit...

var legend = d3.legendColor()
    .labels(function (d) { return labels[d.i]; })
    .shapePadding(0)
    .orient('horizontal')
    .shapeWidth(40)
    .scale(colorScale);

2 您将 css

中的 .countries 的描边颜色更改为黑色 (#000)
  .countries {
    fill: none;
    stroke: #000;
    stroke-linejoin: round;
  }

3 涉及更多,但在数据中(在 console.logging 返回的对象之后)我们知道南极洲的键是“ATA”,因此我们可以从返回的对象中过滤掉它topo.features数据

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

  topo.features = topo.features.filter (function(d) { return d.id !== "ATA"; });

https://jsfiddle.net/13zqyvrL/