React-chartjs-2: OnClick item has the incorrect datasetIndex for line graphs

Created on 20 Mar 2018  路  9Comments  路  Source: reactchartjs/react-chartjs-2

Hi,

I notice that when you associate an onclick event to a line chart, the item that is returned does not contain a validate dataset index. the index for the row is correct but the col value is not and always set to 0.

    public render() {
        const options = {
            onClick: (e, item) => {
                console.log(`Item with text ${item[0]._index} and index ${item[0]._datasetIndex} clicked`);
            }

        };
        return (
            <div>

              <Line data={data}
                    options={options}    />
            </div>
        );
    }

How do we get the data point (x,y) where the user clicks if you don't know what the _dataset index is. when i say x and y I refer to the actual data points and not the position

Thanks,
Derek

Most helpful comment

Hey, I don't know if anyone is still looking for this answer but I came across a nice way to do it today.

I had a stacked line chart and I needed to get the information from the exact data point that was clicked. The charts have a prop called getElementAtEvent, to which you can pass a function that will take an array holding the single element you click on, not the array of every element in the chart like the onClick handler does.

The way I used it was like so:

LineChart Class:

import { Line } from 'react-chart-js2'

function LineChart(props) {
   return (
      <div className="line-chart">
         <Line
             getElementAtEvent={props.handleChartClick}
             ...
          />
      </div>
   )
}

export default LineChart

Parent Class:

import LineChart from './LineChart'

class Parent extends Component {
   handleChartClick(element) {
      const { datasets } = element[0]._chart.tooltip._data
      const datasetIndex = element[0]._datasetIndex
      const dataIndex = element[0]._index

      alert(`${datasets[datasetIndex].label}: ${datasets[datasetIndex].data[dataIndex]}`) 
   }

   render() {
      return (
         <LineChart
            handleChartClick={element => this.handleChartClick(element)}
            ...
         />
      )
   }
}

This will alert the associated label and the value of the data point that you click on in the chart, even with stacked line/bar charts. Then you can do whatever you want with that information!

Hope this helps!

DISCLAIMER: It definitely doesn't have to be organized this way, I just extracted this from my project because I know for a fact it works just like this. You could totally put the handleChartClick(element) directly inside wherever you import the Line class from react-chart-js2.

All 9 comments

How can no one comment on this? This is a basic use case of the library and it's impossible to do!!

@darewreck54 , @francisco4challenge , were you guys able to resolve this issue? If yes, can you please share the knowledge?

Thanks

Need to grab the index in my dataset to link to specific URLs... Anyone solve this click event dilemma?

same issue, _datasetIndex is wrong for me too for my multi-line chart... It would appeared that the array is sorted sequentially based on the datasets array index, and it does not correspond to the accompanying coordinates~ Glaring bug!

Need to grab the index in my dataset to link to specific URLs... Anyone solve this click event dilemma?

An alternative way is to grab the data from the tooltip, though this does not help for my specific use-case

Well... this is a bit outdated topic, but I ran into this issue. I was trying to get a timestamp from the click event handler on a chart. My solution (hacky one) was to interpolate the value using information _xScale and _view from the element object.

const interpolate = ({ anchors, target }) => {
const [ p1, p2 ] = anchors;
const deltaX = p2.x - p1.x;
const deltaY = p2.y - p1.y;

return deltaX === 0 ? p1.y : p1.y + (deltaY * (target - p1.x)) / deltaX;

};

const getTimestampFromClickElement = el => {
const target = el._view.x;
const { left: xMin, right: xMax, min: tMin, max: tMax } = el._xScale;

const tTarget = interpolate({
    anchors: [{  x: xMin, y: tMin  }, {  x: xMax, y: tMax  }], 
    target  });
return new Date(tTarget);

};

const clickEventHandler = ([element]) => {
if (element) {
const ts = getTimestampFromClickElement(element);
selectTimestamp(ts);
} else {
deselectTimestamp();
}
}

Hi, I also ran into the issue of getting a wrong _datasetIndex for my piechart with 2 datasets.

When I click on the inner chart, the _datasetIndex returned is still the one for the outer chart. Huge problem for my use case and I can't seem to fix it

Hey, I don't know if anyone is still looking for this answer but I came across a nice way to do it today.

I had a stacked line chart and I needed to get the information from the exact data point that was clicked. The charts have a prop called getElementAtEvent, to which you can pass a function that will take an array holding the single element you click on, not the array of every element in the chart like the onClick handler does.

The way I used it was like so:

LineChart Class:

import { Line } from 'react-chart-js2'

function LineChart(props) {
   return (
      <div className="line-chart">
         <Line
             getElementAtEvent={props.handleChartClick}
             ...
          />
      </div>
   )
}

export default LineChart

Parent Class:

import LineChart from './LineChart'

class Parent extends Component {
   handleChartClick(element) {
      const { datasets } = element[0]._chart.tooltip._data
      const datasetIndex = element[0]._datasetIndex
      const dataIndex = element[0]._index

      alert(`${datasets[datasetIndex].label}: ${datasets[datasetIndex].data[dataIndex]}`) 
   }

   render() {
      return (
         <LineChart
            handleChartClick={element => this.handleChartClick(element)}
            ...
         />
      )
   }
}

This will alert the associated label and the value of the data point that you click on in the chart, even with stacked line/bar charts. Then you can do whatever you want with that information!

Hope this helps!

DISCLAIMER: It definitely doesn't have to be organized this way, I just extracted this from my project because I know for a fact it works just like this. You could totally put the handleChartClick(element) directly inside wherever you import the Line class from react-chart-js2.

Please open an issue one the chart.js repo. This is simply a wrapper component that passes options along.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cbroberg picture cbroberg  路  5Comments

flavz27 picture flavz27  路  5Comments

flxwu picture flxwu  路  3Comments

souuu picture souuu  路  4Comments

n1c01a5 picture n1c01a5  路  4Comments