Published
Edited
Mar 11, 2021
1 fork
Importers
1 star
Insert cell
Insert cell
chart = {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])
.attr("stroke-width", 2)
.call(drag)

return svg.node();
}
Insert cell
drag = {
function render(event, d) {
let sel = d3.select(this).selectAll("circle")
.data(pointers(event, this).filter(d => d.type !== "mouseup"), d => d.id);
sel.exit().remove();
sel.enter().append("circle")
.attr("r", radius)
.attr("pointer-events", "none")
.attr("fill", () => `hsl(${Math.random() * 360}, 50%, 50%)`)
.merge(sel)
.attr("cx", d => d.x)
.attr("cy", d => d.y);
}

return d3.drag()
.on("start drag end", render);
}
Insert cell
radius = 60
Insert cell
height = 600
Insert cell
d3 = require("d3@6")
Insert cell
Insert cell
// https://github.com/d3/d3-selection/blob/master/src/sourceEvent.js
function sourceEvent(event) {
let sourceEvent;
while (sourceEvent = event.sourceEvent) event = sourceEvent;
return event;
}
Insert cell
// https://github.com/d3/d3-selection/blob/master/src/pointer.js
function pointer(event, node) {
event = sourceEvent(event);
const id = event.identifier || "pointer";
const type = event.type;
if (node === undefined) node = event.currentTarget;
if (node) {
var svg = node.ownerSVGElement || node;
if (svg.createSVGPoint) {
var point = svg.createSVGPoint();
point.x = event.clientX, point.y = event.clientY;
point = point.matrixTransform(node.getScreenCTM().inverse());
return {
x: point.x,
y: point.y,
id,
type
};
}
if (node.getBoundingClientRect) {
var rect = node.getBoundingClientRect();
return {
x: event.clientX - rect.left - node.clientLeft,
y: event.clientY - rect.top - node.clientTop,
id,
type
};
}
}
return {x: event.pageX, y: event.pageY, id, type};
}
Insert cell
// https://github.com/d3/d3-selection/blob/master/src/pointers.js
function pointers(events, node) {
if (events.target) { // i.e., instanceof Event, not TouchList or iterable
events = sourceEvent(events);
if (node === undefined) node = events.currentTarget;
events = events.touches || [events];
}
return Array.from(events, event => pointer(event, 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