Published
Edited
Sep 6, 2019
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
vl.markBar()
.data(data)
.transform(
// this could have been easily done in the `encode` but this approach is a bit drier
vl.groupby("state").aggregate(vl.sum("population").as("population")),
)
.encode(
vl.x().fieldN("state")
// handling the 3 ordering options. true seems to fall back to the default
.sort(orderVega === "alphabetical" ? true : vl.fieldQ("population").order(`${orderVega}`)),
vl.y().fieldQ("population"),
)
.width(900)
.render()
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
// a la Mike Bostock's https://observablehq.com/@d3/sortable-bar-chart
const height = 400
const margin = {top: 40, bottom: 100, left: 60, right: 40}
const svg = d3.create("svg")
.attr("viewBox", [0,0,width,height])
const popData = d3.nest()
.key(k => k.state)
.rollup(v => d3.sum(v, d=> d.population))
.entries(data)
const x = d3.scaleBand().domain(popData.map(d => d.key)).range([margin.left, width - margin.right]).padding(0.15)
const y = d3.scaleLinear().domain([0, d3.max(popData, d => d.value)]).range([height - margin.bottom, margin.top]).nice()
const xAxis = g => g.attr("transform", `translate(0, ${height - margin.bottom})`)
.call(d3.axisBottom(x))
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-0.6em")
.attr("transform", "rotate(-90)")
const yAxis = g => g.attr("transform", `translate(${margin.left}, 0)`)
.call(d3.axisLeft(y))
const bars = svg.append("g")
.attr("fill", "steelblue")
.selectAll("rect")
.data(popData)
.join("rect")
.attr("x", d => x(d.key))
.attr("y", d => y(d.value))
.attr("height", d => y(0) - y(d.value))
.attr("width", x.bandwidth())
const gx = svg.append("g").call(xAxis)
const gy = svg.append("g").call(yAxis)
return Object.assign(svg.node(), {
update(order) {
const t = svg.transition()
.duration(750);
x.domain(popData.sort(order).map(d => d.key))
bars.data(popData, d => d.key)
.order()
.transition(t)
.delay((d, i) => i * 20)
.attr("x", d => x(d.key))
gx.transition(t)
.call(xAxis)
.selectAll(".tick")
.delay((d, i) => i * 20)
}
})
// return popData
}
Insert cell
chart.update(orderD3) // calls the update function whenever orderD3 changes
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