Public
Edited
Aug 1, 2023
78 forks
Importers
18 stars
Insert cell
Insert cell
chart = {

// Specify the chart’s dimensions.
const width = 928;
const marginTop = 46;
const height = width / 2 + marginTop;

// Fit the projection.
const projection = d3.geoEqualEarth().fitExtent([[2, marginTop + 2], [width - 2, height]], {type: "Sphere"});
const path = d3.geoPath(projection);

// Index the values and create the color scale.
const valuemap = new Map(hale.map(d => [d.name, d.hale]));
const color = d3.scaleSequential(d3.extent(valuemap.values()), d3.interpolateYlGnBu);

// Create the SVG container.
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto;");

// Append the legend.
svg.append("g")
.attr("transform", "translate(20,0)")
.append(() => Legend(color, {title: "Healthy life expectancy (years)", width: 260}));

// Add a white sphere with a black border.
svg.append("path")
.datum({type: "Sphere"})
.attr("fill", "white")
.attr("stroke", "currentColor")
.attr("d", path);

// Add a path for each country and color it according te this data.
svg.append("g")
.selectAll("path")
.data(countries.features)
.join("path")
.attr("fill", d => color(valuemap.get(d.properties.name)))
.attr("d", path)
.append("title")
.text(d => `${d.properties.name}\n${valuemap.get(d.properties.name)}`);

// Add a white mesh.
svg.append("path")
.datum(countrymesh)
.attr("fill", "none")
.attr("stroke", "white")
.attr("d", path);

return svg.node();
}
Insert cell
Insert cell
hale = (await FileAttachment("hale.csv").csv()).map(d => ({name: rename.get(d.country) || d.country, hale: +d.hale}))
Insert cell
rename = new Map([
["Antigua and Barbuda", "Antigua and Barb."],
["Bolivia (Plurinational State of)", "Bolivia"],
["Bosnia and Herzegovina", "Bosnia and Herz."],
["Brunei Darussalam", "Brunei"],
["Central African Republic", "Central African Rep."],
["Cook Islands", "Cook Is."],
["Democratic People's Republic of Korea", "North Korea"],
["Democratic Republic of the Congo", "Dem. Rep. Congo"],
["Dominican Republic", "Dominican Rep."],
["Equatorial Guinea", "Eq. Guinea"],
["Iran (Islamic Republic of)", "Iran"],
["Lao People's Democratic Republic", "Laos"],
["Marshall Islands", "Marshall Is."],
["Micronesia (Federated States of)", "Micronesia"],
["Republic of Korea", "South Korea"],
["Republic of Moldova", "Moldova"],
["Russian Federation", "Russia"],
["Saint Kitts and Nevis", "St. Kitts and Nevis"],
["Saint Vincent and the Grenadines", "St. Vin. and Gren."],
["Sao Tome and Principe", "São Tomé and Principe"],
["Solomon Islands", "Solomon Is."],
["South Sudan", "S. Sudan"],
["Swaziland", "eSwatini"],
["Syrian Arab Republic", "Syria"],
["The former Yugoslav Republic of Macedonia", "Macedonia"],
// ["Tuvalu", ?],
["United Republic of Tanzania", "Tanzania"],
["Venezuela (Bolivarian Republic of)", "Venezuela"],
["Viet Nam", "Vietnam"]
])
Insert cell
Insert cell
world = FileAttachment("countries-50m.json").json()
Insert cell
countries = topojson.feature(world, world.objects.countries)
Insert cell
Insert cell
countrymesh = topojson.mesh(world, world.objects.countries, (a, b) => a !== b)
Insert cell
import {Legend} from "@d3/color-legend"
Insert cell
Insert cell
Plot.plot({
projection: "equal-earth",
width: 928,
height: 928 / 2,
color: {scheme: "YlGnBu", unknown: "#ccc", label: "Healthy life expectancy (years)", legend: true},
marks: [
Plot.sphere({fill: "white", stroke: "currentColor"}),
Plot.geo(countries, {
fill: (map => d => map.get(d.properties.name))(new Map(hale.map(d => [d.name, d.hale]))),
}),
Plot.geo(countrymesh, {stroke: "white"}),
]
})
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more