Published
Edited
Sep 27, 2022
Insert cell
Insert cell
map = {
const W = width;
const H = (W * height) / width;
const svg = d3
.select(DOM.svg(W, H))
.style("border", "1px solid #000")
.style("background", "#eee");
const g = svg.append("g");
const g_countries = g.append("g");

const projection = d3
.geoConicConformal()
.parallels([40, 68])
.rotate([-10, 0])
.center([8 - 10, 51.823])
.scale((width * 1.36) / 1.1)
.translate([W / 2, H / 2]);

const path = d3.geoPath().projection(projection);

const countries = g_countries.selectAll("path").data(areas);

countries
.enter()
.append("path")
.attr("class", "country")
.attr("fill", (d) => {
let owidDataPoint = lastData.get(d.properties.iso_a3);

if (owidDataPoint) {
console.log("owid: ", owidDataPoint.Entity, owidDataPoint.pantsOnFire);
let factor = owidDataPoint.pantsOnFire;
if (factor < 0) return d3.interpolateBlues(factor * -1);
else return d3.interpolateReds(owidDataPoint.pantsOnFire);
} else return "grey";
})
.attr("stroke", "black")
.attr("stroke-linejoin", "round")
.merge(countries)
.attr("d", path)
.append("title")
.text((d) => {
let owidDataPoint = lastData.get(d.properties.iso_a3);

if (owidDataPoint) {
return `${d.properties.name}\n${
owidDataPoint.Day
}\nConfirmed COVID-19 deaths: ${d3.format(",")(
owidDataPoint["Total confirmed deaths due to COVID-19"]
)}\nCumulative estimated excess deaths: ${d3.format(",.0f")(
owidDataPoint["cumulative_estimated_daily_excess_deaths"]
)}\nDiff: ${d3.format(".0%")(owidDataPoint.pantsOnFire)}`;
}
return `${d.properties.name}\n`;
});

g.append("text")
.attr("x", 20)
.attr("y", 30)
.attr("font-size", 16)
.attr("font-family", "sans")
.text("Pandemic excess death gap not accounted for by COVID-19 deaths");

g.append("text")
.attr("x", 20)
.attr("y", height - 40)
.attr("font-size", 10)
.attr("font-family", "sans")
.attr("fill", "grey")
.text("Author @velimirgasp");

g.append("text")
.attr("x", 20)
.attr("y", height - 25)
.attr("font-size", 10)
.attr("font-family", "sans")
.attr("fill", "grey")
.text("Data @OurWorldInData");

const entry = g
.selectAll(".legendEntry")
.data(liarsRanked)
.enter()
.append("g");

entry
.append("text")
.attr("x", 32)
.attr("y", (_, i) => i * 18 + 50)
.attr("dy", 9)
.attr("font-size", 11)
.attr("font-family", "sans")
.text((d) => `${d.country} ${d3.format(".0%")(d.diff)}`);

entry
.append("rect")
.attr("x", 20)
.attr("y", (_, i) => i * 18 + 50)
.attr("width", 10)
.attr("height", 10)
.attr("fill", (d) => {
let owidDataPoint = lastData.get(d.code);

if (owidDataPoint) {
console.log("owid: ", owidDataPoint.Entity, owidDataPoint.pantsOnFire);
let factor = owidDataPoint.pantsOnFire;
if (factor < 0) return d3.interpolateBlues(factor * -1);
else return d3.interpolateReds(owidDataPoint.pantsOnFire);
} else return "grey";
});

// graticules.attr("d", path(d3.geoGraticule().step([20, 20])()));

return svg.node();
}
Insert cell
liarsRanked = tableData.sort((a, b) => b.Diff - a.Diff)
Insert cell
tableData = [...lastData.values()]
.filter((d) => d["Total confirmed deaths due to COVID-19"] > 1000)
.map((d) => {
return {
country: d.Entity,
code: d.Code,
diff: d.pantsOnFire
};
})
.sort((a, b) => b.diff - a.diff)
Insert cell
countryCodes = [...new Set(areas.map((d) => d.properties.iso_a3))]
Insert cell
owidKeys = [...countryGroupedOwid.keys()]
Insert cell
lastData = {
let keys = [...owidCountryGrouped.keys()];
let retval = new Map();

keys.forEach((key) => {
let arr = owidCountryGrouped.get(key);

arr = arr.filter((d) => d.cumulative_estimated_daily_excess_deaths);
let prop = arr[arr.length - 1];

let deaths = +prop.cumulative_estimated_daily_excess_deaths;
let covid = +prop["Total confirmed deaths due to COVID-19"];
prop.pantsOnFire = (deaths - covid) / deaths;

retval.set(key, prop);
});
return retval;
}
Insert cell
owidCountryGrouped.get("FRA").filter(d=>d.cumulative_estimated_daily_excess_deaths)
Insert cell
owidCountryGrouped = {
let retval = new Map();

owidKeys.forEach((owidKey) => {
if (countryCodes.includes(owidKey))
retval.set(owidKey, countryGroupedOwid.get(owidKey));
});
return retval;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
areasGrouped.delete("GRL")
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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