Public
Edited
Mar 12, 2024
11 forks
37 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
innerRadius = 0.35 * width/2
Insert cell
outerRadius = 0.9 * width/2
Insert cell
Insert cell
colorDomain = {
const extent = d3.extent( data, d => d.avg ),
interpolated = d3.interpolate( ...extent )
return d3.quantize( interpolated, 7 )
}
Insert cell
Insert cell
color = d3.scaleLinear(
colorDomain,
d3.quantize(d3.interpolateSpectral, 7).reverse()
)
Insert cell
Insert cell
xScale = d3.scaleBand(
data.map(d => d.date),
[ 0, 2 * Math.PI ]
)
Insert cell
yDomain = {
const min = d3.min(data, d => d.min),
max = d3.max(data, d => d.max)
return [ min, max ]
}
Insert cell
yScale = d3.scaleLinear()
.domain( yDomain )
.range([ innerRadius, outerRadius ])
Insert cell
Insert cell
arc = d3.arc()
.innerRadius(d => yScale(d.min))
.outerRadius(d => yScale(d.max))
.startAngle(d => xScale(d.date))
.endAngle(d => xScale(d.date) + xScale.bandwidth())
.padAngle(0.01)
.padRadius(innerRadius)
Insert cell
Insert cell
chart = {
const svg = d3.create('svg')
.attr('width', width)
.attr('height', height)
const container = svg.append('g')
.attr('class', 'container')
.attr('transform', `translate(${ width/2 },${ height/2 })`)
.style('font-size', 10)
.style('font-family', 'sans-serif')
container
.selectAll('path')
.data( data )
.join('path')
.style('fill', d => color(d.avg))
.style('stroke', d => color(d.avg))
.attr('d', arc)

container.append('g')
.call(xAxis)

container.append('g')
.call(yAxis)
return svg.node()
}
Insert cell
Insert cell
Insert cell
Insert cell
xAxis = g => g
.attr('text-anchor', 'middle')
.call(g => g.selectAll('g')
.data([ 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', 'January', 'February', 'March' ])
.join('g')
.attr('transform', (d,i,arr) => `
rotate(${ i * 360/arr.length })
translate(${innerRadius},0)
`)
.call(g => g.append('line')
.attr('x1', -5)
.attr('x2', outerRadius - innerRadius + 10)
.style('stroke', '#aaa'))
.call(g => g.append('text')
.attr('transform', (d,i,arr) => ((i * 360/arr.length) % 360 > 180
? "rotate(90)translate(0,16)"
: "rotate(-90)translate(0,-9)"))
.style('font-family', 'sans-serif')
.style('font-size', 10)
.text(d => d)))
Insert cell
yAxis = g => g
.attr('text-anchor', 'middle')
.call(g => g.append('text')
.attr('text-anchor', 'end')
.attr('x', '-0.5em')
.attr('y', d => -yScale(yScale.ticks(5).pop()) - 10)
.attr('dy', '-1em')
.style('fill', '#1a1a1a')
.text('Temperature (°C)')
)
.call(g => g.selectAll('g')
.data(yScale.ticks(5))
.join('g')
.attr('fill', 'none')
.call(g => g.append('circle')
.style('stroke', '#aaa')
.style('stroke-opacity', 0.5)
.attr('r', yScale))
.call(g => g.append('text')
.attr('y', d => -yScale(d))
.attr('dy', '0.35em')
.style('stroke', '#fff')
.style('stroke-width', 5)
.style("fill",'#1a1a1a')
.text(yScale.tickFormat(6, 's'))
.clone(true)
.style('stroke', 'none')))
Insert cell
Insert cell
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