D3.js,全球叶绿素/热图。使图例水平并在国家周围添加黑色边框
D3.js, Global Chloropleth / Heat Map . Make Legend Horizontal and Add Black Borders Around Countries
我第一次使用 d3.js 并成功创建了基本的叶绿素图。
本质上还有 3 件事我想做,但我对 d3 或 Javascript 不够熟悉,无法完成它们:
水平放置图例并将其移动到非洲海岸下方
为所有国家/地区添加黑色细边框。
也许会自动裁剪出南极洲?如果不可能,这可以在 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"; });
我第一次使用 d3.js 并成功创建了基本的叶绿素图。
本质上还有 3 件事我想做,但我对 d3 或 Javascript 不够熟悉,无法完成它们:
水平放置图例并将其移动到非洲海岸下方
为所有国家/地区添加黑色细边框。
也许会自动裁剪出南极洲?如果不可能,这可以在 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"; });