Public
Edited
Aug 26, 2023
Insert cell
Insert cell
chart = {
const context = DOM.context2d(width, height);
const canvas = context.canvas;

// An assortment of randomly-positioned colorful circles.

// Whenever the circles move, redraw the canvas.
function render() {
context.clearRect(0, 0, width, height);
circles.forEach((d) => {
context.beginPath();
context.moveTo(xScale(d.xValue) + radius, yScale(d.yValue));
context.arc(xScale(d.xValue), yScale(d.yValue), radius, 0, 2 * Math.PI);
context.fillStyle = d.color;
context.fill();
if (d.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.
let quad = d3
.quadtree()
.x((d) => d.xValues)
.y((d) => d.yValues)
.addAll(circles);

function dragsubject(event) {
let subject = null;
let distance = maxDistance;

// Use quadtree's find method to efficiently locate the closest circle.
subject = quad.find(event.x, event.y, maxDistance);

return subject;
}

// When starting a drag gesture, move the subject to the top and mark it as active.
function dragstarted({ subject }) {
console.log(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
Insert cell
Insert cell
Insert cell
maxDistance = Infinity // Limit the search distance, if desired.
Insert cell
height = 600
Insert cell
radius = 32
Insert cell
d3 = require("d3-selection@2", "d3-scale-chromatic@2", "d3-drag@2", "d3-array@2","d3-quadtree@3","d3-scale")
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