I'm using the awesome plugin Chart.js, and I'm trying to find the way of display labels within each percentage. So I googled it, and I found this pull: https://github.com/nnnick/Chart.js/pull/35
I did a simple fiddle to test it, but doesn't works: http://jsfiddle.net/marianico2/7ktug/1/
This is the content:
HTML
<canvas id="canvas" height="450" width="450"></canvas>
JS
$(document).ready(function () {
var pieData = [{
value: 30,
color: "#F38630",
label: 'HELLO',
labelColor: 'black',
labelFontSize: '16'
}, {
value: 50,
color: "#E0E4CC"
}, {
value: 100,
color: "#69D2E7"
}];
var myPie = new Chart(document.getElementById("canvas").getContext("2d")).Pie(pieData, {
labelAlign: 'center'
});
});
I'm afraid there is no information about this in the documentation.
Also I'd like to know how to display a label for each portion, but outside the chart. Linked by a line. As do the charts of highcharts.js.
By the way, I'd be glad if you recommend me an html5 chart alternative which includes the options I said above. I've heard about the flot plugin, but I'm afraid does not support animations...
If you need more info, let me know and I'll edit the post.
You'll have to add code in 2 places. As an example, take the doughnut. First add label info to the defaults (look at the original Chart.js code and compare with this):
chart.Doughnut.defaults = { segmentShowStroke : true, segmentStrokeColor : "#fff", segmentStrokeWidth : 2, percentageInnerCutout : 50, animation : true, animationSteps : 100, animationEasing : "easeOutBounce", animateRotate : true, animateScale : false, onAnimationComplete : null, labelFontFamily : "Arial", labelFontStyle : "normal", labelFontSize : 24, labelFontColor : "#666" };
Then go down to where the Doughnut is drawn and add the four ctx
lines.
animationLoop(config,null,drawPieSegments,ctx); function drawPieSegments (animationDecimal){ ctx.font = config.labelFontStyle + " " + config.labelFontSize+"px " + config.labelFontFamily; ctx.fillStyle = 'black'; ctx.textBaseline = 'middle'; ctx.fillText(data[0].value + "%", width/2 - 20, width/2, 200);
The ctx.fillText
call will put the text onto the canvas, so you can use that to write text with x,y coordinates. You ought to be able to use this way to do basic labels. Here is the jsfiddle to tinker with:
http://jsfiddle.net/nCFGL/ (look at lines 281 and 772 in the JavaScript section of the jsfiddle for aforementioned code)
If you need something fancier, someone forked a version of Charts.js and added tooltips. Here is the discussion https://github.com/nnnick/Chart.js/pull/35, and you'll be able to find the link to the forked version inside that discussion.
This one literally took hours and hours and I found a working solution.
https://github.com/nnnick/Chart.js/pull/116
This was my final code. I was trying to display percentages as labels on doughnut
Chart.types.Doughnut.extend({ name: "DoughnutAlt", draw: function() { Chart.types.Doughnut.prototype.draw.apply(this, arguments); this.chart.ctx.fillStyle = 'black'; this.chart.ctx.textBaseline = 'middle'; this.chart.ctx.textAlign = 'start'; this.chart.ctx.font="18px Verdana"; var total = 0; for (var i = 0; i < this.segments.length; i++) { total += this.segments[i].value; } this.chart.ctx.fillText(total , this.chart.width / 2 - 20, this.chart.height / 2, 100); for(var i = 0; i < this.segments.length; i++){ var percentage = ((this.segments[i].value / total) * 100).toFixed(1); if( percentage > 3 ){ var centreAngle = this.segments[i].startAngle + ((this.segments[i].endAngle - this.segments[i].startAngle) / 2), rangeFromCentre = (this.segments[i].outerRadius - this.segments[i].innerRadius) / 2 + this.segments[i].innerRadius; var x = this.segments[i].x + (Math.cos(centreAngle) * rangeFromCentre); var y = this.segments[i].y + (Math.sin(centreAngle) * rangeFromCentre); this.chart.ctx.textAlign = 'center'; this.chart.ctx.textBaseline = 'middle'; this.chart.ctx.fillStyle = '#fff'; this.chart.ctx.font = 'normal 10px Helvetica'; this.chart.ctx.fillText(percentage , x, y); } } } });
There is an forked version, ChartNew, that provides this functionality out of the box.
If you need to use ChartJS then you can use this revised version of @Jack's solution:
Chart.types.Doughnut.extend({
name: "DoughnutAlt",
draw: function() {
Chart.types.Doughnut.prototype.draw.apply(this, arguments);
this.chart.ctx.fillStyle = 'black';
this.chart.ctx.textBaseline = 'middle';
this.chart.ctx.fillText(this.segments[0].value + "%", this.chart.width / 2 - 20, this.chart.width / 2, 200);
}
});
I have figured out a way so that we can display the values for each region out side the graph.
Also I removed the rotation of the values and I referred to here
Add the following lines of code inside the Doughnut function. ( I have pasted the modified lines from the Chart.js file).
var Doughnut = function(data,config,ctx){
var segmentTotal = 0;
//In case we have a canvas that is not a square. Minus 10 pixels as padding round the edge.
var doughnutRadius = Min([height/2,width/2]) - 15;
var cutoutRadius = doughnutRadius * (config.percentageInnerCutout/100);
//Modified for setting the label values out side the arc
var outRadius= doughnutRadius + cutoutRadius/3;
var outRadiustop= doughnutRadius + cutoutRadius/5;
......
......
......
function drawPieSegments (animationDecimal){
:
:
if (config.scaleShowValues) {
ctx.save();
ctx.translate(width / 2, height / 2);
ctx.font = config.scaleFontStyle + ' ' + config.scaleFontSize + 'px ' + config.scaleFontFamily;
ctx.textBaselne = 'middle';
var a = (cumulativeAngle + cumulativeAngle + segmentAngle) / 2,
w = ctx.measureText(data[i].value).width,
b = Math.PI / 2 < a && a < Math.PI * 3 / 2;
var c = 0 < a && a < Math.PI;
if(b){
ctx.textAlign = 'right';
}
else{
ctx.textAlign = 'left';
}
if(c){
ctx.translate(Math.cos(a) * outRadius +1 , Math.sin(a) * outRadius+1);
}
else{
ctx.translate(Math.cos(a) * outRadiustop, Math.sin(a) * outRadiustop);
}
ctx.fillStyle = config.scaleFontColor;
//If the segment angle less than 0.2, then the lables will overlap, so hiding it.
if(segmentAngle > 0.2){
ctx.fillText(data[i].value,0,0);
}
ctx.restore();
}
......
......
Now the values will be displayed out side each sections and it will not be rotated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With