我有一个使用Chart.js的网页。在这个页面中,我正在渲染三个圆环图。在每个图表的中间,我想显示填充的甜甜圈的百分比。目前,我有以下代码,可在此Fiddle中看到。
function setupChart(chartId, progress) {
var canvas = document.getElementById(chartId);
var context = canvas.getContext('2d');
var remaining = 100 - progress;
var data = {
labels: [ 'Progress', '', ],
datasets: [{
data: [progress, remaining],
backgroundColor: [
'#8FF400',
'#FFFFFF'
],
borderColor: [
'#8FF400',
'#408A00'
],
hoverBackgroundColor: [
'#8FF400',
'#FFFFFF'
]
}]
};
var options = {
responsive: true,
maintainAspectRatio: false,
scaleShowVerticalLines: false,
cutoutPercentage: 80,
legend: {
display: false
},
animation: {
onComplete: function () {
var xCenter = (canvas.width / 2) - 20;
var yCenter = canvas.height / 2 - 40;
context.textAlign = 'center';
context.textBaseline = 'middle';
var progressLabel = data.datasets[0].data[0] + '%';
context.font = '20px Helvetica';
context.fillStyle = 'black';
context.fillText(progressLabel, xCenter, yCenter);
}
}
};
Chart.defaults.global.tooltips.enabled = false;
var chart = new Chart(context, {
type: 'doughnut',
data: data,
options: options
});
}
图表"运行"。但问题在于标签的渲染。标签不是在甜甜圈中间垂直和水平居中。标签的位置也会根据屏幕分辨率而变化。您可以通过调整图表在Fiddle内呈现的框架来查看标签更改位置。
我的问题是,我如何始终将百分比定位在甜甜圈中间?我的页面是一个响应式页面,所以具有一致的定位很重要然而,我不知道还能做什么。我觉得textAlign
和textBaseline
属性不起作用,或者我误解了它们的用法。
谢谢!
答案 0 :(得分:4)
根据this answer,您可以使用其他版本的插件执行此操作。我不知道你是否注意到了,但是如果你增加宽度并在你的小提琴上一遍又一遍地减少它,你的画布的高度会变得越来越大(图表越走越远)。
在您使用的版本上,您可以像这样扩展doughnut
控制器:
http://jsfiddle.net/ivanchaer/cutkqkuz/1/
Chart.defaults.DoughnutTextInside = Chart.helpers.clone(Chart.defaults.doughnut);
Chart.controllers.DoughnutTextInside = Chart.controllers.doughnut.extend({
draw: function(ease) {
var ctx = this.chart.chart.ctx;
var data = this.getDataset();
var easingDecimal = ease || 1;
Chart.helpers.each(this.getDataset().metaData, function(arc, index) {
arc.transition(easingDecimal).draw();
var vm = arc._view;
var radius = (vm.outerRadius + vm.innerRadius) / 2;
var thickness = (vm.outerRadius - vm.innerRadius) / 2;
var angle = Math.PI - vm.endAngle - Math.PI / 2;
ctx.save();
ctx.fillStyle = vm.backgroundColor;
ctx.font = "20px Verdana";
ctx.textAlign = 'center';
ctx.textBaseline = "middle";
var text = data.data[0] + '%';
ctx.fillStyle = '#000';
ctx.fillText(text, $(ctx.canvas).width()/2, $(ctx.canvas).height()/2);
});
ctx.fillStyle = '#fff';
ctx.fill();
ctx.restore();
}
});
function setupChart(chartId, progress) {
var canvas = document.getElementById(chartId);
var context = canvas.getContext('2d');
var remaining = 100 - progress;
var deliveredData = {
labels: [
"Value"
],
datasets: [{
data: [progress, remaining],
backgroundColor: [
'#8FF400',
'#FFFFFF'
],
borderColor: [
'#8FF400',
'#408A00'
],
hoverBackgroundColor: [
'#8FF400',
'#FFFFFF'
]
}]
};
var deliveredOpt = {
cutoutPercentage: 88,
animation: false,
legend: {
display: false
},
tooltips: {
enabled: false
}
};
var chart = new Chart(canvas, {
type: 'DoughnutTextInside',
data: deliveredData,
options: deliveredOpt
});
}
setupChart('standChart', 33);
setupChart('moveChart', 66);
setupChart('exerciseChart', 99);
答案 1 :(得分:2)
请参阅此http://jsfiddle.net/uha5tseb/2/
可以通过此参考
获取每个图表的宽度/高度来处理 onComplete: function (event) {
console.log(this.chart.height);
var xCenter = this.chart.width/2;
var yCenter = this.chart.height/2;
context.textAlign = 'center';
context.textBaseline = 'middle';
var progressLabel = data.datasets[0].data[0] + '%';
context.font = '20px Helvetica';
context.fillStyle = 'black';
context.fillText(progressLabel, xCenter, yCenter);
}
希望这能解决你的问题!
答案 2 :(得分:2)
获取xCenter和yCenter时,无法正确设置变量。目前他们没有得到画布的中间部分。
你有:
var xCenter = (canvas.width / 2) - 20;
var yCenter = canvas.height / 2 - 40;
应该是:
var xCenter = (canvas.width / 2);
var yCenter = (canvas.height / 2);
答案 3 :(得分:0)
我不熟悉chart.js,但据我从文档中了解,他们为您的目的提供了 generateLegend 方法。它返回来自 legendCallback 的数据,您可以在画布外的页面上显示该数据。
图例文本的容器可以相对于画布的包装器对齐。
HTML:
<div class="chart" data-legend="">
<canvas id="standChart"></canvas>
</div>
JS:
var container = canvas.parentElement;
...
container.setAttribute('data-legend', chart.generateLegend());
答案 4 :(得分:0)
解决此问题的一种方法是在画布顶部添加绝对定位的元素。
您可以在每个canvas元素后添加div元素,然后将其样式设置为:
.precentage {
font-family: tahoma;
font-size: 28px;
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
}
这是一个完整的JSFiddle。
答案 5 :(得分:-1)
We Give Size of the Chart Can be with in the Chart And Align to center on the Give the hight width based on the Chart Hight and Width..
i will make simple change in Your Jsfiddle
..
xcenter and y center with the half distence for chart..
[http://jsfiddle.net/uha5tseb/10/][1]