Update charts in chartjs and angular

萝らか妹 提交于 2020-12-08 07:54:32

问题


I have the problem with update chart js in angular. I am using for it ngrx store.

In selector subscriber (run in ngOnInit) I tried update the chart data:

this.yrSubscription = this.userDataStore.pipe(select(selectYrReport))
  .subscribe(el => {
    el.sessions.forEach(item => {
      this.datasetsSessions[0].data.push(+item);
    });
  });

And my chart data:

datasetsSessions: ChartDataSets[] = [{
  label: 'Sessions',
  data: [],
  fill: false
}];

Register charts:

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

And I call it in constructor.

I know, that I need run chart.update(). But still I have got an error about chart is undefined etc.


回答1:


When using ng2-charts, there's no need to invoke chart.update(), let Angular change detection do its job. In case it doesn't work as expected, reassign the data array after pushing a new value to it. This can be done using Array.slice() as shown below.

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

But the main issue is probably located in the _registerCustomChartJSPlugin method. Instead of defining such a method, define its content in a chartPlugins variable as follows:

chartPlugins = [{
  afterDatasetsDraw: (chart, easing): any => {
    ...
  }
}];

Inside the HTML template, you then have to provide chartPlugins as follows.

<canvas baseChart
  [datasets]="datasetsSessions"
  [plugins]="chartPlugins"
  ...
</canvas>

Please have a look at this StackBlitz.




回答2:


Assuming that you are registering the charts in the same component . First of all you need to keep a reference to your custom chart. In your component add this in your component class

customChartInstance : Chart;

Then in your afterDatasetsDraw add this.customChartInstance=chart

then in your subscription add

 this.chart.update();



回答3:


Above Component Decorator have this :-

var require: any;
var Chart = require('chart.js');

In component have a property for keeping instance of chart

public chart: Chart;

First you need to understand is that Chart.plugins.register will only register a plugin globally for all charts. https://www.chartjs.org/docs/latest/developers/plugins.html#global-plugins

You need a chart for this plugin to apply

Lets Say you have a Canvas in your HTML like :-

<div>
  <canvas id="canvas">{{ chart }}</canvas>
</div>

You need to update your inside ngoninit to ngrx Subscription To create a new chart if its not available.

ngOnInit() {
this._registerCustomChartJSPlugin();
this.yrSubscription = this.userDataStore.pipe(select(selectYrReport))
  .subscribe(el => {
      if(!this.chart) {
        this.createChart();
      }
    el.sessions.forEach(item => {
      this.datasetsSessions[0].data.push(+item);
    });
    this.chart.update();
  });
}
public createChart() {
   this.chart = new Chart('canvas'); //Include if any object required as second Parameter
}


来源:https://stackoverflow.com/questions/62104695/update-charts-in-chartjs-and-angular

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!