Published
Edited
Jul 14, 2021
5 stars
Insert cell
Insert cell
Insert cell
n_points = 200000 // you can go over millions here
Insert cell
Insert cell
Insert cell
Insert cell
{
// sets and draw points on scatterplot One
scatterOne.set({
colorBy: "value",
cameraTarget: [0, 0],
cameraDistance: 3,
cameraRotation: 0,
pointColor: points.map((_, i) =>
d3.color(d3.interpolateTurbo((0.8 * i) / points.length)).hex()
)
});
scatterOne.draw(points);
}
Insert cell
{
// sets and draw points on scatterplot two if there are selected points on scatterplot one
if (scatterOne.selectedPoints.length) {
// using geoBounds to get points boundingBox to center the camera target
const boundingBox = d3.geoBounds({
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "LineString",
coordinates: scatterOne.selectedPoints.map((p) => [
points[p][0],
points[p][1]
])
}
}
]
});
// get middle box points coordinates as cameraTarget
scatterTwo.draw(scatterOne.selectedPoints.map((p) => points[p]));

scatterTwo.set({
colorBy: "value",
pointColor: points.map((_, i) =>
d3.color(d3.interpolateTurbo(i / points.length)).hex()
),
cameraTarget: [
(boundingBox[1][0] + boundingBox[0][0]) / 2,
(boundingBox[1][1] + boundingBox[0][1]) / 2
]
});
}
}
Insert cell
height = width / 2
Insert cell
points = {
const points = new Array(n_points).fill().map((_, i) => {
const x = d3.randomNormal()();
const y = d3.randomNormal()();
return [x, y, i, Math.sqrt(x ** 2 + y ** 2)];
});

const extr = d3.extent(points, (d) => d[3]);

return points.map((pt) => [
pt[0],
pt[1],
pt[2],
pt[3] / Math.sqrt(extr[0] ** 2 + extr[1] ** 2)
]);
}
Insert cell
//simple helper to create a dynamic viewof scatterplot
function createScatterplotView(opts = {}) {
const canvas = html`<canvas width="${opts.width}" height="${opts.height}"></canvas>`;

const xScale = d3.scaleLinear();
const yScale = d3.scaleLinear();
const scatterplot = createScatterplot.default({
canvas: canvas,
pointSize: 5,
xScale,
yScale,
...opts
});

canvas.value = { ...scatterplot, xScale, yScale };
canvas.value.selectedPoints = [];
canvas.value.camera = scatterplot.get("camera");

scatterplot.subscribe("view", ({ camera }) => {
canvas.value.camera = camera;
// canvas.dispatchEvent(new Event("input")); //this generates a crazy infinity loop:()
});

scatterplot.subscribe("select", ({ points }) => {
console.log("select");
canvas.value.selectedPoints = points;
canvas.dispatchEvent(new Event("input"));
});

invalidation.then(() => scatterplot.destroy());
return canvas;
}
Insert cell
createScatterplot = require("regl-scatterplot")
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