Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chart create and destroy #218

Open
EoleDev opened this issue Aug 3, 2020 · 6 comments
Open

Chart create and destroy #218

EoleDev opened this issue Aug 3, 2020 · 6 comments

Comments

@EoleDev
Copy link

EoleDev commented Aug 3, 2020

Hi,

Thanks for your work!
We are currently having a problem,
we have a chart on a component with some route parameters.
When the parameters are changing, we can't reset the chart in a simple way.

Would you be able, to add an API call to create and destroy the chart ?
Thank you very much!

@mateuszkornecki
Copy link
Contributor

Hi @EoleDev, thanks for reaching out to us!

To make it work you could save the chart reference and then use it to call the chart.destroy() method.

For the future, for general tech support, please see www.highcharts.com/support.

Live demo:
https://stackblitz.com/edit/highcharts-angular-basic-line-ohj5ek?file=src%2Fapp%2Fapp.component.ts

export class AppComponent {
  Highcharts: typeof Highcharts = Highcharts;
  chartRef: Highcharts.Chart;

  chartOptions: Options = {
    series: [
      {
        type: "line",
        data: [1, 2, 3]
      }
    ]
  };

  chartCallback: Highcharts.ChartCallbackFunction = (chart) => {
    this.chartRef = chart;
  };

  handleClick():void {
    this.chartRef.destroy();
  }

}

@EoleDev
Copy link
Author

EoleDev commented Aug 4, 2020

Thanks for your quick answer @mateuszkornecki

I tried to use the reference and call the destroy function but as I can't recreate the chart,
and as the reference is not destroyed in the "highcharts-chart" component,
I end up with an error when the component try to use the previously destroyed chart.

The main problem is :
When I destroy the chart, I would like to be able to recreate it quickly after ( mainly to reset it on routing parameters change ).
To recreate it, my only option would be to execute the function "updateOrCreateChart" in the highcharts-chart component.
To be able to execute this function, I need to call an update on the component.

updateOrCreateChart() {
    if (this.chart && this.chart.update) {

When it call the function, as the reference on chart is not destroyed, the first condition is fulfilled and it try to
update a destroyed chart.

If you have a solution, It would be a great help :)

@mateuszkornecki
Copy link
Contributor

Then you could try another approach. You can create a ref to the highcharts-chart component using the @ViewChild and then call its ngOnDestroy() method. Then to recreate the chart you would need to change the update flag to true.

References:
https://medium.com/@rawllopes/destroy-child-components-from-parent-component-in-angular-be3d4ad9cf3b

Live example:
https://stackblitz.com/edit/highcharts-angular-basic-line-9q9dwb?file=src%2Fapp%2Fapp.component.ts

<highcharts-chart 
  #chart
  [Highcharts]="Highcharts" 
  [options]="chartOptions"
  [update]="updateFlag"
  ></highcharts-chart>

  <button (click)="destroyChart()">Destroy chart</button>
  <button (click)="createChart()">Create chart</button>
import { Component, ViewChild } from "@angular/core";
import * as Highcharts from 'highcharts';
import { Options } from "highcharts";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  Highcharts: typeof Highcharts = Highcharts;
  @ViewChild('chart') chartRef;
  updateFlag;

  chartOptions: Options = {
    series: [
      {
        type: "line",
        data: [1, 2, 3]
      }
    ]
  };

  createChart():void {
    this.updateFlag = true;
  }

  destroyChart():void {
    this.chartRef.ngOnDestroy();
  }

}

@EoleDev
Copy link
Author

EoleDev commented Aug 5, 2020

Hi @mateuszkornecki,
Thank you for this solution.

Unfortunately, it doesn't bring a solution to my problem.
In fact, when you are calling the ngOnDestroy() with the ViewChild,
you are destroying all the highcharts-chart component and not only the chart.

In your example, if you destroy, create and destroy again the chart you are not
able to recreate it again.
Would it not be easier to update the component to allow creation and destruction of the chart ?

Thanks again!

@mateuszkornecki
Copy link
Contributor

Then let's combine both solutions - destroy the chart using chart reference from the callback function (no the component one), and reset the component's chart object to allow chart's recreation. The highcharts-angular wrapper was build to be a lightweight component (it has literally just a few methods). It might be a good idea for enhancement if more users will request adding that functionality.

Live demo:
https://stackblitz.com/edit/highcharts-angular-basic-line-apwusy?file=src%2Fapp%2Fapp.component.ts

export class AppComponent {
  Highcharts: typeof Highcharts = Highcharts;
  @ViewChild('chart') componentRef;
  chartRef;
  updateFlag;

  chartOptions: Options = {
    series: [
      {
        type: "line",
        data: [1, 2, 3]
      }
    ]
  };

    chartCallback: Highcharts.ChartCallbackFunction = (chart) => {
    this.chartRef = chart;
  };

  createChart():void {
    this.updateFlag = true;
  }

  destroyChart():void {
    this.chartRef.destroy();
    this.componentRef.chart = null;
  }

}

@EoleDev
Copy link
Author

EoleDev commented Aug 10, 2020

Hi @mateuszkornecki,

With the current live demo, things are not working quite well.
I did some tests and after few changes, all is working well.

Changes :

  • in html : "[update]" => "[(update)]" to allow highcharts-chart to reset the update flag

  • in ts : I updated destroyChart function to

    if(this.chartRef)
      this.chartRef.destroy();
    this.chartRef = null;
    this.componentRef.chart = null;
    

In case the chart is not recreated, we don't try to destroy a previously destroyed chart.

This solution allow to destroy and recreate chart. Thanks for all!
As this solution doesn't feel quite clean (access to a private property of a child component)
maybe the implementation of the right API in the future would be a better solution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants