Public
Edited
Sep 28, 2023
Insert cell
Insert cell
Insert cell
Insert cell
alphabet = [..."ABCDEFGHIJKLMNOPQRSTUVWXYZ"]
Insert cell
{
let data = d3.shuffle(alphabet.slice())
.slice(Math.floor(Math.random() * 10) + 5)
.sort(d3.ascending);
// const width = 500;
// const height = 50;
// const margin = {top: 10, bottom: 10, left: 50, right: 10}
// const svg = d3.create("svg")
// .attr("width", width + margin.left + margin.right)
// .attr("height", height + margin.top + margin.bottom);

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

// const yScale = d3.scalePoint()
// .domain(['enter', 'update', 'exit'])
// .range([0, height]);

// const xScale = d3.scalePoint()
// .domain(alphabet)
// .range([10, width])

// g.append("g")
// .call(d3.axisLeft(yScale))

while (true) {

// yield svg.node()
yield data

// Selection
// const textSelection = g.selectAll(".letter")
// .data(data, d => d);

// Enter
// textSelection.enter().append("text")
// .attr("class", "letter")
// .attr("y", yScale('enter') + 5)
// .attr("x", d => xScale(d))
// .style("font", "14px sans-serif")
// .style("fill", "green")
// .text(d => d);

// Update
// textSelection
// .transition()
// .duration(1000)
// .attr("y", yScale('update') + 5)
// .style("fill", "#000");

// Exit
// textSelection.exit()
// .transition()
// .duration(1000)
// .style("fill", "red")
// .attr("y", yScale('exit') + 5)
// .transition()
// .duration(1000)
// .style("opacity", 0)
// .remove();
await Promises.delay(3000);
data = d3.shuffle(alphabet.slice())
.slice(Math.floor(Math.random() * 10) + 5)
.sort(d3.ascending);

}
}
Insert cell
Insert cell
Insert cell
{
let data = d3.shuffle(alphabet.slice())
.slice(Math.floor(Math.random() * 10) + 5)
.sort(d3.ascending);
const width = 500;
const height = 50;
const margin = {top: 10, bottom: 10, left: 50, right: 10}
const svg = d3.create("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);

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

const yScale = d3.scalePoint()
.domain(['enter', 'update', 'exit'])
.range([0, height]);

const xScale = d3.scalePoint()
.domain(alphabet)
.range([10, width])

g.append("g")
.call(d3.axisLeft(yScale))

while (true) {

yield svg.node()
// yield data
// g.selectAll(".letter")
// .data(data, d => d)
// .join(
// enter => enter.append("text")
// .attr("fill", "green")
// .attr("class", "letter")
// .attr("x", d => xScale(d))
// .attr("y", yScale('enter') + 5)
// .style("font", "14px sans-serif")
// .text(d => d),
// update => update
// .attr("fill", "black")
// .call(update => update.transition()
// .attr("y", yScale('update') + 5)),
// exit => exit
// .attr("fill", "red")
// .call(exit => exit.transition()
// .attr("y", yScale('exit') + 5)
// .transition()
// .remove())
// ); // Anything we add after our join will apply to the enter + update elements that remain

// If we don't care about handling enter + update differently, and we just want to remove our exited elements, You can do it all this way.
// g.selectAll(".letter")
// .data(data, d => d)
// .join("text")
// .attr("class", "letter")
// .attr("y", yScale('enter') + 5)
// .attr("x", d => xScale(d))
// .style("font", "14px sans-serif")
// .text(d => d)

await Promises.delay(3000);
data = d3.shuffle(alphabet.slice())
.slice(Math.floor(Math.random() * 10) + 5)
.sort(d3.ascending);

}
}
Insert cell
Insert cell
Insert cell
{
const width = window.innerWidth;
const height = 200;

const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)

const x = d3.scalePoint()
.domain([0, 1, 2, 3, 4])
.range([0, width])
.padding(.5)

svg.selectAll("circle")
.data(d3.range(5).map(Object))
.join("circle")
.attr("cx", (_, i) => x(i))
.attr("cy", height / 2)
.attr("r", 25)

return svg.node()
}
Insert cell
Insert cell
Insert cell
{
const width = 600;
const height = 400;
const margin = { top: 20, bottom: 20, left: 50, right: 50 };

const div = htl.html`<div></div>`;

const categories = d3.groups(iris, d => d.species)

const buttons = d3.select(div)
.selectAll("button")
.data(categories)
.join("button");

buttons.text(d => d[0])
const svg = d3.select(div)
.append("div")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);

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

const x = d3
.scaleLinear()
.domain(d3.extent(iris, (d) => d["sepalLength"]))
.range([0, width]);

const y = d3
.scaleLinear()
.domain(d3.extent(iris, (d) => d["sepalWidth"]))
.range([height, 0]);

const color = d3.scaleOrdinal()
.domain(categories.map(d => d[0]))
.range(d3.schemeDark2)

g.append("g")
.call(d3.axisLeft(y));

g.append("g")
.attr("transform", `translate(0, ${height})`)
.call(d3.axisBottom(x))

const circles = g
.selectAll("circle")
.data(iris.filter(d => d.species == 'setosa'))
.join("circle")
.attr("r", 4)
.style("stroke", "#000")
.attr("cx", (d) => x(d.sepalLength))
.attr("cy", (d) => y(d.sepalWidth))
.style("fill", d => color(d.species));

buttons.on("click", (event, d) => {

})


return div
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
iris.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
{
const width = 500;
const height = 200;
const r = 50;

const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)

const circle = svg.append("circle")
.attr("r", r)
.attr("cx", r)
.attr("cy", height / 2)
.transition().duration(2000)
.attr("cx", width - r)
.transition()
.attr("cx", r)

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