Combining SVG and Canvas
When displaying 100,000 circles in a scatterplot, using canvas is essential for performance.
However, SVG is still ideal for axes and lighter graphical elements. Letβs explore how to combine SVG and canvas effectively!
π Stacking Canvas and SVG
In the previous lesson, we learned how to loop through a dataset and render a circle for each item. This is very close to creating a bubble chart! π
In earlier modules, we explored how to add margins around the chart area and created reusable axis components to define the x and y scales.
The great news is that we can seamlessly combine both canvas
and SVG
, since, at the core, they're both HTML elements!
How to overlap SVG and Canvas layers to create a bubble plot.
π How your DOM will look like
Below is some pseudocode demonstrating the JSX structure of the graph component.
Essentially, your SVG and canvas elements need to be absolutely positioned (using position: absolute
) to stack correctly on top of each other.
A key point to remember is that absolutely positioned elements are positioned relative to the nearest positioned ancestor. So, make sure the parent div
is set to position: relative
, or the positioning wonβt work as expected.
{/* Parent div */}
<div style={{ position: 'relative' }}>
{/* Bounds div */}
<div
style={{
transform: ...translate for margins,
width: boundsWidth,
height: boundsHeight,
}}
>
{/* Axes */}
<svg
width={boundsWidth}
height={boundsHeight}
style={{ position: 'absolute', top: 0, left: 0 }}
>
<AxisLeft yScale={yScale} pixelsPerTick={40} width={boundsWidth} />
<g transform={...translate to bottom}>
<AxisBottom xScale={xScale} pixelsPerTick={40} height={boundsHeight}/>
</g>
</svg>
{/* Canvas is for the circles */}
<canvas
style={{ position: 'relative' }}
ref={canvasRef}
width={boundsWidth}
height={boundsHeight}
/>
</div>
</div>
Application: bubble plot
Here's an example of a bubble plot created with SVG and React! Take a moment to review the code and ensure you fully understand each part.
Your fist bubble chart using canvas (for circles) and SVG (for axes)