Denzell
Denzell

Reputation: 309

ChartJS (React) Line Chart - How to show single tooltip with data and labels from 3 (multiple) dataset?

I am trying to show a tooltip in Line Chart when a point was hovered. The tooltip will contain 3 data from 3 different data sets and 1 Label only.

Label: Date

Data Sets:

 1. Cases
 2. Deaths
 3. Recoveries

This is the current output of the Line Chart that I made:

enter image description here

In the current output when I hover in one data set it only shows the data of the current data set only. In the image above I hovered the data set Cases.

Here's my current source code (CasesGraph.js):

import React, { useState, useEffect } from 'react';
import axios from "axios";
import Chart from "./Chart";

const CasesGraph = (country) => {
let currentCountry = country.country;
const [chart, setChart] = useState({});

useEffect(() => {
    getData();
}, []);

 const getData = async () => {
    try {
      const res = await axios.get(
        "https://corona.lmao.ninja/v3/covid-19/historical/"+currentCountry+"?lastdays=all"
      );

  setChart({
    labels: Object.keys(res.data.timeline.cases),
    showTooltips: true,
    datasets: [
      {
        label: "Covid-19 Cases", //CASES DATASET
        fill: false,
        lineTension: 0.1,
        backgroundColor: "rgba(75,192,192,0.4)",
        borderColor: "#eb1515",
        borderCapStyle: "butt",
        borderDash: [],
        borderDashOffset: 0.0,
        borderJoinStyle: "miter",
        pointBorderColor: "#eb1515",
        pointBackgroundColor: "#fff",
        pointBorderWidth: 1,
        pointHoverRadius: 5,
        pointHoverBackgroundColor: "#eb1515",
        pointHoverBorderColor: "#eb1515",
        pointHoverBorderWidth: 2,
        pointRadius: 1,
        pointHitRadius: 10,
        maintainAspectRatio: false,
        data: Object.values(res.data.timeline.cases)
      },
      {
        label: "Covid-19 Deaths",  //DEATHS DATASET
        fill: false,
        lineTension: 0.1,
        backgroundColor: "rgba(75,192,192,0.4)",
        borderColor: "#1a1c1a",
        borderCapStyle: "butt",
        borderDash: [],
        borderDashOffset: 0.0,
        borderJoinStyle: "miter",
        pointBorderColor: "#1a1c1a",
        pointBackgroundColor: "#fff",
        pointBorderWidth: 1,
        pointHoverRadius: 5,
        pointHoverBackgroundColor: "#1a1c1a",
        pointHoverBorderColor: "#1a1c1a",
        pointHoverBorderWidth: 2,
        pointRadius: 1,
        pointHitRadius: 10,
        maintainAspectRatio: false,
        data: Object.values(res.data.timeline.deaths)
      },
      {
        label: "Covid-19 Recoveries", //RECOVERIES DATASET
        fill: false,
        lineTension: 0.1,
        backgroundColor: "rgba(75,192,192,0.4)",
        borderColor: "#0ec90e",
        borderCapStyle: "butt",
        borderDash: [],
        borderDashOffset: 0.0,
        borderJoinStyle: "miter",
        pointBorderColor: "#0ec90e",
        pointBackgroundColor: "#fff",
        pointBorderWidth: 1,
        pointHoverRadius: 5,
        pointHoverBackgroundColor: "#0ec90e",
        pointHoverBorderColor: "#0ec90e",
        pointHoverBorderWidth: 2,
        pointRadius: 1,
        pointHitRadius: 10,
        maintainAspectRatio: false,
        data: Object.values(res.data.timeline.recovered)
      }
    ],
    tooltips: {
      mode: 'label',
      callbacks: {
  
          title: function(tooltipItem, data) {
              return data.labels[tooltipItem[0].index]; //Date
          },
  
          beforeLabel: function(tooltipItem, data) {
              return '\nCases: ' + data.datasets[0].data[0] + 
                      '\nDeaths: ' + data.datasets[1].data[1] + 
                      '\nRecoveries: ' + data.datasets[2].data[2];
          },
  
          label: function(tooltipItem, data) {
              return 'Data2: ' + data.datasets[tooltipItem.datasetIndex].cases[tooltipItem.index];
          },
      },
    },
  },
  );
} catch (error) {
  console.log("CasesGraph: "+ error.response);
}


};

  return (
    <div style={{ position: "relative", margin: "auto", width: "80vw"}}>
      <Chart data={chart} /> <!-- CHART COMPONENT -->
    </div>
  );
};

export default CasesGraph;

And here's my code for Chart.js component:

import React from "react";
import { Line } from "react-chartjs-2";

const Chart = ({ data }) => {
  return <Line 
            data={data} 
            options={{ 
                responsive: true, 
                showTooltips: true,
                height: '600px', 
                width: "600px", 
                hover: {
                    mode: 'index',
                    intersect: false,
                },
            }}
        />;
};

