Как использовать метки данных плагина Chart.js с ng2-chart?
Ну, вот я снова с моими англоязычными и javascript-проблемами, чувствуя себя тупее на каждый вопрос, который я задаю.
Но позвольте мне попытаться объяснить мои начальные шаги и как это привело к этой проблеме. Итак, в моем последнем проекте я хотел добавить несколько причудливых диаграмм, чтобы сделать вещи более понятными и более доступными для пользователя. На ум пришел Chart.js... или, я бы сказал, ng2-чарты.
Все было хорошо, все выглядело хорошо, но... У меня были две проблемы. На горизонтальной полосе я хотел динамически изменять размер диаграммы, чтобы пользователю не приходилось прокручивать какое-то непонятное количество времени, чтобы перейти на страницу. Так что вместо этого громоздкого зверя...
Я пытаюсь применить некоторую угловую магию. Позже я хочу вычислить размер этого на моем конце бэкэнда. На данный момент статическое значение будет делать.
@ViewChild('inventoryChart') itemChart : ElementRef;
constructor(public renderer: Renderer2) { }
ngAfterViewInit() {
this.renderer.setStyle(this.itemChart.nativeElement, 'height', '230px')
}
Что приводит к...
Ницца. Но моя вторая проблема оказалась намного сложнее, чем я предполагал. Я хотел, чтобы диаграммы имели соответствующие значения на каждой гистограмме. Я был несколько шокирован, узнав, что это не врожденная особенность chart.js, а плагин. Поэтому я попытался сузить свои проблемы, посмотрев на конфигурацию своего графика.
@ViewChild('itemChart') itemChart : ElementRef;
//public context: CanvasRenderingContext2D;
public chartType: string = 'horizontalBar';
chartDatalabel: ChartLabel;
public chartDatasets: Array<any> = [
{ data: [28, 20, 6, 5, 3], label: 'Inventory per country' }
];
public chartLabels: Array<any> = ['DEU', 'SVK', 'FRA', 'GBR', 'AUT'];
public chartColors: Array<any> = [
{
backgroundColor: '#0E599A',
pointBackgroundColor: 'rgba(220,220,220,1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(220,220,220,1)'
},
];
public chartOptions: any = {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
barPercentage: .9,
categoryPercentage: .9,
gridLines: {
offsetGridLines: true,
display: true,
},
ticks: {
beginAtZero: true
}
}],
xAxes: [{
ticks: {
beginAtZero: true,
min: 0
},
gridLines: {
offsetGridLines: true,
display: true,
},
}]
},
};
Поскольку у меня был похожий вопрос, и, посмотрев документацию... потребовалась бы таблица для регистрации плагина.
Итак, я добавил
import { Chart } from 'chart.js';
Но быстро понял, я не знал, как на самом деле получить этот экземпляр диаграммы, который я создавал в моем компоненте. И как я могу добавить это в опцию только для этого конкретного графика? Я не нашел много источников с такой же проблемой, как у меня (что заставило меня чувствовать себя еще более неумелым...).
Есть ли какой-нибудь чистый "угловой путь", чтобы добавить этот плагин в ng2-чарты?
РЕДАКТИРОВАТЬ: Судя по документации, я мог бы определить, что плагин может делать следующими способами...
var plugin = { /* plugin implementation */ };
А потом вызывать этот плагин в настройках графика или глобально...
Chart.plugins.register({
// plugin implementation
});
Которого я бы хотел избежать. Никогда не фанат глобальной конфигурации, если это абсолютно необходимо и экономит время.
РЕДАКТИРОВАТЬ 2: Сорта отказался от НЕ зарегистрировать его в глобальном масштабе, но это все еще не очень помогает. Я добавил в мой импорт...
import { Chart } from 'chart.js';
import * as ChartLabel from 'chartjs-plugin-datalabels';
А затем попытался зарегистрировать плагин в глобальной таблице.
ngOnInit() {
Chart.plugins.register(ChartLabel);
}
Который сделал "что-то", насколько я могу судить. Поэтому я попытался сделать очень простую реализацию плагина. Другие всплывающие подсказки больше не работают, но они вызывают ошибку только при наведении курсора на столбики.
plugins: {
datalabels: {
color: 'white',
display: true,
font: {
weight: 'bold'
},
formatter: Math.round
}
},
Понятия не имею, что я могу сделать больше...
1 ответ
Ну, так как буквального ответа не было, я мог в конечном итоге согласиться на решение "Глобальной" диаграммы.
Chart.pluginService.register({
// I gave it an id, so I could disable the plugin if needed
id: 'p1',
afterDatasetsDraw: function (chart, _ease) {
let width = chart.chart.width;
let ctx = chart.chart.ctx;
let datasets = chart.data.datasets;
datasets.forEach(function (_dataset, index) {
let meta = chart.getDatasetMeta(index);
// grabbing the array with the data...
let barLabelData = meta.controller._data;
// console.log(meta.controller._data)
if (!meta.hidden) {
meta.data.forEach(function (segment, _index) {
let model = segment._model;
let position = segment.tooltipPosition();
let x = position.x;
let y = position.y;
let height = model.height;
ctx.restore();
ctx.textBaseline = "middle";
// var fontSize = (height / 114).toFixed(2);
ctx.font = 'bold ' + height / 2 + 'px Arial';
ctx.fillStyle = '#777'; //first label's font color
let text = barLabelData[_index];
ctx.fillText(text, x, y);
ctx.save();
})
}
});
}
});
Который в конечном счете украшал меня диаграммой сорта хорошо выглядящей. Так что да, это не так чисто, как хотелось бы. Но есть еще проблемы с реализацией.
Мой компонент Chart глобально реализует мою логику плагина. Это ужасный дизайн, и я должен отделить его. Незначительная проблема в том, что я должен убедиться, что этикетки работают всегда и правильно изображены. Но пока я рад, что это работает.
Вот пример, сделанный @paviad:
https://stackblitz.com/edit/ng2-charts-bar-labels
import { Component, OnInit } from '@angular/core';
import { ChartOptions, ChartType, ChartDataSets } from 'chart.js';
import * as pluginDataLabels from 'chartjs-plugin-datalabels';
import { Label } from 'ng2-charts';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
public barChartOptions: ChartOptions = {
responsive: true,
// We use these empty structures as placeholders for dynamic theming.
scales: { xAxes: [{}], yAxes: [{}] },
plugins: {
datalabels: {
anchor: 'end',
align: 'end',
font: {
size: 20,
}
}
}
};
...
public barChartPlugins = [pluginDataLabels];
...
Подробные варианты здесь: https://chartjs-plugin-datalabels.netlify.app/