import { Component, Input, HostBinding, ViewChild, ElementRef, OnDestroy, OnChanges, SimpleChanges, NgZone, AfterViewInit, TemplateRef, OnInit, HostListener } from '@angular/core'; import { Subscription } from 'rxjs/Subscription'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/fromEvent'; import 'rxjs/add/operator/debounceTime'; @Component({ selector: 'bar', template: `

{{_title}}

` }) export class G2BarComponent implements OnDestroy, OnChanges, AfterViewInit, OnInit { // region: fields _title = ''; _titleTpl: TemplateRef; @Input() set title(value: string | TemplateRef) { if (value instanceof TemplateRef) this._titleTpl = value; else this._title = value; } @Input() color = 'rgba(24, 144, 255, 0.85)'; @HostBinding('style.height.px') @Input() height = 0; @Input() margin: number[]; @Input() data: any[]; @Input() autoLabel = true; // endregion @HostBinding('class.g2-chart') _cls = true; @ViewChild('container') node: ElementRef; chart: any; initFlag = false; constructor(private el: ElementRef, private zone: NgZone) { } ngAfterViewInit(): void { this.initFlag = true; this.resize(); } install() { if (!this.data || (this.data && this.data.length < 1)) return; // this.uninstall(); if (!this.margin) this.margin = [32, 0, this.autoHideXLabels ? 8 : 32, 40]; this.zone.runOutsideAngular(() => { this.node.nativeElement.innerHTML = ''; const { Frame } = G2; const frame = new Frame(this.data); const chart = new G2.Chart({ container: this.node.nativeElement, forceFit: true, height: +this.height - 22, legend: null, plotCfg: { margin: this.margin } }); if (this.autoHideXLabels) { chart.axis('x', { title: false, tickLine: false, labels: false }); } else { chart.axis('x', { title: false }); } chart.axis('y', { title: false, line: false, tickLine: false }); chart.source(frame, { x: { type: 'cat' }, y: { min: 0 } }); chart.tooltip({ title: null, crosshairs: false, map: { name: 'x' } }); chart.interval().position('x*y').color(this.color).style({ fillOpacity: 1, }); chart.render(); this.zone.run(() => this.chart = chart); }); } uninstall() { if (this.chart) { this.zone.runOutsideAngular(() => { this.chart.destroy(); }); this.chart = null; } } ngOnInit(): void { this.installResizeEvent(); } ngOnChanges(changes: SimpleChanges): void { if (this.initFlag) this.install(); } ngOnDestroy(): void { this.uninstallResizeEvent(); this.uninstall(); } // region: resize private autoHideXLabels = false; private scroll$: Subscription = null; private installResizeEvent() { if (!this.autoLabel || this.scroll$) return; this.scroll$ = Observable.fromEvent(window, 'resize') .debounceTime(200) .subscribe(() => this.resize()); } private uninstallResizeEvent() { if (this.scroll$) this.scroll$.unsubscribe(); } resize() { const canvasWidth = this.el.nativeElement.clientWidth; const minWidth = this.data.length * 30; if (canvasWidth <= minWidth) { if (!this.autoHideXLabels) { this.autoHideXLabels = true; this.install(); return; } } else if (this.autoHideXLabels) { this.autoHideXLabels = false; this.install(); return; } if (!this.chart) this.install(); } // endregion }