[Chartjs]-Chartjs show hidden data on tooltip

1👍

If you hide all bars except one, you can define a tooltips.callback function for label. This function collects the labels and appropriate values from all datasets using Array.map() and returns a string array.

tooltips: {
  callbacks: {
    label: (tooltipItem, chart) => dataSets.datasets.map(ds => ds.label + ': ' + ds.data[tooltipItem.index])
  }
},

Please have a look at your amended code below:

var ds1 = [], ds2 = [], ds3 = [], ds4 = [], ds5 = [], ds6 = [], labels = [];

for (var i = 0; i < 2; i++) {
  labels.push('Label: ' + i);
  ds1.push(i);
  ds2.push(i + 1);
  ds3.push(i + 2);
  ds4.push(i + 3);
  ds5.push(i + 4);
  ds6.push(5 * i + 10);
};

const dataSets = {
  labels: labels,
  datasets: [{
    label: 'First Label',
    hidden: true,
    data: ds1
  }, {
    label: 'Second Label',
    hidden: true,
    data: ds2
  }, {
    label: 'Third Label',
    hidden: true,
    data: ds3
  }, {
    label: 'Fourth Label',
    hidden: true,
    data: ds4
  }, {
    label: 'Fifth Label',
    hidden: true,
    data: ds5
  }, {
    label: 'Totals',
    data: ds6
  }]
};

var myChart = new Chart('myChart', {
  type: 'horizontalBar',
  responsive: true,
  data: dataSets,
  elements: {
    rectangle: {
      borderWidth: 2
    }
  },
  options: {
    legend: {
      display: false
    },
    title: {
      display: false
    },
    tooltips: {
      callbacks: {
        label: (tooltipItem, chart) => dataSets.datasets.map(ds => ds.label + ': ' + ds.data[tooltipItem.index])
      }
    },
    scales: {
      xAxes: [{
        ticks: {
          min: 0,
          stepSize: 1
        }
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="100"></canvas>

If you wanted to display the legend and allow users to show additional bars through a mouse click on individual legend labels, the callback function would be invoked once for each visible bar. Therefore you would have to make sure to return the labels array only once and return null in all other cases. The following code would return the labels array only for the ‘Totals’ bar.

tooltips: {
  callbacks: {
    label: (tooltipItem, chart) => {
      if (tooltipItem.datasetIndex == dataSets.datasets.length - 1) {
        return dataSets.datasets.map(ds => ds.label + ': ' + ds.data[tooltipItem.index]);
      }
      return null;
    }
  }
},

This would not work however, if the user decides to hide the ‘Totals’ bar. The code could however be improved to also overcome this limitation.

Leave a comment