在Angular 4 app中使用Morris Js插件

时间:2017-08-04 16:59:22

标签: angular typescript morris.js

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

2 个答案:

答案 0 :(得分:5)

我使用相同的方式使用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 :(得分:0)

  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应用程序更好)

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

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

  5. 中的declarations[]
  6. src / app / app.component.ts 中,添加import 'morris.js06/morris.js';

    公共数据; 公共选择; constructor(){      ... } ngOnInit(){     this.datas = [         {xkey:'2018',value:20},         {xkey:'2019',价值:10}     ]     this.options = {             xkey:'xkey',             ykeys:['value'],             标签:['value']     }; }

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

仅此而已^^

this wrapper的启发,这是一个指令和接口,可用于在Angular4 +中轻松使用Morris Chart

morris-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();
        }
    }
}

morris-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;
}