Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
551 views
in Technique[技术] by (71.8m points)

chart.js - chartjs angular update order

Got a question about chartjs in an angular11 environment. I have 2 charts

appcomponent.html:

<div class="col-sm">
  <canvas id="bl" ></canvas>
</div>
<div class="col-sm">
  <canvas id="bl2" ></canvas>
</div>

app.component.ts:

export class AppComponent {
            testChart: any;
            testChart2: any;
            ...
  constructor(private dataSvc:DataRetrieverService){
    dataSvc.getUsers.subscribe( data=> {
      if(!data) return;
      this.Users = data;
      this.Users.forEach(x => {
        this.UsersLabels.push(x.StoreDateTime);
        this.UsersAmount.push(x.Amount);
        this.CreateCharts();
      })
    })

    dataSvc.getParts.subscribe( data=> {
      if(!data) return;
      this.Parts = data;
      this.Parts.forEach(x => {
        this.PartsLabels.push(x.StoreDateTime);
        this.PartsAmount.push(x.Amount);
        this.CreateCharts();
      })
    })
  }
  
  

  CreateCharts(){
    if(this.testChart){
      this.testChart.destroy()
    }
    if(this.testChart2){
      this.testChart2.destroy()
    }
    
    this.testChart = new Chart('bl', {
      type: 'line',
      data: {
        labels: this.UsersLabels,
        datasets: [
          {
            label: 'Users',
            data: this.UsersAmount,
            borderColor: '#01c38c',
            backgroundColor: '#01c38c',
            fill: false
          }
        ]
      },
      options: {... }
      }
    });

    this.testChart2 = new Chart('bl2', {
      type: 'line',
      data: {
        labels: this.PartsLabels,
        datasets: [
          {
            label: 'Parts',
            data: this.PartsAmount,
            borderColor: '#01c38c',
            backgroundColor: '#01c38c',
            fill: true
          }
        ]
      },
      options: {...
      }
    });

Is creating the testChart: Any the correct thing to do?

Why do I have to call this.CreateCharts() after every data retrieval from the service in order to make it work?

I would expect if I would do a this.CreateCharts() at the very last step of the constructor it would also work, but then my chart is empty.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're subscribing to two Observable obtained from dataSvc.getUsers and dataSvc.getParts, corresponding results will be delivered asynchronously, certainly after the invocation of the constructor has finished. Therefore, If with given code, you would invoke CreateChart() at the end of the constructor only, you would see two empty charts because UsersLabels, UsersAmount, PartsLabels and PartsAmount are still empty arrays at this point.

It's however needless to recreate both charts each time any Observable delivers new data. You better split CreateChart() into separate methods, one for each chart. Also instead of using chart.destroy(), you should better simply update the existing chart data and invoke chart.update() afterwards. Please take a look at the section Adding or Removing Data of the Chart.js documentation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...