64

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'
        ]
      }]
    };
Tot Zam
  • 8,406
  • 10
  • 51
  • 76
RamAlx
  • 6,976
  • 23
  • 58
  • 106

6 Answers6

160

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/

Tot Zam
  • 8,406
  • 10
  • 51
  • 76
  • 1
    `data['datasets'][tooltipItem.datasetIndex]['data'][tooltipItem.index]` as we also have the dataSet index. – dNurb Feb 11 '19 at 20:30
  • 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 (https://github.com/jerairrest/react-chartjs-2/issues/450) – Luca Davanzo Oct 24 '19 at 15:04
  • If you want the dataset label as the title: `data['datasets'][tooltipItem[0].datasetIndex].label` – Sondre Nov 09 '20 at 07:36
  • 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. – Andrew Jan 15 '21 at 16:22
  • 1
    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']` – Olcay Jun 16 '21 at 13:50
  • 1
    And for V3.5? This totally changed. – Izzi Sep 09 '21 at 07:09
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
    }
  }
}
Merenzo
  • 5,326
  • 4
  • 31
  • 46
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"
      }
    },
  },
},
Jayanth Kumar T
  • 308
  • 4
  • 9
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
            },
          },
        },
      },
    },
Dharman
  • 30,962
  • 25
  • 85
  • 135
Sideshowlol
  • 131
  • 1
  • 5
2

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;
        }
      }
Tuhin
  • 21
  • 3
2

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>