首页 > 解决方案 > 在 Angular 中使用 Highcharts (>= 8.0.1) 函数 stockChart() 时出错

问题描述

当我使用该函数Highcharts.stockChart时,从导入的highcharts/highstock我得到了这些错误(点击时):

highstock.src.js:3417 Error: <rect> attribute width: Expected length, "NaN".

highstock.src.js:3417 Error: <rect> attribute x: Expected length, "NaN".

如果我使用 highcharts 版本 8.0.0(或 7.1.2),我不会收到任何错误。

我最初认为这些错误是由我的数据集引起的,所以我继续模拟它,但它没有用。然后我尝试模拟传递给函数的对象“选项”,Highcharts.stockChart(domElement, options)但同样,它不起作用。
即使是对该函数的干净调用也不起作用:Highcharts.stockChart(domElement, {})

Stackblitz:https
://stackblitz.com/edit/angular-playground-qdw6ll (文件 tds-chart.component.ts - 查看 Chrome DevTools 控制台以查看错误消息)

这是我的组件的代码(检查功能updateOrCreateChart):

import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  ElementRef,
  Input,
  NgZone,
  OnDestroy,
  OnInit
} from '@angular/core';
import { Chart, Options } from 'highcharts';
import { BehaviorSubject, Subscription } from 'rxjs';
import * as Highcharts from 'highcharts/highstock';

@Component({
  selector: 'tds-chart',
  template: '<div id="myDiv"></div>',
  exportAs: 'tdsChart',
  changeDetection: ChangeDetectionStrategy.OnPush
})
// tslint:disable-next-line: component-class-suffix
export class TdsChart implements OnDestroy, OnInit {
  private _options$ = new BehaviorSubject<Options>(null);
  private _sub: Subscription;
  private _chart: Chart;

  @Input() constructorType: string;
  @Input() oneToOne = false;
  @Input() runOutsideAngular = true;
  @Input() callbackFunction: (chart: Chart) => void;

  @Input() set options(val: Options) {
    this._options$.next(val);
  }

  get chart() {
    return this._chart;
  }

  constructor(
    private el: ElementRef,
    private _zone: NgZone,
    private _cd: ChangeDetectorRef
  ) { }

  ngOnInit() {
    this._sub = this._options$.subscribe(() => this.wrappedUpdateOrCreateChart());
  }

  redraw() {
    this._options$.next(this._options$.value);
  }

  private wrappedUpdateOrCreateChart() {
    if (this.runOutsideAngular) {
      this._zone.runOutsideAngular(() => {
        setTimeout(() => {
          this.updateOrCreateChart();
          this._cd.markForCheck();
        }, 1);
      });
    } else {
      setTimeout(() => {
        this.updateOrCreateChart();
        this._cd.markForCheck();
      }, 1);
    }
  }

  private updateOrCreateChart() {
    if (this._chart) {
      // to do 
    } else {
      this._chart = Highcharts.stockChart('myDiv', {}, null);
    }
  }

  ngOnDestroy() {
    if (this._sub) {
      this._sub.unsubscribe();
    }
    if (this._chart) {
      this._chart.destroy();
      this._chart = null;
    }
  }
}

标签: angularhighcharts

解决方案


在 highcharts 上有一个关于这个 bug的问题。

在该问题中报告了8.0.1+版本的解决方法。

演示:http: //jsfiddle.net/BlackLabel/74m9sf8c/

(function(H) {
  H.wrap(
    H.Navigator.prototype,
    'drawMasks',
    function(proceed, zoomedMin, zoomedMax) {
      if (!H.isNumber(zoomedMin) || !H.isNumber(zoomedMax)) {
        return;
      }
      proceed.apply(this, Array.prototype.slice.call(arguments, 1))
    }
  );
})(Highcharts);

推荐阅读