Cross graph highlight interaction


This post explains how to add cross graph interactions in a react app. It focus on performance, showing how a naive approach with a shared state leads to a disappointing result and how a react context can solve the problem.

Disclaimer: the concepts explained here where showed to me by my colleague Gabriel Vergnaud.

What is cross graph interaction

What it is.

working example

Why do we care?

Focus on performance

Naive solution: shared state

A first solution: a shared state. You defined a react state at the level of the component that wraps all your viz with useState:

const [group, setGroup] = useState<number | null>(null);

You then pass the state and the setter function to each viz. Something like:

<Barplot
  width={300}
  height={220}
  group={group}
  setGroup={setGroup}
/>

Then, for each shape item of the graph you're building, you check wether or not the shape should be highlighted, and changes the way it's rendered if so.

In the example below I slightly increase the opacity, so the div as this in its style attribute:

style={{
  opacity: group === i ? 1 : 0.4,
}}

Here is the result for 4 barplots with 1500 items each:

Four barplots with 1500 groups each. Hovering a group on a chart highlights it on other charts, with very poor performances.

As you can see it works, but is very slow.

Improving rerendering

A first solution: a shared state.

Four barplots with 3000 groups each. Hovering a group on a chart highlights it on other charts, with very poor performances.

Why is it so slow?

Event emitter

Use a context to improve perf

React documentation about context

Context is primarily used when some data needs to be accessible by many components at different nesting levels.

Step 1 is to create the context with createContext.

Doc about CustomEvent(): linkBasically you do const catFound = new CustomEvent('animalfound'). catFound is a CustomEvent. You can trigger it with

Four barplots with 3000 groups each. Hovering a group on a chart highlights it on other charts, with very poor performances.

Conclusion

Article explains how to create a performant cross graph interaction using a react context and an event emitter.

But there is more even more you should do

  • use debounce and throttling to avoid too many concurrent re-renders
  • don't highlight graphs that are outside of the view port



General Knowledge

Contact

👋 Hey, I'm Yan and I'm currently working on this project!

Feedback is welcome ❤️. You can fill an issue on Github, drop me a message on Twitter, or even send me an email pasting yan.holtz.data with gmail.com. You can also subscribe to the newsletter to know when I publish more content!

    Contact

    👋 Hey, I'm Yan and I'm currently working on this project!

    Feedback is welcome ❤️. You can fill an issue on Github, drop me a message on Twitter, or even send me an email pasting yan.holtz.data with gmail.com. You can also subscribe to the newsletter to know when I publish more content!