vimalavinisha / angular2-google-chart

Angular 2 google chart
MIT License
59 stars 45 forks source link

Chart redraw #7

Open franziska-haaf opened 8 years ago

franziska-haaf commented 8 years ago

Added functionality, for redrawing a chart if wanted. (Necessary for changing data.) Just add the reDraw="true" to your chart, and the chart will be redrawn after a period of time. Example: <div id="pressureGauge" [chartData]="pressureData" [chartOptions]="pressureChartOptions" chartType="Gauge" reDraw="true" GoogleChart ></div>

stefanvitz commented 7 years ago

just implement OnChanges as i just did in my pull request. that will redraw every time you change the underlying data

danlesko commented 7 years ago

@stefanvitz can you share how you implemented this functionality?

HarelM commented 7 years ago

I needed the same functionality basically and some more. Not sure this is the relevant place to write it but here goes: I started with ngChanges and found out that it doesn't support changes when only adding or removing rows. I also needed the chart wrapper and an event when the data is updated in order to be able to redraw a special tooltip I'm using. the following is the complete code, let me know if you want a PR. No global variables, just static. no timeouts, added chart view, got some of the ideas from angular-google-chart which I used before migrating to angular 4.

import { Directive, ElementRef, Input, Output, OnChanges, OnInit, EventEmitter, DoCheck, IterableDiffers, IterableDiffer } from "@angular/core";

@Directive({
    selector: "[GoogleChart]",
})
export class GoogleChartDirective implements OnChanges, OnInit, DoCheck {

    private element: HTMLElement;
    @Input()
    public chartType: string;
    @Input()
    public chartOptions: Object;
    @Input()
    public chartData: google.visualization.DataObject;
    @Input()
    public chartView: string[];

    @Output()
    public onWrapperReady = new EventEmitter();

    @Output()
    public afterUpdate = new EventEmitter();

    private static loaded: boolean = false;
    private chartWrapper: google.visualization.ChartWrapper;
    private dataObjectRowDiffer: IterableDiffer<google.visualization.DataObjectRow>;

    constructor(element: ElementRef,
        iterableDiffer: IterableDiffers) {
        this.dataObjectRowDiffer = iterableDiffer.find([]).create<google.visualization.DataObjectRow>(null);

        this.element = element.nativeElement;
    }

    public ngOnInit() {
        google.load("visualization", "1.0", { "packages": ["corechart"], callback: () => { this.onLoadCallback(); } });
        // the follwoing doesn't work for me for some reason... :-/
        //google.charts.load("current", { packages: ["corechart"] });
        //google.charts.setOnLoadCallback(() => { this.onLoadCallback(); });
    }

    public ngOnChanges() {
        if (!GoogleChartDirective.loaded) {
            return;
        }
        this.update();
    }

    public ngDoCheck() {
        let dataObjectChanges = this.dataObjectRowDiffer.diff(this.chartData.rows);
        if (dataObjectChanges) {
            this.update();
        }
    }

    private onLoadCallback = () => {
        this.chartWrapper = new google.visualization.ChartWrapper({
            chartType: this.chartType,
            dataTable: this.chartData,
            options: this.chartOptions || {},
            view: this.chartView
        });
        this.chartWrapper.draw(this.element);
        this.chartWrapper.setContainerId(this.element.id);
        GoogleChartDirective.loaded = true;
        this.onWrapperReady.emit(this.chartWrapper);
    }

    private update() {
        if (GoogleChartDirective.loaded)
        {
            this.chartWrapper.setChartType(this.chartType);
            this.chartWrapper.setDataTable(this.chartData as any);
            this.chartWrapper.setView(JSON.stringify(this.chartView));
            this.chartWrapper.setOptions(this.chartOptions);
            this.chartWrapper.draw();
            this.afterUpdate.emit();
        }
    }
}
manuelarte commented 7 years ago

Does the previous solution posted work in Angular4? Because I cannot make it work

HarelM commented 7 years ago

What do you define as previous solution? The solution I've posted is working for Angular 4. Directive can be found here: https://github.com/IsraelHikingMap/Site/blob/master/IsraelHiking.Web/sources/application/directives/GoogleChartDirective.ts Relevant code that uses this directive can be found here: https://github.com/IsraelHikingMap/Site/blob/master/IsraelHiking.Web/sources/application/components/routeStatisticsChart.html https://github.com/IsraelHikingMap/Site/blob/master/IsraelHiking.Web/sources/application/components/RouteStatisticsChartComponent.ts