Published
Edited
Oct 13, 2021
Fork of Simple D3
1 star
Insert cell
Insert cell
// Make up some random data
data = d3.range(10).map(d => ({ index: d, value: Math.random() * 25}));
Insert cell
Insert cell
viewof currentIndex = Scrubber(
d3.range(0, data.length, 1),
{ autoplay: false, delay: 1000, loop: false }
)
Insert cell
// wire things up so when the Scrubber changes we call the `setIndex` function inside the `chartAnimate` variable below
chartAnimate.setIndex(currentIndex)
Insert cell
chartAnimate = {
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)

const offset = 50;
svg
.selectAll("circle")
.data([data[0]], d => 'current')
.join("circle")
.attr("cx", width / 2) // just put it in the middle of the area
.attr("cy", height / 2)
.attr("r", d => d.value)
.attr("fill", d => colorScale(d.value))

const setIndex = (newIndex) => {
svg
.selectAll("circle")
.data([data[newIndex]], d => 'current')
.transition()
.duration(1000)
.attr("r", d => d.value)
.attr("fill", d => colorScale(d.value))
}
// Extend SVG node, export setYear as a property thereof
return Object.assign(svg.node(), { setIndex });
}
Insert cell
Insert cell
// and lets use some nice colors
colorScale = d3.scaleSequential(d3.interpolateBlues)
.domain(d3.extent(data.map(d => d.value)))
Insert cell
{
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)

const offset = 50;
svg
.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", d => 100 + (d.index * 50)) // this should really be an axis that tells us where to position each circle
.attr("cy", height / 2)
.attr("r", d => d.value)
.attr("fill", d => colorScale(d.value))
return svg.node()
}
Insert cell
Insert cell
// use the `pack` 2d layout algorithm to place circles near each other: https://github.com/d3/d3-hierarchy#pack
packAlgorithm = data => d3.pack() // create a 2d packing layout algorithm
.size([width - 2, height - 2]) // that has this overall size
.padding(3) // and leaves this much space between each node
// now call the algorithm
(d3.hierarchy({children: data}) // now tell it to compute positions with a flat tree (ie. no hierarchy)
.sum(d => d.value)) // and call sum before we use it (because that's just how it works)
Insert cell
// adapted from https://observablehq.com/@d3/bubble-chart
chart = {
const root = packAlgorithm(data); // run the circle packing algorithm to figure out where each circle should go

// set up an SVG container to hold our packed circles
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("font-size", 10) // this font will apply to any text nodes inside this SVG container
.attr("font-family", "sans-serif")
.attr("text-anchor", "middle");

// set up a container for each circle and its label
const leaf = svg.selectAll("g") // a <g> is the generic container to hold stuff in SVG (like <div> in HTML)
.data(root.leaves()) // the data here is all the "leaves" the algorithm has computed for us (1 per data point)
.join("g")
.attr("transform", d => `translate(${d.x + 1},${d.y + 1})`); // put the g container where the algorithm computed (x/y)

// now that it is in the right place, add a circle
leaf.append("circle")
.attr("id", d => (d.leafUid = DOM.uid("leaf")).id) // give it a unique id for good form
.attr("r", d => d.r) // this is the original value WE told it to use
.attr("stroke", d => 'lightgrey') // add a border for better visibility
.attr("fill", d => colorScale(d.value)); // just a normal fill using the colorScale we set up previously

// and now add a label on top of the circle (in the same <g>)
leaf.append("text")
.attr("x", 0) // this x/y position is local to the <circle> element (ie. `leaf`), not to the whole <svg> area
.attr("y", 4)
.text(d => Math.round(d.value));
return svg.node();
}
Insert cell
format = d3.format(",d")
Insert cell
height = 200
Insert cell
import {Scrubber} from "@mbostock/scrubber"
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