chart = () => {
const yearsToFilter = getYearList(data.filter(d => d.entity === entity && d.poverty_line === povLine ));
const plotData = data.filter(d => d.entity === entity
&& d.poverty_line === povLine
&& yearsToFilter.includes(d.year)
)
const minYear = d3.min(plotData, d => d.year);
const maxYear = d3.max(plotData, d => d.year);
const maxPov = d3.max(plotData, d => d.pov_rate);
const zoomGap = 0.02*maxPov;
const randomData = genRandArray((zoom ? maxPov: 1), zoomGap, minYear, maxYear, 0.01*maxPov, 0.005*maxPov)
const values = [];
for (let value = 0; value <= 100; value++) {
if (value % 20 === 0) {
values.push({"x": value/100, "y": minYear -5, "text": `${value}%`});
}
}
const xAxis = getXAxis(zoom ? maxPov: 1, minYear);
var entityLabel = ""
if (entity === "World") {
entityLabel = "THE WORLD"
}else {
entityLabel = entity.toUpperCase()
}
return Plot.plot({
height: 700,
width: 600,
marginLeft: 100,
marginRight: 50,
marginBottom: 50,
title: htl.html`<h2 id="plotTitle">POVERTY IN ${entityLabel}</h2>`,
caption: htl.html`<div id="plotCaption">Data: World Bank PIP<br>Inspired by W.E.B Du Bois<br>Chart by <strong>Luca Picci @lpicci96</strong></div>`,
style: {
fontSize: "13px",
fontFamily: "Public Sans, sans-serif",
color: "#958475",
},
marks: [
//plot the data
Plot.rectY([{}], {x1: 0,
x2: (maxPov === 0 ? 1: (zoom ? maxPov + zoomGap: 1)),
y1: minYear, y2: maxYear,
fill: "#111111"}),
Plot.areaX(plotData,
{y: "year",
x: "pov_rate", fill: "#c3213e",
tip: true,
title: d =>`In ${d.year}\napproximately ${(d.pov_rate*100).toFixed(1)}% of the population in
${d.entity == "World" ? "the ": ""}${d.entity} lived on less that $${d.poverty_line} per day.`
}),
Plot.line(plotData, {x: "pov_rate", y: "year", stroke: "#e2d0be", strokeWidth: 1}),
(maxPov === 0 ? [] : (zoom ? [Plot.areaX(randomData, {y: "y", x1: "x1", x2: "x2", fill: "#111111", stroke: "#111111"}),
Plot.line(randomData, {y: "y", x: "x1", stroke: "#111111", strokeWidth: 0.5})]
: [])),
// gridlines
Plot.ruleY(yearsToFilter,
{x1: 0,
x2: (maxPov === 0 ? 1: zoom ? maxPov + zoomGap: 1),
stroke: "#e2d0be"}),
// value labels on right
Plot.textY(plotData,
{x: (maxPov === 0 ? -0.15 : (zoom ? 0 - (maxPov + zoomGap)*0.15 : -0.15)),
y: "year",
text: d => d.year === minYear
|| d.year === maxYear ? `${(d.pov_rate*100).toFixed(1)}%`: `${(d.pov_rate*100).toFixed(1)}`
}),
// value label heading
Plot.text([{x: (maxPov === 0 ? -0.15 : (zoom ? 0 - (maxPov + zoomGap)*0.15 : -0.15)),
y: minYear - 4, text: "PEOPLE"}],
{x: "x",y: "y",text: "text"}),
Plot.text([{x: (maxPov === 0 ? -0.15 : (zoom ? 0 - (maxPov + zoomGap)*0.15 : -0.15)),
y: minYear - 3, text: "LIVING BELOW"}],
{x: "x",y: "y",text: "text"}),
Plot.text([{x: (maxPov === 0 ? -0.15 : (zoom ? 0 - (maxPov + zoomGap)*0.15 : -0.15)),
y: minYear - 2, text: `$${povLine} A DAY`}],
{x: "x",y: "y",text: "text"}),
// x axis
Plot.text(xAxis, {x: "x", y: minYear-1, text: "text"}),
Plot.ruleX(xAxis, {x: "x", y1: minYear, y2: minYear - 0.5, stroke: "#958475"})
],
y: {
reverse: true,
ticks: yearsToFilter,
tickFormat: ".0f",
tickPadding: 30,
tickSize: 0,
label: null
},
x: {
domain: [(maxPov === 0 ? -0.15 : (zoom ? 0 - (maxPov + zoomGap)*0.15 : -0.15)),
(maxPov === 0? 1 : zoom ? maxPov + zoomGap: 1)],
reverse: true,
axis: "top",
tickFormat: ".0%",
tickSize: 5,
label: null,
ticks: values
}
})
}