Common Caveats


The previous lesson taught several strategies to add hover effects to your charts. Some using pure css, some using a mix of css and javascript.

This lesson covers the most common pitfalls: flickering between shapes, performance traps, animation overuse, mobile compatibility, and more.

Members only
9 minutes read

Less is more

Hover effects should serve a purpose: helping the user identify a specific data point, read an exact value, or understand a relationship.

If a hover effect doesn't make the chart easier to read, remove it.

A good rule of thumb: hover should reveal information, not decorate the chart. Ask yourself: "what does the user learn when they hover here?" If the answer is "nothing useful", skip it.

The flickering problem

This is the most common bug when implementing hover effects. It happens when there are gaps between shapes.

We built a barplot with a hover effect in the Strategy 2 lesson that suffers from this bug. As the user moves the cursor from one bar to the next, the cursor briefly enters the gap, which resets the highlight and triggers a flicker.

import { data } from "./data";
import "./styles.css";

export default function App() {
  return (
    <svg width={430} height={300}>
      <g className="container">
        {data.map((d, i) => (
          <rect
            key={i}
            x={10}
            y={i * 40 + 10}
            width={(d.value / 100) * 400}
            height={30}
            fill="#4e79a7"
            rx={4}
            className="bar"
          />
        ))}
      </g>
    </svg>
  );
}

Move between bars — notice the flicker when crossing gaps.

This is a common issue and there are several workarounds:

1️⃣ Add an invisible overlay (a transparent rect) that captures mouse events, then compute the closest data point from the cursor position.

2️⃣ Use a Voronoi overlay: divide the chart area into regions, one per data point, with no gaps. Each region captures hover for its nearest point. This is the gold standard for scatterplots.

3️⃣ Remove gaps entirely: set bar padding to 0, or use overlapping hit areas that are slightly larger than the visible shapes.

Performance

With many data points per chart — and many charts in your application — hover effects can quickly make the whole app feel sluggish.

A few core rules to keep in mind:

1️⃣ CSS-only strategies first. They don't trigger React re-renders at all, so they're almost free. JavaScript is much costlier.

2️⃣ Minimize what re-renders. Only what changes should be recomputed. If nothing in a component changes, it should not re-render.

3️⃣ Avoid re-computing variables. If only the opacity of elements changes on hover, the scales, axes, and layout should not be recalculated. useMemo is a good friend here.

4️⃣ Avoid re-computing geometries. If all the dots stay the same except the one being hovered, don't recompute the entire shape list. A dedicated hover layer is a good fix.

5️⃣ Consider Canvas for large datasets. Canvas is an alternative to SVG. It's a bit trickier to work with, but it greatly improves rendering performance.

💡 The last module of this course is dedicated to performance. We'll study those 5 rules in depth there.

Oh no! 😱

It seems like you haven't enrolled in the course yet!

Join many other students today and learn how to create bespoke, interactive graphs with d3.js and React!

Enrollment is currently closed. Join the waitlist to be notified when doors reopen:

Or Login