Published
Edited
Nov 1, 2019
Insert cell
Insert cell
canvas = {
// const width = 400
const height = width
const context = DOM.context2d(width, width);
const nPts = 30
const scale = d3.scaleLinear()
.domain([0, nPts])
.range([0, width])
context.canvas.update = mouse => {
let {left: cx, top: cy} = context.canvas.getBoundingClientRect();
let {x: mx, y: my} = mouse;
mx -= cx;
my -= cy;
context.clearRect(0, 0, width, height);
context.beginPath()
const b1 = d3.range(nPts).map(pt => {
const x = scale(pt),
y = 0
context.moveTo(x, y);
context.arc(x, y, 4, 0, 2*Math.PI);

return {x,y}
})
const b2 = d3.range(nPts).map(pt => {
const x = scale(pt),
y = width
context.moveTo(x, y);
context.arc(x, y, 4, 0, 2*Math.PI);

return {x,y}
})
context.fillStyle = "black"
context.fill()
context.beginPath()
const l1 = d3.range(nPts).map(pt => {
const x = mx/nPts * pt
const y = my/nPts * pt
context.moveTo(x, y);
context.arc(x, y, 4, 0, 2*Math.PI);

return {x,y}
})
const l2 = d3.range(nPts).map(pt => {
const x = width - (mx/nPts * pt)
const y = width - (my/nPts * pt)
context.moveTo(x, y);
context.arc(x, y, 4, 0, 2*Math.PI);

return {x,y}
})
context.fillStyle = "black"
context.fill()
for (let i = 0 ; i < nPts ; i++) {
const start = b1[i]
const end = l1[nPts-1-i]

context.beginPath();
context.moveTo(start.x, start.y);
context.lineTo(end.x, end.y);
context.stroke();

}
for (let i = 0 ; i < nPts ; i++) {
const start = b2[i]
const end = l2[i]

context.beginPath();
context.moveTo(start.x, start.y);
context.lineTo(end.x, end.y);
context.stroke();

}
};
return context.canvas;
}
Insert cell
mouse = Generators.observe(notify => {
const update = mouse => (canvas.update(mouse), notify(mouse));
const moved = event => update({x: event.clientX, y: event.clientY});
window.addEventListener("mousemove", moved);
update({x: window.innerWidth / 2, y: window.innerHeight / 2});
return () => window.removeEventListener("mousemove", moved);
})
Insert cell
d3 = require("d3@5")
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