I'm using nivo's Sankey diagram, and I need to trigger click/mouseover events programmatically.
I assume it shouldn't be a problem since nivo is built upon d3 library, which already implements this functionality using the dispatch method:
https://stackoverflow.com/a/40289334/12099841
But it's not included in nivo's API.
Is it possible to add this functionality manually?
Thanks!
It does support onClick already, it just isn't present in that documentation. If you click on a link or node, you will see the event in the Action Log below the chart.
Thanks for replying @wyze!
I wasn't talking about handling a click event, though.
What I need is to programmatically select a specific SVG path in the Sankey diagram, and then trigger an event manually, as in the StackOverflow example:
d3.select('#some-id').dispatch('click');
Ah I see, my fault for the misunderstanding. I'm not sure if it works or not. It definitely would be a challenge to select certain things currently with the DOM structure we render out. Not sure if we would want to modify it for this use case.
/cc @plouc
@realraif, while that's possible when relying on d3 for the rendering, nivo uses React for rendering and only rely on d3 for computations, which works quite differently, and unless you use refs, you cannot access nodes this way.
Unfortunately, you cannot do this, or you could do it by creating a custom layer and implementing elements by yourself creating refs for everything, but it would be a lot of work.
I somehow implemented this using a hack:
// on load
useEffect(clickAllSankeyLinks, []);
// on selection
useEffect(hoverSelectedLink, [selectedLink]);
return (
<div ref={chartRef}>
<ResponsiveSankey {...options}
// using onClick to get the links data
onClick={(data, event) => {
const source = data.source.id;
const target = data.target.id;
const element = event.target;
setSankeyLinks((prevState) => ({
...prevState,
[source]: { ...prevState[source], [target]: element },
}));
}}
/>
</div>
);
I'm triggering the events using a native HTML element method:
const mouseEvent = document.createEvent("SVGEvents");
mouseEvent.initEvent("mouseover", true, true);
element.dispatchEvent(mouseEvent);
Most helpful comment
@realraif, while that's possible when relying on d3 for the rendering, nivo uses React for rendering and only rely on d3 for computations, which works quite differently, and unless you use refs, you cannot access nodes this way.
Unfortunately, you cannot do this, or you could do it by creating a custom layer and implementing elements by yourself creating refs for everything, but it would be a lot of work.