在 Angular 4 个应用中使用 Morris Js 插件

Use Morris Js plugin in Angular 4 app

我想在我的 angular 4 项目中使用 Morris Js 插件吗? 我知道如何在 angular 中使用 jQuery 2、4? 但我不知道如何将 Morris 图表集成到我的 ng 4 应用程序中。 如果您有这方面的经验,请给我帮助。

我使用与 jQuery 相同的方法解决了这个问题。 请看下面的代码。

declare var $: any;
declare var Morris: any;
...
ngOnInit() {
   Morris.Bar({
      element: 'morris-bar',
      data: [
        {
          x: '2017 R1',
          y: 3,
          z: 2,
          a: 3,
        },
   ......
   xkey: 'X',
   kyes: ['y', 'z', 'a'],
   ...
   });
}
  1. Raphael.js 应该安装 (npm install raphael) 然后添加到脚本中的 angular.json。示例:

    "scripts": ["./node_modules/raphael/raphael.min.js"]

  2. 安装morris npm install morris.js06(那个fork不需要jQuery,这对Angular4+ web app更好)

  3. 创建指令morris-chart.ts和接口morris-chart.interface.ts在 src/app/directives/morris-chart(下面提供来源)

  4. src/app/app.module.ts中添加 import { MorrisChartDirective } from './directives/morris-chart/morris-chart'; MorrisChartDirectivedeclarations[]

  5. src/app/app.component.ts中添加import 'morris.js06/morris.js';

    public 数据; public 选项; 构造函数(){ ... } ngOnInit() { this.datas = [ { xkey: '2018', 值: 20 }, { xkey: '2019', 值: 10 } ] this.options = { xkey: 'xkey', ykeys: ['value'], 标签:['value'] }; }

  6. src/app/app.component.html中添加<div mk-morris-js [options]='options' [data]='datas' type='Bar'></div>

就这些了^^

受到this wrapper的启发,这里有一个指令和一个接口,可以通过Angular4+轻松使用Morris Chart

莫里斯-chart.ts

import { Directive, AfterViewInit, OnInit, OnDestroy, Input, ElementRef, NgZone, OnChanges, SimpleChanges, Output, EventEmitter } from '@angular/core';

import { ChartOptions, ChartDatas } from './morris-chart.interface';

@Directive({
    selector: '[mk-morris-js]'
})
export class MorrisChartDirective implements OnInit, AfterViewInit, OnChanges, OnDestroy {
    private window: any = window;
    private _options: ChartOptions;

    public chartInstance: any;

    @Input() type = 'Line';
    @Input() options: ChartOptions;
    @Input() data: ChartDatas;
    @Output() clickChart = new EventEmitter();

    /*
    * [constructor description]
    * @method constructor
    * @param  {ElementRef} private elementRef [description]
    * @param  {NgZone}     private ngZone     [description]
    */
    constructor(
        private elementRef: ElementRef,
        private ngZone: NgZone
    ) {}

    /*
    * [ngOnInit description]
    * @method ngOnInit
    */
    ngOnInit() {
        this._options = Object.assign({}, this.options);
        this._options.element = this.elementRef.nativeElement;
        this._options.data = this.data;
    }

    /*
    * [ngAfterViewInit description]
    * @method ngAfterViewInit
    */
    ngAfterViewInit() {
        if(!this.window.Morris) {
            throw new Error('Please include node_modules/morris.js/morris.js');
        } else {
            this.ngZone.runOutsideAngular(() => {
                this.chartInstance = new this.window.Morris[this.type](this._options);
                let my_this = this;
                this.chartInstance.on('click', function(i, row) { 
                    my_this.clickChart.emit({ event, i, row });
                });
            });
        }
    }

    /*
    * [ngOnChanges description]
    * @method ngOnChanges
    * @param  {SimpleChanges} changes [description]
    */
    ngOnChanges(changes: SimpleChanges) {
        if((changes.data && !changes.data.firstChange) || (changes.options && !changes.options.firstChange)) {
            Object.assign(this.chartInstance.options, this.options);
            this.chartInstance.setData(this.data);
        }
    }

    /*
    * [ngOnDestroy description]
    * @method ngOnDestroy
    */
    ngOnDestroy() {
        if (this.chartInstance.el.empty instanceof Function) {
            this.chartInstance.el.empty();
        }
    }
}

莫里斯-chart.interface.ts

export interface ChartData {
  label: string;
  value: number;
}

export interface ChartDatas {
    [key: string]: ChartData;
}

export interface ChartOptions {
  element: Element;
  data: ChartDatas;
  resize?: boolean;
}


export interface ChartDonutOptions extends ChartOptions {
  colors?: Array<string>;
  formater?: (y, data) => string;
  resize?: boolean;
}

export interface ChartAreaBarLineOptions {
  xkey: string,
  ykeys: Array<string>;
  labels: Array<string>;
  hideHover?: boolean|string;
  hoverCallback?: (index, options, content, row) => void;
  axes?: boolean;
  grid?: boolean;
  gridTextColor?: string;
  gridTextSize?: number;
  gridTextFamily?: string;
  gridTextWeight?: string;
  fillOpacity?: number;
}

export interface ChartAreaOptions extends ChartAreaBarLineOptions {
  behaveLikeLine?: boolean;
}

export interface ChartBarOptions extends ChartAreaBarLineOptions {
  barColors?: Array<string>;
  stacked?: boolean;
}

export interface ChartLineOptions extends ChartAreaBarLineOptions {
  lineColors?: Array<string>;
  lineWidth?: number;
  pointSize?: number;
  pointFillColors?: string;
  pointStrokeColors?: string;
  ymax?: string|number;
  ymin?: string|number;
  smooth?: boolean;
  postUnits?: string;
  preUnits?: string;
  dateFormat?: (timestamp: number) => string;
  xLabels?: string;
  xLabelFormat?: (date: Date) => string;
  xLabelAngle?: number;
  yLabelFormat?: (label: string|number) => string;
  goals?: Array<number>;
  goalStrokeWidth?: number;
  goalLineColors?: string;
  events?: Array<number>;
  eventStrokeWidth?: number;
  eventLineColors?: Array<string>;
  continuousLine?: boolean;
}