Public
Edited
Jun 13, 2023
11 forks
Importers
3 stars
Insert cell
Insert cell
Insert cell
{
const bisector = d3.bisector((i) => stocks[i].Date);
const basis = (I, Y) => Y[I[bisector.center(I, date)]];
return Plot.plot({
style: "overflow: visible;",
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([date]),
Plot.lineY(stocks, Plot.normalizeY(basis, {
x: "Date",
y: "Close",
stroke: "Symbol"
})),
Plot.text(stocks, Plot.selectLast(Plot.normalizeY(basis, {
x: "Date",
y: "Close",
z: "Symbol",
text: "Symbol",
textAnchor: "start",
dx: 3
})))
]
});
}
Insert cell
Insert cell
stocks = (await Promise.all([
FileAttachment("aapl.csv").csv({typed: true}).then((values) => ["AAPL", values]),
FileAttachment("amzn.csv").csv({typed: true}).then((values) => ["AMZN", values]),
FileAttachment("goog.csv").csv({typed: true}).then((values) => ["GOOG", values]),
FileAttachment("ibm.csv").csv({typed: true}).then((values) => ["IBM", values]),
])).flatMap(([Symbol, values]) => values.map(d => ({Symbol, ...d})))
Insert cell
import {Scrubber} from "@mbostock/scrubber"
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