Chart.js甜甜圈圆边和文本居中 [英] Chart.js Doughnut with rounded edges and text centered
问题描述
我正在尝试实现类似于本文
脚本
//圆角
Chart.pluginService.register({
afterUpdate:function (chart){
if(chart.config.options.elements.arc.roundedCornersFor!== undefined){
var arc = chart.getDatasetMeta(0).data [chart.config.options.elements .arc.roundedCornersFor];
arc.round = {
x:(chart.chartArea.left + chart.chartArea.right)/ 2,
y:(chart.chartArea.top + chart。 chartArea.bottom)/ 2,
radius:(chart.outerRadius + chart.innerRadius)/ 2,
th ickness:(chart.outerRadius - chart.innerRadius)/ 2 - 1,
backgroundColor:arc._model.backgroundColor
}
}
},
afterDraw:function(chart){
if(chart.config.options.elements.arc.roundedCornersFor!== undefined){
var ctx = chart.chart.ctx;
var arc = chart.getDatasetMeta(0).data [chart.config.options.elements.arc.roundedCornersFor];
var startAngle = Math.PI / 2 - arc._view.startAngle;
var endAngle = Math.PI / 2 - arc._view.endAngle;
ctx.save();
ctx.translate(arc.round.x,arc.round.y);
console.log(arc.round.startAngle)
ctx.fillStyle = arc.round.backgroundColor;
ctx.beginPath();
ctx.arc(arc.round.radius * Math.sin(startAngle),arc.round.radius * Math.cos(startAngle),arc.round.thickness,0,2 * Math.PI);
ctx.arc(arc.round.radius * Math.sin(endAngle),arc.round.radius * Math.cos(endAngle),arc.round.thickness,0,2 * Math.PI);
ctx.closePath();
ctx.fill();
ctx.restore();
}
},
});
//写入文本插件
Chart.pluginService.register({
afterUpdate:function(chart){
if(chart.config.options.elements.center ){
var helpers = Chart.helpers;
var centerConfig = chart.config.options.elements.center;
var globalConfig = Chart.defaults.global;
var ctx = chart.chart.ctx;
var fontStyle = helpers.getValueOrDefault(centerConfig.fontStyle,globalConfig.defaultFontStyle);
var fontFamily = helpers.getValueOrDefault(centerConfig.fontFamily,globalConfig.defaultFontFamily);
if(centerConfig.fontSize)
var fontSize = centerConfig.fontSize;
//找出最佳字体大小(如果没有指定)
else {
ctx.save();
var fontSize = helpers.getValueOrDefault(centerConfig.minFontSize,1);
var maxFontSiz e = helpers.getValueOrDefault(centerConfig.maxFontSize,256);
var maxText = helpers.getValueOrDefault(centerConfig.maxText,centerConfig.text);
do {
ctx.font = helpers.fontString(fontSize,fontStyle,fontFamily);
var textWidth = ctx.measureText(maxText).width;
//检查它是否合适,是否在配置的限制内,并且我们不是简单地来回切换
if(textWidth< chart.innerRadius * 2&& fontSize< maxFontSize)
fontSize + = 1;
else {
//倒退上一步
fontSize - = 1;
休息;
} while(true)
ctx.restore();
$ b $ //保存属性
chart.center = {
字体:helpers.fontString(fontSize,fontStyle,fontFamily),
fillStyle:helpers .getValueOrDefault(centerConfig.fontColor,globalConfig.defaultFontColor)
};
afterDraw:function(chart){
if(chart.center){
var centerConfig = chart.config.options.elements.center;
var ctx = chart.chart.ctx;
ctx.save();
ctx.font = chart.center.font;
ctx.fillStyle = chart.center.fillStyle;
ctx.textAlign ='center';
ctx.textBaseline ='middle';
var centerX =(chart.chartArea.left + chart.chartArea.right)/ 2;
var centerY =(chart.chartArea.top + chart.chartArea.bottom)/ 2;
ctx.fillText(centerConfig.text,centerX,centerY);
ctx.restore();
}
},
})
然后 p>
...
选项:{
元素:{
arc:{
roundedCornersFor:0
},
center:{
//可以出现在中心的最长文字
maxText:'100%',
text:'67 %',
fontColor:'#FF6684',
fontFamily:''Helvetica Neue','Helvetica','Arial',sans-serif,
fontStyle:'normal',
// fontSize:12,
//如果未指定fontSize,我们将缩放(在下限内)maxText占据中心的最大空间
//如果它们是未指定,我们默认为1和256
minFontSize:1,
maxFontSize:256,
}
}
}
};
如果你不希望它是通用的,你可以去掉一些代码。如果你修正了fontSize,如果你修复了索引等等)
小提琴 - http://jsfiddle.net/cd3fdoy9/
I am trying to achieve rounded corners similar to this article here, but combined with text in the centre, so far i have the code below, but i am not sure how to combine both ideas
Any help would be appreciated!
the image looks like below, donut with text image:
and my code is as follows to produce the text inside the donut.
Chart.types.Doughnut.extend({
name: "DoughnutTextInside",
showTooltip: function() {
this.chart.ctx.save();
Chart.types.Doughnut.prototype.showTooltip.apply(this, arguments);
this.chart.ctx.restore();
},
draw: function() {
Chart.types.Doughnut.prototype.draw.apply(this, arguments);
var width = this.chart.width,
height = this.chart.height;
var fontSize = (height / 114).toFixed(2);
this.chart.ctx.font = fontSize + "em Lato";
this.chart.ctx.textBaseline = "middle";
var text = "40%",
textX = Math.round((width - this.chart.ctx.measureText(text).width) / 2),
textY = height / 2;
this.chart.ctx.fillText(text, textX, textY);
}
});
var data = [{
label: "Wins %",
value: 120,
color: "#2ecc71"
}, {
label: "Losses %",
value: 240,
color: "#dddddd"
}, {
value: 0,
color: "#888888"
}];
var DoughnutTextInsideChart = new Chart($('#myChart') [0].getContext('2d')).DoughnutTextInside(data, {
responsive: true,
segmentShowStroke: false,
animationEasing: "easeInOutQuint",
});
With v2.1.3, you can use the pluginService
to do this
Preview
Script
// round corners
Chart.pluginService.register({
afterUpdate: function (chart) {
if (chart.config.options.elements.arc.roundedCornersFor !== undefined) {
var arc = chart.getDatasetMeta(0).data[chart.config.options.elements.arc.roundedCornersFor];
arc.round = {
x: (chart.chartArea.left + chart.chartArea.right) / 2,
y: (chart.chartArea.top + chart.chartArea.bottom) / 2,
radius: (chart.outerRadius + chart.innerRadius) / 2,
thickness: (chart.outerRadius - chart.innerRadius) / 2 - 1,
backgroundColor: arc._model.backgroundColor
}
}
},
afterDraw: function (chart) {
if (chart.config.options.elements.arc.roundedCornersFor !== undefined) {
var ctx = chart.chart.ctx;
var arc = chart.getDatasetMeta(0).data[chart.config.options.elements.arc.roundedCornersFor];
var startAngle = Math.PI / 2 - arc._view.startAngle;
var endAngle = Math.PI / 2 - arc._view.endAngle;
ctx.save();
ctx.translate(arc.round.x, arc.round.y);
console.log(arc.round.startAngle)
ctx.fillStyle = arc.round.backgroundColor;
ctx.beginPath();
ctx.arc(arc.round.radius * Math.sin(startAngle), arc.round.radius * Math.cos(startAngle), arc.round.thickness, 0, 2 * Math.PI);
ctx.arc(arc.round.radius * Math.sin(endAngle), arc.round.radius * Math.cos(endAngle), arc.round.thickness, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
ctx.restore();
}
},
});
// write text plugin
Chart.pluginService.register({
afterUpdate: function (chart) {
if (chart.config.options.elements.center) {
var helpers = Chart.helpers;
var centerConfig = chart.config.options.elements.center;
var globalConfig = Chart.defaults.global;
var ctx = chart.chart.ctx;
var fontStyle = helpers.getValueOrDefault(centerConfig.fontStyle, globalConfig.defaultFontStyle);
var fontFamily = helpers.getValueOrDefault(centerConfig.fontFamily, globalConfig.defaultFontFamily);
if (centerConfig.fontSize)
var fontSize = centerConfig.fontSize;
// figure out the best font size, if one is not specified
else {
ctx.save();
var fontSize = helpers.getValueOrDefault(centerConfig.minFontSize, 1);
var maxFontSize = helpers.getValueOrDefault(centerConfig.maxFontSize, 256);
var maxText = helpers.getValueOrDefault(centerConfig.maxText, centerConfig.text);
do {
ctx.font = helpers.fontString(fontSize, fontStyle, fontFamily);
var textWidth = ctx.measureText(maxText).width;
// check if it fits, is within configured limits and that we are not simply toggling back and forth
if (textWidth < chart.innerRadius * 2 && fontSize < maxFontSize)
fontSize += 1;
else {
// reverse last step
fontSize -= 1;
break;
}
} while (true)
ctx.restore();
}
// save properties
chart.center = {
font: helpers.fontString(fontSize, fontStyle, fontFamily),
fillStyle: helpers.getValueOrDefault(centerConfig.fontColor, globalConfig.defaultFontColor)
};
}
},
afterDraw: function (chart) {
if (chart.center) {
var centerConfig = chart.config.options.elements.center;
var ctx = chart.chart.ctx;
ctx.save();
ctx.font = chart.center.font;
ctx.fillStyle = chart.center.fillStyle;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var centerX = (chart.chartArea.left + chart.chartArea.right) / 2;
var centerY = (chart.chartArea.top + chart.chartArea.bottom) / 2;
ctx.fillText(centerConfig.text, centerX, centerY);
ctx.restore();
}
},
})
and then
...
options: {
elements: {
arc: {
roundedCornersFor: 0
},
center: {
// the longest text that could appear in the center
maxText: '100%',
text: '67%',
fontColor: '#FF6684',
fontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
fontStyle: 'normal',
// fontSize: 12,
// if a fontSize is NOT specified, we will scale (within the below limits) maxText to take up the maximum space in the center
// if these are not specified either, we default to 1 and 256
minFontSize: 1,
maxFontSize: 256,
}
}
}
};
You can get rid of a bit of code if you don't want it to be generic (eg. if you fix the fontSize, if you fix the index to round, etc.)
Fiddle - http://jsfiddle.net/cd3fdoy9/
这篇关于Chart.js甜甜圈圆边和文本居中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!