Bigous / ng2-highcharts

Angular2 library to use Highcharts out of the box
59 stars 23 forks source link

question: how to update the title #55

Closed crh225 closed 7 years ago

crh225 commented 7 years ago

Here is my chart object

    private chartData = {
        chart: {
            type: 'column'
        },
        title: {
            text: 'hello'
        },
        xAxis: {
            categories: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        },
        series: [
            {
                name: 'NC',
                data: [7057, 6858, 6643, 6570, 6115, 107, 31, 635, 203, 2, 2]
            }, {
                name: 'OK',
                data: [54047, 52484, 50591, 49479, 46677, 33, 156, 947, 408, 6, 2]
            }, {
                name: 'KO',
                data: [11388, 11115, 10742, 10757, 10290, 973, 914, 4054, 732, 34, 2]
            }, {
                name: 'VALID',
                data: [8836, 8509, 8255, 7760, 7621, 973, 914, 4054, 732, 34, 2]
            }, {
                name: 'CHECK',
                data: [115, 162, 150, 187, 172, 973, 914, 4054, 732, 34, 2]
            }, {
                name: 'COR',
                data: [12566, 12116, 11446, 10749, 10439, 973, 914, 4054, 732, 34, 2]
            }
        ]
    };

function that changes title

    changeTitle() {
        this.chartData = this.chartData;

        this.chartData.title.text = 'test';

        let charts = [];
        charts = this.allCharts.forEach(chartRef => {
            //Access the chart property defined in Ng2Highcharts
            let theChart = chartRef.chart;
            theChart.reflow();
        });
    }

I have a button click that calles the change title function. In the function above reflow gets called but nothing happens to the chart title.

If I change the function to

    changeTitle() {
this.chartData = {
        chart: {
            type: 'column'
        },
        title: {
            text: 'IT WORKS
        },
        xAxis: {
            categories: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        },
        series: [
            {
                name: 'NC',
                data: [7057, 6858, 6643, 6570, 6115, 107, 31, 635, 203, 2, 2]
            }, {
                name: 'OK',
                data: [54047, 52484, 50591, 49479, 46677, 33, 156, 947, 408, 6, 2]
            }, {
                name: 'KO',
                data: [11388, 11115, 10742, 10757, 10290, 973, 914, 4054, 732, 34, 2]
            }, {
                name: 'VALID',
                data: [8836, 8509, 8255, 7760, 7621, 973, 914, 4054, 732, 34, 2]
            }, {
                name: 'CHECK',
                data: [115, 162, 150, 187, 172, 973, 914, 4054, 732, 34, 2]
            }, {
                name: 'COR',
                data: [12566, 12116, 11446, 10749, 10439, 973, 914, 4054, 732, 34, 2]
            }
        ]
    };
        let charts = [];
        charts = this.allCharts.forEach(chartRef => {
            //Access the chart property defined in Ng2Highcharts
            let theChart = chartRef.chart;
            theChart.reflow();
        });
    }

the above works, but it redraws the entire chart. Is it possible to just update one of the charts properties and have it bound to the chart?

crh225 commented 7 years ago

In summary I cant bind to the data or the title

crh225 commented 7 years ago

I figured out I can change the title by: this.chart.setTitle({text: "New Title"}); but why can I not change the properties like this: this.chartData.title.text = 'test';

Bigous commented 7 years ago

Highcharts itself (and angular2 too) does not recognizes that you've changed a inner property of an object. You must call reflow of your charts, or changes the object address when a property changes - one could use immutable for that. See #42, #44 and at #48 Greg made a pull request to handle the resize transition of the object and reflect it in the chart. Not an ng2-highcharts question.

crh225 commented 7 years ago

@Bigous, I did call reflow if you look at the code. Honestly, what is the purpose of this package? You can import highcharts nativly and use it. You are telling me I need to use @ViewChild('chart') public chartEl: ElementRef; and reflow, and a bunch of stuff that isnt in this package. I dont appear to gain anything by using this with dynamic data.

crh225 commented 7 years ago

@Bigous, is there not a way to have an input of chartData to your component, and then do so your package could call reflow?

@ViewChild('chart') public chartEl: ElementRef;
ngOnChanges(){
        if (this.chartData) {
            this.opts = this.chartData;
            if (this.chartEl && this.chartEl.nativeElement) {
                this.opts.chart = {
                    renderTo: this.chartEl.nativeElement
                };

                this._chart = new Highcharts.Chart(this.opts);
                this._chart.reflow();

            }
        }
}
Bigous commented 7 years ago

Hi @crh225, the purpose is to wrap highcharts components to make it easier to use. Not reimplement highcharts or change it behaviours.

If it's better to you to use highcharts directly, fine. If you wanna pull some implementations to this library so people can benefits from it too, you are welcome too.

I'm not a highcharts employ nor have any relationship with then. I just though people, like me, could use a library to facilitate thing.

[]'s

Bigous commented 7 years ago

To the question of having an input - yes, I've already implemented that, but to do that, I need o ignore the Angular2 Change detection and implement another one. Just like immutablejs does. The drawback is the duplication of information, and if you are using the same object in another place it could became very difficult to sync. That's why I didn't set this to the library. ImmutableJS does this job with the performance penalty.

Bigous commented 7 years ago

Just to you to test, if instead of alter the title, you copy the entire option to another object and change the title and set the new option to ng2-highcharts, angular2 will handle the change and recreate the object as expected.

crh225 commented 7 years ago

@Bigous , could you use zone and the funciton runOutsideAngular? http://blog.thoughtram.io/angular/2016/02/01/zones-in-angular-2.html

Bigous commented 7 years ago

Hi @crh225 , sorry about the delay. Where do you wanna put the runOutsideAngular?

crh225 commented 7 years ago

@Bigous, Im not using this library anymore. Im using highcharts natively in angular 2 and it works great.

crh225 commented 7 years ago

for the future readers, here is how you update the title:

this._chart.setTitle({ text: title }, { text: this.ChartJsonConfig.subtitle });