Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Label inside donut chart #78

Closed
jomarmen opened this issue Apr 17, 2013 · 85 comments
Closed

Label inside donut chart #78

jomarmen opened this issue Apr 17, 2013 · 85 comments

Comments

@jomarmen
Copy link

Hi,

I would like to be able to add a label inside a donut chart like this charts

lnDId

Thks

@helmund
Copy link

helmund commented Apr 22, 2013

me too +1

@battaglr
Copy link

+1

3 similar comments
@ax003d
Copy link

ax003d commented May 8, 2013

+1

@dibba
Copy link

dibba commented Jun 4, 2013

+1

@michelreyes
Copy link

+1

@nnnick
Copy link
Member

nnnick commented Jun 5, 2013

Would putting this data in an HTML absolutely positioned element over the top of the doughnut not be a better solution than adding more to chart.js to achieve this?

@fizerkhan
Copy link
Contributor

+1

@jcutrell
Copy link

jcutrell commented Jul 7, 2013

It's fairly easy to do this with HTML, but it would be nice if the chart exposed some sort of event API to hook into to populate the value.

@bissy
Copy link

bissy commented Jul 10, 2013

+1

1 similar comment
@SteveD11
Copy link

+1

@J5Dev
Copy link

J5Dev commented Jul 20, 2013

+1

Although, as well as a label I think it would also be good to have it auto add the sum-total of the data put in, or the data type etc

I may work on a way to pass this in if I get the chance this week, though doing the total automatically shouldn't be too much of a stretch.

@deanhume
Copy link

+1

@ghost
Copy link

ghost commented Jan 2, 2014

is there any option to write label for each section?

@erikthedeveloper
Copy link

+1

Yes, this can be accomplished easily with HTML, but I would love to see something like this implemented into the core.

@joetime
Copy link

joetime commented Jan 9, 2014

+1

1 similar comment
@carlosrymer
Copy link

+1

@hutber
Copy link

hutber commented Mar 9, 2014

+2

@marcj
Copy link

marcj commented Mar 9, 2014

+3

@fulldecent
Copy link
Contributor

-1 I think the HTML approach is better. The label will only make sense inside the canvas if it is very small.

I would consider these to be a special-purpose of pie chart: single value pie charts with label in the middle.

Recommending implementation should be outside chart.js

@joetime
Copy link

joetime commented Sep 15, 2014

@fulldecent The advantage to having a label/legend built into the chart is that the user can take the image itself and use it in another doc or presentation without having to re-create the legend. In fact, for my users, this is an absolute requirement - a chart without a legend is useless to them.
Whether that should be within the scope of chart.js is debatable, but I would guess there are many devs that would agree with me on this one. I could be wrong though.

@304NotModified
Copy link

+1

1 similar comment
@andqwerty
Copy link

+1

@fulldecent
Copy link
Contributor

tagging: NEW CHART TYPES

@fixanoid
Copy link

This may be useful for some of you since I've had the same requirement a few weeks ago.
https://github.com/fixanoid/Pretty-Doughtnut

@kiquenet
Copy link

@heyallan
Copy link

+1

@tannerlinsley
Copy link
Contributor

I don't think having a label in the middle of the chart is quite yet needed in the core logic of chartjs. We will probably soon be adding new event-hook-like api's into the core though, that would allow you to achieve this quite easily in a custom implementation along with a lot of other things.

@etimberg etimberg added this to the Version 2.7 milestone May 21, 2017
@alrms
Copy link

alrms commented Jun 26, 2017

How to implement something like this?
untitled

I edited the plugin but it's not absolutely correct:
Chart.pluginService.register({
afterDraw(chart) {
if (chart.center) {
const centerConfig = chart.config.options.elements.center;
const ctx = chart.chart.ctx;
ctx.save();
ctx.font = chart.center.font;
ctx.fillStyle = chart.center.fillStyle;
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
const centerX = (chart.chartArea.left + chart.chartArea.right);
const centerY = (chart.chartArea.top + chart.chartArea.bottom);
ctx.fillText(centerConfig.text, centerX, centerY);
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
const centerXnumb = (chart.chartArea.left + chart.chartArea.right) / 2;
const centerYnumb = (chart.chartArea.top + chart.chartArea.bottom) / 2.4;
ctx.fillText(centerConfig.textNumber, centerXnumb, centerYnumb);
ctx.restore();
}
}
});

It is displayed something like this:
cxzcxzczx
The options is:
elements: {
center: {
textNumber: ${sectorsCounter},
text: intl.formatMessage({ id: 'pie.sectors' }),
fontColor: '#656566',
fontFamily: 'EurobankSans',
fontStyle: 'normal',
minFontSize: 25,
maxFontSize: 25,
}
},

