Published
Edited
Feb 5, 2020
37 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function* rgbColorGenerator() {
let nextColor = 1;
const nextColorStep = 50;

while (nextColor < 16777216) {
const rgb = [];

rgb.push(nextColor & 0xff); // R.
rgb.push((nextColor & 0xff00) >> 8); // G.
rgb.push((nextColor & 0xff0000) >> 16); // B.

nextColor += nextColorStep;
yield `rgb(${rgb.join(',')})`;
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function draw(mouseEvent = {}) {
const hiddenCanvasColor = rgbColorGenerator();
const colorToPoint = {};
const { offsetX = null, offsetY = null } = mouseEvent;
context.clearRect(0, 0, width, height);
hiddenContext.clearRect(0, 0, width, height);
hiddenContextSelection.clearRect(0, 0, width, height);
points.forEach(point => {
// Define point geometry we will render to both the canvas and hidden canvas.
const circle = new Path2D();
circle.arc(point.x, point.y, 10, 0, 2 * Math.PI);
// Render to the hidden canvas and map a hidden canvas color to a point.
// This is where the magic happens.
const color = hiddenCanvasColor.next().value;
colorToPoint[color] = point;
hiddenContext.fillStyle = color;
hiddenContext.fill(circle);
// Render to the hidden selection canvas so we can display how the hidden canvas picking happens.
// This is just for demonstration purposes.
hiddenContextSelection.fillStyle = color;
hiddenContextSelection.fill(circle);
// If a mouse event is given, draw the hidden canvas mouse selection point.
// This is just for demonstration purposes.
if (offsetX && offsetY) {
const circle = new Path2D();
circle.arc(offsetX, offsetY, 5, 0, 2 * Math.PI);
hiddenContextSelection.fillStyle = '#4bf442';
hiddenContextSelection.fill(circle);
}
// Render to the regular canvas.
context.fillStyle = point.color;
context.fill(circle);
});
return colorToPoint;
}
Insert cell
colorToPoint = {
return draw();
}
Insert cell
Insert cell
mousemove = {
return d3.select(context.canvas).on('mousemove', () => {
const mouseEvent = d3.event;
const { offsetX, offsetY } = mouseEvent;
const { data } = hiddenContext.getImageData(offsetX, offsetY, 1, 1);
const colorKey = `rgb(${data[0]},${data[1]},${data[2]})`;
const point = colorToPoint[colorKey];

draw(mouseEvent);

if (point) {
showTooltip(point);
} else {
hideTooltip();
}
});
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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