Published
Edited
Mar 6, 2021
2 stars
Insert cell
md`# Data-driven gradients`
Insert cell
{
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);

const defs = svg.append("defs");

const top = svg
.append("g")
.attr("transform", `translate(${margin}, ${margin})`);

const middle = svg
.append("g")
.attr(
"transform",
`translate(${margin}, ${margin + rectHeight + margin / 2})`
);

const bottom = svg
.append("g")
.attr("transform", `translate(${margin}, ${2 * margin + 2 * rectHeight})`);

top
.selectAll("rect")
.data(data)
.join("rect")
.attr("x", (_, i) => i * rectWidth)
.attr("width", rectWidth)
.attr("height", rectHeight)
.attr("fill", d => color(d / max))
.attr("stroke", "#000000")
.attr("stroke-width", 0.2);

const gradient = defs
.append('linearGradient')
.attr('id', 'gradient')
.attr('x1', 0)
.attr('x2', 1)
.attr('y1', 0)
.attr('y2', 0);

const fraction = 100 / data.length;

gradient
.selectAll("stop")
.data(data)
.join("stop")
.attr("offset", (_, i) => `${i * fraction + fraction / 2}%`)
.attr("stop-color", d => color(d / max));

middle
.append("rect")
.attr("width", rectWidth * data.length)
.attr("height", rectHeight)
.attr("fill", "url(#gradient)");

middle
.append("g")
.attr("class", "grid")
.selectAll("rect")
.data(data)
.join("rect")
.attr("x", (_, i) => i * rectWidth)
.attr("width", rectWidth)
.attr("height", rectHeight)
.attr("fill-opacity", 0)
.attr("stroke", "#000000")
.attr("stroke-width", 0.2);

bottom
.append("rect")
.attr("width", rectWidth * data.length)
.attr("height", rectHeight)
.attr("fill", "url(#gradient)");

return svg.node();
}
Insert cell
color = d3.interpolateGreens
Insert cell
max = d3.max(data)
Insert cell
data = [0, 0, 0, 2, 2, 4, 5, 6, 4, 2, 1, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0]
Insert cell
rectWidth = 30
Insert cell
rectHeight = 60
Insert cell
height = 3 * rectHeight + 3 * margin
Insert cell
margin = 25
Insert cell
d3 = require("d3@6")
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