Public
Edited
Oct 25, 2023
2 forks
5 stars
Insert cell
Insert cell
chart = {
const context = DOM.context2d(width, height);
const canvas = context.canvas;

// An assortment of randomly-positioned colorful circles.
const circles = d3.range(20).map(i => ({
x: Math.random() * (width - radius * 2) + radius,
y: Math.random() * (height - radius * 2) + radius,
color: d3.schemeCategory10[i % 10]
}));

// Whenever the circles move, redraw the canvas.
function render() {
context.clearRect(0, 0, width, height);
for (const {x, y, color, active} of circles) {
context.beginPath();
context.moveTo(x + radius, y);
context.arc(x, y, radius, 0, 2 * Math.PI);
context.fillStyle = color;
context.fill();
if (active) {
context.lineWidth = 2;
context.stroke();
}
}
}

// Bind the drag behavior for interaction.
d3.select(context.canvas).call(drag(circles)
.on("start.render drag.render end.render", render));

// Render the initial canvas.
render();

return canvas;
}
Insert cell
drag = circles => {

// Choose the circle that is closest to the pointer for dragging.
function dragsubject(event) {
let subject = null;
let distance = maxDistance;
for (const c of circles) {
let d = Math.hypot(event.x - c.x, event.y - c.y);
if (d < distance) {
distance = d;
subject = c;
}
}
return subject;
}

// When starting a drag gesture, move the subject to the top and mark it as active.
function dragstarted({subject}) {
circles.splice(circles.indexOf(subject), 1);
circles.push(subject);
subject.active = true;
}

// When dragging, update the subject’s position.
function dragged(event) {
event.subject.x = event.x;
event.subject.y = event.y;
}

// When ending a drag gesture, mark the subject as inactive again.
function dragended({subject}) {
subject.active = false;
}

return d3.drag()
.subject(dragsubject)
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
}
Insert cell
maxDistance = Infinity // Limit the search distance, if desired.
Insert cell
height = 600
Insert cell
radius = 32
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