{
const bisector = d3.bisector((i) => data[i].Date);
const basis = (I, Y) => Y[I[bisector.center(I, dateslider)]];
const formatDate = (date) => {
const currentMonth = d3.timeFormat("%b %Y")(date);
const previousMonth = d3.timeFormat("%b %Y")(getPreviousMonth(date));
return `${previousMonth} - ${currentMonth}`;
};
let relevantGoldPriceData = data.filter(d => d.disaggregation === "GOLD_PRICE" && +d.Date === +dateslider);
let relevantOilPriceData = data.filter(d => d.disaggregation === "OIL_PRICE" && +d.Date === +dateslider);
let relevantCocoaPriceData = data.filter(d => d.disaggregation === "COCOA_PRICE" && +d.Date === +dateslider);
return Plot.plot({
marginTop: 20,
style: "overflow: visible; fontFamily: 'Lato'",
y: {
type: "log",
grid: true,
label: "Change in price (%)",
tickFormat: ((f) => (x) => f((x - 1) * 100))(d3.format("+d"))
},
marks: [
Plot.ruleY([1]),
Plot.ruleX([dateslider]),
Plot.lineY(data, Plot.normalizeY(basis, {
x: "Date",
y: "prices",
stroke: "disaggregation"
})),
Plot.text(data, Plot.selectLast(Plot.normalizeY(basis, {
x: "Date",
y: "prices",
z: "disaggregation",
text: (d, i) => {
const change = getPercentageChangeForDate(data, d.disaggregation, dateslider);
const arrow = change > 0 ? "↑" : (change < 0 ? "↓" : "");
return `(${d.disaggregation}) ${formatDate(dateslider)} ${arrow} (${change}%)`;
},
fill: d => getPercentageChangeForDate(data, d.disaggregation, dateslider) > 0 ? "green" : "red",
textAnchor: "start",
dx: 3,
}))),
Plot.text(relevantGoldPriceData, {
px: d3.max(data, d => d.Date),
py: 6,
dy: -30,
textAnchor: "end",
frameAnchor: "top-right",
fontVariant: "tabular-nums",
text: (d) => {
const change = d.percentageChange;
const arrow = change > 0 ? "↑" : (change < 0 ? "↓" : "");
return [
`${d.disaggregation} in ${formatDate(dateslider)}`,
` ${arrow} (${change}%)`,
`(price: ${d.prices.toFixed(2)} per ounce in US$) `
].join(" ");
},
fill: d => d.percentageChange > 0 ? "green" : "red"
}),
Plot.text(relevantOilPriceData, {
px: d3.max(data, d => d.Date),
py: 6,
dy: -20,
textAnchor: "end",
frameAnchor: "top-right",
fontVariant: "tabular-nums",
text: (d) => {
const change = d.percentageChange;
const arrow = change > 0 ? "↑" : (change < 0 ? "↓" : "");
return [
`${d.disaggregation} in ${formatDate(dateslider)}`,
` ${arrow} (${change}%)`,
`(price: ${d.prices.toFixed(2)} per barrel in US$) `
].join(" ");
},
fill: d => d.percentageChange > 0 ? "green" : "red"
}),
Plot.text(relevantCocoaPriceData, {
px: d3.max(data, d => d.Date),
py: 6,
dy: -10,
textAnchor: "end",
frameAnchor: "top-right",
fontVariant: "tabular-nums",
text: (d) => {
const change = d.percentageChange;
const arrow = change > 0 ? "↑" : (change < 0 ? "↓" : "");
return [
`${d.disaggregation} in ${formatDate(dateslider)}`,
` ${arrow} (${change}%)`,
`(price: ${d.prices.toFixed(2)} per tonne in US$) `
].join(" ");
},
fill: d => d.percentageChange > 0 ? "green" : "red"
})
]
});
}