Angular 10 - Chart.js 在运行时使用 convas id 在数组中绘制图表

Posted

技术标签:

【中文标题】Angular 10 - Chart.js 在运行时使用 convas id 在数组中绘制图表【英文标题】:Angular 10 - Chart.js to draw chart in Array with convas id on runtime 【发布时间】:2021-05-16 01:54:32 【问题描述】:

我需要根据数据库中可用的数据对象绘制图表。为了处理这个问题,我创建了对象数组并使用 convas ID,我在对象中有一个占位符。在 html 中,我从 Object 分配 ID。但是,我收到以下错误 -

创建图表失败:无法从给定项目获取上下文

数据类:

export class SetPressureData 
  popPressure: number;
  seatingPressure: number;
  conclusion: string;
  conclusionOperatorComment: string;
  isSetPressureChartAvailable = false;
  chartName: string;
  showOnCert: boolean=true;

我在 .ts 文件中的代码如下:

setPressureTestLinechart: [];
....
if (_testResultTS.sensorId == SensorId.PZT_01 || _testResultTS.sensorId == SensorId.PT_PT05) 
  this.chartName = 'setPressureChart' + this.setPressureDataCount;
  this.setPressureData.chartName = this.chartName;
  this.prepareCharts(this.setPressureTestLinechart, this.chartName, _testResultTS.values, -1, 1);
  this.setPressureData.isSetPressureChartAvailable = true;


prepareCharts(chartName: Chart, chartCanvas: string, tsSample: TimeSeriesSample[],
  minValOffset ? : number, maxValOffset ? : number) 
  let timeStamps = [];
  let values = [];
  let minValue = Number.MAX_VALUE;
  let maxValue = Number.MIN_VALUE;

  chartName = new Chart(chartCanvas, 
    type: 'line',
    data: 
      labels: timeStamps,
      datasets: [
        pointRadius: 0,
        data: values,
        borderColor: '#3e95cd',
      ]
    ,
    options: chartOptions
  );

我的 HTML 代码如下:

<ng-container *ngIf="certificateData.setPressureResults?.length>0;else pressureTestAborted">
    <div *ngFor="let setPressureData of certificateData.setPressureResults, let i=index">
        <!--Iterate over the Array for all Set Pressure Test Executed -->
        <div id="i" *ngIf="setPressureData.showOnCert">
            <span>
                <br />
                Test #i+1
            </span>
            <input type="checkbox" (click)="updateShowFlag(i)" />Please check, if not required on certificate
            <mat-card-content>
                <div style="display: inline-block; vertical-align: top; width: 41%;">
                    <span class="field-label-prep">Pop Pressure:</span><span class="data">setPressureData.popPressure</span> <span class="units">bar</span><br />
                    <span class="field-label-prep">Seating Pressure:</span> <span class="data">setPressureData.seatingPressure</span><span class="units">bar</span> <br />
                    <div class="col-style-prep" *ngIf="setPressureData.conclusionOperatorComment">
                        <span class="field-label-prep">Operator Comment:</span><br />
                        <span class="comment">setPressureData.conclusionOperatorComment</span>
                    </div>
                </div>
                <div style="display: inline-block; width: 48%;">
                    <canvas class="chart-style"  id="setPressureData.chartName"></canvas>
                    <span class="time-caption">[Time in mm:ss]</span>
                </div>
                <div *ngIf="setPressureData.conclusion!=null" style="display: inline-block; vertical-align: top; width: 11%;">
                    <span
                        class="result-status-column"
                        [ngClass]=" 'testOpResults-Green': (setPressureData.conclusion === testOperationresults.Approved ||setPressureData.conclusion === testOperationresults.Performed),
                                                                                'testOpResults-Red': setPressureData.conclusion === testOperationresults.Failed,
                                                                                'testOpResults-Orange': setPressureData.conclusion === testOperationresults.Aborted "
                    >
                        setPressureData.conclusion
                    </span>
                </div>
            </mat-card-content>
        </div>
    </div>
    <!-- End of Array Iteration-->
</ng-container>

【问题讨论】:

【参考方案1】:

问题是Chart.js 在您创建图表时找不到与指定chartCanvas 匹配的canvas

new Chart(chartCanvas, 
  ...

由于HTML 模板中的*ngIf*ngFor 指令,只有当certificateData.setPressureResults 数组包含一些元素时,canvas 元素才会包含在DOM 中。 Angular 自动更改检测机制通常负责使DOMcomponent 类中包含的数据保持同步。

要解决您的问题,您需要在更新 certificateData.setPressureResults 之后但在创建图表之前手动触发更改检测。这可以通过调用ChangeDetectorRef.detectChanges() 来完成。

因此,component 类的代码必须更改如下:

constructor(private cdr: ChangeDetectorRef, ...) 
  ...


// trigger change detection wherever it fits
this.cdr.detectChanges();

【讨论】:

以上是关于Angular 10 - Chart.js 在运行时使用 convas id 在数组中绘制图表的主要内容,如果未能解决你的问题,请参考以下文章

[转] angular2+highcharts+chart.js

Chart.js 如果主页上不存在,则不会在 Angular2 中显示

markdown Chart.js的Angular2指令

升级到 Angular4 后找不到名称“require”

在 Ionic 框架中使用 Chart.js 和 jQuery

如何在 Chart.js 上显示数据值