-
Notifications
You must be signed in to change notification settings - Fork 117
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
Dynamically Import Highcharts #163
Comments
Hi @Robinyo Thank you for suggesting the enhancement. What will be required for the new feature to work? BTW: Nice article! |
Hi @KacperMadej, -> What will be required for the new feature to work?
-> I imagine that a type-less version of the component could do the trick? Yes, that's what I tried and its working for me.
-> The import of Highcharts in the wrapper component is purely for TS definitions, so without them the import could be removed. Yes. -> BTW: Nice article! Thanks :) Cheers |
Any update on ETA? |
Please vote up with your reaction ( 👍 ) on the opening comment of this issue thread to let us know how much the feature is requested. As far as I can tell right now, it looks like the changes would require creating another wrapper that will be a type-less version (when it comes to the Highcharts properties) to keep the code clean and clear. |
@Robinyo, Does this remove the ability to use HighCharts' types? For example, would it still be possible to specify types when creating a chart?
|
+1 |
Any updates on this feature? It would be great if we could dynamically load natively. In OP's example it looks like to use this in a component, you have to make a separate component that acts as an override for highcharts-angular. It would be stellar if we didn't have to make this go-between. |
@alexmuch |
Any update on this feature? |
Unfortunately for now the solution posted by Robinyo is the only solution. #163 (comment) |
Any updates on this one? |
Original article by @Robinyo is now available at https://rob-ferguson.me/dynamically-importing-highcharts/ Has anybody succeeded in using Highcharts with ESM and proper typing (what I'd consider bare minimum for an Angular app), and also lazy-loading the entire Highchart library to avoid the hit on Initial Total size ? I've been struggling with this issue on and off for months now. And everytime I only end up being frustrated by the state of this repos and lack of documentation for lazy loading the lib 😞 @mateuszkornecki has anything changed on your side in the meantime ? |
@PowerKiKi It is possible to import import Highcharts from 'highcharts/es-modules/masters/highcharts.src'; You are right we don't mention how to do it anywhere in the documentation. We will try to improve it and prepare a demo where we dynamically import Higcharts. |
@karolkolodziej one thing that would really improve usage of this lib would be to leverage Angular DI via providers. So in - @Input() Highcharts: typeof Highcharts | typeof HighchartsESM; we would have an injectable, so something more like: constructor(
private el: ElementRef,
private _zone: NgZone // #75
+ @Inject(HIGHCHARTS) Highcharts: typeof HighchartsESM,
) {} Notice how it only accepts Then we can provide So final usage for end-user would look more like: @Component({
selector: 'app-chart',
standalone: true,
template: `<highcharts-chart [options]="options" />`,
imports: [HighchartsChartComponent],
providers: [
provideHighcharts({
// ... some configuration here, included which modules should be included
}),
],
})
export class ChartComponent {
public options = {}; // ... real options here
public constructor(
@Inject(HIGHCHARTS) Highcharts: typeof HighchartsESM, // Optionally, if we need to access some functions provided by Highcharts in our component
) {
// not much to do...
}
} The fact that This kind of approach is used in ng2-charts since v6 with success. I think it should be adopted here too, or some similar alternatives. The only thing to figure out is how to write the new |
@PowerKiKi Thank you for all the valid points! In the meantime please look at the repo where I use |
I finally came up with a solution that is:
Most of the magic is in This is the kind of thing that I would like to have in the documentation, as the first (and only?) example of usage. import {Component} from '@angular/core';
import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src';
import type {Options} from 'highcharts';
import {HighchartsChartModule} from 'highcharts-angular';
let highcharts: typeof HighchartsESM | null = null;
async function loadHighcharts(): Promise<typeof HighchartsESM> {
if (!highcharts) {
// First load core
const core = await import('highcharts/es-modules/masters/highcharts.src').then(m => m.default);
highcharts = core;
// Then load all modules in parallel, and in an unspecified order
await Promise.all([
import('highcharts/es-modules/masters/highcharts-more.src'),
import('highcharts/es-modules/masters/modules/exporting.src'),
import('highcharts/es-modules/masters/modules/pattern-fill.src'),
import('highcharts/es-modules/masters/modules/gantt.src'),
]);
// Set some global options
core.setOptions({
lang: {
months: [
$localize`Janvier`,
$localize`Février`,
$localize`Mars`,
$localize`Avril`,
$localize`Mai`,
$localize`Juin`,
$localize`Juillet`,
$localize`Août`,
$localize`Septembre`,
$localize`Octobre`,
$localize`Novembre`,
$localize`Décembre`,
],
weekdays: [
$localize`Dimanche`,
$localize`Lundi`,
$localize`Mardi`,
$localize`Mercredi`,
$localize`Jeudi`,
$localize`Vendredi`,
$localize`Samedi`,
],
rangeSelectorFrom: $localize`De`,
rangeSelectorTo: $localize`À`,
rangeSelectorZoom: $localize`Zoom`,
},
});
}
return highcharts;
}
@Component({
selector: 'app-chart',
template: `
@if (Highcharts) {
<highcharts-chart
[Highcharts]="Highcharts"
[oneToOne]="true"
[options]="options"
/>
} @else {
<div>Loading...</div>
}
`,
standalone: true,
imports: [HighchartsChartModule],
})
export class ChartComponent {
public Highcharts: typeof HighchartsESM | null = null;
public options: Options = {
chart: {
renderTo: 'container',
},
title: {
text: 'My chart',
},
series: [
{
type: 'line',
data: [1, 2, 3, 4, 5],
},
],
};
public constructor() {
loadHighcharts().then(Highcharts => (this.Highcharts = Highcharts));
}
} |
Requested feature description
Take advantage of ECMAScript's support for dynamic import() in order to load Highcharts dynamically at runtime.
As we're using Angular and the Angular CLI uses webpack, we can rely on webpack to replace calls to import() with its own dynamic loading function.
See: Dynamically Importing Highcharts
The text was updated successfully, but these errors were encountered: