私はこの記事に似た丸みを帯びた角を達成しようとしています ここ 、しかし中央のテキストと組み合わせて、これまでのところ私は以下のコードを持っていますが、両方のアイデアを組み合わせる方法がわかりません
どんな助けでもいただければ幸いです!
画像は以下のようになります。ドーナツとテキスト画像:
ドーナツ内にテキストを生成するための私のコードは次のとおりです。
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",
});
V2.1.3では、pluginService
を使用してこれを行うことができます
プレビュー
スクリプト
// 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();
}
},
})
その後
...
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,
}
}
}
};
汎用的にしたくない場合は、コードを少し取り除くことができます(たとえば、fontSizeを修正した場合、インデックスをroundに修正した場合など)。
凡例がクリックされたときに中央のテキストを変更するコードを追加しました。
afterDraw: function (chart) {
if (chart.center) {
var ctx = chart.chart.ctx;
var i,a,s;
var n = chart;
var total = 0;
for(i=0,a=(n.data.datasets||[]).length;a>i;++i){
s = n.getDatasetMeta(i);
var x;
for(x=0; x<s.data.length; x++){
if (!s.data[x].hidden)
total += n.data.datasets[i].data[x];
}
}
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(total, centerX, centerY);
ctx.restore();
}
}
アークでのarc.borderWidthの使用を処理するために、コードをわずかに変更しました。 Charts.jsのバージョン2.8の場合
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 + chart.config.options.elements.arc.borderWidth) / 2,
y: (chart.chartArea.top + chart.chartArea.bottom) / 2,
radius: (chart.outerRadius + chart.innerRadius) / 2,
thickness: (chart.outerRadius - chart.innerRadius - (chart.config.options.elements.arc.borderWidth /2)) / 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);
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();
}
}
});