Open Robinyo opened 4 years ago
Hi @Robinyo
Thank you for suggesting the enhancement.
What will be required for the new feature to work? I imagine that a type-less version of the component could do the trick, but maybe there are other requirements? The import of Highcharts in the wrapper component is purely for TS definitions, so without them the import could be removed.
BTW: Nice article!
Hi @KacperMadej,
-> What will be required for the new feature to work?
"module": "esnext"
-> 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.
At the start of the file you will notice the following import statement:
import * as Highcharts from 'highcharts';
However, as the HighchartsChartComponent accepts Highcharts as an @Input() I commented out this line and I updated all references to Highcharts types to <any>.
-> 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 Rob
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?
legend: {
enabled: false
} as LegendOptions,
title: {
text: 'hello',
} as TitleOptions
...
+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
I can see more and more people voting for adding this functionality, and I can agree that it might be a pretty neat feature. However, we need to keep all available highcharts wrappers(highcharts-react-official
, highcharts-vue
...) consistent.
I will consult all possibilities with my colleagues responsible for other wrappers and post an update if anything changes regarding this feature.
Any update on this feature?
Unfortunately for now the solution posted by Robinyo is the only solution. https://github.com/highcharts/highcharts-angular/issues/163#issue-497372364
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 :disappointed:
@mateuszkornecki has anything changed on your side in the meantime ?
@PowerKiKi It is possible to import Highcharts
as ESM- see the demo.
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 HighchartsChartComponent
, instead of:
- @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 HighchartsESM
, and not Highcharts
, because non-ESM must not be used anymore in Angular ecosystem.
Then we can provide HIGHCHARTS
with a new built-in provider function provideHighcharts()
. The provider function would accept arguments to configure optional features with ease in a tree-shakable way.
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 provideHighcharts()
is used in the component itself, and not at the application level, makes it easy to be tree-shakable, as long as the route is lazy-loaded or the template is @defer
ed. It is overall even simpler to use and more idiomatic to Angular.
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 provideHighcharts()
and its arguments to be ESM and tree-shakeable.
@PowerKiKi Thank you for all the valid points!
I like the idea of provideHighcharts
! I'll try that then.
In the meantime please look at the repo where I use import()
to load Highcharts dynamically (without using highcharts-angular
).
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