How to customize the tooltip of a Chart.js 2.0 Doughnut Chart?
Asked Answered
S

8

66

I'm trying to show some data using a doughnut chart from Chart.js2.

My current chart looks like this:
current chart

My desired output must show another attribute, which is the percentage, and looks like this:
desired chart with percentage

I've read the documentation, but I can't cope with this because it's very general and I'm new to JavaScript.

My code for the first chart is the following:

const renderCashCurrencyPie = (cashAnalysisBalances) => {
  if (cashAnalysisBalances) {
    const currenciesName = cashAnalysisBalances
    .map(curName => curName.currency);

    const availableCash = cashAnalysisBalances
    .map(avCash => avCash.availableCash);

    let currenciesCounter = 0;
    for (let i = 0; i < currenciesName.length; i += 1) {
      if (currenciesName[i] !== currenciesName[i + 1]) {
        currenciesCounter += 1;
      }
    }

    const currenciesData = {
      labels: currenciesName,
      datasets: [{
        data: availableCash,
        backgroundColor: [
          '#129CFF',
          '#0C6DB3',
          '#FF6384',
          '#00FFFF'
        ],
        hoverBackgroundColor: [
          '#FF6384',
          '#36A2EB',
          '#FFCE56',
          '#00FFFF'
        ]
      }]
    };
Stockman answered 25/4, 2017 at 7:44 Comment(0)
M
161

You can customize the tooltips using the chart options tooltip configuration section, as explained here: http://www.chartjs.org/docs/latest/configuration/tooltip.html#tooltip-configuration

As shown in the example code below, you can change things like color, sizing and styles. Check out the documentation linked above for a full list of configurable options.

If you want to add the percentage to the tooltip display, you can use tooltip callbacks. The documentation has a list of all the possible customizable callback fields.

In the below example, I set the "title" to show the label name, "label" to show the value, and added the percentage to "afterLabel".

var myChart = new Chart(ctx, {
  type: 'doughnut',
  data: data,
  options: {
    tooltips: {
      callbacks: {
        title: function(tooltipItem, data) {
          return data['labels'][tooltipItem[0]['index']];
        },
        label: function(tooltipItem, data) {
          return data['datasets'][0]['data'][tooltipItem['index']];
        },
        afterLabel: function(tooltipItem, data) {
          var dataset = data['datasets'][0];
          var percent = Math.round((dataset['data'][tooltipItem['index']] / dataset["_meta"][0]['total']) * 100)
          return '(' + percent + '%)';
        }
      },
      backgroundColor: '#FFF',
      titleFontSize: 16,
      titleFontColor: '#0066ff',
      bodyFontColor: '#000',
      bodyFontSize: 14,
      displayColors: false
    }
  }
});

Working JSFiddle: https://jsfiddle.net/m7s43hrs/

Mar answered 16/5, 2017 at 20:14 Comment(6)
data['datasets'][tooltipItem.datasetIndex]['data'][tooltipItem.index] as we also have the dataSet index.Rattlesnake
Yes, this is nice if you need a lite-customization. But what if you need to render a button for instance, or a table, or whatelse.. you have to implement custom options but is not too easy (github.com/jerairrest/react-chartjs-2/issues/450)Grenoble
If you want the dataset label as the title: data['datasets'][tooltipItem[0].datasetIndex].labelShirr
Note that some fields, like title, are passed an array of toolTipItem objects, and others, like label, are passed a single object; notice how the index value for each is accessed differently in the example above.Notch
when I try to get total value after reach meta, I noticed that meta nuber is changed dynamic (ex: 0 ,1,14,20). thats why I change the dataset["_meta"][0]['total'] to let total = dataset["_meta"][Object.keys(dataset["_meta"])[0]]['total']Sidwell
And for V3.5? This totally changed.Begird
S
11

As per @Tot Zam's answer, but using arrow functions for brevity:

options: {
  tooltips: {
    callbacks: {
      title: (items, data) => data.datasets[items[0].datasetIndex].data[items[0].index].myProperty1,
      label: (item, data) => data.datasets[item.datasetIndex].data[item.index].myProperty2
    }
  }
}
Symphonious answered 28/2, 2018 at 9:40 Comment(0)
K
5

For those who are using latest Chart.js version v3.5.1, below is the code you can add to customize tooltip.

Add below plugins object to chart options

plugins: {
  tooltip: {
    enabled: true,
    usePointStyle: true,
    callbacks: { 
      // To change title in tooltip
      title: (data) => { return data[0].parsed.x } 

      // To change label in tooltip
      label: (data) => { 
            return data.parsed.y === 2 ? "Good" : "Critical"
      }
    },
  },
},
Kiakiah answered 22/10, 2021 at 2:17 Comment(0)
Z
3

Anybody looking out for solution in 2021 to set the label as title of tooltip, below code snippet works. use console.dir(tooltipItems) to see the contents of tooltipItems.

callbacks: {
        title: function (tooltipItems) {
          return tooltipItems[0].formattedValue;
        }
      }
Zorine answered 20/5, 2021 at 18:7 Comment(4)
how could this works? I still get undefined for scatter.Ferbam
@JorgeAlvarado works on line chart. make sure you have placed the above code block under options > tooltip as property.Zorine
I made this possible, with some commands in line; I was using ScatterFerbam
Huh. This worked! -- except I just returned tooltipItems.formattedValueBegird
H
3

Thanks to Tuhin for his answer. It helped me to figure out how to change the tooltip title using a callback function.

I'm quite new to javascript so it wasn't obvious to me from the Chart.js 3.4.1 docs exactly how to work with the tooltip object. By using console.log(tooltipItems), as suggested, I was able to get the info I required.

I ended up with a config object with the following callback set in options.plugins. I wanted a shortened date string to be displayed as the title of the tooltip. Using toDateString() did the trick.

Here's how I set up my callback:

    options: {
      ...

      plugins: {
        tooltip: {
          callbacks: {
            title: tooltipItems => {
              title = tooltipItems[0].parsed.x
              if (title !== null) {
                console.dir(title)
                title = new Date(title).toDateString()
              }
              return title
            },
          },
        },
      },
    },
Himeji answered 6/7, 2021 at 21:1 Comment(1)
This worked with react-chartjs-2. options.plugins.tooltip.callbacks is the path you need.Costermansville
L
3

Hi i found a practical solution to format the text of tooltip

 const label = (context) => {
   
    let lbl = context.label+' '+ context.formattedValue+' ' + '%'
    return lbl
  }
  const chartOptions = { 
    plugins:{
      tooltip: {
        callbacks: {
            label: label,
        }, 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Louvre answered 16/6, 2022 at 13:24 Comment(0)
T
0

Here is an example an Doughnut chart with a tooltip (Chart.js 4.4.0) :

let chart = new Chart(el.getContext('2d'), {
    type: 'doughnut',
    data: {
      datasets: [
        {
          data: this.doughnutData
        }
      ]
    },
    options: {
      plugins: {
        tooltip: {
          callbacks: {
            label: function(context) {
              var label = context.dataset.data[context.dataIndex]['label'];
              var value = context.formattedValue;
              return label + ' : ' + value + ' %';
            }
          }
        }
      },
      responsive: true,
      // This doughnut chart will respond to mousemove or click (show label-percentage).
      events: ['click','mousemove']
    }
  });

It works fine, hope it helps :)

Tooltip Doc : https://www.chartjs.org/docs/latest/configuration/tooltip.html#tooltip-item-context.

Thinking answered 4/10, 2023 at 13:54 Comment(0)
S
0

public lineChartConnexionOptions: ChartOptions = { responsive: true, scales: { xAxes: [{}], yAxes: [{ ticks: { beginAtZero: true, min: 0, suggestedMax: 12 } }] },

tooltips: {
  enabled: true,
  mode: 'single',
  callbacks: {
           label: function (tooltipItems, data) {
               
               let fg = parseInt(tooltipItems.value)
               if(fg > 6){
                 return " En charge "
               }else{
                if(fg> 0){
                  return    " La borne est En ligne 6 herbeat/heure "
                }else{
                  return    " La borne est Hors ligne "
                }
                
               }
           }
  }},

plugins: {

  datalabels: {
    anchor: 'end',
    align: 'end',
  }
}

};

See answered 22/1 at 12:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.