Public
Edited
May 19, 2021
Insert cell
md`# Wave Height January 2021
Wave data from coastalmonitoring.org`
Insert cell
chart = {
const svg = d3
.create("svg")
.attr("viewBox", [-width / 2, -height / 2, width, height])
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round");

svg
.append("path")
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("d", line.radius(d => y(+d.hs))(data));

svg.append("g").call(yAxis);

svg.append("g").call(xAxis);

return svg.node();
}
Insert cell
margin = 10
Insert cell
outerRadius = width / 2 - margin
Insert cell
innerRadius = width / 5
Insert cell
line = d3.lineRadial()
.curve(d3.curveLinearClosed)
.angle(d => x(d.timestamp))
Insert cell
y = d3
.scaleLinear()
.domain([0,5])
.range([innerRadius, outerRadius])
Insert cell
x = d3
.scaleUtc()
.domain([Date.UTC(2021, 0, 1), Date.UTC(2021, 1, 1) - 1])
.range([0, 2 * Math.PI])
Insert cell
yAxis = g =>
g
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.call(g =>
g
.selectAll("g")
.data(y.nice().ticks(5).reverse())
.join("g")
.attr("fill", "none")
.call(g =>
g
.append("circle")
.attr("stroke", "#000")
.attr("stroke-opacity", 0.2)
.attr("r", y)
)
.call(g =>
g
.append("text")
.attr("y", d => -y(d))
.attr("dy", "0.35em")
.attr("stroke", "#fff")
.attr("stroke-width", 5)
.text((x, i) => `${x.toFixed(0)}${i ? "" : "m"}`)
.clone(true)
.attr("y", d => y(d))
.selectAll(function() {
return [this, this.previousSibling];
})
.clone(true)
.attr("fill", "currentColor")
.attr("stroke", "none")
)
)
Insert cell
xAxis = g =>
g
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.call(g =>
g
.selectAll("g")
.data(x.ticks(31))
.join("g")
.each((d, i) => (d.id = DOM.uid("day")))
.call(g =>
g
.append("path")
.attr("stroke", "#000")
.attr("stroke-opacity", 0.2)
.attr(
"d",
d => `
M${d3.pointRadial(x(d), innerRadius)}
L${d3.pointRadial(x(d), outerRadius)}
`
)
)
.call(g =>
g
.append("path")
.attr("id", d => d.id.id)
.datum(d => [d, d3.timeDay.offset(d, 1)])
.attr("fill", "none")
.attr(
"d",
([a, b]) => `
M${d3.pointRadial(x(a), innerRadius-10)}
A${innerRadius-10},${innerRadius-10} 0,0,1 ${d3.pointRadial(
x(b),
innerRadius-10
)}
`
)
)
.call(g =>
g
.append("text")
.append("textPath")
.attr("startOffset", 6)
.attr("xlink:href", d => d.id.href)
.text(d3.utcFormat("%e"))
)
)
Insert cell
minmax = d3.extent(data, d=> +d.hs)
Insert cell
height = width
Insert cell
data = d3.tsvParse(await FileAttachment("Prp_waves202101@1.txt").text(), d => ({
...d,
timestamp: Date.parse(d.timestamp)
}))
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