Nivo: Extending nivo.rocks sankey diagram functionality

Created on 9 Nov 2020  路  5Comments  路  Source: plouc/nivo

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!

question sankey

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.

All 5 comments

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);
Was this page helpful?
0 / 5 - 0 ratings

Related issues

ellipticaldoor picture ellipticaldoor  路  4Comments

stahlmanDesign picture stahlmanDesign  路  3Comments

PattieC4ke picture PattieC4ke  路  3Comments

danpettay picture danpettay  路  3Comments

KENNYSOFT picture KENNYSOFT  路  3Comments