admin管理员组文章数量:1410712
How can I add a text label inside Doughnut chart using Chart.js and Angular2? I saw some answers on this topic but none of them are working for me since I am working with Ionic2 app. This is my simplified code:
import { Chart } from 'chart.js';
@ViewChild('doughnutCanvas') doughnutCanvas;
ionViewDidEnter() {
this.doughnutChart = new Chart(this.doughnutCanvas.nativeElement, {
type: 'doughnut',
data: {
labels: this.titles,
datasets: [{
label: '# of Work',
data: this.times,
backgroundColor: [
'rgba(255, 99, 132, 0.5)',
'rgba(54, 162, 235, 0.5)'
],
hoverBackgroundColor: [
"#FF6384",
"#36A2EB"
]
}]
},
options: {
responsive: true,
legend: {
display: false
}
}
});
}
How can I add a text label inside Doughnut chart using Chart.js and Angular2? I saw some answers on this topic but none of them are working for me since I am working with Ionic2 app. This is my simplified code:
import { Chart } from 'chart.js';
@ViewChild('doughnutCanvas') doughnutCanvas;
ionViewDidEnter() {
this.doughnutChart = new Chart(this.doughnutCanvas.nativeElement, {
type: 'doughnut',
data: {
labels: this.titles,
datasets: [{
label: '# of Work',
data: this.times,
backgroundColor: [
'rgba(255, 99, 132, 0.5)',
'rgba(54, 162, 235, 0.5)'
],
hoverBackgroundColor: [
"#FF6384",
"#36A2EB"
]
}]
},
options: {
responsive: true,
legend: {
display: false
}
}
});
}
Share
Improve this question
edited May 9, 2017 at 7:07
Suraj Rao
29.6k11 gold badges95 silver badges104 bronze badges
asked May 9, 2017 at 7:04
user7832762user7832762
3 Answers
Reset to default 4This can be achieved by creating / registering a plugin before generating the chart and you could create the plugin in the following way ...
Chart.plugins.register({
beforeDraw: function(chart) {
var data = chart.data.datasets[0].data;
var sum = data.reduce(function(a, b) {
return a + b;
}, 0);
var width = chart.chart.width,
height = chart.chart.height,
ctx = chart.chart.ctx;
ctx.restore();
var fontSize = (height / 10).toFixed(2);
ctx.font = fontSize + "px Arial";
ctx.textBaseline = "middle";
var text = sum,
textX = Math.round((width - ctx.measureText(text).width) / 2),
textY = height / 2;
ctx.fillText(text, textX, textY);
ctx.save();
}
});
ᴅᴇᴍᴏ
// register plugin
Chart.plugins.register({
beforeDraw: function(chart) {
var data = chart.data.datasets[0].data;
var sum = data.reduce(function(a, b) {
return a + b;
}, 0);
var width = chart.chart.width,
height = chart.chart.height,
ctx = chart.chart.ctx;
ctx.restore();
var fontSize = (height / 10).toFixed(2);
ctx.font = fontSize + "px Arial";
ctx.textBaseline = "middle";
var text = sum,
textX = Math.round((width - ctx.measureText(text).width) / 2),
textY = height / 2;
ctx.fillText(text, textX, textY);
ctx.save();
}
});
// generate chart
var ctx = document.getElementById('canvas').getContext('2d');
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ["Red", "Blue", "Yellow"],
datasets: [{
data: [300, 50, 100],
backgroundColor: ["#FF6384", "#36A2EB", "#FFCE56"],
hoverBackgroundColor: ["#FF6384", "#36A2EB", "#FFCE56"]
}]
},
options: {
responsive: false,
legend: {
display: false
}
}
});
<script src="https://cdnjs.cloudflare./ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<canvas id="canvas"></canvas>
If you guys are trying to add legend. You should change the height by using
height = (chart.chartArea.top + chart.chartArea.bottom) / 2
textY = height;
using the chartArea is more correct. Otherwise your text would ignore the height of legend and be located in the wrong place.
For anybody who is using ng2-charts^2.4.2"
the registration of the inline plugin can be done via the baseChart
directive's input attribute [plugins]
.
First you have to define a plugins
property holding and array of plugins. (You could also register your official plugins there plugins = [ChartDataLabels, {/*inline plugin*/}]
)
For correct label placement inside the doughnut chart you have to take into account the position of the legend, which could be above, below or at the left or right side. So I tweaked @GRUNT and @ginagigo123 answers into an ultimate answer that is based on the following calculations
let textX = Math.round(((chart.chartArea.left + chart.chartArea.right) - ctx.measureText(text).width) / 2),
let textY = Math.round((chart.chartArea.top + chart.chartArea.bottom) / 2);
poonent.ts
@ViewChild(BaseChartDirective, { static: true })
chartNgWrapper: BaseChartDirective;
plugins = [
{
beforeDraw: function (chart: any) {
let data = chart.data.datasets[0].data;
let sum = (data as number[]).reduce(function (a, b) {
return a + b;
}, 0);
let width = chart.chartArea.left + chart.chartArea.right,
height = chart.chartArea.top + chart.chartArea.bottom,
ctx = chart.chart.ctx;
ctx.restore();
let fontSize = (height / 10).toFixed(2);
ctx.font = fontSize + 'px Arial';
ctx.textBaseline = 'middle';
let text = sum,
textX = Math.round((width - ctx.measureText(text).width) / 2),
textY = height / 2;
ctx.fillText(text, textX, textY);
ctx.save();
},
},
];
In case you are making an app that can switch language writing mode, you have to get the current rtl
(right-to-left) value from somewhere (mine is defined in the legend) and add or substract based on it:
let textX = chart.legend.options.rtl
? Math.round((width + ctx.measureText(text).width) / 2)
: Math.round((width - ctx.measureText(text).width) / 2),
If you are manipulation the writing direction via an html element's dir
attribute (<app-root dir="ltr">
) you can also get the current language writing mode from chart.ctx.direction
, in this case it returns 'rtl'
or 'ltr'
strings
ponent.html
<canvas
baseChart
#chart
[datasets]="doughnutChartData"
[chartType]="doughnutChartType"
[labels]="doughnutChartLabels"
[options]="options"
[plugins]="plugins"
>
</canvas>
本文标签: javascriptText inside Doughnut chart using Chartjs and Angular2Ionic2Stack Overflow
版权声明:本文标题:javascript - Text inside Doughnut chart using Chart.js and Angular2, Ionic2 - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745030555a2638468.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论