javascript - Uppdatera diagram i chartjs och angular
Jag har problemet med att uppdatera chart js i Angular. Jag använder ngrx store för det.
I selektorprenumerant (körs i ngOnInit) försökte jag uppdatera diagramdata:
this.yrSubscription = this.userDataStore.pipe(select(selectYrReport))
.subscribe(el => {
el.sessions.forEach(item => {
this.datasetsSessions[0].data.push(+item);
});
});
Och mina diagramdata:
datasetsSessions: ChartDataSets[] = [{
label: 'Sessions',
data: [],
fill: false
}];
Registerdiagram:
private _registerCustomChartJSPlugin(): void {
(window as any).Chart.plugins.register({
afterDatasetsDraw: (chart, easing): any => {
if (!chart.options.plugins.xLabelsOnTop
|| (chart.options.plugins.xLabelsOnTop && chart.options.plugins.xLabelsOnTop.active === false)) {
return;
}
const ctx = chart.ctx;
chart.data.datasets.forEach((dataset, i): any => {
const meta = chart.getDatasetMeta(i);
if (!meta.hidden) {
meta.data.forEach((element, index): any => {
// Draw the text in black, with the specified font
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
const fontSize = 13;
const fontStyle = 'normal';
const fontFamily = 'Roboto, Helvetica Neue, Arial';
ctx.font = (window as any).Chart.helpers.fontString(fontSize, fontStyle, fontFamily);
const dataString = dataset.data[index].toString() + 'k';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
const padding = 15;
const startY = 24;
const position = element.tooltipPosition();
ctx.fillText(dataString, position.x, startY);
ctx.save();
ctx.beginPath();
ctx.setLineDash([5, 3]);
ctx.moveTo(position.x, startY + padding);
ctx.lineTo(position.x, position.y - padding);
ctx.strokeStyle = 'rgba(255,255,255,0.12)';
ctx.stroke();
ctx.restore();
});
}
});
}
});
}
Och jag kallar det i konstruktorn.
Jag vet att jag behöver köra chart.update(). Men ändå har jag fått ett fel om att chart är odefinierad osv.
Svar #1
När du använder ng2-charts finns det inget behov av att anropa chart.update(), låt Angulars ändringsdetektering göra sitt jobb. Om det inte fungerar som förväntat, tilldela data-arrayen igen efter att ha lagt till ett nytt värde i den. Detta kan göras med Array.slice() som visas nedan.
this.yrSubscription = this.userDataStore.pipe(select(selectYrReport))
.subscribe(el => {
el.sessions.forEach(item => {
this.datasetsSessions[0].data.push(+item);
this.datasetsSessions[0].data = this.datasetsSessions[0].data.slice();
});
});
Men huvudproblemet är förmodligen beläget i _registerCustomChartJSPlugin-metoden. Istället för att definiera en sådan metod, definiera dess innehåll i en chartPlugins-variabel som följer:
chartPlugins = [{
afterDatasetsDraw: (chart, easing): any => {
...
}
}];
Inuti HTML-mallen måste du sedan ange chartPlugins på följande sätt.
<canvas baseChart
[datasets]="datasetsSessions"
[plugins]="chartPlugins"
...
</canvas>
Ta en titt på detta StackBlitz.
Svar #2
Förutsatt att du registrerar diagrammen i samma komponent. Först och främst behöver du behålla en referens till ditt anpassade diagram. I din komponent lägger du till detta i din komponentklass
customChartInstance : Chart;
Sedan i din afterDatasetsDraw lägg till this.customChartInstance=chart
lägg sedan till i din prenumeration
this.chart.update();
