Public
Edited
Mar 31, 2023
Insert cell
Insert cell
data = ({
categories: [
{
label: "Cat A",
values: [
{ value: 2 },
{ value: 2 },
{ value: 4 },
{ value: 8 },
{ value: 15 },
{ value: 5 },
{ value: 3 }
]
},
{
label: "Cat B",
values: [
{ value: 18 },
{ value: 6 },
{ value: 2 },
{ value: 1 },
{ value: 11 },
{ value: 20 },
{ value: 6 }
]
}
]
})
Insert cell
viewof plot = {
const outerPadding = 20;

const categoryHeight = 400;
const categoryWidth = 200;
const valueSize = 30;

const totalHeight =
categoryHeight * data.categories.length + outerPadding * 2;
const totalWidth = categoryWidth + outerPadding;

let svg = d3
.create("svg")
.attr("width", totalWidth)
.attr("height", totalHeight);

// Create boxes for each category
let categoryBoxes = svg
.selectAll("g")
.data(data.categories)
.enter()
.append("g")
.attr(
"transform",
(d, i) => `translate(0, ${i * categoryHeight + outerPadding})`
);

// Add background box
categoryBoxes
.append("rect")
.attr("x", outerPadding)
.attr("y", 0)
.attr("width", categoryWidth)
.attr("height", categoryHeight)
.attr("fill", "white")
.attr("stroke", "black");

// Create colour scale for values
let valueScale = d3
.scaleLinear()
.domain([
0,
d3.max(data.categories, (d) => d3.max(d.values, (d) => d.value))
])
.range(["white", "red"]);

// Create a box for each value in a 3x3 grid
let valueBoxes = categoryBoxes
.selectAll("rect")
.data((d) => d.values)
.enter()
.append("rect")
.attr("x", (d, i) => outerPadding + (i % 3) * valueSize)
.attr("y", (d, i) => Math.floor(i / 3) * valueSize)
.attr("width", valueSize)
.attr("height", valueSize)
.attr("fill", (d) => valueScale(d.value))
.attr("stroke", "red")
.attr("class", (d, i) => `value-${i}`);

return svg.node();
}
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