Chart.js不读取来自可观察(Angular )的输入数据

neskvpey  于 2022-11-29  发布在  Chart.js
关注(0)|答案(1)|浏览(129)

我正在创建一个基于一些数据的图表,但是我卡住了。我的问题是,由于某种原因,Chart.JS无法识别来自父组件的数据。
我的数据的示例:

[
{month: 'January', revenue: 100}, 
{month: 'February', revenue: 140}..
]

我获取数据,将其发送到父容器组件中,使用异步管道订阅模板,并在子组件中使用Input访问数据。
子组件:

export class MonthlySalesComponent implements OnInit {
  @Input() soldUnitsPerMonth!: any;

  @ViewChild('chart')
  private chartRef!: ElementRef;
  private chart!: Chart;

  public barChartLegend = true;
  public barChartPlugins = [];

  constructor() {}

  ngOnInit(): void {}

  ngAfterViewInit(): void {
    this.chart = new Chart(this.chartRef.nativeElement, {
      type: 'bar',
      data: {
        labels: [1, 2, 3, 4, 5, 6, 7, 8, 9],
        datasets: [
          {
            label: 'Interesting Data',
            data: [1, 2, 3, 1, 5, 7, 1, 2, 3, 5],
          },
        ],
      },
    });
  }

  getAllMonths() {
    return this.soldUnitsPerMonth.map((item: any) => item.month);
  }
}

我不想在标签和数据数组中使用硬编码的值,而是想访问每个月(和每个收入),因此我创建了getAllMonths函数。
问题是,即使我编写了这些函数,new Chart构造函数也无法访问它,因为Input数据仍然未定义。我不明白为什么,因为如果我使用ul/li - ngFor方法访问它,我可以很容易地在UI上呈现数据。但由于某种原因,new Chart无法访问此数据。
我读到一个使用ngAfterViewInit钩子的提示,但那也没有帮助。
子模板:

<canvas #chart width="600" height="200"></canvas>
b0zn9rqh

b0zn9rqh1#

[已解决]
问题是数据以异步方式到达,并且在创建组件时还没有准备好,因此我必须将新的Chart逻辑 Package 到一个observable中,然后使用switchMap来利用它的高阶功能。

ngAfterViewInit() {
    this.setChart().subscribe();
  }

  setChart() {
    return this.soldUnitsPerMonth.pipe(
      switchMap((items) => {
        return this.defineChartDetails(items);
      })
    );
  }

  defineChartDetails(items: any) {
    return new Observable((obs) => {
      if (this.chart) {
        this.chart.destroy();
      }

      this.chart = new Chart(this.chartRef.nativeElement, {
        type: 'bar',
        data: {
          labels: items.map((item: any) => item.month + 1),
          datasets: [
            {
              label: 'Interesting Data',
              data: items.map((item: any) => item.totalSalesInMonth),
            },
          ],
        },
      });
    });
  }

如果有人遇到这个问题,请注意,您还必须使用ngOnDestroy取消订阅setChart方法。

相关问题