Public
Edited
Jul 2, 2024
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
{
const svg = d3.create("svg").attr("width", width).attr("height", height);

// Axis
svg
.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.attr("class", "x-axis")
.call(xAxis);

svg
.append("g")
.attr("class", "y-axis")
.attr("transform", `translate(${margin.left}, 0)`)
.call(yAxis);

// Line
svg
.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "#8868cb")
.attr("stroke-width", 1.8)
.attr("d", line);

const lastValue = data[data.length - 1];
svg
.append("circle")
.attr("cx", width - margin.right)
.attr("cy", yScale(lastValue.Close))
.attr("r", 5.8)
.attr("fill", "#8868cb")
.attr("stroke", "#fff")
.attr("stroke-width", 1);

// Update div text
d3.select("#price").text(`${format(lastValue.Close)}`);
d3.select("#date").text(
`${d3.timeFormat("%b %d, %Y")(lastValue.date_parsed)}`
);

return svg.node();
}
Insert cell
// thousand + no decimal point
format = d3.format(",.2f") //(".1f")
Insert cell
Insert cell
line = d3
.line()
.curve(d3.curveCardinal)
.x((d) => xScale(d.date_parsed))
.y((d) => yScale(d.Close))
Insert cell
Insert cell
yAxis = d3
.axisLeft(yScale)
.ticks(5)
.tickSize(-width + margin.right + margin.left)
Insert cell
xAxis = d3
.axisBottom(xScale)
.tickFormat((d) => formatXAxis(d))
.ticks(5)
.tickSizeOuter(0)
Insert cell
formatXAxis = d3.timeFormat("%b %Y")
Insert cell
Insert cell
yScale = d3
.scaleLinear()
.domain(d3.extent(data, (d) => d.Close))
.range([height - margin.bottom, margin.top])
Insert cell
xScale = d3
.scaleUtc()
.domain(d3.extent(data, (d) => d.date_parsed))
.range([margin.left, width - margin.right])
Insert cell
margin = ({ top: 2, right: 30, bottom: 40, left: 60 })
Insert cell
Insert cell
Insert cell
data = raw_data.map((d) => {
d.Close = +d.Close;
d.date_parsed = parseTime(d.Date);
return d;
})
Insert cell
parseTime = d3.timeParse('%Y-%m-%d')
Insert cell
raw_data = d3.csvParse(await FileAttachment("BTC-USD.csv").text())
Insert cell
Insert cell
html`
<style>
.tick {
font-size: 14px;
color: #777;
}

.y-axis .domain {
display: none;
}

.y-axis .tick line {
stroke: #dfdfdf;
}

#price {
font-family: arial;
font-size: 38px;
font-weight: 600;
text-anchor: end;
letter-spacing: -.3px;
}

.unit {
font-family: arial;
font-size: 16px;
font-weight: 600;
text-anchor: end;
color: #999;
margin-left: 3px;
}

#date {
font-family: arial;
color: #999;
margin-top: 0px;
font-size: 16px;
padding: 3px 8px;
}

</style>
`
Insert cell
d3.range(10)
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