chart.component.ts 2.15 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  ElementRef,
  Input,
  NgZone,
  OnChanges,
  OnInit,
  SimpleChanges,
  ViewChild
} from '@angular/core';
import { asapScheduler } from 'rxjs';
// @ts-ignore
import ApexCharts from 'apexcharts';

export interface ApexOptions {
  annotations?: ApexAnnotations;
  chart?: ApexChart;
  colors?: any[];
  dataLabels?: ApexDataLabels;
  fill?: ApexFill;
  grid?: ApexGrid;
  labels?: string[] | number[];
  legend?: ApexLegend;
  markers?: ApexMarkers;
  noData?: ApexNoData;
  plotOptions?: ApexPlotOptions;
  responsive?: ApexResponsive[];
  series?: ApexAxisChartSeries | ApexNonAxisChartSeries;
  states?: ApexStates;
  stroke?: ApexStroke;
  subtitle?: ApexTitleSubtitle;
  theme?: ApexTheme;
  title?: ApexTitleSubtitle;
  tooltip?: ApexTooltip;
  xaxis?: ApexXAxis;
  yaxis?: ApexYAxis | ApexYAxis[];
}

@Component({
  selector: 'vex-chart',
  template: ` <div #chart></div> `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChartComponent implements OnInit, OnChanges {
  @Input() options: ApexOptions;
  @Input() series: ApexAxisChartSeries | ApexNonAxisChartSeries;
  @Input() autoUpdateSeries = true;
  public chart: ApexCharts;
  @ViewChild('chart', { static: true }) private chartElement: ElementRef;

  constructor(private cd: ChangeDetectorRef, private ngZone: NgZone) {}

  ngOnInit() {
    asapScheduler.schedule(() => {
      this._createElement();
    });
  }

  ngOnChanges(changes: SimpleChanges): void {
    asapScheduler.schedule(() => {
      if (
        this.autoUpdateSeries &&
        Object.keys(changes).filter(c => c !== 'series').length === 0
      ) {
        this.chart.updateSeries(this.series, true);
        return;
      }

      this._createElement();
    });
  }

  public render(): Promise<void> {
    return this.chart.render();
  }

  private _createElement() {
    if (this.series) {
      this.options.series = this.series;
    }

    if (this.chart) {
      this.chart.destroy();
    }

    this.ngZone.runOutsideAngular(() => {
      this.chart = new ApexCharts(
        this.chartElement.nativeElement,
        this.options
      );

      this.render();
    });
  }
}