@dhniels
Copy link

dhniels commented Jul 10, 2017

I added the center label easily with an absolute positioned HTML element, though having this feature natively to ChartJS would be cool. What brought me here and what I'm really pining for is something like @dannysindra 's example of having percentage labels (or even just having the tooltips always on) inside each area of the chart. I've tried implementing it in our Angular app but am having trouble. A built in solution to do this seems like a no-brainer. Add my voice to that feature request!

@dhniels
Copy link

dhniels commented Jul 11, 2017

@emn178 just tried your solution and its working! you are awesome!

@MatthewSwarbrick
Copy link

to get this working I extended the draw function for Chart,Tooltip with the following:

    if (this._chart.options.tooltips.displayPercentage) {
        var activeChart = this._chart;
	var cx = activeChart.width / 2;
	var cy = activeChart.chartArea.top + ((activeChart.height - activeChart.chartArea.top) / 2);
	ctx.textAlign = 'center';
	ctx.textBaseline = 'middle';
	ctx.font = '28px Arial';
	ctx.fillStyle = "#63666A";

	var total = _.sum(activeChart.data.datasets[0].data);
	var percent = 100 * activeChart.data.datasets[0].data[vm.dataPoints[0].index] / total;
	ctx.fillText(Math.round(percent) + "%", cx, cy);
    }

You can now add on the options for tooltip whether to display percentage or not, and it'll appear in the center when hovering. The sum calculation is using lodash, this could be a simple function

@Ashnarya
Copy link

Hi,
I've tried all the possibilities to make tooltip visible always. But nothing works.
Kindly help to fix this, The data is passed as a string which is fetched from database.

var ctx2 = document.getElementById("PieChart2");
var options = {
title: {
display: true,
maintainAspectRatio: true,
responsive: false,
text: 'Predicted risks from Data'
},
events: [],
animation: {
duration: 0,
onComplete: function () {
var self = this;

          var elementsArray = [];
          Chart.helpers.each(self.data.datasets, function (dataset, datasetIndex) {
              Chart.helpers.each(dataset.metaData, function (element, index) {
                  var tooltip = new Chart.Tooltip({
                      _chart: self.chart,
                      _chartInstance: self,
                      _data: self.data,
                      _options: self.options,
                      _active: [element]
                  }, self);

                  tooltip.update();
                  tooltip.transition(Chart.helpers.easingEffects.linear).draw();
              }, self);
          }, self);
        }
      }
};
	var scatterChart = new Chart(ctx2, {
	    type: 'pie',
	    data: {
	    	labels: [${piePlot2.age}],
	        datasets: [{
	        	backgroundColor: [
	        		
	        		"#ff6969",
	        		"#ffb4b4",
	        		"red",
	        		"#ff2d2d"
	        		
	              ],
	            data: [<c:out value='${piePlot2.result}'/>]
	        }]
	    }
	});

image

When hovering, it is displays the data. But i want it be appeared always. Any help!

Thanks in Advance!

@pachos7
Copy link

pachos7 commented Sep 8, 2017

+1

@Nothenn
Copy link

Nothenn commented Oct 10, 2017

Any news on whether this is being still being worked on or planned for a release as I noticed it has been added and removed to milestones multiples times.

@sadikyalcin
Copy link

sadikyalcin commented Nov 9, 2017

@ShawnCorrigan that is excellent as it's responsive.

Edit: actually found an issue with this. Destroy / re adding the chart - the text keeps on adding on and get's blurry.

@iratierana
Copy link

Any of this solutions is working on my code, can someone help me?

Here is the HTML code:
<div id="canvas-holder" style="width:18%"> <canvas id="chart-area" /> </div>

and javascript code:
var confi2 = { type: 'doughnut', data: { datasets: [{ data: [ "33.33333", "33.33333", "33.33333", ], backgroundColor: [ "#FFFFFF", "#009688", "#FFFFFF", ], }, { data: [ "64", "36", ], backgroundColor: [ "#F41616", "#FFFFFF", ], },{ data: [ "111", ], backgroundColor: [ "#948F8F", ], }] }, options: { responsive: true, } };
var ctx = document.getElementById("chart-area").getContext("2d"); window.myDoughnut = new Chart(ctx, confi2);

Thank you on advise

@abhinav1602
Copy link

abhinav1602 commented Feb 21, 2018

Here is what worked for me. Thanks to google and such a great community out there. 😄 : CLOSED

