Chart.js 圆角边缘和文本居中的甜甜圈 [英] Chart.js Doughnut with rounded edges and text centered
本文介绍了Chart.js 圆角边缘和文本居中的甜甜圈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试实现类似于本文
<小时>脚本
//圆角Chart.pluginService.register({afterUpdate:函数(图表){if (chart.config.options.elements.arc.roundedCornersFor !== undefined) {var arc = chart.getDatasetMeta(0).data[chart.config.options.elements.arc.roundedCornersFor];圆弧 = {x: (chart.chartArea.left + chart.chartArea.right)/2,y: (chart.chartArea.top + chart.chartArea.bottom)/2,半径:(chart.outerRadius + chart.innerRadius)/2,厚度:(chart.outerRadius - chart.innerRadius)/2 - 1,背景颜色:arc._model.backgroundColor}}},afterDraw:函数(图表){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);控制台日志(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:函数(图表){如果(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);如果(centerConfig.fontSize)var fontSize = centerConfig.fontSize;//找出最佳字体大小,如果没有指定别的 {ctx.save();var fontSize = helpers.getValueOrDefault(centerConfig.minFontSize, 1);var maxFontSize = helpers.getValueOrDefault(centerConfig.maxFontSize, 256);var maxText = helpers.getValueOrDefault(centerConfig.maxText, centerConfig.text);做 {ctx.font = helpers.fontString(fontSize, fontStyle, fontFamily);var textWidth = ctx.measureText(maxText).width;//检查它是否合适,是否在配置的限制范围内,并且我们不是简单地来回切换if (textWidth < chart.innerRadius * 2 && fontSize < maxFontSize)字体大小 += 1;别的 {//反转最后一步字体大小 -= 1;休息;}} 而(真)ctx.restore();}//保存属性图表中心 = {字体:helpers.fontString(fontSize, fontStyle, fontFamily),填充样式:helpers.getValueOrDefault(centerConfig.fontColor, globalConfig.defaultFontColor)};}},afterDraw:函数(图表){如果(图表中心){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 = '中心';ctx.textBaseline = '中间';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();}},})
然后
<代码> ...选项: {元素:{弧:{圆角为:0},中央: {//可能出现在中心的最长文本maxText: '100%',文字:'67%',fontColor: '#FF6684',fontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",fontStyle: '正常',//字体大小:12,//如果未指定 fontSize,我们将缩放(在以下限制内)maxText 以占据中心的最大空间//如果这些都没有指定,我们默认为 1 和 256最小字体大小:1,最大字体大小: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屋!
查看全文