chart.js 2.6.0
J'ai besoin de rendre un graphique qui ressemble à ceci:
Toujours afficher toutes les info-bulles n'est pas une manière acceptable, car elles ne seront pas rendues correctement:
Malheureusement, je n'ai pas encore trouvé de solution. J'ai essayé le plug-in piece-label , mais cela a les mêmes problèmes, car ses étiquettes se chevauchent et je ne peux pas masquer certaines étiquettes.
Voici le code qui crée mon graphique en utilisant morceau-étiquette pour positionner les étiquettes au-dessus des tranches:
private createStatusChart(): void {
const chartData = this.getStatusChartData();
if (!chartData) {
return;
}
const $container = $(Templates.Dashboard.ChartContainer({
ContainerID: 'chart-status',
HeaderText: 'Status'
}));
this._$content.append($container);
const legendOptions =
new Model.Charts.LegendOptions()
.SetDisplay(false);
const pieceLabelOptions =
new Model.Charts.PieceLabelOptions()
.SetRender('label')
.SetPosition('outside')
.SetArc(true)
.SetOverlap(true);
const options =
new Model.Charts.Options()
.SetLegend(legendOptions)
.SetPieceLabel(pieceLabelOptions);
const chartDefinition = new Model.Charts.Pie(chartData, options);
const ctx = this._$content.find('#chart-status canvas').get(0);
const chart = new Chart(ctx, chartDefinition);
}
private getStatusChartData(): Model.Charts.PieChartData {
if (!this._data) {
return;
}
const instance = this;
const data: Array<number> = [];
const labels: Array<string> = [];
const colors: Array<string> = [];
this._data.StatusGroupings.forEach(sg => {
if (!sg.StatusOID) {
data.Push(sg.Count);
labels.Push(i18next.t('Dashboard.NoStateSet'));
colors.Push('#4572A7');
return;
}
const status = DAL.Properties.GetByOID(sg.StatusOID);
data.Push(sg.Count);
labels.Push(status ? status.Title : i18next.t('Misc.Unknown'));
colors.Push(status ? status.Color : '#fff');
});
const dataset = new Model.Charts.Dataset(data).setBackgroundColor(colors);
return new Model.Charts.PieChartData(labels, [dataset]);
}
Le résultat:
Le vrai problème réside dans le chevauchement des étiquettes lorsque les tranches sont petites.Vous pouvez utiliser PieceLabel.js qui résout le problème des étiquettes qui se chevauchent en le masquant. Vous avez mentionné que vous ne pouvez pas masquer les étiquettes alors utilisez des légendes, qui afficheront les noms de toutes les tranches
Ou si vous voulez un comportement exact, vous pouvez utiliser le highcharts , mais il nécessite une licence pour un usage commercial.
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var ctx = document.getElementById("chart-area").getContext("2d");
var myDoughnut = new Chart(ctx, {
type: 'pie',
data: {
labels: ["January", "February", "March", "April", "May"],
datasets: [{
data: [
250,
30,
5,
4,
2,
],
backgroundColor: ['#ff3d67', '#ff9f40', '#ffcd56', '#4bc0c0', '#999999'],
borderColor: 'white',
borderWidth: 5,
}]
},
showDatapoints: true,
options: {
tooltips: {
enabled: false
},
pieceLabel: {
render: 'label',
arc: true,
fontColor: '#000',
position: 'outside'
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Testing',
fontSize: 20
},
animation: {
animateScale: true,
animateRotate: true
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<script src="https://cdn.rawgit.com/emn178/Chart.PieceLabel.js/master/build/Chart.PieceLabel.min.js"></script>
<canvas id="chart-area"></canvas>
Fiddle démo
Il y a un nouveau plugin (depuis un an), appelé chartjs-plugin-piece-maphart-outlabels
Importez simplement la source<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-piechart-outlabels"></script>
et l'utiliser avec le type outlabeledPie
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var ctx = document.getElementById("chart-area").getContext("2d");
var myDoughnut = new Chart(ctx, {
type: 'outlabeledPie',
data: {
labels: ["January", "February", "March", "April", "May"],
...
plugins: {
legend: false,
outlabels: {
text: '%l %p',
color: 'white',
stretch: 45,
font: {
resizable: true,
minSize: 12,
maxSize: 18
}
}
}
})