//Plugin for center text
Chart.pluginService.register({
  beforeDraw: function(chart) {
    var width = chart.chart.width,
    height = chart.chart.height,
    ctx = chart.chart.ctx;
    ctx.restore();
    var fontSize = (height / 160).toFixed(2);
    ctx.font = fontSize + "em sans-serif";
    ctx.textBaseline = "top";
    var text = "Foo-bar",
    textX = Math.round((width - ctx.measureText(text).width) / 2),
    textY = height / 2;
    ctx.fillText(text, textX, textY);
    ctx.save();
  }
});

So what it actually does is, it takes the height, width of the chart and then places the desired text at half the height and width of your chart. You don't have to worry about the responsiveness and changing size(handled similarly) of the chart. Its completely dynamic this way.

@gabarreto
Copy link

I have almost no experience with JavaScript, and I need to put a FontAwesome icon inside the doughnut chart. It would be a chart to show the temperature, and the thermometer icon should be in it's middle. Could anyone help me?

@fernandocode
Copy link

@gabarreto Here is not the best place to ask questions about implementation. I recommend creating a question in StackOveflow with the tag chart.js.

@gbrits
Copy link

gbrits commented May 5, 2018

To expand on the plugin provided by @abhinav1602 to center text, I did the following to show percentage on my doughnut charts:

// Just copy and paste this bit above your chart inits. It will only apply to doughnuts.
Chart.pluginService.register({
  beforeDraw: function(chart) {
    if(chart.chart.chart.config.type=='doughnut'){
      var width = chart.chart.width,
      height = chart.chart.height,
      ctx = chart.chart.ctx;
      ctx.restore();
      var fontSize = (height / 160).toFixed(2);
      ctx.font = fontSize + "em sans-serif";
      ctx.textBaseline = "top";
      // Ensure your first data is the percentage data in your dataset
      var chart_percent = chart.chart.chart.data.datasets[0].data[0];
      chart_percent = chart_percent || 0;
      var text = chart_percent+'%',
      textX = Math.round((width - ctx.measureText(text).width) / 2),
      textY = height / 2;
      ctx.fillText(text, textX, textY);
      ctx.save();
    }
  }
});

An example of my usage:

this.doughnutChart1 = new Chart(this.doughnutCanvas1.nativeElement, {
  type: 'doughnut',
  data: {
    datasets: [{
        // So this donut is 75% as per the first data item (will reflect with the txt plugin)
        data: [75,25],
        borderWidth: 0,
        backgroundColor: [
            '#67bebf',
            '#caced5',
        ],
        hoverBackgroundColor: [
            "#67bebf",
            "#caced5",
        ]
    }]
  },
  options: {
    cutoutPercentage: 90
  }
});

@ciprianciurea
Copy link

ciprianciurea commented May 23, 2018

I've added a new plugin that allows to display multiple lines of text in the center of the doughnut on Github: chartjs-plugin-doughnutlabel if that helps. See the Demo.
image

@natibs
Copy link

natibs commented Aug 19, 2018

To place the text in the center, you need to consider the size of the font size. another fix for the solution of gbrits. in the textY `object:

textY = (height / 2) - (fontSize * 16 / 2)

@simonbrunel
Copy link
Member

I'm going to close this issue since many solutions exist now and maintainers decided to not add it to the core package. I think the best approach is to use a plugin such as chartjs-plugin-doughnutlabel (thanks @ciprianciurea) and at some point, the datalabels plugin may also offer a (limited) way to center labels.

@ciprianciurea feel free to open a PR adding it to the docs.

@DevOpsBandhala
Copy link

Below the code work for me, but in the centre text (100%) appearing in another chart in same page !.

Chart.pluginService.register({
                        beforeDraw: function(chart) {
                          var width = chart.chart.width,
                          height = chart.chart.height,
                          ctx = chart.chart.ctx;
                          ctx.restore();
                          var fontSize = (height / 160).toFixed(2);
                          ctx.font = fontSize + "em sans-serif";
                          ctx.textBaseline = "top";
                          var text = "100%",
                          textX = Math.round((width - ctx.measureText(text).width) / 2),
                          textY = height / 2;
                          ctx.fillText(text, textX, textY);
                          ctx.save();
                        }
                      });

@mesqueeb
Copy link

mesqueeb commented Apr 9, 2024

Does anyone have an updated plugin for center doughnut labels for chartJS v4?

@stockiNail
Copy link
Contributor

Does anyone have an updated plugin for center doughnut labels for chartJS v4?

AFAIK there isn't. There is a pending PR in chartjs-plugin-annotation for that: chartjs/chartjs-plugin-annotation#825

@Kinqdos
Copy link

Kinqdos commented Sep 5, 2024

Can you please reopen this issue? Seems like no one cares about the plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests