Public
Edited
Mar 21, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
let svg = d3.create("svg").attr("height", height).attr("width", width);

let margin = { top: 20, bottom: 20, left: 90, right: 20 };

let chartw = width - margin.left - margin.right;
let charth = height - margin.top - margin.bottom;

let xScale = d3
.scaleTime()
.domain([
d3.min(faminesOwd, (d) => d.start),
d3.max(faminesOwd, (d) => d.end)
])
.range([0, chartw]);

let yScale = d3
.scaleLinear()
.domain(d3.extent(faminesOwd, (d) => d["mortality_mid"]))
.range([charth, 0]);

let textScale = d3
.scaleSqrt()
.domain(d3.extent(faminesOwd, (d) => d["mortality_mid"]))
.range([minTextSize, textSize]);

let groups = svg
.append("g")
.attr("id", "viz")
.attr("transform", `translate(${margin.left}, ${margin.top})`)
.selectAll("g")
.data(faminesOwd)
.join("g")
.attr("id", (d) => d["Country"])
.attr(
"transform",
(d) =>
`translate(${xScale(d["start"])}, ${
yScale(d["mortality_mid"]) - barsHeight / 2
})`
);

groups
.append("rect")
.attr("height", 2)
.attr("width", (d) => xScale(d.end) - xScale(d.start))
.attr("fill", (d) => colorScale[d.continent]);

groups
.append("line")
.attr("x1", 0)
.attr("x2", 0)
.attr("y1", barsHeight + handleSize)
.attr("y2", -handleSize)
.attr("stroke", (d) => colorScale[d.continent]);

groups
.append("line")
.attr("x1", (d) => xScale(d.end) - xScale(d.start))
.attr("x2", (d) => xScale(d.end) - xScale(d.start))
.attr("y1", barsHeight + handleSize)
.attr("y2", -handleSize)
.attr("stroke", (d) => colorScale[d.continent]);

let texts = svg
.append("g")
.attr("id", "viz")
.attr("transform", `translate(${margin.left}, ${margin.top})`)
.selectAll("text")
.data(faminesOwd)
.join("text")
.attr("x", (d) => (xScale(d.end) + xScale(d.start)) / 2)
.attr("y", (d) => yScale(d["mortality_mid"]) - barsHeight / 2 - textPadding)
.text((d) => d.country)
.attr("font-family", "sans-serif")
.attr("text-anchor", "middle")
.attr("font-size", (d) => textScale(d["mortality_mid"]));

const gx = svg
.append("g")
.attr("transform", `translate(${margin.left},${height - margin.bottom})`)
.call(d3.axisBottom(xScale));

gx.selectAll(".tick text").attr("font-size", "14");

const gy = svg
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`)
.call(d3.axisLeft(yScale));

gy.selectAll(".tick text").attr("font-size", "14");

return svg.node();
}
Insert cell
colorScale = ({
asia: "#d14f5c",
africa: "#5774b7",
europe: "#fed337",
america: "#6dbd86"
})
Insert cell
data = FileAttachment("famines-owd@3.csv").csv()
Insert cell
faminesOwd = data.map((d) => ({
start: new Date(d.start_date),
end: new Date(d.end_date.split("-")[0], d.end_date.split("-")[1], 30),
mortality_mid: d["Excess Mortality midpoint"] * 1,
country: d["Country"],
continent: d["continent"]
}))
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