1

I am creating a Sankey chart via react-google-charts. Each time when clicked on the link between the nodes I am printing the data which has been working fine until recently.

Assume my Sankey diagram to be like this and I clicked on the link between A & P:

[A] ----> [P] ------> [X]
[B] ----> [Q] ------> [Y]
[C] ----> [R] ------> [Z]


let myOptions = {
  sankey: {
    link: {
      interactivity: true
    }
  }
}

...
...

<Chart
  chartType='Sankey'
  data={
    [
      ['From', 'To', 'Weight', {role: 'tooltip', type: 'string'}],
      ['A', 'P', 1, 'i111'],
      ['B', 'Q', 1, 'j333'],
      ['C', 'R', 1, 'k444'],
      ['P', 'X', 1, 'l555'],
      ['Q', 'Y', 1, 'l666'],
      ['R', 'Z', 1, 'n999']
    ]
  }
  columns
  options={myOptions}
  chartEvents={[
    {
      eventName: 'select',
      callback: ({chartWrapper}) => {
        const chart = chartWrapper.getChart()
        const selection = chart.getSelection()
        if (selection.length === 1) {
          const [selectedItem] = selection
          const {row} = selectedItem

          // below line was working until recently, but not anymore
          console.log(chartWrapper.getDataTable().Vf[row].c)

          // updated the property key after which it works
          console.log(chartWrapper.getDataTable().Wf[row].c)
          // returns [{v: 'A'}, {v: 'P'}, {v: 1}, {v: 'i111'}]
        }
      }
    }
  ]}
/>

I can also get the selection data like this but it does not give me the final column value i.e., tooltip in this case.

console.log(chartWrapper.getDataTable().cache[row])
// returns [{Me: 'A'}, {Me: 'P'}, {Me: '1'}]

Is there any other way for me to get the data apart from what I have done above? Especially the line

chartWrapper.getDataTable().Wf[row].c

Having a property value hardcoded has broken my UI thrice in recent times and I would like to avoid doing so.

WhiteHat
  • 59,912
  • 7
  • 51
  • 133
Imran
  • 67
  • 6

1 Answers1

0

to my knowledge, the sankey chart will only allow you to select the nodes,
not the links between the nodes.
and this is only allowed after setting the interactivity option.

options: {
  sankey: {
    node: {
      interactivity: true
    }
  }
}

the selection returns the name of the node selected,
which can appear in the data table multiple times.
in the following example, I've added an additional "P" node to demonstrate.

when the select event fires, you can get the name of the node selected from the chart's selection.
then you must search through the rows in the data table to find the row with the matching node name.

once you've found the data table row for the selected node name,
you can use data table method getValue to retrieve the values for that row.

see following working snippet...

google.charts.load('current', {
  packages: ['controls', 'sankey']
}).then(function () {
  var chartWrapper = new google.visualization.ChartWrapper({
    chartType: 'Sankey',
    containerId: 'chart',
    dataTable: google.visualization.arrayToDataTable([
      ['From', 'To', 'Weight', {role: 'tooltip', type: 'string'}],
      ['A', 'P', 1, 'i111'],
      ['B', 'Q', 1, 'j333'],
      ['C', 'R', 1, 'k444'],
      ['P', 'X', 1, 'l555'],
      ['P', 'Y', 2, 'l555'],
      ['Q', 'Y', 1, 'l666'],
      ['R', 'Z', 1, 'n999']
    ]),
    options: {
      sankey: {
        node: {
          interactivity: true
        }
      }
    }
  });

  google.visualization.events.addListener(chartWrapper, 'ready', function () {
    google.visualization.events.addListener(chartWrapper.getChart(), 'select', selectEvent);
  });
  chartWrapper.draw();

  function selectEvent() {
    var chart = chartWrapper.getChart();
    var data = chartWrapper.getDataTable();
    var selection = chart.getSelection();
    if (selection.length > 0) {
      // find data table rows for selected node name
      var nodeName = selection[0].name;
      var nodeRows = data.getFilteredRows([{
        column: 0,
        value: nodeName
      }]);

      // find row values for selected node name
      nodeRows.forEach(function (row) {
        var valFrom = data.getValue(row, 0);
        var valTo = data.getValue(row, 1);
        var valWeight = data.getValue(row, 2);
        var valTooltip = data.getValue(row, 3);
        console.log(valFrom, valTo, valWeight, valTooltip);
      });
    }
  }
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>
WhiteHat
  • 59,912
  • 7
  • 51
  • 133
  • You can do both node & link selection in Sankey. I appreciate your inputs but I was specifically looking for selection event on link in Sankey. For some reason, `chartWrapper.getDataTable()` is returning object with an updated/different key after every few months. – Imran Jul 05 '21 at 07:37