Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chart.js v2: How to make tooltips always appear on pie chart?

I have found similar questions in Stack Overflow, but all of them were addressed one and two years ago. Now Chart.js has come up in version 2, and lots of the documentation changes. Can someone please help me showing an example of pie chart with labels - or pie chart with all of its segment's tooltips are visible?

UPDATE

Thanks to @potatopeelings, his answer works perfectly for Chart.js v2.1.

Although I initially asked how to permanently show tooltips on pie chart here, I found a better solution: showing values as labels in percentages! It is now enabled for pie chart in Chart.js v2.1. In the chart options:

animation: {   duration: 0,   onComplete: function () {     var self = this,         chartInstance = this.chart,         ctx = chartInstance.ctx;      ctx.font = '18px Arial';     ctx.textAlign = "center";     ctx.fillStyle = "#ffffff";      Chart.helpers.each(self.data.datasets.forEach(function (dataset, datasetIndex) {         var meta = self.getDatasetMeta(datasetIndex),             total = 0, //total values to compute fraction             labelxy = [],             offset = Math.PI / 2, //start sector from top             radius,             centerx,             centery,              lastend = 0; //prev arc's end line: starting with 0          for (var val of dataset.data) { total += val; }           Chart.helpers.each(meta.data.forEach( function (element, index) {             radius = 0.9 * element._model.outerRadius - element._model.innerRadius;             centerx = element._model.x;             centery = element._model.y;             var thispart = dataset.data[index],                 arcsector = Math.PI * (2 * thispart / total);             if (element.hasValue() && dataset.data[index] > 0) {               labelxy.push(lastend + arcsector / 2 + Math.PI + offset);             }             else {               labelxy.push(-1);             }             lastend += arcsector;         }), self)          var lradius = radius * 3 / 4;         for (var idx in labelxy) {           if (labelxy[idx] === -1) continue;           var langle = labelxy[idx],               dx = centerx + lradius * Math.cos(langle),               dy = centery + lradius * Math.sin(langle),               val = Math.round(dataset.data[idx] / total * 100);           ctx.fillText(val + '%', dx, dy);         }      }), self);   } }, 
like image 962
Danny Avatar asked May 02 '16 22:05

Danny


People also ask

What is tooltip chart?

Overview. Tooltips are the labels that appear when users hover over data points on your chart. They generally appear across all ZingChart charts by default, and can display any combination of data values, text, and/or tokens.

Does chart js use canvas?

Chart. js charts are rendered on user provided canvas elements. Thus, it is up to the user to create the canvas element in a way that is accessible.


2 Answers

Solution for ChartJs Version > 2.1.5:

Chart.pluginService.register({   beforeRender: function (chart) {     if (chart.config.options.showAllTooltips) {         // create an array of tooltips         // we can't use the chart tooltip because there is only one tooltip per chart         chart.pluginTooltips = [];         chart.config.data.datasets.forEach(function (dataset, i) {             chart.getDatasetMeta(i).data.forEach(function (sector, j) {                 chart.pluginTooltips.push(new Chart.Tooltip({                     _chart: chart.chart,                     _chartInstance: chart,                     _data: chart.data,                     _options: chart.options.tooltips,                     _active: [sector]                 }, chart));             });         });          // turn off normal tooltips         chart.options.tooltips.enabled = false;     } },   afterDraw: function (chart, easing) {     if (chart.config.options.showAllTooltips) {         // we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once         if (!chart.allTooltipsOnce) {             if (easing !== 1)                 return;             chart.allTooltipsOnce = true;         }          // turn on tooltips         chart.options.tooltips.enabled = true;         Chart.helpers.each(chart.pluginTooltips, function (tooltip) {             tooltip.initialize();             tooltip.update();             // we don't actually need this since we are not animating tooltips             tooltip.pivot();             tooltip.transition(easing).draw();         });         chart.options.tooltips.enabled = false;     }   } }); 
like image 113
Fl0R1D3R Avatar answered Oct 02 '22 08:10

Fl0R1D3R


With the new Chart.js 2.1 you can write a plugin to do this and control it via an options property


Preview

enter image description here


Script

Note that you need to register the plugin before you initialize the chart

Chart.pluginService.register({     beforeRender: function (chart) {         if (chart.config.options.showAllTooltips) {             // create an array of tooltips             // we can't use the chart tooltip because there is only one tooltip per chart             chart.pluginTooltips = [];             chart.config.data.datasets.forEach(function (dataset, i) {                 chart.getDatasetMeta(i).data.forEach(function (sector, j) {                     chart.pluginTooltips.push(new Chart.Tooltip({                         _chart: chart.chart,                         _chartInstance: chart,                         _data: chart.data,                         _options: chart.options,                         _active: [sector]                     }, chart));                 });             });              // turn off normal tooltips             chart.options.tooltips.enabled = false;         }     },     afterDraw: function (chart, easing) {         if (chart.config.options.showAllTooltips) {             // we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once             if (!chart.allTooltipsOnce) {                 if (easing !== 1)                     return;                 chart.allTooltipsOnce = true;             }              // turn on tooltips             chart.options.tooltips.enabled = true;             Chart.helpers.each(chart.pluginTooltips, function (tooltip) {                 tooltip.initialize();                 tooltip.update();                 // we don't actually need this since we are not animating tooltips                 tooltip.pivot();                 tooltip.transition(easing).draw();             });             chart.options.tooltips.enabled = false;         }     } }); 

and then

new Chart(ctx, {     type: 'pie',     data: data,     options: {         showAllTooltips: true         ... 

With the older 2.x version, you should able to move the same (or similar, I'm not sure about the earlier data structure ) to the options.animation.onComplete


Fiddle - http://jsfiddle.net/q15ta78q/

like image 34
potatopeelings Avatar answered Oct 02 '22 09:10

potatopeelings