Skip to content

Commit e562f41

Browse files
authored
Merge pull request #416 from pmoleri/pmoleri/revert-insync-render
fix(): revert insync render
2 parents e963650 + db83fcd commit e562f41

File tree

2 files changed

+38
-13
lines changed

2 files changed

+38
-13
lines changed

projects/ng-apexcharts/src/lib/chart/chart.component.spec.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,29 @@ describe('ChartComponent', () => {
3232
await firstValueFrom(outputToObservable(component.chartReady));
3333
expect(fixture.debugElement.query(By.css('svg'))).toBeTruthy();
3434
});
35+
36+
it('update series does not re-create the chart', async () => {
37+
fixture.componentRef.setInput('chart', { type: 'line' });
38+
fixture.componentRef.setInput('series', [{ name: 'series1', data: [10, 20, 27] }]);
39+
fixture.componentRef.setInput('xaxis', { categories: ['Jan', 'Feb', 'Mar'] });
40+
await firstValueFrom(outputToObservable(component.chartReady));
41+
const chart1 = component.chartInstance();
42+
expect(chart1).toBeTruthy();
43+
expect(fixture.debugElement.queryAll(By.css('.apexcharts-series')).length).toBe(1);
44+
45+
const createElementSpy = spyOn(component as any, 'createElement').and.callThrough();
46+
47+
// Update the series
48+
fixture.componentRef.setInput('series', [{ name: 'series1', data: [10, 20, 30] }, { name: 'series2', data: [15, 25, 47] }]);
49+
await fixture.whenStable();
50+
51+
expect(createElementSpy).not.toHaveBeenCalled();
52+
const chart2 = component.chartInstance();
53+
expect(chart2).toBeTruthy();
54+
expect(chart1).withContext('Chart instances should be the same').toBe(chart2);
55+
56+
expect(fixture.debugElement.queryAll(By.css('.apexcharts-series')).length).toBe(2);
57+
});
3558
});
3659

3760
describe('when used inside conditional content projection component', () => {
@@ -99,7 +122,7 @@ class MockConditionalWrapperComponent {
99122
selector: 'mock-conditional-parent',
100123
template: `
101124
<mock-conditional-wrapper [show]="show()">
102-
<apx-chart [chart]="config" [series]="chartSeries" [xaxis]="xAxisDetails"></apx-chart>
125+
<apx-chart [chart]="config" [series]="chartSeries"></apx-chart>
103126
</mock-conditional-wrapper>
104127
`,
105128
imports: [ChartComponent, MockConditionalWrapperComponent],

projects/ng-apexcharts/src/lib/chart/chart.component.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { isPlatformBrowser } from "@angular/common";
22
import {
33
afterEveryRender,
4+
afterNextRender,
45
AfterRenderRef,
5-
AfterViewInit,
66
ChangeDetectionStrategy,
77
Component,
88
ElementRef,
@@ -56,7 +56,7 @@ declare global {
5656
changeDetection: ChangeDetectionStrategy.OnPush,
5757
standalone: true,
5858
})
59-
export class ChartComponent implements OnChanges, AfterViewInit, OnDestroy {
59+
export class ChartComponent implements OnChanges, OnDestroy {
6060
readonly chart = input<ApexChart>();
6161
readonly annotations = input<ApexAnnotations>();
6262
readonly colors = input<any[]>();
@@ -105,14 +105,7 @@ export class ChartComponent implements OnChanges, AfterViewInit, OnDestroy {
105105
ngOnChanges(changes: SimpleChanges): void {
106106
if (!this.isBrowser) return;
107107

108-
if (this.chartElement().nativeElement) {
109-
this.hydrate(changes);
110-
}
111-
}
112-
113-
ngAfterViewInit() {
114-
if (!this.isBrowser) return;
115-
this.createElement();
108+
this.hydrate(changes);
116109
}
117110

118111
ngOnDestroy() {
@@ -124,7 +117,12 @@ export class ChartComponent implements OnChanges, AfterViewInit, OnDestroy {
124117
private get isConnected() {
125118
return this.chartElement()?.nativeElement.isConnected;
126119
}
120+
127121
private hydrate(changes: SimpleChanges): void {
122+
if (this.waitingForConnectedRef) {
123+
return;
124+
}
125+
128126
const shouldUpdateSeries =
129127
this.chartInstance() &&
130128
this.autoUpdateSeries() &&
@@ -135,11 +133,15 @@ export class ChartComponent implements OnChanges, AfterViewInit, OnDestroy {
135133
return;
136134
}
137135

138-
this.createElement();
136+
// Create the chart after the layout is finalized and ready to be measured.
137+
afterNextRender({
138+
read: () => this.createElement(),
139+
}, { injector: this._injector });
139140
}
140141

141142
private async createElement() {
142-
window.ApexCharts ||= (await import("apexcharts")).default;
143+
const { default: ApexCharts } = await import("apexcharts");
144+
window.ApexCharts ||= ApexCharts;
143145

144146
if (this._destroyed) return;
145147
if (!this.isConnected) {

0 commit comments

Comments
 (0)