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();

Relaterade artiklar