Published
Edited
Nov 30, 2020
Insert cell
Insert cell
Insert cell
{
const m = 40
const svg = d3.select(DOM.svg(width + m, height + m))
svg.append('g')
.attr('transform', `translate(${m}, ${height})`)
.call(xAxis);
const locations = svg.selectAll('g.locations')
.data(data)
.enter().append('g')
.attr('transform', `translate(${m}, 0)`)
const rects = locations.selectAll('rect')
.data(dataPrep) // map each location's object into an array
.enter().append('rect')
rects
.attr('x', (d, i) => scale(d.value - d3.mean(data, e => e[d.feature])))
.attr('y', d => d.featureIndex * 30)
.attr('fill', d => d.location === selectedLocation.toString() ? "#2f55ad" : "#aaa")
.attr('fill-opacity', d => d.location === selectedLocation.toString() ? 1 : 0.6)
.attr('height', s)
.attr('width', s)
.attr('transform', `translate(${-s/2}, ${-s/2})`)
.attr("rx", s/2)
locations.filter(d => d.location === selectedLocation.toString())
.raise() // bring selected locaiton to front
.selectAll('line').data(dataPrep) // map each location's object into an array
.enter().append('line')
.attr('stroke', "#2f55ad")
.attr('stroke-width', 2)
.attr('x1', d => scale(d.value - d3.mean(data, e => e[d.feature])))
.attr('x2', scale(0))
.attr('y1', d => d.featureIndex * 30)
.attr('y2', d => d.featureIndex * 30)
return svg.node()
}
Insert cell
Insert cell
Insert cell
Insert cell
function dataPrep(d, locationIndex) {
const values = Object.entries(d).map(([key, value], i) => {
return { location: d.location, value: value, feature: key, locationIndex: locationIndex, featureIndex: i, svg: svg }
}).filter((_, i) => i > 0) // filter out non-features
return values
}
Insert cell
Insert cell
Insert cell
Insert cell
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