export default Chart;

For more clear illustration of what I am trying to achieve here's the example: Chart.js - Line Chart Tooltip Hover Mode

enter image description here

Notice the tooltip has the two data from the two different datasets.

Upvotes: 3

Views: 6094

Answers (2)

Pramod Kharade
Pramod Kharade

Reputation: 2085

I have also been facing the same issue with react-chartjs-2 where I was unable to show multiple tooltips for Line Graph. After reading the document and trial and error, somehow I have cracked the solution.

There are three things. Need to configured with right namespace.

1.interaction:

interaction: {
              mode: "index",
              intersect: false,
            }

2. tooltips:

tooltips:{
     mode: "index",
     intersect: false,
 }

3.Hover:

 hover: {
            mode: "nearest",
            intersect: true,
          },

Three configuration with correct name will as below in options props.

 options={{
        interaction: {
          mode: "index",
          intersect: false,
        },

        plugins: {
          legend: {
            display: true,
            position: "right",
            align: "start",
            labels: {
              usePointStyle: true,
              boxWidth: 6,
            },
            title: {
              display: true,
              text: "Chart.js Bar Chart",
            },
          },
          tooltips: {
            mode: "index",
            intersect: false,
          },
          hover: {
            mode: "nearest",
            intersect: true,
          },
        },
        responsive: true,
        title: {
          display: false,
        },
        scales: {
          x: {
            type: "time",
            ticks: {
              autoSkip: true,
              maxTicksLimit: 14,
            },
            time: {
              unit: "month",
              displayFormats: {
                quarter: "MMM YYYY",
              },
            },
          },
          y: {
            ticks: {
              callback: function (value, index, values) {
                return `${value}  kVA`;
              },
            },
          },
        },
      }}

Upvotes: 2

Try removing the tooltips in your code and set your code - as is shown in this working jsfiddle I made.

So, the config section should look like this:

// NOTE: "full_data" is the data source (i.e res.data, in your case).

var config = {
  type: 'line',
  data: {
    labels: Object.keys(full_data.timeline.cases),
    showTooltips: true,
    datasets: [{
      label: "Covid-19 Cases", //CASES DATASET
      fill: false,
      lineTension: 0.1,
      backgroundColor: "rgba(75,192,192,0.4)",
      borderColor: "#eb1515",
      borderCapStyle: "butt",
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: "miter",
      pointBorderColor: "#eb1515",
      pointBackgroundColor: "#fff",
      pointBorderWidth: 1,
      pointHoverRadius: 5,
      pointHoverBackgroundColor: "#eb1515",
      pointHoverBorderColor: "#eb1515",
      pointHoverBorderWidth: 2,
      pointRadius: 1,
      pointHitRadius: 10,
      maintainAspectRatio: false,
      data: Object.values(full_data.timeline.cases)
    }, {
      label: "Covid-19 Deaths", //DEATHS DATASET
      fill: false,
      lineTension: 0.1,
      backgroundColor: "rgba(75,192,192,0.4)",
      borderColor: "#1a1c1a",
      borderCapStyle: "butt",
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: "miter",
      pointBorderColor: "#1a1c1a",
      pointBackgroundColor: "#fff",
      pointBorderWidth: 1,
      pointHoverRadius: 5,
      pointHoverBackgroundColor: "#1a1c1a",
      pointHoverBorderColor: "#1a1c1a",
      pointHoverBorderWidth: 2,
      pointRadius: 1,
      pointHitRadius: 10,
      maintainAspectRatio: false,
      data: Object.values(full_data.timeline.deaths)
    }, {
      label: "Covid-19 Recoveries", //RECOVERIES DATASET
      fill: false,
      lineTension: 0.1,
      backgroundColor: "rgba(75,192,192,0.4)",
      borderColor: "#0ec90e",
      borderCapStyle: "butt",
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: "miter",
      pointBorderColor: "#0ec90e",
      pointBackgroundColor: "#fff",
      pointBorderWidth: 1,
      pointHoverRadius: 5,
      pointHoverBackgroundColor: "#0ec90e",
      pointHoverBorderColor: "#0ec90e",
      pointHoverBorderWidth: 2,
      pointRadius: 1,
      pointHitRadius: 10,
      maintainAspectRatio: false,
      data: Object.values(full_data.timeline.recovered)
    }]
  },
  options: {
    responsive: true,
    title: {
      display: true,
      text: 'Chart.js Line Chart'
    },
    tooltips: {
      mode: 'index',
      intersect: false,
    },
    hover: {
      mode: 'nearest',
      intersect: true
    },
    scales: {
      xAxes: [{
        display: true,
        scaleLabel: {
          display: true,
          labelString: 'Dates'
        }
      }],
      yAxes: [{
        display: true,
        scaleLabel: {
          display: true,
        },
      }]
    }
  }
};

Upvotes: 0

Related Questions