react-chartjs-2 icon indicating copy to clipboard operation
react-chartjs-2 copied to clipboard

How to get onClick Event for a Label of a Line Chart in Chart.js [React]?

Open amresha opened this issue 3 years ago • 10 comments

I have a line chart I want that when someone clicks on the data points the particular index dataset and label is fetched. I have the below implementation which extracts the entire element in the console. Here is the screenshot of the console log https://imgur.com/a/ukgmrCY how should I extract the date/day as well which is in the x-axis? Please advise

import React from 'react';
import Chart from 'chart.js/auto';
import { Line } from 'react-chartjs-2';
import ChartDataLabels from 'chartjs-plugin-datalabels';


const Graph  = props => {

    Chart.register(ChartDataLabels);

    
        const labelstemp = [];
        for (let i = 0; i < 7; i++) {    
            labelstemp.push(props.temp_dates[i]);
        }

        
        const datasetLow = [];
        for (let i = 0; i < 7; i++) {    
            datasetLow.push(props.temp_low[i]);
        }

        const datasetHigh = [];
        for (let i = 0; i < 7; i++) {    
            datasetHigh.push(props.temp_high[i]);
        }

     const data = {
        labels:labelstemp,
        
        datasets: [
          {
            label: "Low Temp",
            data: datasetLow,
            fill: false,
            pointStyle: 'round',
            backgroundColor: "rgba(75,192,192,0.2)",
            borderColor: "rgba(75,192,192,1)",
            datalabels: {
                color: 'rgba(75,192,192,1)',
                padding: {
                    top: 10,
                    bottom: 30
                },
                fontSize: 15,
                titleSpacing: 2            }
        },
          {
            label: "High Temp",
            data: datasetHigh,
            fill: false,
            pointStyle: 'round',
            borderColor: "gray"
          }
        ]
      };
 
const options = {
    responsive: true,
   
    onClick: (e, elements) => {
        
        console.log(elements);
      },

    plugins:  {
           title: {
                display: true,
                text: 'Average High & Low Temperatures for ' + props.city,
                fontFace: 'verdana',
                fontSize:20, 
                padding: {
                    top: 10,
                    bottom: 30
                }
            },

            datalabels: {
                display: true
            },
            scales: {
                y: {
                    display: true,
                        title: {
                        display: true,
                        text: 'Temperature',
                        color: '#191'
                    },
                   padding: {top: 30, left: 0, right: 0, bottom: 0}
                },
                x: {
                    display: true,
                        title: {
                            display: true,
                            text: 'Days',
                            color: '#191'
                        },
                  padding: {top: 30, left: 0, right: 0, bottom: 0}
                },
              }      
        }
   
};


    return (
     <div className='container'>         
      <Line data={data} 
            options={options}
      />
    
     </div>   
    );

        }
export default Graph;

amresha avatar Dec 15 '21 09:12 amresha

Can you please post this project to sandbox? And use my changes, where you firstly tagged me.

tynarbekov avatar Dec 15 '21 11:12 tynarbekov

Can you please post this project to sandbox? And use my changes, where you firstly tagged me.

Please find the link to the sandbox, https://codesandbox.io/s/fragrant-cherry-w5sjh?file=/src/App.js If I can just get the array index which I can save it in a variable and can use it globally inside other components as I have a card component where I want to show the temperature of the clicked data point on the line chart.

amresha avatar Dec 15 '21 13:12 amresha

Hi, can you check this code

<Line data={data} options={options} getElementAtEvent={(elements, event) => { if (event.type === "click" && elements.length) { console.log(elements[0]); } }} />

Venulapog avatar Dec 16 '21 06:12 Venulapog

Hi, can you check this code

<Line data={data} options={options} getElementAtEvent={(elements, event) => { if (event.type === "click" && elements.length) { console.log(elements[0]); } }} />

I have updated the sandbox, please check. It shows the entire element, I want just the index value of the data set which has been clicked https://imgur.com/a/KRIZ20I

If I do console.log(elements[0].index) I don't get the index value, how should I access this value.

amresha avatar Dec 16 '21 08:12 amresha

hi i am also very new with this, I edited like this to test

const options = { responsive: true,

onClick: (e, elements) => {
  console.log('console 2', elements[0]?.index, elements[0]?.datasetIndex);
},

plugins: {
  title: {
    display: true,
    text: 'Average High & Low Temperatures for ' + props.city,
    fontFace: 'verdana',
    fontSize: 20,
    padding: {
      top: 10,
      bottom: 30,
    },
  },

  datalabels: {
    display: true,
  },
  scales: {
    y: {
      display: true,
      title: {
        display: true,
        text: 'Temperature',
        color: '#191',
      },
      padding: { top: 30, left: 0, right: 0, bottom: 0 },
    },
    x: {
      display: true,
      title: {
        display: true,
        text: 'Days',
        color: '#191',
      },
      padding: { top: 30, left: 0, right: 0, bottom: 0 },
    },
  },
},

};

return ( <div className="container"> <Line data={data} options={options} getElementAtEvent={(elements, event) => { if (event.type === 'click' && elements.length) { console.log( 'console 1', elements[0]?.index, elements[0]?.datasetIndex ); } }} /> ); }; export default Graph;

for my local machine, I am getting both console 1 and console 2, but for sandbox, I am getting only console 2

Venulapog avatar Dec 16 '21 08:12 Venulapog

elements[0]?.index, elements[0]?.datasetIndex

Many Thanks @Venulapog its working. I can get the index value. Can you please guide me on how should I use this index value to update a Global variable or update the State variable which is defined in my App.js as I need to update my Weather component when someone clicks on the data points?

amresha avatar Dec 16 '21 10:12 amresha

right now I am also stuck in the same part, whenever I update the state variable on click the graph re-renders, so basically on click graph is moving from the bottom to the point where it should be, I too also need guidance in this case.

Venulapog avatar Dec 16 '21 12:12 Venulapog

@tynarbekov can you please help us in this situation.

amresha avatar Dec 16 '21 12:12 amresha

right now I am also stuck in the same part, whenever I update the state variable on click the graph re-renders, so basically on click graph is moving from the bottom to the point where it should be, I too also need guidance in this case.

@Venulapog I am able to get the current index value at App.js with the help of function but this updated value is not reflecting here how should I bind this value so it should get updated value every time, any idea? the app is deployed here check the console

amresha avatar Dec 16 '21 18:12 amresha

I am also stuck in this situation only, the global variable is updated inside the function but it is the same outside the function, or it is not re-rendering

Venulapog avatar Dec 17 '21 07:12 Venulapog