ChartJS 进行新api调用时刷新ng2图表

vatpfxk5  于 2022-11-06  发布在  Chart.js
关注(0)|答案(1)|浏览(219)

我的条形图是通过API调用填充的。API接受过滤器,因此,我希望在从下拉列表中选择选项时更新图表数据。只有2022年的数据,因此在选择另一年时,图表为空(这是预期的),但图例仍具有旧数据,并且不是空的。
再次选择“2022”时,数据将被复制,但图表上仅显示一个带额外空间的条形,且无标签,图例为每个条形显示两次标签。预期的行为是图表中仅显示一个条形,图例中有一个标签,且无额外空间。

“chart.js”:“^3.6.0”
“ng 2-图表”:“^3.1.2”
页面加载时的图表

选择另一年时的图表

重新选择2022年时的图表

报告.组件.html

<mat-select ngClass="w-25" [value]="currentYear" (selectionChange)="getSelectedYear($event.value)">
        <mat-option *ngFor="let year of yearList" [value]="year">
            {{year}}
        </mat-option>
    </mat-select>

报告.组件.ts

import { BaseChartDirective } from 'ng2-charts';
import { ChartData, ChartOptions } from 'chart.js';
import { Component, OnInit, ViewChild } from '@angular/core';
import { UsageService } from 'src/app/services/report/usage.service';
import { usageStats } from 'src/types/ReportTypes';
import { ColorGeneratorService } from 'src/app/services/helper/color/color-generator.service';

@Component({
  selector: 'app-usage',
  templateUrl: './usage.component.html',
  styleUrls: ['./usage.component.scss']
})
export class UsageComponent implements OnInit {

  monthLabels: string[] = [];
  chartInfo: any[] = [];
  yearList: number[] = [];
  currentYear: number = new Date().getFullYear();
  @ViewChild(BaseChartDirective) chart!: BaseChartDirective;

  // static chartdata

  chartData: ChartData<'bar'> = {
    labels: [],
    datasets: []
  };

chartOptions: ChartOptions = {
    responsive: true,
    plugins: {
      title: {
        display: true,
        text: 'Monthly Report',
        font: {
          size: 22,
          family: 'Poppins'
        }
      },
      legend: {
        position: 'bottom',
      }
    },
    scales: {
      xAxis: {
        title: {
          display: true
          font: {
            size: 16,
            family: 'Poppins',
            weight: 'bold'
          }
        }
      },
      yAxis: {
        title: {
          display: true
          font: {
            size: 16,
            family: 'Poppins',
            weight: 'bold'
          }
        },
        ticks: {
          precision: 0
        }
      },

    }
  };

  constructor(
    private usage: UsageService,
    private colorGenerator: ColorGeneratorService) { }

  ngOnInit(): void {

    // Load the chart with data from the current year
    this.populateChart(this.currentYear);
  }

  getSelectedYear(year: number) {
       this.removeData(this.chart);
       this.populateChart(year);
  }

  removeData(chart: any) {
    chart.data.labels.pop();
    chart.data.datasets.forEach((dataset: any) => {
      dataset.data.pop();
    });
    chart.update();
  }

  addData(chart: any, label?: any, data?: any) {
    chart.data.labels.push(label);
    chart.data.datasets.forEach((dataset: any) => {
      dataset.data.push(data);
    });
    chart.update();
  }

  populateChart(selectedYear: number) {
    this.usage.getUsageReport(selectedYear,
      (stats: Array<usageStats>) => {

        console.log("Stats", stats);

        if (stats.length > 0) {
          stats.forEach((s) => {
            this.monthLabels.push(s.month);
            this.chartInfo.push({
              'label': s.service, data: [s.count],
              backgroundColor: this.colorGenerator.getRandomColor(),
              borderColor: this.colorGenerator.getRandomColor(),
              borderRadius: 20, hoverBackgroundColor:
                this.colorGenerator.getRandomColor(),
            });

            // Do not add duplicate years to the filter list
            if (!this.yearList.includes(s.year)) {
              this.yearList.push(s.year);
              this.yearList.push(2024);
              this.yearList.push(2023);

              // Sort the list in ascending order
              this.yearList.sort((a, b) => a - b);
            }
          });

          this.chartData = {
            labels: this.monthLabels,
            datasets: this.chartInfo
          }
            this.chart.update();
        }
      },
      (error: any) => {

      }
    );
  }

}
ux6nzvsh

