Machine-readable page content
Canonical: https://semiotic.nteract.io/cookbook/canvas-interaction
Canvas Interaction
When your dataset has tens of thousands of points, SVG rendering becomes slow and the DOM balloons in size. This recipe shows how to render nearly 54,000 diamond data points on a canvas element while still retaining full hover interactivity through Semiotic's Voronoi-based interaction layer.
The Visualization
This page uses the classic diamond dataset of nearly 54,000 diamonds from the ggplot2 project.
StreamXYFrame uses the same streaming architecture for both live and static data. When a large bounded dataset is passed via the data prop, the frame automatically chunks it and renders progressively across animation frames — the first batch appears immediately and the rest fill in over subsequent frames. No special configuration is needed; just pass your data and the frame handles the rest.
Loading...
How It Works
The entire trick is the canvasPoints prop. When set totrue, StreamXYFrame draws points to a canvas element instead of creating individual SVG circles. The interaction layer still uses an SVG overlay with a Voronoi tessellation, so hover and click behaviors work seamlessly:
JSX
const frameProps = { size: [700, 500], points: parsedDiamonds, // ~54,000 points xAccessor: "x", yAccessor: "y", canvasPoints: true, hoverAnnotation: true, pointStyle: d => ({ fill: d.color, fillOpacity: 0.9 }) }
The tooltip uses coincidentPoints to show when multiple diamonds overlap at the same location, since with this many data points collisions are inevitable:
JSX
tooltipContent: d => ( <div className="tooltip-content"> <p>Price: ${d.y}</p> <p>Carat: {d.x}</p> <p> {d.coincidentPoints.length > 1 && `+${d.coincidentPoints.length - 1} more`} </p> </div> )
Key Takeaways
- Use
canvasPoints (or canvasLines,canvasAreas) to switch from SVG to canvas rendering for large datasets. - Hover interactions work the same way regardless of render mode -- Semiotic's Voronoi layer operates independently of the rendering target.
- The
coincidentPoints property on hover data helps you handle overlapping points gracefully. - Loading data asynchronously (via fetch/CSV parse) keeps the component responsive during initial render.
- StreamXYFrame — the underlying frame with canvas rendering support
- Scatterplot — point-based visualization at smaller scales
- Tooltips — customizing tooltip content and positioning