Как добавить метки в плагин Chart.js canvas?
Я использую awesome plugin Chart.js, и я пытаюсь найти способ отображать метки в каждом проценте. Поэтому я искал ее в googled, и я нашел это притяжение: https://github.com/nnnick/Chart.js/pull/35
Я попробовал протестировать его, но не работает: http://jsfiddle.net/marianico2/7ktug/1/
Это содержимое:
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'
});
});
Я боюсь, что в документации нет информации об этом.
Также я хотел бы знать, как отображать метку для каждой части, но вне диаграммы. Связан с линией. Как и диаграммы highcharts.js.
Кстати, я был бы рад, если вы порекомендуете мне альтернативу html5, которая включает в себя варианты, которые я сказал выше. Я слышал о плагине flot, но, боюсь, не поддерживает анимацию...
Если вам нужна дополнительная информация, дайте мне знать, и я отредактирую сообщение.
Ответы
Ответ 1
Вам нужно добавить код в 2 места. В качестве примера возьмите пончик. Сначала добавьте информацию метки в значения по умолчанию (посмотрите на исходный код Chart.js и сравните с этим):
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"
};
Затем спуститесь туда, где вырисовывается пончик, и добавьте четыре строки ctx
.
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);
Вызов ctx.fillText
помещает текст в холст, поэтому вы можете использовать его для записи текста с координатами x, y. Вы должны использовать этот способ для создания основных меток. Вот jsfiddle, чтобы возиться с:
http://jsfiddle.net/nCFGL/ (посмотрите строки 281 и 772 в разделе JavaScript jsfiddle для вышеупомянутого кода)
Если вам нужно что-то более интересное, кто-то разветкил версию Charts.js и добавил всплывающие подсказки. Вот обсуждение https://github.com/nnnick/Chart.js/pull/35, и вы сможете найти ссылку на разветвленную версию внутри этого обсуждения.
Ответ 2
Это буквально занимало часы и часы, и я нашел рабочее решение.
https://github.com/nnnick/Chart.js/pull/116
Это был мой последний код. Я пытался отображать проценты в качестве меток на пончике
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);
}
}
}
});
Ответ 3
Я понял способ, чтобы мы могли отображать значения для каждого региона вне графика.
Также я удалил поворот значений, и я упомянул здесь
Добавьте следующие строки кода внутри функции Donut. (Я вставил модифицированные строки из файла Chart.js).
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();
}
......
......
Теперь значения будут отображаться на каждой секции и не будут вращаться.
Ответ 4
Существует версия forked, ChartNew, которая предоставляет эту функциональность из коробки.
Если вам нужно использовать ChartJS, вы можете использовать эту пересмотренную версию
Решение @Jack:
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);
}
});