From 26827f1dd2334a42df48346e3624197a85e4347b Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:08:01 +0100 Subject: [PATCH 01/94] convert highcharts-chart.component.ts to standalone and deprecate module --- highcharts-angular/src/lib/highcharts-chart.component.ts | 3 ++- highcharts-angular/src/lib/highcharts-chart.module.ts | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.component.ts b/highcharts-angular/src/lib/highcharts-chart.component.ts index 8080a77..2b52479 100644 --- a/highcharts-angular/src/lib/highcharts-chart.component.ts +++ b/highcharts-angular/src/lib/highcharts-chart.component.ts @@ -5,7 +5,8 @@ import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; @Component({ selector: 'highcharts-chart', - template: '' + template: '', + standalone: true }) export class HighchartsChartComponent implements OnDestroy, OnChanges { @Input() Highcharts: typeof Highcharts | typeof HighchartsESM; diff --git a/highcharts-angular/src/lib/highcharts-chart.module.ts b/highcharts-angular/src/lib/highcharts-chart.module.ts index bf1fdc5..908fc77 100644 --- a/highcharts-angular/src/lib/highcharts-chart.module.ts +++ b/highcharts-angular/src/lib/highcharts-chart.module.ts @@ -1,8 +1,11 @@ import {NgModule} from '@angular/core'; import {HighchartsChartComponent} from './highcharts-chart.component'; +/** + * @deprecated Use `HighchartsChartComponent` directly instead. + */ @NgModule({ - declarations: [ HighchartsChartComponent ], + imports: [ HighchartsChartComponent ], exports: [ HighchartsChartComponent ] }) export class HighchartsChartModule {} From a5b12ab3096358d94ab7b28bb628fbdeacd18a43 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:10:55 +0100 Subject: [PATCH 02/94] correct test file --- src/app/tests/line-test/line-test.component.spec.ts | 3 +-- src/test.ts | 7 +------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/app/tests/line-test/line-test.component.spec.ts b/src/app/tests/line-test/line-test.component.spec.ts index 65687fc..f943af1 100644 --- a/src/app/tests/line-test/line-test.component.spec.ts +++ b/src/app/tests/line-test/line-test.component.spec.ts @@ -1,5 +1,4 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { BrowserModule } from '@angular/platform-browser'; import { LineTestComponent } from './line-test.component'; import { HighchartsChartModule } from '../../../../highcharts-angular/src/lib/highcharts-chart.module' @@ -36,7 +35,7 @@ describe('LineTestComponent', () => { it('should be properly updated', () => { const chart = component.Highcharts.charts[component.Highcharts.charts.length - 1]; - const series = chart.series[0] as unknown as Highcharts.SeriesLineOptions; + const series = chart.series[0] as unknown as Highcharts.Series; expect(series.color).toEqual('hotpink'); }); }); diff --git a/src/test.ts b/src/test.ts index b836d64..b69fb17 100644 --- a/src/test.ts +++ b/src/test.ts @@ -1,11 +1,6 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files -import 'zone.js/dist/long-stack-trace-zone'; -import 'zone.js/dist/proxy.js'; -import 'zone.js/dist/sync-test'; -import 'zone.js/dist/jasmine-patch'; -import 'zone.js/dist/async-test'; -import 'zone.js/dist/fake-async-test'; +import 'zone.js/testing'; import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, From b3e96dbf7a21ffbc677581fd6931fb46e755fdb9 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:18:00 +0100 Subject: [PATCH 03/94] mv to ng17 --- angular.json | 8 ++++---- highcharts-angular/package.json | 4 ++-- package.json | 30 +++++++++++++++--------------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/angular.json b/angular.json index ea7dfb4..b9dc6fb 100644 --- a/angular.json +++ b/angular.json @@ -62,18 +62,18 @@ "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { - "browserTarget": "my-app:build" + "buildTarget": "my-app:build" }, "configurations": { "production": { - "browserTarget": "my-app:build:production" + "buildTarget": "my-app:build:production" } } }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { - "browserTarget": "my-app:build" + "buildTarget": "my-app:build" } }, "test": { @@ -134,7 +134,7 @@ "polyfills": "src/polyfills.ts", "tsConfig": "./tsconfig.spec.json", "scripts": [], - "styles": [], + "styles": [] } } } diff --git a/highcharts-angular/package.json b/highcharts-angular/package.json index a6f07ad..f1d815e 100644 --- a/highcharts-angular/package.json +++ b/highcharts-angular/package.json @@ -19,8 +19,8 @@ "angular" ], "peerDependencies": { - "@angular/common": ">=16.0.0", - "@angular/core": ">=16.0.0", + "@angular/common": ">=17.0.0", + "@angular/core": ">=17.0.0", "highcharts": ">=9.0.0" }, "dependencies": { diff --git a/package.json b/package.json index aeaddf9..7c7effc 100644 --- a/package.json +++ b/package.json @@ -17,14 +17,14 @@ "e2e": "ng e2e" }, "dependencies": { - "@angular/animations": "16.2.12", - "@angular/common": "16.2.12", - "@angular/compiler": "16.2.12", - "@angular/core": "16.2.12", - "@angular/forms": "16.2.12", - "@angular/platform-browser": "16.2.12", - "@angular/platform-browser-dynamic": "16.2.12", - "@angular/router": "16.2.12", + "@angular/animations": "17.3.12", + "@angular/common": "17.3.12", + "@angular/compiler": "17.3.12", + "@angular/core": "17.3.12", + "@angular/forms": "17.3.12", + "@angular/platform-browser": "17.3.12", + "@angular/platform-browser-dynamic": "17.3.12", + "@angular/router": "17.3.12", "@highcharts/map-collection": "^1.1.3", "core-js": "^3.19.2", "highcharts": "^11.2.0", @@ -33,13 +33,13 @@ "proj4": "^2.7.5", "rxjs": "^7.4.0", "tslib": "^2.3.1", - "zone.js": "~0.13.3" + "zone.js": "~0.14.10" }, "devDependencies": { - "@angular-devkit/build-angular": "^16.2.9", - "@angular-eslint/schematics": "^16.2.0", - "@angular/cli": "16.2.9", - "@angular/compiler-cli": "16.2.12", + "@angular-devkit/build-angular": "^17.3.11", + "@angular-eslint/schematics": "^17.5.3", + "@angular/cli": "17.3.11", + "@angular/compiler-cli": "17.3.12", "@types/estree": "^1.0.0", "@types/jasmine": "3.10.2", "@types/jasminewd2": "2.0.10", @@ -52,12 +52,12 @@ "karma-coverage-istanbul-reporter": "~3.0.3", "karma-jasmine": "~4.0.1", "karma-jasmine-html-reporter": "^1.7.0", - "ng-packagr": "^16.2.3", + "ng-packagr": "^17.3.0", "node-sass": "7.0.1", "protractor": "~7.0.0", "standard-version": "^9.3.2", "ts-node": "^10.4.0", "tslint": "~6.1.0", - "typescript": "5.1.6" + "typescript": "5.4.5" } } From 61270819c71ba075021629fa05ec228c6f705669 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:18:32 +0100 Subject: [PATCH 04/94] release 5.0.0-alpha.1 --- highcharts-angular/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highcharts-angular/package.json b/highcharts-angular/package.json index f1d815e..e9bcb43 100644 --- a/highcharts-angular/package.json +++ b/highcharts-angular/package.json @@ -1,7 +1,7 @@ { "name": "highcharts-angular", "description": "Highcharts component for Angular.", - "version": "4.0.1", + "version": "5.0.0-alpha.1", "license": "MIT", "author": "Black Label (http://blacklabel.pl)", "bugs": { From e90e3984ea1ba937cbee5ba37a5235e7a38288f3 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:25:22 +0100 Subject: [PATCH 05/94] use the new control flow --- src/app/line-chart/line-chart.component.html | 17 +++++++++-------- src/app/line-chart/line-chart.component.ts | 4 ++-- src/app/stock-chart/stock-chart.component.html | 13 +++++++------ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/app/line-chart/line-chart.component.html b/src/app/line-chart/line-chart.component.html index 9140452..a6a528b 100644 --- a/src/app/line-chart/line-chart.component.html +++ b/src/app/line-chart/line-chart.component.html @@ -8,12 +8,13 @@

Demo #1: Highcharts with a basic editor

- + @if (showChart) { + + } diff --git a/src/app/line-chart/line-chart.component.ts b/src/app/line-chart/line-chart.component.ts index 71fffc7..42ae0fd 100644 --- a/src/app/line-chart/line-chart.component.ts +++ b/src/app/line-chart/line-chart.component.ts @@ -14,7 +14,7 @@ export class LineChartComponent { public showChart = true; public toggleButtonTitle = "Destroy chart"; - private optFromInputString = ` + public optFromInputString = ` { "title": { "text": "Highcharts chart" }, "series": [{ @@ -29,7 +29,7 @@ export class LineChartComponent { }] } `; - private optFromInput: Highcharts.Options = JSON.parse( + public optFromInput: Highcharts.Options = JSON.parse( this.optFromInputString, ); private seriesTypes = { diff --git a/src/app/stock-chart/stock-chart.component.html b/src/app/stock-chart/stock-chart.component.html index 6a0c3a4..aa67e6d 100644 --- a/src/app/stock-chart/stock-chart.component.html +++ b/src/app/stock-chart/stock-chart.component.html @@ -2,17 +2,19 @@

Demo #2: Highcharts Stock with simple updates

Chart title text:

-

Data sets:

- + @for (i of [0,1,2]; track i) { + + }
Demo #2: Highcharts Stock with simple updates [(update)]="updateDemo2" >
- \ No newline at end of file From b52b80f0d8d7e5d54dae5f5f795d001b6bc8d77c Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:27:42 +0100 Subject: [PATCH 06/94] remove polyfills.ts --- angular.json | 6 +++--- src/main.ts | 1 - src/polyfills.ts | 51 ---------------------------------------------- tsconfig.app.json | 3 +-- tsconfig.spec.json | 3 +-- 5 files changed, 5 insertions(+), 59 deletions(-) delete mode 100644 src/polyfills.ts diff --git a/angular.json b/angular.json index b9dc6fb..530aa27 100644 --- a/angular.json +++ b/angular.json @@ -19,7 +19,7 @@ "index": "src/index.html", "main": "src/main.ts", "tsConfig": "./tsconfig.app.json", - "polyfills": "src/polyfills.ts", + "polyfills": ["core-js/es/reflect", "zone.js"], "assets": [ "src/assets", "src/favicon.ico" @@ -81,7 +81,7 @@ "options": { "main": "src/test.ts", "karmaConfig": "./karma.conf.js", - "polyfills": "src/polyfills.ts", + "polyfills": ["core-js/es/reflect", "zone.js"], "tsConfig": "./tsconfig.spec.json", "scripts": [], "styles": [], @@ -131,7 +131,7 @@ "options": { "main": "src/test.ts", "karmaConfig": "./karma.conf.js", - "polyfills": "src/polyfills.ts", + "polyfills": ["core-js/es/reflect", "zone.js"], "tsConfig": "./tsconfig.spec.json", "scripts": [], "styles": [] diff --git a/src/main.ts b/src/main.ts index 768c2b5..8e5a596 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,3 @@ -import "./polyfills"; import { enableProdMode } from "@angular/core"; import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; import { AppModule } from "./app/app.module"; diff --git a/src/polyfills.ts b/src/polyfills.ts deleted file mode 100644 index 51d09fe..0000000 --- a/src/polyfills.ts +++ /dev/null @@ -1,51 +0,0 @@ -/** - * This file includes polyfills needed by Angular and is loaded before the app. - * You can add your own extra polyfills to this file. - * - * This file is divided into 2 sections: - * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. - * 2. Application imports. Files imported after ZoneJS that should be loaded before your main - * file. - * - * The current setup is for so-called "evergreen" browsers; the last versions of browsers that - * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), - * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. - * - * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html - */ - -/*************************************************************************************************** - * BROWSER POLYFILLS - */ - -/** IE9, IE10 and IE11 requires all of the following polyfills. **/ -// import 'core-js/es6/symbol'; -// import 'core-js/es6/object'; -// import 'core-js/es6/function'; -// import 'core-js/es6/parse-int'; -// import 'core-js/es6/parse-float'; -// import 'core-js/es6/number'; -// import 'core-js/es6/math'; -// import 'core-js/es6/string'; -// import 'core-js/es6/date'; -// import 'core-js/es6/array'; -// import 'core-js/es6/regexp'; -// import 'core-js/es6/map'; -// import 'core-js/es6/set'; - -/** Evergreen browsers require these. **/ -import "core-js/es/reflect"; -/*************************************************************************************************** - * Zone JS is required by Angular itself. - */ -import "zone.js"; // Included with Angular CLI. - -/*************************************************************************************************** - * APPLICATION IMPORTS - */ - -/** - * Date, currency, decimal and percent pipes. - * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 - */ -// import 'intl'; // Run `npm install --save intl`. diff --git a/tsconfig.app.json b/tsconfig.app.json index a481e2a..05ade5b 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -14,7 +14,6 @@ } }, "files": [ - "src/main.ts", - "src/polyfills.ts" + "src/main.ts" ] } diff --git a/tsconfig.spec.json b/tsconfig.spec.json index b04b2ef..54e6791 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -13,8 +13,7 @@ ] }, "files": [ - "src/test.ts", - "src/polyfills.ts" + "src/test.ts" ], "include": [ "src/**/*.spec.ts", From 39e4e8560a47cfdc74116d2fd1ed87191404e97f Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:33:12 +0100 Subject: [PATCH 07/94] use standalone component instead of module --- src/app/app.module.ts | 23 ++++++++++--------- .../line-test/line-test.component.spec.ts | 4 ++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index d760794..efb6e34 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,21 +1,22 @@ -import { HttpClientModule } from "@angular/common/http"; -import { NgModule } from "@angular/core"; -import { FormsModule } from "@angular/forms"; -import { BrowserModule } from "@angular/platform-browser"; -import { HighchartsChartModule } from "highcharts-angular"; -import { AppComponent } from "./app.component"; -import { LineChartComponent } from "./line-chart/line-chart.component"; -import { StockChartComponent } from "./stock-chart/stock-chart.component"; -import { MapChartComponent } from "./map-chart/map-chart.component"; -import { GanttChartComponent } from "./gantt-chart/gantt-chart.component"; +import { HttpClientModule } from '@angular/common/http'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { BrowserModule } from '@angular/platform-browser'; +import { HighchartsChartComponent } from 'highcharts-angular'; +import { AppComponent } from './app.component'; +import { LineChartComponent } from './line-chart/line-chart.component'; +import { StockChartComponent } from './stock-chart/stock-chart.component'; +import { MapChartComponent } from './map-chart/map-chart.component'; +import { GanttChartComponent } from './gantt-chart/gantt-chart.component'; import { LazyLoadingChartComponent } from './lazy-loading-chart/lazy-loading-chart.component'; import { LineTestComponent } from './tests/line-test/line-test.component'; + @NgModule({ declarations: [AppComponent, LineChartComponent, StockChartComponent, MapChartComponent, GanttChartComponent, LazyLoadingChartComponent, LineTestComponent], imports: [ BrowserModule, FormsModule, - HighchartsChartModule, + HighchartsChartComponent, HttpClientModule, ], providers: [], diff --git a/src/app/tests/line-test/line-test.component.spec.ts b/src/app/tests/line-test/line-test.component.spec.ts index f943af1..d32e83f 100644 --- a/src/app/tests/line-test/line-test.component.spec.ts +++ b/src/app/tests/line-test/line-test.component.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { LineTestComponent } from './line-test.component'; -import { HighchartsChartModule } from '../../../../highcharts-angular/src/lib/highcharts-chart.module' +import { HighchartsChartComponent } from '../../../../highcharts-angular/src/lib/highcharts-chart.component' describe('LineTestComponent', () => { @@ -9,7 +9,7 @@ describe('LineTestComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [ HighchartsChartModule ], + imports: [ HighchartsChartComponent ], declarations: [ LineTestComponent ] }) .compileComponents(); From 6c502ecaca9240156a166089729e80f515f272ca Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:33:20 +0100 Subject: [PATCH 08/94] update README.md --- README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index d37e6bc..1558b84 100644 --- a/README.md +++ b/README.md @@ -32,12 +32,13 @@ Official minimal Highcharts integration for Angular Make sure you have **node**, **NPM** and **Angular** up to date. -| Version | Node | Angular | Highcharts | -|---------------|---------------|---------------|---------------| -| 4.0.0 | >=16.14 | >=16.0.0 | >=11.0.0 | -| 3.1.2 | >=14.13 | >=15.0.0 | >=10.3.3 | -| 3.0.0 | >=14.13 | >=9.0.0 | >=8.0.0 | -| <2.10.0 | >=6.10.2 | >=6.0.0 | >=6.0.0 | +| Version | Node | Angular | Highcharts | +|---------|----------|----------|---------------| +| 5.0.0 | >=18.14 | >=17.0.0 | >=11.0.0 | +| 4.0.0 | >=16.14 | >=16.0.0 | >=11.0.0 | +| 3.1.2 | >=14.13 | >=15.0.0 | >=10.3.3 | +| 3.0.0 | >=14.13 | >=9.0.0 | >=8.0.0 | +| <2.10.0 | >=6.10.2 | >=6.0.0 | >=6.0.0 | ### Installing @@ -48,16 +49,16 @@ Get package from NPM in your Angular app: npm install highcharts-angular --save ``` -In your app.module.ts add the HighchartsChartModule: +In your app.module.ts add the HighchartsChartComponent: ```ts ... -import { HighchartsChartModule } from 'highcharts-angular'; +import { HighchartsChartComponent } from 'highcharts-angular'; @NgModule({ imports: [ ... - HighchartsChartModule + HighchartsChartComponent, ``` In a component that will be building your Highcharts charts you will need to [import Highcharts](https://www.highcharts.com/docs/getting-started/install-from-npm) first, so in system console, while in your Angular app: From 85fb9a5b2d661456d342eb02eb76c6e5328585f1 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:34:04 +0100 Subject: [PATCH 09/94] update to node 18 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7c7effc..2452864 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@types/estree": "^1.0.0", "@types/jasmine": "3.10.2", "@types/jasminewd2": "2.0.10", - "@types/node": "^16.11.11", + "@types/node": "^18.19.64", "codelyzer": "^6.0.2", "jasmine-core": "~3.10.1", "jasmine-spec-reporter": "~7.0.0", From 6a80fe1aa7df22398fd85c62d57b0ac26bb068a4 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:39:40 +0100 Subject: [PATCH 10/94] lint file --- src/app/line-chart/line-chart.component.ts | 79 +++++++++++----------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/src/app/line-chart/line-chart.component.ts b/src/app/line-chart/line-chart.component.ts index 42ae0fd..c8db842 100644 --- a/src/app/line-chart/line-chart.component.ts +++ b/src/app/line-chart/line-chart.component.ts @@ -1,18 +1,18 @@ -import { Component } from "@angular/core"; -import * as Highcharts from "highcharts"; -import HC_customEvents from "highcharts-custom-events"; +import { Component } from '@angular/core'; +import * as Highcharts from 'highcharts'; +import HC_customEvents from 'highcharts-custom-events'; HC_customEvents(Highcharts); @Component({ - selector: "app-line-chart", - templateUrl: "./line-chart.component.html", - styleUrls: ["./line-chart.component.css"], + selector: 'app-line-chart', + templateUrl: './line-chart.component.html', + styleUrls: ['./line-chart.component.css'], }) export class LineChartComponent { - public Highcharts: typeof Highcharts = Highcharts; - public updateFromInput = false; - public showChart = true; - public toggleButtonTitle = "Destroy chart"; + public Highcharts: typeof Highcharts = Highcharts; + public updateFromInput = false; + public showChart = true; + public toggleButtonTitle = 'Destroy chart'; public optFromInputString = ` { @@ -29,39 +29,36 @@ export class LineChartComponent { }] } `; - public optFromInput: Highcharts.Options = JSON.parse( - this.optFromInputString, - ); - private seriesTypes = { - line: "column", - column: "scatter", - scatter: "spline", - spline: "line", - }; + public optFromInput: Highcharts.Options = JSON.parse(this.optFromInputString); + private seriesTypes = { + line: 'column', + column: 'scatter', + scatter: 'spline', + spline: 'line', + }; - // Demonstrate chart instance - public logChartInstance(chart: Highcharts.Chart) { - if (chart) { - console.log("Chart instance received:", chart); - } else { - console.log("Chart instance destroyed"); - } - } + // Demonstrate chart instance + public logChartInstance(chart: Highcharts.Chart) { + if (chart) { + console.log('Chart instance received:', chart); + } else { + console.log('Chart instance destroyed'); + } + } - public updateInputChart() { - this.optFromInput = JSON.parse(this.optFromInputString); - } + public updateInputChart() { + this.optFromInput = JSON.parse(this.optFromInputString); + } - public toggleSeriesType(index = 0) { - this.optFromInput.series[index].type = this.seriesTypes[ - this.optFromInput.series[index].type || "line" - ] as keyof typeof this.seriesTypes; - // nested change - must trigger update - this.updateFromInput = true; - } + public toggleSeriesType(index = 0) { + this.optFromInput.series[index].type = this.seriesTypes[ + this.optFromInput.series[index].type || 'line'] as keyof typeof this.seriesTypes; + // nested change - must trigger update + this.updateFromInput = true; + } - public toggleChart() { - this.showChart = !this.showChart; - this.toggleButtonTitle = this.showChart ? "Destroy chart" : "Recreate chart"; - } + public toggleChart() { + this.showChart = !this.showChart; + this.toggleButtonTitle = this.showChart ? 'Destroy chart' : 'Recreate chart'; + } } From 39ee094dc6375c9ff9754a2f169b95297b915f8c Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:41:09 +0100 Subject: [PATCH 11/94] update to es2020 --- highcharts-angular/tsconfig.lib.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/highcharts-angular/tsconfig.lib.json b/highcharts-angular/tsconfig.lib.json index a4a00f8..d5d0446 100644 --- a/highcharts-angular/tsconfig.lib.json +++ b/highcharts-angular/tsconfig.lib.json @@ -4,7 +4,7 @@ "baseUrl": ".", "outDir": "../out-tsc/lib", "declarationMap": true, - "module": "es2015", + "module": "es2020", "moduleResolution": "node", "declaration": true, "sourceMap": true, @@ -13,7 +13,7 @@ "importHelpers": true, "lib": [ "dom", - "es2015" + "es2020" ] }, "angularCompilerOptions": { From 89a7343929bcf1cb0b8d1bffad830a347302c207 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:42:19 +0100 Subject: [PATCH 12/94] fix tslint issue --- src/app/app.component.ts | 2 +- src/app/apple-data.service.ts | 4 ++-- src/app/map-chart/map-chart.component.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index f569eaa..aff4c90 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -3,7 +3,7 @@ declare var require: any; import { Component } from '@angular/core'; import ExportingModule from 'highcharts/modules/exporting'; import SunsetTheme from 'highcharts/themes/sunset.js'; -import * as Highcharts from "highcharts"; +import * as Highcharts from 'highcharts'; // The modules will work for all charts. ExportingModule(Highcharts); diff --git a/src/app/apple-data.service.ts b/src/app/apple-data.service.ts index 1c5be71..d1416ce 100644 --- a/src/app/apple-data.service.ts +++ b/src/app/apple-data.service.ts @@ -22,7 +22,7 @@ export class AppleDataService { } errorHandler(error: HttpErrorResponse) { - return throwError(error.message || "server error."); + return throwError(error.message || 'server error.'); } -} \ No newline at end of file +} diff --git a/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts index 461d7e7..aa7f968 100644 --- a/src/app/map-chart/map-chart.component.ts +++ b/src/app/map-chart/map-chart.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import * as Highcharts from 'highcharts'; import HC_map from 'highcharts/modules/map'; -import worldMap from "@highcharts/map-collection/custom/world.geo.json"; +import worldMap from '@highcharts/map-collection/custom/world.geo.json'; import proj4 from 'proj4'; HC_map(Highcharts); From 6118a1521f5a8f4cb71a234ee8fd0171f77c7eb5 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:42:46 +0100 Subject: [PATCH 13/94] fix tslint issue --- src/main.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.ts b/src/main.ts index 8e5a596..1482cad 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,7 @@ -import { enableProdMode } from "@angular/core"; -import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; -import { AppModule } from "./app/app.module"; -import { environment } from "./environments/environment"; +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; if (environment.production) { enableProdMode(); From ded9d70ce1a91a370e42b01f1d79ba2ddb580dbe Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:48:13 +0100 Subject: [PATCH 14/94] fix tslint issue --- highcharts-angular/src/test.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/highcharts-angular/src/test.ts b/highcharts-angular/src/test.ts index 25c8e10..5ffcd58 100644 --- a/highcharts-angular/src/test.ts +++ b/highcharts-angular/src/test.ts @@ -1,13 +1,11 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files -import { getTestBed } from "@angular/core/testing"; +import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting -} from "@angular/platform-browser-dynamic/testing"; -import "core-js/es/reflect"; -import "zone.js"; -import "zone.js/testing"; +} from '@angular/platform-browser-dynamic/testing'; +import 'zone.js/testing'; declare const require: any; @@ -17,6 +15,6 @@ getTestBed().initTestEnvironment( platformBrowserDynamicTesting() ); // Then we find all the tests. -const context = require.context("./", true, /\.spec\.ts$/); +const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. context.keys().map(context); From 1ee8f7b56e539d55a3ca3d26efa12dc42e04319e Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:48:34 +0100 Subject: [PATCH 15/94] use new output function instead of decorator --- highcharts-angular/src/lib/highcharts-chart.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.component.ts b/highcharts-angular/src/lib/highcharts-chart.component.ts index 2b52479..2cb7144 100644 --- a/highcharts-angular/src/lib/highcharts-chart.component.ts +++ b/highcharts-angular/src/lib/highcharts-chart.component.ts @@ -1,5 +1,5 @@ import type { OnChanges, OnDestroy } from '@angular/core'; -import { Component, ElementRef, EventEmitter, Input, Output, NgZone, SimpleChanges } from '@angular/core'; +import { Component, ElementRef, EventEmitter, Input, Output, output, NgZone, SimpleChanges } from '@angular/core'; import type * as Highcharts from 'highcharts'; import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; @@ -18,7 +18,7 @@ export class HighchartsChartComponent implements OnDestroy, OnChanges { @Input() update: boolean; @Output() updateChange = new EventEmitter(true); - @Output() chartInstance = new EventEmitter(); // #26 + chartInstance = output(); // #26 private chart: Highcharts.Chart | null; From f1517dd12ec19f2ae594823cb95c25e39ee8f04b Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:50:44 +0100 Subject: [PATCH 16/94] use model signal to handle input/output --- highcharts-angular/src/lib/highcharts-chart.component.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.component.ts b/highcharts-angular/src/lib/highcharts-chart.component.ts index 2cb7144..fb3e8b1 100644 --- a/highcharts-angular/src/lib/highcharts-chart.component.ts +++ b/highcharts-angular/src/lib/highcharts-chart.component.ts @@ -1,5 +1,5 @@ import type { OnChanges, OnDestroy } from '@angular/core'; -import { Component, ElementRef, EventEmitter, Input, Output, output, NgZone, SimpleChanges } from '@angular/core'; +import { Component, ElementRef, OutputEmitterRef, Input, output, model, NgZone, SimpleChanges } from '@angular/core'; import type * as Highcharts from 'highcharts'; import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; @@ -15,10 +15,9 @@ export class HighchartsChartComponent implements OnDestroy, OnChanges { @Input() oneToOne: boolean; // #20 @Input() runOutsideAngular: boolean; // #75 @Input() options: Highcharts.Options | HighchartsESM.Options; - @Input() update: boolean; + update = model(); - @Output() updateChange = new EventEmitter(true); - chartInstance = output(); // #26 + chartInstance: OutputEmitterRef = output(); // #26 private chart: Highcharts.Chart | null; @@ -32,7 +31,7 @@ export class HighchartsChartComponent implements OnDestroy, OnChanges { if (changes.options || update) { this.wrappedUpdateOrCreateChart(); if (update) { - this.updateChange.emit(false); // clear the flag after update + this.update.set(false); // clear the flag after update } } } From c1e7b2dbad37d97b0325ce25dc2b49dd16ba64b7 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:54:14 +0100 Subject: [PATCH 17/94] use destroyRef instead of OnDestroy hook --- .../src/lib/highcharts-chart.component.ts | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.component.ts b/highcharts-angular/src/lib/highcharts-chart.component.ts index fb3e8b1..240d9a3 100644 --- a/highcharts-angular/src/lib/highcharts-chart.component.ts +++ b/highcharts-angular/src/lib/highcharts-chart.component.ts @@ -1,5 +1,5 @@ -import type { OnChanges, OnDestroy } from '@angular/core'; -import { Component, ElementRef, OutputEmitterRef, Input, output, model, NgZone, SimpleChanges } from '@angular/core'; +import type { OnChanges } from '@angular/core'; +import { Component, ElementRef, OutputEmitterRef, Input, output, model, NgZone, SimpleChanges, DestroyRef, inject } from '@angular/core'; import type * as Highcharts from 'highcharts'; import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; @@ -8,7 +8,7 @@ import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; template: '', standalone: true }) -export class HighchartsChartComponent implements OnDestroy, OnChanges { +export class HighchartsChartComponent implements OnChanges { @Input() Highcharts: typeof Highcharts | typeof HighchartsESM; @Input() constructorType: string; @Input() callbackFunction: Highcharts.ChartCallbackFunction; @@ -21,10 +21,22 @@ export class HighchartsChartComponent implements OnDestroy, OnChanges { private chart: Highcharts.Chart | null; + destroyRef = inject(DestroyRef); + constructor( private el: ElementRef, private _zone: NgZone // #75 - ) {} + ) { + this.destroyRef.onDestroy(() => { // #44 + if (this.chart) { // #56 + this.chart.destroy(); + this.chart = null; + + // emit chart instance on destroy + this.chartInstance.emit(this.chart); + } + }); + } ngOnChanges(changes: SimpleChanges): void { const update = changes.update?.currentValue; @@ -60,14 +72,4 @@ export class HighchartsChartComponent implements OnDestroy, OnChanges { this.chartInstance.emit(this.chart); } } - - ngOnDestroy() { // #44 - if (this.chart) { // #56 - this.chart.destroy(); - this.chart = null; - - // emit chart instance on destroy - this.chartInstance.emit(this.chart); - } - } } From 26a844dbb5f924f02b86ed832ab053190872cc54 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Thu, 21 Nov 2024 23:58:44 +0100 Subject: [PATCH 18/94] convert to Signal Input --- .../src/lib/highcharts-chart.component.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.component.ts b/highcharts-angular/src/lib/highcharts-chart.component.ts index 240d9a3..0e18571 100644 --- a/highcharts-angular/src/lib/highcharts-chart.component.ts +++ b/highcharts-angular/src/lib/highcharts-chart.component.ts @@ -1,5 +1,5 @@ import type { OnChanges } from '@angular/core'; -import { Component, ElementRef, OutputEmitterRef, Input, output, model, NgZone, SimpleChanges, DestroyRef, inject } from '@angular/core'; +import { Component, ElementRef, OutputEmitterRef, input, output, model, NgZone, SimpleChanges, DestroyRef, inject } from '@angular/core'; import type * as Highcharts from 'highcharts'; import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; @@ -9,12 +9,12 @@ import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; standalone: true }) export class HighchartsChartComponent implements OnChanges { - @Input() Highcharts: typeof Highcharts | typeof HighchartsESM; - @Input() constructorType: string; - @Input() callbackFunction: Highcharts.ChartCallbackFunction; - @Input() oneToOne: boolean; // #20 - @Input() runOutsideAngular: boolean; // #75 - @Input() options: Highcharts.Options | HighchartsESM.Options; + Highcharts = input(); + constructorType = input(); + callbackFunction = input(); + oneToOne = input(); // #20 + runOutsideAngular = input(); // #75 + options = input(); update = model(); chartInstance: OutputEmitterRef = output(); // #26 @@ -49,7 +49,7 @@ export class HighchartsChartComponent implements OnChanges { } wrappedUpdateOrCreateChart() { // #75 - if (this.runOutsideAngular) { + if (this.runOutsideAngular()) { this._zone.runOutsideAngular(() => { this.updateOrCreateChart() }); @@ -60,12 +60,12 @@ export class HighchartsChartComponent implements OnChanges { updateOrCreateChart() { if (this.chart?.update) { - this.chart.update(this.options, true, this.oneToOne || false); + this.chart.update(this.options(), true, this.oneToOne() || false); } else { - this.chart = this.Highcharts[this.constructorType || 'chart']( + this.chart = this.Highcharts()[this.constructorType() || 'chart']( this.el.nativeElement, - this.options, - this.callbackFunction || null + this.options(), + this.callbackFunction() || null ); // emit chart instance on init From 51a3ae8e9d452876f9b96f25e3d3f8d03dcfa0bd Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 00:12:20 +0100 Subject: [PATCH 19/94] add new packages --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index 2452864..fea9162 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,9 @@ "zone.js": "~0.14.10" }, "devDependencies": { + "@angular-devkit/core": "^17.3.11", "@angular-devkit/build-angular": "^17.3.11", + "@angular-devkit/schematics": "^17.3.11", "@angular-eslint/schematics": "^17.5.3", "@angular/cli": "17.3.11", "@angular/compiler-cli": "17.3.12", From 84187e21351b0444482ccbdd83e5304a4db54db2 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 00:17:57 +0100 Subject: [PATCH 20/94] remove unused packages --- package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/package.json b/package.json index fea9162..75ad52f 100644 --- a/package.json +++ b/package.json @@ -36,10 +36,7 @@ "zone.js": "~0.14.10" }, "devDependencies": { - "@angular-devkit/core": "^17.3.11", "@angular-devkit/build-angular": "^17.3.11", - "@angular-devkit/schematics": "^17.3.11", - "@angular-eslint/schematics": "^17.5.3", "@angular/cli": "17.3.11", "@angular/compiler-cli": "17.3.12", "@types/estree": "^1.0.0", From df279db9930ad8b321b6f0f40a6aeb2c1d871467 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 00:38:52 +0100 Subject: [PATCH 21/94] mv to ng 18 --- README.md | 2 +- highcharts-angular/package.json | 6 +++--- package.json | 24 ++++++++++++------------ src/app/app.module.ts | 5 ++--- tsconfig.json | 3 +-- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 1558b84..499e381 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Make sure you have **node**, **NPM** and **Angular** up to date. | Version | Node | Angular | Highcharts | |---------|----------|----------|---------------| -| 5.0.0 | >=18.14 | >=17.0.0 | >=11.0.0 | +| 5.0.0 | >=18.14 | >=18.0.0 | >=11.0.0 | | 4.0.0 | >=16.14 | >=16.0.0 | >=11.0.0 | | 3.1.2 | >=14.13 | >=15.0.0 | >=10.3.3 | | 3.0.0 | >=14.13 | >=9.0.0 | >=8.0.0 | diff --git a/highcharts-angular/package.json b/highcharts-angular/package.json index e9bcb43..f805861 100644 --- a/highcharts-angular/package.json +++ b/highcharts-angular/package.json @@ -1,7 +1,7 @@ { "name": "highcharts-angular", "description": "Highcharts component for Angular.", - "version": "5.0.0-alpha.1", + "version": "5.0.0-alpha.2", "license": "MIT", "author": "Black Label (http://blacklabel.pl)", "bugs": { @@ -19,8 +19,8 @@ "angular" ], "peerDependencies": { - "@angular/common": ">=17.0.0", - "@angular/core": ">=17.0.0", + "@angular/common": ">=18.0.0", + "@angular/core": ">=18.0.0", "highcharts": ">=9.0.0" }, "dependencies": { diff --git a/package.json b/package.json index 75ad52f..5eb99a3 100644 --- a/package.json +++ b/package.json @@ -17,14 +17,14 @@ "e2e": "ng e2e" }, "dependencies": { - "@angular/animations": "17.3.12", - "@angular/common": "17.3.12", - "@angular/compiler": "17.3.12", - "@angular/core": "17.3.12", - "@angular/forms": "17.3.12", - "@angular/platform-browser": "17.3.12", - "@angular/platform-browser-dynamic": "17.3.12", - "@angular/router": "17.3.12", + "@angular/animations": "18.2.12", + "@angular/common": "18.2.12", + "@angular/compiler": "18.2.12", + "@angular/core": "18.2.12", + "@angular/forms": "18.2.12", + "@angular/platform-browser": "18.2.12", + "@angular/platform-browser-dynamic": "18.2.12", + "@angular/router": "18.2.12", "@highcharts/map-collection": "^1.1.3", "core-js": "^3.19.2", "highcharts": "^11.2.0", @@ -36,9 +36,9 @@ "zone.js": "~0.14.10" }, "devDependencies": { - "@angular-devkit/build-angular": "^17.3.11", - "@angular/cli": "17.3.11", - "@angular/compiler-cli": "17.3.12", + "@angular-devkit/build-angular": "^18.2.12", + "@angular/cli": "18.2.12", + "@angular/compiler-cli": "18.2.12", "@types/estree": "^1.0.0", "@types/jasmine": "3.10.2", "@types/jasminewd2": "2.0.10", @@ -51,7 +51,7 @@ "karma-coverage-istanbul-reporter": "~3.0.3", "karma-jasmine": "~4.0.1", "karma-jasmine-html-reporter": "^1.7.0", - "ng-packagr": "^17.3.0", + "ng-packagr": "^18.2.1", "node-sass": "7.0.1", "protractor": "~7.0.0", "standard-version": "^9.3.2", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index efb6e34..4c7dce0 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,4 +1,4 @@ -import { HttpClientModule } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { BrowserModule } from '@angular/platform-browser'; @@ -17,9 +17,8 @@ import { LineTestComponent } from './tests/line-test/line-test.component'; BrowserModule, FormsModule, HighchartsChartComponent, - HttpClientModule, ], - providers: [], + providers: [provideHttpClient(withInterceptorsFromDi())], bootstrap: [AppComponent] }) export class AppModule {} diff --git a/tsconfig.json b/tsconfig.json index 73c5142..b53c429 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,9 @@ { "compileOnSave": false, "compilerOptions": { - "allowSyntheticDefaultImports": true, "baseUrl": "./", - "downlevelIteration": true, "outDir": "./dist/out-tsc", + "esModuleInterop": true, "sourceMap": true, "declaration": false, "module": "es2020", From 3ba8eb2cf6b28451e33efb8428e361f1bbad670f Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 00:50:11 +0100 Subject: [PATCH 22/94] mark not standalone as false --- src/app/app.component.ts | 3 ++- src/app/gantt-chart/gantt-chart.component.ts | 3 ++- src/app/lazy-loading-chart/lazy-loading-chart.component.ts | 3 ++- src/app/line-chart/line-chart.component.ts | 1 + src/app/map-chart/map-chart.component.ts | 3 ++- src/app/stock-chart/stock-chart.component.ts | 3 ++- src/app/tests/line-test/line-test.component.ts | 3 ++- 7 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index aff4c90..49db50c 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -23,7 +23,8 @@ Highcharts.setOptions({ @Component({ selector: 'app-root', templateUrl: 'app.component.html', - styleUrls: ['./app.component.css'] + styleUrls: ['./app.component.css'], + standalone: false }) export class AppComponent { diff --git a/src/app/gantt-chart/gantt-chart.component.ts b/src/app/gantt-chart/gantt-chart.component.ts index 936c5c9..3852584 100644 --- a/src/app/gantt-chart/gantt-chart.component.ts +++ b/src/app/gantt-chart/gantt-chart.component.ts @@ -7,7 +7,8 @@ HC_gantt(Highcharts); @Component({ selector: 'app-gantt-chart', templateUrl: './gantt-chart.component.html', - styleUrls: ['./gantt-chart.component.css'] + styleUrls: ['./gantt-chart.component.css'], + standalone: false }) export class GanttChartComponent { Highcharts: typeof Highcharts = Highcharts; diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts index 8ddd370..2e4af0a 100644 --- a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts @@ -14,7 +14,8 @@ interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGrou @Component({ selector: 'app-lazy-loading-chart', templateUrl: './lazy-loading-chart.component.html', - styleUrls: ['./lazy-loading-chart.component.css'] + styleUrls: ['./lazy-loading-chart.component.css'], + standalone: false }) export class LazyLoadingChartComponent { diff --git a/src/app/line-chart/line-chart.component.ts b/src/app/line-chart/line-chart.component.ts index c8db842..25f798a 100644 --- a/src/app/line-chart/line-chart.component.ts +++ b/src/app/line-chart/line-chart.component.ts @@ -7,6 +7,7 @@ HC_customEvents(Highcharts); selector: 'app-line-chart', templateUrl: './line-chart.component.html', styleUrls: ['./line-chart.component.css'], + standalone: false }) export class LineChartComponent { public Highcharts: typeof Highcharts = Highcharts; diff --git a/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts index aa7f968..f9f7d52 100644 --- a/src/app/map-chart/map-chart.component.ts +++ b/src/app/map-chart/map-chart.component.ts @@ -12,7 +12,8 @@ HC_map(Highcharts); @Component({ selector: 'app-map-chart', templateUrl: './map-chart.component.html', - styleUrls: ['./map-chart.component.css'] + styleUrls: ['./map-chart.component.css'], + standalone: false }) export class MapChartComponent { diff --git a/src/app/stock-chart/stock-chart.component.ts b/src/app/stock-chart/stock-chart.component.ts index 068256a..ba2a066 100644 --- a/src/app/stock-chart/stock-chart.component.ts +++ b/src/app/stock-chart/stock-chart.component.ts @@ -14,7 +14,8 @@ HC_customEvents(Highcharts); @Component({ selector: 'app-stock-chart', templateUrl: './stock-chart.component.html', - styleUrls: ['./stock-chart.component.css'] + styleUrls: ['./stock-chart.component.css'], + standalone: false }) export class StockChartComponent { diff --git a/src/app/tests/line-test/line-test.component.ts b/src/app/tests/line-test/line-test.component.ts index d76488d..a18dbaa 100644 --- a/src/app/tests/line-test/line-test.component.ts +++ b/src/app/tests/line-test/line-test.component.ts @@ -8,7 +8,8 @@ interface ExtendedSeriesCandlestickOptions extends Highcharts.SeriesCandlestickO @Component({ selector: 'app-line-test', templateUrl: './line-test.component.html', - styleUrls: ['./line-test.component.css'] + styleUrls: ['./line-test.component.css'], + standalone: false }) export class LineTestComponent { Highcharts: typeof Highcharts = Highcharts; From ba3ef526a5d329bccc262ee84bf3f3894f45599f Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 00:51:28 +0100 Subject: [PATCH 23/94] mv to ng 19 --- README.md | 2 +- highcharts-angular/package.json | 4 ++-- package.json | 28 ++++++++++++++-------------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 499e381..b817b79 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Make sure you have **node**, **NPM** and **Angular** up to date. | Version | Node | Angular | Highcharts | |---------|----------|----------|---------------| -| 5.0.0 | >=18.14 | >=18.0.0 | >=11.0.0 | +| 5.0.0 | >=18.19 | >=19.0.0 | >=11.0.0 | | 4.0.0 | >=16.14 | >=16.0.0 | >=11.0.0 | | 3.1.2 | >=14.13 | >=15.0.0 | >=10.3.3 | | 3.0.0 | >=14.13 | >=9.0.0 | >=8.0.0 | diff --git a/highcharts-angular/package.json b/highcharts-angular/package.json index f805861..166de31 100644 --- a/highcharts-angular/package.json +++ b/highcharts-angular/package.json @@ -19,8 +19,8 @@ "angular" ], "peerDependencies": { - "@angular/common": ">=18.0.0", - "@angular/core": ">=18.0.0", + "@angular/common": ">=19.0.0", + "@angular/core": ">=19.0.0", "highcharts": ">=9.0.0" }, "dependencies": { diff --git a/package.json b/package.json index 5eb99a3..e5249eb 100644 --- a/package.json +++ b/package.json @@ -17,14 +17,14 @@ "e2e": "ng e2e" }, "dependencies": { - "@angular/animations": "18.2.12", - "@angular/common": "18.2.12", - "@angular/compiler": "18.2.12", - "@angular/core": "18.2.12", - "@angular/forms": "18.2.12", - "@angular/platform-browser": "18.2.12", - "@angular/platform-browser-dynamic": "18.2.12", - "@angular/router": "18.2.12", + "@angular/animations": "19.0.0", + "@angular/common": "19.0.0", + "@angular/compiler": "19.0.0", + "@angular/core": "19.0.0", + "@angular/forms": "19.0.0", + "@angular/platform-browser": "19.0.0", + "@angular/platform-browser-dynamic": "19.0.0", + "@angular/router": "19.0.0", "@highcharts/map-collection": "^1.1.3", "core-js": "^3.19.2", "highcharts": "^11.2.0", @@ -33,12 +33,12 @@ "proj4": "^2.7.5", "rxjs": "^7.4.0", "tslib": "^2.3.1", - "zone.js": "~0.14.10" + "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.2.12", - "@angular/cli": "18.2.12", - "@angular/compiler-cli": "18.2.12", + "@angular-devkit/build-angular": "^19.0.1", + "@angular/cli": "19.0.1", + "@angular/compiler-cli": "19.0.0", "@types/estree": "^1.0.0", "@types/jasmine": "3.10.2", "@types/jasminewd2": "2.0.10", @@ -51,12 +51,12 @@ "karma-coverage-istanbul-reporter": "~3.0.3", "karma-jasmine": "~4.0.1", "karma-jasmine-html-reporter": "^1.7.0", - "ng-packagr": "^18.2.1", + "ng-packagr": "^19.0.0", "node-sass": "7.0.1", "protractor": "~7.0.0", "standard-version": "^9.3.2", "ts-node": "^10.4.0", "tslint": "~6.1.0", - "typescript": "5.4.5" + "typescript": "5.6.3" } } From 8aa6270ef73ce5a18592729692bedc0e75ea9912 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 01:42:10 +0100 Subject: [PATCH 24/94] refactor highchart component --- .../src/lib/highcharts-chart.component.ts | 91 +++++++++---------- src/app/map-chart/map-chart.component.ts | 4 +- 2 files changed, 45 insertions(+), 50 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.component.ts b/highcharts-angular/src/lib/highcharts-chart.component.ts index 0e18571..3ae6630 100644 --- a/highcharts-angular/src/lib/highcharts-chart.component.ts +++ b/highcharts-angular/src/lib/highcharts-chart.component.ts @@ -1,75 +1,70 @@ -import type { OnChanges } from '@angular/core'; -import { Component, ElementRef, OutputEmitterRef, input, output, model, NgZone, SimpleChanges, DestroyRef, inject } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + DestroyRef, + afterRenderEffect, + ElementRef, + inject, + input, + linkedSignal, + model, + output, + OutputEmitterRef, + untracked +} from '@angular/core'; import type * as Highcharts from 'highcharts'; import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; @Component({ selector: 'highcharts-chart', template: '', - standalone: true + changeDetection: ChangeDetectionStrategy.OnPush, }) -export class HighchartsChartComponent implements OnChanges { +export class HighchartsChartComponent { Highcharts = input(); - constructorType = input(); - callbackFunction = input(); + constructorType = input('chart'); + callbackFunction = input(null); oneToOne = input(); // #20 + /** @deprecated */ runOutsideAngular = input(); // #75 options = input(); update = model(); chartInstance: OutputEmitterRef = output(); // #26 - private chart: Highcharts.Chart | null; + private chart = linkedSignal<{ options: Highcharts.Options | HighchartsESM.Options, update: boolean }, Highcharts.Chart | null>({ + source: () => ({options: this.options(), update: this.update()}), + computation: (source, previous) => { + return untracked(() => { + if (previous && previous.value) { + previous.value.update(source.options, true, this.oneToOne() || false); + return previous.value; + } + return this.Highcharts()[this.constructorType()](this.el.nativeElement, source.options, this.callbackFunction()); + }) + } + }); + + private destroyRef = inject(DestroyRef); - destroyRef = inject(DestroyRef); + private el = inject(ElementRef); - constructor( - private el: ElementRef, - private _zone: NgZone // #75 - ) { + constructor() { this.destroyRef.onDestroy(() => { // #44 - if (this.chart) { // #56 - this.chart.destroy(); - this.chart = null; + if (this.chart()) { // #56 + this.chart().destroy(); + this.chart.set(null); // emit chart instance on destroy - this.chartInstance.emit(this.chart); + this.chartInstance.emit(this.chart()); } }); - } - ngOnChanges(changes: SimpleChanges): void { - const update = changes.update?.currentValue; - if (changes.options || update) { - this.wrappedUpdateOrCreateChart(); - if (update) { + afterRenderEffect(() => this.chartInstance.emit(this.chart())); + afterRenderEffect(() => { + if (this.update()) { this.update.set(false); // clear the flag after update } - } - } - - wrappedUpdateOrCreateChart() { // #75 - if (this.runOutsideAngular()) { - this._zone.runOutsideAngular(() => { - this.updateOrCreateChart() - }); - } else { - this.updateOrCreateChart(); - } - } - - updateOrCreateChart() { - if (this.chart?.update) { - this.chart.update(this.options(), true, this.oneToOne() || false); - } else { - this.chart = this.Highcharts()[this.constructorType() || 'chart']( - this.el.nativeElement, - this.options(), - this.callbackFunction() || null - ); - - // emit chart instance on init - this.chartInstance.emit(this.chart); - } + }); } } diff --git a/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts index f9f7d52..31ba0ff 100644 --- a/src/app/map-chart/map-chart.component.ts +++ b/src/app/map-chart/map-chart.component.ts @@ -2,7 +2,7 @@ import { Component } from '@angular/core'; import * as Highcharts from 'highcharts'; import HC_map from 'highcharts/modules/map'; import worldMap from '@highcharts/map-collection/custom/world.geo.json'; -import proj4 from 'proj4'; +// import proj4 from 'proj4'; HC_map(Highcharts); @@ -23,7 +23,7 @@ export class MapChartComponent { chartMap: Highcharts.Options = { chart: { map: worldMap as any, - proj4: proj4 + // proj4: proj4 }, title: { text: 'Highcharts Maps - basic demo' From 59056cda04347c002670edb0e443838065b525f7 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 01:45:34 +0100 Subject: [PATCH 25/94] generate jsdoc --- .../src/lib/highcharts-chart.component.ts | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.component.ts b/highcharts-angular/src/lib/highcharts-chart.component.ts index 3ae6630..844e67d 100644 --- a/highcharts-angular/src/lib/highcharts-chart.component.ts +++ b/highcharts-angular/src/lib/highcharts-chart.component.ts @@ -21,13 +21,40 @@ import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class HighchartsChartComponent { + /** + * Highcharts library or Highcharts ESM module. + */ Highcharts = input(); + + /** + * Type of the chart constructor. + */ constructorType = input('chart'); + + /** + * Callback function for the chart. + */ callbackFunction = input(null); - oneToOne = input(); // #20 - /** @deprecated */ - runOutsideAngular = input(); // #75 + + /** + * Whether to update the chart one-to-one. + */ + oneToOne = input(); + + /** + * Whether to run the chart outside Angular. + * @deprecated + */ + runOutsideAngular = input(); + + /** + * Options for the Highcharts chart. + */ options = input(); + + /** + * Whether to rerender the chart. + */ update = model(); chartInstance: OutputEmitterRef = output(); // #26 From 069278667b2141d7e2c52136d10deba21164f995 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 01:47:51 +0100 Subject: [PATCH 26/94] remove old packages --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index e5249eb..7176706 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "karma-jasmine": "~4.0.1", "karma-jasmine-html-reporter": "^1.7.0", "ng-packagr": "^19.0.0", - "node-sass": "7.0.1", "protractor": "~7.0.0", "standard-version": "^9.3.2", "ts-node": "^10.4.0", From 3846fcb5862f2c6ab2fc595f3751db159ca0d8b8 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 01:54:03 +0100 Subject: [PATCH 27/94] update map collection --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7176706..bd58033 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@angular/platform-browser": "19.0.0", "@angular/platform-browser-dynamic": "19.0.0", "@angular/router": "19.0.0", - "@highcharts/map-collection": "^1.1.3", + "@highcharts/map-collection": "^2.3.0", "core-js": "^3.19.2", "highcharts": "^11.2.0", "highcharts-custom-events": "^3.0.10", From f1492973988e5956c0286eb61784e116ac45b8d1 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 02:00:38 +0100 Subject: [PATCH 28/94] update karma --- package.json | 14 +++++++------- src/test.ts | 17 ++--------------- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index bd58033..5eea4fd 100644 --- a/package.json +++ b/package.json @@ -40,17 +40,17 @@ "@angular/cli": "19.0.1", "@angular/compiler-cli": "19.0.0", "@types/estree": "^1.0.0", - "@types/jasmine": "3.10.2", - "@types/jasminewd2": "2.0.10", + "@types/jasmine": "^5.1.4", + "@types/jasminewd2": "^2.0.13", "@types/node": "^18.19.64", "codelyzer": "^6.0.2", - "jasmine-core": "~3.10.1", + "jasmine-core": "^5.4.0", "jasmine-spec-reporter": "~7.0.0", - "karma": "~6.3.9", - "karma-chrome-launcher": "~3.1.0", + "karma": "^6.4.4", + "karma-chrome-launcher": "^3.2.0", "karma-coverage-istanbul-reporter": "~3.0.3", - "karma-jasmine": "~4.0.1", - "karma-jasmine-html-reporter": "^1.7.0", + "karma-jasmine": "^5.1.0", + "karma-jasmine-html-reporter": "^2.1.0", "ng-packagr": "^19.0.0", "protractor": "~7.0.0", "standard-version": "^9.3.2", diff --git a/src/test.ts b/src/test.ts index b69fb17..d510be4 100644 --- a/src/test.ts +++ b/src/test.ts @@ -1,24 +1,11 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files import 'zone.js/testing'; -import { getTestBed } from '@angular/core/testing'; +import {getTestBed} from '@angular/core/testing'; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; -// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. -declare var __karma__: any; - -// Prevent Karma from running prematurely. -__karma__.loaded = function () {}; - // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting(), { - teardown: { destroyAfterEach: false } -} -); -// Finally, start Karma to run the tests. -__karma__.start(); +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), {teardown: {destroyAfterEach: false}}); From 472708ff82780257a36015ded3b05214c09e5f74 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 02:01:07 +0100 Subject: [PATCH 29/94] correct imports --- src/app/gantt-chart/gantt-chart.component.ts | 2 +- src/app/lazy-loading-chart/lazy-loading-chart.component.ts | 2 +- src/app/line-chart/line-chart.component.ts | 2 +- src/app/map-chart/map-chart.component.ts | 2 +- src/app/stock-chart/stock-chart.component.ts | 2 +- src/app/tests/line-test/line-test.component.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/gantt-chart/gantt-chart.component.ts b/src/app/gantt-chart/gantt-chart.component.ts index 3852584..ebe0089 100644 --- a/src/app/gantt-chart/gantt-chart.component.ts +++ b/src/app/gantt-chart/gantt-chart.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import * as Highcharts from 'highcharts'; +import Highcharts from 'highcharts'; import HC_gantt from 'highcharts/modules/gantt'; HC_gantt(Highcharts); diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts index 2e4af0a..dc4e77e 100644 --- a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import * as Highcharts from 'highcharts'; +import Highcharts from 'highcharts'; import HC_stock from 'highcharts/modules/stock'; import { AppleDataService } from '../apple-data.service' import $ from 'jquery'; diff --git a/src/app/line-chart/line-chart.component.ts b/src/app/line-chart/line-chart.component.ts index 25f798a..c8174fa 100644 --- a/src/app/line-chart/line-chart.component.ts +++ b/src/app/line-chart/line-chart.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import * as Highcharts from 'highcharts'; +import Highcharts from 'highcharts'; import HC_customEvents from 'highcharts-custom-events'; HC_customEvents(Highcharts); diff --git a/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts index 31ba0ff..c2ed5d1 100644 --- a/src/app/map-chart/map-chart.component.ts +++ b/src/app/map-chart/map-chart.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import * as Highcharts from 'highcharts'; +import Highcharts from 'highcharts'; import HC_map from 'highcharts/modules/map'; import worldMap from '@highcharts/map-collection/custom/world.geo.json'; // import proj4 from 'proj4'; diff --git a/src/app/stock-chart/stock-chart.component.ts b/src/app/stock-chart/stock-chart.component.ts index ba2a066..23ddad7 100644 --- a/src/app/stock-chart/stock-chart.component.ts +++ b/src/app/stock-chart/stock-chart.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import * as Highcharts from 'highcharts'; +import Highcharts from 'highcharts'; import HC_stock from 'highcharts/modules/stock'; import HC_customEvents from 'highcharts-custom-events'; diff --git a/src/app/tests/line-test/line-test.component.ts b/src/app/tests/line-test/line-test.component.ts index a18dbaa..d3081b4 100644 --- a/src/app/tests/line-test/line-test.component.ts +++ b/src/app/tests/line-test/line-test.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import * as Highcharts from 'highcharts'; +import Highcharts from 'highcharts'; interface ExtendedSeriesCandlestickOptions extends Highcharts.SeriesCandlestickOptions { color: Highcharts.ColorType; From ab734a045e1d82c9a904e8f1c97bbc9b9410417a Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 02:04:08 +0100 Subject: [PATCH 30/94] use esbuild to build the demo app --- angular.json | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/angular.json b/angular.json index 530aa27..ce215e5 100644 --- a/angular.json +++ b/angular.json @@ -8,16 +8,16 @@ "projectType": "application", "architect": { "build": { - "builder": "@angular-devkit/build-angular:browser", + "builder": "@angular-devkit/build-angular:application", "options": { "aot": false, "allowedCommonJsDependencies": [ "highcharts", "highcharts-custom-events" ], - "outputPath": "dist", + "outputPath": {"base": "dist"}, "index": "src/index.html", - "main": "src/main.ts", + "browser": "src/main.ts", "tsConfig": "./tsconfig.app.json", "polyfills": ["core-js/es/reflect", "zone.js"], "assets": [ @@ -26,9 +26,7 @@ ], "styles": [], "scripts": [], - "vendorChunk": true, "extractLicenses": false, - "buildOptimizer": false, "sourceMap": true, "optimization": false, "namedChunks": true @@ -47,8 +45,6 @@ "namedChunks": false, "aot": true, "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, "fileReplacements": [ { "replace": "src/environments/environment.ts", From d771296943086c28079fad44c54ea5afbd87548d Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 02:11:46 +0100 Subject: [PATCH 31/94] convert demo project to standalone --- src/app/app.component.ts | 9 ++++--- src/app/app.module.ts | 24 ------------------- src/app/gantt-chart/gantt-chart.component.ts | 7 +++--- .../lazy-loading-chart.component.ts | 7 +++--- src/app/line-chart/line-chart.component.ts | 7 ++++-- src/app/map-chart/map-chart.component.ts | 5 ++-- src/app/stock-chart/stock-chart.component.ts | 8 ++++--- .../line-test/line-test.component.spec.ts | 6 ++--- .../tests/line-test/line-test.component.ts | 3 ++- src/main.ts | 15 ++++++++---- 10 files changed, 41 insertions(+), 50 deletions(-) delete mode 100644 src/app/app.module.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 49db50c..235da8f 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,9 +1,12 @@ -declare var require: any; - import { Component } from '@angular/core'; import ExportingModule from 'highcharts/modules/exporting'; import SunsetTheme from 'highcharts/themes/sunset.js'; import * as Highcharts from 'highcharts'; +import { LineChartComponent } from './line-chart/line-chart.component'; +import { StockChartComponent } from './stock-chart/stock-chart.component'; +import { MapChartComponent } from './map-chart/map-chart.component'; +import { GanttChartComponent } from './gantt-chart/gantt-chart.component'; +import { LazyLoadingChartComponent } from './lazy-loading-chart/lazy-loading-chart.component'; // The modules will work for all charts. ExportingModule(Highcharts); @@ -24,7 +27,7 @@ Highcharts.setOptions({ selector: 'app-root', templateUrl: 'app.component.html', styleUrls: ['./app.component.css'], - standalone: false + imports: [LineChartComponent, StockChartComponent, MapChartComponent, GanttChartComponent, LazyLoadingChartComponent] }) export class AppComponent { diff --git a/src/app/app.module.ts b/src/app/app.module.ts deleted file mode 100644 index 4c7dce0..0000000 --- a/src/app/app.module.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { BrowserModule } from '@angular/platform-browser'; -import { HighchartsChartComponent } from 'highcharts-angular'; -import { AppComponent } from './app.component'; -import { LineChartComponent } from './line-chart/line-chart.component'; -import { StockChartComponent } from './stock-chart/stock-chart.component'; -import { MapChartComponent } from './map-chart/map-chart.component'; -import { GanttChartComponent } from './gantt-chart/gantt-chart.component'; -import { LazyLoadingChartComponent } from './lazy-loading-chart/lazy-loading-chart.component'; -import { LineTestComponent } from './tests/line-test/line-test.component'; - -@NgModule({ - declarations: [AppComponent, LineChartComponent, StockChartComponent, MapChartComponent, GanttChartComponent, LazyLoadingChartComponent, LineTestComponent], - imports: [ - BrowserModule, - FormsModule, - HighchartsChartComponent, - ], - providers: [provideHttpClient(withInterceptorsFromDi())], - bootstrap: [AppComponent] -}) -export class AppModule {} diff --git a/src/app/gantt-chart/gantt-chart.component.ts b/src/app/gantt-chart/gantt-chart.component.ts index ebe0089..30b8b34 100644 --- a/src/app/gantt-chart/gantt-chart.component.ts +++ b/src/app/gantt-chart/gantt-chart.component.ts @@ -1,6 +1,7 @@ import { Component } from '@angular/core'; import Highcharts from 'highcharts'; import HC_gantt from 'highcharts/modules/gantt'; +import {HighchartsChartComponent} from 'highcharts-angular'; HC_gantt(Highcharts); @@ -8,7 +9,7 @@ HC_gantt(Highcharts); selector: 'app-gantt-chart', templateUrl: './gantt-chart.component.html', styleUrls: ['./gantt-chart.component.css'], - standalone: false + imports: [HighchartsChartComponent] }) export class GanttChartComponent { Highcharts: typeof Highcharts = Highcharts; @@ -39,8 +40,8 @@ export class GanttChartComponent { start: Date.UTC(2014, 10, 20), end: Date.UTC(2014, 10, 25), completed: { - amount: 0.12, - fill: '#fa0' + amount: 0.12, + fill: '#fa0' } }, { name: 'Run acceptance tests', diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts index dc4e77e..7a0d2e1 100644 --- a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts @@ -4,10 +4,11 @@ import HC_stock from 'highcharts/modules/stock'; import { AppleDataService } from '../apple-data.service' import $ from 'jquery'; import { Observable } from 'rxjs'; +import { HighchartsChartComponent } from 'highcharts-angular'; HC_stock(Highcharts); -interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGroupingOptionsObject{ +interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGroupingOptionsObject { enabled: boolean } @@ -15,7 +16,7 @@ interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGrou selector: 'app-lazy-loading-chart', templateUrl: './lazy-loading-chart.component.html', styleUrls: ['./lazy-loading-chart.component.css'], - standalone: false + imports: [HighchartsChartComponent] }) export class LazyLoadingChartComponent { @@ -46,7 +47,7 @@ export class LazyLoadingChartComponent { events: { load: () => { const chart = this.chartRef; - const data = this.fetchData() + this.fetchData() .subscribe((data: Array<[]>) => { // Add a null value for the end date const chartData = [...data, [Date.UTC(2011, 9, 14, 19, 59), null, null, null, null]]; diff --git a/src/app/line-chart/line-chart.component.ts b/src/app/line-chart/line-chart.component.ts index c8174fa..0cc819f 100644 --- a/src/app/line-chart/line-chart.component.ts +++ b/src/app/line-chart/line-chart.component.ts @@ -1,13 +1,16 @@ import { Component } from '@angular/core'; import Highcharts from 'highcharts'; import HC_customEvents from 'highcharts-custom-events'; +import { FormsModule } from '@angular/forms'; +import { HighchartsChartComponent } from 'highcharts-angular'; + HC_customEvents(Highcharts); @Component({ selector: 'app-line-chart', templateUrl: './line-chart.component.html', styleUrls: ['./line-chart.component.css'], - standalone: false + imports: [FormsModule, HighchartsChartComponent] }) export class LineChartComponent { public Highcharts: typeof Highcharts = Highcharts; @@ -53,7 +56,7 @@ export class LineChartComponent { public toggleSeriesType(index = 0) { this.optFromInput.series[index].type = this.seriesTypes[ - this.optFromInput.series[index].type || 'line'] as keyof typeof this.seriesTypes; + this.optFromInput.series[index].type || 'line'] as keyof typeof this.seriesTypes; // nested change - must trigger update this.updateFromInput = true; } diff --git a/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts index c2ed5d1..5071419 100644 --- a/src/app/map-chart/map-chart.component.ts +++ b/src/app/map-chart/map-chart.component.ts @@ -2,6 +2,7 @@ import { Component } from '@angular/core'; import Highcharts from 'highcharts'; import HC_map from 'highcharts/modules/map'; import worldMap from '@highcharts/map-collection/custom/world.geo.json'; +import { HighchartsChartComponent } from 'highcharts-angular'; // import proj4 from 'proj4'; HC_map(Highcharts); @@ -13,14 +14,14 @@ HC_map(Highcharts); selector: 'app-map-chart', templateUrl: './map-chart.component.html', styleUrls: ['./map-chart.component.css'], - standalone: false + imports: [HighchartsChartComponent] }) export class MapChartComponent { Highcharts: typeof Highcharts = Highcharts; - chartMap: Highcharts.Options = { + chartMap: Highcharts.Options = { chart: { map: worldMap as any, // proj4: proj4 diff --git a/src/app/stock-chart/stock-chart.component.ts b/src/app/stock-chart/stock-chart.component.ts index 23ddad7..ca87628 100644 --- a/src/app/stock-chart/stock-chart.component.ts +++ b/src/app/stock-chart/stock-chart.component.ts @@ -2,6 +2,8 @@ import { Component } from '@angular/core'; import Highcharts from 'highcharts'; import HC_stock from 'highcharts/modules/stock'; import HC_customEvents from 'highcharts-custom-events'; +import { FormsModule } from '@angular/forms'; +import { HighchartsChartComponent } from 'highcharts-angular'; HC_stock(Highcharts); HC_customEvents(Highcharts); @@ -15,7 +17,7 @@ HC_customEvents(Highcharts); selector: 'app-stock-chart', templateUrl: './stock-chart.component.html', styleUrls: ['./stock-chart.component.css'], - standalone: false + imports: [FormsModule, HighchartsChartComponent] }) export class StockChartComponent { @@ -45,8 +47,8 @@ export class StockChartComponent { subtitle: { text: '1st data set' }, plotOptions: { series: { - pointStart: Date.now(), - pointInterval: 86400000 // 1 day + pointStart: Date.now(), + pointInterval: 86400000 // 1 day } }, series: [{ diff --git a/src/app/tests/line-test/line-test.component.spec.ts b/src/app/tests/line-test/line-test.component.spec.ts index d32e83f..7c9439a 100644 --- a/src/app/tests/line-test/line-test.component.spec.ts +++ b/src/app/tests/line-test/line-test.component.spec.ts @@ -1,6 +1,5 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { LineTestComponent } from './line-test.component'; -import { HighchartsChartComponent } from '../../../../highcharts-angular/src/lib/highcharts-chart.component' describe('LineTestComponent', () => { @@ -9,8 +8,7 @@ describe('LineTestComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [ HighchartsChartComponent ], - declarations: [ LineTestComponent ] + imports: [LineTestComponent] }) .compileComponents(); })); @@ -29,7 +27,7 @@ describe('LineTestComponent', () => { it('should have data given from chartOptions', () => { const chartOptions = component.chartOptions; const chart = component.Highcharts.charts[component.Highcharts.charts.length - 1]; - const series = chart.series[0] ; + const series = chart.series[0]; expect((series as any).yData).toEqual((chartOptions.series[0] as any).data); }); diff --git a/src/app/tests/line-test/line-test.component.ts b/src/app/tests/line-test/line-test.component.ts index d3081b4..cb8e3ec 100644 --- a/src/app/tests/line-test/line-test.component.ts +++ b/src/app/tests/line-test/line-test.component.ts @@ -1,5 +1,6 @@ import { Component } from '@angular/core'; import Highcharts from 'highcharts'; +import { HighchartsChartComponent } from 'highcharts-angular'; interface ExtendedSeriesCandlestickOptions extends Highcharts.SeriesCandlestickOptions { color: Highcharts.ColorType; @@ -9,7 +10,7 @@ interface ExtendedSeriesCandlestickOptions extends Highcharts.SeriesCandlestickO selector: 'app-line-test', templateUrl: './line-test.component.html', styleUrls: ['./line-test.component.css'], - standalone: false + imports: [HighchartsChartComponent] }) export class LineTestComponent { Highcharts: typeof Highcharts = Highcharts; diff --git a/src/main.ts b/src/main.ts index 1482cad..f62dcc1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,17 @@ -import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { AppModule } from './app/app.module'; +import { enableProdMode, importProvidersFrom } from '@angular/core'; import { environment } from './environments/environment'; +import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { BrowserModule, bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; if (environment.production) { enableProdMode(); } -platformBrowserDynamic() - .bootstrapModule(AppModule) +bootstrapApplication(AppComponent, { + providers: [ + importProvidersFrom(BrowserModule), + provideHttpClient(withInterceptorsFromDi()) + ] +}) .catch(err => console.log(err)); From 81d488cafc9aa4967fb47c27ca766b56ac5e34fc Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 02:20:35 +0100 Subject: [PATCH 32/94] use onPush change detection --- src/app/app.component.ts | 5 +++-- src/app/gantt-chart/gantt-chart.component.ts | 5 +++-- src/app/lazy-loading-chart/lazy-loading-chart.component.ts | 5 +++-- src/app/line-chart/line-chart.component.ts | 5 +++-- src/app/map-chart/map-chart.component.ts | 5 +++-- src/app/stock-chart/stock-chart.component.ts | 5 +++-- src/app/tests/line-test/line-test.component.ts | 5 +++-- 7 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 235da8f..bb5c66c 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import ExportingModule from 'highcharts/modules/exporting'; import SunsetTheme from 'highcharts/themes/sunset.js'; import * as Highcharts from 'highcharts'; @@ -27,7 +27,8 @@ Highcharts.setOptions({ selector: 'app-root', templateUrl: 'app.component.html', styleUrls: ['./app.component.css'], - imports: [LineChartComponent, StockChartComponent, MapChartComponent, GanttChartComponent, LazyLoadingChartComponent] + imports: [LineChartComponent, StockChartComponent, MapChartComponent, GanttChartComponent, LazyLoadingChartComponent], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class AppComponent { diff --git a/src/app/gantt-chart/gantt-chart.component.ts b/src/app/gantt-chart/gantt-chart.component.ts index 30b8b34..be29c57 100644 --- a/src/app/gantt-chart/gantt-chart.component.ts +++ b/src/app/gantt-chart/gantt-chart.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import Highcharts from 'highcharts'; import HC_gantt from 'highcharts/modules/gantt'; import {HighchartsChartComponent} from 'highcharts-angular'; @@ -9,7 +9,8 @@ HC_gantt(Highcharts); selector: 'app-gantt-chart', templateUrl: './gantt-chart.component.html', styleUrls: ['./gantt-chart.component.css'], - imports: [HighchartsChartComponent] + imports: [HighchartsChartComponent], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class GanttChartComponent { Highcharts: typeof Highcharts = Highcharts; diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts index 7a0d2e1..6ff4497 100644 --- a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import Highcharts from 'highcharts'; import HC_stock from 'highcharts/modules/stock'; import { AppleDataService } from '../apple-data.service' @@ -16,7 +16,8 @@ interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGrou selector: 'app-lazy-loading-chart', templateUrl: './lazy-loading-chart.component.html', styleUrls: ['./lazy-loading-chart.component.css'], - imports: [HighchartsChartComponent] + imports: [HighchartsChartComponent], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class LazyLoadingChartComponent { diff --git a/src/app/line-chart/line-chart.component.ts b/src/app/line-chart/line-chart.component.ts index 0cc819f..0924f57 100644 --- a/src/app/line-chart/line-chart.component.ts +++ b/src/app/line-chart/line-chart.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import Highcharts from 'highcharts'; import HC_customEvents from 'highcharts-custom-events'; import { FormsModule } from '@angular/forms'; @@ -10,7 +10,8 @@ HC_customEvents(Highcharts); selector: 'app-line-chart', templateUrl: './line-chart.component.html', styleUrls: ['./line-chart.component.css'], - imports: [FormsModule, HighchartsChartComponent] + imports: [FormsModule, HighchartsChartComponent], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class LineChartComponent { public Highcharts: typeof Highcharts = Highcharts; diff --git a/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts index 5071419..e8e0ef4 100644 --- a/src/app/map-chart/map-chart.component.ts +++ b/src/app/map-chart/map-chart.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import Highcharts from 'highcharts'; import HC_map from 'highcharts/modules/map'; import worldMap from '@highcharts/map-collection/custom/world.geo.json'; @@ -14,7 +14,8 @@ HC_map(Highcharts); selector: 'app-map-chart', templateUrl: './map-chart.component.html', styleUrls: ['./map-chart.component.css'], - imports: [HighchartsChartComponent] + imports: [HighchartsChartComponent], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class MapChartComponent { diff --git a/src/app/stock-chart/stock-chart.component.ts b/src/app/stock-chart/stock-chart.component.ts index ca87628..eb23570 100644 --- a/src/app/stock-chart/stock-chart.component.ts +++ b/src/app/stock-chart/stock-chart.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import Highcharts from 'highcharts'; import HC_stock from 'highcharts/modules/stock'; import HC_customEvents from 'highcharts-custom-events'; @@ -17,7 +17,8 @@ HC_customEvents(Highcharts); selector: 'app-stock-chart', templateUrl: './stock-chart.component.html', styleUrls: ['./stock-chart.component.css'], - imports: [FormsModule, HighchartsChartComponent] + imports: [FormsModule, HighchartsChartComponent], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class StockChartComponent { diff --git a/src/app/tests/line-test/line-test.component.ts b/src/app/tests/line-test/line-test.component.ts index cb8e3ec..141f2f1 100644 --- a/src/app/tests/line-test/line-test.component.ts +++ b/src/app/tests/line-test/line-test.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import Highcharts from 'highcharts'; import { HighchartsChartComponent } from 'highcharts-angular'; @@ -10,7 +10,8 @@ interface ExtendedSeriesCandlestickOptions extends Highcharts.SeriesCandlestickO selector: 'app-line-test', templateUrl: './line-test.component.html', styleUrls: ['./line-test.component.css'], - imports: [HighchartsChartComponent] + imports: [HighchartsChartComponent], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class LineTestComponent { Highcharts: typeof Highcharts = Highcharts; From 65dfaf6592a80df8cac7cbeee698ad3beaad9129 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 02:20:49 +0100 Subject: [PATCH 33/94] ref local folder for test --- tsconfig.spec.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 54e6791..efa2f1b 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "paths": { - "highcharts-angular": ["../dist/highcharts-angular"], + "highcharts-angular": ["../dist/highcharts-angular", "highcharts-angular/src/public_api.ts"], "highcharts-angular/*": ["../dist/highcharts-angular/*"] }, "outDir": "./out-tsc/spec", From e92337ae152346409af04cbbc8774b47f9a6b4a2 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 22 Nov 2024 02:24:33 +0100 Subject: [PATCH 34/94] release v5.0.0 --- highcharts-angular/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highcharts-angular/package.json b/highcharts-angular/package.json index 166de31..3f0d392 100644 --- a/highcharts-angular/package.json +++ b/highcharts-angular/package.json @@ -1,7 +1,7 @@ { "name": "highcharts-angular", "description": "Highcharts component for Angular.", - "version": "5.0.0-alpha.2", + "version": "5.0.0", "license": "MIT", "author": "Black Label (http://blacklabel.pl)", "bugs": { From 2492c567ad4a85fa405ca157d0ca392b75c2d5bf Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 24 Nov 2024 15:04:51 +0100 Subject: [PATCH 35/94] move logic to directive, this give more flexibility to dev --- .../src/lib/highcharts-chart.component.ts | 101 ++---------------- .../src/lib/highcharts-chart.directive.ts | 94 ++++++++++++++++ highcharts-angular/src/public_api.ts | 1 + 3 files changed, 105 insertions(+), 91 deletions(-) create mode 100644 highcharts-angular/src/lib/highcharts-chart.directive.ts diff --git a/highcharts-angular/src/lib/highcharts-chart.component.ts b/highcharts-angular/src/lib/highcharts-chart.component.ts index 844e67d..185151a 100644 --- a/highcharts-angular/src/lib/highcharts-chart.component.ts +++ b/highcharts-angular/src/lib/highcharts-chart.component.ts @@ -1,97 +1,16 @@ -import { - ChangeDetectionStrategy, - Component, - DestroyRef, - afterRenderEffect, - ElementRef, - inject, - input, - linkedSignal, - model, - output, - OutputEmitterRef, - untracked -} from '@angular/core'; -import type * as Highcharts from 'highcharts'; -import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; +import { ChangeDetectionStrategy, Component} from '@angular/core'; +import { HighchartsChartDirective } from './highcharts-chart.directive'; @Component({ selector: 'highcharts-chart', template: '', + hostDirectives: [ + { + directive: HighchartsChartDirective, + inputs: ['Highcharts', 'constructorType', 'callbackFunction', 'oneToOne', 'runOutsideAngular', 'options', 'update'], + outputs: ['chartInstance', 'updateChange'] + } + ], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class HighchartsChartComponent { - /** - * Highcharts library or Highcharts ESM module. - */ - Highcharts = input(); - - /** - * Type of the chart constructor. - */ - constructorType = input('chart'); - - /** - * Callback function for the chart. - */ - callbackFunction = input(null); - - /** - * Whether to update the chart one-to-one. - */ - oneToOne = input(); - - /** - * Whether to run the chart outside Angular. - * @deprecated - */ - runOutsideAngular = input(); - - /** - * Options for the Highcharts chart. - */ - options = input(); - - /** - * Whether to rerender the chart. - */ - update = model(); - - chartInstance: OutputEmitterRef = output(); // #26 - - private chart = linkedSignal<{ options: Highcharts.Options | HighchartsESM.Options, update: boolean }, Highcharts.Chart | null>({ - source: () => ({options: this.options(), update: this.update()}), - computation: (source, previous) => { - return untracked(() => { - if (previous && previous.value) { - previous.value.update(source.options, true, this.oneToOne() || false); - return previous.value; - } - return this.Highcharts()[this.constructorType()](this.el.nativeElement, source.options, this.callbackFunction()); - }) - } - }); - - private destroyRef = inject(DestroyRef); - - private el = inject(ElementRef); - - constructor() { - this.destroyRef.onDestroy(() => { // #44 - if (this.chart()) { // #56 - this.chart().destroy(); - this.chart.set(null); - - // emit chart instance on destroy - this.chartInstance.emit(this.chart()); - } - }); - - afterRenderEffect(() => this.chartInstance.emit(this.chart())); - afterRenderEffect(() => { - if (this.update()) { - this.update.set(false); // clear the flag after update - } - }); - } -} +export class HighchartsChartComponent {} diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.ts b/highcharts-angular/src/lib/highcharts-chart.directive.ts new file mode 100644 index 0000000..858c821 --- /dev/null +++ b/highcharts-angular/src/lib/highcharts-chart.directive.ts @@ -0,0 +1,94 @@ +import { + Directive, + DestroyRef, + afterRenderEffect, + ElementRef, + inject, + input, + linkedSignal, + model, + output, + OutputEmitterRef, + untracked +} from '@angular/core'; +import type * as Highcharts from 'highcharts'; +import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; + +@Directive({ + selector: 'highcharts-chart', +}) +export class HighchartsChartDirective { + /** + * Highcharts library or Highcharts ESM module. + */ + Highcharts = input(); + + /** + * Type of the chart constructor. + */ + constructorType = input('chart'); + + /** + * Callback function for the chart. + */ + callbackFunction = input(null); + + /** + * Whether to update the chart one-to-one. + */ + oneToOne = input(); + + /** + * Whether to run the chart outside Angular. + * @deprecated + */ + runOutsideAngular = input(); + + /** + * Options for the Highcharts chart. + */ + options = input(); + + /** + * Whether to rerender the chart. + */ + update = model(); + + chartInstance: OutputEmitterRef = output(); // #26 + + private chart = linkedSignal<{ options: Highcharts.Options | HighchartsESM.Options, update: boolean }, Highcharts.Chart | null>({ + source: () => ({options: this.options(), update: this.update()}), + computation: (source, previous) => { + return untracked(() => { + if (previous && previous.value) { + previous.value.update(source.options, true, this.oneToOne() || false); + return previous.value; + } + return this.Highcharts()[this.constructorType()](this.el.nativeElement, source.options, this.callbackFunction()); + }) + } + }); + + private destroyRef = inject(DestroyRef); + + private el = inject(ElementRef); + + constructor() { + this.destroyRef.onDestroy(() => { // #44 + if (this.chart()) { // #56 + this.chart().destroy(); + this.chart.set(null); + + // emit chart instance on destroy + this.chartInstance.emit(this.chart()); + } + }); + + afterRenderEffect(() => this.chartInstance.emit(this.chart())); + afterRenderEffect(() => { + if (this.update()) { + this.update.set(false); // clear the flag after update + } + }); + } +} diff --git a/highcharts-angular/src/public_api.ts b/highcharts-angular/src/public_api.ts index 2848fcb..6da0199 100644 --- a/highcharts-angular/src/public_api.ts +++ b/highcharts-angular/src/public_api.ts @@ -4,3 +4,4 @@ export * from './lib/highcharts-chart.module'; export * from './lib/highcharts-chart.component'; +export * from './lib/highcharts-chart.directive'; From 0514986f3116b2af3dc97f7199103a0428e8ff3c Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 24 Nov 2024 15:05:04 +0100 Subject: [PATCH 36/94] add doc for directive --- README.md | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b817b79..69fb661 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,37 @@ In the same file (app.component.ts) add to the **template** Highcharts-angular c > ``` +or you can use directive + +```ts +... +import { HighchartsChartDirective } from 'highcharts-angular'; + +@Component({ + imports: [ + ... + HighchartsChartDirective, +``` + +In the component file add to the **template** Highcharts-angular directive selector `highcharts-chart`: + +```html +
+``` + Right side names, in double quotes, are just names of variables you are going to set next, so you could name them whatever you like. Style at the bottom of the selector is optional, but browsers do not know how to display ``, so you should set some styles. In the same file (app.component.ts) all variables should be set in `export class AppComponent {` like: @@ -155,11 +186,13 @@ export class AppComponent { ``` ```HTML - +@if (isHighcharts) { + +} + ``` ### Angular Elements and useHTML From 019eb1759e9f7167eec777000c1a6a077014e76f Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 24 Nov 2024 22:18:48 +0100 Subject: [PATCH 37/94] create css class --- .../lazy-loading-chart/lazy-loading-chart.component.css | 8 +++++++- .../lazy-loading-chart/lazy-loading-chart.component.html | 2 +- src/app/map-chart/map-chart.component.css | 7 ++++++- src/app/map-chart/map-chart.component.html | 5 ++--- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.css b/src/app/lazy-loading-chart/lazy-loading-chart.component.css index 548515f..6a487ef 100644 --- a/src/app/lazy-loading-chart/lazy-loading-chart.component.css +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.css @@ -2,4 +2,10 @@ h2 { font-family: Arial, Helvetica, sans-serif; font-size: 1.25rem; margin: 0 0 1.5rem 0; -} \ No newline at end of file +} + +.main { + width: 100%; + height: 650px; + display: block; +} diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.html b/src/app/lazy-loading-chart/lazy-loading-chart.component.html index c72654e..bb42ae3 100644 --- a/src/app/lazy-loading-chart/lazy-loading-chart.component.html +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.html @@ -5,6 +5,6 @@

Demo #5: Lazy loading in Highcharts Stock

[constructorType]="'stockChart'" [callbackFunction]="chartCallback" [options]="chartLazyLoading" - style="width: 100%; height: 650px; display: block;" + class="main" >
diff --git a/src/app/map-chart/map-chart.component.css b/src/app/map-chart/map-chart.component.css index b1a8ec0..6a487ef 100644 --- a/src/app/map-chart/map-chart.component.css +++ b/src/app/map-chart/map-chart.component.css @@ -3,4 +3,9 @@ h2 { font-size: 1.25rem; margin: 0 0 1.5rem 0; } - \ No newline at end of file + +.main { + width: 100%; + height: 650px; + display: block; +} diff --git a/src/app/map-chart/map-chart.component.html b/src/app/map-chart/map-chart.component.html index 55b0757..b8abbf3 100644 --- a/src/app/map-chart/map-chart.component.html +++ b/src/app/map-chart/map-chart.component.html @@ -4,7 +4,6 @@

Demo #3: Highcharts Maps with the lat/lon points

[Highcharts]="Highcharts" [constructorType]="'mapChart'" [options]="chartMap" - - style="width: 100%; height: 650px; display: block;" + class="main" > - \ No newline at end of file + From fbc658acfa87288364c4cc1fdc8e432ad43c2dba Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 24 Nov 2024 22:19:14 +0100 Subject: [PATCH 38/94] create css class --- src/app/gantt-chart/gantt-chart.component.css | 8 +++++++- src/app/gantt-chart/gantt-chart.component.html | 6 +++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/app/gantt-chart/gantt-chart.component.css b/src/app/gantt-chart/gantt-chart.component.css index 548515f..caf005c 100644 --- a/src/app/gantt-chart/gantt-chart.component.css +++ b/src/app/gantt-chart/gantt-chart.component.css @@ -2,4 +2,10 @@ h2 { font-family: Arial, Helvetica, sans-serif; font-size: 1.25rem; margin: 0 0 1.5rem 0; -} \ No newline at end of file +} + +.main { + width: 100%; + height: 350px; + display: block; +} diff --git a/src/app/gantt-chart/gantt-chart.component.html b/src/app/gantt-chart/gantt-chart.component.html index 2f8437b..5f6c01c 100644 --- a/src/app/gantt-chart/gantt-chart.component.html +++ b/src/app/gantt-chart/gantt-chart.component.html @@ -2,8 +2,8 @@

Demo #4: Highcharts Gantt chart

- \ No newline at end of file + From 0cf465b3d6452673e6b5534c21bffcccf8637ab8 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Mon, 25 Nov 2024 00:14:10 +0100 Subject: [PATCH 39/94] split command --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 5eea4fd..36e36b3 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "author": "Black Label (http://blacklabel.pl)", "scripts": { "ng": "ng", - "start": "node tasks/build.js && ng serve --open", + "serve": "ng serve --open", + "start": "node tasks/build.js && npm run serve", "build": "node tasks/build.js", "test": "ng test", "lint": "ng lint highcharts-angular", From e5b4a15f7883f2bbfcdc9abb194b707fae04a649 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Mon, 25 Nov 2024 00:17:28 +0100 Subject: [PATCH 40/94] introduce injection token and provider to supply with module factory --- .../src/lib/highcharts-chart.provider.ts | 21 ++++++++++++++++ .../src/lib/highcharts-chart.token.ts | 11 +++++++++ highcharts-angular/src/lib/types.ts | 10 ++++++++ highcharts-angular/src/lib/utils.ts | 24 +++++++++++++++++++ 4 files changed, 66 insertions(+) create mode 100644 highcharts-angular/src/lib/highcharts-chart.provider.ts create mode 100644 highcharts-angular/src/lib/highcharts-chart.token.ts create mode 100644 highcharts-angular/src/lib/types.ts create mode 100644 highcharts-angular/src/lib/utils.ts diff --git a/highcharts-angular/src/lib/highcharts-chart.provider.ts b/highcharts-angular/src/lib/highcharts-chart.provider.ts new file mode 100644 index 0000000..9a30389 --- /dev/null +++ b/highcharts-angular/src/lib/highcharts-chart.provider.ts @@ -0,0 +1,21 @@ +import { Provider } from '@angular/core'; +import { HIGHCHARTS_MODULE, HIGHCHARTS_ES_MODULE } from './highcharts-chart.token'; +import { Chart, moduleFactory } from './types'; + +export const provideHighChartsModuleFactory = (...modules: moduleFactory[]): Provider[] => { + return [ + { + provide: HIGHCHARTS_MODULE, + useFactory: () => import('highcharts').then(m => m.default), + }, + { + provide: HIGHCHARTS_ES_MODULE, + useFactory: async (Highcharts: Promise) => { + const value = await Highcharts; + modules.forEach(module => module(value)); + return value; + }, + deps: [HIGHCHARTS_MODULE], + } + ] +} diff --git a/highcharts-angular/src/lib/highcharts-chart.token.ts b/highcharts-angular/src/lib/highcharts-chart.token.ts new file mode 100644 index 0000000..388016a --- /dev/null +++ b/highcharts-angular/src/lib/highcharts-chart.token.ts @@ -0,0 +1,11 @@ +import { InjectionToken, Injector } from '@angular/core'; +import { Chart } from './types' + +export const HIGHCHARTS_MODULE = new InjectionToken>('HIGHCHARTS_MODULE'); +export const HIGHCHARTS_ES_MODULE = new InjectionToken('HIGHCHARTS_ES_MODULE'); + +export const loadHighcharts = (injector: Injector): Promise => { + const defaultHighcharts = import('highcharts').then(m => m.default); + const Highcharts = injector.get>(HIGHCHARTS_MODULE, defaultHighcharts); + return injector.get>(HIGHCHARTS_ES_MODULE, Highcharts); +} diff --git a/highcharts-angular/src/lib/types.ts b/highcharts-angular/src/lib/types.ts new file mode 100644 index 0000000..560c54c --- /dev/null +++ b/highcharts-angular/src/lib/types.ts @@ -0,0 +1,10 @@ +import type Highcharts from 'highcharts'; +import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; + +export interface Chart { + options: Highcharts.Options | HighchartsESM.Options, + update: boolean, + highcharts: typeof Highcharts | typeof HighchartsESM +} + +export type moduleFactory = (highcharts: Chart['highcharts']) => void; diff --git a/highcharts-angular/src/lib/utils.ts b/highcharts-angular/src/lib/utils.ts new file mode 100644 index 0000000..b6465f5 --- /dev/null +++ b/highcharts-angular/src/lib/utils.ts @@ -0,0 +1,24 @@ +import { signal } from '@angular/core'; + +export function promiseToSignal(promise: Promise) { + const value = signal(null); + const error = signal(null); + const isLoading = signal(true); + + promise + .then((result) => { + value.set(result); + error.set(null); + }) + .catch((err) => { + value.set(null); + error.set(err); + }) + .finally(() => { + isLoading.set(false); + }); + + return value.asReadonly(); +} + + From 2512d05e63c5147563ca48da09a150bd1458ede5 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Mon, 25 Nov 2024 00:18:22 +0100 Subject: [PATCH 41/94] modify directive to support new changes --- .../src/lib/highcharts-chart.directive.ts | 49 ++++++++++++------- highcharts-angular/src/public_api.ts | 2 + 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.ts b/highcharts-angular/src/lib/highcharts-chart.directive.ts index 858c821..bb316c4 100644 --- a/highcharts-angular/src/lib/highcharts-chart.directive.ts +++ b/highcharts-angular/src/lib/highcharts-chart.directive.ts @@ -9,19 +9,23 @@ import { model, output, OutputEmitterRef, - untracked + untracked, + Injector } from '@angular/core'; -import type * as Highcharts from 'highcharts'; -import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; +import { Chart } from './types'; +import { promiseToSignal } from './utils'; +import { loadHighcharts } from './highcharts-chart.token'; + @Directive({ - selector: 'highcharts-chart', + selector: '[highcharts-chart]', }) export class HighchartsChartDirective { /** * Highcharts library or Highcharts ESM module. + * @deprecated */ - Highcharts = input(); + Highcharts = input(); /** * Type of the chart constructor. @@ -47,7 +51,7 @@ export class HighchartsChartDirective { /** * Options for the Highcharts chart. */ - options = input(); + options = input(); /** * Whether to rerender the chart. @@ -56,22 +60,31 @@ export class HighchartsChartDirective { chartInstance: OutputEmitterRef = output(); // #26 - private chart = linkedSignal<{ options: Highcharts.Options | HighchartsESM.Options, update: boolean }, Highcharts.Chart | null>({ - source: () => ({options: this.options(), update: this.update()}), + private destroyRef = inject(DestroyRef); + + private el = inject(ElementRef); + + private injector = inject(Injector); + + private highCharts = promiseToSignal(loadHighcharts(this.injector)) + + private chart = linkedSignal({ + source: () => ({options: this.options(), update: this.update(), highcharts: this.highCharts()}), computation: (source, previous) => { - return untracked(() => { - if (previous && previous.value) { - previous.value.update(source.options, true, this.oneToOne() || false); - return previous.value; - } - return this.Highcharts()[this.constructorType()](this.el.nativeElement, source.options, this.callbackFunction()); - }) + const highcharts = source.highcharts || this.Highcharts(); + if (highcharts) { + return untracked(() => { + if (previous && previous.value) { + previous.value.update(source.options, true, this.oneToOne() || false); + return previous.value; + } + return highcharts[this.constructorType()](this.el.nativeElement, source.options, this.callbackFunction()); + }) + } + return undefined; } }); - private destroyRef = inject(DestroyRef); - - private el = inject(ElementRef); constructor() { this.destroyRef.onDestroy(() => { // #44 diff --git a/highcharts-angular/src/public_api.ts b/highcharts-angular/src/public_api.ts index 6da0199..1772efd 100644 --- a/highcharts-angular/src/public_api.ts +++ b/highcharts-angular/src/public_api.ts @@ -5,3 +5,5 @@ export * from './lib/highcharts-chart.module'; export * from './lib/highcharts-chart.component'; export * from './lib/highcharts-chart.directive'; +export * from './lib/highcharts-chart.token'; +export * from './lib/highcharts-chart.provider'; From f610e0dc02e975724033973708a50c63b6340c68 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Mon, 25 Nov 2024 00:19:24 +0100 Subject: [PATCH 42/94] adapt demo component --- src/app/gantt-chart/gantt-chart.component.html | 7 +------ src/app/gantt-chart/gantt-chart.component.ts | 7 ++----- .../lazy-loading-chart.component.html | 8 +------- .../lazy-loading-chart.component.ts | 9 +++------ src/app/line-chart/line-chart.component.html | 1 - src/app/line-chart/line-chart.component.ts | 7 ++----- src/app/map-chart/map-chart.component.html | 7 +------ src/app/map-chart/map-chart.component.ts | 10 +++------- src/app/stock-chart/stock-chart.component.html | 1 - src/app/stock-chart/stock-chart.component.ts | 12 ++++-------- 10 files changed, 17 insertions(+), 52 deletions(-) diff --git a/src/app/gantt-chart/gantt-chart.component.html b/src/app/gantt-chart/gantt-chart.component.html index 5f6c01c..75942bd 100644 --- a/src/app/gantt-chart/gantt-chart.component.html +++ b/src/app/gantt-chart/gantt-chart.component.html @@ -1,9 +1,4 @@

Demo #4: Highcharts Gantt chart

- +
diff --git a/src/app/gantt-chart/gantt-chart.component.ts b/src/app/gantt-chart/gantt-chart.component.ts index be29c57..3e1b49f 100644 --- a/src/app/gantt-chart/gantt-chart.component.ts +++ b/src/app/gantt-chart/gantt-chart.component.ts @@ -1,20 +1,17 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import Highcharts from 'highcharts'; import HC_gantt from 'highcharts/modules/gantt'; -import {HighchartsChartComponent} from 'highcharts-angular'; +import { HighchartsChartComponent, provideHighChartsModuleFactory } from 'highcharts-angular'; -HC_gantt(Highcharts); @Component({ selector: 'app-gantt-chart', templateUrl: './gantt-chart.component.html', styleUrls: ['./gantt-chart.component.css'], imports: [HighchartsChartComponent], + providers: [provideHighChartsModuleFactory(HC_gantt)], changeDetection: ChangeDetectionStrategy.OnPush, }) export class GanttChartComponent { - Highcharts: typeof Highcharts = Highcharts; - chartGantt: Highcharts.Options = { title: { text: 'Highcharts Gantt with Progress Indicators' diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.html b/src/app/lazy-loading-chart/lazy-loading-chart.component.html index bb42ae3..d984ab5 100644 --- a/src/app/lazy-loading-chart/lazy-loading-chart.component.html +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.html @@ -1,10 +1,4 @@

Demo #5: Lazy loading in Highcharts Stock

- +
diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts index 6ff4497..6bf5d04 100644 --- a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts @@ -1,12 +1,10 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import Highcharts from 'highcharts'; +import type Highcharts from 'highcharts'; import HC_stock from 'highcharts/modules/stock'; import { AppleDataService } from '../apple-data.service' -import $ from 'jquery'; import { Observable } from 'rxjs'; -import { HighchartsChartComponent } from 'highcharts-angular'; +import { HighchartsChartComponent, provideHighChartsModuleFactory } from 'highcharts-angular'; -HC_stock(Highcharts); interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGroupingOptionsObject { enabled: boolean @@ -17,14 +15,13 @@ interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGrou templateUrl: './lazy-loading-chart.component.html', styleUrls: ['./lazy-loading-chart.component.css'], imports: [HighchartsChartComponent], + providers: [provideHighChartsModuleFactory(HC_stock)], changeDetection: ChangeDetectionStrategy.OnPush, }) export class LazyLoadingChartComponent { constructor(private appleDataService: AppleDataService) { } - Highcharts: typeof Highcharts = Highcharts; - chartRef: Highcharts.Chart; chartCallback: Highcharts.ChartCallbackFunction = (chart) => { diff --git a/src/app/line-chart/line-chart.component.html b/src/app/line-chart/line-chart.component.html index a6a528b..30982cc 100644 --- a/src/app/line-chart/line-chart.component.html +++ b/src/app/line-chart/line-chart.component.html @@ -10,7 +10,6 @@

Demo #1: Highcharts with a basic editor

@if (showChart) {

Demo #3: Highcharts Maps with the lat/lon points

- + diff --git a/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts index e8e0ef4..c199636 100644 --- a/src/app/map-chart/map-chart.component.ts +++ b/src/app/map-chart/map-chart.component.ts @@ -1,12 +1,10 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import Highcharts from 'highcharts'; +import type Highcharts from 'highcharts'; import HC_map from 'highcharts/modules/map'; import worldMap from '@highcharts/map-collection/custom/world.geo.json'; -import { HighchartsChartComponent } from 'highcharts-angular'; +import { HighchartsChartComponent, provideHighChartsModuleFactory } from 'highcharts-angular'; // import proj4 from 'proj4'; -HC_map(Highcharts); - // Legacy way of map loading - see file at the path for more info. // require('../../js/worldmap')(Highcharts); @@ -15,13 +13,11 @@ HC_map(Highcharts); templateUrl: './map-chart.component.html', styleUrls: ['./map-chart.component.css'], imports: [HighchartsChartComponent], + providers: [provideHighChartsModuleFactory(HC_map)], changeDetection: ChangeDetectionStrategy.OnPush, }) export class MapChartComponent { - - Highcharts: typeof Highcharts = Highcharts; - chartMap: Highcharts.Options = { chart: { map: worldMap as any, diff --git a/src/app/stock-chart/stock-chart.component.html b/src/app/stock-chart/stock-chart.component.html index aa67e6d..00761e6 100644 --- a/src/app/stock-chart/stock-chart.component.html +++ b/src/app/stock-chart/stock-chart.component.html @@ -18,7 +18,6 @@

Demo #2: Highcharts Stock with simple updates

{ - console.log('some variables: ', Highcharts, chart, this.charts); + console.log('some variables: ', chart, this.charts); } }, { hcOptions: { From 423a21e3820e764a6a9a2afa52b27c7ae0f5704b Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 29 Nov 2024 23:51:54 +0100 Subject: [PATCH 43/94] a better approach to serve global setting and single providers --- .../src/lib/highcharts-chart.directive.ts | 16 +++--- .../src/lib/highcharts-chart.provider.ts | 54 +++++++++++++------ .../src/lib/highcharts-chart.service.ts | 30 +++++++++++ .../src/lib/highcharts-chart.token.ts | 16 +++--- highcharts-angular/src/lib/types.ts | 7 +++ highcharts-angular/src/lib/utils.ts | 24 --------- 6 files changed, 90 insertions(+), 57 deletions(-) create mode 100644 highcharts-angular/src/lib/highcharts-chart.service.ts delete mode 100644 highcharts-angular/src/lib/utils.ts diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.ts b/highcharts-angular/src/lib/highcharts-chart.directive.ts index bb316c4..4e257bf 100644 --- a/highcharts-angular/src/lib/highcharts-chart.directive.ts +++ b/highcharts-angular/src/lib/highcharts-chart.directive.ts @@ -9,12 +9,12 @@ import { model, output, OutputEmitterRef, - untracked, - Injector + untracked } from '@angular/core'; +import {toSignal} from '@angular/core/rxjs-interop'; +import { HighchartsChartService } from './highcharts-chart.service'; +import { HIGHCHARTS_MODULES } from './highcharts-chart.token'; import { Chart } from './types'; -import { promiseToSignal } from './utils'; -import { loadHighcharts } from './highcharts-chart.token'; @Directive({ @@ -64,9 +64,11 @@ export class HighchartsChartDirective { private el = inject(ElementRef); - private injector = inject(Injector); + private modules = inject(HIGHCHARTS_MODULES, {optional: true}); - private highCharts = promiseToSignal(loadHighcharts(this.injector)) + private highchartsChartService = inject(HighchartsChartService); + + private highCharts = toSignal(this.highchartsChartService.loaderChanges$); private chart = linkedSignal({ source: () => ({options: this.options(), update: this.update(), highcharts: this.highCharts()}), @@ -87,6 +89,8 @@ export class HighchartsChartDirective { constructor() { + // make sure to load global config + modules on demand + this.highchartsChartService.load(this.modules); this.destroyRef.onDestroy(() => { // #44 if (this.chart()) { // #56 this.chart().destroy(); diff --git a/highcharts-angular/src/lib/highcharts-chart.provider.ts b/highcharts-angular/src/lib/highcharts-chart.provider.ts index 9a30389..7549d0e 100644 --- a/highcharts-angular/src/lib/highcharts-chart.provider.ts +++ b/highcharts-angular/src/lib/highcharts-chart.provider.ts @@ -1,21 +1,41 @@ -import { Provider } from '@angular/core'; -import { HIGHCHARTS_MODULE, HIGHCHARTS_ES_MODULE } from './highcharts-chart.token'; -import { Chart, moduleFactory } from './types'; +import { EnvironmentProviders, makeEnvironmentProviders, Provider } from '@angular/core'; +import { HIGHCHARTS_LOADER, HIGHCHARTS_MODULES, HIGHCHARTS_ROOT_MODULES, HIGHCHARTS_OPTIONS } from './highcharts-chart.token'; +import { Chart, moduleFactory, HighchartsConfig } from './types'; -export const provideHighChartsModuleFactory = (...modules: moduleFactory[]): Provider[] => { - return [ + +export function provideHighChartInstance(instance: Promise) { + return makeEnvironmentProviders([ { - provide: HIGHCHARTS_MODULE, - useFactory: () => import('highcharts').then(m => m.default), + provide: HIGHCHARTS_LOADER, + useValue: instance || import('highcharts').then(m => m.default), }, - { - provide: HIGHCHARTS_ES_MODULE, - useFactory: async (Highcharts: Promise) => { - const value = await Highcharts; - modules.forEach(module => module(value)); - return value; - }, - deps: [HIGHCHARTS_MODULE], - } - ] + ]); +} + +export function provideHighChartModules(...modules: moduleFactory[]): Provider[] { + return modules.map((module) => ({ + provide: HIGHCHARTS_MODULES, + useValue: module, + multi: true, + })); +} + + +export function provideHighChartOptions(options: Chart['options']) { + return makeEnvironmentProviders([{provide: HIGHCHARTS_OPTIONS, useValue: options}]); +} + +export function provideHighChartRootModules(...modules: moduleFactory[]) { + return makeEnvironmentProviders([{provide: HIGHCHARTS_ROOT_MODULES, useValue: modules}]); +} + +export function provideHighCharts(config: HighchartsConfig) { + const providers: EnvironmentProviders[] = [provideHighChartInstance(config.instance)]; + if (config.options) { + providers.push(provideHighChartOptions(config.options)); + } + if (config.modules) { + providers.push(provideHighChartRootModules(...config.modules)); + } + return providers; } diff --git a/highcharts-angular/src/lib/highcharts-chart.service.ts b/highcharts-angular/src/lib/highcharts-chart.service.ts new file mode 100644 index 0000000..fe92846 --- /dev/null +++ b/highcharts-angular/src/lib/highcharts-chart.service.ts @@ -0,0 +1,30 @@ +import { Inject, Injectable, Optional } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { HIGHCHARTS_ROOT_MODULES, HIGHCHARTS_LOADER, HIGHCHARTS_OPTIONS } from './highcharts-chart.token'; +import { Chart, moduleFactory } from './types'; + +@Injectable({providedIn: 'root'}) +export class HighchartsChartService { + private loader: BehaviorSubject = new BehaviorSubject(undefined); + loaderChanges$ = this.loader.asObservable(); + + constructor( + @Inject(HIGHCHARTS_LOADER) private source: Promise, + @Optional() @Inject(HIGHCHARTS_OPTIONS) private globalOptions: Chart['options'], + @Optional() @Inject(HIGHCHARTS_ROOT_MODULES) private globalModules: moduleFactory[], + ) { + } + + load(modules?: moduleFactory[]) { + this.source.then(source => { + source.setOptions(this.globalOptions); + if (this.globalModules) { + this.globalModules.forEach(module => module(source)); + } + if (modules) { + modules.forEach(module => module(source)); + } + this.loader.next(source); + }); + } +} diff --git a/highcharts-angular/src/lib/highcharts-chart.token.ts b/highcharts-angular/src/lib/highcharts-chart.token.ts index 388016a..95b7a3d 100644 --- a/highcharts-angular/src/lib/highcharts-chart.token.ts +++ b/highcharts-angular/src/lib/highcharts-chart.token.ts @@ -1,11 +1,7 @@ -import { InjectionToken, Injector } from '@angular/core'; -import { Chart } from './types' +import {InjectionToken} from '@angular/core'; +import {Chart, moduleFactory} from './types' -export const HIGHCHARTS_MODULE = new InjectionToken>('HIGHCHARTS_MODULE'); -export const HIGHCHARTS_ES_MODULE = new InjectionToken('HIGHCHARTS_ES_MODULE'); - -export const loadHighcharts = (injector: Injector): Promise => { - const defaultHighcharts = import('highcharts').then(m => m.default); - const Highcharts = injector.get>(HIGHCHARTS_MODULE, defaultHighcharts); - return injector.get>(HIGHCHARTS_ES_MODULE, Highcharts); -} +export const HIGHCHARTS_LOADER = new InjectionToken>('HIGHCHARTS_MODULE'); +export const HIGHCHARTS_ROOT_MODULES = new InjectionToken('HIGHCHARTS_ROOT_MODULES'); +export const HIGHCHARTS_MODULES = new InjectionToken('HIGHCHARTS_MODULES'); +export const HIGHCHARTS_OPTIONS = new InjectionToken('HIGHCHARTS_OPTIONS', {providedIn: 'root', factory: () => ({})}); diff --git a/highcharts-angular/src/lib/types.ts b/highcharts-angular/src/lib/types.ts index 560c54c..71e289d 100644 --- a/highcharts-angular/src/lib/types.ts +++ b/highcharts-angular/src/lib/types.ts @@ -8,3 +8,10 @@ export interface Chart { } export type moduleFactory = (highcharts: Chart['highcharts']) => void; + + +export interface HighchartsConfig { + instance?: Promise; + options?: Chart['options']; + modules?: moduleFactory[]; +} diff --git a/highcharts-angular/src/lib/utils.ts b/highcharts-angular/src/lib/utils.ts deleted file mode 100644 index b6465f5..0000000 --- a/highcharts-angular/src/lib/utils.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { signal } from '@angular/core'; - -export function promiseToSignal(promise: Promise) { - const value = signal(null); - const error = signal(null); - const isLoading = signal(true); - - promise - .then((result) => { - value.set(result); - error.set(null); - }) - .catch((err) => { - value.set(null); - error.set(err); - }) - .finally(() => { - isLoading.set(false); - }); - - return value.asReadonly(); -} - - From 60b79708dcde36ef4c2b17bf6dbc5fd2167229f1 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Fri, 29 Nov 2024 23:54:33 +0100 Subject: [PATCH 44/94] correct demo app --- src/app/app.component.ts | 22 +------------------ src/app/gantt-chart/gantt-chart.component.ts | 4 ++-- .../lazy-loading-chart.component.ts | 4 ++-- src/app/line-chart/line-chart.component.ts | 4 ++-- src/app/map-chart/map-chart.component.ts | 4 ++-- src/app/stock-chart/stock-chart.component.ts | 4 ++-- src/main.ts | 19 +++++++++++++++- 7 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index bb5c66c..834a353 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,27 +1,10 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import ExportingModule from 'highcharts/modules/exporting'; -import SunsetTheme from 'highcharts/themes/sunset.js'; -import * as Highcharts from 'highcharts'; import { LineChartComponent } from './line-chart/line-chart.component'; import { StockChartComponent } from './stock-chart/stock-chart.component'; import { MapChartComponent } from './map-chart/map-chart.component'; import { GanttChartComponent } from './gantt-chart/gantt-chart.component'; import { LazyLoadingChartComponent } from './lazy-loading-chart/lazy-loading-chart.component'; -// The modules will work for all charts. -ExportingModule(Highcharts); -SunsetTheme(Highcharts); - -Highcharts.setOptions({ - title: { - style: { - color: 'tomato' - } - }, - legend: { - enabled: false - } -}); @Component({ selector: 'app-root', @@ -30,7 +13,4 @@ Highcharts.setOptions({ imports: [LineChartComponent, StockChartComponent, MapChartComponent, GanttChartComponent, LazyLoadingChartComponent], changeDetection: ChangeDetectionStrategy.OnPush, }) - -export class AppComponent { - -} +export class AppComponent {} diff --git a/src/app/gantt-chart/gantt-chart.component.ts b/src/app/gantt-chart/gantt-chart.component.ts index 3e1b49f..429776a 100644 --- a/src/app/gantt-chart/gantt-chart.component.ts +++ b/src/app/gantt-chart/gantt-chart.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import HC_gantt from 'highcharts/modules/gantt'; -import { HighchartsChartComponent, provideHighChartsModuleFactory } from 'highcharts-angular'; +import { HighchartsChartComponent, provideHighChartModules } from 'highcharts-angular'; @Component({ @@ -8,7 +8,7 @@ import { HighchartsChartComponent, provideHighChartsModuleFactory } from 'highch templateUrl: './gantt-chart.component.html', styleUrls: ['./gantt-chart.component.css'], imports: [HighchartsChartComponent], - providers: [provideHighChartsModuleFactory(HC_gantt)], + providers: [provideHighChartModules(HC_gantt)], changeDetection: ChangeDetectionStrategy.OnPush, }) export class GanttChartComponent { diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts index 6bf5d04..bc0c0d9 100644 --- a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts @@ -3,7 +3,7 @@ import type Highcharts from 'highcharts'; import HC_stock from 'highcharts/modules/stock'; import { AppleDataService } from '../apple-data.service' import { Observable } from 'rxjs'; -import { HighchartsChartComponent, provideHighChartsModuleFactory } from 'highcharts-angular'; +import { HighchartsChartComponent, provideHighChartModules } from 'highcharts-angular'; interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGroupingOptionsObject { @@ -15,7 +15,7 @@ interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGrou templateUrl: './lazy-loading-chart.component.html', styleUrls: ['./lazy-loading-chart.component.css'], imports: [HighchartsChartComponent], - providers: [provideHighChartsModuleFactory(HC_stock)], + providers: [provideHighChartModules(HC_stock)], changeDetection: ChangeDetectionStrategy.OnPush, }) export class LazyLoadingChartComponent { diff --git a/src/app/line-chart/line-chart.component.ts b/src/app/line-chart/line-chart.component.ts index f555511..7503091 100644 --- a/src/app/line-chart/line-chart.component.ts +++ b/src/app/line-chart/line-chart.component.ts @@ -1,14 +1,14 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import HC_customEvents from 'highcharts-custom-events'; import { FormsModule } from '@angular/forms'; -import { HighchartsChartComponent, provideHighChartsModuleFactory } from 'highcharts-angular'; +import { HighchartsChartComponent, provideHighChartModules } from 'highcharts-angular'; @Component({ selector: 'app-line-chart', templateUrl: './line-chart.component.html', styleUrls: ['./line-chart.component.css'], imports: [FormsModule, HighchartsChartComponent], - providers: [provideHighChartsModuleFactory(HC_customEvents)], + providers: [provideHighChartModules(HC_customEvents)], changeDetection: ChangeDetectionStrategy.OnPush, }) export class LineChartComponent { diff --git a/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts index c199636..7cf3a02 100644 --- a/src/app/map-chart/map-chart.component.ts +++ b/src/app/map-chart/map-chart.component.ts @@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import type Highcharts from 'highcharts'; import HC_map from 'highcharts/modules/map'; import worldMap from '@highcharts/map-collection/custom/world.geo.json'; -import { HighchartsChartComponent, provideHighChartsModuleFactory } from 'highcharts-angular'; +import { HighchartsChartComponent, provideHighChartModules } from 'highcharts-angular'; // import proj4 from 'proj4'; // Legacy way of map loading - see file at the path for more info. @@ -13,7 +13,7 @@ import { HighchartsChartComponent, provideHighChartsModuleFactory } from 'highch templateUrl: './map-chart.component.html', styleUrls: ['./map-chart.component.css'], imports: [HighchartsChartComponent], - providers: [provideHighChartsModuleFactory(HC_map)], + providers: [provideHighChartModules(HC_map)], changeDetection: ChangeDetectionStrategy.OnPush, }) diff --git a/src/app/stock-chart/stock-chart.component.ts b/src/app/stock-chart/stock-chart.component.ts index 23308b8..b9bf207 100644 --- a/src/app/stock-chart/stock-chart.component.ts +++ b/src/app/stock-chart/stock-chart.component.ts @@ -3,7 +3,7 @@ import type Highcharts from 'highcharts'; import HC_stock from 'highcharts/modules/stock'; import HC_customEvents from 'highcharts-custom-events'; import { FormsModule } from '@angular/forms'; -import { HighchartsChartComponent, provideHighChartsModuleFactory } from 'highcharts-angular'; +import { HighchartsChartComponent, provideHighChartModules } from 'highcharts-angular'; // Alternative way of a plugin loading: @@ -15,7 +15,7 @@ import { HighchartsChartComponent, provideHighChartsModuleFactory } from 'highch templateUrl: './stock-chart.component.html', styleUrls: ['./stock-chart.component.css'], imports: [FormsModule, HighchartsChartComponent], - providers: [provideHighChartsModuleFactory(HC_stock, HC_customEvents)], + providers: [provideHighChartModules(HC_stock, HC_customEvents)], changeDetection: ChangeDetectionStrategy.OnPush, }) export class StockChartComponent { diff --git a/src/main.ts b/src/main.ts index f62dcc1..0b48bcc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,7 @@ import { enableProdMode, importProvidersFrom } from '@angular/core'; +import ExportingModule from 'highcharts/modules/exporting'; +import SunsetTheme from 'highcharts/themes/sunset.js'; +import { provideHighCharts } from '../highcharts-angular/src/public_api'; import { environment } from './environments/environment'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { BrowserModule, bootstrapApplication } from '@angular/platform-browser'; @@ -11,7 +14,21 @@ if (environment.production) { bootstrapApplication(AppComponent, { providers: [ importProvidersFrom(BrowserModule), - provideHttpClient(withInterceptorsFromDi()) + provideHttpClient(withInterceptorsFromDi()), + provideHighCharts({ + options: { + title: { + style: { + color: 'tomato' + } + }, + legend: { + enabled: false + } + }, + // The modules will work for all charts. + modules: [ExportingModule, SunsetTheme] + }) ] }) .catch(err => console.log(err)); From 0e23dcbd0e0c310a99db2e0253254c9b799d049f Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 30 Nov 2024 00:05:52 +0100 Subject: [PATCH 45/94] use new syntax approach to inject tokens --- .../src/lib/highcharts-chart.service.ts | 11 ++++------- highcharts-angular/src/lib/highcharts-chart.token.ts | 2 +- src/main.ts | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.service.ts b/highcharts-angular/src/lib/highcharts-chart.service.ts index fe92846..f15df0c 100644 --- a/highcharts-angular/src/lib/highcharts-chart.service.ts +++ b/highcharts-angular/src/lib/highcharts-chart.service.ts @@ -1,4 +1,4 @@ -import { Inject, Injectable, Optional } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { HIGHCHARTS_ROOT_MODULES, HIGHCHARTS_LOADER, HIGHCHARTS_OPTIONS } from './highcharts-chart.token'; import { Chart, moduleFactory } from './types'; @@ -8,12 +8,9 @@ export class HighchartsChartService { private loader: BehaviorSubject = new BehaviorSubject(undefined); loaderChanges$ = this.loader.asObservable(); - constructor( - @Inject(HIGHCHARTS_LOADER) private source: Promise, - @Optional() @Inject(HIGHCHARTS_OPTIONS) private globalOptions: Chart['options'], - @Optional() @Inject(HIGHCHARTS_ROOT_MODULES) private globalModules: moduleFactory[], - ) { - } + private source: Promise = inject(HIGHCHARTS_LOADER); + private globalOptions: Chart['options'] = inject(HIGHCHARTS_OPTIONS, { optional: true }); + private globalModules: moduleFactory[] = inject(HIGHCHARTS_ROOT_MODULES, { optional: true }); load(modules?: moduleFactory[]) { this.source.then(source => { diff --git a/highcharts-angular/src/lib/highcharts-chart.token.ts b/highcharts-angular/src/lib/highcharts-chart.token.ts index 95b7a3d..9dba445 100644 --- a/highcharts-angular/src/lib/highcharts-chart.token.ts +++ b/highcharts-angular/src/lib/highcharts-chart.token.ts @@ -1,7 +1,7 @@ import {InjectionToken} from '@angular/core'; import {Chart, moduleFactory} from './types' -export const HIGHCHARTS_LOADER = new InjectionToken>('HIGHCHARTS_MODULE'); +export const HIGHCHARTS_LOADER = new InjectionToken>('HIGHCHARTS_LOADER'); export const HIGHCHARTS_ROOT_MODULES = new InjectionToken('HIGHCHARTS_ROOT_MODULES'); export const HIGHCHARTS_MODULES = new InjectionToken('HIGHCHARTS_MODULES'); export const HIGHCHARTS_OPTIONS = new InjectionToken('HIGHCHARTS_OPTIONS', {providedIn: 'root', factory: () => ({})}); diff --git a/src/main.ts b/src/main.ts index 0b48bcc..d09a837 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,7 @@ import { enableProdMode, importProvidersFrom } from '@angular/core'; import ExportingModule from 'highcharts/modules/exporting'; import SunsetTheme from 'highcharts/themes/sunset.js'; -import { provideHighCharts } from '../highcharts-angular/src/public_api'; +import { provideHighCharts } from 'highcharts-angular'; import { environment } from './environments/environment'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { BrowserModule, bootstrapApplication } from '@angular/platform-browser'; From 8aa9fc65a437fa2beb3a4402bbebe40bfdb8dd19 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 30 Nov 2024 00:46:42 +0100 Subject: [PATCH 46/94] lint files --- highcharts-angular/src/lib/highcharts-chart.directive.ts | 2 +- highcharts-angular/src/lib/highcharts-chart.module.ts | 4 ++-- highcharts-angular/src/lib/highcharts-chart.provider.ts | 2 +- highcharts-angular/src/lib/highcharts-chart.token.ts | 4 ++-- highcharts-angular/src/public_api.ts | 1 + 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.ts b/highcharts-angular/src/lib/highcharts-chart.directive.ts index 4e257bf..7d60073 100644 --- a/highcharts-angular/src/lib/highcharts-chart.directive.ts +++ b/highcharts-angular/src/lib/highcharts-chart.directive.ts @@ -11,7 +11,7 @@ import { OutputEmitterRef, untracked } from '@angular/core'; -import {toSignal} from '@angular/core/rxjs-interop'; +import { toSignal } from '@angular/core/rxjs-interop'; import { HighchartsChartService } from './highcharts-chart.service'; import { HIGHCHARTS_MODULES } from './highcharts-chart.token'; import { Chart } from './types'; diff --git a/highcharts-angular/src/lib/highcharts-chart.module.ts b/highcharts-angular/src/lib/highcharts-chart.module.ts index 908fc77..18e359d 100644 --- a/highcharts-angular/src/lib/highcharts-chart.module.ts +++ b/highcharts-angular/src/lib/highcharts-chart.module.ts @@ -1,5 +1,5 @@ -import {NgModule} from '@angular/core'; -import {HighchartsChartComponent} from './highcharts-chart.component'; +import { NgModule } from '@angular/core'; +import { HighchartsChartComponent } from './highcharts-chart.component'; /** * @deprecated Use `HighchartsChartComponent` directly instead. diff --git a/highcharts-angular/src/lib/highcharts-chart.provider.ts b/highcharts-angular/src/lib/highcharts-chart.provider.ts index 7549d0e..1cb9361 100644 --- a/highcharts-angular/src/lib/highcharts-chart.provider.ts +++ b/highcharts-angular/src/lib/highcharts-chart.provider.ts @@ -22,7 +22,7 @@ export function provideHighChartModules(...modules: moduleFactory[]): Provider[] export function provideHighChartOptions(options: Chart['options']) { - return makeEnvironmentProviders([{provide: HIGHCHARTS_OPTIONS, useValue: options}]); + return makeEnvironmentProviders([{provide: HIGHCHARTS_OPTIONS, useValue: options || {}}]); } export function provideHighChartRootModules(...modules: moduleFactory[]) { diff --git a/highcharts-angular/src/lib/highcharts-chart.token.ts b/highcharts-angular/src/lib/highcharts-chart.token.ts index 9dba445..fa05cf9 100644 --- a/highcharts-angular/src/lib/highcharts-chart.token.ts +++ b/highcharts-angular/src/lib/highcharts-chart.token.ts @@ -1,5 +1,5 @@ -import {InjectionToken} from '@angular/core'; -import {Chart, moduleFactory} from './types' +import { InjectionToken } from '@angular/core'; +import { Chart, moduleFactory } from './types' export const HIGHCHARTS_LOADER = new InjectionToken>('HIGHCHARTS_LOADER'); export const HIGHCHARTS_ROOT_MODULES = new InjectionToken('HIGHCHARTS_ROOT_MODULES'); diff --git a/highcharts-angular/src/public_api.ts b/highcharts-angular/src/public_api.ts index 1772efd..a1d2510 100644 --- a/highcharts-angular/src/public_api.ts +++ b/highcharts-angular/src/public_api.ts @@ -7,3 +7,4 @@ export * from './lib/highcharts-chart.component'; export * from './lib/highcharts-chart.directive'; export * from './lib/highcharts-chart.token'; export * from './lib/highcharts-chart.provider'; +export * from './lib/highcharts-chart.service'; From 2b132a6d8a1fd25806b522ee7410ba692b3ae5be Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 30 Nov 2024 00:47:48 +0100 Subject: [PATCH 47/94] correct test component --- src/app/tests/line-test/line-test.component.html | 7 ++----- src/app/tests/line-test/line-test.component.ts | 3 +-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/app/tests/line-test/line-test.component.html b/src/app/tests/line-test/line-test.component.html index a712ade..99f4f1e 100644 --- a/src/app/tests/line-test/line-test.component.html +++ b/src/app/tests/line-test/line-test.component.html @@ -1,5 +1,2 @@ - + + diff --git a/src/app/tests/line-test/line-test.component.ts b/src/app/tests/line-test/line-test.component.ts index 141f2f1..219c61d 100644 --- a/src/app/tests/line-test/line-test.component.ts +++ b/src/app/tests/line-test/line-test.component.ts @@ -1,5 +1,5 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import Highcharts from 'highcharts'; +import type Highcharts from 'highcharts'; import { HighchartsChartComponent } from 'highcharts-angular'; interface ExtendedSeriesCandlestickOptions extends Highcharts.SeriesCandlestickOptions { @@ -14,7 +14,6 @@ interface ExtendedSeriesCandlestickOptions extends Highcharts.SeriesCandlestickO changeDetection: ChangeDetectionStrategy.OnPush, }) export class LineTestComponent { - Highcharts: typeof Highcharts = Highcharts; updateFlag = false; chartOptions: Highcharts.Options = { From b3bab662740dd662ed17f047ec0493dc624a2092 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 30 Nov 2024 00:54:00 +0100 Subject: [PATCH 48/94] correct test component --- .../line-test/line-test.component.spec.ts | 31 +++++++++++++------ .../tests/line-test/line-test.component.ts | 2 +- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/app/tests/line-test/line-test.component.spec.ts b/src/app/tests/line-test/line-test.component.spec.ts index 7c9439a..884a76e 100644 --- a/src/app/tests/line-test/line-test.component.spec.ts +++ b/src/app/tests/line-test/line-test.component.spec.ts @@ -1,20 +1,25 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { provideHighCharts, HighchartsChartService } from '../../../../highcharts-angular/src/public_api'; import { LineTestComponent } from './line-test.component'; describe('LineTestComponent', () => { let component: LineTestComponent; let fixture: ComponentFixture; + let service: HighchartsChartService; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [LineTestComponent] + imports: [LineTestComponent], + providers: [provideHighCharts({})] }) .compileComponents(); })); - beforeEach(() => { + beforeEach(async () => { fixture = TestBed.createComponent(LineTestComponent); + service = TestBed.inject(HighchartsChartService); + service.load(); component = fixture.componentInstance; component.updateSeriesColor(); fixture.detectChanges(); @@ -24,16 +29,22 @@ describe('LineTestComponent', () => { expect(component).toBeTruthy(); }); - it('should have data given from chartOptions', () => { + it('should have data given from chartOptions', (done) => { const chartOptions = component.chartOptions; - const chart = component.Highcharts.charts[component.Highcharts.charts.length - 1]; - const series = chart.series[0]; - expect((series as any).yData).toEqual((chartOptions.series[0] as any).data); + service.loaderChanges$.subscribe(loader => { + const chart = loader.charts[loader.charts.length - 1]; + const series = chart.series[0]; + expect((series as any).yData).toEqual((chartOptions.series[0] as any).data); + done(); + }); }); - it('should be properly updated', () => { - const chart = component.Highcharts.charts[component.Highcharts.charts.length - 1]; - const series = chart.series[0] as unknown as Highcharts.Series; - expect(series.color).toEqual('hotpink'); + it('should be properly updated', (done) => { + service.loaderChanges$.subscribe(loader => { + const chart = loader.charts[loader.charts.length - 1]; + const series = chart.series[0] as unknown as Highcharts.Series; + expect(series.color).toEqual('hotpink'); + done(); + }); }); }); diff --git a/src/app/tests/line-test/line-test.component.ts b/src/app/tests/line-test/line-test.component.ts index 219c61d..dc795f5 100644 --- a/src/app/tests/line-test/line-test.component.ts +++ b/src/app/tests/line-test/line-test.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import type Highcharts from 'highcharts'; -import { HighchartsChartComponent } from 'highcharts-angular'; +import { HighchartsChartComponent } from '../../../../highcharts-angular/src/public_api'; interface ExtendedSeriesCandlestickOptions extends Highcharts.SeriesCandlestickOptions { color: Highcharts.ColorType; From 2623cadc573a37225e2de92dd69188589143d5e8 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 30 Nov 2024 15:02:54 +0100 Subject: [PATCH 49/94] allow to provide highchart at the child level --- .../src/lib/highcharts-chart.directive.ts | 6 ++++-- .../src/lib/highcharts-chart.provider.ts | 20 +++++++++++++------ .../src/lib/highcharts-chart.service.ts | 10 ++++++---- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.ts b/highcharts-angular/src/lib/highcharts-chart.directive.ts index 7d60073..c5d3877 100644 --- a/highcharts-angular/src/lib/highcharts-chart.directive.ts +++ b/highcharts-angular/src/lib/highcharts-chart.directive.ts @@ -13,7 +13,7 @@ import { } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { HighchartsChartService } from './highcharts-chart.service'; -import { HIGHCHARTS_MODULES } from './highcharts-chart.token'; +import { HIGHCHARTS_LOADER, HIGHCHARTS_MODULES } from './highcharts-chart.token'; import { Chart } from './types'; @@ -64,6 +64,8 @@ export class HighchartsChartDirective { private el = inject(ElementRef); + private loader = inject(HIGHCHARTS_LOADER, {optional: true}); + private modules = inject(HIGHCHARTS_MODULES, {optional: true}); private highchartsChartService = inject(HighchartsChartService); @@ -90,7 +92,7 @@ export class HighchartsChartDirective { constructor() { // make sure to load global config + modules on demand - this.highchartsChartService.load(this.modules); + this.highchartsChartService.load(this.modules, this.loader); this.destroyRef.onDestroy(() => { // #44 if (this.chart()) { // #56 this.chart().destroy(); diff --git a/highcharts-angular/src/lib/highcharts-chart.provider.ts b/highcharts-angular/src/lib/highcharts-chart.provider.ts index 1cb9361..c2939db 100644 --- a/highcharts-angular/src/lib/highcharts-chart.provider.ts +++ b/highcharts-angular/src/lib/highcharts-chart.provider.ts @@ -12,12 +12,20 @@ export function provideHighChartInstance(instance: Promise) ]); } -export function provideHighChartModules(...modules: moduleFactory[]): Provider[] { - return modules.map((module) => ({ - provide: HIGHCHARTS_MODULES, - useValue: module, - multi: true, - })); +export function providePartialHighChart(config: Pick): Provider[] { + const providers: Provider[] = []; + if (config.modules) { + const modules = config.modules.map((module) => ({ + provide: HIGHCHARTS_MODULES, + useValue: module, + multi: true, + })) + providers.push(...modules); + } + if (config.instance) { + providers.push({provide: HIGHCHARTS_LOADER, useValue: config.instance}); + } + return providers; } diff --git a/highcharts-angular/src/lib/highcharts-chart.service.ts b/highcharts-angular/src/lib/highcharts-chart.service.ts index f15df0c..8707a40 100644 --- a/highcharts-angular/src/lib/highcharts-chart.service.ts +++ b/highcharts-angular/src/lib/highcharts-chart.service.ts @@ -12,10 +12,12 @@ export class HighchartsChartService { private globalOptions: Chart['options'] = inject(HIGHCHARTS_OPTIONS, { optional: true }); private globalModules: moduleFactory[] = inject(HIGHCHARTS_ROOT_MODULES, { optional: true }); - load(modules?: moduleFactory[]) { - this.source.then(source => { - source.setOptions(this.globalOptions); - if (this.globalModules) { + load(modules?: moduleFactory[], loader?: Promise) { + (loader || this.source).then(source => { + if (!loader){ + source.setOptions(this.globalOptions); + } + if (this.globalModules && !loader) { this.globalModules.forEach(module => module(source)); } if (modules) { From 66ab624b7938fcea709c635cda4571e08db7d001 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 30 Nov 2024 15:05:42 +0100 Subject: [PATCH 50/94] correct demo app --- src/app/gantt-chart/gantt-chart.component.ts | 4 ++-- src/app/lazy-loading-chart/lazy-loading-chart.component.ts | 4 ++-- src/app/line-chart/line-chart.component.ts | 4 ++-- src/app/map-chart/map-chart.component.ts | 4 ++-- src/app/stock-chart/stock-chart.component.ts | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/app/gantt-chart/gantt-chart.component.ts b/src/app/gantt-chart/gantt-chart.component.ts index 429776a..e62386b 100644 --- a/src/app/gantt-chart/gantt-chart.component.ts +++ b/src/app/gantt-chart/gantt-chart.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import HC_gantt from 'highcharts/modules/gantt'; -import { HighchartsChartComponent, provideHighChartModules } from 'highcharts-angular'; +import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; @Component({ @@ -8,7 +8,7 @@ import { HighchartsChartComponent, provideHighChartModules } from 'highcharts-an templateUrl: './gantt-chart.component.html', styleUrls: ['./gantt-chart.component.css'], imports: [HighchartsChartComponent], - providers: [provideHighChartModules(HC_gantt)], + providers: [providePartialHighChart({ modules: [HC_gantt] })], changeDetection: ChangeDetectionStrategy.OnPush, }) export class GanttChartComponent { diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts index bc0c0d9..20cc21b 100644 --- a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts @@ -3,7 +3,7 @@ import type Highcharts from 'highcharts'; import HC_stock from 'highcharts/modules/stock'; import { AppleDataService } from '../apple-data.service' import { Observable } from 'rxjs'; -import { HighchartsChartComponent, provideHighChartModules } from 'highcharts-angular'; +import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGroupingOptionsObject { @@ -15,7 +15,7 @@ interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGrou templateUrl: './lazy-loading-chart.component.html', styleUrls: ['./lazy-loading-chart.component.css'], imports: [HighchartsChartComponent], - providers: [provideHighChartModules(HC_stock)], + providers: [providePartialHighChart({ modules: [HC_stock] })], changeDetection: ChangeDetectionStrategy.OnPush, }) export class LazyLoadingChartComponent { diff --git a/src/app/line-chart/line-chart.component.ts b/src/app/line-chart/line-chart.component.ts index 7503091..c5a97fc 100644 --- a/src/app/line-chart/line-chart.component.ts +++ b/src/app/line-chart/line-chart.component.ts @@ -1,14 +1,14 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import HC_customEvents from 'highcharts-custom-events'; import { FormsModule } from '@angular/forms'; -import { HighchartsChartComponent, provideHighChartModules } from 'highcharts-angular'; +import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; @Component({ selector: 'app-line-chart', templateUrl: './line-chart.component.html', styleUrls: ['./line-chart.component.css'], imports: [FormsModule, HighchartsChartComponent], - providers: [provideHighChartModules(HC_customEvents)], + providers: [providePartialHighChart({ modules: [HC_customEvents] })], changeDetection: ChangeDetectionStrategy.OnPush, }) export class LineChartComponent { diff --git a/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts index 7cf3a02..ea58113 100644 --- a/src/app/map-chart/map-chart.component.ts +++ b/src/app/map-chart/map-chart.component.ts @@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import type Highcharts from 'highcharts'; import HC_map from 'highcharts/modules/map'; import worldMap from '@highcharts/map-collection/custom/world.geo.json'; -import { HighchartsChartComponent, provideHighChartModules } from 'highcharts-angular'; +import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; // import proj4 from 'proj4'; // Legacy way of map loading - see file at the path for more info. @@ -13,7 +13,7 @@ import { HighchartsChartComponent, provideHighChartModules } from 'highcharts-an templateUrl: './map-chart.component.html', styleUrls: ['./map-chart.component.css'], imports: [HighchartsChartComponent], - providers: [provideHighChartModules(HC_map)], + providers: [providePartialHighChart({ modules: [HC_map] })], changeDetection: ChangeDetectionStrategy.OnPush, }) diff --git a/src/app/stock-chart/stock-chart.component.ts b/src/app/stock-chart/stock-chart.component.ts index b9bf207..5a36c45 100644 --- a/src/app/stock-chart/stock-chart.component.ts +++ b/src/app/stock-chart/stock-chart.component.ts @@ -3,7 +3,7 @@ import type Highcharts from 'highcharts'; import HC_stock from 'highcharts/modules/stock'; import HC_customEvents from 'highcharts-custom-events'; import { FormsModule } from '@angular/forms'; -import { HighchartsChartComponent, provideHighChartModules } from 'highcharts-angular'; +import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; // Alternative way of a plugin loading: @@ -15,7 +15,7 @@ import { HighchartsChartComponent, provideHighChartModules } from 'highcharts-an templateUrl: './stock-chart.component.html', styleUrls: ['./stock-chart.component.css'], imports: [FormsModule, HighchartsChartComponent], - providers: [provideHighChartModules(HC_stock, HC_customEvents)], + providers: [providePartialHighChart({ modules: [HC_stock, HC_customEvents] })], changeDetection: ChangeDetectionStrategy.OnPush, }) export class StockChartComponent { From 9b3ac50155f83a2bfbb84417c6ae1990d5052500 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 30 Nov 2024 17:18:38 +0100 Subject: [PATCH 51/94] use better approach --- .../src/lib/highcharts-chart.directive.ts | 27 +++++++++------ .../src/lib/highcharts-chart.provider.ts | 34 +++++-------------- .../src/lib/highcharts-chart.service.ts | 16 ++++----- .../src/lib/highcharts-chart.token.ts | 6 ++-- highcharts-angular/src/lib/types.ts | 6 +++- 5 files changed, 40 insertions(+), 49 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.ts b/highcharts-angular/src/lib/highcharts-chart.directive.ts index c5d3877..a858b7f 100644 --- a/highcharts-angular/src/lib/highcharts-chart.directive.ts +++ b/highcharts-angular/src/lib/highcharts-chart.directive.ts @@ -9,11 +9,12 @@ import { model, output, OutputEmitterRef, - untracked + untracked, + computed } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { HighchartsChartService } from './highcharts-chart.service'; -import { HIGHCHARTS_LOADER, HIGHCHARTS_MODULES } from './highcharts-chart.token'; +import { HIGHCHARTS_CONFIG } from './highcharts-chart.token'; import { Chart } from './types'; @@ -64,25 +65,31 @@ export class HighchartsChartDirective { private el = inject(ElementRef); - private loader = inject(HIGHCHARTS_LOADER, {optional: true}); - - private modules = inject(HIGHCHARTS_MODULES, {optional: true}); + private relativeConfig = inject(HIGHCHARTS_CONFIG, { optional: true }); private highchartsChartService = inject(HighchartsChartService); private highCharts = toSignal(this.highchartsChartService.loaderChanges$); + private constructorChart = computed(() => { + const constructorType = untracked(this.constructorType); + const highCharts = this.highCharts() || this.Highcharts(); + if (constructorType && highCharts) { + return highCharts[constructorType]; + } + return undefined; + }); + private chart = linkedSignal({ - source: () => ({options: this.options(), update: this.update(), highcharts: this.highCharts()}), + source: () => ({options: this.options(), update: this.update(), constructorChart: this.constructorChart()}), computation: (source, previous) => { - const highcharts = source.highcharts || this.Highcharts(); - if (highcharts) { + if (source.constructorChart) { return untracked(() => { if (previous && previous.value) { previous.value.update(source.options, true, this.oneToOne() || false); return previous.value; } - return highcharts[this.constructorType()](this.el.nativeElement, source.options, this.callbackFunction()); + return source.constructorChart(this.el.nativeElement, source.options, this.callbackFunction()); }) } return undefined; @@ -92,7 +99,7 @@ export class HighchartsChartDirective { constructor() { // make sure to load global config + modules on demand - this.highchartsChartService.load(this.modules, this.loader); + this.highchartsChartService.load(this.relativeConfig); this.destroyRef.onDestroy(() => { // #44 if (this.chart()) { // #56 this.chart().destroy(); diff --git a/highcharts-angular/src/lib/highcharts-chart.provider.ts b/highcharts-angular/src/lib/highcharts-chart.provider.ts index c2939db..e8998a7 100644 --- a/highcharts-angular/src/lib/highcharts-chart.provider.ts +++ b/highcharts-angular/src/lib/highcharts-chart.provider.ts @@ -1,40 +1,22 @@ import { EnvironmentProviders, makeEnvironmentProviders, Provider } from '@angular/core'; -import { HIGHCHARTS_LOADER, HIGHCHARTS_MODULES, HIGHCHARTS_ROOT_MODULES, HIGHCHARTS_OPTIONS } from './highcharts-chart.token'; -import { Chart, moduleFactory, HighchartsConfig } from './types'; +import { HIGHCHARTS_LOADER, HIGHCHARTS_CONFIG, HIGHCHARTS_ROOT_MODULES, HIGHCHARTS_OPTIONS } from './highcharts-chart.token'; +import { Chart, moduleFactory, HighchartsConfig, PartialHighchartsConfig } from './types'; -export function provideHighChartInstance(instance: Promise) { - return makeEnvironmentProviders([ - { - provide: HIGHCHARTS_LOADER, - useValue: instance || import('highcharts').then(m => m.default), - }, - ]); +export function providePartialHighChart(config: PartialHighchartsConfig): Provider { + return { provide: HIGHCHARTS_CONFIG, useValue: config }; } -export function providePartialHighChart(config: Pick): Provider[] { - const providers: Provider[] = []; - if (config.modules) { - const modules = config.modules.map((module) => ({ - provide: HIGHCHARTS_MODULES, - useValue: module, - multi: true, - })) - providers.push(...modules); - } - if (config.instance) { - providers.push({provide: HIGHCHARTS_LOADER, useValue: config.instance}); - } - return providers; +export function provideHighChartInstance(instance: Promise) { + return makeEnvironmentProviders([{ provide: HIGHCHARTS_LOADER, useValue: instance || import('highcharts').then(m => m.default) }]); } - export function provideHighChartOptions(options: Chart['options']) { - return makeEnvironmentProviders([{provide: HIGHCHARTS_OPTIONS, useValue: options || {}}]); + return makeEnvironmentProviders([{ provide: HIGHCHARTS_OPTIONS, useValue: options || {}} ]); } export function provideHighChartRootModules(...modules: moduleFactory[]) { - return makeEnvironmentProviders([{provide: HIGHCHARTS_ROOT_MODULES, useValue: modules}]); + return makeEnvironmentProviders([{ provide: HIGHCHARTS_ROOT_MODULES, useValue: modules }]); } export function provideHighCharts(config: HighchartsConfig) { diff --git a/highcharts-angular/src/lib/highcharts-chart.service.ts b/highcharts-angular/src/lib/highcharts-chart.service.ts index 8707a40..5be5f5f 100644 --- a/highcharts-angular/src/lib/highcharts-chart.service.ts +++ b/highcharts-angular/src/lib/highcharts-chart.service.ts @@ -1,7 +1,7 @@ import { inject, Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { HIGHCHARTS_ROOT_MODULES, HIGHCHARTS_LOADER, HIGHCHARTS_OPTIONS } from './highcharts-chart.token'; -import { Chart, moduleFactory } from './types'; +import { Chart, moduleFactory, PartialHighchartsConfig } from './types'; @Injectable({providedIn: 'root'}) export class HighchartsChartService { @@ -12,16 +12,14 @@ export class HighchartsChartService { private globalOptions: Chart['options'] = inject(HIGHCHARTS_OPTIONS, { optional: true }); private globalModules: moduleFactory[] = inject(HIGHCHARTS_ROOT_MODULES, { optional: true }); - load(modules?: moduleFactory[], loader?: Promise) { - (loader || this.source).then(source => { - if (!loader){ - source.setOptions(this.globalOptions); - } - if (this.globalModules && !loader) { + load(partialConfig?: PartialHighchartsConfig) { + this.source.then(source => { + source.setOptions(this.globalOptions); + if (this.globalModules) { this.globalModules.forEach(module => module(source)); } - if (modules) { - modules.forEach(module => module(source)); + if (partialConfig?.modules) { + partialConfig.modules.forEach(module => module(source)); } this.loader.next(source); }); diff --git a/highcharts-angular/src/lib/highcharts-chart.token.ts b/highcharts-angular/src/lib/highcharts-chart.token.ts index fa05cf9..fa12529 100644 --- a/highcharts-angular/src/lib/highcharts-chart.token.ts +++ b/highcharts-angular/src/lib/highcharts-chart.token.ts @@ -1,7 +1,7 @@ import { InjectionToken } from '@angular/core'; -import { Chart, moduleFactory } from './types' +import { Chart, moduleFactory, PartialHighchartsConfig } from './types' export const HIGHCHARTS_LOADER = new InjectionToken>('HIGHCHARTS_LOADER'); export const HIGHCHARTS_ROOT_MODULES = new InjectionToken('HIGHCHARTS_ROOT_MODULES'); -export const HIGHCHARTS_MODULES = new InjectionToken('HIGHCHARTS_MODULES'); -export const HIGHCHARTS_OPTIONS = new InjectionToken('HIGHCHARTS_OPTIONS', {providedIn: 'root', factory: () => ({})}); +export const HIGHCHARTS_OPTIONS = new InjectionToken('HIGHCHARTS_OPTIONS'); +export const HIGHCHARTS_CONFIG = new InjectionToken('HIGHCHARTS_CONFIG'); diff --git a/highcharts-angular/src/lib/types.ts b/highcharts-angular/src/lib/types.ts index 71e289d..8c5b634 100644 --- a/highcharts-angular/src/lib/types.ts +++ b/highcharts-angular/src/lib/types.ts @@ -4,11 +4,15 @@ import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; export interface Chart { options: Highcharts.Options | HighchartsESM.Options, update: boolean, - highcharts: typeof Highcharts | typeof HighchartsESM + highcharts?: typeof Highcharts | typeof HighchartsESM + constructorChart?: Function; } export type moduleFactory = (highcharts: Chart['highcharts']) => void; +export interface PartialHighchartsConfig { + modules?: moduleFactory[]; +} export interface HighchartsConfig { instance?: Promise; From 2e3eb17ca978b3f7a8a9b616e24e7617b94cde17 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 30 Nov 2024 17:54:29 +0100 Subject: [PATCH 52/94] finish upgrade --- .../src/lib/highcharts-chart.directive.ts | 47 +++++++++++-------- .../src/lib/highcharts-chart.service.ts | 4 +- .../tests/line-test/line-test.component.html | 2 +- .../line-test/line-test.component.spec.ts | 21 +++------ .../tests/line-test/line-test.component.ts | 1 + 5 files changed, 39 insertions(+), 36 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.ts b/highcharts-angular/src/lib/highcharts-chart.directive.ts index a858b7f..a8e9148 100644 --- a/highcharts-angular/src/lib/highcharts-chart.directive.ts +++ b/highcharts-angular/src/lib/highcharts-chart.directive.ts @@ -83,33 +83,40 @@ export class HighchartsChartDirective { private chart = linkedSignal({ source: () => ({options: this.options(), update: this.update(), constructorChart: this.constructorChart()}), computation: (source, previous) => { - if (source.constructorChart) { - return untracked(() => { - if (previous && previous.value) { - previous.value.update(source.options, true, this.oneToOne() || false); - return previous.value; - } - return source.constructorChart(this.el.nativeElement, source.options, this.callbackFunction()); - }) - } - return undefined; + return untracked(() => this.createOrUpdateChart(source, previous?.value, this.oneToOne(), this.callbackFunction())); } }); + private createOrUpdateChart( + source: Chart, + chart: Highcharts.Chart, + oneToOne: boolean, + callbackFunction: Highcharts.ChartCallbackFunction + ): Highcharts.Chart | null { + if (chart) { + chart.update(source.options, true, oneToOne || false); + return chart; + } + if (source.constructorChart) { + return source.constructorChart(this.el.nativeElement, source.options, callbackFunction); + } + return undefined; + } + + private destroyChart() { + if (this.chart()) { // #56 + this.chart().destroy(); + this.chart.set(null); + // emit chart instance on destroy + this.chartInstance.emit(this.chart()); + } + } + constructor() { // make sure to load global config + modules on demand this.highchartsChartService.load(this.relativeConfig); - this.destroyRef.onDestroy(() => { // #44 - if (this.chart()) { // #56 - this.chart().destroy(); - this.chart.set(null); - - // emit chart instance on destroy - this.chartInstance.emit(this.chart()); - } - }); - + this.destroyRef.onDestroy(() => this.destroyChart()); // #44 afterRenderEffect(() => this.chartInstance.emit(this.chart())); afterRenderEffect(() => { if (this.update()) { diff --git a/highcharts-angular/src/lib/highcharts-chart.service.ts b/highcharts-angular/src/lib/highcharts-chart.service.ts index 5be5f5f..d451709 100644 --- a/highcharts-angular/src/lib/highcharts-chart.service.ts +++ b/highcharts-angular/src/lib/highcharts-chart.service.ts @@ -14,7 +14,9 @@ export class HighchartsChartService { load(partialConfig?: PartialHighchartsConfig) { this.source.then(source => { - source.setOptions(this.globalOptions); + if (this.globalOptions){ + source.setOptions(this.globalOptions); + } if (this.globalModules) { this.globalModules.forEach(module => module(source)); } diff --git a/src/app/tests/line-test/line-test.component.html b/src/app/tests/line-test/line-test.component.html index 99f4f1e..6783e08 100644 --- a/src/app/tests/line-test/line-test.component.html +++ b/src/app/tests/line-test/line-test.component.html @@ -1,2 +1,2 @@ - + diff --git a/src/app/tests/line-test/line-test.component.spec.ts b/src/app/tests/line-test/line-test.component.spec.ts index 884a76e..6116bf1 100644 --- a/src/app/tests/line-test/line-test.component.spec.ts +++ b/src/app/tests/line-test/line-test.component.spec.ts @@ -29,22 +29,15 @@ describe('LineTestComponent', () => { expect(component).toBeTruthy(); }); - it('should have data given from chartOptions', (done) => { + it('should have data given from chartOptions', () => { const chartOptions = component.chartOptions; - service.loaderChanges$.subscribe(loader => { - const chart = loader.charts[loader.charts.length - 1]; - const series = chart.series[0]; - expect((series as any).yData).toEqual((chartOptions.series[0] as any).data); - done(); - }); + const series = component.chartInstance.series[0]; + expect((series as any).yData).toEqual((chartOptions.series[0] as any).data); }); - it('should be properly updated', (done) => { - service.loaderChanges$.subscribe(loader => { - const chart = loader.charts[loader.charts.length - 1]; - const series = chart.series[0] as unknown as Highcharts.Series; - expect(series.color).toEqual('hotpink'); - done(); - }); + it('should be properly updated', () => { + const chart = component.chartInstance; + const series = chart.series[0] as unknown as Highcharts.Series; + expect(series.color).toEqual('hotpink'); }); }); diff --git a/src/app/tests/line-test/line-test.component.ts b/src/app/tests/line-test/line-test.component.ts index dc795f5..92ca7dd 100644 --- a/src/app/tests/line-test/line-test.component.ts +++ b/src/app/tests/line-test/line-test.component.ts @@ -15,6 +15,7 @@ interface ExtendedSeriesCandlestickOptions extends Highcharts.SeriesCandlestickO }) export class LineTestComponent { updateFlag = false; + chartInstance: Highcharts.Chart; chartOptions: Highcharts.Options = { series: [ From b11b5c1319a918ff7a23788fdc16af354aac461a Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 30 Nov 2024 18:26:10 +0100 Subject: [PATCH 53/94] correct configuration --- angular.json | 14 ++++++++------ highcharts-angular/src/test.ts | 20 -------------------- highcharts-angular/tsconfig.lib.json | 1 - highcharts-angular/tsconfig.spec.json | 4 +--- 4 files changed, 9 insertions(+), 30 deletions(-) delete mode 100644 highcharts-angular/src/test.ts diff --git a/angular.json b/angular.json index ce215e5..b9fbba7 100644 --- a/angular.json +++ b/angular.json @@ -117,18 +117,20 @@ }, "configurations": { "production": { - "project": "highcharts-angular/ng-package.prod.json", "tsConfig": "highcharts-angular/tsconfig.lib.prod.json" + }, + "development": { + "tsConfig": "highcharts-angular/tsconfig.lib.json" } - } + }, + "defaultConfiguration": "production" }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { - "main": "src/test.ts", - "karmaConfig": "./karma.conf.js", - "polyfills": ["core-js/es/reflect", "zone.js"], - "tsConfig": "./tsconfig.spec.json", + "karmaConfig": "highcharts-angular/karma.conf.js", + "polyfills": ["zone.js", "zone.js/testing"], + "tsConfig": "highcharts-angular/tsconfig.spec.json", "scripts": [], "styles": [] } diff --git a/highcharts-angular/src/test.ts b/highcharts-angular/src/test.ts deleted file mode 100644 index 5ffcd58..0000000 --- a/highcharts-angular/src/test.ts +++ /dev/null @@ -1,20 +0,0 @@ -// This file is required by karma.conf.js and loads recursively all the .spec and framework files - -import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; -import 'zone.js/testing'; - -declare const require: any; - -// First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); -// Then we find all the tests. -const context = require.context('./', true, /\.spec\.ts$/); -// And load the modules. -context.keys().map(context); diff --git a/highcharts-angular/tsconfig.lib.json b/highcharts-angular/tsconfig.lib.json index d5d0446..e1e3eba 100644 --- a/highcharts-angular/tsconfig.lib.json +++ b/highcharts-angular/tsconfig.lib.json @@ -25,7 +25,6 @@ "flatModuleOutFile": "AUTOGENERATED" }, "exclude": [ - "src/test.ts", "**/*.spec.ts" ] } diff --git a/highcharts-angular/tsconfig.spec.json b/highcharts-angular/tsconfig.spec.json index a8d18be..d3d65e3 100644 --- a/highcharts-angular/tsconfig.spec.json +++ b/highcharts-angular/tsconfig.spec.json @@ -7,9 +7,7 @@ "node" ] }, - "files": [ - "src/test.ts" - ], + "files": [], "include": [ "**/*.spec.ts", "**/*.d.ts" From 3c0c47c29d8767e02632c54790dce54e047a23c2 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 1 Dec 2024 16:03:33 +0100 Subject: [PATCH 54/94] add test for service --- .../src/lib/highcharts-chart.provider.ts | 2 +- .../src/lib/highcharts-chart.service.spec.ts | 106 ++++++++++++++++++ .../src/lib/highcharts-chart.service.ts | 2 +- 3 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 highcharts-angular/src/lib/highcharts-chart.service.spec.ts diff --git a/highcharts-angular/src/lib/highcharts-chart.provider.ts b/highcharts-angular/src/lib/highcharts-chart.provider.ts index e8998a7..041f755 100644 --- a/highcharts-angular/src/lib/highcharts-chart.provider.ts +++ b/highcharts-angular/src/lib/highcharts-chart.provider.ts @@ -12,7 +12,7 @@ export function provideHighChartInstance(instance: Promise) } export function provideHighChartOptions(options: Chart['options']) { - return makeEnvironmentProviders([{ provide: HIGHCHARTS_OPTIONS, useValue: options || {}} ]); + return makeEnvironmentProviders([{ provide: HIGHCHARTS_OPTIONS, useValue: options } ]); } export function provideHighChartRootModules(...modules: moduleFactory[]) { diff --git a/highcharts-angular/src/lib/highcharts-chart.service.spec.ts b/highcharts-angular/src/lib/highcharts-chart.service.spec.ts new file mode 100644 index 0000000..4bf90db --- /dev/null +++ b/highcharts-angular/src/lib/highcharts-chart.service.spec.ts @@ -0,0 +1,106 @@ +import { TestBed } from '@angular/core/testing'; +import { HighchartsChartService } from './highcharts-chart.service'; +import { HIGHCHARTS_LOADER, HIGHCHARTS_OPTIONS, HIGHCHARTS_ROOT_MODULES } from './highcharts-chart.token'; +import { Chart, moduleFactory } from './types'; + +describe('HighchartsChartService', () => { + let service: HighchartsChartService; + let mockLoader: Promise; + let mockGlobalOptions: Chart['options']; + let mockGlobalModules: moduleFactory[]; + + beforeEach(() => { + mockLoader = Promise.resolve({ + setOptions: jasmine.createSpy('setOptions'), + } as unknown as Chart['highcharts']); + mockGlobalOptions = { lang: { thousandsSep: ',' } }; + mockGlobalModules = [jasmine.createSpy('module1'), jasmine.createSpy('module2')]; + + TestBed.configureTestingModule({ + providers: [ + HighchartsChartService, + { provide: HIGHCHARTS_LOADER, useValue: mockLoader }, + { provide: HIGHCHARTS_OPTIONS, useValue: mockGlobalOptions }, + { provide: HIGHCHARTS_ROOT_MODULES, useValue: mockGlobalModules }, + ], + }); + + service = TestBed.inject(HighchartsChartService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should emit the loaded Highcharts instance', async () => { + const loaderSpy = jasmine.createSpy('loaderSpy'); + service.loaderChanges$.subscribe(loaderSpy); + + service.load(); + await mockLoader; + + expect(loaderSpy).toHaveBeenCalledWith(jasmine.any(Object)); + }); + + it('should call setOptions with global options if provided', async () => { + service.load(); + const highcharts = await mockLoader; + + expect(highcharts.setOptions).toHaveBeenCalledWith(mockGlobalOptions); + }); + + it('should load global modules if provided', async () => { + service.load(); + const highcharts = await mockLoader; + + mockGlobalModules.forEach(module => { + expect(module).toHaveBeenCalledWith(highcharts); + }); + }); + + it('should load partialConfig modules if provided', async () => { + const mockPartialModules: moduleFactory[] = [ + jasmine.createSpy('partialModule1'), + jasmine.createSpy('partialModule2'), + ]; + + service.load({ modules: mockPartialModules }); + const highcharts = await mockLoader; + + mockPartialModules.forEach(module => { + expect(module).toHaveBeenCalledWith(highcharts); + }); + }); +}); + +describe('With not provided Value', () => { + let service: HighchartsChartService; + let mockLoader: Promise; + let mockGlobalModules: moduleFactory[]; + + beforeEach(() => { + mockLoader = Promise.resolve({ + setOptions: jasmine.createSpy('setOptions'), + } as unknown as Chart['highcharts']); + mockGlobalModules = []; + + + TestBed.configureTestingModule({ + providers: [ + HighchartsChartService, + { provide: HIGHCHARTS_LOADER, useValue: mockLoader }, + { provide: HIGHCHARTS_OPTIONS, useValue: undefined }, + { provide: HIGHCHARTS_ROOT_MODULES, useValue: mockGlobalModules }, + ], + }); + + service = TestBed.inject(HighchartsChartService); + }); + + it('should not call setOptions if global options are not provided', async () => { + service.load(); + const highcharts = await mockLoader; + + expect(highcharts.setOptions).not.toHaveBeenCalled(); + }); +}); diff --git a/highcharts-angular/src/lib/highcharts-chart.service.ts b/highcharts-angular/src/lib/highcharts-chart.service.ts index d451709..b50765b 100644 --- a/highcharts-angular/src/lib/highcharts-chart.service.ts +++ b/highcharts-angular/src/lib/highcharts-chart.service.ts @@ -14,7 +14,7 @@ export class HighchartsChartService { load(partialConfig?: PartialHighchartsConfig) { this.source.then(source => { - if (this.globalOptions){ + if (this.globalOptions) { source.setOptions(this.globalOptions); } if (this.globalModules) { From e30e6f793228067075cbced7ff0fdc70c91ba24b Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 1 Dec 2024 19:21:15 +0100 Subject: [PATCH 55/94] add test for directive --- .../lib/highcharts-chart.directive.spec.ts | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 highcharts-angular/src/lib/highcharts-chart.directive.spec.ts diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.spec.ts b/highcharts-angular/src/lib/highcharts-chart.directive.spec.ts new file mode 100644 index 0000000..3d116db --- /dev/null +++ b/highcharts-angular/src/lib/highcharts-chart.directive.spec.ts @@ -0,0 +1,57 @@ +import { TestBed } from '@angular/core/testing'; +import { Component, ComponentRef, DebugElement } from '@angular/core'; +import { By } from '@angular/platform-browser'; +import { of } from 'rxjs'; +import { HighchartsChartDirective } from './highcharts-chart.directive'; +import { HIGHCHARTS_CONFIG } from './highcharts-chart.token'; +import { HighchartsChartService } from './highcharts-chart.service'; + +@Component({ + template: `
`, + imports: [HighchartsChartDirective], +}) +class TestHostComponent { + options = {}; +} + +describe('HighchartsChartDirective', () => { + let debugElement: DebugElement; + let directive: HighchartsChartDirective; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [TestHostComponent, HighchartsChartDirective], + providers: [ + { + provide: HIGHCHARTS_CONFIG, + useValue: {} + }, + { + provide: HighchartsChartService, + useValue: { + loaderChanges$: of(null), + load: jasmine.createSpy('load'), + } + } + ] + }); + + const fixture = TestBed.createComponent(TestHostComponent); + fixture.detectChanges(); + debugElement = fixture.debugElement.query(By.directive(HighchartsChartDirective)); + directive = debugElement.injector.get(HighchartsChartDirective); + }); + + it('should create the directive', () => { + expect(directive).toBeTruthy(); + }); + + it('should initialize with default constructorType as "chart"', () => { + expect(directive.constructorType()).toBe('chart'); + }); + + it('should load global config on initialization', () => { + const highchartsChartService = TestBed.inject(HighchartsChartService); + expect(highchartsChartService.load).toHaveBeenCalledWith({}); + }); +}); From ccdb9acd4a24ff182ed53862a9512cc38c9ebd4c Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 14:00:15 +0100 Subject: [PATCH 56/94] revert back version so it will be changed when packing --- highcharts-angular/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highcharts-angular/package.json b/highcharts-angular/package.json index 3f0d392..aba4941 100644 --- a/highcharts-angular/package.json +++ b/highcharts-angular/package.json @@ -1,7 +1,7 @@ { "name": "highcharts-angular", "description": "Highcharts component for Angular.", - "version": "5.0.0", + "version": "4.0.1", "license": "MIT", "author": "Black Label (http://blacklabel.pl)", "bugs": { From eba03ffcbb58cec819675c21a344ffa3c61ff4f2 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 14:03:53 +0100 Subject: [PATCH 57/94] add possible chart to input "constructorType" --- highcharts-angular/src/lib/highcharts-chart.directive.ts | 4 ++-- highcharts-angular/src/lib/types.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.ts b/highcharts-angular/src/lib/highcharts-chart.directive.ts index a8e9148..35c7175 100644 --- a/highcharts-angular/src/lib/highcharts-chart.directive.ts +++ b/highcharts-angular/src/lib/highcharts-chart.directive.ts @@ -15,7 +15,7 @@ import { import { toSignal } from '@angular/core/rxjs-interop'; import { HighchartsChartService } from './highcharts-chart.service'; import { HIGHCHARTS_CONFIG } from './highcharts-chart.token'; -import { Chart } from './types'; +import type { Chart, ChartType } from './types'; @Directive({ @@ -31,7 +31,7 @@ export class HighchartsChartDirective { /** * Type of the chart constructor. */ - constructorType = input('chart'); + constructorType = input('chart'); /** * Callback function for the chart. diff --git a/highcharts-angular/src/lib/types.ts b/highcharts-angular/src/lib/types.ts index 8c5b634..e846abf 100644 --- a/highcharts-angular/src/lib/types.ts +++ b/highcharts-angular/src/lib/types.ts @@ -8,6 +8,7 @@ export interface Chart { constructorChart?: Function; } +export type ChartType = 'chart' | 'ganttChart' | 'stockChart' | 'mapChart'; export type moduleFactory = (highcharts: Chart['highcharts']) => void; export interface PartialHighchartsConfig { From 1be6e8cb97b99308775252f6ad784ce9f137bea8 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 14:04:41 +0100 Subject: [PATCH 58/94] update should be optional --- highcharts-angular/src/lib/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highcharts-angular/src/lib/types.ts b/highcharts-angular/src/lib/types.ts index e846abf..e8a4448 100644 --- a/highcharts-angular/src/lib/types.ts +++ b/highcharts-angular/src/lib/types.ts @@ -3,7 +3,7 @@ import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; export interface Chart { options: Highcharts.Options | HighchartsESM.Options, - update: boolean, + update?: boolean, highcharts?: typeof Highcharts | typeof HighchartsESM constructorChart?: Function; } From fe0d146eb95ffbd9498fc98a148b1a48e2b62af4 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 14:05:48 +0100 Subject: [PATCH 59/94] rename variable --- highcharts-angular/src/lib/highcharts-chart.directive.ts | 4 ++-- highcharts-angular/src/lib/types.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.ts b/highcharts-angular/src/lib/highcharts-chart.directive.ts index 35c7175..c0e42cc 100644 --- a/highcharts-angular/src/lib/highcharts-chart.directive.ts +++ b/highcharts-angular/src/lib/highcharts-chart.directive.ts @@ -15,7 +15,7 @@ import { import { toSignal } from '@angular/core/rxjs-interop'; import { HighchartsChartService } from './highcharts-chart.service'; import { HIGHCHARTS_CONFIG } from './highcharts-chart.token'; -import type { Chart, ChartType } from './types'; +import type { Chart, ChartConstructorType } from './types'; @Directive({ @@ -31,7 +31,7 @@ export class HighchartsChartDirective { /** * Type of the chart constructor. */ - constructorType = input('chart'); + constructorType = input('chart'); /** * Callback function for the chart. diff --git a/highcharts-angular/src/lib/types.ts b/highcharts-angular/src/lib/types.ts index e8a4448..9ea681a 100644 --- a/highcharts-angular/src/lib/types.ts +++ b/highcharts-angular/src/lib/types.ts @@ -8,7 +8,7 @@ export interface Chart { constructorChart?: Function; } -export type ChartType = 'chart' | 'ganttChart' | 'stockChart' | 'mapChart'; +export type ChartConstructorType = 'chart' | 'ganttChart' | 'stockChart' | 'mapChart'; export type moduleFactory = (highcharts: Chart['highcharts']) => void; export interface PartialHighchartsConfig { From b7469a8f4cecd8cce510c69cff5d27f7b394fed1 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 14:13:07 +0100 Subject: [PATCH 60/94] update jsdoc for oneToOne and update input --- highcharts-angular/src/lib/highcharts-chart.directive.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.ts b/highcharts-angular/src/lib/highcharts-chart.directive.ts index c0e42cc..49b31e0 100644 --- a/highcharts-angular/src/lib/highcharts-chart.directive.ts +++ b/highcharts-angular/src/lib/highcharts-chart.directive.ts @@ -39,7 +39,9 @@ export class HighchartsChartDirective { callbackFunction = input(null); /** - * Whether to update the chart one-to-one. + * When enabled, Updates `series`, `xAxis`, `yAxis`, and `annotations` to match new options. + * Items are added/removed as needed. Series with `id`s are matched by `id`; + * unmatched items are removed. Omitted `series` leaves existing ones unchanged. */ oneToOne = input(); @@ -55,7 +57,9 @@ export class HighchartsChartDirective { options = input(); /** - * Whether to rerender the chart. + * Whether to redraw the chart. + * Check how update works in Highcharts + * API doc here: https://api.highcharts.com/class-reference/Highcharts.Chart#update */ update = model(); From dbd2576a822d5542763474ec71e072189ca5cdf5 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 14:23:51 +0100 Subject: [PATCH 61/94] patch packages --- package.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 36e36b3..cdbb888 100644 --- a/package.json +++ b/package.json @@ -18,41 +18,41 @@ "e2e": "ng e2e" }, "dependencies": { - "@angular/animations": "19.0.0", - "@angular/common": "19.0.0", - "@angular/compiler": "19.0.0", - "@angular/core": "19.0.0", - "@angular/forms": "19.0.0", - "@angular/platform-browser": "19.0.0", - "@angular/platform-browser-dynamic": "19.0.0", - "@angular/router": "19.0.0", + "@angular/animations": "19.0.3", + "@angular/common": "19.0.3", + "@angular/compiler": "19.0.3", + "@angular/core": "19.0.3", + "@angular/forms": "19.0.3", + "@angular/platform-browser": "19.0.3", + "@angular/platform-browser-dynamic": "19.0.3", + "@angular/router": "19.0.3", "@highcharts/map-collection": "^2.3.0", "core-js": "^3.19.2", "highcharts": "^11.2.0", "highcharts-custom-events": "^3.0.10", "jquery": "^3.6.0", - "proj4": "^2.7.5", + "proj4": "^2.15.0", "rxjs": "^7.4.0", "tslib": "^2.3.1", "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^19.0.1", - "@angular/cli": "19.0.1", - "@angular/compiler-cli": "19.0.0", + "@angular/build": "^19.0.4", + "@angular/cli": "19.0.4", + "@angular/compiler-cli": "19.0.3", "@types/estree": "^1.0.0", - "@types/jasmine": "^5.1.4", + "@types/jasmine": "^5.1.5", "@types/jasminewd2": "^2.0.13", - "@types/node": "^18.19.64", + "@types/node": "^22.10.1", "codelyzer": "^6.0.2", - "jasmine-core": "^5.4.0", + "jasmine-core": "^5.5.0", "jasmine-spec-reporter": "~7.0.0", "karma": "^6.4.4", "karma-chrome-launcher": "^3.2.0", "karma-coverage-istanbul-reporter": "~3.0.3", "karma-jasmine": "^5.1.0", "karma-jasmine-html-reporter": "^2.1.0", - "ng-packagr": "^19.0.0", + "ng-packagr": "^19.0.1", "protractor": "~7.0.0", "standard-version": "^9.3.2", "ts-node": "^10.4.0", From ee3a775e5b715b0b0a88c8431036348c4e362256 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 14:28:32 +0100 Subject: [PATCH 62/94] patch packages --- angular.json | 6 +++--- package.json | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/angular.json b/angular.json index b9fbba7..8a80d3c 100644 --- a/angular.json +++ b/angular.json @@ -8,7 +8,7 @@ "projectType": "application", "architect": { "build": { - "builder": "@angular-devkit/build-angular:application", + "builder": "@angular/build:application", "options": { "aot": false, "allowedCommonJsDependencies": [ @@ -56,7 +56,7 @@ "defaultConfiguration": "" }, "serve": { - "builder": "@angular-devkit/build-angular:dev-server", + "builder": "@angular/build:dev-server", "options": { "buildTarget": "my-app:build" }, @@ -67,7 +67,7 @@ } }, "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", + "builder": "@angular/build:extract-i18n", "options": { "buildTarget": "my-app:build" } diff --git a/package.json b/package.json index cdbb888..fd4744c 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "zone.js": "~0.15.0" }, "devDependencies": { + "@angular-devkit/build-angular": "^19.0.4", "@angular/build": "^19.0.4", "@angular/cli": "19.0.4", "@angular/compiler-cli": "19.0.3", From 60ad6c6ab08fbda3f6deb52fa1d1f8b45af8a932 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 15:30:23 +0100 Subject: [PATCH 63/94] move default app to new folder --- angular.json | 96 +++++++++--------- apps/my-app/public/favicon.ico | Bin 0 -> 15086 bytes .../my-app/src}/app/app.component.css | 0 .../my-app/src}/app/app.component.html | 0 {src => apps/my-app/src}/app/app.component.ts | 0 apps/my-app/src/app/app.config.ts | 28 +++++ .../my-app/src}/app/apple-data.service.ts | 0 .../app/gantt-chart/gantt-chart.component.css | 0 .../gantt-chart/gantt-chart.component.html | 0 .../app/gantt-chart/gantt-chart.component.ts | 0 .../lazy-loading-chart.component.css | 0 .../lazy-loading-chart.component.html | 0 .../lazy-loading-chart.component.ts | 0 .../app/line-chart/line-chart.component.css | 0 .../app/line-chart/line-chart.component.html | 0 .../app/line-chart/line-chart.component.ts | 0 .../app/map-chart/map-chart.component.css | 0 .../app/map-chart/map-chart.component.html | 0 .../src}/app/map-chart/map-chart.component.ts | 0 .../app/stock-chart/stock-chart.component.css | 0 .../stock-chart/stock-chart.component.html | 0 .../app/stock-chart/stock-chart.component.ts | 0 .../tests/line-test/line-test.component.css | 0 .../tests/line-test/line-test.component.html | 0 .../line-test/line-test.component.spec.ts | 2 +- .../tests/line-test/line-test.component.ts | 2 +- apps/my-app/src/global.d.ts | 1 + {src => apps/my-app/src}/index.html | 3 +- apps/my-app/src/main.ts | 6 ++ apps/my-app/src/styles.css | 1 + {src => apps/my-app/src}/test.ts | 0 {src => apps/my-app/src}/typings.d.ts | 0 apps/my-app/tsconfig.app.json | 15 +++ apps/my-app/tsconfig.spec.json | 17 ++++ src/assets/.gitkeep | 0 src/environments/environment.prod.ts | 3 - src/environments/environment.ts | 8 -- src/favicon.ico | Bin 5430 -> 0 bytes src/global.d.ts | 1 - src/main.ts | 34 ------- tsconfig.app.json | 19 ---- tsconfig.json | 10 +- tsconfig.spec.json | 23 ----- 43 files changed, 126 insertions(+), 143 deletions(-) create mode 100644 apps/my-app/public/favicon.ico rename {src => apps/my-app/src}/app/app.component.css (100%) rename {src => apps/my-app/src}/app/app.component.html (100%) rename {src => apps/my-app/src}/app/app.component.ts (100%) create mode 100644 apps/my-app/src/app/app.config.ts rename {src => apps/my-app/src}/app/apple-data.service.ts (100%) rename {src => apps/my-app/src}/app/gantt-chart/gantt-chart.component.css (100%) rename {src => apps/my-app/src}/app/gantt-chart/gantt-chart.component.html (100%) rename {src => apps/my-app/src}/app/gantt-chart/gantt-chart.component.ts (100%) rename {src => apps/my-app/src}/app/lazy-loading-chart/lazy-loading-chart.component.css (100%) rename {src => apps/my-app/src}/app/lazy-loading-chart/lazy-loading-chart.component.html (100%) rename {src => apps/my-app/src}/app/lazy-loading-chart/lazy-loading-chart.component.ts (100%) rename {src => apps/my-app/src}/app/line-chart/line-chart.component.css (100%) rename {src => apps/my-app/src}/app/line-chart/line-chart.component.html (100%) rename {src => apps/my-app/src}/app/line-chart/line-chart.component.ts (100%) rename {src => apps/my-app/src}/app/map-chart/map-chart.component.css (100%) rename {src => apps/my-app/src}/app/map-chart/map-chart.component.html (100%) rename {src => apps/my-app/src}/app/map-chart/map-chart.component.ts (100%) rename {src => apps/my-app/src}/app/stock-chart/stock-chart.component.css (100%) rename {src => apps/my-app/src}/app/stock-chart/stock-chart.component.html (100%) rename {src => apps/my-app/src}/app/stock-chart/stock-chart.component.ts (100%) rename {src => apps/my-app/src}/app/tests/line-test/line-test.component.css (100%) rename {src => apps/my-app/src}/app/tests/line-test/line-test.component.html (100%) rename {src => apps/my-app/src}/app/tests/line-test/line-test.component.spec.ts (96%) rename {src => apps/my-app/src}/app/tests/line-test/line-test.component.ts (89%) create mode 100644 apps/my-app/src/global.d.ts rename {src => apps/my-app/src}/index.html (96%) create mode 100644 apps/my-app/src/main.ts create mode 100644 apps/my-app/src/styles.css rename {src => apps/my-app/src}/test.ts (100%) rename {src => apps/my-app/src}/typings.d.ts (100%) create mode 100644 apps/my-app/tsconfig.app.json create mode 100644 apps/my-app/tsconfig.spec.json delete mode 100644 src/assets/.gitkeep delete mode 100644 src/environments/environment.prod.ts delete mode 100644 src/environments/environment.ts delete mode 100644 src/favicon.ico delete mode 100644 src/global.d.ts delete mode 100644 src/main.ts delete mode 100644 tsconfig.app.json delete mode 100644 tsconfig.spec.json diff --git a/angular.json b/angular.json index 8a80d3c..a2f0b8a 100644 --- a/angular.json +++ b/angular.json @@ -1,90 +1,86 @@ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, + "newProjectRoot": "apps", "projects": { "my-app": { - "root": "", - "sourceRoot": "src", + "root": "apps/my-app", + "sourceRoot": "apps/my-app/src", "projectType": "application", + "schematics": {}, + "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { - "aot": false, - "allowedCommonJsDependencies": [ - "highcharts", - "highcharts-custom-events" - ], - "outputPath": {"base": "dist"}, - "index": "src/index.html", - "browser": "src/main.ts", - "tsConfig": "./tsconfig.app.json", - "polyfills": ["core-js/es/reflect", "zone.js"], + "outputPath": "dist/my-app", + "index": "apps/my-app/src/index.html", + "browser": "apps/my-app/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/my-app/tsconfig.app.json", "assets": [ - "src/assets", - "src/favicon.ico" + { + "glob": "**/*", + "input": "apps/my-app/public" + } ], - "styles": [], - "scripts": [], - "extractLicenses": false, - "sourceMap": true, - "optimization": false, - "namedChunks": true + "styles": ["apps/my-app/src/styles.css"], + "scripts": [] }, "configurations": { "production": { "budgets": [ + { + "type": "initial", + "maximumWarning": "500kB", + "maximumError": "1MB" + }, { "type": "anyComponentStyle", - "maximumWarning": "6kb" + "maximumWarning": "4kB", + "maximumError": "8kB" } ], - "optimization": true, - "outputHashing": "all", - "sourceMap": false, - "namedChunks": false, - "aot": true, - "extractLicenses": true, - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.prod.ts" - } - ] + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true } }, - "defaultConfiguration": "" + "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", - "options": { - "buildTarget": "my-app:build" - }, "configurations": { "production": { "buildTarget": "my-app:build:production" + }, + "development": { + "buildTarget": "my-app:build:development" } - } + }, + "defaultConfiguration": "development" }, "extract-i18n": { - "builder": "@angular/build:extract-i18n", - "options": { - "buildTarget": "my-app:build" - } + "builder": "@angular/build:extract-i18n" }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { - "main": "src/test.ts", + "main": "apps/my-app/src/test.ts", "karmaConfig": "./karma.conf.js", - "polyfills": ["core-js/es/reflect", "zone.js"], - "tsConfig": "./tsconfig.spec.json", - "scripts": [], - "styles": [], + "polyfills": ["core-js/es/reflect", "zone.js", "zone.js/testing"], + "tsConfig": "apps/my-app/tsconfig.spec.json", "assets": [ - "src/assets", - "src/favicon.ico" - ] + { + "glob": "**/*", + "input": "apps/my-app/public" + } + ], + "styles": ["apps/my-app/src/styles.css"], + "scripts": [] } } } diff --git a/apps/my-app/public/favicon.ico b/apps/my-app/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..57614f9c967596fad0a3989bec2b1deff33034f6 GIT binary patch literal 15086 zcmd^G33O9Omi+`8$@{|M-I6TH3wzF-p5CV8o}7f~KxR60LK+ApEFB<$bcciv%@SmA zV{n>g85YMFFeU*Uvl=i4v)C*qgnb;$GQ=3XTe9{Y%c`mO%su)noNCCQ*@t1WXn|B(hQ7i~ zrUK8|pUkD6#lNo!bt$6)jR!&C?`P5G(`e((P($RaLeq+o0Vd~f11;qB05kdbAOm?r zXv~GYr_sibQO9NGTCdT;+G(!{4Xs@4fPak8#L8PjgJwcs-Mm#nR_Z0s&u?nDX5^~@ z+A6?}g0|=4e_LoE69pPFO`yCD@BCjgKpzMH0O4Xs{Ahc?K3HC5;l=f zg>}alhBXX&);z$E-wai+9TTRtBX-bWYY@cl$@YN#gMd~tM_5lj6W%8ah4;uZ;jP@Q zVbuel1rPA?2@x9Y+u?e`l{Z4ngfG5q5BLH5QsEu4GVpt{KIp1?U)=3+KQ;%7ec8l* zdV=zZgN5>O3G(3L2fqj3;oBbZZw$Ij@`Juz@?+yy#OPw)>#wsTewVgTK9BGt5AbZ&?K&B3GVF&yu?@(Xj3fR3n+ZP0%+wo)D9_xp>Z$`A4 zfV>}NWjO#3lqumR0`gvnffd9Ka}JJMuHS&|55-*mCD#8e^anA<+sFZVaJe7{=p*oX zE_Uv?1>e~ga=seYzh{9P+n5<+7&9}&(kwqSaz;1aD|YM3HBiy<))4~QJSIryyqp| z8nGc(8>3(_nEI4n)n7j(&d4idW1tVLjZ7QbNLXg;LB ziHsS5pXHEjGJZb59KcvS~wv;uZR-+4qEqow`;JCfB*+b^UL^3!?;-^F%yt=VjU|v z39SSqKcRu_NVvz!zJzL0CceJaS6%!(eMshPv_0U5G`~!a#I$qI5Ic(>IONej@aH=f z)($TAT#1I{iCS4f{D2+ApS=$3E7}5=+y(rA9mM#;Cky%b*Gi0KfFA`ofKTzu`AV-9 znW|y@19rrZ*!N2AvDi<_ZeR3O2R{#dh1#3-d%$k${Rx42h+i&GZo5!C^dSL34*AKp z27mTd>k>?V&X;Nl%GZ(>0s`1UN~Hfyj>KPjtnc|)xM@{H_B9rNr~LuH`Gr5_am&Ep zTjZA8hljNj5H1Ipm-uD9rC}U{-vR!eay5&6x6FkfupdpT*84MVwGpdd(}ib)zZ3Ky z7C$pnjc82(W_y_F{PhYj?o!@3__UUvpX)v69aBSzYj3 zdi}YQkKs^SyXyFG2LTRz9{(w}y~!`{EuAaUr6G1M{*%c+kP1olW9z23dSH!G4_HSK zzae-DF$OGR{ofP*!$a(r^5Go>I3SObVI6FLY)N@o<*gl0&kLo-OT{Tl*7nCz>Iq=? zcigIDHtj|H;6sR?or8Wd_a4996GI*CXGU}o;D9`^FM!AT1pBY~?|4h^61BY#_yIfO zKO?E0 zJ{Pc`9rVEI&$xxXu`<5E)&+m(7zX^v0rqofLs&bnQT(1baQkAr^kEsk)15vlzAZ-l z@OO9RF<+IiJ*O@HE256gCt!bF=NM*vh|WVWmjVawcNoksRTMvR03H{p@cjwKh(CL4 z7_PB(dM=kO)!s4fW!1p0f93YN@?ZSG` z$B!JaAJCtW$B97}HNO9(x-t30&E}Mo1UPi@Av%uHj~?T|!4JLwV;KCx8xO#b9IlUW zI6+{a@Wj|<2Y=U;a@vXbxqZNngH8^}LleE_4*0&O7#3iGxfJ%Id>+sb;7{L=aIic8 z|EW|{{S)J-wr@;3PmlxRXU8!e2gm_%s|ReH!reFcY8%$Hl4M5>;6^UDUUae?kOy#h zk~6Ee_@ZAn48Bab__^bNmQ~+k=02jz)e0d9Z3>G?RGG!65?d1>9}7iG17?P*=GUV-#SbLRw)Hu{zx*azHxWkGNTWl@HeWjA?39Ia|sCi{e;!^`1Oec zb>Z|b65OM*;eC=ZLSy?_fg$&^2xI>qSLA2G*$nA3GEnp3$N-)46`|36m*sc#4%C|h zBN<2U;7k>&G_wL4=Ve5z`ubVD&*Hxi)r@{4RCDw7U_D`lbC(9&pG5C*z#W>8>HU)h z!h3g?2UL&sS!oY5$3?VlA0Me9W5e~V;2jds*fz^updz#AJ%G8w2V}AEE?E^=MK%Xt z__Bx1cr7+DQmuHmzn*|hh%~eEc9@m05@clWfpEFcr+06%0&dZJH&@8^&@*$qR@}o3 z@Tuuh2FsLz^zH+dN&T&?0G3I?MpmYJ;GP$J!EzjeM#YLJ!W$}MVNb0^HfOA>5Fe~UNn%Zk(PT@~9}1dt)1UQ zU*B5K?Dl#G74qmg|2>^>0WtLX#Jz{lO4NT`NYB*(L#D|5IpXr9v&7a@YsGp3vLR7L zHYGHZg7{ie6n~2p$6Yz>=^cEg7tEgk-1YRl%-s7^cbqFb(U7&Dp78+&ut5!Tn(hER z|Gp4Ed@CnOPeAe|N>U(dB;SZ?NU^AzoD^UAH_vamp6Ws}{|mSq`^+VP1g~2B{%N-!mWz<`)G)>V-<`9`L4?3dM%Qh6<@kba+m`JS{Ya@9Fq*m6$$ zA1%Ogc~VRH33|S9l%CNb4zM%k^EIpqY}@h{w(aBcJ9c05oiZx#SK9t->5lSI`=&l~ z+-Ic)a{FbBhXV$Xt!WRd`R#Jk-$+_Z52rS>?Vpt2IK<84|E-SBEoIw>cs=a{BlQ7O z-?{Fy_M&84&9|KM5wt~)*!~i~E=(6m8(uCO)I=)M?)&sRbzH$9Rovzd?ZEY}GqX+~ zFbEbLz`BZ49=2Yh-|<`waK-_4!7`ro@zlC|r&I4fc4oyb+m=|c8)8%tZ-z5FwhzDt zL5kB@u53`d@%nHl0Sp)Dw`(QU&>vujEn?GPEXUW!Wi<+4e%BORl&BIH+SwRcbS}X@ z01Pk|vA%OdJKAs17zSXtO55k!;%m9>1eW9LnyAX4uj7@${O6cfii`49qTNItzny5J zH&Gj`e}o}?xjQ}r?LrI%FjUd@xflT3|7LA|ka%Q3i}a8gVm<`HIWoJGH=$EGClX^C0lysQJ>UO(q&;`T#8txuoQ_{l^kEV9CAdXuU1Ghg8 zN_6hHFuy&1x24q5-(Z7;!poYdt*`UTdrQOIQ!2O7_+AHV2hgXaEz7)>$LEdG z<8vE^Tw$|YwZHZDPM!SNOAWG$?J)MdmEk{U!!$M#fp7*Wo}jJ$Q(=8>R`Ats?e|VU?Zt7Cdh%AdnfyN3MBWw{ z$OnREvPf7%z6`#2##_7id|H%Y{vV^vWXb?5d5?a_y&t3@p9t$ncHj-NBdo&X{wrfJ zamN)VMYROYh_SvjJ=Xd!Ga?PY_$;*L=SxFte!4O6%0HEh%iZ4=gvns7IWIyJHa|hT z2;1+e)`TvbNb3-0z&DD_)Jomsg-7p_Uh`wjGnU1urmv1_oVqRg#=C?e?!7DgtqojU zWoAB($&53;TsXu^@2;8M`#z{=rPy?JqgYM0CDf4v@z=ZD|ItJ&8%_7A#K?S{wjxgd z?xA6JdJojrWpB7fr2p_MSsU4(R7=XGS0+Eg#xR=j>`H@R9{XjwBmqAiOxOL` zt?XK-iTEOWV}f>Pz3H-s*>W z4~8C&Xq25UQ^xH6H9kY_RM1$ch+%YLF72AA7^b{~VNTG}Tj#qZltz5Q=qxR`&oIlW Nr__JTFzvMr^FKp4S3v*( literal 0 HcmV?d00001 diff --git a/src/app/app.component.css b/apps/my-app/src/app/app.component.css similarity index 100% rename from src/app/app.component.css rename to apps/my-app/src/app/app.component.css diff --git a/src/app/app.component.html b/apps/my-app/src/app/app.component.html similarity index 100% rename from src/app/app.component.html rename to apps/my-app/src/app/app.component.html diff --git a/src/app/app.component.ts b/apps/my-app/src/app/app.component.ts similarity index 100% rename from src/app/app.component.ts rename to apps/my-app/src/app/app.component.ts diff --git a/apps/my-app/src/app/app.config.ts b/apps/my-app/src/app/app.config.ts new file mode 100644 index 0000000..36573cc --- /dev/null +++ b/apps/my-app/src/app/app.config.ts @@ -0,0 +1,28 @@ +import {provideHttpClient, withInterceptorsFromDi} from '@angular/common/http'; +import {ApplicationConfig, importProvidersFrom, provideZoneChangeDetection} from '@angular/core'; +import {BrowserModule} from '@angular/platform-browser'; +import { provideHighCharts } from 'highcharts-angular'; +import ExportingModule from 'highcharts/modules/exporting'; +import SunsetTheme from 'highcharts/themes/sunset'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideZoneChangeDetection({ eventCoalescing: true }), + importProvidersFrom(BrowserModule), + provideHttpClient(withInterceptorsFromDi()), + provideHighCharts({ + options: { + title: { + style: { + color: 'tomato' + } + }, + legend: { + enabled: false + } + }, + // The modules will work for all charts. + modules: [ExportingModule, SunsetTheme] + }) + ] +}; diff --git a/src/app/apple-data.service.ts b/apps/my-app/src/app/apple-data.service.ts similarity index 100% rename from src/app/apple-data.service.ts rename to apps/my-app/src/app/apple-data.service.ts diff --git a/src/app/gantt-chart/gantt-chart.component.css b/apps/my-app/src/app/gantt-chart/gantt-chart.component.css similarity index 100% rename from src/app/gantt-chart/gantt-chart.component.css rename to apps/my-app/src/app/gantt-chart/gantt-chart.component.css diff --git a/src/app/gantt-chart/gantt-chart.component.html b/apps/my-app/src/app/gantt-chart/gantt-chart.component.html similarity index 100% rename from src/app/gantt-chart/gantt-chart.component.html rename to apps/my-app/src/app/gantt-chart/gantt-chart.component.html diff --git a/src/app/gantt-chart/gantt-chart.component.ts b/apps/my-app/src/app/gantt-chart/gantt-chart.component.ts similarity index 100% rename from src/app/gantt-chart/gantt-chart.component.ts rename to apps/my-app/src/app/gantt-chart/gantt-chart.component.ts diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.css b/apps/my-app/src/app/lazy-loading-chart/lazy-loading-chart.component.css similarity index 100% rename from src/app/lazy-loading-chart/lazy-loading-chart.component.css rename to apps/my-app/src/app/lazy-loading-chart/lazy-loading-chart.component.css diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.html b/apps/my-app/src/app/lazy-loading-chart/lazy-loading-chart.component.html similarity index 100% rename from src/app/lazy-loading-chart/lazy-loading-chart.component.html rename to apps/my-app/src/app/lazy-loading-chart/lazy-loading-chart.component.html diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts b/apps/my-app/src/app/lazy-loading-chart/lazy-loading-chart.component.ts similarity index 100% rename from src/app/lazy-loading-chart/lazy-loading-chart.component.ts rename to apps/my-app/src/app/lazy-loading-chart/lazy-loading-chart.component.ts diff --git a/src/app/line-chart/line-chart.component.css b/apps/my-app/src/app/line-chart/line-chart.component.css similarity index 100% rename from src/app/line-chart/line-chart.component.css rename to apps/my-app/src/app/line-chart/line-chart.component.css diff --git a/src/app/line-chart/line-chart.component.html b/apps/my-app/src/app/line-chart/line-chart.component.html similarity index 100% rename from src/app/line-chart/line-chart.component.html rename to apps/my-app/src/app/line-chart/line-chart.component.html diff --git a/src/app/line-chart/line-chart.component.ts b/apps/my-app/src/app/line-chart/line-chart.component.ts similarity index 100% rename from src/app/line-chart/line-chart.component.ts rename to apps/my-app/src/app/line-chart/line-chart.component.ts diff --git a/src/app/map-chart/map-chart.component.css b/apps/my-app/src/app/map-chart/map-chart.component.css similarity index 100% rename from src/app/map-chart/map-chart.component.css rename to apps/my-app/src/app/map-chart/map-chart.component.css diff --git a/src/app/map-chart/map-chart.component.html b/apps/my-app/src/app/map-chart/map-chart.component.html similarity index 100% rename from src/app/map-chart/map-chart.component.html rename to apps/my-app/src/app/map-chart/map-chart.component.html diff --git a/src/app/map-chart/map-chart.component.ts b/apps/my-app/src/app/map-chart/map-chart.component.ts similarity index 100% rename from src/app/map-chart/map-chart.component.ts rename to apps/my-app/src/app/map-chart/map-chart.component.ts diff --git a/src/app/stock-chart/stock-chart.component.css b/apps/my-app/src/app/stock-chart/stock-chart.component.css similarity index 100% rename from src/app/stock-chart/stock-chart.component.css rename to apps/my-app/src/app/stock-chart/stock-chart.component.css diff --git a/src/app/stock-chart/stock-chart.component.html b/apps/my-app/src/app/stock-chart/stock-chart.component.html similarity index 100% rename from src/app/stock-chart/stock-chart.component.html rename to apps/my-app/src/app/stock-chart/stock-chart.component.html diff --git a/src/app/stock-chart/stock-chart.component.ts b/apps/my-app/src/app/stock-chart/stock-chart.component.ts similarity index 100% rename from src/app/stock-chart/stock-chart.component.ts rename to apps/my-app/src/app/stock-chart/stock-chart.component.ts diff --git a/src/app/tests/line-test/line-test.component.css b/apps/my-app/src/app/tests/line-test/line-test.component.css similarity index 100% rename from src/app/tests/line-test/line-test.component.css rename to apps/my-app/src/app/tests/line-test/line-test.component.css diff --git a/src/app/tests/line-test/line-test.component.html b/apps/my-app/src/app/tests/line-test/line-test.component.html similarity index 100% rename from src/app/tests/line-test/line-test.component.html rename to apps/my-app/src/app/tests/line-test/line-test.component.html diff --git a/src/app/tests/line-test/line-test.component.spec.ts b/apps/my-app/src/app/tests/line-test/line-test.component.spec.ts similarity index 96% rename from src/app/tests/line-test/line-test.component.spec.ts rename to apps/my-app/src/app/tests/line-test/line-test.component.spec.ts index 6116bf1..57ad3f8 100644 --- a/src/app/tests/line-test/line-test.component.spec.ts +++ b/apps/my-app/src/app/tests/line-test/line-test.component.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { provideHighCharts, HighchartsChartService } from '../../../../highcharts-angular/src/public_api'; +import { provideHighCharts, HighchartsChartService } from '../../../../../../highcharts-angular/src/public_api'; import { LineTestComponent } from './line-test.component'; diff --git a/src/app/tests/line-test/line-test.component.ts b/apps/my-app/src/app/tests/line-test/line-test.component.ts similarity index 89% rename from src/app/tests/line-test/line-test.component.ts rename to apps/my-app/src/app/tests/line-test/line-test.component.ts index 92ca7dd..fa5f605 100644 --- a/src/app/tests/line-test/line-test.component.ts +++ b/apps/my-app/src/app/tests/line-test/line-test.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import type Highcharts from 'highcharts'; -import { HighchartsChartComponent } from '../../../../highcharts-angular/src/public_api'; +import { HighchartsChartComponent } from '../../../../../../highcharts-angular/src/public_api'; interface ExtendedSeriesCandlestickOptions extends Highcharts.SeriesCandlestickOptions { color: Highcharts.ColorType; diff --git a/apps/my-app/src/global.d.ts b/apps/my-app/src/global.d.ts new file mode 100644 index 0000000..c610914 --- /dev/null +++ b/apps/my-app/src/global.d.ts @@ -0,0 +1 @@ +declare module '*'; diff --git a/src/index.html b/apps/my-app/src/index.html similarity index 96% rename from src/index.html rename to apps/my-app/src/index.html index 8f37ba3..369c452 100644 --- a/src/index.html +++ b/apps/my-app/src/index.html @@ -1,10 +1,9 @@ - + highcharts-angular - diff --git a/apps/my-app/src/main.ts b/apps/my-app/src/main.ts new file mode 100644 index 0000000..35b00f3 --- /dev/null +++ b/apps/my-app/src/main.ts @@ -0,0 +1,6 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, appConfig) + .catch((err) => console.error(err)); diff --git a/apps/my-app/src/styles.css b/apps/my-app/src/styles.css new file mode 100644 index 0000000..90d4ee0 --- /dev/null +++ b/apps/my-app/src/styles.css @@ -0,0 +1 @@ +/* You can add global styles to this file, and also import other style files */ diff --git a/src/test.ts b/apps/my-app/src/test.ts similarity index 100% rename from src/test.ts rename to apps/my-app/src/test.ts diff --git a/src/typings.d.ts b/apps/my-app/src/typings.d.ts similarity index 100% rename from src/typings.d.ts rename to apps/my-app/src/typings.d.ts diff --git a/apps/my-app/tsconfig.app.json b/apps/my-app/tsconfig.app.json new file mode 100644 index 0000000..e40712b --- /dev/null +++ b/apps/my-app/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/apps/my-app/tsconfig.spec.json b/apps/my-app/tsconfig.spec.json new file mode 100644 index 0000000..ec8f031 --- /dev/null +++ b/apps/my-app/tsconfig.spec.json @@ -0,0 +1,17 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": [ + "jasmine", + "node" + ], + }, + "files": ["src/test.ts"], + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/src/assets/.gitkeep b/src/assets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts deleted file mode 100644 index 3612073..0000000 --- a/src/environments/environment.prod.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const environment = { - production: true -}; diff --git a/src/environments/environment.ts b/src/environments/environment.ts deleted file mode 100644 index b7f639a..0000000 --- a/src/environments/environment.ts +++ /dev/null @@ -1,8 +0,0 @@ -// The file contents for the current environment will overwrite these during build. -// The build system defaults to the dev environment which uses `environment.ts`, but if you do -// `ng build --env=prod` then `environment.prod.ts` will be used instead. -// The list of which env maps to which file can be found in `.angular-cli.json`. - -export const environment = { - production: false -}; diff --git a/src/favicon.ico b/src/favicon.ico deleted file mode 100644 index 8081c7ceaf2be08bf59010158c586170d9d2d517..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5430 zcmc(je{54#6vvCoAI3i*G5%$U7!sA3wtMZ$fH6V9C`=eXGJb@R1%(I_{vnZtpD{6n z5Pl{DmxzBDbrB>}`90e12m8T*36WoeDLA&SD_hw{H^wM!cl_RWcVA!I+x87ee975; z@4kD^=bYPn&pmG@(+JZ`rqQEKxW<}RzhW}I!|ulN=fmjVi@x{p$cC`)5$a!)X&U+blKNvN5tg=uLvuLnuqRM;Yc*swiexsoh#XPNu{9F#c`G zQLe{yWA(Y6(;>y|-efAy11k<09(@Oo1B2@0`PtZSkqK&${ zgEY}`W@t{%?9u5rF?}Y7OL{338l*JY#P!%MVQY@oqnItpZ}?s z!r?*kwuR{A@jg2Chlf0^{q*>8n5Ir~YWf*wmsh7B5&EpHfd5@xVaj&gqsdui^spyL zB|kUoblGoO7G(MuKTfa9?pGH0@QP^b#!lM1yHWLh*2iq#`C1TdrnO-d#?Oh@XV2HK zKA{`eo{--^K&MW66Lgsktfvn#cCAc*(}qsfhrvOjMGLE?`dHVipu1J3Kgr%g?cNa8 z)pkmC8DGH~fG+dlrp(5^-QBeEvkOvv#q7MBVLtm2oD^$lJZx--_=K&Ttd=-krx(Bb zcEoKJda@S!%%@`P-##$>*u%T*mh+QjV@)Qa=Mk1?#zLk+M4tIt%}wagT{5J%!tXAE;r{@=bb%nNVxvI+C+$t?!VJ@0d@HIyMJTI{vEw0Ul ze(ha!e&qANbTL1ZneNl45t=#Ot??C0MHjjgY8%*mGisN|S6%g3;Hlx#fMNcL<87MW zZ>6moo1YD?P!fJ#Jb(4)_cc50X5n0KoDYfdPoL^iV`k&o{LPyaoqMqk92wVM#_O0l z09$(A-D+gVIlq4TA&{1T@BsUH`Bm=r#l$Z51J-U&F32+hfUP-iLo=jg7Xmy+WLq6_tWv&`wDlz#`&)Jp~iQf zZP)tu>}pIIJKuw+$&t}GQuqMd%Z>0?t%&BM&Wo^4P^Y z)c6h^f2R>X8*}q|bblAF?@;%?2>$y+cMQbN{X$)^R>vtNq_5AB|0N5U*d^T?X9{xQnJYeU{ zoZL#obI;~Pp95f1`%X3D$Mh*4^?O?IT~7HqlWguezmg?Ybq|7>qQ(@pPHbE9V?f|( z+0xo!#m@Np9PljsyxBY-UA*{U*la#8Wz2sO|48_-5t8%_!n?S$zlGe+NA%?vmxjS- zHE5O3ZarU=X}$7>;Okp(UWXJxI%G_J-@IH;%5#Rt$(WUX?6*Ux!IRd$dLP6+SmPn= z8zjm4jGjN772R{FGkXwcNv8GBcZI#@Y2m{RNF_w8(Z%^A*!bS*!}s6sh*NnURytky humW;*g7R+&|Ledvc- console.log(err)); diff --git a/tsconfig.app.json b/tsconfig.app.json deleted file mode 100644 index 05ade5b..0000000 --- a/tsconfig.app.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../out-tsc/app", - "baseUrl": "tsconfig.app", - "types": [], - "paths": { - "highcharts-angular": [ - "../dist/highcharts-angular" - ], - "highcharts-angular/*": [ - "../dist/highcharts-angular/*" - ] - } - }, - "files": [ - "src/main.ts" - ] -} diff --git a/tsconfig.json b/tsconfig.json index b53c429..e0e0e4e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,15 @@ "es2018", "dom" ], - "useDefineForClassFields": false + "useDefineForClassFields": false, + "paths": { + "highcharts-angular": [ + "./dist/highcharts-angular" + ], + "highcharts-angular/*": [ + "./dist/highcharts-angular/*" + ] + } }, "angularCompilerOptions": { "fullTemplateTypeCheck": true diff --git a/tsconfig.spec.json b/tsconfig.spec.json deleted file mode 100644 index efa2f1b..0000000 --- a/tsconfig.spec.json +++ /dev/null @@ -1,23 +0,0 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "paths": { - "highcharts-angular": ["../dist/highcharts-angular", "highcharts-angular/src/public_api.ts"], - "highcharts-angular/*": ["../dist/highcharts-angular/*"] - }, - "outDir": "./out-tsc/spec", - "types": [ - "jasmine", - "node" - ] - }, - "files": [ - "src/test.ts" - ], - "include": [ - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} - From cbcfada95b8a6b6df79044c09d58314b349c20b6 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 15:30:43 +0100 Subject: [PATCH 64/94] default command to my-app --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index fd4744c..e2655d6 100644 --- a/package.json +++ b/package.json @@ -7,10 +7,10 @@ "author": "Black Label (http://blacklabel.pl)", "scripts": { "ng": "ng", - "serve": "ng serve --open", + "serve": "ng serve my-app --open", "start": "node tasks/build.js && npm run serve", "build": "node tasks/build.js", - "test": "ng test", + "test": "ng test my-app", "lint": "ng lint highcharts-angular", "release": "cd ./highcharts-angular && standard-version && cd ../ && node tasks/build.js && node tasks/release.js", "release-minor": "cd ./highcharts-angular && standard-version --release-as minor && cd ../ && node tasks/build.js && node tasks/release.js", From 9aa01fe9d64563254f58e13bc8f9df94fe462c31 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 16:09:05 +0100 Subject: [PATCH 65/94] handle SSR case for directive --- highcharts-angular/src/lib/highcharts-chart.directive.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.ts b/highcharts-angular/src/lib/highcharts-chart.directive.ts index 49b31e0..273c937 100644 --- a/highcharts-angular/src/lib/highcharts-chart.directive.ts +++ b/highcharts-angular/src/lib/highcharts-chart.directive.ts @@ -10,8 +10,10 @@ import { output, OutputEmitterRef, untracked, - computed + computed, + PLATFORM_ID, } from '@angular/core'; +import { isPlatformServer } from '@angular/common'; import { toSignal } from '@angular/core/rxjs-interop'; import { HighchartsChartService } from './highcharts-chart.service'; import { HIGHCHARTS_CONFIG } from './highcharts-chart.token'; @@ -69,6 +71,8 @@ export class HighchartsChartDirective { private el = inject(ElementRef); + private platformId = inject(PLATFORM_ID); + private relativeConfig = inject(HIGHCHARTS_CONFIG, { optional: true }); private highchartsChartService = inject(HighchartsChartService); @@ -118,6 +122,9 @@ export class HighchartsChartDirective { constructor() { + if (this.platformId && isPlatformServer(this.platformId)) { + return; + } // make sure to load global config + modules on demand this.highchartsChartService.load(this.relativeConfig); this.destroyRef.onDestroy(() => this.destroyChart()); // #44 From 5622ee71618e63138382eb163fa9e6f67034bd88 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 16:12:33 +0100 Subject: [PATCH 66/94] add new ssr-app for showcase --- angular.json | 94 ++++++ apps/my-ssr-app/public/favicon.ico | Bin 0 -> 15086 bytes apps/my-ssr-app/src/app/app.component.css | 22 ++ apps/my-ssr-app/src/app/app.component.html | 7 + apps/my-ssr-app/src/app/app.component.ts | 16 + apps/my-ssr-app/src/app/app.config.server.ts | 11 + apps/my-ssr-app/src/app/app.config.ts | 29 ++ apps/my-ssr-app/src/app/apple-data.service.ts | 28 ++ .../app/gantt-chart/gantt-chart.component.css | 11 + .../gantt-chart/gantt-chart.component.html | 4 + .../app/gantt-chart/gantt-chart.component.ts | 52 +++ .../lazy-loading-chart.component.css | 11 + .../lazy-loading-chart.component.html | 4 + .../lazy-loading-chart.component.ts | 136 ++++++++ .../app/line-chart/line-chart.component.css | 32 ++ .../app/line-chart/line-chart.component.html | 19 ++ .../app/line-chart/line-chart.component.ts | 66 ++++ .../src/app/map-chart/map-chart.component.css | 11 + .../app/map-chart/map-chart.component.html | 4 + .../src/app/map-chart/map-chart.component.ts | 301 ++++++++++++++++++ .../app/stock-chart/stock-chart.component.css | 23 ++ .../stock-chart/stock-chart.component.html | 26 ++ .../app/stock-chart/stock-chart.component.ts | 114 +++++++ apps/my-ssr-app/src/index.html | 13 + apps/my-ssr-app/src/main.server.ts | 7 + apps/my-ssr-app/src/main.ts | 6 + apps/my-ssr-app/src/server.ts | 65 ++++ apps/my-ssr-app/src/styles.css | 1 + apps/my-ssr-app/tsconfig.app.json | 19 ++ apps/my-ssr-app/tsconfig.spec.json | 15 + package.json | 8 +- 31 files changed, 1154 insertions(+), 1 deletion(-) create mode 100644 apps/my-ssr-app/public/favicon.ico create mode 100644 apps/my-ssr-app/src/app/app.component.css create mode 100644 apps/my-ssr-app/src/app/app.component.html create mode 100644 apps/my-ssr-app/src/app/app.component.ts create mode 100644 apps/my-ssr-app/src/app/app.config.server.ts create mode 100644 apps/my-ssr-app/src/app/app.config.ts create mode 100644 apps/my-ssr-app/src/app/apple-data.service.ts create mode 100644 apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.css create mode 100644 apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.html create mode 100644 apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.ts create mode 100644 apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.css create mode 100644 apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.html create mode 100644 apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.ts create mode 100644 apps/my-ssr-app/src/app/line-chart/line-chart.component.css create mode 100644 apps/my-ssr-app/src/app/line-chart/line-chart.component.html create mode 100644 apps/my-ssr-app/src/app/line-chart/line-chart.component.ts create mode 100644 apps/my-ssr-app/src/app/map-chart/map-chart.component.css create mode 100644 apps/my-ssr-app/src/app/map-chart/map-chart.component.html create mode 100644 apps/my-ssr-app/src/app/map-chart/map-chart.component.ts create mode 100644 apps/my-ssr-app/src/app/stock-chart/stock-chart.component.css create mode 100644 apps/my-ssr-app/src/app/stock-chart/stock-chart.component.html create mode 100644 apps/my-ssr-app/src/app/stock-chart/stock-chart.component.ts create mode 100644 apps/my-ssr-app/src/index.html create mode 100644 apps/my-ssr-app/src/main.server.ts create mode 100644 apps/my-ssr-app/src/main.ts create mode 100644 apps/my-ssr-app/src/server.ts create mode 100644 apps/my-ssr-app/src/styles.css create mode 100644 apps/my-ssr-app/tsconfig.app.json create mode 100644 apps/my-ssr-app/tsconfig.spec.json diff --git a/angular.json b/angular.json index a2f0b8a..3620f8f 100644 --- a/angular.json +++ b/angular.json @@ -132,6 +132,100 @@ } } } + }, + "my-ssr-app": { + "projectType": "application", + "schematics": {}, + "root": "apps/my-ssr-app", + "sourceRoot": "apps/my-ssr-app/src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:application", + "options": { + "outputPath": "dist/my-ssr-app", + "index": "apps/my-ssr-app/src/index.html", + "browser": "apps/my-ssr-app/src/main.ts", + "polyfills": [ + "zone.js" + ], + "tsConfig": "apps/my-ssr-app/tsconfig.app.json", + "assets": [ + { + "glob": "**/*", + "input": "apps/my-ssr-app/public" + } + ], + "styles": [ + "apps/my-ssr-app/src/styles.css" + ], + "scripts": [], + "server": "apps/my-ssr-app/src/main.server.ts", + "prerender": true, + "ssr": { + "entry": "apps/my-ssr-app/src/server.ts" + } + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kB", + "maximumError": "1MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kB", + "maximumError": "8kB" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "my-ssr-app:build:production" + }, + "development": { + "buildTarget": "my-ssr-app:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n" + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "polyfills": [ + "zone.js", + "zone.js/testing" + ], + "tsConfig": "apps/my-ssr-app/tsconfig.spec.json", + "assets": [ + { + "glob": "**/*", + "input": "apps/my-ssr-app/public" + } + ], + "styles": [ + "apps/my-ssr-app/src/styles.css" + ], + "scripts": [] + } + } + } } }, "schematics": { diff --git a/apps/my-ssr-app/public/favicon.ico b/apps/my-ssr-app/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..57614f9c967596fad0a3989bec2b1deff33034f6 GIT binary patch literal 15086 zcmd^G33O9Omi+`8$@{|M-I6TH3wzF-p5CV8o}7f~KxR60LK+ApEFB<$bcciv%@SmA zV{n>g85YMFFeU*Uvl=i4v)C*qgnb;$GQ=3XTe9{Y%c`mO%su)noNCCQ*@t1WXn|B(hQ7i~ zrUK8|pUkD6#lNo!bt$6)jR!&C?`P5G(`e((P($RaLeq+o0Vd~f11;qB05kdbAOm?r zXv~GYr_sibQO9NGTCdT;+G(!{4Xs@4fPak8#L8PjgJwcs-Mm#nR_Z0s&u?nDX5^~@ z+A6?}g0|=4e_LoE69pPFO`yCD@BCjgKpzMH0O4Xs{Ahc?K3HC5;l=f zg>}alhBXX&);z$E-wai+9TTRtBX-bWYY@cl$@YN#gMd~tM_5lj6W%8ah4;uZ;jP@Q zVbuel1rPA?2@x9Y+u?e`l{Z4ngfG5q5BLH5QsEu4GVpt{KIp1?U)=3+KQ;%7ec8l* zdV=zZgN5>O3G(3L2fqj3;oBbZZw$Ij@`Juz@?+yy#OPw)>#wsTewVgTK9BGt5AbZ&?K&B3GVF&yu?@(Xj3fR3n+ZP0%+wo)D9_xp>Z$`A4 zfV>}NWjO#3lqumR0`gvnffd9Ka}JJMuHS&|55-*mCD#8e^anA<+sFZVaJe7{=p*oX zE_Uv?1>e~ga=seYzh{9P+n5<+7&9}&(kwqSaz;1aD|YM3HBiy<))4~QJSIryyqp| z8nGc(8>3(_nEI4n)n7j(&d4idW1tVLjZ7QbNLXg;LB ziHsS5pXHEjGJZb59KcvS~wv;uZR-+4qEqow`;JCfB*+b^UL^3!?;-^F%yt=VjU|v z39SSqKcRu_NVvz!zJzL0CceJaS6%!(eMshPv_0U5G`~!a#I$qI5Ic(>IONej@aH=f z)($TAT#1I{iCS4f{D2+ApS=$3E7}5=+y(rA9mM#;Cky%b*Gi0KfFA`ofKTzu`AV-9 znW|y@19rrZ*!N2AvDi<_ZeR3O2R{#dh1#3-d%$k${Rx42h+i&GZo5!C^dSL34*AKp z27mTd>k>?V&X;Nl%GZ(>0s`1UN~Hfyj>KPjtnc|)xM@{H_B9rNr~LuH`Gr5_am&Ep zTjZA8hljNj5H1Ipm-uD9rC}U{-vR!eay5&6x6FkfupdpT*84MVwGpdd(}ib)zZ3Ky z7C$pnjc82(W_y_F{PhYj?o!@3__UUvpX)v69aBSzYj3 zdi}YQkKs^SyXyFG2LTRz9{(w}y~!`{EuAaUr6G1M{*%c+kP1olW9z23dSH!G4_HSK zzae-DF$OGR{ofP*!$a(r^5Go>I3SObVI6FLY)N@o<*gl0&kLo-OT{Tl*7nCz>Iq=? zcigIDHtj|H;6sR?or8Wd_a4996GI*CXGU}o;D9`^FM!AT1pBY~?|4h^61BY#_yIfO zKO?E0 zJ{Pc`9rVEI&$xxXu`<5E)&+m(7zX^v0rqofLs&bnQT(1baQkAr^kEsk)15vlzAZ-l z@OO9RF<+IiJ*O@HE256gCt!bF=NM*vh|WVWmjVawcNoksRTMvR03H{p@cjwKh(CL4 z7_PB(dM=kO)!s4fW!1p0f93YN@?ZSG` z$B!JaAJCtW$B97}HNO9(x-t30&E}Mo1UPi@Av%uHj~?T|!4JLwV;KCx8xO#b9IlUW zI6+{a@Wj|<2Y=U;a@vXbxqZNngH8^}LleE_4*0&O7#3iGxfJ%Id>+sb;7{L=aIic8 z|EW|{{S)J-wr@;3PmlxRXU8!e2gm_%s|ReH!reFcY8%$Hl4M5>;6^UDUUae?kOy#h zk~6Ee_@ZAn48Bab__^bNmQ~+k=02jz)e0d9Z3>G?RGG!65?d1>9}7iG17?P*=GUV-#SbLRw)Hu{zx*azHxWkGNTWl@HeWjA?39Ia|sCi{e;!^`1Oec zb>Z|b65OM*;eC=ZLSy?_fg$&^2xI>qSLA2G*$nA3GEnp3$N-)46`|36m*sc#4%C|h zBN<2U;7k>&G_wL4=Ve5z`ubVD&*Hxi)r@{4RCDw7U_D`lbC(9&pG5C*z#W>8>HU)h z!h3g?2UL&sS!oY5$3?VlA0Me9W5e~V;2jds*fz^updz#AJ%G8w2V}AEE?E^=MK%Xt z__Bx1cr7+DQmuHmzn*|hh%~eEc9@m05@clWfpEFcr+06%0&dZJH&@8^&@*$qR@}o3 z@Tuuh2FsLz^zH+dN&T&?0G3I?MpmYJ;GP$J!EzjeM#YLJ!W$}MVNb0^HfOA>5Fe~UNn%Zk(PT@~9}1dt)1UQ zU*B5K?Dl#G74qmg|2>^>0WtLX#Jz{lO4NT`NYB*(L#D|5IpXr9v&7a@YsGp3vLR7L zHYGHZg7{ie6n~2p$6Yz>=^cEg7tEgk-1YRl%-s7^cbqFb(U7&Dp78+&ut5!Tn(hER z|Gp4Ed@CnOPeAe|N>U(dB;SZ?NU^AzoD^UAH_vamp6Ws}{|mSq`^+VP1g~2B{%N-!mWz<`)G)>V-<`9`L4?3dM%Qh6<@kba+m`JS{Ya@9Fq*m6$$ zA1%Ogc~VRH33|S9l%CNb4zM%k^EIpqY}@h{w(aBcJ9c05oiZx#SK9t->5lSI`=&l~ z+-Ic)a{FbBhXV$Xt!WRd`R#Jk-$+_Z52rS>?Vpt2IK<84|E-SBEoIw>cs=a{BlQ7O z-?{Fy_M&84&9|KM5wt~)*!~i~E=(6m8(uCO)I=)M?)&sRbzH$9Rovzd?ZEY}GqX+~ zFbEbLz`BZ49=2Yh-|<`waK-_4!7`ro@zlC|r&I4fc4oyb+m=|c8)8%tZ-z5FwhzDt zL5kB@u53`d@%nHl0Sp)Dw`(QU&>vujEn?GPEXUW!Wi<+4e%BORl&BIH+SwRcbS}X@ z01Pk|vA%OdJKAs17zSXtO55k!;%m9>1eW9LnyAX4uj7@${O6cfii`49qTNItzny5J zH&Gj`e}o}?xjQ}r?LrI%FjUd@xflT3|7LA|ka%Q3i}a8gVm<`HIWoJGH=$EGClX^C0lysQJ>UO(q&;`T#8txuoQ_{l^kEV9CAdXuU1Ghg8 zN_6hHFuy&1x24q5-(Z7;!poYdt*`UTdrQOIQ!2O7_+AHV2hgXaEz7)>$LEdG z<8vE^Tw$|YwZHZDPM!SNOAWG$?J)MdmEk{U!!$M#fp7*Wo}jJ$Q(=8>R`Ats?e|VU?Zt7Cdh%AdnfyN3MBWw{ z$OnREvPf7%z6`#2##_7id|H%Y{vV^vWXb?5d5?a_y&t3@p9t$ncHj-NBdo&X{wrfJ zamN)VMYROYh_SvjJ=Xd!Ga?PY_$;*L=SxFte!4O6%0HEh%iZ4=gvns7IWIyJHa|hT z2;1+e)`TvbNb3-0z&DD_)Jomsg-7p_Uh`wjGnU1urmv1_oVqRg#=C?e?!7DgtqojU zWoAB($&53;TsXu^@2;8M`#z{=rPy?JqgYM0CDf4v@z=ZD|ItJ&8%_7A#K?S{wjxgd z?xA6JdJojrWpB7fr2p_MSsU4(R7=XGS0+Eg#xR=j>`H@R9{XjwBmqAiOxOL` zt?XK-iTEOWV}f>Pz3H-s*>W z4~8C&Xq25UQ^xH6H9kY_RM1$ch+%YLF72AA7^b{~VNTG}Tj#qZltz5Q=qxR`&oIlW Nr__JTFzvMr^FKp4S3v*( literal 0 HcmV?d00001 diff --git a/apps/my-ssr-app/src/app/app.component.css b/apps/my-ssr-app/src/app/app.component.css new file mode 100644 index 0000000..58a2628 --- /dev/null +++ b/apps/my-ssr-app/src/app/app.component.css @@ -0,0 +1,22 @@ +.card { + border: solid 1px #E1E1E1; + border-radius: 0.5rem; + display: flex; + flex-direction: column; + margin-top: 2rem; + max-width: 1184px; + padding: 2rem; + width: 100%; + background: white; +} + +main { + display:flex; + flex-direction: column; + align-items: center; + width: 100%; +} + +main:last-child { + margin-bottom: 2rem; +} diff --git a/apps/my-ssr-app/src/app/app.component.html b/apps/my-ssr-app/src/app/app.component.html new file mode 100644 index 0000000..bbfc368 --- /dev/null +++ b/apps/my-ssr-app/src/app/app.component.html @@ -0,0 +1,7 @@ +
+ + + + + +
diff --git a/apps/my-ssr-app/src/app/app.component.ts b/apps/my-ssr-app/src/app/app.component.ts new file mode 100644 index 0000000..b42cd04 --- /dev/null +++ b/apps/my-ssr-app/src/app/app.component.ts @@ -0,0 +1,16 @@ +import { Component } from '@angular/core'; +import {GanttChartComponent} from './gantt-chart/gantt-chart.component'; +import {LazyLoadingChartComponent} from './lazy-loading-chart/lazy-loading-chart.component'; +import {LineChartComponent} from './line-chart/line-chart.component'; +// import {MapChartComponent} from './map-chart/map-chart.component'; +import {StockChartComponent} from './stock-chart/stock-chart.component'; + +@Component({ + selector: 'app-root', + imports: [GanttChartComponent, LineChartComponent, StockChartComponent, LazyLoadingChartComponent], + templateUrl: './app.component.html', + styleUrl: './app.component.css' +}) +export class AppComponent { + title = 'my-ssr-app'; +} diff --git a/apps/my-ssr-app/src/app/app.config.server.ts b/apps/my-ssr-app/src/app/app.config.server.ts new file mode 100644 index 0000000..3514d3a --- /dev/null +++ b/apps/my-ssr-app/src/app/app.config.server.ts @@ -0,0 +1,11 @@ +import { mergeApplicationConfig, ApplicationConfig } from '@angular/core'; +import { provideServerRendering } from '@angular/platform-server'; +import { appConfig } from './app.config'; + +const serverConfig: ApplicationConfig = { + providers: [ + provideServerRendering(), + ] +}; + +export const config = mergeApplicationConfig(appConfig, serverConfig); diff --git a/apps/my-ssr-app/src/app/app.config.ts b/apps/my-ssr-app/src/app/app.config.ts new file mode 100644 index 0000000..5863f39 --- /dev/null +++ b/apps/my-ssr-app/src/app/app.config.ts @@ -0,0 +1,29 @@ +import {provideHttpClient, withFetch, withInterceptorsFromDi} from '@angular/common/http'; +import {ApplicationConfig, importProvidersFrom, provideZoneChangeDetection} from '@angular/core'; +import {BrowserModule, provideClientHydration, withEventReplay} from '@angular/platform-browser'; +import {provideHighCharts} from 'highcharts-angular'; +import ExportingModule from 'highcharts/modules/exporting'; +import SunsetTheme from 'highcharts/themes/sunset'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideZoneChangeDetection({eventCoalescing: true}), + provideClientHydration(withEventReplay()), + importProvidersFrom(BrowserModule), + provideHttpClient(withInterceptorsFromDi(), withFetch()), + provideHighCharts({ + options: { + title: { + style: { + color: 'tomato' + } + }, + legend: { + enabled: false + } + }, + // The modules will work for all charts. + modules: [ExportingModule, SunsetTheme] + }) + ] +}; diff --git a/apps/my-ssr-app/src/app/apple-data.service.ts b/apps/my-ssr-app/src/app/apple-data.service.ts new file mode 100644 index 0000000..d1416ce --- /dev/null +++ b/apps/my-ssr-app/src/app/apple-data.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; +import { HttpClient, HttpErrorResponse } from '@angular/common/http' +import { Observable, throwError } from 'rxjs'; +import { catchError } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root' +}) +export class AppleDataService { + private dataUrl = 'https://demo-live-data.highcharts.com/aapl-historical.json'; + + constructor(private http: HttpClient) { } + + fetchData(): Observable { + return this.http.get(this.dataUrl) + .pipe(catchError(this.errorHandler)); + } + + fetchSqlData(min: number, max: number): Observable { + return this.http.get(`${this.dataUrl}?start=${Math.round(min)}&end=${Math.round(max)}`) + .pipe(catchError(this.errorHandler)); + } + + errorHandler(error: HttpErrorResponse) { + return throwError(error.message || 'server error.'); + } + +} diff --git a/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.css b/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.css new file mode 100644 index 0000000..caf005c --- /dev/null +++ b/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.css @@ -0,0 +1,11 @@ +h2 { + font-family: Arial, Helvetica, sans-serif; + font-size: 1.25rem; + margin: 0 0 1.5rem 0; +} + +.main { + width: 100%; + height: 350px; + display: block; +} diff --git a/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.html b/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.html new file mode 100644 index 0000000..75942bd --- /dev/null +++ b/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.html @@ -0,0 +1,4 @@ +
+

Demo #4: Highcharts Gantt chart

+ +
diff --git a/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.ts b/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.ts new file mode 100644 index 0000000..2654dfd --- /dev/null +++ b/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.ts @@ -0,0 +1,52 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import HC_gantt from 'highcharts/modules/gantt'; +import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; + + +@Component({ + selector: 'app-gantt-chart', + templateUrl: './gantt-chart.component.html', + styleUrls: ['./gantt-chart.component.css'], + imports: [HighchartsChartComponent], + providers: [providePartialHighChart({ modules: [HC_gantt] })], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class GanttChartComponent { + chartGantt: Highcharts.Options = { + title: { + text: 'Highcharts Gantt with Progress Indicators' + }, + xAxis: { + min: Date.UTC(2014, 10, 17), + max: Date.UTC(2014, 10, 30) + }, + + series: [{ + name: 'Project 1', + type: 'gantt', + data: [{ + name: 'Start prototype', + start: Date.UTC(2014, 10, 18), + end: Date.UTC(2014, 10, 25), + completed: 0.25 + }, { + name: 'Test prototype', + start: Date.UTC(2014, 10, 27), + end: Date.UTC(2014, 10, 29) + }, { + name: 'Develop', + start: Date.UTC(2014, 10, 20), + end: Date.UTC(2014, 10, 25), + completed: { + amount: 0.12, + fill: '#fa0' + } + }, { + name: 'Run acceptance tests', + start: Date.UTC(2014, 10, 23), + end: Date.UTC(2014, 10, 26) + }] + }] + }; + +} diff --git a/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.css b/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.css new file mode 100644 index 0000000..6a487ef --- /dev/null +++ b/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.css @@ -0,0 +1,11 @@ +h2 { + font-family: Arial, Helvetica, sans-serif; + font-size: 1.25rem; + margin: 0 0 1.5rem 0; +} + +.main { + width: 100%; + height: 650px; + display: block; +} diff --git a/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.html b/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.html new file mode 100644 index 0000000..d984ab5 --- /dev/null +++ b/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.html @@ -0,0 +1,4 @@ +
+

Demo #5: Lazy loading in Highcharts Stock

+ +
diff --git a/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.ts b/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.ts new file mode 100644 index 0000000..20cc21b --- /dev/null +++ b/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.ts @@ -0,0 +1,136 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import type Highcharts from 'highcharts'; +import HC_stock from 'highcharts/modules/stock'; +import { AppleDataService } from '../apple-data.service' +import { Observable } from 'rxjs'; +import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; + + +interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGroupingOptionsObject { + enabled: boolean +} + +@Component({ + selector: 'app-lazy-loading-chart', + templateUrl: './lazy-loading-chart.component.html', + styleUrls: ['./lazy-loading-chart.component.css'], + imports: [HighchartsChartComponent], + providers: [providePartialHighChart({ modules: [HC_stock] })], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class LazyLoadingChartComponent { + + constructor(private appleDataService: AppleDataService) { } + + chartRef: Highcharts.Chart; + + chartCallback: Highcharts.ChartCallbackFunction = (chart) => { + this.chartRef = chart; + }; + + fetchData(): Observable { + return this.appleDataService.fetchData(); + } + + fetchSqlData(min: number, max: number): Observable { + return this.appleDataService.fetchSqlData(min, max); + } + + chartLazyLoading: Highcharts.Options = { + chart: { + type: 'candlestick', + zooming: { + type: 'x' + }, + events: { + load: () => { + const chart = this.chartRef; + this.fetchData() + .subscribe((data: Array<[]>) => { + // Add a null value for the end date + const chartData = [...data, [Date.UTC(2011, 9, 14, 19, 59), null, null, null, null]]; + + chart.addSeries({ + type: 'candlestick', + data: chartData, + dataGrouping: { + enabled: false + } as ExtendedPlotCandlestickDataGroupingOptions + }, false); + + chart.update({ + navigator: { + series: { + data: chartData + } + } + }); + }); + } + } + }, + + navigator: { + adaptToUpdatedData: false + }, + + scrollbar: { + liveRedraw: false + }, + + title: { + text: 'AAPL history by the minute from 1998 to 2011' + }, + + subtitle: { + text: 'Displaying 1.7 million data points in Highcharts Stock by async server loading' + }, + + rangeSelector: { + buttons: [{ + type: 'hour', + count: 1, + text: '1h' + }, { + type: 'day', + count: 1, + text: '1d' + }, { + type: 'month', + count: 1, + text: '1m' + }, { + type: 'year', + count: 1, + text: '1y' + }, { + type: 'all', + text: 'All' + }], + inputEnabled: false, // it supports only days + selected: 4 // all + }, + + xAxis: { + events: { + afterSetExtremes: (event) => { + const chart = this.chartRef; + + chart.showLoading('Loading data from server...'); + + // Load new data depending on the selected min and max + this.fetchSqlData(event.min, event.max).subscribe((data: Array<[]>) => { + chart.series[0].setData(data); + chart.hideLoading(); + }) + } + }, + minRange: 3600 * 1000 // one hour + }, + + yAxis: { + floor: 0 + } + }; + +} diff --git a/apps/my-ssr-app/src/app/line-chart/line-chart.component.css b/apps/my-ssr-app/src/app/line-chart/line-chart.component.css new file mode 100644 index 0000000..f76518a --- /dev/null +++ b/apps/my-ssr-app/src/app/line-chart/line-chart.component.css @@ -0,0 +1,32 @@ +article { + display: flex; +} + +button{ + margin-right: 1rem; +} + +.buttons-wrapper { + margin-top: 1.5rem; +} + +h2 { + font-family: Arial, Helvetica, sans-serif; + font-size: 1.25rem; + margin: 0 0 1.5rem 0; +} + +highcharts-chart { + flex-grow: 3; +} + +section { + display: flex; + flex-direction: column; + width: 40% +} + +textarea { + border: 1px solid #E1E1E1; + border-radius: 0.5rem; +} \ No newline at end of file diff --git a/apps/my-ssr-app/src/app/line-chart/line-chart.component.html b/apps/my-ssr-app/src/app/line-chart/line-chart.component.html new file mode 100644 index 0000000..30982cc --- /dev/null +++ b/apps/my-ssr-app/src/app/line-chart/line-chart.component.html @@ -0,0 +1,19 @@ +

Demo #1: Highcharts with a basic editor

+
+
+ +
+ + + +
+
+ @if (showChart) { + + } +
diff --git a/apps/my-ssr-app/src/app/line-chart/line-chart.component.ts b/apps/my-ssr-app/src/app/line-chart/line-chart.component.ts new file mode 100644 index 0000000..c5a97fc --- /dev/null +++ b/apps/my-ssr-app/src/app/line-chart/line-chart.component.ts @@ -0,0 +1,66 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import HC_customEvents from 'highcharts-custom-events'; +import { FormsModule } from '@angular/forms'; +import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; + +@Component({ + selector: 'app-line-chart', + templateUrl: './line-chart.component.html', + styleUrls: ['./line-chart.component.css'], + imports: [FormsModule, HighchartsChartComponent], + providers: [providePartialHighChart({ modules: [HC_customEvents] })], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class LineChartComponent { + public updateFromInput = false; + public showChart = true; + public toggleButtonTitle = 'Destroy chart'; + + public optFromInputString = ` + { + "title": { "text": "Highcharts chart" }, + "series": [{ + "data": [11,2,3], + "zones": [{ + "value": 7.2, + "dashStyle": "dot", + "color": "red" + }] + }, { + "data": [5,6,7] + }] + } + `; + public optFromInput: Highcharts.Options = JSON.parse(this.optFromInputString); + private seriesTypes = { + line: 'column', + column: 'scatter', + scatter: 'spline', + spline: 'line', + }; + + // Demonstrate chart instance + public logChartInstance(chart: Highcharts.Chart) { + if (chart) { + console.log('Chart instance received:', chart); + } else { + console.log('Chart instance destroyed'); + } + } + + public updateInputChart() { + this.optFromInput = JSON.parse(this.optFromInputString); + } + + public toggleSeriesType(index = 0) { + this.optFromInput.series[index].type = this.seriesTypes[ + this.optFromInput.series[index].type || 'line'] as keyof typeof this.seriesTypes; + // nested change - must trigger update + this.updateFromInput = true; + } + + public toggleChart() { + this.showChart = !this.showChart; + this.toggleButtonTitle = this.showChart ? 'Destroy chart' : 'Recreate chart'; + } +} diff --git a/apps/my-ssr-app/src/app/map-chart/map-chart.component.css b/apps/my-ssr-app/src/app/map-chart/map-chart.component.css new file mode 100644 index 0000000..6a487ef --- /dev/null +++ b/apps/my-ssr-app/src/app/map-chart/map-chart.component.css @@ -0,0 +1,11 @@ +h2 { + font-family: Arial, Helvetica, sans-serif; + font-size: 1.25rem; + margin: 0 0 1.5rem 0; +} + +.main { + width: 100%; + height: 650px; + display: block; +} diff --git a/apps/my-ssr-app/src/app/map-chart/map-chart.component.html b/apps/my-ssr-app/src/app/map-chart/map-chart.component.html new file mode 100644 index 0000000..ca1f3f9 --- /dev/null +++ b/apps/my-ssr-app/src/app/map-chart/map-chart.component.html @@ -0,0 +1,4 @@ +
+

Demo #3: Highcharts Maps with the lat/lon points

+ +
diff --git a/apps/my-ssr-app/src/app/map-chart/map-chart.component.ts b/apps/my-ssr-app/src/app/map-chart/map-chart.component.ts new file mode 100644 index 0000000..3fb9a19 --- /dev/null +++ b/apps/my-ssr-app/src/app/map-chart/map-chart.component.ts @@ -0,0 +1,301 @@ +import {AsyncPipe, JsonPipe} from '@angular/common'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import type Highcharts from 'highcharts'; +import HC_map from 'highcharts/modules/map'; +import worldMap from '@highcharts/map-collection/custom/world.geo.json'; +import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; +// import proj4 from 'proj4'; + +// Legacy way of map loading - see file at the path for more info. +// require('../../js/worldmap')(Highcharts); + +@Component({ + selector: 'app-map-chart', + templateUrl: './map-chart.component.html', + styleUrls: ['./map-chart.component.css'], + imports: [HighchartsChartComponent, AsyncPipe, JsonPipe], + providers: [providePartialHighChart({ modules: [HC_map] })], + changeDetection: ChangeDetectionStrategy.OnPush, +}) + +export class MapChartComponent { + chartMap: Highcharts.Options = { + chart: { + map: worldMap as any, + // proj4: proj4 + }, + title: { + text: 'Highcharts Maps - basic demo' + }, + subtitle: { + text: `Selected Canadian cities were marked using their lat/lon coordinates.
+ Source map: World, Miller projection, medium resolution.` + }, + mapNavigation: { + enabled: true, + buttonOptions: { + alignTo: 'spacingBox' + } + }, + legend: { + enabled: true + }, + colorAxis: { + min: 0 + }, + series: [{ + name: 'Random data', + states: { + hover: { + color: '#BADA55' + } + }, + dataLabels: { + enabled: true, + format: '{point.name}' + }, + allAreas: false, + data: [ + ['fo', 0], + ['um', 1], + ['us', 2], + ['jp', 3], + ['sc', 4], + ['in', 5], + ['fr', 6], + ['fm', 7], + ['cn', 8], + ['pt', 9], + ['sw', 10], + ['sh', 11], + ['br', 12], + ['ki', 13], + ['ph', 14], + ['mx', 15], + ['es', 16], + ['bu', 17], + ['mv', 18], + ['sp', 19], + ['gb', 20], + ['gr', 21], + ['as', 22], + ['dk', 23], + ['gl', 24], + ['gu', 25], + ['mp', 26], + ['pr', 27], + ['vi', 28], + ['ca', 29], + ['st', 30], + ['cv', 31], + ['dm', 32], + ['nl', 33], + ['jm', 34], + ['ws', 35], + ['om', 36], + ['vc', 37], + ['tr', 38], + ['bd', 39], + ['lc', 40], + ['nr', 41], + ['no', 42], + ['kn', 43], + ['bh', 44], + ['to', 45], + ['fi', 46], + ['id', 47], + ['mu', 48], + ['se', 49], + ['tt', 50], + ['my', 51], + ['pa', 52], + ['pw', 53], + ['tv', 54], + ['mh', 55], + ['cl', 56], + ['th', 57], + ['gd', 58], + ['ee', 59], + ['ag', 60], + ['tw', 61], + ['bb', 62], + ['it', 63], + ['mt', 64], + ['vu', 65], + ['sg', 66], + ['cy', 67], + ['lk', 68], + ['km', 69], + ['fj', 70], + ['ru', 71], + ['va', 72], + ['sm', 73], + ['kz', 74], + ['az', 75], + ['tj', 76], + ['ls', 77], + ['uz', 78], + ['ma', 79], + ['co', 80], + ['tl', 81], + ['tz', 82], + ['ar', 83], + ['sa', 84], + ['pk', 85], + ['ye', 86], + ['ae', 87], + ['ke', 88], + ['pe', 89], + ['do', 90], + ['ht', 91], + ['pg', 92], + ['ao', 93], + ['kh', 94], + ['vn', 95], + ['mz', 96], + ['cr', 97], + ['bj', 98], + ['ng', 99], + ['ir', 100], + ['sv', 101], + ['sl', 102], + ['gw', 103], + ['hr', 104], + ['bz', 105], + ['za', 106], + ['cf', 107], + ['sd', 108], + ['cd', 109], + ['kw', 110], + ['de', 111], + ['be', 112], + ['ie', 113], + ['kp', 114], + ['kr', 115], + ['gy', 116], + ['hn', 117], + ['mm', 118], + ['ga', 119], + ['gq', 120], + ['ni', 121], + ['lv', 122], + ['ug', 123], + ['mw', 124], + ['am', 125], + ['sx', 126], + ['tm', 127], + ['zm', 128], + ['nc', 129], + ['mr', 130], + ['dz', 131], + ['lt', 132], + ['et', 133], + ['er', 134], + ['gh', 135], + ['si', 136], + ['gt', 137], + ['ba', 138], + ['jo', 139], + ['sy', 140], + ['mc', 141], + ['al', 142], + ['uy', 143], + ['cnm', 144], + ['mn', 145], + ['rw', 146], + ['so', 147], + ['bo', 148], + ['cm', 149], + ['cg', 150], + ['eh', 151], + ['rs', 152], + ['me', 153], + ['tg', 154], + ['la', 155], + ['af', 156], + ['ua', 157], + ['sk', 158], + ['jk', 159], + ['bg', 160], + ['qa', 161], + ['li', 162], + ['at', 163], + ['sz', 164], + ['hu', 165], + ['ro', 166], + ['ne', 167], + ['lu', 168], + ['ad', 169], + ['ci', 170], + ['lr', 171], + ['bn', 172], + ['iq', 173], + ['ge', 174], + ['gm', 175], + ['ch', 176], + ['td', 177], + ['kv', 178], + ['lb', 179], + ['dj', 180], + ['bi', 181], + ['sr', 182], + ['il', 183], + ['ml', 184], + ['sn', 185], + ['gn', 186], + ['zw', 187], + ['pl', 188], + ['mk', 189], + ['py', 190], + ['by', 191], + ['cz', 192], + ['bf', 193], + ['na', 194], + ['ly', 195], + ['tn', 196], + ['bt', 197], + ['md', 198], + ['ss', 199], + ['bw', 200], + ['bs', 201], + ['nz', 202], + ['cu', 203], + ['ec', 204], + ['au', 205], + ['ve', 206], + ['sb', 207], + ['mg', 208], + ['is', 209], + ['eg', 210], + ['kg', 211], + ['np', 212] + ] + } as Highcharts.SeriesMapOptions, + { + // Specify points using lat/lon + type: 'mappoint', + name: 'Canada cities', + marker: { + radius: 5, + fillColor: 'tomato' + }, + data: [ + { + name: 'Vancouver', + lat: 49.246292, + lon: -123.116226 + }, + { + name: 'Quebec City', + lat: 46.829853, + lon: -71.254028 + }, + { + name: 'Yellowknife', + lat: 62.4540, + lon: -114.3718 + } + ] + } as Highcharts.SeriesMappointOptions] + } +} diff --git a/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.css b/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.css new file mode 100644 index 0000000..76ded5a --- /dev/null +++ b/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.css @@ -0,0 +1,23 @@ +article { + display: flex; +} + +button { + margin-bottom: 1rem; +} + +h2 { + font-family: Arial, Helvetica, sans-serif; + font-size: 1.25rem; + margin: 0 0 1.5rem 0; +} + +highcharts-chart { + min-height: 350px; flex-grow: 3; +} + +section { + display: flex; + flex-direction: column; + width: 40%; +} \ No newline at end of file diff --git a/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.html b/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.html new file mode 100644 index 0000000..00761e6 --- /dev/null +++ b/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.html @@ -0,0 +1,26 @@ +

Demo #2: Highcharts Stock with simple updates

+
+
+

Chart title text:

+ +

Data sets:

+
+ @for (i of [0,1,2]; track i) { + + } +
+
+ +
diff --git a/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.ts b/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.ts new file mode 100644 index 0000000..5a36c45 --- /dev/null +++ b/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.ts @@ -0,0 +1,114 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import type Highcharts from 'highcharts'; +import HC_stock from 'highcharts/modules/stock'; +import HC_customEvents from 'highcharts-custom-events'; +import { FormsModule } from '@angular/forms'; +import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; + + +// Alternative way of a plugin loading: +// const HC_ce = require('highcharts-custom-events'); +// HC_ce(Highcharts); + +@Component({ + selector: 'app-stock-chart', + templateUrl: './stock-chart.component.html', + styleUrls: ['./stock-chart.component.css'], + imports: [FormsModule, HighchartsChartComponent], + providers: [providePartialHighChart({ modules: [HC_stock, HC_customEvents] })], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class StockChartComponent { + + // starting values + updateDemo2: boolean = false; + usedIndex: number = 0; + chartTitle: string = 'My chart'; // for init - change through titleChange + + // change in all places + titleChange(event: any) { + var v = event; + this.chartTitle = v; + + this.charts.forEach((el) => { + el.hcOptions.title.text = v; + }); + + // trigger ngOnChanges + this.updateDemo2 = true; + }; + + charts = [{ + hcOptions: { + title: { text: this.chartTitle }, + subtitle: { text: '1st data set' }, + plotOptions: { + series: { + pointStart: Date.now(), + pointInterval: 86400000 // 1 day + } + }, + series: [{ + type: 'line', + data: [11, 2, 3], + threshold: 5, + negativeColor: 'red', + events: { + dblclick: function () { + console.log('dblclick - thanks to the Custom Events plugin'); + } + } + }, { + type: 'candlestick', + + data: [ + [0, 15, -6, 7], + [7, 12, -1, 3], + [3, 10, -3, 3] + ] + }] + } as Highcharts.Options, + hcCallback: (chart: Highcharts.Chart) => { + console.log('some variables: ', chart, this.charts); + } + }, { + hcOptions: { + title: { text: this.chartTitle }, + subtitle: { text: '2nd data set' }, + series: [{ + type: 'column', + data: [4, 3, -12], + threshold: -10 + }, { + type: 'ohlc', + data: [ + [0, 15, -6, 7], + [7, 12, -1, 3], + [3, 10, -3, 3] + ] + }] + } as Highcharts.Options, + hcCallback: () => {} + }, { + hcOptions: { + title: { text: this.chartTitle }, + subtitle: { text: '3rd data set' }, + series: [{ + type: 'scatter', + data: [1, 2, 3, 4, 5] + }, { + type: 'areaspline', + data: [ + 5, + 11, + 3, + 6, + 0 + ] + }] + } as Highcharts.Options, + hcCallback: () => {} + }]; + + +} diff --git a/apps/my-ssr-app/src/index.html b/apps/my-ssr-app/src/index.html new file mode 100644 index 0000000..c4d0bb1 --- /dev/null +++ b/apps/my-ssr-app/src/index.html @@ -0,0 +1,13 @@ + + + + + My Ssr App + + + + + + + + diff --git a/apps/my-ssr-app/src/main.server.ts b/apps/my-ssr-app/src/main.server.ts new file mode 100644 index 0000000..4b9d4d1 --- /dev/null +++ b/apps/my-ssr-app/src/main.server.ts @@ -0,0 +1,7 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { config } from './app/app.config.server'; + +const bootstrap = () => bootstrapApplication(AppComponent, config); + +export default bootstrap; diff --git a/apps/my-ssr-app/src/main.ts b/apps/my-ssr-app/src/main.ts new file mode 100644 index 0000000..35b00f3 --- /dev/null +++ b/apps/my-ssr-app/src/main.ts @@ -0,0 +1,6 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, appConfig) + .catch((err) => console.error(err)); diff --git a/apps/my-ssr-app/src/server.ts b/apps/my-ssr-app/src/server.ts new file mode 100644 index 0000000..f6a88ad --- /dev/null +++ b/apps/my-ssr-app/src/server.ts @@ -0,0 +1,65 @@ +import { APP_BASE_HREF } from '@angular/common'; +import { CommonEngine, isMainModule } from '@angular/ssr/node'; +import express from 'express'; +import { dirname, join, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import bootstrap from './main.server'; + +const serverDistFolder = dirname(fileURLToPath(import.meta.url)); +const browserDistFolder = resolve(serverDistFolder, '../browser'); +const indexHtml = join(serverDistFolder, 'index.server.html'); + +const app = express(); +const commonEngine = new CommonEngine(); + +/** + * Example Express Rest API endpoints can be defined here. + * Uncomment and define endpoints as necessary. + * + * Example: + * ```ts + * app.get('/api/**', (req, res) => { + * // Handle API request + * }); + * ``` + */ + +/** + * Serve static files from /browser + */ +app.get( + '**', + express.static(browserDistFolder, { + maxAge: '1y', + index: 'index.html' + }), +); + +/** + * Handle all other requests by rendering the Angular application. + */ +app.get('**', (req, res, next) => { + const { protocol, originalUrl, baseUrl, headers } = req; + + commonEngine + .render({ + bootstrap, + documentFilePath: indexHtml, + url: `${protocol}://${headers.host}${originalUrl}`, + publicPath: browserDistFolder, + providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }], + }) + .then((html) => res.send(html)) + .catch((err) => next(err)); +}); + +/** + * Start the server if this module is the main entry point. + * The server listens on the port defined by the `PORT` environment variable, or defaults to 4000. + */ +if (isMainModule(import.meta.url)) { + const port = process.env['PORT'] || 4000; + app.listen(port, () => { + console.log(`Node Express server listening on http://localhost:${port}`); + }); +} diff --git a/apps/my-ssr-app/src/styles.css b/apps/my-ssr-app/src/styles.css new file mode 100644 index 0000000..90d4ee0 --- /dev/null +++ b/apps/my-ssr-app/src/styles.css @@ -0,0 +1 @@ +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/my-ssr-app/tsconfig.app.json b/apps/my-ssr-app/tsconfig.app.json new file mode 100644 index 0000000..6ce3d0a --- /dev/null +++ b/apps/my-ssr-app/tsconfig.app.json @@ -0,0 +1,19 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/app", + "types": [ + "node" + ] + }, + "files": [ + "src/main.ts", + "src/main.server.ts", + "src/server.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/apps/my-ssr-app/tsconfig.spec.json b/apps/my-ssr-app/tsconfig.spec.json new file mode 100644 index 0000000..0a43b83 --- /dev/null +++ b/apps/my-ssr-app/tsconfig.spec.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/package.json b/package.json index e2655d6..87430f7 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,10 @@ "scripts": { "ng": "ng", "serve": "ng serve my-app --open", + "serve:ssr": "node dist/my-ssr-app/server/server.mjs", "start": "node tasks/build.js && npm run serve", "build": "node tasks/build.js", + "build:ssr": "ng build my-ssr-app", "test": "ng test my-app", "lint": "ng lint highcharts-angular", "release": "cd ./highcharts-angular && standard-version && cd ../ && node tasks/build.js && node tasks/release.js", @@ -25,9 +27,12 @@ "@angular/forms": "19.0.3", "@angular/platform-browser": "19.0.3", "@angular/platform-browser-dynamic": "19.0.3", + "@angular/platform-server": "19.0.3", "@angular/router": "19.0.3", + "@angular/ssr": "^19.0.4", "@highcharts/map-collection": "^2.3.0", "core-js": "^3.19.2", + "express": "^4.18.2", "highcharts": "^11.2.0", "highcharts-custom-events": "^3.0.10", "jquery": "^3.6.0", @@ -42,9 +47,10 @@ "@angular/cli": "19.0.4", "@angular/compiler-cli": "19.0.3", "@types/estree": "^1.0.0", + "@types/express": "^4.17.17", "@types/jasmine": "^5.1.5", "@types/jasminewd2": "^2.0.13", - "@types/node": "^22.10.1", + "@types/node": "^18.18.0", "codelyzer": "^6.0.2", "jasmine-core": "^5.5.0", "jasmine-spec-reporter": "~7.0.0", From 9b8000f7ae5d546053d3c0ffbc9aee1241ce7fb7 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 16:15:37 +0100 Subject: [PATCH 67/94] allowedCommonJsDependencies --- angular.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/angular.json b/angular.json index 3620f8f..05198b6 100644 --- a/angular.json +++ b/angular.json @@ -25,14 +25,15 @@ } ], "styles": ["apps/my-app/src/styles.css"], - "scripts": [] + "scripts": [], + "allowedCommonJsDependencies": ["*"] }, "configurations": { "production": { "budgets": [ { "type": "initial", - "maximumWarning": "500kB", + "maximumWarning": "800kB", "maximumError": "1MB" }, { @@ -164,7 +165,8 @@ "prerender": true, "ssr": { "entry": "apps/my-ssr-app/src/server.ts" - } + }, + "allowedCommonJsDependencies": ["*"] }, "configurations": { "production": { From 8185c7670115332be435dd17b04c107b58c28cc0 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 16:32:24 +0100 Subject: [PATCH 68/94] handle map case differently --- angular.json | 10 + .../app/map-chart/map-chart.component.html | 2 +- .../src/app/map-chart/map-chart.component.ts | 565 +++++++++--------- apps/my-ssr-app/src/app/app.component.html | 2 +- apps/my-ssr-app/src/app/app.component.ts | 4 +- .../app/map-chart/map-chart.component.html | 2 +- .../src/app/map-chart/map-chart.component.ts | 560 ++++++++--------- 7 files changed, 584 insertions(+), 561 deletions(-) diff --git a/angular.json b/angular.json index 05198b6..e519c86 100644 --- a/angular.json +++ b/angular.json @@ -22,6 +22,11 @@ { "glob": "**/*", "input": "apps/my-app/public" + }, + { + "glob": "**/*", + "input": "./node_modules/@highcharts/map-collection/custom/", + "output": "/highcharts/" } ], "styles": ["apps/my-app/src/styles.css"], @@ -155,6 +160,11 @@ { "glob": "**/*", "input": "apps/my-ssr-app/public" + }, + { + "glob": "**/*", + "input": "./node_modules/@highcharts/map-collection/custom/", + "output": "/highcharts/" } ], "styles": [ diff --git a/apps/my-app/src/app/map-chart/map-chart.component.html b/apps/my-app/src/app/map-chart/map-chart.component.html index 08f862f..f403605 100644 --- a/apps/my-app/src/app/map-chart/map-chart.component.html +++ b/apps/my-app/src/app/map-chart/map-chart.component.html @@ -1,4 +1,4 @@

Demo #3: Highcharts Maps with the lat/lon points

- +
diff --git a/apps/my-app/src/app/map-chart/map-chart.component.ts b/apps/my-app/src/app/map-chart/map-chart.component.ts index ea58113..7380eeb 100644 --- a/apps/my-app/src/app/map-chart/map-chart.component.ts +++ b/apps/my-app/src/app/map-chart/map-chart.component.ts @@ -1,7 +1,9 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; +import {AsyncPipe} from '@angular/common'; +import {HttpClient} from '@angular/common/http'; +import {ChangeDetectionStrategy, Component, inject} from '@angular/core'; import type Highcharts from 'highcharts'; import HC_map from 'highcharts/modules/map'; -import worldMap from '@highcharts/map-collection/custom/world.geo.json'; +import { map } from 'rxjs'; import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; // import proj4 from 'proj4'; @@ -12,290 +14,295 @@ import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-an selector: 'app-map-chart', templateUrl: './map-chart.component.html', styleUrls: ['./map-chart.component.css'], - imports: [HighchartsChartComponent], + imports: [HighchartsChartComponent, AsyncPipe], providers: [providePartialHighChart({ modules: [HC_map] })], changeDetection: ChangeDetectionStrategy.OnPush, }) export class MapChartComponent { - chartMap: Highcharts.Options = { - chart: { - map: worldMap as any, - // proj4: proj4 - }, - title: { - text: 'Highcharts Maps - basic demo' - }, - subtitle: { - text: `Selected Canadian cities were marked using their lat/lon coordinates.
+ private http = inject(HttpClient); + chartMap$ = this.http.get('/highcharts/world.geo.json').pipe( + map((worldMap: any) => { + return { + chart: { + map: worldMap as any, + // proj4: proj4 + }, + title: { + text: 'Highcharts Maps - basic demo' + }, + subtitle: { + text: `Selected Canadian cities were marked using their lat/lon coordinates.
Source map: World, Miller projection, medium resolution.` - }, - mapNavigation: { - enabled: true, - buttonOptions: { - alignTo: 'spacingBox' - } - }, - legend: { - enabled: true - }, - colorAxis: { - min: 0 - }, - series: [{ - name: 'Random data', - states: { - hover: { - color: '#BADA55' - } - }, - dataLabels: { - enabled: true, - format: '{point.name}' - }, - allAreas: false, - data: [ - ['fo', 0], - ['um', 1], - ['us', 2], - ['jp', 3], - ['sc', 4], - ['in', 5], - ['fr', 6], - ['fm', 7], - ['cn', 8], - ['pt', 9], - ['sw', 10], - ['sh', 11], - ['br', 12], - ['ki', 13], - ['ph', 14], - ['mx', 15], - ['es', 16], - ['bu', 17], - ['mv', 18], - ['sp', 19], - ['gb', 20], - ['gr', 21], - ['as', 22], - ['dk', 23], - ['gl', 24], - ['gu', 25], - ['mp', 26], - ['pr', 27], - ['vi', 28], - ['ca', 29], - ['st', 30], - ['cv', 31], - ['dm', 32], - ['nl', 33], - ['jm', 34], - ['ws', 35], - ['om', 36], - ['vc', 37], - ['tr', 38], - ['bd', 39], - ['lc', 40], - ['nr', 41], - ['no', 42], - ['kn', 43], - ['bh', 44], - ['to', 45], - ['fi', 46], - ['id', 47], - ['mu', 48], - ['se', 49], - ['tt', 50], - ['my', 51], - ['pa', 52], - ['pw', 53], - ['tv', 54], - ['mh', 55], - ['cl', 56], - ['th', 57], - ['gd', 58], - ['ee', 59], - ['ag', 60], - ['tw', 61], - ['bb', 62], - ['it', 63], - ['mt', 64], - ['vu', 65], - ['sg', 66], - ['cy', 67], - ['lk', 68], - ['km', 69], - ['fj', 70], - ['ru', 71], - ['va', 72], - ['sm', 73], - ['kz', 74], - ['az', 75], - ['tj', 76], - ['ls', 77], - ['uz', 78], - ['ma', 79], - ['co', 80], - ['tl', 81], - ['tz', 82], - ['ar', 83], - ['sa', 84], - ['pk', 85], - ['ye', 86], - ['ae', 87], - ['ke', 88], - ['pe', 89], - ['do', 90], - ['ht', 91], - ['pg', 92], - ['ao', 93], - ['kh', 94], - ['vn', 95], - ['mz', 96], - ['cr', 97], - ['bj', 98], - ['ng', 99], - ['ir', 100], - ['sv', 101], - ['sl', 102], - ['gw', 103], - ['hr', 104], - ['bz', 105], - ['za', 106], - ['cf', 107], - ['sd', 108], - ['cd', 109], - ['kw', 110], - ['de', 111], - ['be', 112], - ['ie', 113], - ['kp', 114], - ['kr', 115], - ['gy', 116], - ['hn', 117], - ['mm', 118], - ['ga', 119], - ['gq', 120], - ['ni', 121], - ['lv', 122], - ['ug', 123], - ['mw', 124], - ['am', 125], - ['sx', 126], - ['tm', 127], - ['zm', 128], - ['nc', 129], - ['mr', 130], - ['dz', 131], - ['lt', 132], - ['et', 133], - ['er', 134], - ['gh', 135], - ['si', 136], - ['gt', 137], - ['ba', 138], - ['jo', 139], - ['sy', 140], - ['mc', 141], - ['al', 142], - ['uy', 143], - ['cnm', 144], - ['mn', 145], - ['rw', 146], - ['so', 147], - ['bo', 148], - ['cm', 149], - ['cg', 150], - ['eh', 151], - ['rs', 152], - ['me', 153], - ['tg', 154], - ['la', 155], - ['af', 156], - ['ua', 157], - ['sk', 158], - ['jk', 159], - ['bg', 160], - ['qa', 161], - ['li', 162], - ['at', 163], - ['sz', 164], - ['hu', 165], - ['ro', 166], - ['ne', 167], - ['lu', 168], - ['ad', 169], - ['ci', 170], - ['lr', 171], - ['bn', 172], - ['iq', 173], - ['ge', 174], - ['gm', 175], - ['ch', 176], - ['td', 177], - ['kv', 178], - ['lb', 179], - ['dj', 180], - ['bi', 181], - ['sr', 182], - ['il', 183], - ['ml', 184], - ['sn', 185], - ['gn', 186], - ['zw', 187], - ['pl', 188], - ['mk', 189], - ['py', 190], - ['by', 191], - ['cz', 192], - ['bf', 193], - ['na', 194], - ['ly', 195], - ['tn', 196], - ['bt', 197], - ['md', 198], - ['ss', 199], - ['bw', 200], - ['bs', 201], - ['nz', 202], - ['cu', 203], - ['ec', 204], - ['au', 205], - ['ve', 206], - ['sb', 207], - ['mg', 208], - ['is', 209], - ['eg', 210], - ['kg', 211], - ['np', 212] - ] - } as Highcharts.SeriesMapOptions, - { - // Specify points using lat/lon - type: 'mappoint', - name: 'Canada cities', - marker: { - radius: 5, - fillColor: 'tomato' - }, - data: [ - { - name: 'Vancouver', - lat: 49.246292, - lon: -123.116226 }, - { - name: 'Quebec City', - lat: 46.829853, - lon: -71.254028 + mapNavigation: { + enabled: true, + buttonOptions: { + alignTo: 'spacingBox' + } }, - { - name: 'Yellowknife', - lat: 62.4540, - lon: -114.3718 - } - ] - } as Highcharts.SeriesMappointOptions] - }; + legend: { + enabled: true + }, + colorAxis: { + min: 0 + }, + series: [{ + name: 'Random data', + states: { + hover: { + color: '#BADA55' + } + }, + dataLabels: { + enabled: true, + format: '{point.name}' + }, + allAreas: false, + data: [ + ['fo', 0], + ['um', 1], + ['us', 2], + ['jp', 3], + ['sc', 4], + ['in', 5], + ['fr', 6], + ['fm', 7], + ['cn', 8], + ['pt', 9], + ['sw', 10], + ['sh', 11], + ['br', 12], + ['ki', 13], + ['ph', 14], + ['mx', 15], + ['es', 16], + ['bu', 17], + ['mv', 18], + ['sp', 19], + ['gb', 20], + ['gr', 21], + ['as', 22], + ['dk', 23], + ['gl', 24], + ['gu', 25], + ['mp', 26], + ['pr', 27], + ['vi', 28], + ['ca', 29], + ['st', 30], + ['cv', 31], + ['dm', 32], + ['nl', 33], + ['jm', 34], + ['ws', 35], + ['om', 36], + ['vc', 37], + ['tr', 38], + ['bd', 39], + ['lc', 40], + ['nr', 41], + ['no', 42], + ['kn', 43], + ['bh', 44], + ['to', 45], + ['fi', 46], + ['id', 47], + ['mu', 48], + ['se', 49], + ['tt', 50], + ['my', 51], + ['pa', 52], + ['pw', 53], + ['tv', 54], + ['mh', 55], + ['cl', 56], + ['th', 57], + ['gd', 58], + ['ee', 59], + ['ag', 60], + ['tw', 61], + ['bb', 62], + ['it', 63], + ['mt', 64], + ['vu', 65], + ['sg', 66], + ['cy', 67], + ['lk', 68], + ['km', 69], + ['fj', 70], + ['ru', 71], + ['va', 72], + ['sm', 73], + ['kz', 74], + ['az', 75], + ['tj', 76], + ['ls', 77], + ['uz', 78], + ['ma', 79], + ['co', 80], + ['tl', 81], + ['tz', 82], + ['ar', 83], + ['sa', 84], + ['pk', 85], + ['ye', 86], + ['ae', 87], + ['ke', 88], + ['pe', 89], + ['do', 90], + ['ht', 91], + ['pg', 92], + ['ao', 93], + ['kh', 94], + ['vn', 95], + ['mz', 96], + ['cr', 97], + ['bj', 98], + ['ng', 99], + ['ir', 100], + ['sv', 101], + ['sl', 102], + ['gw', 103], + ['hr', 104], + ['bz', 105], + ['za', 106], + ['cf', 107], + ['sd', 108], + ['cd', 109], + ['kw', 110], + ['de', 111], + ['be', 112], + ['ie', 113], + ['kp', 114], + ['kr', 115], + ['gy', 116], + ['hn', 117], + ['mm', 118], + ['ga', 119], + ['gq', 120], + ['ni', 121], + ['lv', 122], + ['ug', 123], + ['mw', 124], + ['am', 125], + ['sx', 126], + ['tm', 127], + ['zm', 128], + ['nc', 129], + ['mr', 130], + ['dz', 131], + ['lt', 132], + ['et', 133], + ['er', 134], + ['gh', 135], + ['si', 136], + ['gt', 137], + ['ba', 138], + ['jo', 139], + ['sy', 140], + ['mc', 141], + ['al', 142], + ['uy', 143], + ['cnm', 144], + ['mn', 145], + ['rw', 146], + ['so', 147], + ['bo', 148], + ['cm', 149], + ['cg', 150], + ['eh', 151], + ['rs', 152], + ['me', 153], + ['tg', 154], + ['la', 155], + ['af', 156], + ['ua', 157], + ['sk', 158], + ['jk', 159], + ['bg', 160], + ['qa', 161], + ['li', 162], + ['at', 163], + ['sz', 164], + ['hu', 165], + ['ro', 166], + ['ne', 167], + ['lu', 168], + ['ad', 169], + ['ci', 170], + ['lr', 171], + ['bn', 172], + ['iq', 173], + ['ge', 174], + ['gm', 175], + ['ch', 176], + ['td', 177], + ['kv', 178], + ['lb', 179], + ['dj', 180], + ['bi', 181], + ['sr', 182], + ['il', 183], + ['ml', 184], + ['sn', 185], + ['gn', 186], + ['zw', 187], + ['pl', 188], + ['mk', 189], + ['py', 190], + ['by', 191], + ['cz', 192], + ['bf', 193], + ['na', 194], + ['ly', 195], + ['tn', 196], + ['bt', 197], + ['md', 198], + ['ss', 199], + ['bw', 200], + ['bs', 201], + ['nz', 202], + ['cu', 203], + ['ec', 204], + ['au', 205], + ['ve', 206], + ['sb', 207], + ['mg', 208], + ['is', 209], + ['eg', 210], + ['kg', 211], + ['np', 212] + ] + } as Highcharts.SeriesMapOptions, + { + // Specify points using lat/lon + type: 'mappoint', + name: 'Canada cities', + marker: { + radius: 5, + fillColor: 'tomato' + }, + data: [ + { + name: 'Vancouver', + lat: 49.246292, + lon: -123.116226 + }, + { + name: 'Quebec City', + lat: 46.829853, + lon: -71.254028 + }, + { + name: 'Yellowknife', + lat: 62.4540, + lon: -114.3718 + } + ] + } as Highcharts.SeriesMappointOptions] + } + }) + ) } diff --git a/apps/my-ssr-app/src/app/app.component.html b/apps/my-ssr-app/src/app/app.component.html index bbfc368..c8acc02 100644 --- a/apps/my-ssr-app/src/app/app.component.html +++ b/apps/my-ssr-app/src/app/app.component.html @@ -1,7 +1,7 @@
- +
diff --git a/apps/my-ssr-app/src/app/app.component.ts b/apps/my-ssr-app/src/app/app.component.ts index b42cd04..15e0a51 100644 --- a/apps/my-ssr-app/src/app/app.component.ts +++ b/apps/my-ssr-app/src/app/app.component.ts @@ -2,12 +2,12 @@ import { Component } from '@angular/core'; import {GanttChartComponent} from './gantt-chart/gantt-chart.component'; import {LazyLoadingChartComponent} from './lazy-loading-chart/lazy-loading-chart.component'; import {LineChartComponent} from './line-chart/line-chart.component'; -// import {MapChartComponent} from './map-chart/map-chart.component'; +import {MapChartComponent} from './map-chart/map-chart.component'; import {StockChartComponent} from './stock-chart/stock-chart.component'; @Component({ selector: 'app-root', - imports: [GanttChartComponent, LineChartComponent, StockChartComponent, LazyLoadingChartComponent], + imports: [GanttChartComponent, LineChartComponent, StockChartComponent, LazyLoadingChartComponent, MapChartComponent], templateUrl: './app.component.html', styleUrl: './app.component.css' }) diff --git a/apps/my-ssr-app/src/app/map-chart/map-chart.component.html b/apps/my-ssr-app/src/app/map-chart/map-chart.component.html index ca1f3f9..c212596 100644 --- a/apps/my-ssr-app/src/app/map-chart/map-chart.component.html +++ b/apps/my-ssr-app/src/app/map-chart/map-chart.component.html @@ -1,4 +1,4 @@

Demo #3: Highcharts Maps with the lat/lon points

- +
diff --git a/apps/my-ssr-app/src/app/map-chart/map-chart.component.ts b/apps/my-ssr-app/src/app/map-chart/map-chart.component.ts index 3fb9a19..8b3c5ae 100644 --- a/apps/my-ssr-app/src/app/map-chart/map-chart.component.ts +++ b/apps/my-ssr-app/src/app/map-chart/map-chart.component.ts @@ -1,8 +1,9 @@ import {AsyncPipe, JsonPipe} from '@angular/common'; -import { ChangeDetectionStrategy, Component } from '@angular/core'; +import {HttpClient} from '@angular/common/http'; +import {ChangeDetectionStrategy, Component, inject} from '@angular/core'; import type Highcharts from 'highcharts'; import HC_map from 'highcharts/modules/map'; -import worldMap from '@highcharts/map-collection/custom/world.geo.json'; +import { map } from 'rxjs'; import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; // import proj4 from 'proj4'; @@ -13,289 +14,294 @@ import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-an selector: 'app-map-chart', templateUrl: './map-chart.component.html', styleUrls: ['./map-chart.component.css'], - imports: [HighchartsChartComponent, AsyncPipe, JsonPipe], + imports: [HighchartsChartComponent, AsyncPipe], providers: [providePartialHighChart({ modules: [HC_map] })], changeDetection: ChangeDetectionStrategy.OnPush, }) export class MapChartComponent { - chartMap: Highcharts.Options = { - chart: { - map: worldMap as any, - // proj4: proj4 - }, - title: { - text: 'Highcharts Maps - basic demo' - }, - subtitle: { - text: `Selected Canadian cities were marked using their lat/lon coordinates.
+ private http = inject(HttpClient); + chartMap$ = this.http.get('/highcharts/world.geo.json').pipe( + map((worldMap: any) => { + return { + chart: { + map: worldMap as any, + // proj4: proj4 + }, + title: { + text: 'Highcharts Maps - basic demo' + }, + subtitle: { + text: `Selected Canadian cities were marked using their lat/lon coordinates.
Source map: World, Miller projection, medium resolution.` - }, - mapNavigation: { - enabled: true, - buttonOptions: { - alignTo: 'spacingBox' - } - }, - legend: { - enabled: true - }, - colorAxis: { - min: 0 - }, - series: [{ - name: 'Random data', - states: { - hover: { - color: '#BADA55' - } - }, - dataLabels: { - enabled: true, - format: '{point.name}' - }, - allAreas: false, - data: [ - ['fo', 0], - ['um', 1], - ['us', 2], - ['jp', 3], - ['sc', 4], - ['in', 5], - ['fr', 6], - ['fm', 7], - ['cn', 8], - ['pt', 9], - ['sw', 10], - ['sh', 11], - ['br', 12], - ['ki', 13], - ['ph', 14], - ['mx', 15], - ['es', 16], - ['bu', 17], - ['mv', 18], - ['sp', 19], - ['gb', 20], - ['gr', 21], - ['as', 22], - ['dk', 23], - ['gl', 24], - ['gu', 25], - ['mp', 26], - ['pr', 27], - ['vi', 28], - ['ca', 29], - ['st', 30], - ['cv', 31], - ['dm', 32], - ['nl', 33], - ['jm', 34], - ['ws', 35], - ['om', 36], - ['vc', 37], - ['tr', 38], - ['bd', 39], - ['lc', 40], - ['nr', 41], - ['no', 42], - ['kn', 43], - ['bh', 44], - ['to', 45], - ['fi', 46], - ['id', 47], - ['mu', 48], - ['se', 49], - ['tt', 50], - ['my', 51], - ['pa', 52], - ['pw', 53], - ['tv', 54], - ['mh', 55], - ['cl', 56], - ['th', 57], - ['gd', 58], - ['ee', 59], - ['ag', 60], - ['tw', 61], - ['bb', 62], - ['it', 63], - ['mt', 64], - ['vu', 65], - ['sg', 66], - ['cy', 67], - ['lk', 68], - ['km', 69], - ['fj', 70], - ['ru', 71], - ['va', 72], - ['sm', 73], - ['kz', 74], - ['az', 75], - ['tj', 76], - ['ls', 77], - ['uz', 78], - ['ma', 79], - ['co', 80], - ['tl', 81], - ['tz', 82], - ['ar', 83], - ['sa', 84], - ['pk', 85], - ['ye', 86], - ['ae', 87], - ['ke', 88], - ['pe', 89], - ['do', 90], - ['ht', 91], - ['pg', 92], - ['ao', 93], - ['kh', 94], - ['vn', 95], - ['mz', 96], - ['cr', 97], - ['bj', 98], - ['ng', 99], - ['ir', 100], - ['sv', 101], - ['sl', 102], - ['gw', 103], - ['hr', 104], - ['bz', 105], - ['za', 106], - ['cf', 107], - ['sd', 108], - ['cd', 109], - ['kw', 110], - ['de', 111], - ['be', 112], - ['ie', 113], - ['kp', 114], - ['kr', 115], - ['gy', 116], - ['hn', 117], - ['mm', 118], - ['ga', 119], - ['gq', 120], - ['ni', 121], - ['lv', 122], - ['ug', 123], - ['mw', 124], - ['am', 125], - ['sx', 126], - ['tm', 127], - ['zm', 128], - ['nc', 129], - ['mr', 130], - ['dz', 131], - ['lt', 132], - ['et', 133], - ['er', 134], - ['gh', 135], - ['si', 136], - ['gt', 137], - ['ba', 138], - ['jo', 139], - ['sy', 140], - ['mc', 141], - ['al', 142], - ['uy', 143], - ['cnm', 144], - ['mn', 145], - ['rw', 146], - ['so', 147], - ['bo', 148], - ['cm', 149], - ['cg', 150], - ['eh', 151], - ['rs', 152], - ['me', 153], - ['tg', 154], - ['la', 155], - ['af', 156], - ['ua', 157], - ['sk', 158], - ['jk', 159], - ['bg', 160], - ['qa', 161], - ['li', 162], - ['at', 163], - ['sz', 164], - ['hu', 165], - ['ro', 166], - ['ne', 167], - ['lu', 168], - ['ad', 169], - ['ci', 170], - ['lr', 171], - ['bn', 172], - ['iq', 173], - ['ge', 174], - ['gm', 175], - ['ch', 176], - ['td', 177], - ['kv', 178], - ['lb', 179], - ['dj', 180], - ['bi', 181], - ['sr', 182], - ['il', 183], - ['ml', 184], - ['sn', 185], - ['gn', 186], - ['zw', 187], - ['pl', 188], - ['mk', 189], - ['py', 190], - ['by', 191], - ['cz', 192], - ['bf', 193], - ['na', 194], - ['ly', 195], - ['tn', 196], - ['bt', 197], - ['md', 198], - ['ss', 199], - ['bw', 200], - ['bs', 201], - ['nz', 202], - ['cu', 203], - ['ec', 204], - ['au', 205], - ['ve', 206], - ['sb', 207], - ['mg', 208], - ['is', 209], - ['eg', 210], - ['kg', 211], - ['np', 212] - ] - } as Highcharts.SeriesMapOptions, - { - // Specify points using lat/lon - type: 'mappoint', - name: 'Canada cities', - marker: { - radius: 5, - fillColor: 'tomato' }, - data: [ - { - name: 'Vancouver', - lat: 49.246292, - lon: -123.116226 + mapNavigation: { + enabled: true, + buttonOptions: { + alignTo: 'spacingBox' + } + }, + legend: { + enabled: true + }, + colorAxis: { + min: 0 + }, + series: [{ + name: 'Random data', + states: { + hover: { + color: '#BADA55' + } }, - { - name: 'Quebec City', - lat: 46.829853, - lon: -71.254028 + dataLabels: { + enabled: true, + format: '{point.name}' }, + allAreas: false, + data: [ + ['fo', 0], + ['um', 1], + ['us', 2], + ['jp', 3], + ['sc', 4], + ['in', 5], + ['fr', 6], + ['fm', 7], + ['cn', 8], + ['pt', 9], + ['sw', 10], + ['sh', 11], + ['br', 12], + ['ki', 13], + ['ph', 14], + ['mx', 15], + ['es', 16], + ['bu', 17], + ['mv', 18], + ['sp', 19], + ['gb', 20], + ['gr', 21], + ['as', 22], + ['dk', 23], + ['gl', 24], + ['gu', 25], + ['mp', 26], + ['pr', 27], + ['vi', 28], + ['ca', 29], + ['st', 30], + ['cv', 31], + ['dm', 32], + ['nl', 33], + ['jm', 34], + ['ws', 35], + ['om', 36], + ['vc', 37], + ['tr', 38], + ['bd', 39], + ['lc', 40], + ['nr', 41], + ['no', 42], + ['kn', 43], + ['bh', 44], + ['to', 45], + ['fi', 46], + ['id', 47], + ['mu', 48], + ['se', 49], + ['tt', 50], + ['my', 51], + ['pa', 52], + ['pw', 53], + ['tv', 54], + ['mh', 55], + ['cl', 56], + ['th', 57], + ['gd', 58], + ['ee', 59], + ['ag', 60], + ['tw', 61], + ['bb', 62], + ['it', 63], + ['mt', 64], + ['vu', 65], + ['sg', 66], + ['cy', 67], + ['lk', 68], + ['km', 69], + ['fj', 70], + ['ru', 71], + ['va', 72], + ['sm', 73], + ['kz', 74], + ['az', 75], + ['tj', 76], + ['ls', 77], + ['uz', 78], + ['ma', 79], + ['co', 80], + ['tl', 81], + ['tz', 82], + ['ar', 83], + ['sa', 84], + ['pk', 85], + ['ye', 86], + ['ae', 87], + ['ke', 88], + ['pe', 89], + ['do', 90], + ['ht', 91], + ['pg', 92], + ['ao', 93], + ['kh', 94], + ['vn', 95], + ['mz', 96], + ['cr', 97], + ['bj', 98], + ['ng', 99], + ['ir', 100], + ['sv', 101], + ['sl', 102], + ['gw', 103], + ['hr', 104], + ['bz', 105], + ['za', 106], + ['cf', 107], + ['sd', 108], + ['cd', 109], + ['kw', 110], + ['de', 111], + ['be', 112], + ['ie', 113], + ['kp', 114], + ['kr', 115], + ['gy', 116], + ['hn', 117], + ['mm', 118], + ['ga', 119], + ['gq', 120], + ['ni', 121], + ['lv', 122], + ['ug', 123], + ['mw', 124], + ['am', 125], + ['sx', 126], + ['tm', 127], + ['zm', 128], + ['nc', 129], + ['mr', 130], + ['dz', 131], + ['lt', 132], + ['et', 133], + ['er', 134], + ['gh', 135], + ['si', 136], + ['gt', 137], + ['ba', 138], + ['jo', 139], + ['sy', 140], + ['mc', 141], + ['al', 142], + ['uy', 143], + ['cnm', 144], + ['mn', 145], + ['rw', 146], + ['so', 147], + ['bo', 148], + ['cm', 149], + ['cg', 150], + ['eh', 151], + ['rs', 152], + ['me', 153], + ['tg', 154], + ['la', 155], + ['af', 156], + ['ua', 157], + ['sk', 158], + ['jk', 159], + ['bg', 160], + ['qa', 161], + ['li', 162], + ['at', 163], + ['sz', 164], + ['hu', 165], + ['ro', 166], + ['ne', 167], + ['lu', 168], + ['ad', 169], + ['ci', 170], + ['lr', 171], + ['bn', 172], + ['iq', 173], + ['ge', 174], + ['gm', 175], + ['ch', 176], + ['td', 177], + ['kv', 178], + ['lb', 179], + ['dj', 180], + ['bi', 181], + ['sr', 182], + ['il', 183], + ['ml', 184], + ['sn', 185], + ['gn', 186], + ['zw', 187], + ['pl', 188], + ['mk', 189], + ['py', 190], + ['by', 191], + ['cz', 192], + ['bf', 193], + ['na', 194], + ['ly', 195], + ['tn', 196], + ['bt', 197], + ['md', 198], + ['ss', 199], + ['bw', 200], + ['bs', 201], + ['nz', 202], + ['cu', 203], + ['ec', 204], + ['au', 205], + ['ve', 206], + ['sb', 207], + ['mg', 208], + ['is', 209], + ['eg', 210], + ['kg', 211], + ['np', 212] + ] + } as Highcharts.SeriesMapOptions, { - name: 'Yellowknife', - lat: 62.4540, - lon: -114.3718 - } - ] - } as Highcharts.SeriesMappointOptions] - } + // Specify points using lat/lon + type: 'mappoint', + name: 'Canada cities', + marker: { + radius: 5, + fillColor: 'tomato' + }, + data: [ + { + name: 'Vancouver', + lat: 49.246292, + lon: -123.116226 + }, + { + name: 'Quebec City', + lat: 46.829853, + lon: -71.254028 + }, + { + name: 'Yellowknife', + lat: 62.4540, + lon: -114.3718 + } + ] + } as Highcharts.SeriesMappointOptions] + } + }) + ) } From 158de68521d7599af85d4ef7d9fd95426f7c5f59 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 16:32:55 +0100 Subject: [PATCH 69/94] correct title --- apps/my-ssr-app/src/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/my-ssr-app/src/index.html b/apps/my-ssr-app/src/index.html index c4d0bb1..be5a150 100644 --- a/apps/my-ssr-app/src/index.html +++ b/apps/my-ssr-app/src/index.html @@ -2,7 +2,7 @@ - My Ssr App + highcharts-angular-ssr From 90923065d05c94c1d0c4712e94d77ba14f1c502e Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 16:34:51 +0100 Subject: [PATCH 70/94] increase budget --- angular.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/angular.json b/angular.json index e519c86..b8bf1a7 100644 --- a/angular.json +++ b/angular.json @@ -183,7 +183,7 @@ "budgets": [ { "type": "initial", - "maximumWarning": "500kB", + "maximumWarning": "800kB", "maximumError": "1MB" }, { From 782422446593326b881c4a27e73d3b1560645232 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 23:23:20 +0100 Subject: [PATCH 71/94] we can reuse app for both ssr and no-ssr --- angular.json | 46 +-- apps/my-app/tsconfig.app.json | 15 - apps/my-ssr-app/public/favicon.ico | Bin 15086 -> 0 bytes apps/my-ssr-app/src/app/app.component.css | 22 -- apps/my-ssr-app/src/app/app.component.html | 7 - apps/my-ssr-app/src/app/app.component.ts | 16 - apps/my-ssr-app/src/app/app.config.ts | 29 -- apps/my-ssr-app/src/app/apple-data.service.ts | 28 -- .../app/gantt-chart/gantt-chart.component.css | 11 - .../gantt-chart/gantt-chart.component.html | 4 - .../app/gantt-chart/gantt-chart.component.ts | 52 --- .../lazy-loading-chart.component.css | 11 - .../lazy-loading-chart.component.html | 4 - .../lazy-loading-chart.component.ts | 136 -------- .../app/line-chart/line-chart.component.css | 32 -- .../app/line-chart/line-chart.component.html | 19 -- .../app/line-chart/line-chart.component.ts | 66 ---- .../src/app/map-chart/map-chart.component.css | 11 - .../app/map-chart/map-chart.component.html | 4 - .../src/app/map-chart/map-chart.component.ts | 307 ------------------ .../app/stock-chart/stock-chart.component.css | 23 -- .../stock-chart/stock-chart.component.html | 26 -- .../app/stock-chart/stock-chart.component.ts | 114 ------- apps/my-ssr-app/src/index.html | 13 - apps/my-ssr-app/src/main.ts | 6 - apps/my-ssr-app/src/styles.css | 1 - apps/my-ssr-app/tsconfig.spec.json | 15 - .../my-app/src => src}/app/app.component.css | 0 .../my-app/src => src}/app/app.component.html | 0 {apps/my-app/src => src}/app/app.component.ts | 0 .../src => src}/app/app.config.server.ts | 0 {apps/my-app/src => src}/app/app.config.ts | 5 +- .../src => src}/app/apple-data.service.ts | 0 .../app/gantt-chart/gantt-chart.component.css | 0 .../gantt-chart/gantt-chart.component.html | 0 .../app/gantt-chart/gantt-chart.component.ts | 0 .../lazy-loading-chart.component.css | 0 .../lazy-loading-chart.component.html | 0 .../lazy-loading-chart.component.ts | 0 .../app/line-chart/line-chart.component.css | 0 .../app/line-chart/line-chart.component.html | 0 .../app/line-chart/line-chart.component.ts | 0 .../app/map-chart/map-chart.component.css | 0 .../app/map-chart/map-chart.component.html | 0 .../app/map-chart/map-chart.component.ts | 0 .../app/stock-chart/stock-chart.component.css | 0 .../stock-chart/stock-chart.component.html | 0 .../app/stock-chart/stock-chart.component.ts | 0 .../tests/line-test/line-test.component.css | 0 .../tests/line-test/line-test.component.html | 0 .../line-test/line-test.component.spec.ts | 2 +- .../tests/line-test/line-test.component.ts | 2 +- .../my-app/public => src/assets}/favicon.ico | Bin {apps/my-app/src => src}/global.d.ts | 0 {apps/my-app/src => src}/index.html | 0 {apps/my-ssr-app/src => src}/main.server.ts | 0 {apps/my-app/src => src}/main.ts | 0 {apps/my-ssr-app/src => src}/server.ts | 0 {apps/my-app/src => src}/styles.css | 0 {apps/my-app/src => src}/test.ts | 0 {apps/my-app/src => src}/typings.d.ts | 0 .../tsconfig.app.json => tsconfig.app.json | 6 +- .../tsconfig.spec.json => tsconfig.spec.json | 8 +- 63 files changed, 35 insertions(+), 1006 deletions(-) delete mode 100644 apps/my-app/tsconfig.app.json delete mode 100644 apps/my-ssr-app/public/favicon.ico delete mode 100644 apps/my-ssr-app/src/app/app.component.css delete mode 100644 apps/my-ssr-app/src/app/app.component.html delete mode 100644 apps/my-ssr-app/src/app/app.component.ts delete mode 100644 apps/my-ssr-app/src/app/app.config.ts delete mode 100644 apps/my-ssr-app/src/app/apple-data.service.ts delete mode 100644 apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.css delete mode 100644 apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.html delete mode 100644 apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.ts delete mode 100644 apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.css delete mode 100644 apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.html delete mode 100644 apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.ts delete mode 100644 apps/my-ssr-app/src/app/line-chart/line-chart.component.css delete mode 100644 apps/my-ssr-app/src/app/line-chart/line-chart.component.html delete mode 100644 apps/my-ssr-app/src/app/line-chart/line-chart.component.ts delete mode 100644 apps/my-ssr-app/src/app/map-chart/map-chart.component.css delete mode 100644 apps/my-ssr-app/src/app/map-chart/map-chart.component.html delete mode 100644 apps/my-ssr-app/src/app/map-chart/map-chart.component.ts delete mode 100644 apps/my-ssr-app/src/app/stock-chart/stock-chart.component.css delete mode 100644 apps/my-ssr-app/src/app/stock-chart/stock-chart.component.html delete mode 100644 apps/my-ssr-app/src/app/stock-chart/stock-chart.component.ts delete mode 100644 apps/my-ssr-app/src/index.html delete mode 100644 apps/my-ssr-app/src/main.ts delete mode 100644 apps/my-ssr-app/src/styles.css delete mode 100644 apps/my-ssr-app/tsconfig.spec.json rename {apps/my-app/src => src}/app/app.component.css (100%) rename {apps/my-app/src => src}/app/app.component.html (100%) rename {apps/my-app/src => src}/app/app.component.ts (100%) rename {apps/my-ssr-app/src => src}/app/app.config.server.ts (100%) rename {apps/my-app/src => src}/app/app.config.ts (79%) rename {apps/my-app/src => src}/app/apple-data.service.ts (100%) rename {apps/my-app/src => src}/app/gantt-chart/gantt-chart.component.css (100%) rename {apps/my-app/src => src}/app/gantt-chart/gantt-chart.component.html (100%) rename {apps/my-app/src => src}/app/gantt-chart/gantt-chart.component.ts (100%) rename {apps/my-app/src => src}/app/lazy-loading-chart/lazy-loading-chart.component.css (100%) rename {apps/my-app/src => src}/app/lazy-loading-chart/lazy-loading-chart.component.html (100%) rename {apps/my-app/src => src}/app/lazy-loading-chart/lazy-loading-chart.component.ts (100%) rename {apps/my-app/src => src}/app/line-chart/line-chart.component.css (100%) rename {apps/my-app/src => src}/app/line-chart/line-chart.component.html (100%) rename {apps/my-app/src => src}/app/line-chart/line-chart.component.ts (100%) rename {apps/my-app/src => src}/app/map-chart/map-chart.component.css (100%) rename {apps/my-app/src => src}/app/map-chart/map-chart.component.html (100%) rename {apps/my-app/src => src}/app/map-chart/map-chart.component.ts (100%) rename {apps/my-app/src => src}/app/stock-chart/stock-chart.component.css (100%) rename {apps/my-app/src => src}/app/stock-chart/stock-chart.component.html (100%) rename {apps/my-app/src => src}/app/stock-chart/stock-chart.component.ts (100%) rename {apps/my-app/src => src}/app/tests/line-test/line-test.component.css (100%) rename {apps/my-app/src => src}/app/tests/line-test/line-test.component.html (100%) rename {apps/my-app/src => src}/app/tests/line-test/line-test.component.spec.ts (96%) rename {apps/my-app/src => src}/app/tests/line-test/line-test.component.ts (89%) rename {apps/my-app/public => src/assets}/favicon.ico (100%) rename {apps/my-app/src => src}/global.d.ts (100%) rename {apps/my-app/src => src}/index.html (100%) rename {apps/my-ssr-app/src => src}/main.server.ts (100%) rename {apps/my-app/src => src}/main.ts (100%) rename {apps/my-ssr-app/src => src}/server.ts (100%) rename {apps/my-app/src => src}/styles.css (100%) rename {apps/my-app/src => src}/test.ts (100%) rename {apps/my-app/src => src}/typings.d.ts (100%) rename apps/my-ssr-app/tsconfig.app.json => tsconfig.app.json (85%) rename apps/my-app/tsconfig.spec.json => tsconfig.spec.json (84%) diff --git a/angular.json b/angular.json index b8bf1a7..e2d87c2 100644 --- a/angular.json +++ b/angular.json @@ -4,8 +4,8 @@ "newProjectRoot": "apps", "projects": { "my-app": { - "root": "apps/my-app", - "sourceRoot": "apps/my-app/src", + "root": "", + "sourceRoot": "src", "projectType": "application", "schematics": {}, "prefix": "app", @@ -14,14 +14,14 @@ "builder": "@angular/build:application", "options": { "outputPath": "dist/my-app", - "index": "apps/my-app/src/index.html", - "browser": "apps/my-app/src/main.ts", + "index": "src/index.html", + "browser": "src/main.ts", "polyfills": ["zone.js"], - "tsConfig": "apps/my-app/tsconfig.app.json", + "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", - "input": "apps/my-app/public" + "input": "src/public" }, { "glob": "**/*", @@ -29,7 +29,7 @@ "output": "/highcharts/" } ], - "styles": ["apps/my-app/src/styles.css"], + "styles": ["src/styles.css"], "scripts": [], "allowedCommonJsDependencies": ["*"] }, @@ -75,17 +75,17 @@ "test": { "builder": "@angular-devkit/build-angular:karma", "options": { - "main": "apps/my-app/src/test.ts", + "main": "src/test.ts", "karmaConfig": "./karma.conf.js", "polyfills": ["core-js/es/reflect", "zone.js", "zone.js/testing"], - "tsConfig": "apps/my-app/tsconfig.spec.json", + "tsConfig": "tsconfig.spec.json", "assets": [ { "glob": "**/*", - "input": "apps/my-app/public" + "input": "src/public" } ], - "styles": ["apps/my-app/src/styles.css"], + "styles": ["src/styles.css"], "scripts": [] } } @@ -142,24 +142,24 @@ "my-ssr-app": { "projectType": "application", "schematics": {}, - "root": "apps/my-ssr-app", - "sourceRoot": "apps/my-ssr-app/src", + "root": "", + "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": "dist/my-ssr-app", - "index": "apps/my-ssr-app/src/index.html", - "browser": "apps/my-ssr-app/src/main.ts", + "index": "src/index.html", + "browser": "src/main.ts", "polyfills": [ "zone.js" ], - "tsConfig": "apps/my-ssr-app/tsconfig.app.json", + "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", - "input": "apps/my-ssr-app/public" + "input": "src/public" }, { "glob": "**/*", @@ -168,13 +168,13 @@ } ], "styles": [ - "apps/my-ssr-app/src/styles.css" + "src/styles.css" ], "scripts": [], - "server": "apps/my-ssr-app/src/main.server.ts", + "server": "src/main.server.ts", "prerender": true, "ssr": { - "entry": "apps/my-ssr-app/src/server.ts" + "entry": "src/server.ts" }, "allowedCommonJsDependencies": ["*"] }, @@ -224,15 +224,15 @@ "zone.js", "zone.js/testing" ], - "tsConfig": "apps/my-ssr-app/tsconfig.spec.json", + "tsConfig": "tsconfig.spec.json", "assets": [ { "glob": "**/*", - "input": "apps/my-ssr-app/public" + "input": "src/public" } ], "styles": [ - "apps/my-ssr-app/src/styles.css" + "src/styles.css" ], "scripts": [] } diff --git a/apps/my-app/tsconfig.app.json b/apps/my-app/tsconfig.app.json deleted file mode 100644 index e40712b..0000000 --- a/apps/my-app/tsconfig.app.json +++ /dev/null @@ -1,15 +0,0 @@ -/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ -/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/app", - "types": [] - }, - "files": [ - "src/main.ts" - ], - "include": [ - "src/**/*.d.ts" - ] -} diff --git a/apps/my-ssr-app/public/favicon.ico b/apps/my-ssr-app/public/favicon.ico deleted file mode 100644 index 57614f9c967596fad0a3989bec2b1deff33034f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 zcmd^G33O9Omi+`8$@{|M-I6TH3wzF-p5CV8o}7f~KxR60LK+ApEFB<$bcciv%@SmA zV{n>g85YMFFeU*Uvl=i4v)C*qgnb;$GQ=3XTe9{Y%c`mO%su)noNCCQ*@t1WXn|B(hQ7i~ zrUK8|pUkD6#lNo!bt$6)jR!&C?`P5G(`e((P($RaLeq+o0Vd~f11;qB05kdbAOm?r zXv~GYr_sibQO9NGTCdT;+G(!{4Xs@4fPak8#L8PjgJwcs-Mm#nR_Z0s&u?nDX5^~@ z+A6?}g0|=4e_LoE69pPFO`yCD@BCjgKpzMH0O4Xs{Ahc?K3HC5;l=f zg>}alhBXX&);z$E-wai+9TTRtBX-bWYY@cl$@YN#gMd~tM_5lj6W%8ah4;uZ;jP@Q zVbuel1rPA?2@x9Y+u?e`l{Z4ngfG5q5BLH5QsEu4GVpt{KIp1?U)=3+KQ;%7ec8l* zdV=zZgN5>O3G(3L2fqj3;oBbZZw$Ij@`Juz@?+yy#OPw)>#wsTewVgTK9BGt5AbZ&?K&B3GVF&yu?@(Xj3fR3n+ZP0%+wo)D9_xp>Z$`A4 zfV>}NWjO#3lqumR0`gvnffd9Ka}JJMuHS&|55-*mCD#8e^anA<+sFZVaJe7{=p*oX zE_Uv?1>e~ga=seYzh{9P+n5<+7&9}&(kwqSaz;1aD|YM3HBiy<))4~QJSIryyqp| z8nGc(8>3(_nEI4n)n7j(&d4idW1tVLjZ7QbNLXg;LB ziHsS5pXHEjGJZb59KcvS~wv;uZR-+4qEqow`;JCfB*+b^UL^3!?;-^F%yt=VjU|v z39SSqKcRu_NVvz!zJzL0CceJaS6%!(eMshPv_0U5G`~!a#I$qI5Ic(>IONej@aH=f z)($TAT#1I{iCS4f{D2+ApS=$3E7}5=+y(rA9mM#;Cky%b*Gi0KfFA`ofKTzu`AV-9 znW|y@19rrZ*!N2AvDi<_ZeR3O2R{#dh1#3-d%$k${Rx42h+i&GZo5!C^dSL34*AKp z27mTd>k>?V&X;Nl%GZ(>0s`1UN~Hfyj>KPjtnc|)xM@{H_B9rNr~LuH`Gr5_am&Ep zTjZA8hljNj5H1Ipm-uD9rC}U{-vR!eay5&6x6FkfupdpT*84MVwGpdd(}ib)zZ3Ky z7C$pnjc82(W_y_F{PhYj?o!@3__UUvpX)v69aBSzYj3 zdi}YQkKs^SyXyFG2LTRz9{(w}y~!`{EuAaUr6G1M{*%c+kP1olW9z23dSH!G4_HSK zzae-DF$OGR{ofP*!$a(r^5Go>I3SObVI6FLY)N@o<*gl0&kLo-OT{Tl*7nCz>Iq=? zcigIDHtj|H;6sR?or8Wd_a4996GI*CXGU}o;D9`^FM!AT1pBY~?|4h^61BY#_yIfO zKO?E0 zJ{Pc`9rVEI&$xxXu`<5E)&+m(7zX^v0rqofLs&bnQT(1baQkAr^kEsk)15vlzAZ-l z@OO9RF<+IiJ*O@HE256gCt!bF=NM*vh|WVWmjVawcNoksRTMvR03H{p@cjwKh(CL4 z7_PB(dM=kO)!s4fW!1p0f93YN@?ZSG` z$B!JaAJCtW$B97}HNO9(x-t30&E}Mo1UPi@Av%uHj~?T|!4JLwV;KCx8xO#b9IlUW zI6+{a@Wj|<2Y=U;a@vXbxqZNngH8^}LleE_4*0&O7#3iGxfJ%Id>+sb;7{L=aIic8 z|EW|{{S)J-wr@;3PmlxRXU8!e2gm_%s|ReH!reFcY8%$Hl4M5>;6^UDUUae?kOy#h zk~6Ee_@ZAn48Bab__^bNmQ~+k=02jz)e0d9Z3>G?RGG!65?d1>9}7iG17?P*=GUV-#SbLRw)Hu{zx*azHxWkGNTWl@HeWjA?39Ia|sCi{e;!^`1Oec zb>Z|b65OM*;eC=ZLSy?_fg$&^2xI>qSLA2G*$nA3GEnp3$N-)46`|36m*sc#4%C|h zBN<2U;7k>&G_wL4=Ve5z`ubVD&*Hxi)r@{4RCDw7U_D`lbC(9&pG5C*z#W>8>HU)h z!h3g?2UL&sS!oY5$3?VlA0Me9W5e~V;2jds*fz^updz#AJ%G8w2V}AEE?E^=MK%Xt z__Bx1cr7+DQmuHmzn*|hh%~eEc9@m05@clWfpEFcr+06%0&dZJH&@8^&@*$qR@}o3 z@Tuuh2FsLz^zH+dN&T&?0G3I?MpmYJ;GP$J!EzjeM#YLJ!W$}MVNb0^HfOA>5Fe~UNn%Zk(PT@~9}1dt)1UQ zU*B5K?Dl#G74qmg|2>^>0WtLX#Jz{lO4NT`NYB*(L#D|5IpXr9v&7a@YsGp3vLR7L zHYGHZg7{ie6n~2p$6Yz>=^cEg7tEgk-1YRl%-s7^cbqFb(U7&Dp78+&ut5!Tn(hER z|Gp4Ed@CnOPeAe|N>U(dB;SZ?NU^AzoD^UAH_vamp6Ws}{|mSq`^+VP1g~2B{%N-!mWz<`)G)>V-<`9`L4?3dM%Qh6<@kba+m`JS{Ya@9Fq*m6$$ zA1%Ogc~VRH33|S9l%CNb4zM%k^EIpqY}@h{w(aBcJ9c05oiZx#SK9t->5lSI`=&l~ z+-Ic)a{FbBhXV$Xt!WRd`R#Jk-$+_Z52rS>?Vpt2IK<84|E-SBEoIw>cs=a{BlQ7O z-?{Fy_M&84&9|KM5wt~)*!~i~E=(6m8(uCO)I=)M?)&sRbzH$9Rovzd?ZEY}GqX+~ zFbEbLz`BZ49=2Yh-|<`waK-_4!7`ro@zlC|r&I4fc4oyb+m=|c8)8%tZ-z5FwhzDt zL5kB@u53`d@%nHl0Sp)Dw`(QU&>vujEn?GPEXUW!Wi<+4e%BORl&BIH+SwRcbS}X@ z01Pk|vA%OdJKAs17zSXtO55k!;%m9>1eW9LnyAX4uj7@${O6cfii`49qTNItzny5J zH&Gj`e}o}?xjQ}r?LrI%FjUd@xflT3|7LA|ka%Q3i}a8gVm<`HIWoJGH=$EGClX^C0lysQJ>UO(q&;`T#8txuoQ_{l^kEV9CAdXuU1Ghg8 zN_6hHFuy&1x24q5-(Z7;!poYdt*`UTdrQOIQ!2O7_+AHV2hgXaEz7)>$LEdG z<8vE^Tw$|YwZHZDPM!SNOAWG$?J)MdmEk{U!!$M#fp7*Wo}jJ$Q(=8>R`Ats?e|VU?Zt7Cdh%AdnfyN3MBWw{ z$OnREvPf7%z6`#2##_7id|H%Y{vV^vWXb?5d5?a_y&t3@p9t$ncHj-NBdo&X{wrfJ zamN)VMYROYh_SvjJ=Xd!Ga?PY_$;*L=SxFte!4O6%0HEh%iZ4=gvns7IWIyJHa|hT z2;1+e)`TvbNb3-0z&DD_)Jomsg-7p_Uh`wjGnU1urmv1_oVqRg#=C?e?!7DgtqojU zWoAB($&53;TsXu^@2;8M`#z{=rPy?JqgYM0CDf4v@z=ZD|ItJ&8%_7A#K?S{wjxgd z?xA6JdJojrWpB7fr2p_MSsU4(R7=XGS0+Eg#xR=j>`H@R9{XjwBmqAiOxOL` zt?XK-iTEOWV}f>Pz3H-s*>W z4~8C&Xq25UQ^xH6H9kY_RM1$ch+%YLF72AA7^b{~VNTG}Tj#qZltz5Q=qxR`&oIlW Nr__JTFzvMr^FKp4S3v*( diff --git a/apps/my-ssr-app/src/app/app.component.css b/apps/my-ssr-app/src/app/app.component.css deleted file mode 100644 index 58a2628..0000000 --- a/apps/my-ssr-app/src/app/app.component.css +++ /dev/null @@ -1,22 +0,0 @@ -.card { - border: solid 1px #E1E1E1; - border-radius: 0.5rem; - display: flex; - flex-direction: column; - margin-top: 2rem; - max-width: 1184px; - padding: 2rem; - width: 100%; - background: white; -} - -main { - display:flex; - flex-direction: column; - align-items: center; - width: 100%; -} - -main:last-child { - margin-bottom: 2rem; -} diff --git a/apps/my-ssr-app/src/app/app.component.html b/apps/my-ssr-app/src/app/app.component.html deleted file mode 100644 index c8acc02..0000000 --- a/apps/my-ssr-app/src/app/app.component.html +++ /dev/null @@ -1,7 +0,0 @@ -
- - - - - -
diff --git a/apps/my-ssr-app/src/app/app.component.ts b/apps/my-ssr-app/src/app/app.component.ts deleted file mode 100644 index 15e0a51..0000000 --- a/apps/my-ssr-app/src/app/app.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component } from '@angular/core'; -import {GanttChartComponent} from './gantt-chart/gantt-chart.component'; -import {LazyLoadingChartComponent} from './lazy-loading-chart/lazy-loading-chart.component'; -import {LineChartComponent} from './line-chart/line-chart.component'; -import {MapChartComponent} from './map-chart/map-chart.component'; -import {StockChartComponent} from './stock-chart/stock-chart.component'; - -@Component({ - selector: 'app-root', - imports: [GanttChartComponent, LineChartComponent, StockChartComponent, LazyLoadingChartComponent, MapChartComponent], - templateUrl: './app.component.html', - styleUrl: './app.component.css' -}) -export class AppComponent { - title = 'my-ssr-app'; -} diff --git a/apps/my-ssr-app/src/app/app.config.ts b/apps/my-ssr-app/src/app/app.config.ts deleted file mode 100644 index 5863f39..0000000 --- a/apps/my-ssr-app/src/app/app.config.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {provideHttpClient, withFetch, withInterceptorsFromDi} from '@angular/common/http'; -import {ApplicationConfig, importProvidersFrom, provideZoneChangeDetection} from '@angular/core'; -import {BrowserModule, provideClientHydration, withEventReplay} from '@angular/platform-browser'; -import {provideHighCharts} from 'highcharts-angular'; -import ExportingModule from 'highcharts/modules/exporting'; -import SunsetTheme from 'highcharts/themes/sunset'; - -export const appConfig: ApplicationConfig = { - providers: [ - provideZoneChangeDetection({eventCoalescing: true}), - provideClientHydration(withEventReplay()), - importProvidersFrom(BrowserModule), - provideHttpClient(withInterceptorsFromDi(), withFetch()), - provideHighCharts({ - options: { - title: { - style: { - color: 'tomato' - } - }, - legend: { - enabled: false - } - }, - // The modules will work for all charts. - modules: [ExportingModule, SunsetTheme] - }) - ] -}; diff --git a/apps/my-ssr-app/src/app/apple-data.service.ts b/apps/my-ssr-app/src/app/apple-data.service.ts deleted file mode 100644 index d1416ce..0000000 --- a/apps/my-ssr-app/src/app/apple-data.service.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Injectable } from '@angular/core'; -import { HttpClient, HttpErrorResponse } from '@angular/common/http' -import { Observable, throwError } from 'rxjs'; -import { catchError } from 'rxjs/operators'; - -@Injectable({ - providedIn: 'root' -}) -export class AppleDataService { - private dataUrl = 'https://demo-live-data.highcharts.com/aapl-historical.json'; - - constructor(private http: HttpClient) { } - - fetchData(): Observable { - return this.http.get(this.dataUrl) - .pipe(catchError(this.errorHandler)); - } - - fetchSqlData(min: number, max: number): Observable { - return this.http.get(`${this.dataUrl}?start=${Math.round(min)}&end=${Math.round(max)}`) - .pipe(catchError(this.errorHandler)); - } - - errorHandler(error: HttpErrorResponse) { - return throwError(error.message || 'server error.'); - } - -} diff --git a/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.css b/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.css deleted file mode 100644 index caf005c..0000000 --- a/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.css +++ /dev/null @@ -1,11 +0,0 @@ -h2 { - font-family: Arial, Helvetica, sans-serif; - font-size: 1.25rem; - margin: 0 0 1.5rem 0; -} - -.main { - width: 100%; - height: 350px; - display: block; -} diff --git a/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.html b/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.html deleted file mode 100644 index 75942bd..0000000 --- a/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.html +++ /dev/null @@ -1,4 +0,0 @@ -
-

Demo #4: Highcharts Gantt chart

- -
diff --git a/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.ts b/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.ts deleted file mode 100644 index 2654dfd..0000000 --- a/apps/my-ssr-app/src/app/gantt-chart/gantt-chart.component.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import HC_gantt from 'highcharts/modules/gantt'; -import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; - - -@Component({ - selector: 'app-gantt-chart', - templateUrl: './gantt-chart.component.html', - styleUrls: ['./gantt-chart.component.css'], - imports: [HighchartsChartComponent], - providers: [providePartialHighChart({ modules: [HC_gantt] })], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class GanttChartComponent { - chartGantt: Highcharts.Options = { - title: { - text: 'Highcharts Gantt with Progress Indicators' - }, - xAxis: { - min: Date.UTC(2014, 10, 17), - max: Date.UTC(2014, 10, 30) - }, - - series: [{ - name: 'Project 1', - type: 'gantt', - data: [{ - name: 'Start prototype', - start: Date.UTC(2014, 10, 18), - end: Date.UTC(2014, 10, 25), - completed: 0.25 - }, { - name: 'Test prototype', - start: Date.UTC(2014, 10, 27), - end: Date.UTC(2014, 10, 29) - }, { - name: 'Develop', - start: Date.UTC(2014, 10, 20), - end: Date.UTC(2014, 10, 25), - completed: { - amount: 0.12, - fill: '#fa0' - } - }, { - name: 'Run acceptance tests', - start: Date.UTC(2014, 10, 23), - end: Date.UTC(2014, 10, 26) - }] - }] - }; - -} diff --git a/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.css b/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.css deleted file mode 100644 index 6a487ef..0000000 --- a/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.css +++ /dev/null @@ -1,11 +0,0 @@ -h2 { - font-family: Arial, Helvetica, sans-serif; - font-size: 1.25rem; - margin: 0 0 1.5rem 0; -} - -.main { - width: 100%; - height: 650px; - display: block; -} diff --git a/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.html b/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.html deleted file mode 100644 index d984ab5..0000000 --- a/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.html +++ /dev/null @@ -1,4 +0,0 @@ -
-

Demo #5: Lazy loading in Highcharts Stock

- -
diff --git a/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.ts b/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.ts deleted file mode 100644 index 20cc21b..0000000 --- a/apps/my-ssr-app/src/app/lazy-loading-chart/lazy-loading-chart.component.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import type Highcharts from 'highcharts'; -import HC_stock from 'highcharts/modules/stock'; -import { AppleDataService } from '../apple-data.service' -import { Observable } from 'rxjs'; -import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; - - -interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGroupingOptionsObject { - enabled: boolean -} - -@Component({ - selector: 'app-lazy-loading-chart', - templateUrl: './lazy-loading-chart.component.html', - styleUrls: ['./lazy-loading-chart.component.css'], - imports: [HighchartsChartComponent], - providers: [providePartialHighChart({ modules: [HC_stock] })], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class LazyLoadingChartComponent { - - constructor(private appleDataService: AppleDataService) { } - - chartRef: Highcharts.Chart; - - chartCallback: Highcharts.ChartCallbackFunction = (chart) => { - this.chartRef = chart; - }; - - fetchData(): Observable { - return this.appleDataService.fetchData(); - } - - fetchSqlData(min: number, max: number): Observable { - return this.appleDataService.fetchSqlData(min, max); - } - - chartLazyLoading: Highcharts.Options = { - chart: { - type: 'candlestick', - zooming: { - type: 'x' - }, - events: { - load: () => { - const chart = this.chartRef; - this.fetchData() - .subscribe((data: Array<[]>) => { - // Add a null value for the end date - const chartData = [...data, [Date.UTC(2011, 9, 14, 19, 59), null, null, null, null]]; - - chart.addSeries({ - type: 'candlestick', - data: chartData, - dataGrouping: { - enabled: false - } as ExtendedPlotCandlestickDataGroupingOptions - }, false); - - chart.update({ - navigator: { - series: { - data: chartData - } - } - }); - }); - } - } - }, - - navigator: { - adaptToUpdatedData: false - }, - - scrollbar: { - liveRedraw: false - }, - - title: { - text: 'AAPL history by the minute from 1998 to 2011' - }, - - subtitle: { - text: 'Displaying 1.7 million data points in Highcharts Stock by async server loading' - }, - - rangeSelector: { - buttons: [{ - type: 'hour', - count: 1, - text: '1h' - }, { - type: 'day', - count: 1, - text: '1d' - }, { - type: 'month', - count: 1, - text: '1m' - }, { - type: 'year', - count: 1, - text: '1y' - }, { - type: 'all', - text: 'All' - }], - inputEnabled: false, // it supports only days - selected: 4 // all - }, - - xAxis: { - events: { - afterSetExtremes: (event) => { - const chart = this.chartRef; - - chart.showLoading('Loading data from server...'); - - // Load new data depending on the selected min and max - this.fetchSqlData(event.min, event.max).subscribe((data: Array<[]>) => { - chart.series[0].setData(data); - chart.hideLoading(); - }) - } - }, - minRange: 3600 * 1000 // one hour - }, - - yAxis: { - floor: 0 - } - }; - -} diff --git a/apps/my-ssr-app/src/app/line-chart/line-chart.component.css b/apps/my-ssr-app/src/app/line-chart/line-chart.component.css deleted file mode 100644 index f76518a..0000000 --- a/apps/my-ssr-app/src/app/line-chart/line-chart.component.css +++ /dev/null @@ -1,32 +0,0 @@ -article { - display: flex; -} - -button{ - margin-right: 1rem; -} - -.buttons-wrapper { - margin-top: 1.5rem; -} - -h2 { - font-family: Arial, Helvetica, sans-serif; - font-size: 1.25rem; - margin: 0 0 1.5rem 0; -} - -highcharts-chart { - flex-grow: 3; -} - -section { - display: flex; - flex-direction: column; - width: 40% -} - -textarea { - border: 1px solid #E1E1E1; - border-radius: 0.5rem; -} \ No newline at end of file diff --git a/apps/my-ssr-app/src/app/line-chart/line-chart.component.html b/apps/my-ssr-app/src/app/line-chart/line-chart.component.html deleted file mode 100644 index 30982cc..0000000 --- a/apps/my-ssr-app/src/app/line-chart/line-chart.component.html +++ /dev/null @@ -1,19 +0,0 @@ -

Demo #1: Highcharts with a basic editor

-
-
- -
- - - -
-
- @if (showChart) { - - } -
diff --git a/apps/my-ssr-app/src/app/line-chart/line-chart.component.ts b/apps/my-ssr-app/src/app/line-chart/line-chart.component.ts deleted file mode 100644 index c5a97fc..0000000 --- a/apps/my-ssr-app/src/app/line-chart/line-chart.component.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import HC_customEvents from 'highcharts-custom-events'; -import { FormsModule } from '@angular/forms'; -import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; - -@Component({ - selector: 'app-line-chart', - templateUrl: './line-chart.component.html', - styleUrls: ['./line-chart.component.css'], - imports: [FormsModule, HighchartsChartComponent], - providers: [providePartialHighChart({ modules: [HC_customEvents] })], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class LineChartComponent { - public updateFromInput = false; - public showChart = true; - public toggleButtonTitle = 'Destroy chart'; - - public optFromInputString = ` - { - "title": { "text": "Highcharts chart" }, - "series": [{ - "data": [11,2,3], - "zones": [{ - "value": 7.2, - "dashStyle": "dot", - "color": "red" - }] - }, { - "data": [5,6,7] - }] - } - `; - public optFromInput: Highcharts.Options = JSON.parse(this.optFromInputString); - private seriesTypes = { - line: 'column', - column: 'scatter', - scatter: 'spline', - spline: 'line', - }; - - // Demonstrate chart instance - public logChartInstance(chart: Highcharts.Chart) { - if (chart) { - console.log('Chart instance received:', chart); - } else { - console.log('Chart instance destroyed'); - } - } - - public updateInputChart() { - this.optFromInput = JSON.parse(this.optFromInputString); - } - - public toggleSeriesType(index = 0) { - this.optFromInput.series[index].type = this.seriesTypes[ - this.optFromInput.series[index].type || 'line'] as keyof typeof this.seriesTypes; - // nested change - must trigger update - this.updateFromInput = true; - } - - public toggleChart() { - this.showChart = !this.showChart; - this.toggleButtonTitle = this.showChart ? 'Destroy chart' : 'Recreate chart'; - } -} diff --git a/apps/my-ssr-app/src/app/map-chart/map-chart.component.css b/apps/my-ssr-app/src/app/map-chart/map-chart.component.css deleted file mode 100644 index 6a487ef..0000000 --- a/apps/my-ssr-app/src/app/map-chart/map-chart.component.css +++ /dev/null @@ -1,11 +0,0 @@ -h2 { - font-family: Arial, Helvetica, sans-serif; - font-size: 1.25rem; - margin: 0 0 1.5rem 0; -} - -.main { - width: 100%; - height: 650px; - display: block; -} diff --git a/apps/my-ssr-app/src/app/map-chart/map-chart.component.html b/apps/my-ssr-app/src/app/map-chart/map-chart.component.html deleted file mode 100644 index c212596..0000000 --- a/apps/my-ssr-app/src/app/map-chart/map-chart.component.html +++ /dev/null @@ -1,4 +0,0 @@ -
-

Demo #3: Highcharts Maps with the lat/lon points

- -
diff --git a/apps/my-ssr-app/src/app/map-chart/map-chart.component.ts b/apps/my-ssr-app/src/app/map-chart/map-chart.component.ts deleted file mode 100644 index 8b3c5ae..0000000 --- a/apps/my-ssr-app/src/app/map-chart/map-chart.component.ts +++ /dev/null @@ -1,307 +0,0 @@ -import {AsyncPipe, JsonPipe} from '@angular/common'; -import {HttpClient} from '@angular/common/http'; -import {ChangeDetectionStrategy, Component, inject} from '@angular/core'; -import type Highcharts from 'highcharts'; -import HC_map from 'highcharts/modules/map'; -import { map } from 'rxjs'; -import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; -// import proj4 from 'proj4'; - -// Legacy way of map loading - see file at the path for more info. -// require('../../js/worldmap')(Highcharts); - -@Component({ - selector: 'app-map-chart', - templateUrl: './map-chart.component.html', - styleUrls: ['./map-chart.component.css'], - imports: [HighchartsChartComponent, AsyncPipe], - providers: [providePartialHighChart({ modules: [HC_map] })], - changeDetection: ChangeDetectionStrategy.OnPush, -}) - -export class MapChartComponent { - private http = inject(HttpClient); - chartMap$ = this.http.get('/highcharts/world.geo.json').pipe( - map((worldMap: any) => { - return { - chart: { - map: worldMap as any, - // proj4: proj4 - }, - title: { - text: 'Highcharts Maps - basic demo' - }, - subtitle: { - text: `Selected Canadian cities were marked using their lat/lon coordinates.
- Source map: World, Miller projection, medium resolution.` - }, - mapNavigation: { - enabled: true, - buttonOptions: { - alignTo: 'spacingBox' - } - }, - legend: { - enabled: true - }, - colorAxis: { - min: 0 - }, - series: [{ - name: 'Random data', - states: { - hover: { - color: '#BADA55' - } - }, - dataLabels: { - enabled: true, - format: '{point.name}' - }, - allAreas: false, - data: [ - ['fo', 0], - ['um', 1], - ['us', 2], - ['jp', 3], - ['sc', 4], - ['in', 5], - ['fr', 6], - ['fm', 7], - ['cn', 8], - ['pt', 9], - ['sw', 10], - ['sh', 11], - ['br', 12], - ['ki', 13], - ['ph', 14], - ['mx', 15], - ['es', 16], - ['bu', 17], - ['mv', 18], - ['sp', 19], - ['gb', 20], - ['gr', 21], - ['as', 22], - ['dk', 23], - ['gl', 24], - ['gu', 25], - ['mp', 26], - ['pr', 27], - ['vi', 28], - ['ca', 29], - ['st', 30], - ['cv', 31], - ['dm', 32], - ['nl', 33], - ['jm', 34], - ['ws', 35], - ['om', 36], - ['vc', 37], - ['tr', 38], - ['bd', 39], - ['lc', 40], - ['nr', 41], - ['no', 42], - ['kn', 43], - ['bh', 44], - ['to', 45], - ['fi', 46], - ['id', 47], - ['mu', 48], - ['se', 49], - ['tt', 50], - ['my', 51], - ['pa', 52], - ['pw', 53], - ['tv', 54], - ['mh', 55], - ['cl', 56], - ['th', 57], - ['gd', 58], - ['ee', 59], - ['ag', 60], - ['tw', 61], - ['bb', 62], - ['it', 63], - ['mt', 64], - ['vu', 65], - ['sg', 66], - ['cy', 67], - ['lk', 68], - ['km', 69], - ['fj', 70], - ['ru', 71], - ['va', 72], - ['sm', 73], - ['kz', 74], - ['az', 75], - ['tj', 76], - ['ls', 77], - ['uz', 78], - ['ma', 79], - ['co', 80], - ['tl', 81], - ['tz', 82], - ['ar', 83], - ['sa', 84], - ['pk', 85], - ['ye', 86], - ['ae', 87], - ['ke', 88], - ['pe', 89], - ['do', 90], - ['ht', 91], - ['pg', 92], - ['ao', 93], - ['kh', 94], - ['vn', 95], - ['mz', 96], - ['cr', 97], - ['bj', 98], - ['ng', 99], - ['ir', 100], - ['sv', 101], - ['sl', 102], - ['gw', 103], - ['hr', 104], - ['bz', 105], - ['za', 106], - ['cf', 107], - ['sd', 108], - ['cd', 109], - ['kw', 110], - ['de', 111], - ['be', 112], - ['ie', 113], - ['kp', 114], - ['kr', 115], - ['gy', 116], - ['hn', 117], - ['mm', 118], - ['ga', 119], - ['gq', 120], - ['ni', 121], - ['lv', 122], - ['ug', 123], - ['mw', 124], - ['am', 125], - ['sx', 126], - ['tm', 127], - ['zm', 128], - ['nc', 129], - ['mr', 130], - ['dz', 131], - ['lt', 132], - ['et', 133], - ['er', 134], - ['gh', 135], - ['si', 136], - ['gt', 137], - ['ba', 138], - ['jo', 139], - ['sy', 140], - ['mc', 141], - ['al', 142], - ['uy', 143], - ['cnm', 144], - ['mn', 145], - ['rw', 146], - ['so', 147], - ['bo', 148], - ['cm', 149], - ['cg', 150], - ['eh', 151], - ['rs', 152], - ['me', 153], - ['tg', 154], - ['la', 155], - ['af', 156], - ['ua', 157], - ['sk', 158], - ['jk', 159], - ['bg', 160], - ['qa', 161], - ['li', 162], - ['at', 163], - ['sz', 164], - ['hu', 165], - ['ro', 166], - ['ne', 167], - ['lu', 168], - ['ad', 169], - ['ci', 170], - ['lr', 171], - ['bn', 172], - ['iq', 173], - ['ge', 174], - ['gm', 175], - ['ch', 176], - ['td', 177], - ['kv', 178], - ['lb', 179], - ['dj', 180], - ['bi', 181], - ['sr', 182], - ['il', 183], - ['ml', 184], - ['sn', 185], - ['gn', 186], - ['zw', 187], - ['pl', 188], - ['mk', 189], - ['py', 190], - ['by', 191], - ['cz', 192], - ['bf', 193], - ['na', 194], - ['ly', 195], - ['tn', 196], - ['bt', 197], - ['md', 198], - ['ss', 199], - ['bw', 200], - ['bs', 201], - ['nz', 202], - ['cu', 203], - ['ec', 204], - ['au', 205], - ['ve', 206], - ['sb', 207], - ['mg', 208], - ['is', 209], - ['eg', 210], - ['kg', 211], - ['np', 212] - ] - } as Highcharts.SeriesMapOptions, - { - // Specify points using lat/lon - type: 'mappoint', - name: 'Canada cities', - marker: { - radius: 5, - fillColor: 'tomato' - }, - data: [ - { - name: 'Vancouver', - lat: 49.246292, - lon: -123.116226 - }, - { - name: 'Quebec City', - lat: 46.829853, - lon: -71.254028 - }, - { - name: 'Yellowknife', - lat: 62.4540, - lon: -114.3718 - } - ] - } as Highcharts.SeriesMappointOptions] - } - }) - ) -} diff --git a/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.css b/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.css deleted file mode 100644 index 76ded5a..0000000 --- a/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.css +++ /dev/null @@ -1,23 +0,0 @@ -article { - display: flex; -} - -button { - margin-bottom: 1rem; -} - -h2 { - font-family: Arial, Helvetica, sans-serif; - font-size: 1.25rem; - margin: 0 0 1.5rem 0; -} - -highcharts-chart { - min-height: 350px; flex-grow: 3; -} - -section { - display: flex; - flex-direction: column; - width: 40%; -} \ No newline at end of file diff --git a/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.html b/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.html deleted file mode 100644 index 00761e6..0000000 --- a/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.html +++ /dev/null @@ -1,26 +0,0 @@ -

Demo #2: Highcharts Stock with simple updates

-
-
-

Chart title text:

- -

Data sets:

-
- @for (i of [0,1,2]; track i) { - - } -
-
- -
diff --git a/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.ts b/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.ts deleted file mode 100644 index 5a36c45..0000000 --- a/apps/my-ssr-app/src/app/stock-chart/stock-chart.component.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import type Highcharts from 'highcharts'; -import HC_stock from 'highcharts/modules/stock'; -import HC_customEvents from 'highcharts-custom-events'; -import { FormsModule } from '@angular/forms'; -import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; - - -// Alternative way of a plugin loading: -// const HC_ce = require('highcharts-custom-events'); -// HC_ce(Highcharts); - -@Component({ - selector: 'app-stock-chart', - templateUrl: './stock-chart.component.html', - styleUrls: ['./stock-chart.component.css'], - imports: [FormsModule, HighchartsChartComponent], - providers: [providePartialHighChart({ modules: [HC_stock, HC_customEvents] })], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class StockChartComponent { - - // starting values - updateDemo2: boolean = false; - usedIndex: number = 0; - chartTitle: string = 'My chart'; // for init - change through titleChange - - // change in all places - titleChange(event: any) { - var v = event; - this.chartTitle = v; - - this.charts.forEach((el) => { - el.hcOptions.title.text = v; - }); - - // trigger ngOnChanges - this.updateDemo2 = true; - }; - - charts = [{ - hcOptions: { - title: { text: this.chartTitle }, - subtitle: { text: '1st data set' }, - plotOptions: { - series: { - pointStart: Date.now(), - pointInterval: 86400000 // 1 day - } - }, - series: [{ - type: 'line', - data: [11, 2, 3], - threshold: 5, - negativeColor: 'red', - events: { - dblclick: function () { - console.log('dblclick - thanks to the Custom Events plugin'); - } - } - }, { - type: 'candlestick', - - data: [ - [0, 15, -6, 7], - [7, 12, -1, 3], - [3, 10, -3, 3] - ] - }] - } as Highcharts.Options, - hcCallback: (chart: Highcharts.Chart) => { - console.log('some variables: ', chart, this.charts); - } - }, { - hcOptions: { - title: { text: this.chartTitle }, - subtitle: { text: '2nd data set' }, - series: [{ - type: 'column', - data: [4, 3, -12], - threshold: -10 - }, { - type: 'ohlc', - data: [ - [0, 15, -6, 7], - [7, 12, -1, 3], - [3, 10, -3, 3] - ] - }] - } as Highcharts.Options, - hcCallback: () => {} - }, { - hcOptions: { - title: { text: this.chartTitle }, - subtitle: { text: '3rd data set' }, - series: [{ - type: 'scatter', - data: [1, 2, 3, 4, 5] - }, { - type: 'areaspline', - data: [ - 5, - 11, - 3, - 6, - 0 - ] - }] - } as Highcharts.Options, - hcCallback: () => {} - }]; - - -} diff --git a/apps/my-ssr-app/src/index.html b/apps/my-ssr-app/src/index.html deleted file mode 100644 index be5a150..0000000 --- a/apps/my-ssr-app/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - highcharts-angular-ssr - - - - - - - - diff --git a/apps/my-ssr-app/src/main.ts b/apps/my-ssr-app/src/main.ts deleted file mode 100644 index 35b00f3..0000000 --- a/apps/my-ssr-app/src/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, appConfig) - .catch((err) => console.error(err)); diff --git a/apps/my-ssr-app/src/styles.css b/apps/my-ssr-app/src/styles.css deleted file mode 100644 index 90d4ee0..0000000 --- a/apps/my-ssr-app/src/styles.css +++ /dev/null @@ -1 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ diff --git a/apps/my-ssr-app/tsconfig.spec.json b/apps/my-ssr-app/tsconfig.spec.json deleted file mode 100644 index 0a43b83..0000000 --- a/apps/my-ssr-app/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ -/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": [ - "jasmine" - ] - }, - "include": [ - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/my-app/src/app/app.component.css b/src/app/app.component.css similarity index 100% rename from apps/my-app/src/app/app.component.css rename to src/app/app.component.css diff --git a/apps/my-app/src/app/app.component.html b/src/app/app.component.html similarity index 100% rename from apps/my-app/src/app/app.component.html rename to src/app/app.component.html diff --git a/apps/my-app/src/app/app.component.ts b/src/app/app.component.ts similarity index 100% rename from apps/my-app/src/app/app.component.ts rename to src/app/app.component.ts diff --git a/apps/my-ssr-app/src/app/app.config.server.ts b/src/app/app.config.server.ts similarity index 100% rename from apps/my-ssr-app/src/app/app.config.server.ts rename to src/app/app.config.server.ts diff --git a/apps/my-app/src/app/app.config.ts b/src/app/app.config.ts similarity index 79% rename from apps/my-app/src/app/app.config.ts rename to src/app/app.config.ts index 36573cc..63d0437 100644 --- a/apps/my-app/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -1,4 +1,4 @@ -import {provideHttpClient, withInterceptorsFromDi} from '@angular/common/http'; +import {provideHttpClient, withFetch, withInterceptorsFromDi} from '@angular/common/http'; import {ApplicationConfig, importProvidersFrom, provideZoneChangeDetection} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import { provideHighCharts } from 'highcharts-angular'; @@ -8,8 +8,9 @@ import SunsetTheme from 'highcharts/themes/sunset'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), + // provideClientHydration(withEventReplay()), importProvidersFrom(BrowserModule), - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withInterceptorsFromDi(), withFetch()), provideHighCharts({ options: { title: { diff --git a/apps/my-app/src/app/apple-data.service.ts b/src/app/apple-data.service.ts similarity index 100% rename from apps/my-app/src/app/apple-data.service.ts rename to src/app/apple-data.service.ts diff --git a/apps/my-app/src/app/gantt-chart/gantt-chart.component.css b/src/app/gantt-chart/gantt-chart.component.css similarity index 100% rename from apps/my-app/src/app/gantt-chart/gantt-chart.component.css rename to src/app/gantt-chart/gantt-chart.component.css diff --git a/apps/my-app/src/app/gantt-chart/gantt-chart.component.html b/src/app/gantt-chart/gantt-chart.component.html similarity index 100% rename from apps/my-app/src/app/gantt-chart/gantt-chart.component.html rename to src/app/gantt-chart/gantt-chart.component.html diff --git a/apps/my-app/src/app/gantt-chart/gantt-chart.component.ts b/src/app/gantt-chart/gantt-chart.component.ts similarity index 100% rename from apps/my-app/src/app/gantt-chart/gantt-chart.component.ts rename to src/app/gantt-chart/gantt-chart.component.ts diff --git a/apps/my-app/src/app/lazy-loading-chart/lazy-loading-chart.component.css b/src/app/lazy-loading-chart/lazy-loading-chart.component.css similarity index 100% rename from apps/my-app/src/app/lazy-loading-chart/lazy-loading-chart.component.css rename to src/app/lazy-loading-chart/lazy-loading-chart.component.css diff --git a/apps/my-app/src/app/lazy-loading-chart/lazy-loading-chart.component.html b/src/app/lazy-loading-chart/lazy-loading-chart.component.html similarity index 100% rename from apps/my-app/src/app/lazy-loading-chart/lazy-loading-chart.component.html rename to src/app/lazy-loading-chart/lazy-loading-chart.component.html diff --git a/apps/my-app/src/app/lazy-loading-chart/lazy-loading-chart.component.ts b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts similarity index 100% rename from apps/my-app/src/app/lazy-loading-chart/lazy-loading-chart.component.ts rename to src/app/lazy-loading-chart/lazy-loading-chart.component.ts diff --git a/apps/my-app/src/app/line-chart/line-chart.component.css b/src/app/line-chart/line-chart.component.css similarity index 100% rename from apps/my-app/src/app/line-chart/line-chart.component.css rename to src/app/line-chart/line-chart.component.css diff --git a/apps/my-app/src/app/line-chart/line-chart.component.html b/src/app/line-chart/line-chart.component.html similarity index 100% rename from apps/my-app/src/app/line-chart/line-chart.component.html rename to src/app/line-chart/line-chart.component.html diff --git a/apps/my-app/src/app/line-chart/line-chart.component.ts b/src/app/line-chart/line-chart.component.ts similarity index 100% rename from apps/my-app/src/app/line-chart/line-chart.component.ts rename to src/app/line-chart/line-chart.component.ts diff --git a/apps/my-app/src/app/map-chart/map-chart.component.css b/src/app/map-chart/map-chart.component.css similarity index 100% rename from apps/my-app/src/app/map-chart/map-chart.component.css rename to src/app/map-chart/map-chart.component.css diff --git a/apps/my-app/src/app/map-chart/map-chart.component.html b/src/app/map-chart/map-chart.component.html similarity index 100% rename from apps/my-app/src/app/map-chart/map-chart.component.html rename to src/app/map-chart/map-chart.component.html diff --git a/apps/my-app/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts similarity index 100% rename from apps/my-app/src/app/map-chart/map-chart.component.ts rename to src/app/map-chart/map-chart.component.ts diff --git a/apps/my-app/src/app/stock-chart/stock-chart.component.css b/src/app/stock-chart/stock-chart.component.css similarity index 100% rename from apps/my-app/src/app/stock-chart/stock-chart.component.css rename to src/app/stock-chart/stock-chart.component.css diff --git a/apps/my-app/src/app/stock-chart/stock-chart.component.html b/src/app/stock-chart/stock-chart.component.html similarity index 100% rename from apps/my-app/src/app/stock-chart/stock-chart.component.html rename to src/app/stock-chart/stock-chart.component.html diff --git a/apps/my-app/src/app/stock-chart/stock-chart.component.ts b/src/app/stock-chart/stock-chart.component.ts similarity index 100% rename from apps/my-app/src/app/stock-chart/stock-chart.component.ts rename to src/app/stock-chart/stock-chart.component.ts diff --git a/apps/my-app/src/app/tests/line-test/line-test.component.css b/src/app/tests/line-test/line-test.component.css similarity index 100% rename from apps/my-app/src/app/tests/line-test/line-test.component.css rename to src/app/tests/line-test/line-test.component.css diff --git a/apps/my-app/src/app/tests/line-test/line-test.component.html b/src/app/tests/line-test/line-test.component.html similarity index 100% rename from apps/my-app/src/app/tests/line-test/line-test.component.html rename to src/app/tests/line-test/line-test.component.html diff --git a/apps/my-app/src/app/tests/line-test/line-test.component.spec.ts b/src/app/tests/line-test/line-test.component.spec.ts similarity index 96% rename from apps/my-app/src/app/tests/line-test/line-test.component.spec.ts rename to src/app/tests/line-test/line-test.component.spec.ts index 57ad3f8..6116bf1 100644 --- a/apps/my-app/src/app/tests/line-test/line-test.component.spec.ts +++ b/src/app/tests/line-test/line-test.component.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { provideHighCharts, HighchartsChartService } from '../../../../../../highcharts-angular/src/public_api'; +import { provideHighCharts, HighchartsChartService } from '../../../../highcharts-angular/src/public_api'; import { LineTestComponent } from './line-test.component'; diff --git a/apps/my-app/src/app/tests/line-test/line-test.component.ts b/src/app/tests/line-test/line-test.component.ts similarity index 89% rename from apps/my-app/src/app/tests/line-test/line-test.component.ts rename to src/app/tests/line-test/line-test.component.ts index fa5f605..92ca7dd 100644 --- a/apps/my-app/src/app/tests/line-test/line-test.component.ts +++ b/src/app/tests/line-test/line-test.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import type Highcharts from 'highcharts'; -import { HighchartsChartComponent } from '../../../../../../highcharts-angular/src/public_api'; +import { HighchartsChartComponent } from '../../../../highcharts-angular/src/public_api'; interface ExtendedSeriesCandlestickOptions extends Highcharts.SeriesCandlestickOptions { color: Highcharts.ColorType; diff --git a/apps/my-app/public/favicon.ico b/src/assets/favicon.ico similarity index 100% rename from apps/my-app/public/favicon.ico rename to src/assets/favicon.ico diff --git a/apps/my-app/src/global.d.ts b/src/global.d.ts similarity index 100% rename from apps/my-app/src/global.d.ts rename to src/global.d.ts diff --git a/apps/my-app/src/index.html b/src/index.html similarity index 100% rename from apps/my-app/src/index.html rename to src/index.html diff --git a/apps/my-ssr-app/src/main.server.ts b/src/main.server.ts similarity index 100% rename from apps/my-ssr-app/src/main.server.ts rename to src/main.server.ts diff --git a/apps/my-app/src/main.ts b/src/main.ts similarity index 100% rename from apps/my-app/src/main.ts rename to src/main.ts diff --git a/apps/my-ssr-app/src/server.ts b/src/server.ts similarity index 100% rename from apps/my-ssr-app/src/server.ts rename to src/server.ts diff --git a/apps/my-app/src/styles.css b/src/styles.css similarity index 100% rename from apps/my-app/src/styles.css rename to src/styles.css diff --git a/apps/my-app/src/test.ts b/src/test.ts similarity index 100% rename from apps/my-app/src/test.ts rename to src/test.ts diff --git a/apps/my-app/src/typings.d.ts b/src/typings.d.ts similarity index 100% rename from apps/my-app/src/typings.d.ts rename to src/typings.d.ts diff --git a/apps/my-ssr-app/tsconfig.app.json b/tsconfig.app.json similarity index 85% rename from apps/my-ssr-app/tsconfig.app.json rename to tsconfig.app.json index 6ce3d0a..172afbf 100644 --- a/apps/my-ssr-app/tsconfig.app.json +++ b/tsconfig.app.json @@ -1,12 +1,10 @@ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { - "extends": "../../tsconfig.json", + "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../out-tsc/app", - "types": [ - "node" - ] + "types": [] }, "files": [ "src/main.ts", diff --git a/apps/my-app/tsconfig.spec.json b/tsconfig.spec.json similarity index 84% rename from apps/my-app/tsconfig.spec.json rename to tsconfig.spec.json index ec8f031..9e9a4d5 100644 --- a/apps/my-app/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -1,15 +1,17 @@ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { - "extends": "../../tsconfig.json", + "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../out-tsc/spec", "types": [ "jasmine", "node" - ], + ] }, - "files": ["src/test.ts"], + "files": [ + "src/test.ts" + ], "include": [ "src/**/*.spec.ts", "src/**/*.d.ts" From c40107ae92b369e79495402f2b454ef2b6b6db5e Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 23:34:17 +0100 Subject: [PATCH 72/94] reset config --- angular.json | 13 ++++--------- src/{assets => }/favicon.ico | Bin src/styles.css | 1 - tsconfig.app.json | 2 +- tsconfig.spec.json | 2 +- 5 files changed, 6 insertions(+), 12 deletions(-) rename src/{assets => }/favicon.ico (100%) delete mode 100644 src/styles.css diff --git a/angular.json b/angular.json index e2d87c2..9729a02 100644 --- a/angular.json +++ b/angular.json @@ -1,7 +1,6 @@ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, - "newProjectRoot": "apps", "projects": { "my-app": { "root": "", @@ -29,7 +28,7 @@ "output": "/highcharts/" } ], - "styles": ["src/styles.css"], + "styles": [], "scripts": [], "allowedCommonJsDependencies": ["*"] }, @@ -85,7 +84,7 @@ "input": "src/public" } ], - "styles": ["src/styles.css"], + "styles": [], "scripts": [] } } @@ -167,9 +166,7 @@ "output": "/highcharts/" } ], - "styles": [ - "src/styles.css" - ], + "styles": [], "scripts": [], "server": "src/main.server.ts", "prerender": true, @@ -231,9 +228,7 @@ "input": "src/public" } ], - "styles": [ - "src/styles.css" - ], + "styles": [], "scripts": [] } } diff --git a/src/assets/favicon.ico b/src/favicon.ico similarity index 100% rename from src/assets/favicon.ico rename to src/favicon.ico diff --git a/src/styles.css b/src/styles.css deleted file mode 100644 index 90d4ee0..0000000 --- a/src/styles.css +++ /dev/null @@ -1 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ diff --git a/tsconfig.app.json b/tsconfig.app.json index 172afbf..8569547 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -3,7 +3,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "outDir": "../../out-tsc/app", + "outDir": "../out-tsc/app", "types": [] }, "files": [ diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 9e9a4d5..099def8 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -3,7 +3,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "outDir": "../../out-tsc/spec", + "outDir": "./out-tsc/spec", "types": [ "jasmine", "node" From ec37324693e47a9d1fe5cc09c7f6df68a624f949 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 23:36:17 +0100 Subject: [PATCH 73/94] reset config --- src/assets/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/assets/.gitkeep diff --git a/src/assets/.gitkeep b/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 From 3c5b7f31f504e0f5a1561917bd55a35d1654e380 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 23:39:40 +0100 Subject: [PATCH 74/94] use signals --- src/app/map-chart/map-chart.component.html | 2 +- src/app/map-chart/map-chart.component.ts | 558 ++++++++++----------- 2 files changed, 279 insertions(+), 281 deletions(-) diff --git a/src/app/map-chart/map-chart.component.html b/src/app/map-chart/map-chart.component.html index f403605..81332d2 100644 --- a/src/app/map-chart/map-chart.component.html +++ b/src/app/map-chart/map-chart.component.html @@ -1,4 +1,4 @@

Demo #3: Highcharts Maps with the lat/lon points

- +
diff --git a/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts index 7380eeb..897ed4c 100644 --- a/src/app/map-chart/map-chart.component.ts +++ b/src/app/map-chart/map-chart.component.ts @@ -1,9 +1,8 @@ -import {AsyncPipe} from '@angular/common'; import {HttpClient} from '@angular/common/http'; -import {ChangeDetectionStrategy, Component, inject} from '@angular/core'; +import {ChangeDetectionStrategy, Component, inject, computed} from '@angular/core'; +import {toSignal} from '@angular/core/rxjs-interop'; import type Highcharts from 'highcharts'; import HC_map from 'highcharts/modules/map'; -import { map } from 'rxjs'; import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; // import proj4 from 'proj4'; @@ -14,295 +13,294 @@ import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-an selector: 'app-map-chart', templateUrl: './map-chart.component.html', styleUrls: ['./map-chart.component.css'], - imports: [HighchartsChartComponent, AsyncPipe], + imports: [HighchartsChartComponent], providers: [providePartialHighChart({ modules: [HC_map] })], changeDetection: ChangeDetectionStrategy.OnPush, }) export class MapChartComponent { private http = inject(HttpClient); - chartMap$ = this.http.get('/highcharts/world.geo.json').pipe( - map((worldMap: any) => { - return { - chart: { - map: worldMap as any, - // proj4: proj4 - }, - title: { - text: 'Highcharts Maps - basic demo' - }, - subtitle: { - text: `Selected Canadian cities were marked using their lat/lon coordinates.
+ worldMap = toSignal(this.http.get('/highcharts/world.geo.json')); + chartMap = computed(() => { + return { + chart: { + map: this.worldMap() as any, + // proj4: proj4 + }, + title: { + text: 'Highcharts Maps - basic demo' + }, + subtitle: { + text: `Selected Canadian cities were marked using their lat/lon coordinates.
Source map: World, Miller projection, medium resolution.` - }, - mapNavigation: { - enabled: true, - buttonOptions: { - alignTo: 'spacingBox' + }, + mapNavigation: { + enabled: true, + buttonOptions: { + alignTo: 'spacingBox' + } + }, + legend: { + enabled: true + }, + colorAxis: { + min: 0 + }, + series: [{ + name: 'Random data', + states: { + hover: { + color: '#BADA55' } }, - legend: { - enabled: true - }, - colorAxis: { - min: 0 + dataLabels: { + enabled: true, + format: '{point.name}' }, - series: [{ - name: 'Random data', - states: { - hover: { - color: '#BADA55' - } - }, - dataLabels: { - enabled: true, - format: '{point.name}' + allAreas: false, + data: [ + ['fo', 0], + ['um', 1], + ['us', 2], + ['jp', 3], + ['sc', 4], + ['in', 5], + ['fr', 6], + ['fm', 7], + ['cn', 8], + ['pt', 9], + ['sw', 10], + ['sh', 11], + ['br', 12], + ['ki', 13], + ['ph', 14], + ['mx', 15], + ['es', 16], + ['bu', 17], + ['mv', 18], + ['sp', 19], + ['gb', 20], + ['gr', 21], + ['as', 22], + ['dk', 23], + ['gl', 24], + ['gu', 25], + ['mp', 26], + ['pr', 27], + ['vi', 28], + ['ca', 29], + ['st', 30], + ['cv', 31], + ['dm', 32], + ['nl', 33], + ['jm', 34], + ['ws', 35], + ['om', 36], + ['vc', 37], + ['tr', 38], + ['bd', 39], + ['lc', 40], + ['nr', 41], + ['no', 42], + ['kn', 43], + ['bh', 44], + ['to', 45], + ['fi', 46], + ['id', 47], + ['mu', 48], + ['se', 49], + ['tt', 50], + ['my', 51], + ['pa', 52], + ['pw', 53], + ['tv', 54], + ['mh', 55], + ['cl', 56], + ['th', 57], + ['gd', 58], + ['ee', 59], + ['ag', 60], + ['tw', 61], + ['bb', 62], + ['it', 63], + ['mt', 64], + ['vu', 65], + ['sg', 66], + ['cy', 67], + ['lk', 68], + ['km', 69], + ['fj', 70], + ['ru', 71], + ['va', 72], + ['sm', 73], + ['kz', 74], + ['az', 75], + ['tj', 76], + ['ls', 77], + ['uz', 78], + ['ma', 79], + ['co', 80], + ['tl', 81], + ['tz', 82], + ['ar', 83], + ['sa', 84], + ['pk', 85], + ['ye', 86], + ['ae', 87], + ['ke', 88], + ['pe', 89], + ['do', 90], + ['ht', 91], + ['pg', 92], + ['ao', 93], + ['kh', 94], + ['vn', 95], + ['mz', 96], + ['cr', 97], + ['bj', 98], + ['ng', 99], + ['ir', 100], + ['sv', 101], + ['sl', 102], + ['gw', 103], + ['hr', 104], + ['bz', 105], + ['za', 106], + ['cf', 107], + ['sd', 108], + ['cd', 109], + ['kw', 110], + ['de', 111], + ['be', 112], + ['ie', 113], + ['kp', 114], + ['kr', 115], + ['gy', 116], + ['hn', 117], + ['mm', 118], + ['ga', 119], + ['gq', 120], + ['ni', 121], + ['lv', 122], + ['ug', 123], + ['mw', 124], + ['am', 125], + ['sx', 126], + ['tm', 127], + ['zm', 128], + ['nc', 129], + ['mr', 130], + ['dz', 131], + ['lt', 132], + ['et', 133], + ['er', 134], + ['gh', 135], + ['si', 136], + ['gt', 137], + ['ba', 138], + ['jo', 139], + ['sy', 140], + ['mc', 141], + ['al', 142], + ['uy', 143], + ['cnm', 144], + ['mn', 145], + ['rw', 146], + ['so', 147], + ['bo', 148], + ['cm', 149], + ['cg', 150], + ['eh', 151], + ['rs', 152], + ['me', 153], + ['tg', 154], + ['la', 155], + ['af', 156], + ['ua', 157], + ['sk', 158], + ['jk', 159], + ['bg', 160], + ['qa', 161], + ['li', 162], + ['at', 163], + ['sz', 164], + ['hu', 165], + ['ro', 166], + ['ne', 167], + ['lu', 168], + ['ad', 169], + ['ci', 170], + ['lr', 171], + ['bn', 172], + ['iq', 173], + ['ge', 174], + ['gm', 175], + ['ch', 176], + ['td', 177], + ['kv', 178], + ['lb', 179], + ['dj', 180], + ['bi', 181], + ['sr', 182], + ['il', 183], + ['ml', 184], + ['sn', 185], + ['gn', 186], + ['zw', 187], + ['pl', 188], + ['mk', 189], + ['py', 190], + ['by', 191], + ['cz', 192], + ['bf', 193], + ['na', 194], + ['ly', 195], + ['tn', 196], + ['bt', 197], + ['md', 198], + ['ss', 199], + ['bw', 200], + ['bs', 201], + ['nz', 202], + ['cu', 203], + ['ec', 204], + ['au', 205], + ['ve', 206], + ['sb', 207], + ['mg', 208], + ['is', 209], + ['eg', 210], + ['kg', 211], + ['np', 212] + ] + } as Highcharts.SeriesMapOptions, + { + // Specify points using lat/lon + type: 'mappoint', + name: 'Canada cities', + marker: { + radius: 5, + fillColor: 'tomato' }, - allAreas: false, data: [ - ['fo', 0], - ['um', 1], - ['us', 2], - ['jp', 3], - ['sc', 4], - ['in', 5], - ['fr', 6], - ['fm', 7], - ['cn', 8], - ['pt', 9], - ['sw', 10], - ['sh', 11], - ['br', 12], - ['ki', 13], - ['ph', 14], - ['mx', 15], - ['es', 16], - ['bu', 17], - ['mv', 18], - ['sp', 19], - ['gb', 20], - ['gr', 21], - ['as', 22], - ['dk', 23], - ['gl', 24], - ['gu', 25], - ['mp', 26], - ['pr', 27], - ['vi', 28], - ['ca', 29], - ['st', 30], - ['cv', 31], - ['dm', 32], - ['nl', 33], - ['jm', 34], - ['ws', 35], - ['om', 36], - ['vc', 37], - ['tr', 38], - ['bd', 39], - ['lc', 40], - ['nr', 41], - ['no', 42], - ['kn', 43], - ['bh', 44], - ['to', 45], - ['fi', 46], - ['id', 47], - ['mu', 48], - ['se', 49], - ['tt', 50], - ['my', 51], - ['pa', 52], - ['pw', 53], - ['tv', 54], - ['mh', 55], - ['cl', 56], - ['th', 57], - ['gd', 58], - ['ee', 59], - ['ag', 60], - ['tw', 61], - ['bb', 62], - ['it', 63], - ['mt', 64], - ['vu', 65], - ['sg', 66], - ['cy', 67], - ['lk', 68], - ['km', 69], - ['fj', 70], - ['ru', 71], - ['va', 72], - ['sm', 73], - ['kz', 74], - ['az', 75], - ['tj', 76], - ['ls', 77], - ['uz', 78], - ['ma', 79], - ['co', 80], - ['tl', 81], - ['tz', 82], - ['ar', 83], - ['sa', 84], - ['pk', 85], - ['ye', 86], - ['ae', 87], - ['ke', 88], - ['pe', 89], - ['do', 90], - ['ht', 91], - ['pg', 92], - ['ao', 93], - ['kh', 94], - ['vn', 95], - ['mz', 96], - ['cr', 97], - ['bj', 98], - ['ng', 99], - ['ir', 100], - ['sv', 101], - ['sl', 102], - ['gw', 103], - ['hr', 104], - ['bz', 105], - ['za', 106], - ['cf', 107], - ['sd', 108], - ['cd', 109], - ['kw', 110], - ['de', 111], - ['be', 112], - ['ie', 113], - ['kp', 114], - ['kr', 115], - ['gy', 116], - ['hn', 117], - ['mm', 118], - ['ga', 119], - ['gq', 120], - ['ni', 121], - ['lv', 122], - ['ug', 123], - ['mw', 124], - ['am', 125], - ['sx', 126], - ['tm', 127], - ['zm', 128], - ['nc', 129], - ['mr', 130], - ['dz', 131], - ['lt', 132], - ['et', 133], - ['er', 134], - ['gh', 135], - ['si', 136], - ['gt', 137], - ['ba', 138], - ['jo', 139], - ['sy', 140], - ['mc', 141], - ['al', 142], - ['uy', 143], - ['cnm', 144], - ['mn', 145], - ['rw', 146], - ['so', 147], - ['bo', 148], - ['cm', 149], - ['cg', 150], - ['eh', 151], - ['rs', 152], - ['me', 153], - ['tg', 154], - ['la', 155], - ['af', 156], - ['ua', 157], - ['sk', 158], - ['jk', 159], - ['bg', 160], - ['qa', 161], - ['li', 162], - ['at', 163], - ['sz', 164], - ['hu', 165], - ['ro', 166], - ['ne', 167], - ['lu', 168], - ['ad', 169], - ['ci', 170], - ['lr', 171], - ['bn', 172], - ['iq', 173], - ['ge', 174], - ['gm', 175], - ['ch', 176], - ['td', 177], - ['kv', 178], - ['lb', 179], - ['dj', 180], - ['bi', 181], - ['sr', 182], - ['il', 183], - ['ml', 184], - ['sn', 185], - ['gn', 186], - ['zw', 187], - ['pl', 188], - ['mk', 189], - ['py', 190], - ['by', 191], - ['cz', 192], - ['bf', 193], - ['na', 194], - ['ly', 195], - ['tn', 196], - ['bt', 197], - ['md', 198], - ['ss', 199], - ['bw', 200], - ['bs', 201], - ['nz', 202], - ['cu', 203], - ['ec', 204], - ['au', 205], - ['ve', 206], - ['sb', 207], - ['mg', 208], - ['is', 209], - ['eg', 210], - ['kg', 211], - ['np', 212] - ] - } as Highcharts.SeriesMapOptions, - { - // Specify points using lat/lon - type: 'mappoint', - name: 'Canada cities', - marker: { - radius: 5, - fillColor: 'tomato' + { + name: 'Vancouver', + lat: 49.246292, + lon: -123.116226 }, - data: [ - { - name: 'Vancouver', - lat: 49.246292, - lon: -123.116226 - }, - { - name: 'Quebec City', - lat: 46.829853, - lon: -71.254028 - }, - { - name: 'Yellowknife', - lat: 62.4540, - lon: -114.3718 - } - ] - } as Highcharts.SeriesMappointOptions] - } - }) - ) + { + name: 'Quebec City', + lat: 46.829853, + lon: -71.254028 + }, + { + name: 'Yellowknife', + lat: 62.4540, + lon: -114.3718 + } + ] + } as Highcharts.SeriesMappointOptions] + } + }) } From a5c097b8b56d9632e1ff6cae07911e4c906d5720 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 23:43:47 +0100 Subject: [PATCH 75/94] correct type --- src/app/map-chart/map-chart.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts index 897ed4c..47532e4 100644 --- a/src/app/map-chart/map-chart.component.ts +++ b/src/app/map-chart/map-chart.component.ts @@ -20,11 +20,11 @@ import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-an export class MapChartComponent { private http = inject(HttpClient); - worldMap = toSignal(this.http.get('/highcharts/world.geo.json')); - chartMap = computed(() => { + worldMap = toSignal(this.http.get('/highcharts/world.geo.json')); + chartMap = computed(() => { return { chart: { - map: this.worldMap() as any, + map: this.worldMap(), // proj4: proj4 }, title: { From dd1617a91c48e86ebd4575d78240d45663ed21dc Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 23:49:37 +0100 Subject: [PATCH 76/94] rename vars and add comments --- .../src/lib/highcharts-chart.directive.spec.ts | 2 +- .../src/lib/highcharts-chart.directive.ts | 1 + .../src/lib/highcharts-chart.provider.ts | 4 ++-- .../src/lib/highcharts-chart.service.spec.ts | 8 ++++---- .../src/lib/highcharts-chart.service.ts | 4 ++-- highcharts-angular/src/lib/highcharts-chart.token.ts | 4 ++-- highcharts-angular/src/lib/types.ts | 11 ++++++----- 7 files changed, 18 insertions(+), 16 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.spec.ts b/highcharts-angular/src/lib/highcharts-chart.directive.spec.ts index 3d116db..3362e0b 100644 --- a/highcharts-angular/src/lib/highcharts-chart.directive.spec.ts +++ b/highcharts-angular/src/lib/highcharts-chart.directive.spec.ts @@ -1,5 +1,5 @@ import { TestBed } from '@angular/core/testing'; -import { Component, ComponentRef, DebugElement } from '@angular/core'; +import { Component, DebugElement } from '@angular/core'; import { By } from '@angular/platform-browser'; import { of } from 'rxjs'; import { HighchartsChartDirective } from './highcharts-chart.directive'; diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.ts b/highcharts-angular/src/lib/highcharts-chart.directive.ts index 273c937..967df68 100644 --- a/highcharts-angular/src/lib/highcharts-chart.directive.ts +++ b/highcharts-angular/src/lib/highcharts-chart.directive.ts @@ -122,6 +122,7 @@ export class HighchartsChartDirective { constructor() { + // should stop loading on the server side for SSR if (this.platformId && isPlatformServer(this.platformId)) { return; } diff --git a/highcharts-angular/src/lib/highcharts-chart.provider.ts b/highcharts-angular/src/lib/highcharts-chart.provider.ts index 041f755..57b2a05 100644 --- a/highcharts-angular/src/lib/highcharts-chart.provider.ts +++ b/highcharts-angular/src/lib/highcharts-chart.provider.ts @@ -1,6 +1,6 @@ import { EnvironmentProviders, makeEnvironmentProviders, Provider } from '@angular/core'; import { HIGHCHARTS_LOADER, HIGHCHARTS_CONFIG, HIGHCHARTS_ROOT_MODULES, HIGHCHARTS_OPTIONS } from './highcharts-chart.token'; -import { Chart, moduleFactory, HighchartsConfig, PartialHighchartsConfig } from './types'; +import { Chart, ModuleFactory, HighchartsConfig, PartialHighchartsConfig } from './types'; export function providePartialHighChart(config: PartialHighchartsConfig): Provider { @@ -15,7 +15,7 @@ export function provideHighChartOptions(options: Chart['options']) { return makeEnvironmentProviders([{ provide: HIGHCHARTS_OPTIONS, useValue: options } ]); } -export function provideHighChartRootModules(...modules: moduleFactory[]) { +export function provideHighChartRootModules(...modules: ModuleFactory[]) { return makeEnvironmentProviders([{ provide: HIGHCHARTS_ROOT_MODULES, useValue: modules }]); } diff --git a/highcharts-angular/src/lib/highcharts-chart.service.spec.ts b/highcharts-angular/src/lib/highcharts-chart.service.spec.ts index 4bf90db..eeb1853 100644 --- a/highcharts-angular/src/lib/highcharts-chart.service.spec.ts +++ b/highcharts-angular/src/lib/highcharts-chart.service.spec.ts @@ -1,13 +1,13 @@ import { TestBed } from '@angular/core/testing'; import { HighchartsChartService } from './highcharts-chart.service'; import { HIGHCHARTS_LOADER, HIGHCHARTS_OPTIONS, HIGHCHARTS_ROOT_MODULES } from './highcharts-chart.token'; -import { Chart, moduleFactory } from './types'; +import { Chart, ModuleFactory } from './types'; describe('HighchartsChartService', () => { let service: HighchartsChartService; let mockLoader: Promise; let mockGlobalOptions: Chart['options']; - let mockGlobalModules: moduleFactory[]; + let mockGlobalModules: ModuleFactory[]; beforeEach(() => { mockLoader = Promise.resolve({ @@ -59,7 +59,7 @@ describe('HighchartsChartService', () => { }); it('should load partialConfig modules if provided', async () => { - const mockPartialModules: moduleFactory[] = [ + const mockPartialModules: ModuleFactory[] = [ jasmine.createSpy('partialModule1'), jasmine.createSpy('partialModule2'), ]; @@ -76,7 +76,7 @@ describe('HighchartsChartService', () => { describe('With not provided Value', () => { let service: HighchartsChartService; let mockLoader: Promise; - let mockGlobalModules: moduleFactory[]; + let mockGlobalModules: ModuleFactory[]; beforeEach(() => { mockLoader = Promise.resolve({ diff --git a/highcharts-angular/src/lib/highcharts-chart.service.ts b/highcharts-angular/src/lib/highcharts-chart.service.ts index b50765b..f1d1e4f 100644 --- a/highcharts-angular/src/lib/highcharts-chart.service.ts +++ b/highcharts-angular/src/lib/highcharts-chart.service.ts @@ -1,7 +1,7 @@ import { inject, Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { HIGHCHARTS_ROOT_MODULES, HIGHCHARTS_LOADER, HIGHCHARTS_OPTIONS } from './highcharts-chart.token'; -import { Chart, moduleFactory, PartialHighchartsConfig } from './types'; +import { Chart, ModuleFactory, PartialHighchartsConfig } from './types'; @Injectable({providedIn: 'root'}) export class HighchartsChartService { @@ -10,7 +10,7 @@ export class HighchartsChartService { private source: Promise = inject(HIGHCHARTS_LOADER); private globalOptions: Chart['options'] = inject(HIGHCHARTS_OPTIONS, { optional: true }); - private globalModules: moduleFactory[] = inject(HIGHCHARTS_ROOT_MODULES, { optional: true }); + private globalModules: ModuleFactory[] = inject(HIGHCHARTS_ROOT_MODULES, { optional: true }); load(partialConfig?: PartialHighchartsConfig) { this.source.then(source => { diff --git a/highcharts-angular/src/lib/highcharts-chart.token.ts b/highcharts-angular/src/lib/highcharts-chart.token.ts index fa12529..f313572 100644 --- a/highcharts-angular/src/lib/highcharts-chart.token.ts +++ b/highcharts-angular/src/lib/highcharts-chart.token.ts @@ -1,7 +1,7 @@ import { InjectionToken } from '@angular/core'; -import { Chart, moduleFactory, PartialHighchartsConfig } from './types' +import { Chart, ModuleFactory, PartialHighchartsConfig } from './types' export const HIGHCHARTS_LOADER = new InjectionToken>('HIGHCHARTS_LOADER'); -export const HIGHCHARTS_ROOT_MODULES = new InjectionToken('HIGHCHARTS_ROOT_MODULES'); +export const HIGHCHARTS_ROOT_MODULES = new InjectionToken('HIGHCHARTS_ROOT_MODULES'); export const HIGHCHARTS_OPTIONS = new InjectionToken('HIGHCHARTS_OPTIONS'); export const HIGHCHARTS_CONFIG = new InjectionToken('HIGHCHARTS_CONFIG'); diff --git a/highcharts-angular/src/lib/types.ts b/highcharts-angular/src/lib/types.ts index 9ea681a..658627b 100644 --- a/highcharts-angular/src/lib/types.ts +++ b/highcharts-angular/src/lib/types.ts @@ -1,6 +1,10 @@ import type Highcharts from 'highcharts'; import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; +export type ChartConstructorType = 'chart' | 'ganttChart' | 'stockChart' | 'mapChart'; + +export type ModuleFactory = (highcharts: Chart['highcharts']) => void; + export interface Chart { options: Highcharts.Options | HighchartsESM.Options, update?: boolean, @@ -8,15 +12,12 @@ export interface Chart { constructorChart?: Function; } -export type ChartConstructorType = 'chart' | 'ganttChart' | 'stockChart' | 'mapChart'; -export type moduleFactory = (highcharts: Chart['highcharts']) => void; - export interface PartialHighchartsConfig { - modules?: moduleFactory[]; + modules?: ModuleFactory[]; } export interface HighchartsConfig { instance?: Promise; options?: Chart['options']; - modules?: moduleFactory[]; + modules?: ModuleFactory[]; } From 2cfe94612d90902d5beb7ef1eef1e0d0925902de Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sat, 7 Dec 2024 23:50:36 +0100 Subject: [PATCH 77/94] rename readme v4 --- README.md => README_V4.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README.md => README_V4.md (100%) diff --git a/README.md b/README_V4.md similarity index 100% rename from README.md rename to README_V4.md From 654b1a29a146e7d192fa0988c0930f423d45590e Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 8 Dec 2024 01:42:58 +0100 Subject: [PATCH 78/94] update readme.md --- README.md | 536 +++++++++++++++++++++++++++ highcharts-angular/src/public_api.ts | 1 + package.json | 4 +- 3 files changed, 540 insertions(+), 1 deletion(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..9082787 --- /dev/null +++ b/README.md @@ -0,0 +1,536 @@ +# Highcharts Angular + +Official minimal Highcharts integration for Angular. + +## Table of Contents +1. [Getting Started](#getting-started) + 1. [General Prerequisites](#general-prerequisites) + 2. [Installing](#installing) + 3. [Usage](#usage) + 4. [SSR Support](#ssr-support) + 5. [Angular Elements and `useHTML`](#angular-elements-and-usehtml) +2. [Options Details](#options-details) +3. [Chart Instance](#chart-instance) +4. [Highcharts Partial Loading on the Component Level](#highcharts-partial-loading-on-the-component-level) + 1. [Loading a Module & Plugin](#to-load-a-module--plugins) + 2. [Loading a Map for Highcharts Maps](#to-load-a-map-for-highcharts-maps) + 3. [Loading a Map for Highcharts Stock](#to-load-a-stock-for-highcharts) + 4. [Loading a Wrapper](#to-load-a-wrapper) +5. [Demo App](#demo-app) + 1. [Play with the App](#play-with-the-app) + 2. [Files to Modify](#files-to-play-with) +6. [Online Examples](#online-examples) +7. [Release](#release) +8. [Help and FAQ](#help-and-faq) + +--- + +## Getting Started + +### General Prerequisites + +Ensure that **Node.js**, **npm**, and **Angular** are installed and up to date. Refer to the compatibility table below for the required versions: + +| Highcharts Angular Version | Node.js | Angular | Highcharts | +|----------------------------|-----------|-----------|--------------| +| 5.0.0 | >=18.19 | >=19.0.0 | >=11.0.0 | +| 4.0.0 | >=16.14 | >=16.0.0 | >=11.0.0 | +| 3.1.2 | >=14.13 | >=15.0.0 | >=10.3.3 | +| 3.0.0 | >=14.13 | >=9.0.0 | >=8.0.0 | +| <2.10.0 | >=6.10.2 | >=6.0.0 | >=6.0.0 | + +--- + +### Installing + +Install the `highcharts-angular` package along with the [highcharts](https://www.highcharts.com/docs/getting-started/install-from-npm) dependency: + +```bash +npm install highcharts-angular highcharts --save +``` + +Then, configure the Highcharts provider in your app.config.ts file: + +```ts +import { provideHighCharts } from 'highcharts-angular'; +import ExportingModule from 'highcharts/modules/exporting'; +import SunsetTheme from 'highcharts/themes/sunset'; + +export const appConfig: ApplicationConfig = { + providers: [ + // Other providers + provideHighCharts({ + // Optional: Define the Highcharts instance + // instance: import('highcharts'), + + // Global options for all charts + options: { + title: { + style: { + color: 'tomato' + } + }, + legend: { + enabled: false + } + }, + + // Modules for additional functionality + modules: [ExportingModule, SunsetTheme] + }) + ] +}; +``` + +The `provideHighCharts` function allows you to define global settings for all charts within your project. + +Here is the configuration interface for reference: + +```ts +export interface HighchartsConfig { + instance?: Promise; + options?: Highcharts.Options; + modules?: ModuleFactory[]; +} +``` + +### Key Notes: +- The `instance` property allows you to specify the Highcharts instance dynamically. +- The `options` property is used to define global chart configurations applied across all charts. +- The `modules` array enables you to include Highcharts modules (e.g., exporting, accessibility) or custom themes. + +### Usage + +You can use Highcharts in your Angular application either as a **Component** or a **Directive**. Below are the usage examples for both approaches: + +--- + +#### 1. Using the Component + +In your `app.component.ts`, import the required `HighchartsChartComponent` and other relevant types at the top of the file: + +```ts +import { Component } from '@angular/core'; +import { HighchartsChartComponent, ChartConstructorType } from 'highcharts-angular'; + +@Component({ + template: ` + + `, + styles: [`.chart { width: 100%; height: 400px; display: block; }`], + imports: [HighchartsChartComponent] +}) +export class AppComponent { + chartOptions: Highcharts.Options = { ... }; // Required + chartConstructor: ChartConstructorType = 'chart'; // Optional, defaults to 'chart' + chartCallback: Highcharts.ChartCallbackFunction = function (chart) { ... }; // Optional, defaults to null + updateFlag: boolean = false; // Optional + oneToOneFlag: boolean = true; // Optional, defaults to false +} +``` + +#### 2. Using the Directive + +In your `app.component.ts`, import the `HighchartsChartDirective` and other relevant types at the top of the file: + + +```ts +import {Component} from '@angular/core'; +import { HighchartsChartDirective, ChartConstructorType } from 'highcharts-angular'; + +@Component({ + template: ` +
+ `, + styles: [`.chart { width: 100%; height: 400px; display: block; }`], + imports: [HighchartsChartDirective] +}) +export class AppComponent { + chartOptions: Highcharts.Options = { ... }; // Required + chartConstructor: ChartConstructorType = 'chart'; // Optional, defaults to 'chart' + chartCallback: Highcharts.ChartCallbackFunction = function (chart) { ... }; // Optional, defaults to null + updateFlag: boolean = false; // Optional + oneToOneFlag: boolean = true; // Optional, defaults to false +} +``` + +#### 3. Example + +This is the minimum example you can start with: + +```ts +import { Component } from '@angular/core'; +import { HighchartsChartDirective } from 'highcharts-angular'; + +@Component({ + template: ` +
+ `, + styles: [`.chart { width: 100%; height: 400px; display: block; }`], + imports: [HighchartsChartDirective] +}) +export class AppComponent { + chartOptions: Highcharts.Options = { + series: [{ + data: [1, 2, 3], + type: 'line' + }] + }; +} +``` + +Build and run your Angular app to see a basic line chart. + +Used options are explained [below](#options-details). + +### SSR Support + +Both the component and directive in this library are fully compatible with Angular Universal (SSR). + +In SSR, the code runs twice: once on the server (in an environment without a window object) and once in the browser. Since Highcharts is tightly integrated with browser events, it should not run on the server-side. But don’t worry—we’ve already handled this case for you! 😉 + +Our showcase application includes an example of SSR integration. You can try it by running: +``` cli +ng serve my-ssr-app --open +``` + +### Angular Elements and useHTML + +First, install angular elements: + +```cli +npm install @angular/elements --save +``` + +Include in main.ts file your element tag inside allowedTags and [element properties](https://angular.io/guide/elements#mapping) inside allowedAttributes: + +```ts +if (Highcharts && Highcharts.AST) { + Highcharts.AST.allowedTags.push('translation-element'); + Highcharts.AST.allowedAttributes.push('translation-key'); +} +``` + +Define your element in the constructor of the component that will use it: + +```ts +private defineTranslationElement() { + if (isNil(customElements.get('translation-element'))) { + const translationElement = createCustomElement(TranslationComponent, {injector: this.injector}); + customElements.define('translation-element', translationElement); + } +} +``` + +Then, create the element, set properties and use it in the chart: + +```ts +const translationEl: NgElement & WithProperties = document.createElement(translationElementTag); +translationEl.setAttribute('translation-key', 'shared.title'); + +const chartOptions: Highcharts.Options = { + title: { + text: translationEl.outerHTML, + useHTML: true, + }, + ... +} +``` + +For a more detailed view take a look at the [Online Examples - Angular Elements and useHTML](#online-examples) + +## Options details + +| Parameter | Type | Required | Defaults | Description | +| --------------------- | -------------------- | -------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `[constructorType]` | `ChartConstructorType` | No | `'chart'` | A string for the [constructor method](https://www.highcharts.com/docs/getting-started/your-first-chart). Official constructors include:
- `'chart'` for Highcharts charts
- `'stockChart'` for Highcharts Stock
- `'mapChart'` for Highcharts Maps
- `'ganttChart'` for Highcharts Gantt

Note that `'stockChart'`, `'mapChart'`, and `'ganttChart'` require loading the appropriate package or module. | +| `[options]` | `Object` | Yes | `-` | The chart options as described in the [Highcharts API reference](http://api.highcharts.com/highcharts). A minimal working object for basic testing is `{ series:[{ data:[1, 2] }] }`. | +| `[(update)]` | `Boolean` | No | `-` | A boolean to trigger a chart update. Angular does not detect nested changes in objects passed to a component. Set the corresponding variable (`updateFlag` in the example) to `true`, and after the update is done, it will asynchronously change back to `false` by the Highcharts Angular component. | +| `[oneToOne]` | `Boolean` | No | `false` | The `oneToOne` parameter for [updates](https://api.highcharts.com/class-reference/Highcharts.Chart#update). When `true`, the `series`, `xAxis`, and `yAxis` collections will be updated one to one, and items will be added or removed to match the updated options. For example, if a chart has **two** series, calling `chart.update` with a configuration containing **three** series will add **one**. Similarly, calling `chart.update` with **one** series will remove **one**. Setting an empty series array removes all series, while leaving out the `series` property leaves them untouched. If the series have `id`s, new series options will be matched by `id`, and the remaining ones will be removed.

This option is demonstrated in [the demo](#demo-app). Try setting new chart options with different numbers of series in the [textarea input](https://github.com/highcharts/highcharts-angular/blob/36e158e684b5823e1b1bd1cedf75548022eba1a9/src/app/app.component.html#L7) to see it in action. | +| `[callbackFunction]` | `Function` | No | `-` | A callback function that is triggered when the chart is created. The first argument will be the created **chart**. The default `this` inside the function will refer to the **chart**. | + +## Chart instance + +A chart instance can be obtained using the following methods: + +* **Chart's callback function** - The `chart` is provided as the first argument (see [demo app](#demo-app) and the first `hcCallback` function). +* **Chart's events** - The context of all [chart's events](https://api.highcharts.com/highcharts/chart.events) functions is the chart instance. +* **Component output `chartInstance`** - Emitted after the chart is created (see [demo app](#demo-app) and the `logChartInstance` function). + +**Note:** If you are obtaining the chart instance from the **[chart's load event](https://api.highcharts.com/highcharts/chart.events.load)** or **chart's callback function**, and you plan to support exporting, the function will run again when the chart is exported. This is because a separate chart is created for export. To distinguish between the main chart and the export chart, you can check `chart.renderer.forExport`. It will be set to `true` for the export chart and `undefined` for the main chart. + +# Highcharts Partial Loading on the Component Level + +A Highcharts instance is optionally initialized with **[modules](#to-load-a-module)**, **[plugins](#to-load-a-plugin)**, **[maps](#to-load-a-map-for-Highcharts-Maps)**, **[wrappers](#to-load-a-wrapper)**, and set **[global options](#to-use-setoptions)** using **[`setOptions`](https://www.highcharts.com/docs/getting-started/how-to-set-options#2)**. **The core is required.** + +**Note:** The Highcharts instance is shared across components in an Angular app, meaning that loaded modules will affect all charts. + +With this v5, you can set provide extra modules or plugins on demand to your chart at the component level: + +## Example + +### To load a module + plugins + +A module is a Highcharts official addon - including Highcharts Stock [Technical Indicators](https://www.highcharts.com/docs/stock/technical-indicator-series), style [themes](https://www.highcharts.com/docs/chart-design-and-style/themes), specialized series types (e.g. [Bullet](https://www.highcharts.com/docs/chart-and-series-types/bullet-chart), [Venn](https://www.highcharts.com/docs/chart-and-series-types/venn-series)). + +After importing Highcharts, Highcharts Stock, or Highcharts Maps, use `providePartialHighChart` and initialize modules with an array of Highcharts factory functions. + +A plugin is a third-party/community-made Highcharts addon (plugins are listed in the [Highcharts plugin registry](https://www.highcharts.com/blog/add-ons/)). First, make sure that a plugin supports loading over NPM and load the required files. For example, [Custom-Events](https://www.npmjs.com/package/highcharts-custom-events) supports NPM loading, so after installing the package you can initialize it like: + +If a plugin doesn't support loading through NPM, treat it as a wrapper - see instructions below. + +If a lack of TypeScript definitions `d.ts` is showing as an error - see [Solving problems](https://www.highcharts.com/docs/advanced-chart-features/highcharts-typescript-declarations) section of Highcharts documentation for TypeScript usage. + +```ts +import { Component } from '@angular/core'; +import { HighchartsChartDirective } from 'highcharts-angular'; +// Load core +import HC_gantt from 'highcharts/modules/gantt'; +// Load core module +import HC_exporting from 'highcharts/modules/exporting'; +// Load plugins +import * as HC_customEvents from 'highcharts-custom-events'; + +@Component({ + template: ` +
+ `, + styles: [`.chart { width: 100%; height: 400px; display: block; }`], + imports: [HighchartsChartDirective], + providers: [providePartialHighChart({ modules: [HC_gantt, HC_exporting, HC_customEvents] })], +}) +export class GanttComponent { + chartOptions: Highcharts.Options = { + series: [{ + data: [1, 2, 3], + type: 'line' + }] + }; +} +``` + +### To load a map for Highcharts Maps + +Official map collection is published and [here](https://www.npmjs.com/package/@highcharts/map-collection#install-from-npm) are basic instructions for loading a map. A full example can also be found in the [demo app](#demo-app). + +```ts +import { Component } from '@angular/core'; +import { HighchartsChartDirective } from 'highcharts-angular'; +import HC_map from 'highcharts/modules/map'; + +@Component({ + template: ` +
+ `, + styles: [`.chart { width: 100%; height: 400px; display: block; }`], + imports: [HighchartsChartDirective], + providers: [providePartialHighChart({ modules: [HC_map] })], +}) +export class MapComponent { + chartOptions: Highcharts.Options = { + series: [{ + data: [1, 2, 3], + type: 'line' + }] + }; +} +``` + +### To load a stock for Highcharts + +```ts +import { Component } from '@angular/core'; +import { HighchartsChartDirective } from 'highcharts-angular'; +import HC_stock from 'highcharts/modules/stock'; + +@Component({ + template: ` +
+ `, + styles: [`.chart { width: 100%; height: 400px; display: block; }`], + imports: [HighchartsChartDirective], + providers: [providePartialHighChart({ modules: [HC_stock] })], +}) +export class StockComponent { + chartOptions: Highcharts.Options = { + series: [{ + data: [1, 2, 3], + type: 'line' + }] + }; +} +``` + +### To load a wrapper + +A wrapper is a [custom extension](https://www.highcharts.com/docs/extending-highcharts/extending-highcharts) for Highcharts. To load a wrapper in the same way as a module, save it as a JavaScript file and add the following code to the beginning and end of the file: + +```js +(function (factory) { + if (typeof module === 'object' && module.exports) { + module.exports = factory; + } else { + factory(Highcharts); + } +}(function (Highcharts) { + +... +/* wrapper code */ +... + +})); +``` + +Next, you will be loading a local `.js` file, so add `allowJs: true` to the `tsconfig.json` in your app: + +```json +{ + "compilerOptions": { + "allowJs": true + } +} +``` + +The wrapper is now ready to be imported into your app. Use `require` instead of `import` to prevent TS5055 errors: + +```ts +import * as Highcharts from 'highcharts'; +require('./relative-path-to-the-wrapper-file/wrapper-file-name')(Highcharts); +``` + +Where `relative-path-to-the-wrapper-file` is the relative path (from the module importing the wrapper) to the wrapper file, and `wrapper-file-name` is the name of the wrapper file. + +If TypeScript definitions (`d.ts`) are missing and causing errors, see the [Solving problems](https://www.highcharts.com/docs/advanced-chart-features/highcharts-typescript-declarations) section of the Highcharts documentation for TypeScript usage. + +## Demo app + +Download (or clone) the contents of the **[highcharts-angular](https://github.com/highcharts/highcharts-angular)** GitHub repository. +The demo app does not rely on external dependencies but instead builds the `highcharts-angular` package, so it's necessary to run `npm start` to generate this package. + +In your system console, in the main repo folder, run: + +```cli +npm install +``` + +1. Start Default: +```cli +npm start +``` + +2. Start with SSR: +```cli +npm start:ssr +``` + +The command `npm start` will launch the default app, while `npm start:ssr` will start the server-side rendering (SSR) version. Both versions can be accessed at [http://localhost:4200/](http://localhost:4200/) in your default browser. + +To open the app on a different port (e.g., `12345`), use: + +```cli +npm start -- --port 12345 +``` + +### Play with the app + +Keep the console running, and modify files — after saving, the app will automatically rebuild and refresh in the localhost preview. + +### Files to play with + +* **app.component.ts** (located in `src\app`) + +This file contains the main Angular component, which utilizes different components like *line-chart*, *gantt-chart*, *map-chart*, and *stock-chart*. + + +## Online examples + +* [Basic line](https://stackblitz.com/edit/highcharts-angular-line) +* [Stock](https://stackblitz.com/edit/highcharts-angular-stock-chart) +* [Stock + indicators](https://stackblitz.com/edit/highcharts-angular-stock-with-indicators) +* [Stock + GUI](https://stackblitz.com/edit/highcharts-angular-stock-tools-gui) +* [Map](https://stackblitz.com/edit/highcharts-angular-world-map) +* [Gantt](https://stackblitz.com/edit/highcharts-angular-gantt-chart) +* [Map + mapppoints with lat/lon](https://stackblitz.com/edit/highcharts-angular-mappoint-lat-lon) +* [Map + mapppoints with proj4](https://stackblitz.com/edit/highcharts-angular-map-with-proj4) +* [Optimal way to update](https://stackblitz.com/edit/highcharts-angular-update-optimal-way) +* [Data from the service](https://stackblitz.com/edit/highcharts-angular-data-from-a-service) +* [Applying a custom plugin/wrap](https://stackblitz.com/edit/highcharts-angular-a-custom-plugin) +* [Property `XXX` does not exist on type `YYY`](https://stackblitz.com/edit/highcharts-angular-property-xxx-doesnt-exist) +* [Using portals to render an angular component within a chart](https://stackblitz.com/edit/highcharts-angular-portals) +* [Angular Elements and useHTML](https://stackblitz.com/~/github.com/karolkolodziej/highcharts-angular-elements) + +## Release + +Using Angular CLI v19, the library must be manually rebuilt on each change in order to reflect in the demo app. + +Run the following command on each change to the `highcharts-chart.directive.ts` file: + +```cli +npm run build +``` + +If you are running the demo app in another terminal window when you rebuild the +library, the changes should be reflected in your browser (note: you may need to +refresh the browser a second time after the live reload in order to see the change). + +For CHANGELOG.md update use : +```cli +npm run release +``` + +## Help and FAQ + +For technical support please contact [Highcharts technical support](https://www.highcharts.com/support). + +For TypeScript problems with Highcharts first see [Highcharts documentation for TypeScript usage](https://www.highcharts.com/docs/advanced-chart-features/highcharts-typescript-declarations). + +### FAQ: + +#### How to add and use indicators? + +Add [indicators](https://www.highcharts.com/docs/chart-and-series-types/technical-indicator-series) as any other module. +[Live demo](https://stackblitz.com/edit/highcharts-angular-stock-with-indicators) + +#### How to add and use themes? + +Add [themes](https://www.highcharts.com/docs/chart-design-and-style/themes) as any other module. +See the [demo app](#demo-app) in this repository for an example. + +More info about custom themes in [Highcharts general documentation](https://www.highcharts.com/docs/chart-design-and-style/custom-themes-in-styled-mode). + +#### I have a general issue with Highcharts and TypeScript + +The correct repository to report such issues is [main Highcharts repository](https://github.com/highcharts/highcharts/issues). + +#### Synchronized Charts Angular demo + +Based on original Highcharts demo for [Synchronized charts](https://www.highcharts.com/demo/synchronized-charts). + +Additionally added class based sync between charts - [demo](https://stackblitz.com/edit/highcharts-angular-synced-charts). + +#### Property `XXX` does not exist on type `YYY` + +It is happening when you are trying to use non-existing property or one of our internal properties that are not publicly available for example `axis.dataMin`. To fix that you need to create your own type that will extend the default Highcharts one with the new properties. Then all you need to do is to cast the selected option / to the extended type - [demo](https://stackblitz.com/edit/highcharts-angular-property-xxx-doesnt-exist). + +#### How to use Highcharts Maps with the proj4? + +Install the `proj4` library and its types `@types/proj4`. Then pass it to `chartOptions.chart.proj4` property. See the [demo app](#demo-app) in this repository or [live demo](https://stackblitz.com/edit/highcharts-angular-map-with-proj4) example. + +#### I want to render angular component in the tooltip/axis formatter + +To render angular component within the chart you can use the angular [portals](https://material.angular.io/cdk/portal/overview) - [demo](https://stackblitz.com/edit/highcharts-angular-portals) diff --git a/highcharts-angular/src/public_api.ts b/highcharts-angular/src/public_api.ts index a1d2510..c4f9103 100644 --- a/highcharts-angular/src/public_api.ts +++ b/highcharts-angular/src/public_api.ts @@ -8,3 +8,4 @@ export * from './lib/highcharts-chart.directive'; export * from './lib/highcharts-chart.token'; export * from './lib/highcharts-chart.provider'; export * from './lib/highcharts-chart.service'; +export * from './lib/types'; diff --git a/package.json b/package.json index 87430f7..f1a9c42 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,12 @@ "scripts": { "ng": "ng", "serve": "ng serve my-app --open", - "serve:ssr": "node dist/my-ssr-app/server/server.mjs", + "serve:ssr": "ng serve my-ssr-app --open", "start": "node tasks/build.js && npm run serve", + "start:ssr": "node tasks/build.js && npm run serve:ssr", "build": "node tasks/build.js", "build:ssr": "ng build my-ssr-app", + "run:ssr": "node dist/my-ssr-app/server/server.mjs", "test": "ng test my-app", "lint": "ng lint highcharts-angular", "release": "cd ./highcharts-angular && standard-version && cd ../ && node tasks/build.js && node tasks/release.js", From e87e1ad002487d33f8fedf7ae9c43c64e69cd5b6 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 8 Dec 2024 01:48:26 +0100 Subject: [PATCH 79/94] update readme.md --- README.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9082787..c2da2dc 100644 --- a/README.md +++ b/README.md @@ -280,7 +280,7 @@ A Highcharts instance is optionally initialized with **[modules](#to-load-a-modu **Note:** The Highcharts instance is shared across components in an Angular app, meaning that loaded modules will affect all charts. -With this v5, you can set provide extra modules or plugins on demand to your chart at the component level: +With this v5, you can provide extra modules or plugins on demand to your chart at the component level: ## Example @@ -409,8 +409,27 @@ Next, you will be loading a local `.js` file, so add `allowJs: true` to the `tsc The wrapper is now ready to be imported into your app. Use `require` instead of `import` to prevent TS5055 errors: ```ts -import * as Highcharts from 'highcharts'; -require('./relative-path-to-the-wrapper-file/wrapper-file-name')(Highcharts); +import { Component } from '@angular/core'; +import { HighchartsChartDirective } from 'highcharts-angular'; +const customWrapper = require('./relative-path-to-the-wrapper-file/wrapper-file-name'); + + +@Component({ + template: ` +
+ `, + styles: [`.chart { width: 100%; height: 400px; display: block; }`], + imports: [HighchartsChartDirective], + providers: [providePartialHighChart({ modules: [customWrapper] })], +}) +export class StockComponent { + chartOptions: Highcharts.Options = { + series: [{ + data: [1, 2, 3], + type: 'line' + }] + }; +} ``` Where `relative-path-to-the-wrapper-file` is the relative path (from the module importing the wrapper) to the wrapper file, and `wrapper-file-name` is the name of the wrapper file. From 1d962a999bf38ea384caf730c40ca4aa43620332 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 8 Dec 2024 22:24:59 +0100 Subject: [PATCH 80/94] add support to Highcharts 12 --- .../src/lib/highcharts-chart.provider.ts | 13 +++++---- .../src/lib/highcharts-chart.service.ts | 29 ++++++++++++------- .../src/lib/highcharts-chart.token.ts | 4 +-- highcharts-angular/src/lib/types.ts | 8 +++-- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.provider.ts b/highcharts-angular/src/lib/highcharts-chart.provider.ts index 57b2a05..f1a86e4 100644 --- a/highcharts-angular/src/lib/highcharts-chart.provider.ts +++ b/highcharts-angular/src/lib/highcharts-chart.provider.ts @@ -1,7 +1,8 @@ import { EnvironmentProviders, makeEnvironmentProviders, Provider } from '@angular/core'; import { HIGHCHARTS_LOADER, HIGHCHARTS_CONFIG, HIGHCHARTS_ROOT_MODULES, HIGHCHARTS_OPTIONS } from './highcharts-chart.token'; -import { Chart, ModuleFactory, HighchartsConfig, PartialHighchartsConfig } from './types'; +import { Chart, ModuleFactoryFunction, HighchartsConfig, PartialHighchartsConfig } from './types'; +const emptyModuleFactoryFunction: ModuleFactoryFunction = () => []; export function providePartialHighChart(config: PartialHighchartsConfig): Provider { return { provide: HIGHCHARTS_CONFIG, useValue: config }; @@ -15,17 +16,17 @@ export function provideHighChartOptions(options: Chart['options']) { return makeEnvironmentProviders([{ provide: HIGHCHARTS_OPTIONS, useValue: options } ]); } -export function provideHighChartRootModules(...modules: ModuleFactory[]) { +export function provideHighChartRootModules(modules: ModuleFactoryFunction) { return makeEnvironmentProviders([{ provide: HIGHCHARTS_ROOT_MODULES, useValue: modules }]); } export function provideHighCharts(config: HighchartsConfig) { - const providers: EnvironmentProviders[] = [provideHighChartInstance(config.instance)]; + const providers: EnvironmentProviders[] = [ + provideHighChartInstance(config.instance), + provideHighChartRootModules(config.modules || emptyModuleFactoryFunction) + ]; if (config.options) { providers.push(provideHighChartOptions(config.options)); } - if (config.modules) { - providers.push(provideHighChartRootModules(...config.modules)); - } return providers; } diff --git a/highcharts-angular/src/lib/highcharts-chart.service.ts b/highcharts-angular/src/lib/highcharts-chart.service.ts index f1d1e4f..a790b72 100644 --- a/highcharts-angular/src/lib/highcharts-chart.service.ts +++ b/highcharts-angular/src/lib/highcharts-chart.service.ts @@ -1,7 +1,7 @@ import { inject, Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { HIGHCHARTS_ROOT_MODULES, HIGHCHARTS_LOADER, HIGHCHARTS_OPTIONS } from './highcharts-chart.token'; -import { Chart, ModuleFactory, PartialHighchartsConfig } from './types'; +import { Chart, ModuleFactoryFunction, PartialHighchartsConfig } from './types'; @Injectable({providedIn: 'root'}) export class HighchartsChartService { @@ -10,20 +10,29 @@ export class HighchartsChartService { private source: Promise = inject(HIGHCHARTS_LOADER); private globalOptions: Chart['options'] = inject(HIGHCHARTS_OPTIONS, { optional: true }); - private globalModules: ModuleFactory[] = inject(HIGHCHARTS_ROOT_MODULES, { optional: true }); + private globalModules: ModuleFactoryFunction = inject(HIGHCHARTS_ROOT_MODULES, { optional: true }); + + private async loadHighchartsWithModules(partialConfig?: PartialHighchartsConfig): Promise { + const Highcharts: Chart['highcharts'] = await this.source; // Ensure Highcharts core is loaded + const version: number = Number(Highcharts['version'].split('.').map((v: string) => v.padStart(2, '0')).join('')); + const results = await Promise.all( + partialConfig?.modules ? [...this.globalModules(), ...partialConfig.modules()] : this.globalModules() + ); + if (version < 120000) { + results.forEach(module => module.default(Highcharts)); + } + // Return the Highcharts instance + return Highcharts; + } + load(partialConfig?: PartialHighchartsConfig) { - this.source.then(source => { + this.loadHighchartsWithModules(partialConfig).then((source: Chart['highcharts']) => { if (this.globalOptions) { source.setOptions(this.globalOptions); } - if (this.globalModules) { - this.globalModules.forEach(module => module(source)); - } - if (partialConfig?.modules) { - partialConfig.modules.forEach(module => module(source)); - } - this.loader.next(source); + // add timeout to make sure the loader has attached all modules + setTimeout(() => this.loader.next(source), 500); }); } } diff --git a/highcharts-angular/src/lib/highcharts-chart.token.ts b/highcharts-angular/src/lib/highcharts-chart.token.ts index f313572..0c69eb7 100644 --- a/highcharts-angular/src/lib/highcharts-chart.token.ts +++ b/highcharts-angular/src/lib/highcharts-chart.token.ts @@ -1,7 +1,7 @@ import { InjectionToken } from '@angular/core'; -import { Chart, ModuleFactory, PartialHighchartsConfig } from './types' +import { Chart, ModuleFactoryFunction, PartialHighchartsConfig } from './types' export const HIGHCHARTS_LOADER = new InjectionToken>('HIGHCHARTS_LOADER'); -export const HIGHCHARTS_ROOT_MODULES = new InjectionToken('HIGHCHARTS_ROOT_MODULES'); +export const HIGHCHARTS_ROOT_MODULES = new InjectionToken('HIGHCHARTS_ROOT_MODULES'); export const HIGHCHARTS_OPTIONS = new InjectionToken('HIGHCHARTS_OPTIONS'); export const HIGHCHARTS_CONFIG = new InjectionToken('HIGHCHARTS_CONFIG'); diff --git a/highcharts-angular/src/lib/types.ts b/highcharts-angular/src/lib/types.ts index 658627b..f81a4cf 100644 --- a/highcharts-angular/src/lib/types.ts +++ b/highcharts-angular/src/lib/types.ts @@ -3,7 +3,9 @@ import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; export type ChartConstructorType = 'chart' | 'ganttChart' | 'stockChart' | 'mapChart'; -export type ModuleFactory = (highcharts: Chart['highcharts']) => void; +export type ModuleFactory = Promise<{Highcharts: Chart['highcharts'], default: (highcharts: Chart['highcharts']) => void}>; + +export type ModuleFactoryFunction = () => ModuleFactory[]; export interface Chart { options: Highcharts.Options | HighchartsESM.Options, @@ -13,11 +15,11 @@ export interface Chart { } export interface PartialHighchartsConfig { - modules?: ModuleFactory[]; + modules?: ModuleFactoryFunction; } export interface HighchartsConfig { instance?: Promise; options?: Chart['options']; - modules?: ModuleFactory[]; + modules?: ModuleFactoryFunction; } From f8e348d4c7f6367da63feeae2791c7f08bb699ed Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 8 Dec 2024 22:26:32 +0100 Subject: [PATCH 81/94] update showcase --- src/app/app.config.ts | 10 +++++++--- src/app/gantt-chart/gantt-chart.component.ts | 3 +-- .../lazy-loading-chart/lazy-loading-chart.component.ts | 3 +-- src/app/line-chart/line-chart.component.ts | 3 +-- src/app/map-chart/map-chart.component.ts | 3 +-- src/app/stock-chart/stock-chart.component.ts | 4 +--- 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 63d0437..ff7948e 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -2,8 +2,6 @@ import {provideHttpClient, withFetch, withInterceptorsFromDi} from '@angular/com import {ApplicationConfig, importProvidersFrom, provideZoneChangeDetection} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import { provideHighCharts } from 'highcharts-angular'; -import ExportingModule from 'highcharts/modules/exporting'; -import SunsetTheme from 'highcharts/themes/sunset'; export const appConfig: ApplicationConfig = { providers: [ @@ -23,7 +21,13 @@ export const appConfig: ApplicationConfig = { } }, // The modules will work for all charts. - modules: [ExportingModule, SunsetTheme] + modules: () => { + return [ + import('highcharts/modules/accessibility'), + import('highcharts/modules/exporting'), + import('highcharts/themes/sunset') + ] + } }) ] }; diff --git a/src/app/gantt-chart/gantt-chart.component.ts b/src/app/gantt-chart/gantt-chart.component.ts index e62386b..8b12d6a 100644 --- a/src/app/gantt-chart/gantt-chart.component.ts +++ b/src/app/gantt-chart/gantt-chart.component.ts @@ -1,5 +1,4 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import HC_gantt from 'highcharts/modules/gantt'; import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; @@ -8,7 +7,7 @@ import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-an templateUrl: './gantt-chart.component.html', styleUrls: ['./gantt-chart.component.css'], imports: [HighchartsChartComponent], - providers: [providePartialHighChart({ modules: [HC_gantt] })], + providers: [providePartialHighChart({ modules: () => [import('highcharts/modules/gantt')] })], changeDetection: ChangeDetectionStrategy.OnPush, }) export class GanttChartComponent { diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts index 20cc21b..b19451b 100644 --- a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts @@ -1,6 +1,5 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import type Highcharts from 'highcharts'; -import HC_stock from 'highcharts/modules/stock'; import { AppleDataService } from '../apple-data.service' import { Observable } from 'rxjs'; import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; @@ -15,7 +14,7 @@ interface ExtendedPlotCandlestickDataGroupingOptions extends Highcharts.DataGrou templateUrl: './lazy-loading-chart.component.html', styleUrls: ['./lazy-loading-chart.component.css'], imports: [HighchartsChartComponent], - providers: [providePartialHighChart({ modules: [HC_stock] })], + providers: [providePartialHighChart({ modules: () => [import('highcharts/modules/stock')] })], changeDetection: ChangeDetectionStrategy.OnPush, }) export class LazyLoadingChartComponent { diff --git a/src/app/line-chart/line-chart.component.ts b/src/app/line-chart/line-chart.component.ts index c5a97fc..e67483f 100644 --- a/src/app/line-chart/line-chart.component.ts +++ b/src/app/line-chart/line-chart.component.ts @@ -1,5 +1,4 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import HC_customEvents from 'highcharts-custom-events'; import { FormsModule } from '@angular/forms'; import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; @@ -8,7 +7,7 @@ import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-an templateUrl: './line-chart.component.html', styleUrls: ['./line-chart.component.css'], imports: [FormsModule, HighchartsChartComponent], - providers: [providePartialHighChart({ modules: [HC_customEvents] })], + providers: [providePartialHighChart({ modules: () => [import('highcharts-custom-events')] })], changeDetection: ChangeDetectionStrategy.OnPush, }) export class LineChartComponent { diff --git a/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts index 47532e4..a4baeff 100644 --- a/src/app/map-chart/map-chart.component.ts +++ b/src/app/map-chart/map-chart.component.ts @@ -2,7 +2,6 @@ import {HttpClient} from '@angular/common/http'; import {ChangeDetectionStrategy, Component, inject, computed} from '@angular/core'; import {toSignal} from '@angular/core/rxjs-interop'; import type Highcharts from 'highcharts'; -import HC_map from 'highcharts/modules/map'; import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; // import proj4 from 'proj4'; @@ -14,7 +13,7 @@ import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-an templateUrl: './map-chart.component.html', styleUrls: ['./map-chart.component.css'], imports: [HighchartsChartComponent], - providers: [providePartialHighChart({ modules: [HC_map] })], + providers: [providePartialHighChart({ modules: () => [import('highcharts/modules/map')] })], changeDetection: ChangeDetectionStrategy.OnPush, }) diff --git a/src/app/stock-chart/stock-chart.component.ts b/src/app/stock-chart/stock-chart.component.ts index 5a36c45..9e17a52 100644 --- a/src/app/stock-chart/stock-chart.component.ts +++ b/src/app/stock-chart/stock-chart.component.ts @@ -1,7 +1,5 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import type Highcharts from 'highcharts'; -import HC_stock from 'highcharts/modules/stock'; -import HC_customEvents from 'highcharts-custom-events'; import { FormsModule } from '@angular/forms'; import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-angular'; @@ -15,7 +13,7 @@ import { HighchartsChartComponent, providePartialHighChart } from 'highcharts-an templateUrl: './stock-chart.component.html', styleUrls: ['./stock-chart.component.css'], imports: [FormsModule, HighchartsChartComponent], - providers: [providePartialHighChart({ modules: [HC_stock, HC_customEvents] })], + providers: [providePartialHighChart({ modules: () => [import('highcharts/modules/stock'), import('highcharts-custom-events')] })], changeDetection: ChangeDetectionStrategy.OnPush, }) export class StockChartComponent { From ec4f722e989fe656a17244ec945d7566e1bc1ced Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 8 Dec 2024 22:46:36 +0100 Subject: [PATCH 82/94] correct types --- highcharts-angular/src/lib/highcharts-chart.service.ts | 4 ++-- highcharts-angular/src/lib/types.ts | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.service.ts b/highcharts-angular/src/lib/highcharts-chart.service.ts index a790b72..0dadffc 100644 --- a/highcharts-angular/src/lib/highcharts-chart.service.ts +++ b/highcharts-angular/src/lib/highcharts-chart.service.ts @@ -1,7 +1,7 @@ import { inject, Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { HIGHCHARTS_ROOT_MODULES, HIGHCHARTS_LOADER, HIGHCHARTS_OPTIONS } from './highcharts-chart.token'; -import { Chart, ModuleFactoryFunction, PartialHighchartsConfig } from './types'; +import { Chart, ModuleFactoryFunction, PartialHighchartsConfig, ModuleFactory } from './types'; @Injectable({providedIn: 'root'}) export class HighchartsChartService { @@ -15,7 +15,7 @@ export class HighchartsChartService { private async loadHighchartsWithModules(partialConfig?: PartialHighchartsConfig): Promise { const Highcharts: Chart['highcharts'] = await this.source; // Ensure Highcharts core is loaded const version: number = Number(Highcharts['version'].split('.').map((v: string) => v.padStart(2, '0')).join('')); - const results = await Promise.all( + const results: ModuleFactory[] = await Promise.all( partialConfig?.modules ? [...this.globalModules(), ...partialConfig.modules()] : this.globalModules() ); if (version < 120000) { diff --git a/highcharts-angular/src/lib/types.ts b/highcharts-angular/src/lib/types.ts index f81a4cf..2fc8597 100644 --- a/highcharts-angular/src/lib/types.ts +++ b/highcharts-angular/src/lib/types.ts @@ -3,9 +3,12 @@ import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; export type ChartConstructorType = 'chart' | 'ganttChart' | 'stockChart' | 'mapChart'; -export type ModuleFactory = Promise<{Highcharts: Chart['highcharts'], default: (highcharts: Chart['highcharts']) => void}>; +export type ModuleFactoryFunction = () => Promise[]; -export type ModuleFactoryFunction = () => ModuleFactory[]; +export interface ModuleFactory { + Highcharts?: Chart['highcharts'], + default?: (highcharts: Chart['highcharts']) => void +} export interface Chart { options: Highcharts.Options | HighchartsESM.Options, From 79ee4d23867df39bb59fde8b00817b55aea0ec06 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 8 Dec 2024 23:17:50 +0100 Subject: [PATCH 83/94] correct tests --- .../src/lib/highcharts-chart.service.spec.ts | 128 +++++++++++++----- .../src/lib/highcharts-chart.service.ts | 2 +- 2 files changed, 92 insertions(+), 38 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.service.spec.ts b/highcharts-angular/src/lib/highcharts-chart.service.spec.ts index eeb1853..e2199c2 100644 --- a/highcharts-angular/src/lib/highcharts-chart.service.spec.ts +++ b/highcharts-angular/src/lib/highcharts-chart.service.spec.ts @@ -1,25 +1,30 @@ -import { TestBed } from '@angular/core/testing'; +import { TestBed, tick, fakeAsync } from '@angular/core/testing'; import { HighchartsChartService } from './highcharts-chart.service'; import { HIGHCHARTS_LOADER, HIGHCHARTS_OPTIONS, HIGHCHARTS_ROOT_MODULES } from './highcharts-chart.token'; -import { Chart, ModuleFactory } from './types'; +import { Chart, ModuleFactoryFunction } from './types'; describe('HighchartsChartService', () => { let service: HighchartsChartService; - let mockLoader: Promise; + let mockLoader: Chart['highcharts']; let mockGlobalOptions: Chart['options']; - let mockGlobalModules: ModuleFactory[]; + let mockGlobalModules: ModuleFactoryFunction; beforeEach(() => { - mockLoader = Promise.resolve({ + // Mock Highcharts instance with the setOptions method + mockLoader = { + version: '11.0.0', setOptions: jasmine.createSpy('setOptions'), - } as unknown as Chart['highcharts']); + } as unknown as Chart['highcharts'] mockGlobalOptions = { lang: { thousandsSep: ',' } }; - mockGlobalModules = [jasmine.createSpy('module1'), jasmine.createSpy('module2')]; + mockGlobalModules = jasmine.createSpy('mockGlobalModules').and.returnValue([ + Promise.resolve({ default: jasmine.createSpy() }), + Promise.resolve({ default: jasmine.createSpy() }), + ]); TestBed.configureTestingModule({ providers: [ HighchartsChartService, - { provide: HIGHCHARTS_LOADER, useValue: mockLoader }, + { provide: HIGHCHARTS_LOADER, useValue: Promise.resolve(mockLoader) }, { provide: HIGHCHARTS_OPTIONS, useValue: mockGlobalOptions }, { provide: HIGHCHARTS_ROOT_MODULES, useValue: mockGlobalModules }, ], @@ -32,57 +37,64 @@ describe('HighchartsChartService', () => { expect(service).toBeTruthy(); }); - it('should emit the loaded Highcharts instance', async () => { + it('should emit the loaded Highcharts instance', fakeAsync(() => { const loaderSpy = jasmine.createSpy('loaderSpy'); service.loaderChanges$.subscribe(loaderSpy); service.load(); - await mockLoader; + tick(100); // Simulate the passage of time for the timeout in the load method - expect(loaderSpy).toHaveBeenCalledWith(jasmine.any(Object)); - }); + expect(loaderSpy).toHaveBeenCalledWith(jasmine.any(Object)); // The Highcharts object should be emitted + })); - it('should call setOptions with global options if provided', async () => { + it('should call setOptions with global options if provided', fakeAsync(() => { service.load(); - const highcharts = await mockLoader; + tick(100); // Simulate the passage of time for the timeout in the load method - expect(highcharts.setOptions).toHaveBeenCalledWith(mockGlobalOptions); - }); + // Check if setOptions was called with the global options + expect(mockLoader.setOptions).toHaveBeenCalledWith(mockGlobalOptions); + })); - it('should load global modules if provided', async () => { + it('should load global modules if provided', fakeAsync(() => { service.load(); - const highcharts = await mockLoader; + tick(100); // Simulate the passage of time for the timeout in the load method - mockGlobalModules.forEach(module => { - expect(module).toHaveBeenCalledWith(highcharts); + // Wait for each module to resolve, then check if its `default` method was called with highcharts + mockGlobalModules().forEach((moduleSpy) => { + moduleSpy.then((module) => { + expect(module.default).toHaveBeenCalledWith(mockLoader); + }) }); - }); - - it('should load partialConfig modules if provided', async () => { - const mockPartialModules: ModuleFactory[] = [ - jasmine.createSpy('partialModule1'), - jasmine.createSpy('partialModule2'), - ]; - - service.load({ modules: mockPartialModules }); - const highcharts = await mockLoader; - - mockPartialModules.forEach(module => { - expect(module).toHaveBeenCalledWith(highcharts); + })); + + it('should load partialConfig modules if provided', fakeAsync(() => { + const mockPartialModules = jasmine.createSpy('mockPartialModules').and.returnValue([ + Promise.resolve({default: jasmine.createSpy()}), + Promise.resolve({default: jasmine.createSpy()}), + ]); + + // Call the load method with partial modules + service.load({modules: mockPartialModules}); + tick(100); // Simulate the passage of time for the timeout in the load method + + // Wait for each module to resolve and check if `default` was called with highcharts + mockGlobalModules().forEach((moduleSpy) => { + moduleSpy.then((resolvedModule) => { + expect(resolvedModule.default).toHaveBeenCalledWith(mockLoader); + }) }); - }); + })); }); describe('With not provided Value', () => { let service: HighchartsChartService; let mockLoader: Promise; - let mockGlobalModules: ModuleFactory[]; beforeEach(() => { mockLoader = Promise.resolve({ + version: '11.0.0', setOptions: jasmine.createSpy('setOptions'), } as unknown as Chart['highcharts']); - mockGlobalModules = []; TestBed.configureTestingModule({ @@ -90,7 +102,7 @@ describe('With not provided Value', () => { HighchartsChartService, { provide: HIGHCHARTS_LOADER, useValue: mockLoader }, { provide: HIGHCHARTS_OPTIONS, useValue: undefined }, - { provide: HIGHCHARTS_ROOT_MODULES, useValue: mockGlobalModules }, + { provide: HIGHCHARTS_ROOT_MODULES, useValue: undefined }, ], }); @@ -104,3 +116,45 @@ describe('With not provided Value', () => { expect(highcharts.setOptions).not.toHaveBeenCalled(); }); }); + + +describe('With Version 12', () => { + let service: HighchartsChartService; + let mockLoader: Chart['highcharts']; + let mockGlobalModules: ModuleFactoryFunction; + + beforeEach(() => { + mockLoader = { + version: '12.0.0', + setOptions: jasmine.createSpy('setOptions'), + } as unknown as Chart['highcharts'] + mockGlobalModules = jasmine.createSpy('mockGlobalModules').and.returnValue([ + Promise.resolve({ default: jasmine.createSpy() }), + Promise.resolve({ default: jasmine.createSpy() }), + ]); + + + TestBed.configureTestingModule({ + providers: [ + HighchartsChartService, + { provide: HIGHCHARTS_LOADER, useValue: Promise.resolve(mockLoader) }, + { provide: HIGHCHARTS_OPTIONS, useValue: undefined }, + { provide: HIGHCHARTS_ROOT_MODULES, useValue: mockGlobalModules }, + ], + }); + + service = TestBed.inject(HighchartsChartService); + }); + + it('should load global modules without default', fakeAsync(() => { + service.load(); + tick(100); // Simulate the passage of time for the timeout in the load method + + // Wait for each module to resolve, then check if its `default` method was called with highcharts + mockGlobalModules().forEach((moduleSpy) => { + moduleSpy.then((module) => { + expect(module.default).not.toHaveBeenCalledWith(mockLoader); + }) + }); + })); +}); diff --git a/highcharts-angular/src/lib/highcharts-chart.service.ts b/highcharts-angular/src/lib/highcharts-chart.service.ts index 0dadffc..ad225ca 100644 --- a/highcharts-angular/src/lib/highcharts-chart.service.ts +++ b/highcharts-angular/src/lib/highcharts-chart.service.ts @@ -32,7 +32,7 @@ export class HighchartsChartService { source.setOptions(this.globalOptions); } // add timeout to make sure the loader has attached all modules - setTimeout(() => this.loader.next(source), 500); + setTimeout(() => this.loader.next(source), 100); }); } } From 1d4f93c499de742f7f1b8f94163dafd21a456559 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 8 Dec 2024 23:23:43 +0100 Subject: [PATCH 84/94] update readme --- README.md | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index c2da2dc..3fbf292 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,13 @@ export const appConfig: ApplicationConfig = { }, // Modules for additional functionality - modules: [ExportingModule, SunsetTheme] + modules: () => { + return [ + import('highcharts/modules/accessibility'), + import('highcharts/modules/exporting'), + import('highcharts/themes/sunset') + ] + } }) ] }; @@ -90,14 +96,14 @@ Here is the configuration interface for reference: export interface HighchartsConfig { instance?: Promise; options?: Highcharts.Options; - modules?: ModuleFactory[]; + modules?: ModuleFactoryFunction; } ``` ### Key Notes: - The `instance` property allows you to specify the Highcharts instance dynamically. - The `options` property is used to define global chart configurations applied across all charts. -- The `modules` array enables you to include Highcharts modules (e.g., exporting, accessibility) or custom themes. +- The `modules` a callback with an array enables you to include Highcharts modules (e.g., exporting, accessibility) or custom themes. ### Usage @@ -299,12 +305,6 @@ If a lack of TypeScript definitions `d.ts` is showing as an error - see [Solving ```ts import { Component } from '@angular/core'; import { HighchartsChartDirective } from 'highcharts-angular'; -// Load core -import HC_gantt from 'highcharts/modules/gantt'; -// Load core module -import HC_exporting from 'highcharts/modules/exporting'; -// Load plugins -import * as HC_customEvents from 'highcharts-custom-events'; @Component({ template: ` @@ -312,7 +312,20 @@ import * as HC_customEvents from 'highcharts-custom-events'; `, styles: [`.chart { width: 100%; height: 400px; display: block; }`], imports: [HighchartsChartDirective], - providers: [providePartialHighChart({ modules: [HC_gantt, HC_exporting, HC_customEvents] })], + providers: [ + providePartialHighChart({ + modules: () => { + return [ + // Load Gantt Chart + import('highcharts/modules/gantt'), + // Load core module + import('highcharts/modules/exporting'), + // Load plugins + import('highcharts-custom-events'), + ] + } + }) + ], }) export class GanttComponent { chartOptions: Highcharts.Options = { @@ -331,7 +344,6 @@ Official map collection is published and [here](https://www.npmjs.com/package/@h ```ts import { Component } from '@angular/core'; import { HighchartsChartDirective } from 'highcharts-angular'; -import HC_map from 'highcharts/modules/map'; @Component({ template: ` @@ -339,7 +351,7 @@ import HC_map from 'highcharts/modules/map'; `, styles: [`.chart { width: 100%; height: 400px; display: block; }`], imports: [HighchartsChartDirective], - providers: [providePartialHighChart({ modules: [HC_map] })], + providers: [providePartialHighChart({ modules: () => [import('highcharts/modules/map')] })], }) export class MapComponent { chartOptions: Highcharts.Options = { @@ -356,7 +368,6 @@ export class MapComponent { ```ts import { Component } from '@angular/core'; import { HighchartsChartDirective } from 'highcharts-angular'; -import HC_stock from 'highcharts/modules/stock'; @Component({ template: ` @@ -364,7 +375,7 @@ import HC_stock from 'highcharts/modules/stock'; `, styles: [`.chart { width: 100%; height: 400px; display: block; }`], imports: [HighchartsChartDirective], - providers: [providePartialHighChart({ modules: [HC_stock] })], + providers: [providePartialHighChart({ modules: () => [import('highcharts/modules/stock')] })], }) export class StockComponent { chartOptions: Highcharts.Options = { @@ -411,7 +422,6 @@ The wrapper is now ready to be imported into your app. Use `require` instead of ```ts import { Component } from '@angular/core'; import { HighchartsChartDirective } from 'highcharts-angular'; -const customWrapper = require('./relative-path-to-the-wrapper-file/wrapper-file-name'); @Component({ @@ -420,7 +430,7 @@ const customWrapper = require('./relative-path-to-the-wrapper-file/wrapper-file- `, styles: [`.chart { width: 100%; height: 400px; display: block; }`], imports: [HighchartsChartDirective], - providers: [providePartialHighChart({ modules: [customWrapper] })], + providers: [providePartialHighChart({ modules: () => [import('./relative-path-to-the-wrapper-file/wrapper-file-name')] })], }) export class StockComponent { chartOptions: Highcharts.Options = { From ee1bebbb3f7bc58a8bb276549c8d8bcc23aff373 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 8 Dec 2024 23:26:59 +0100 Subject: [PATCH 85/94] update readme --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 3fbf292..03efdff 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,6 @@ Then, configure the Highcharts provider in your app.config.ts file: ```ts import { provideHighCharts } from 'highcharts-angular'; -import ExportingModule from 'highcharts/modules/exporting'; -import SunsetTheme from 'highcharts/themes/sunset'; export const appConfig: ApplicationConfig = { providers: [ From 7c8074093b015367d9c9f65b7189947c585599e1 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Sun, 8 Dec 2024 23:34:44 +0100 Subject: [PATCH 86/94] correct test --- src/app/tests/line-test/line-test.component.spec.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/app/tests/line-test/line-test.component.spec.ts b/src/app/tests/line-test/line-test.component.spec.ts index 6116bf1..1bd25d8 100644 --- a/src/app/tests/line-test/line-test.component.spec.ts +++ b/src/app/tests/line-test/line-test.component.spec.ts @@ -1,4 +1,4 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import {ComponentFixture, TestBed, waitForAsync, fakeAsync, tick} from '@angular/core/testing'; import { provideHighCharts, HighchartsChartService } from '../../../../highcharts-angular/src/public_api'; import { LineTestComponent } from './line-test.component'; @@ -16,14 +16,15 @@ describe('LineTestComponent', () => { .compileComponents(); })); - beforeEach(async () => { + beforeEach(fakeAsync(() => { fixture = TestBed.createComponent(LineTestComponent); service = TestBed.inject(HighchartsChartService); service.load(); + tick(100); component = fixture.componentInstance; component.updateSeriesColor(); fixture.detectChanges(); - }); + })); it('should create', () => { expect(component).toBeTruthy(); From f6ecfc8f533e51e07795939531013c1d87c0fd96 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Mon, 9 Dec 2024 21:14:01 +0100 Subject: [PATCH 87/94] lazy load main module --- .../src/lib/highcharts-chart.provider.ts | 7 +++--- .../src/lib/highcharts-chart.service.spec.ts | 22 ++++++++++++------- .../src/lib/highcharts-chart.service.ts | 6 ++--- .../src/lib/highcharts-chart.token.ts | 4 ++-- highcharts-angular/src/lib/types.ts | 3 ++- src/app/app.config.ts | 1 + 6 files changed, 26 insertions(+), 17 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.provider.ts b/highcharts-angular/src/lib/highcharts-chart.provider.ts index f1a86e4..26165a9 100644 --- a/highcharts-angular/src/lib/highcharts-chart.provider.ts +++ b/highcharts-angular/src/lib/highcharts-chart.provider.ts @@ -1,15 +1,16 @@ import { EnvironmentProviders, makeEnvironmentProviders, Provider } from '@angular/core'; import { HIGHCHARTS_LOADER, HIGHCHARTS_CONFIG, HIGHCHARTS_ROOT_MODULES, HIGHCHARTS_OPTIONS } from './highcharts-chart.token'; -import { Chart, ModuleFactoryFunction, HighchartsConfig, PartialHighchartsConfig } from './types'; +import { Chart, ModuleFactoryFunction, HighchartsConfig, PartialHighchartsConfig, InstanceFactoryFunction } from './types'; const emptyModuleFactoryFunction: ModuleFactoryFunction = () => []; +const defaultInstanceFactoryFunction: InstanceFactoryFunction = () => import('highcharts').then(m => m.default); export function providePartialHighChart(config: PartialHighchartsConfig): Provider { return { provide: HIGHCHARTS_CONFIG, useValue: config }; } -export function provideHighChartInstance(instance: Promise) { - return makeEnvironmentProviders([{ provide: HIGHCHARTS_LOADER, useValue: instance || import('highcharts').then(m => m.default) }]); +export function provideHighChartInstance(instance: InstanceFactoryFunction) { + return makeEnvironmentProviders([{ provide: HIGHCHARTS_LOADER, useValue: instance || defaultInstanceFactoryFunction }]); } export function provideHighChartOptions(options: Chart['options']) { diff --git a/highcharts-angular/src/lib/highcharts-chart.service.spec.ts b/highcharts-angular/src/lib/highcharts-chart.service.spec.ts index e2199c2..0f093a0 100644 --- a/highcharts-angular/src/lib/highcharts-chart.service.spec.ts +++ b/highcharts-angular/src/lib/highcharts-chart.service.spec.ts @@ -1,7 +1,7 @@ import { TestBed, tick, fakeAsync } from '@angular/core/testing'; import { HighchartsChartService } from './highcharts-chart.service'; import { HIGHCHARTS_LOADER, HIGHCHARTS_OPTIONS, HIGHCHARTS_ROOT_MODULES } from './highcharts-chart.token'; -import { Chart, ModuleFactoryFunction } from './types'; +import { Chart, ModuleFactoryFunction, InstanceFactoryFunction } from './types'; describe('HighchartsChartService', () => { let service: HighchartsChartService; @@ -20,11 +20,12 @@ describe('HighchartsChartService', () => { Promise.resolve({ default: jasmine.createSpy() }), Promise.resolve({ default: jasmine.createSpy() }), ]); + const instance = () => Promise.resolve(mockLoader); TestBed.configureTestingModule({ providers: [ HighchartsChartService, - { provide: HIGHCHARTS_LOADER, useValue: Promise.resolve(mockLoader) }, + { provide: HIGHCHARTS_LOADER, useValue: instance }, { provide: HIGHCHARTS_OPTIONS, useValue: mockGlobalOptions }, { provide: HIGHCHARTS_ROOT_MODULES, useValue: mockGlobalModules }, ], @@ -88,19 +89,22 @@ describe('HighchartsChartService', () => { describe('With not provided Value', () => { let service: HighchartsChartService; - let mockLoader: Promise; + let mockLoader: Chart['highcharts']; + let mockLoaderInstance: InstanceFactoryFunction; beforeEach(() => { - mockLoader = Promise.resolve({ + mockLoader = { version: '11.0.0', setOptions: jasmine.createSpy('setOptions'), - } as unknown as Chart['highcharts']); + } as unknown as Chart['highcharts'] + + mockLoaderInstance = () => Promise.resolve(mockLoader); TestBed.configureTestingModule({ providers: [ HighchartsChartService, - { provide: HIGHCHARTS_LOADER, useValue: mockLoader }, + { provide: HIGHCHARTS_LOADER, useValue: mockLoaderInstance }, { provide: HIGHCHARTS_OPTIONS, useValue: undefined }, { provide: HIGHCHARTS_ROOT_MODULES, useValue: undefined }, ], @@ -111,7 +115,7 @@ describe('With not provided Value', () => { it('should not call setOptions if global options are not provided', async () => { service.load(); - const highcharts = await mockLoader; + const highcharts = await mockLoaderInstance(); expect(highcharts.setOptions).not.toHaveBeenCalled(); }); @@ -133,11 +137,13 @@ describe('With Version 12', () => { Promise.resolve({ default: jasmine.createSpy() }), ]); + const instance = () => Promise.resolve(mockLoader); + TestBed.configureTestingModule({ providers: [ HighchartsChartService, - { provide: HIGHCHARTS_LOADER, useValue: Promise.resolve(mockLoader) }, + { provide: HIGHCHARTS_LOADER, useValue: instance }, { provide: HIGHCHARTS_OPTIONS, useValue: undefined }, { provide: HIGHCHARTS_ROOT_MODULES, useValue: mockGlobalModules }, ], diff --git a/highcharts-angular/src/lib/highcharts-chart.service.ts b/highcharts-angular/src/lib/highcharts-chart.service.ts index ad225ca..98d109d 100644 --- a/highcharts-angular/src/lib/highcharts-chart.service.ts +++ b/highcharts-angular/src/lib/highcharts-chart.service.ts @@ -1,19 +1,19 @@ import { inject, Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { HIGHCHARTS_ROOT_MODULES, HIGHCHARTS_LOADER, HIGHCHARTS_OPTIONS } from './highcharts-chart.token'; -import { Chart, ModuleFactoryFunction, PartialHighchartsConfig, ModuleFactory } from './types'; +import { Chart, ModuleFactoryFunction, PartialHighchartsConfig, ModuleFactory, InstanceFactoryFunction } from './types'; @Injectable({providedIn: 'root'}) export class HighchartsChartService { private loader: BehaviorSubject = new BehaviorSubject(undefined); loaderChanges$ = this.loader.asObservable(); - private source: Promise = inject(HIGHCHARTS_LOADER); + private source: InstanceFactoryFunction = inject(HIGHCHARTS_LOADER); private globalOptions: Chart['options'] = inject(HIGHCHARTS_OPTIONS, { optional: true }); private globalModules: ModuleFactoryFunction = inject(HIGHCHARTS_ROOT_MODULES, { optional: true }); private async loadHighchartsWithModules(partialConfig?: PartialHighchartsConfig): Promise { - const Highcharts: Chart['highcharts'] = await this.source; // Ensure Highcharts core is loaded + const Highcharts: Chart['highcharts'] = await this.source(); // Ensure Highcharts core is loaded const version: number = Number(Highcharts['version'].split('.').map((v: string) => v.padStart(2, '0')).join('')); const results: ModuleFactory[] = await Promise.all( partialConfig?.modules ? [...this.globalModules(), ...partialConfig.modules()] : this.globalModules() diff --git a/highcharts-angular/src/lib/highcharts-chart.token.ts b/highcharts-angular/src/lib/highcharts-chart.token.ts index 0c69eb7..fb0d2d1 100644 --- a/highcharts-angular/src/lib/highcharts-chart.token.ts +++ b/highcharts-angular/src/lib/highcharts-chart.token.ts @@ -1,7 +1,7 @@ import { InjectionToken } from '@angular/core'; -import { Chart, ModuleFactoryFunction, PartialHighchartsConfig } from './types' +import { Chart, InstanceFactoryFunction, ModuleFactoryFunction, PartialHighchartsConfig } from './types' -export const HIGHCHARTS_LOADER = new InjectionToken>('HIGHCHARTS_LOADER'); +export const HIGHCHARTS_LOADER = new InjectionToken('HIGHCHARTS_LOADER'); export const HIGHCHARTS_ROOT_MODULES = new InjectionToken('HIGHCHARTS_ROOT_MODULES'); export const HIGHCHARTS_OPTIONS = new InjectionToken('HIGHCHARTS_OPTIONS'); export const HIGHCHARTS_CONFIG = new InjectionToken('HIGHCHARTS_CONFIG'); diff --git a/highcharts-angular/src/lib/types.ts b/highcharts-angular/src/lib/types.ts index 2fc8597..44c767f 100644 --- a/highcharts-angular/src/lib/types.ts +++ b/highcharts-angular/src/lib/types.ts @@ -4,6 +4,7 @@ import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; export type ChartConstructorType = 'chart' | 'ganttChart' | 'stockChart' | 'mapChart'; export type ModuleFactoryFunction = () => Promise[]; +export type InstanceFactoryFunction = () => Promise; export interface ModuleFactory { Highcharts?: Chart['highcharts'], @@ -22,7 +23,7 @@ export interface PartialHighchartsConfig { } export interface HighchartsConfig { - instance?: Promise; + instance?: InstanceFactoryFunction; options?: Chart['options']; modules?: ModuleFactoryFunction; } diff --git a/src/app/app.config.ts b/src/app/app.config.ts index ff7948e..bda5bea 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -10,6 +10,7 @@ export const appConfig: ApplicationConfig = { importProvidersFrom(BrowserModule), provideHttpClient(withInterceptorsFromDi(), withFetch()), provideHighCharts({ + instance: () => import('highcharts').then(m => m.default), options: { title: { style: { From 103505b73ae2e4c81977d84e7705af38fafbc332 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Mon, 9 Dec 2024 22:30:34 +0100 Subject: [PATCH 88/94] address feedbacks --- .../src/lib/highcharts-chart.component.ts | 2 +- .../src/lib/highcharts-chart.directive.ts | 20 ++++--------------- .../src/lib/highcharts-chart.module.ts | 11 ---------- .../src/lib/highcharts-chart.provider.ts | 14 ++++++------- highcharts-angular/src/lib/types.ts | 3 +-- highcharts-angular/src/public_api.ts | 11 ++++------ 6 files changed, 17 insertions(+), 44 deletions(-) delete mode 100644 highcharts-angular/src/lib/highcharts-chart.module.ts diff --git a/highcharts-angular/src/lib/highcharts-chart.component.ts b/highcharts-angular/src/lib/highcharts-chart.component.ts index 185151a..a64045c 100644 --- a/highcharts-angular/src/lib/highcharts-chart.component.ts +++ b/highcharts-angular/src/lib/highcharts-chart.component.ts @@ -7,7 +7,7 @@ import { HighchartsChartDirective } from './highcharts-chart.directive'; hostDirectives: [ { directive: HighchartsChartDirective, - inputs: ['Highcharts', 'constructorType', 'callbackFunction', 'oneToOne', 'runOutsideAngular', 'options', 'update'], + inputs: ['constructorType', 'callbackFunction', 'oneToOne', 'options', 'update'], outputs: ['chartInstance', 'updateChange'] } ], diff --git a/highcharts-angular/src/lib/highcharts-chart.directive.ts b/highcharts-angular/src/lib/highcharts-chart.directive.ts index 967df68..ac50851 100644 --- a/highcharts-angular/src/lib/highcharts-chart.directive.ts +++ b/highcharts-angular/src/lib/highcharts-chart.directive.ts @@ -24,12 +24,6 @@ import type { Chart, ChartConstructorType } from './types'; selector: '[highcharts-chart]', }) export class HighchartsChartDirective { - /** - * Highcharts library or Highcharts ESM module. - * @deprecated - */ - Highcharts = input(); - /** * Type of the chart constructor. */ @@ -45,18 +39,12 @@ export class HighchartsChartDirective { * Items are added/removed as needed. Series with `id`s are matched by `id`; * unmatched items are removed. Omitted `series` leaves existing ones unchanged. */ - oneToOne = input(); - - /** - * Whether to run the chart outside Angular. - * @deprecated - */ - runOutsideAngular = input(); + oneToOne = input(false); /** * Options for the Highcharts chart. */ - options = input(); + options = input.required(); /** * Whether to redraw the chart. @@ -81,7 +69,7 @@ export class HighchartsChartDirective { private constructorChart = computed(() => { const constructorType = untracked(this.constructorType); - const highCharts = this.highCharts() || this.Highcharts(); + const highCharts = this.highCharts(); if (constructorType && highCharts) { return highCharts[constructorType]; } @@ -102,7 +90,7 @@ export class HighchartsChartDirective { callbackFunction: Highcharts.ChartCallbackFunction ): Highcharts.Chart | null { if (chart) { - chart.update(source.options, true, oneToOne || false); + chart.update(source.options, true, oneToOne); return chart; } if (source.constructorChart) { diff --git a/highcharts-angular/src/lib/highcharts-chart.module.ts b/highcharts-angular/src/lib/highcharts-chart.module.ts deleted file mode 100644 index 18e359d..0000000 --- a/highcharts-angular/src/lib/highcharts-chart.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { NgModule } from '@angular/core'; -import { HighchartsChartComponent } from './highcharts-chart.component'; - -/** - * @deprecated Use `HighchartsChartComponent` directly instead. - */ -@NgModule({ - imports: [ HighchartsChartComponent ], - exports: [ HighchartsChartComponent ] -}) -export class HighchartsChartModule {} diff --git a/highcharts-angular/src/lib/highcharts-chart.provider.ts b/highcharts-angular/src/lib/highcharts-chart.provider.ts index 26165a9..050d17c 100644 --- a/highcharts-angular/src/lib/highcharts-chart.provider.ts +++ b/highcharts-angular/src/lib/highcharts-chart.provider.ts @@ -5,22 +5,22 @@ import { Chart, ModuleFactoryFunction, HighchartsConfig, PartialHighchartsConfig const emptyModuleFactoryFunction: ModuleFactoryFunction = () => []; const defaultInstanceFactoryFunction: InstanceFactoryFunction = () => import('highcharts').then(m => m.default); -export function providePartialHighChart(config: PartialHighchartsConfig): Provider { - return { provide: HIGHCHARTS_CONFIG, useValue: config }; -} - -export function provideHighChartInstance(instance: InstanceFactoryFunction) { +function provideHighChartInstance(instance: InstanceFactoryFunction) { return makeEnvironmentProviders([{ provide: HIGHCHARTS_LOADER, useValue: instance || defaultInstanceFactoryFunction }]); } -export function provideHighChartOptions(options: Chart['options']) { +function provideHighChartOptions(options: Chart['options']) { return makeEnvironmentProviders([{ provide: HIGHCHARTS_OPTIONS, useValue: options } ]); } -export function provideHighChartRootModules(modules: ModuleFactoryFunction) { +function provideHighChartRootModules(modules: ModuleFactoryFunction) { return makeEnvironmentProviders([{ provide: HIGHCHARTS_ROOT_MODULES, useValue: modules }]); } +export function providePartialHighChart(config: PartialHighchartsConfig): Provider { + return { provide: HIGHCHARTS_CONFIG, useValue: config }; +} + export function provideHighCharts(config: HighchartsConfig) { const providers: EnvironmentProviders[] = [ provideHighChartInstance(config.instance), diff --git a/highcharts-angular/src/lib/types.ts b/highcharts-angular/src/lib/types.ts index 44c767f..a3d9ff1 100644 --- a/highcharts-angular/src/lib/types.ts +++ b/highcharts-angular/src/lib/types.ts @@ -1,4 +1,3 @@ -import type Highcharts from 'highcharts'; import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; export type ChartConstructorType = 'chart' | 'ganttChart' | 'stockChart' | 'mapChart'; @@ -14,7 +13,7 @@ export interface ModuleFactory { export interface Chart { options: Highcharts.Options | HighchartsESM.Options, update?: boolean, - highcharts?: typeof Highcharts | typeof HighchartsESM + highcharts?: typeof HighchartsESM constructorChart?: Function; } diff --git a/highcharts-angular/src/public_api.ts b/highcharts-angular/src/public_api.ts index c4f9103..929f17b 100644 --- a/highcharts-angular/src/public_api.ts +++ b/highcharts-angular/src/public_api.ts @@ -2,10 +2,7 @@ * Public API Surface of highcharts-angular */ -export * from './lib/highcharts-chart.module'; -export * from './lib/highcharts-chart.component'; -export * from './lib/highcharts-chart.directive'; -export * from './lib/highcharts-chart.token'; -export * from './lib/highcharts-chart.provider'; -export * from './lib/highcharts-chart.service'; -export * from './lib/types'; +export { HighchartsChartComponent } from './lib/highcharts-chart.component'; +export { HighchartsChartDirective } from './lib/highcharts-chart.directive'; +export { provideHighCharts, providePartialHighChart } from './lib/highcharts-chart.provider'; +export { HighchartsConfig, PartialHighchartsConfig, ChartConstructorType } from './lib/types'; From a57878c399af340d870f719024cc10dfed1b9be1 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Mon, 9 Dec 2024 22:37:30 +0100 Subject: [PATCH 89/94] update README.md --- README.md | 17 ++++++++++++++--- package.json | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 03efdff..9508335 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,10 @@ Official minimal Highcharts integration for Angular. 1. [Getting Started](#getting-started) 1. [General Prerequisites](#general-prerequisites) 2. [Installing](#installing) - 3. [Usage](#usage) - 4. [SSR Support](#ssr-support) - 5. [Angular Elements and `useHTML`](#angular-elements-and-usehtml) + 3. [Upgrade to v5](#upgrade-to-v5) + 4. [Usage](#usage) + 5. [SSR Support](#ssr-support) + 6. [Angular Elements and `useHTML`](#angular-elements-and-usehtml) 2. [Options Details](#options-details) 3. [Chart Instance](#chart-instance) 4. [Highcharts Partial Loading on the Component Level](#highcharts-partial-loading-on-the-component-level) @@ -103,6 +104,16 @@ export interface HighchartsConfig { - The `options` property is used to define global chart configurations applied across all charts. - The `modules` a callback with an array enables you to include Highcharts modules (e.g., exporting, accessibility) or custom themes. +### Upgrade to v5 + +Version 5 introduces significant improvements and changes to align with modern Angular practices. **Please review the following breaking changes before upgrading:** + +#### Breaking Changes + +1. **Dropped Support for `HighchartsChartModule`:** + - In v5, the package no longer requires `HighchartsChartModule`. This change leverages Angular's standalone component model for a more streamlined development experience. + - **Action Required:** Migrate your components to standalone by importing necessary dependencies directly into the component or directive. + ### Usage You can use Highcharts in your Angular application either as a **Component** or a **Directive**. Below are the usage examples for both approaches: diff --git a/package.json b/package.json index f1a9c42..fd362aa 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@highcharts/map-collection": "^2.3.0", "core-js": "^3.19.2", "express": "^4.18.2", - "highcharts": "^11.2.0", + "highcharts": "^12.0.2", "highcharts-custom-events": "^3.0.10", "jquery": "^3.6.0", "proj4": "^2.15.0", From be5a0272db1750c7f74a422f3373703ccab489e9 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Mon, 9 Dec 2024 23:07:45 +0100 Subject: [PATCH 90/94] correct test --- .../line-test/line-test.component.spec.ts | 77 ++++++++++++++----- .../tests/line-test/line-test.component.ts | 5 +- 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/src/app/tests/line-test/line-test.component.spec.ts b/src/app/tests/line-test/line-test.component.spec.ts index 1bd25d8..cc7a37a 100644 --- a/src/app/tests/line-test/line-test.component.spec.ts +++ b/src/app/tests/line-test/line-test.component.spec.ts @@ -1,44 +1,81 @@ -import {ComponentFixture, TestBed, waitForAsync, fakeAsync, tick} from '@angular/core/testing'; -import { provideHighCharts, HighchartsChartService } from '../../../../highcharts-angular/src/public_api'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { provideHighCharts } from '../../../../highcharts-angular/src/public_api'; import { LineTestComponent } from './line-test.component'; - describe('LineTestComponent', () => { let component: LineTestComponent; let fixture: ComponentFixture; - let service: HighchartsChartService; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ + beforeEach(async () => { + await TestBed.configureTestingModule({ + providers: [provideHighCharts({})], imports: [LineTestComponent], - providers: [provideHighCharts({})] - }) - .compileComponents(); - })); + }).compileComponents(); - beforeEach(fakeAsync(() => { fixture = TestBed.createComponent(LineTestComponent); - service = TestBed.inject(HighchartsChartService); - service.load(); - tick(100); component = fixture.componentInstance; - component.updateSeriesColor(); fixture.detectChanges(); - })); + }); - it('should create', () => { + it('should create the component', () => { expect(component).toBeTruthy(); }); + it('should have default chart options with a line series', () => { + expect(component.chartOptions.series).toBeDefined(); + expect(component.chartOptions.series[0].type).toBe('line'); + expect((component.chartOptions.series[0] as any).data).toEqual([1, 2, 3]); + }); + it('should have data given from chartOptions', () => { const chartOptions = component.chartOptions; + + // Simulate the chartInstance being assigned (this happens when the chart is rendered) + component.chartInstance = { + series: [{yData: [1, 2, 3]}], + } as unknown as Highcharts.Chart; + const series = component.chartInstance.series[0]; expect((series as any).yData).toEqual((chartOptions.series[0] as any).data); }); + it('should update series color and set updateFlag to true', () => { + component.updateSeriesColor(); + + const updatedSeries = component.chartOptions.series[0] as any; + expect(updatedSeries.color).toBe('hotpink'); + expect(component.updateFlag).toBeTrue(); + }); + it('should be properly updated', () => { - const chart = component.chartInstance; - const series = chart.series[0] as unknown as Highcharts.Series; - expect(series.color).toEqual('hotpink'); + // Simulate the chartInstance and a mock series + const mockSeries = { color: 'hotpink' } as unknown as Highcharts.Series; + + component.chartInstance = { + series: [mockSeries], + } as unknown as Highcharts.Chart; + + // Perform the color update + component.updateSeriesColor(); + + // Ensure the color was updated + const series = component.chartInstance.series[0]; + expect(series.color).toBe('hotpink'); + }); + + it('should bind chart instance when Highcharts chart emits instance', () => { + const mockChartInstance = {} as Highcharts.Chart; + component.chartInstance = mockChartInstance; + + expect(component.chartInstance).toBe(mockChartInstance); + }); + + it('should trigger update when updateFlag is set', () => { + spyOn(component, 'updateSeriesColor').and.callThrough(); + const updateButton = fixture.nativeElement.querySelector('button'); + updateButton.click(); + fixture.detectChanges(); + + expect(component.updateSeriesColor).toHaveBeenCalled(); }); }); diff --git a/src/app/tests/line-test/line-test.component.ts b/src/app/tests/line-test/line-test.component.ts index 92ca7dd..a95c2a2 100644 --- a/src/app/tests/line-test/line-test.component.ts +++ b/src/app/tests/line-test/line-test.component.ts @@ -1,8 +1,8 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import type Highcharts from 'highcharts'; +import type HighchartsESM from 'highcharts/es-modules/masters/highcharts.src'; import { HighchartsChartComponent } from '../../../../highcharts-angular/src/public_api'; -interface ExtendedSeriesCandlestickOptions extends Highcharts.SeriesCandlestickOptions { +interface ExtendedSeriesCandlestickOptions extends HighchartsESM.SeriesCandlestickOptions { color: Highcharts.ColorType; } @@ -16,7 +16,6 @@ interface ExtendedSeriesCandlestickOptions extends Highcharts.SeriesCandlestickO export class LineTestComponent { updateFlag = false; chartInstance: Highcharts.Chart; - chartOptions: Highcharts.Options = { series: [ { From e4fe3ff28f3de4c0142ca0b45f7e536e2c3a8d4e Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Mon, 9 Dec 2024 23:12:38 +0100 Subject: [PATCH 91/94] switch to ESM --- highcharts-angular/src/lib/highcharts-chart.provider.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.provider.ts b/highcharts-angular/src/lib/highcharts-chart.provider.ts index 050d17c..5c7ca73 100644 --- a/highcharts-angular/src/lib/highcharts-chart.provider.ts +++ b/highcharts-angular/src/lib/highcharts-chart.provider.ts @@ -3,7 +3,9 @@ import { HIGHCHARTS_LOADER, HIGHCHARTS_CONFIG, HIGHCHARTS_ROOT_MODULES, HIGHCHAR import { Chart, ModuleFactoryFunction, HighchartsConfig, PartialHighchartsConfig, InstanceFactoryFunction } from './types'; const emptyModuleFactoryFunction: ModuleFactoryFunction = () => []; -const defaultInstanceFactoryFunction: InstanceFactoryFunction = () => import('highcharts').then(m => m.default); +const defaultInstanceFactoryFunction: InstanceFactoryFunction = () => { + return import('highcharts/es-modules/masters/highcharts.src').then(m => m.default); +}; function provideHighChartInstance(instance: InstanceFactoryFunction) { return makeEnvironmentProviders([{ provide: HIGHCHARTS_LOADER, useValue: instance || defaultInstanceFactoryFunction }]); From ee5f97109777b0adf53bcc290286e86249367ec5 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Mon, 9 Dec 2024 23:14:38 +0100 Subject: [PATCH 92/94] switch to ESM --- highcharts-angular/src/lib/highcharts-chart.provider.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/highcharts-angular/src/lib/highcharts-chart.provider.ts b/highcharts-angular/src/lib/highcharts-chart.provider.ts index 5c7ca73..0ed1ea2 100644 --- a/highcharts-angular/src/lib/highcharts-chart.provider.ts +++ b/highcharts-angular/src/lib/highcharts-chart.provider.ts @@ -3,9 +3,8 @@ import { HIGHCHARTS_LOADER, HIGHCHARTS_CONFIG, HIGHCHARTS_ROOT_MODULES, HIGHCHAR import { Chart, ModuleFactoryFunction, HighchartsConfig, PartialHighchartsConfig, InstanceFactoryFunction } from './types'; const emptyModuleFactoryFunction: ModuleFactoryFunction = () => []; -const defaultInstanceFactoryFunction: InstanceFactoryFunction = () => { - return import('highcharts/es-modules/masters/highcharts.src').then(m => m.default); -}; +// tslint:disable-next-line:max-line-length +const defaultInstanceFactoryFunction: InstanceFactoryFunction = () => import('highcharts/es-modules/masters/highcharts.src').then(m => m.default); function provideHighChartInstance(instance: InstanceFactoryFunction) { return makeEnvironmentProviders([{ provide: HIGHCHARTS_LOADER, useValue: instance || defaultInstanceFactoryFunction }]); From d71ae0c8a77c8ac18ff45e30beeb1faf1fea3aa3 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Mon, 9 Dec 2024 23:32:22 +0100 Subject: [PATCH 93/94] add new commands --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index fd362aa..14f0959 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "start": "node tasks/build.js && npm run serve", "start:ssr": "node tasks/build.js && npm run serve:ssr", "build": "node tasks/build.js", + "build:app": "ng build my-app", "build:ssr": "ng build my-ssr-app", "run:ssr": "node dist/my-ssr-app/server/server.mjs", "test": "ng test my-app", From 8698e8596b0c37bf9969a826c3ee59757cd2b054 Mon Sep 17 00:00:00 2001 From: Mohamed Ben Makhlouf Date: Mon, 9 Dec 2024 23:36:24 +0100 Subject: [PATCH 94/94] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9508335..1561fa2 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ export const appConfig: ApplicationConfig = { // Other providers provideHighCharts({ // Optional: Define the Highcharts instance - // instance: import('highcharts'), + // instance: () => import('highcharts'), // Global options for all charts options: {