Public
Edited
Nov 1, 2022
Fork of Simple D3
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
textFormat = tonnes => {
const kilogramsFormat = `${tonnes*1000}kg`
const tonnesFormat = `${d3.format(".2s")(tonnes)}t`
return tonnes < 1 ? kilogramsFormat : tonnesFormat
}
Insert cell
// Check what the result looks like
impacts.map(d=>textFormat(d['co2e (tonnes)']))
Insert cell
diagonalLength = 50
Insert cell
calloutHeight = 25
Insert cell
textDistanceToCallout = 7
Insert cell
x = d3.scaleLinear()
.domain([0, 100])
.range([0, width])
Insert cell
Insert cell
// From Carbon Context by Duncan Geere: google sheet converted to json
// https://docs.google.com/spreadsheets/d/1kPuNFFncPWrx2ZZqCT7cT4j0pwmL9O29MLLzCAyo3sg/edit#gid=0
impacts = FileAttachment("impacts.json").json()
Insert cell
Insert cell
height = 800
Insert cell
// How many orders of magnitude should each subchart cover?
// oomPerSubchart = 3 // we moved this to a view up above
Insert cell
getOrderOfMagnitude = x => Math.floor(Math.log10(x))
Insert cell
import {wrap_text} from "@ben-tanen/svg-text-and-tspan-word-wrapping@224"
Insert cell
impactsTons = impacts.map(d=>d['co2e (tonnes)']);
Insert cell
impactsOom = impactsTons.map(getOrderOfMagnitude)
Insert cell
dataOomRange = {
const extent = d3.extent(impactsOom)
return {
min: extent[0],
max: extent[1]
}
}
Insert cell
Insert cell
d3.extent(Object.keys(oomBins).map(d=>+d))
Insert cell
subchartCount = Math.ceil((maxOom - minOom) / oomPerSubchart)
Insert cell
subchartIndices = [...Array(subchartCount).keys()]
Insert cell
xDomainEdges = {
// [0,1,2,3, ... , subchartCount]
const subchartIndicesWithRightEdge = [...subchartIndices, subchartCount]

// [-2,0,2,4, ...] (orders of magnitude)
const subchartEdgeOoms = subchartIndicesWithRightEdge.map(i => (i * oomPerSubchart) + minOom)

// [1e-2,1e0,1e2,1e4, ...]
const subchartEdges = subchartEdgeOoms.map(oom => Math.pow(10, oom))

return subchartEdges
}
Insert cell
xDomains = xDomainEdges
.slice(0,-1) // get left edges only
.map(
(leftEdge, index) => [
leftEdge,
xDomainEdges[index + 1]
]
)
Insert cell
getSubchartIndex = x => xDomains.findIndex(([minRange, maxRange]) => (maxRange >= x))
Insert cell
// Quick test - these should all be reasonable indices
[
getSubchartIndex(0),
getSubchartIndex(1000),
getSubchartIndex(Math.min(...impactsTons)),
getSubchartIndex(Math.max(...impactsTons))
]
Insert cell
xRange = [margin.left, width - margin.right]
Insert cell
subchartUpperEdges = subchartIndices.map(i => subchartHeight * i + margin.top)
Insert cell
subchartHeight = (height - margin.top - margin.bottom) / subchartCount
Insert cell
margin = ({top: 20, right: 200, bottom: 20, left: 100})
Insert cell
markerCircleRadius = 5
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