D3: Mappa coropletica - Proiezioni
<style>
.country:hover {
stroke: #b64;
stroke-width: 1px;
}
</style>
<script>
let svg = d3.select("body").append("svg")
.attr("width",670).attr("height",350)
let margin = { top: 0, right: 0, bottom: 0, left: 40 }
let graphWidth = 670 - margin.left - margin.right
let graphHeight = 350 - margin.top - margin.bottom
let graph = svg.append("g")
.attr("transform", "translate("+margin.left+","+margin.top+")")
let projection = d3.geoNaturalEarth1()
projection.translate([graphWidth/2, graphHeight/2])
.scale(projection.scale() * (graphHeight/500))
let pathGenerator = d3.geoPath().projection(projection)
Promise.all([
d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson"),
d3.tsv("https://unpkg.com/world-atlas@1.1.4/world/50m.tsv")
]).then(function([geoData, tsvData]) {
let countryIncomes = {}
tsvData.forEach(d => {
countryIncomes[d.iso_a3] = d.income_grp
})
let incomeGroups = []
tsvData.forEach(d => {
if (!incomeGroups.includes(d.income_grp)) {
incomeGroups.push(d.income_grp)
}
})
let colorScale = d3.scaleOrdinal()
.domain(incomeGroups.sort())
.range(d3.schemeBlues[incomeGroups.length+1].slice().reverse())
graph.selectAll(".country")
.data(geoData.features)
.join("path")
.attr("class", "country")
.attr("d", pathGenerator)
.attr("fill", d => {
let incomeGroup = countryIncomes[d.id]
return incomeGroup ? colorScale(incomeGroup) : "#bbb"
})
.append("title")
.text(d => {
let countryName = d.properties.name
let incomeGroup = countryIncomes[d.id] || "Unclassified"
return countryName + ":\n" + incomeGroup
})
let legendY = svg.attr("height") - incomeGroups.length*18 - 20
let legend = svg.append("g")
.attr("class", "legend")
.attr("transform", "translate(10, " + legendY + ")")
incomeGroups.forEach((group, i) => {
let legendRow = legend.append("g")
.attr("transform", "translate(0, " + (i*18) + ")")
legendRow.append("rect")
.attr("width", 15)
.attr("height", 15)
.attr("fill", colorScale(group))
legendRow.append("text")
.attr("x", 22)
.attr("y", 12)
.style("font-family", "sans-serif")
.style("font-size", "12px")
.text(group)
})
})
</script>
Viene creata un’istanza della modalità di proiezione cartografica pseudocilindrica “Natural Earth” (d3.geoNaturalEarth1() ). La proiezione viene centrata all’interno del gruppo graph e, visto che le impostazioni predefinite si riferiscono a una dimensione complessiva di 960x500 pixel, la scala viene adattata alla risoluzione del gruppo con la mappa (projection.scale() * (graphHeight/500) ).
La proiezione viene usata per impostare le trasformazioni del generatore di sagome creato con il metodo d3.geoPath() .
Usare una diversa modalità di visualizzazione provando fra le proiezioni di d3.js , ad esempio: d3.geoEquirectangular() oppure d3.geoOrthographic()