ux6nzvsh1#

我在填充之前清除了数组,这样以前的数据就不存在了,这样它就可以工作了

import { BaseChartDirective } from 'ng2-charts';
import { ChartData, ChartOptions } from 'chart.js';
import { Component, OnInit, ViewChild } from '@angular/core';
import { UsageService } from 'src/app/services/report/usage.service';
import { usageStats } from 'src/types/ReportTypes';
import { ColorGeneratorService } from 'src/app/services/helper/color/color-generator.service';

@Component({
  selector: 'app-usage',
  templateUrl: './usage.component.html',
  styleUrls: ['./usage.component.scss']
})
export class UsageComponent implements OnInit {

  monthLabels: string[] = [];
  chartInfo: any[] = [];
  yearList: number[] = [];
  currentYear: number = new Date().getFullYear();
  @ViewChild(BaseChartDirective) chart!: BaseChartDirective;

  // static chartdata

  chartData: ChartData<'bar'> = {
    labels: [],
    datasets: []
  };

chartOptions: ChartOptions = {
    responsive: true,
    plugins: {
      title: {
        display: true,
        text: 'Monthly Report',
        font: {
          size: 22,
          family: 'Poppins'
        }
      },
      legend: {
        position: 'bottom',
      }
    },
    scales: {
      xAxis: {
        title: {
          display: true
          font: {
            size: 16,
            family: 'Poppins',
            weight: 'bold'
          }
        }
      },
      yAxis: {
        title: {
          display: true
          font: {
            size: 16,
            family: 'Poppins',
            weight: 'bold'
          }
        },
        ticks: {
          precision: 0
        }
      },

    }
  };

  constructor(
    private usage: UsageService,
    private colorGenerator: ColorGeneratorService) { }

  ngOnInit(): void {

    // Load the chart with data from the current year
    this.populateChart(this.currentYear);
  }

  getSelectedYear(year: number) {
       this.removeData(this.chart);
       this.populateChart(year);
  }

  removeData(chart: any) {
    chart.data.labels.pop();
    chart.data.datasets.forEach((dataset: any) => {
      dataset.data.pop();
    });
    chart.update();
  }

  addData(chart: any, label?: any, data?: any) {
    chart.data.labels.push(label);
    chart.data.datasets.forEach((dataset: any) => {
      dataset.data.push(data);
    });
    chart.update();
  }

  populateChart(selectedYear: number) {
    this.usage.getUsageReport(selectedYear,
      (stats: Array<usageStats>) => {

   //Clear arrays used to store the chart details
    this.monthLabels = [];
    this.chartInfo = [];

        if (stats.length > 0) {
          stats.forEach((s) => {
            this.monthLabels.push(s.month);
            this.chartInfo.push({
              'label': s.service, data: [s.count],
              backgroundColor: this.colorGenerator.getRandomColor(),
              borderColor: this.colorGenerator.getRandomColor(),
              borderRadius: 20, hoverBackgroundColor:
                this.colorGenerator.getRandomColor(),
            });

            // Do not add duplicate years to the filter list
            if (!this.yearList.includes(s.year)) {
              this.yearList.push(s.year);
              this.yearList.push(2024);
              this.yearList.push(2023);

              // Sort the list in ascending order
              this.yearList.sort((a, b) => a - b);
            }
          });

          this.chartData = {
            labels: this.monthLabels,
            datasets: this.chartInfo
          }
            this.chart.update();
        }
      },
      (error: any) => {

      }
    );
  }

}

相关问题