ngx-apextree 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,80 @@
1
+ ## 📄 License Options for ngx-apextree
2
+
3
+ ngx-apextree is the official Angular wrapper for ApexTree and follows the same licensing model as ApexCharts.
4
+
5
+ ---
6
+
7
+ ### 🔓 Community License (Free)
8
+
9
+ For individuals, non-profits, educators, and small businesses with **less than $2 million USD in annual revenue**.
10
+
11
+ ✅ What's allowed:
12
+
13
+ - Personal, educational, or non-profit use
14
+ - Commercial use by small orgs (< $2M annual revenue)
15
+ - Modifications and redistribution (with attribution)
16
+
17
+ 🚫 Not allowed:
18
+
19
+ - Use by companies or entities over $2M/year revenue
20
+ - Use in competing charting products
21
+ - Sublicensing under different terms
22
+
23
+ ➡ By using ngx-apextree under this license, you confirm that **you qualify as a Small Organization**.
24
+
25
+ ---
26
+
27
+ ### 💼 Commercial License (Paid)
28
+
29
+ Required if **you or your affiliated organization earns $2 million USD or more per year**.
30
+
31
+ ✅ What's included:
32
+
33
+ - Use in internal tools and commercial applications
34
+ - Modifications and app-level distribution
35
+ - 12-month subscription with updates & support
36
+
37
+ 🚫 Not allowed:
38
+
39
+ - Redistribution in toolkits, SDKs, or platforms
40
+ - Use by unlicensed developers
41
+ - Competing charting products
42
+
43
+ ---
44
+
45
+ ### 🔄 OEM / Redistribution License (Paid)
46
+
47
+ Required if you are **embedding ApexTree into a product or platform used by other people**, such as:
48
+
49
+ - No-code dashboards
50
+ - Developer platforms
51
+ - Embedded BI tools
52
+ - White-labeled apps or SDKs
53
+
54
+ ✅ What's included:
55
+
56
+ - Redistribution rights for 1 application or product
57
+ - 12-month subscription with updates & support
58
+
59
+ ✅ OEM **not required** if your app simply renders static charts and users **cannot** configure or interact with them.
60
+
61
+ ---
62
+
63
+ ### ⚠️ License Acceptance
64
+
65
+ By installing ngx-apextree (e.g., via `npm install ngx-apextree`), you are agreeing to the applicable license based on your usage:
66
+
67
+ - Community License (if under $2M revenue)
68
+ - Commercial License (if over $2M revenue)
69
+ - OEM License (if redistributing to third-party users)
70
+
71
+ ---
72
+
73
+ ### 🛠 Need a License or Have Questions?
74
+
75
+ 📧 Contact us at [sales@apexcharts.com](mailto:sales@apexcharts.com)
76
+ 📚 Read full license agreements here: [https://apexcharts.com/license](https://apexcharts.com/license)
77
+
78
+ ---
79
+
80
+ Thank you for supporting ApexTree! Your licensing helps keep it free and open for individuals and small teams.
package/README.md ADDED
@@ -0,0 +1,329 @@
1
+ # ngx-apextree
2
+
3
+ Angular wrapper for [ApexTree](https://github.com/apexcharts/apextree) - a JavaScript library for creating organizational and hierarchical charts.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install ngx-apextree apextree
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Basic Example
14
+
15
+ ```typescript
16
+ // app.component.ts
17
+ import { Component } from '@angular/core';
18
+ import { NgxApextreeComponent, TreeNode, ApexTreeOptions } from 'ngx-apextree';
19
+
20
+ @Component({
21
+ selector: 'app-root',
22
+ standalone: true,
23
+ imports: [NgxApextreeComponent],
24
+ template: `
25
+ <ngx-apextree
26
+ [data]="treeData"
27
+ [options]="treeOptions"
28
+ (nodeClick)="onNodeClick($event)"
29
+ (graphReady)="onGraphReady($event)"
30
+ >
31
+ </ngx-apextree>
32
+ `,
33
+ })
34
+ export class AppComponent {
35
+ treeData: TreeNode = {
36
+ id: '1',
37
+ name: 'CEO',
38
+ children: [
39
+ {
40
+ id: '2',
41
+ name: 'CTO',
42
+ children: [
43
+ { id: '3', name: 'Dev Lead' },
44
+ { id: '4', name: 'QA Lead' },
45
+ ],
46
+ },
47
+ {
48
+ id: '5',
49
+ name: 'CFO',
50
+ },
51
+ ],
52
+ };
53
+
54
+ treeOptions: ApexTreeOptions = {
55
+ width: 800,
56
+ height: 600,
57
+ nodeWidth: 150,
58
+ nodeHeight: 60,
59
+ direction: 'top',
60
+ childrenSpacing: 80,
61
+ siblingSpacing: 30,
62
+ };
63
+
64
+ onNodeClick(event: any) {
65
+ console.log('Node clicked:', event.node);
66
+ }
67
+
68
+ onGraphReady(graph: any) {
69
+ console.log('Graph ready:', graph);
70
+ }
71
+ }
72
+ ```
73
+
74
+ ### Custom Node Template
75
+
76
+ Use Angular's `ng-template` for custom node rendering:
77
+
78
+ ```typescript
79
+ @Component({
80
+ selector: 'app-root',
81
+ standalone: true,
82
+ imports: [NgxApextreeComponent],
83
+ template: `
84
+ <ngx-apextree [data]="treeData" [options]="treeOptions">
85
+ <ng-template #nodeTemplate let-content>
86
+ <div class="custom-node">
87
+ <img [src]="content.imageURL" alt="" />
88
+ <span>{{ content.name }}</span>
89
+ </div>
90
+ </ng-template>
91
+ </ngx-apextree>
92
+ `,
93
+ styles: [
94
+ `
95
+ .custom-node {
96
+ display: flex;
97
+ align-items: center;
98
+ gap: 8px;
99
+ height: 100%;
100
+ padding: 0 10px;
101
+ }
102
+ .custom-node img {
103
+ width: 40px;
104
+ height: 40px;
105
+ border-radius: 50%;
106
+ }
107
+ `,
108
+ ],
109
+ })
110
+ export class AppComponent {
111
+ treeData: TreeNode = {
112
+ id: '1',
113
+ data: {
114
+ name: 'John Doe',
115
+ imageURL: 'https://i.pravatar.cc/300?img=68',
116
+ },
117
+ children: [
118
+ {
119
+ id: '2',
120
+ data: {
121
+ name: 'Jane Smith',
122
+ imageURL: 'https://i.pravatar.cc/300?img=69',
123
+ },
124
+ },
125
+ ],
126
+ };
127
+
128
+ treeOptions: ApexTreeOptions = {
129
+ contentKey: 'data',
130
+ width: 800,
131
+ height: 600,
132
+ nodeWidth: 180,
133
+ nodeHeight: 60,
134
+ };
135
+ }
136
+ ```
137
+
138
+ ### Custom Tooltip Template
139
+
140
+ You can provide a custom tooltip using the `tooltipTemplate` option:
141
+
142
+ ```typescript
143
+ @Component({
144
+ selector: 'app-root',
145
+ standalone: true,
146
+ imports: [NgxApextreeComponent],
147
+ template: ` <ngx-apextree [data]="treeData" [options]="treeOptions"></ngx-apextree> `,
148
+ })
149
+ export class AppComponent {
150
+ treeData: TreeNode = {
151
+ id: '1',
152
+ data: {
153
+ name: 'John Doe',
154
+ role: 'CEO',
155
+ email: 'john@company.com',
156
+ },
157
+ children: [
158
+ {
159
+ id: '2',
160
+ data: {
161
+ name: 'Jane Smith',
162
+ role: 'CTO',
163
+ email: 'jane@company.com',
164
+ },
165
+ },
166
+ ],
167
+ };
168
+
169
+ treeOptions: ApexTreeOptions = {
170
+ contentKey: 'data',
171
+ width: 800,
172
+ height: 600,
173
+ enableTooltip: true,
174
+ tooltipTemplate: (content: any) => {
175
+ return `
176
+ <div style="padding: 10px;">
177
+ <strong>${content.name}</strong>
178
+ <p>${content.role}</p>
179
+ <p>${content.email}</p>
180
+ </div>
181
+ `;
182
+ },
183
+ };
184
+ }
185
+ ```
186
+
187
+ Alternatively, use Angular's `ng-template` for tooltip rendering:
188
+
189
+ ```html
190
+ <ngx-apextree [data]="treeData" [options]="{ enableTooltip: true }">
191
+ <ng-template #tooltipTemplate let-content>
192
+ <div class="custom-tooltip">
193
+ <strong>{{ content.name }}</strong>
194
+ <p>{{ content.description }}</p>
195
+ </div>
196
+ </ng-template>
197
+ </ngx-apextree>
198
+ ```
199
+
200
+ ### Graph Methods
201
+
202
+ Access graph methods through component reference or the emitted graph instance:
203
+
204
+ ```typescript
205
+ @Component({
206
+ template: `
207
+ <ngx-apextree
208
+ #tree
209
+ [data]="treeData"
210
+ [options]="treeOptions"
211
+ (graphReady)="onGraphReady($event)"
212
+ >
213
+ </ngx-apextree>
214
+
215
+ <button (click)="changeDirection()">Change Direction</button>
216
+ <button (click)="fit()">Fit Screen</button>
217
+ `,
218
+ })
219
+ export class AppComponent {
220
+ @ViewChild('tree') tree!: NgxApextreeComponent;
221
+
222
+ private graph: any;
223
+
224
+ onGraphReady(graph: any) {
225
+ this.graph = graph;
226
+ }
227
+
228
+ changeDirection() {
229
+ // using component method
230
+ this.tree.changeLayout('left');
231
+
232
+ // or using graph instance directly
233
+ // this.graph.changeLayout('left');
234
+ }
235
+
236
+ fit() {
237
+ this.tree.fitScreen();
238
+ }
239
+ }
240
+ ```
241
+
242
+ ## API
243
+
244
+ ### Inputs
245
+
246
+ | Input | Type | Description |
247
+ | --------- | ----------------- | --------------------- |
248
+ | `data` | `TreeNode` | Tree data structure |
249
+ | `options` | `ApexTreeOptions` | Configuration options |
250
+
251
+ ### Outputs
252
+
253
+ | Output | Type | Description |
254
+ | -------------- | ---------------- | ------------------------------- |
255
+ | `nodeClick` | `NodeClickEvent` | Emits when a node is clicked |
256
+ | `graphReady` | `ApexTreeGraph` | Emits after initial render |
257
+ | `graphUpdated` | `ApexTreeGraph` | Emits after data/options update |
258
+
259
+ ### Content Templates
260
+
261
+ | Template | Context | Description |
262
+ | ------------------ | -------------------- | ------------------- |
263
+ | `#nodeTemplate` | `$implicit: content` | Custom node HTML |
264
+ | `#tooltipTemplate` | `$implicit: content` | Custom tooltip HTML |
265
+
266
+ ### Component Methods
267
+
268
+ | Method | Parameters | Description |
269
+ | -------------- | -------------------------- | --------------------- |
270
+ | `changeLayout` | `direction: TreeDirection` | Change tree direction |
271
+ | `collapse` | `nodeId: string` | Collapse a node |
272
+ | `expand` | `nodeId: string` | Expand a node |
273
+ | `fitScreen` | - | Fit graph to screen |
274
+ | `getGraph` | - | Get graph instance |
275
+ | `render` | - | Manually re-render |
276
+
277
+ ## License Setup
278
+
279
+ If you have a commercial license, set it once at app initialization.
280
+
281
+ ### Option 1: Angular Provider (Recommended)
282
+
283
+ **Standalone App:**
284
+
285
+ ```typescript
286
+ // app.config.ts
287
+ import { ApplicationConfig } from '@angular/core';
288
+ import { provideApexTreeLicense } from 'ngx-apextree';
289
+
290
+ export const appConfig: ApplicationConfig = {
291
+ providers: [provideApexTreeLicense('your-license-key-here')],
292
+ };
293
+ ```
294
+
295
+ **Module-based App:**
296
+
297
+ ```typescript
298
+ // app.module.ts
299
+ import { NgModule } from '@angular/core';
300
+ import { provideApexTreeLicense } from 'ngx-apextree';
301
+
302
+ @NgModule({
303
+ providers: [provideApexTreeLicense('your-license-key-here')],
304
+ })
305
+ export class AppModule {}
306
+ ```
307
+
308
+ ### Option 2: Static Method
309
+
310
+ ```typescript
311
+ // main.ts
312
+ import { bootstrapApplication } from '@angular/platform-browser';
313
+ import { setApexTreeLicense } from 'ngx-apextree';
314
+ import { AppComponent } from './app/app.component';
315
+ import { appConfig } from './app/app.config';
316
+
317
+ // set license before bootstrapping
318
+ setApexTreeLicense('your-license-key-here');
319
+
320
+ bootstrapApplication(AppComponent, appConfig);
321
+ ```
322
+
323
+ ## Tree Options
324
+
325
+ See the full list of options in the [ApexTree documentation](https://github.com/apexcharts/apextree).
326
+
327
+ ## License
328
+
329
+ See [LICENSE](./LICENSE) for details.
@@ -0,0 +1,319 @@
1
+ import * as i0 from '@angular/core';
2
+ import { EventEmitter, inject, PLATFORM_ID, NgZone, ViewChild, ContentChild, Output, Input, ChangeDetectionStrategy, Component, InjectionToken, ENVIRONMENT_INITIALIZER } from '@angular/core';
3
+ import { isPlatformBrowser, CommonModule } from '@angular/common';
4
+ import ApexTree from 'apextree';
5
+
6
+ class NgxApextreeComponent {
7
+ /**
8
+ * tree data to render
9
+ */
10
+ data = null;
11
+ /**
12
+ * tree configuration options
13
+ */
14
+ options = {};
15
+ /**
16
+ * emits when a node is clicked
17
+ */
18
+ nodeClick = new EventEmitter();
19
+ /**
20
+ * emits when graph is ready after initial render
21
+ */
22
+ graphReady = new EventEmitter();
23
+ /**
24
+ * emits when graph is updated after data/options change
25
+ */
26
+ graphUpdated = new EventEmitter();
27
+ /**
28
+ * custom node template
29
+ */
30
+ nodeTemplateRef = null;
31
+ /**
32
+ * custom tooltip template
33
+ */
34
+ tooltipTemplateRef = null;
35
+ chartContainer;
36
+ platformId = inject(PLATFORM_ID);
37
+ ngZone = inject(NgZone);
38
+ treeInstance = null;
39
+ graphInstance = null;
40
+ isInitialized = false;
41
+ ngOnInit() {
42
+ // initialization logic
43
+ }
44
+ ngAfterViewInit() {
45
+ if (isPlatformBrowser(this.platformId)) {
46
+ this.initChart();
47
+ }
48
+ }
49
+ ngOnChanges(changes) {
50
+ if (!this.isInitialized) {
51
+ return;
52
+ }
53
+ // re-render on data or options change
54
+ if (changes['data'] || changes['options']) {
55
+ this.updateChart();
56
+ }
57
+ }
58
+ ngOnDestroy() {
59
+ this.destroyChart();
60
+ }
61
+ /**
62
+ * change the layout direction
63
+ */
64
+ changeLayout(direction) {
65
+ if (this.graphInstance) {
66
+ this.ngZone.runOutsideAngular(() => {
67
+ this.graphInstance.changeLayout(direction);
68
+ });
69
+ }
70
+ }
71
+ /**
72
+ * collapse a node by id
73
+ */
74
+ collapse(nodeId) {
75
+ if (this.graphInstance) {
76
+ this.ngZone.runOutsideAngular(() => {
77
+ this.graphInstance.collapse(nodeId);
78
+ });
79
+ }
80
+ }
81
+ /**
82
+ * expand a node by id
83
+ */
84
+ expand(nodeId) {
85
+ if (this.graphInstance) {
86
+ this.ngZone.runOutsideAngular(() => {
87
+ this.graphInstance.expand(nodeId);
88
+ });
89
+ }
90
+ }
91
+ /**
92
+ * fit the graph to screen
93
+ */
94
+ fitScreen() {
95
+ if (this.graphInstance) {
96
+ this.ngZone.runOutsideAngular(() => {
97
+ this.graphInstance.fitScreen();
98
+ });
99
+ }
100
+ }
101
+ /**
102
+ * get the underlying graph instance
103
+ */
104
+ getGraph() {
105
+ return this.graphInstance;
106
+ }
107
+ /**
108
+ * manually trigger a re-render
109
+ */
110
+ render() {
111
+ this.updateChart();
112
+ }
113
+ initChart() {
114
+ if (!this.data) {
115
+ return;
116
+ }
117
+ this.ngZone.runOutsideAngular(() => {
118
+ const mergedOptions = this.buildOptions();
119
+ this.treeInstance = new ApexTree(this.chartContainer.nativeElement, mergedOptions);
120
+ this.graphInstance = this.treeInstance.render(this.data);
121
+ this.isInitialized = true;
122
+ this.ngZone.run(() => {
123
+ this.graphReady.emit(this.graphInstance);
124
+ });
125
+ });
126
+ }
127
+ updateChart() {
128
+ if (!isPlatformBrowser(this.platformId)) {
129
+ return;
130
+ }
131
+ // destroy and recreate for now
132
+ // apextree doesn't have an update method
133
+ this.destroyChart();
134
+ if (this.data) {
135
+ this.ngZone.runOutsideAngular(() => {
136
+ const mergedOptions = this.buildOptions();
137
+ this.treeInstance = new ApexTree(this.chartContainer.nativeElement, mergedOptions);
138
+ this.graphInstance = this.treeInstance.render(this.data);
139
+ this.isInitialized = true;
140
+ this.ngZone.run(() => {
141
+ this.graphUpdated.emit(this.graphInstance);
142
+ });
143
+ });
144
+ }
145
+ }
146
+ destroyChart() {
147
+ // clear the container
148
+ if (this.chartContainer?.nativeElement) {
149
+ this.chartContainer.nativeElement.innerHTML = '';
150
+ }
151
+ this.treeInstance = null;
152
+ this.graphInstance = null;
153
+ this.isInitialized = false;
154
+ }
155
+ buildOptions() {
156
+ const options = { ...this.options };
157
+ // handle node template
158
+ if (this.nodeTemplateRef) {
159
+ options.nodeTemplate = (content) => {
160
+ return this.renderTemplate(this.nodeTemplateRef, content);
161
+ };
162
+ }
163
+ // handle tooltip template
164
+ if (this.tooltipTemplateRef) {
165
+ options.tooltipTemplate = (content) => {
166
+ return this.renderTemplate(this.tooltipTemplateRef, content);
167
+ };
168
+ }
169
+ // handle node click
170
+ if (this.nodeClick.observed) {
171
+ options.onNodeClick = (node) => {
172
+ this.ngZone.run(() => {
173
+ this.nodeClick.emit({
174
+ node,
175
+ event: window.event,
176
+ });
177
+ });
178
+ };
179
+ }
180
+ return options;
181
+ }
182
+ renderTemplate(templateRef, content) {
183
+ // create embedded view
184
+ const viewRef = templateRef.createEmbeddedView({ $implicit: content });
185
+ viewRef.detectChanges();
186
+ // extract html from the view
187
+ const html = this.extractHtmlFromView(viewRef);
188
+ // destroy the view
189
+ viewRef.destroy();
190
+ return html;
191
+ }
192
+ extractHtmlFromView(viewRef) {
193
+ const nodes = viewRef.rootNodes;
194
+ let html = '';
195
+ for (const node of nodes) {
196
+ if (node instanceof HTMLElement) {
197
+ html += node.outerHTML;
198
+ }
199
+ else if (node instanceof Text) {
200
+ html += node.textContent || '';
201
+ }
202
+ else if (node instanceof Comment) {
203
+ // skip comments
204
+ }
205
+ }
206
+ return html;
207
+ }
208
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxApextreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
209
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: NgxApextreeComponent, isStandalone: true, selector: "ngx-apextree", inputs: { data: "data", options: "options" }, outputs: { nodeClick: "nodeClick", graphReady: "graphReady", graphUpdated: "graphUpdated" }, queries: [{ propertyName: "nodeTemplateRef", first: true, predicate: ["nodeTemplate"], descendants: true }, { propertyName: "tooltipTemplateRef", first: true, predicate: ["tooltipTemplate"], descendants: true }], viewQueries: [{ propertyName: "chartContainer", first: true, predicate: ["chartContainer"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: `<div #chartContainer class="ngx-apextree-container"></div>`, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
210
+ }
211
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxApextreeComponent, decorators: [{
212
+ type: Component,
213
+ args: [{ selector: 'ngx-apextree', standalone: true, imports: [CommonModule], template: `<div #chartContainer class="ngx-apextree-container"></div>`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}\n"] }]
214
+ }], propDecorators: { data: [{
215
+ type: Input
216
+ }], options: [{
217
+ type: Input
218
+ }], nodeClick: [{
219
+ type: Output
220
+ }], graphReady: [{
221
+ type: Output
222
+ }], graphUpdated: [{
223
+ type: Output
224
+ }], nodeTemplateRef: [{
225
+ type: ContentChild,
226
+ args: ['nodeTemplate', { static: false }]
227
+ }], tooltipTemplateRef: [{
228
+ type: ContentChild,
229
+ args: ['tooltipTemplate', { static: false }]
230
+ }], chartContainer: [{
231
+ type: ViewChild,
232
+ args: ['chartContainer', { static: true }]
233
+ }] } });
234
+
235
+ /**
236
+ * injection token for apextree license key
237
+ */
238
+ const APEXTREE_LICENSE_KEY = new InjectionToken('APEXTREE_LICENSE_KEY');
239
+ /**
240
+ * internal variable to store license key
241
+ */
242
+ let licenseKey = null;
243
+ /**
244
+ * static method to set license
245
+ * call this before bootstrapping your app
246
+ *
247
+ * @example
248
+ * ```typescript
249
+ * import { setApexTreeLicense } from 'ngx-apextree';
250
+ *
251
+ * setApexTreeLicense('your-license-key-here');
252
+ *
253
+ * bootstrapApplication(AppComponent, appConfig);
254
+ * ```
255
+ */
256
+ function setApexTreeLicense(license) {
257
+ licenseKey = license;
258
+ // set license in apextree library if it has a method for it
259
+ if (typeof ApexTree.setLicense === 'function') {
260
+ ApexTree.setLicense(license);
261
+ }
262
+ }
263
+ /**
264
+ * get the currently set license key
265
+ */
266
+ function getApexTreeLicense() {
267
+ return licenseKey;
268
+ }
269
+ /**
270
+ * angular provider function for license configuration
271
+ * use this in your app config or module providers
272
+ *
273
+ * @example
274
+ * ```typescript
275
+ * // standalone app (app.config.ts)
276
+ * import { provideApexTreeLicense } from 'ngx-apextree';
277
+ *
278
+ * export const appConfig: ApplicationConfig = {
279
+ * providers: [
280
+ * provideApexTreeLicense('your-license-key-here'),
281
+ * ]
282
+ * };
283
+ *
284
+ * // module-based app (app.module.ts)
285
+ * @NgModule({
286
+ * providers: [
287
+ * provideApexTreeLicense('your-license-key-here'),
288
+ * ]
289
+ * })
290
+ * export class AppModule { }
291
+ * ```
292
+ */
293
+ function provideApexTreeLicense(license) {
294
+ return [
295
+ {
296
+ provide: APEXTREE_LICENSE_KEY,
297
+ useValue: license,
298
+ },
299
+ {
300
+ provide: ENVIRONMENT_INITIALIZER,
301
+ multi: true,
302
+ useValue: () => {
303
+ setApexTreeLicense(license);
304
+ },
305
+ },
306
+ ];
307
+ }
308
+
309
+ /*
310
+ * Public API Surface of ngx-apextree
311
+ */
312
+ // component
313
+
314
+ /**
315
+ * Generated bundle index. Do not edit.
316
+ */
317
+
318
+ export { APEXTREE_LICENSE_KEY, NgxApextreeComponent, getApexTreeLicense, provideApexTreeLicense, setApexTreeLicense };
319
+ //# sourceMappingURL=ngx-apextree.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-apextree.mjs","sources":["../../../projects/ngx-apextree/src/lib/ngx-apextree.component.ts","../../../projects/ngx-apextree/src/lib/ngx-apextree.license.ts","../../../projects/ngx-apextree/src/public-api.ts","../../../projects/ngx-apextree/src/ngx-apextree.ts"],"sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n ElementRef,\n OnInit,\n OnDestroy,\n OnChanges,\n SimpleChanges,\n ContentChild,\n TemplateRef,\n ViewChild,\n AfterViewInit,\n NgZone,\n ChangeDetectionStrategy,\n inject,\n PLATFORM_ID,\n} from '@angular/core';\nimport { isPlatformBrowser, CommonModule } from '@angular/common';\nimport ApexTree from 'apextree';\nimport {\n ApexTreeOptions,\n ApexTreeGraph,\n TreeNode,\n NodeClickEvent,\n TreeDirection,\n} from './ngx-apextree.types';\n\n@Component({\n selector: 'ngx-apextree',\n standalone: true,\n imports: [CommonModule],\n template: `<div #chartContainer class=\"ngx-apextree-container\"></div>`,\n styles: [\n `\n :host {\n display: block;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class NgxApextreeComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy {\n /**\n * tree data to render\n */\n @Input() data: TreeNode | null = null;\n\n /**\n * tree configuration options\n */\n @Input() options: ApexTreeOptions = {};\n\n /**\n * emits when a node is clicked\n */\n @Output() nodeClick = new EventEmitter<NodeClickEvent>();\n\n /**\n * emits when graph is ready after initial render\n */\n @Output() graphReady = new EventEmitter<ApexTreeGraph>();\n\n /**\n * emits when graph is updated after data/options change\n */\n @Output() graphUpdated = new EventEmitter<ApexTreeGraph>();\n\n /**\n * custom node template\n */\n @ContentChild('nodeTemplate', { static: false })\n nodeTemplateRef: TemplateRef<any> | null = null;\n\n /**\n * custom tooltip template\n */\n @ContentChild('tooltipTemplate', { static: false })\n tooltipTemplateRef: TemplateRef<any> | null = null;\n\n @ViewChild('chartContainer', { static: true })\n private chartContainer!: ElementRef<HTMLElement>;\n\n private platformId = inject(PLATFORM_ID);\n private ngZone = inject(NgZone);\n\n private treeInstance: any = null;\n private graphInstance: ApexTreeGraph | null = null;\n private isInitialized = false;\n\n ngOnInit(): void {\n // initialization logic\n }\n\n ngAfterViewInit(): void {\n if (isPlatformBrowser(this.platformId)) {\n this.initChart();\n }\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (!this.isInitialized) {\n return;\n }\n\n // re-render on data or options change\n if (changes['data'] || changes['options']) {\n this.updateChart();\n }\n }\n\n ngOnDestroy(): void {\n this.destroyChart();\n }\n\n /**\n * change the layout direction\n */\n changeLayout(direction: TreeDirection): void {\n if (this.graphInstance) {\n this.ngZone.runOutsideAngular(() => {\n this.graphInstance!.changeLayout(direction);\n });\n }\n }\n\n /**\n * collapse a node by id\n */\n collapse(nodeId: string): void {\n if (this.graphInstance) {\n this.ngZone.runOutsideAngular(() => {\n this.graphInstance!.collapse(nodeId);\n });\n }\n }\n\n /**\n * expand a node by id\n */\n expand(nodeId: string): void {\n if (this.graphInstance) {\n this.ngZone.runOutsideAngular(() => {\n this.graphInstance!.expand(nodeId);\n });\n }\n }\n\n /**\n * fit the graph to screen\n */\n fitScreen(): void {\n if (this.graphInstance) {\n this.ngZone.runOutsideAngular(() => {\n this.graphInstance!.fitScreen();\n });\n }\n }\n\n /**\n * get the underlying graph instance\n */\n getGraph(): ApexTreeGraph | null {\n return this.graphInstance;\n }\n\n /**\n * manually trigger a re-render\n */\n render(): void {\n this.updateChart();\n }\n\n private initChart(): void {\n if (!this.data) {\n return;\n }\n\n this.ngZone.runOutsideAngular(() => {\n const mergedOptions = this.buildOptions();\n\n this.treeInstance = new ApexTree(this.chartContainer.nativeElement, mergedOptions);\n\n this.graphInstance = this.treeInstance.render(this.data);\n this.isInitialized = true;\n\n this.ngZone.run(() => {\n this.graphReady.emit(this.graphInstance!);\n });\n });\n }\n\n private updateChart(): void {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n\n // destroy and recreate for now\n // apextree doesn't have an update method\n this.destroyChart();\n\n if (this.data) {\n this.ngZone.runOutsideAngular(() => {\n const mergedOptions = this.buildOptions();\n\n this.treeInstance = new ApexTree(this.chartContainer.nativeElement, mergedOptions);\n\n this.graphInstance = this.treeInstance.render(this.data);\n this.isInitialized = true;\n\n this.ngZone.run(() => {\n this.graphUpdated.emit(this.graphInstance!);\n });\n });\n }\n }\n\n private destroyChart(): void {\n // clear the container\n if (this.chartContainer?.nativeElement) {\n this.chartContainer.nativeElement.innerHTML = '';\n }\n this.treeInstance = null;\n this.graphInstance = null;\n this.isInitialized = false;\n }\n\n private buildOptions(): ApexTreeOptions {\n const options: ApexTreeOptions = { ...this.options };\n\n // handle node template\n if (this.nodeTemplateRef) {\n options.nodeTemplate = (content: any) => {\n return this.renderTemplate(this.nodeTemplateRef!, content);\n };\n }\n\n // handle tooltip template\n if (this.tooltipTemplateRef) {\n options.tooltipTemplate = (content: any) => {\n return this.renderTemplate(this.tooltipTemplateRef!, content);\n };\n }\n\n // handle node click\n if (this.nodeClick.observed) {\n options.onNodeClick = (node: any) => {\n this.ngZone.run(() => {\n this.nodeClick.emit({\n node,\n event: window.event as MouseEvent,\n });\n });\n };\n }\n\n return options as any;\n }\n\n private renderTemplate(templateRef: TemplateRef<any>, content: any): string {\n // create embedded view\n const viewRef = templateRef.createEmbeddedView({ $implicit: content });\n viewRef.detectChanges();\n\n // extract html from the view\n const html = this.extractHtmlFromView(viewRef);\n\n // destroy the view\n viewRef.destroy();\n\n return html;\n }\n\n private extractHtmlFromView(viewRef: any): string {\n const nodes = viewRef.rootNodes;\n let html = '';\n\n for (const node of nodes) {\n if (node instanceof HTMLElement) {\n html += node.outerHTML;\n } else if (node instanceof Text) {\n html += node.textContent || '';\n } else if (node instanceof Comment) {\n // skip comments\n }\n }\n\n return html;\n }\n}\n","import { InjectionToken, Provider, ENVIRONMENT_INITIALIZER, inject } from '@angular/core';\nimport ApexTree from 'apextree';\n\n/**\n * injection token for apextree license key\n */\nexport const APEXTREE_LICENSE_KEY = new InjectionToken<string>('APEXTREE_LICENSE_KEY');\n\n/**\n * internal variable to store license key\n */\nlet licenseKey: string | null = null;\n\n/**\n * static method to set license\n * call this before bootstrapping your app\n *\n * @example\n * ```typescript\n * import { setApexTreeLicense } from 'ngx-apextree';\n *\n * setApexTreeLicense('your-license-key-here');\n *\n * bootstrapApplication(AppComponent, appConfig);\n * ```\n */\nexport function setApexTreeLicense(license: string): void {\n licenseKey = license;\n // set license in apextree library if it has a method for it\n if (typeof (ApexTree as any).setLicense === 'function') {\n (ApexTree as any).setLicense(license);\n }\n}\n\n/**\n * get the currently set license key\n */\nexport function getApexTreeLicense(): string | null {\n return licenseKey;\n}\n\n/**\n * angular provider function for license configuration\n * use this in your app config or module providers\n *\n * @example\n * ```typescript\n * // standalone app (app.config.ts)\n * import { provideApexTreeLicense } from 'ngx-apextree';\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideApexTreeLicense('your-license-key-here'),\n * ]\n * };\n *\n * // module-based app (app.module.ts)\n * @NgModule({\n * providers: [\n * provideApexTreeLicense('your-license-key-here'),\n * ]\n * })\n * export class AppModule { }\n * ```\n */\nexport function provideApexTreeLicense(license: string): Provider[] {\n return [\n {\n provide: APEXTREE_LICENSE_KEY,\n useValue: license,\n },\n {\n provide: ENVIRONMENT_INITIALIZER,\n multi: true,\n useValue: () => {\n setApexTreeLicense(license);\n },\n },\n ];\n}\n","/*\n * Public API Surface of ngx-apextree\n */\n\n// component\nexport { NgxApextreeComponent } from './lib/ngx-apextree.component';\n\n// types\nexport type {\n ApexTreeOptions,\n ApexTreeGraph,\n TreeNode,\n NodeClickEvent,\n TreeDirection,\n NodeOptions,\n TooltipOptions,\n FontOptions,\n EdgeOptions,\n NodeStylingOptions,\n ExpandCollapseOptions,\n} from './lib/ngx-apextree.types';\n\n// license utilities\nexport {\n APEXTREE_LICENSE_KEY,\n setApexTreeLicense,\n getApexTreeLicense,\n provideApexTreeLicense,\n} from './lib/ngx-apextree.license';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "ngx-apextree",
3
+ "version": "1.0.0",
4
+ "description": "Angular wrapper for ApexTree - hierarchical and organizational chart library",
5
+ "license": "See LICENSE in LICENSE",
6
+ "author": "ApexCharts",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/apexcharts/ngx-apextree.git"
10
+ },
11
+ "keywords": [
12
+ "angular",
13
+ "tree",
14
+ "chart",
15
+ "organizational-chart",
16
+ "hierarchy",
17
+ "svg",
18
+ "apextree",
19
+ "ngx-apextree"
20
+ ],
21
+ "peerDependencies": {
22
+ "@angular/common": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0",
23
+ "@angular/core": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0",
24
+ "apextree": "^1.6.1"
25
+ },
26
+ "dependencies": {
27
+ "tslib": "^2.3.0"
28
+ },
29
+ "sideEffects": false
30
+ }
@@ -0,0 +1,248 @@
1
+ import * as i0 from '@angular/core';
2
+ import { OnInit, AfterViewInit, OnChanges, OnDestroy, EventEmitter, TemplateRef, SimpleChanges, InjectionToken, Provider } from '@angular/core';
3
+
4
+ /**
5
+ * tree direction options
6
+ */
7
+ type TreeDirection = 'top' | 'bottom' | 'left' | 'right';
8
+ /**
9
+ * node options that can be applied per-node
10
+ */
11
+ interface NodeOptions {
12
+ nodeBGColor?: string;
13
+ nodeBGColorHover?: string;
14
+ borderColor?: string;
15
+ borderColorHover?: string;
16
+ fontSize?: string;
17
+ fontFamily?: string;
18
+ fontWeight?: string;
19
+ fontColor?: string;
20
+ }
21
+ /**
22
+ * tree node data structure
23
+ */
24
+ interface TreeNode<T = any> {
25
+ id: string;
26
+ name?: string;
27
+ data?: T;
28
+ options?: NodeOptions;
29
+ children?: TreeNode<T>[];
30
+ }
31
+ /**
32
+ * tooltip options
33
+ */
34
+ interface TooltipOptions {
35
+ enableTooltip?: boolean;
36
+ tooltipId?: string;
37
+ tooltipMaxWidth?: number;
38
+ tooltipMinWidth?: number;
39
+ tooltipBorderColor?: string;
40
+ tooltipBGColor?: string;
41
+ tooltipFontColor?: string;
42
+ tooltipFontSize?: string;
43
+ tooltipPadding?: number;
44
+ tooltipOffset?: number;
45
+ }
46
+ /**
47
+ * font options
48
+ */
49
+ interface FontOptions {
50
+ fontSize?: string;
51
+ fontFamily?: string;
52
+ fontWeight?: string;
53
+ fontColor?: string;
54
+ }
55
+ /**
56
+ * edge options
57
+ */
58
+ interface EdgeOptions {
59
+ edgeWidth?: number;
60
+ edgeColor?: string;
61
+ edgeColorHover?: string;
62
+ }
63
+ /**
64
+ * node styling options
65
+ */
66
+ interface NodeStylingOptions {
67
+ nodeWidth?: number;
68
+ nodeHeight?: number;
69
+ nodeBGColor?: string;
70
+ nodeBGColorHover?: string;
71
+ borderWidth?: number;
72
+ borderStyle?: string;
73
+ borderRadius?: string;
74
+ borderColor?: string;
75
+ borderColorHover?: string;
76
+ nodeStyle?: string;
77
+ nodeClassName?: string;
78
+ }
79
+ /**
80
+ * expand/collapse options
81
+ */
82
+ interface ExpandCollapseOptions {
83
+ enableExpandCollapse?: boolean;
84
+ expandCollapseButtonBGColor?: string;
85
+ expandCollapseButtonBorderColor?: string;
86
+ }
87
+ /**
88
+ * complete tree options
89
+ */
90
+ interface ApexTreeOptions extends TooltipOptions, FontOptions, EdgeOptions, NodeStylingOptions, ExpandCollapseOptions {
91
+ width?: number | string;
92
+ height?: number | string;
93
+ direction?: TreeDirection;
94
+ contentKey?: string;
95
+ siblingSpacing?: number;
96
+ childrenSpacing?: number;
97
+ highlightOnHover?: boolean;
98
+ containerClassName?: string;
99
+ canvasStyle?: string;
100
+ enableToolbar?: boolean;
101
+ groupLeafNodes?: boolean;
102
+ groupLeafNodesSpacing?: number;
103
+ viewPortWidth?: number;
104
+ viewPortHeight?: number;
105
+ nodeTemplate?: (content: any) => string;
106
+ tooltipTemplate?: (content: any) => string;
107
+ onNodeClick?: (node: any) => void;
108
+ }
109
+ /**
110
+ * graph instance returned by render
111
+ */
112
+ interface ApexTreeGraph {
113
+ changeLayout(direction: TreeDirection): void;
114
+ collapse(nodeId: string): void;
115
+ expand(nodeId: string): void;
116
+ fitScreen(): void;
117
+ }
118
+ /**
119
+ * node click event payload
120
+ */
121
+ interface NodeClickEvent<T = any> {
122
+ node: TreeNode<T>;
123
+ event: MouseEvent;
124
+ }
125
+
126
+ declare class NgxApextreeComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy {
127
+ /**
128
+ * tree data to render
129
+ */
130
+ data: TreeNode | null;
131
+ /**
132
+ * tree configuration options
133
+ */
134
+ options: ApexTreeOptions;
135
+ /**
136
+ * emits when a node is clicked
137
+ */
138
+ nodeClick: EventEmitter<NodeClickEvent<any>>;
139
+ /**
140
+ * emits when graph is ready after initial render
141
+ */
142
+ graphReady: EventEmitter<ApexTreeGraph>;
143
+ /**
144
+ * emits when graph is updated after data/options change
145
+ */
146
+ graphUpdated: EventEmitter<ApexTreeGraph>;
147
+ /**
148
+ * custom node template
149
+ */
150
+ nodeTemplateRef: TemplateRef<any> | null;
151
+ /**
152
+ * custom tooltip template
153
+ */
154
+ tooltipTemplateRef: TemplateRef<any> | null;
155
+ private chartContainer;
156
+ private platformId;
157
+ private ngZone;
158
+ private treeInstance;
159
+ private graphInstance;
160
+ private isInitialized;
161
+ ngOnInit(): void;
162
+ ngAfterViewInit(): void;
163
+ ngOnChanges(changes: SimpleChanges): void;
164
+ ngOnDestroy(): void;
165
+ /**
166
+ * change the layout direction
167
+ */
168
+ changeLayout(direction: TreeDirection): void;
169
+ /**
170
+ * collapse a node by id
171
+ */
172
+ collapse(nodeId: string): void;
173
+ /**
174
+ * expand a node by id
175
+ */
176
+ expand(nodeId: string): void;
177
+ /**
178
+ * fit the graph to screen
179
+ */
180
+ fitScreen(): void;
181
+ /**
182
+ * get the underlying graph instance
183
+ */
184
+ getGraph(): ApexTreeGraph | null;
185
+ /**
186
+ * manually trigger a re-render
187
+ */
188
+ render(): void;
189
+ private initChart;
190
+ private updateChart;
191
+ private destroyChart;
192
+ private buildOptions;
193
+ private renderTemplate;
194
+ private extractHtmlFromView;
195
+ static ɵfac: i0.ɵɵFactoryDeclaration<NgxApextreeComponent, never>;
196
+ static ɵcmp: i0.ɵɵComponentDeclaration<NgxApextreeComponent, "ngx-apextree", never, { "data": { "alias": "data"; "required": false; }; "options": { "alias": "options"; "required": false; }; }, { "nodeClick": "nodeClick"; "graphReady": "graphReady"; "graphUpdated": "graphUpdated"; }, ["nodeTemplateRef", "tooltipTemplateRef"], never, true, never>;
197
+ }
198
+
199
+ /**
200
+ * injection token for apextree license key
201
+ */
202
+ declare const APEXTREE_LICENSE_KEY: InjectionToken<string>;
203
+ /**
204
+ * static method to set license
205
+ * call this before bootstrapping your app
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * import { setApexTreeLicense } from 'ngx-apextree';
210
+ *
211
+ * setApexTreeLicense('your-license-key-here');
212
+ *
213
+ * bootstrapApplication(AppComponent, appConfig);
214
+ * ```
215
+ */
216
+ declare function setApexTreeLicense(license: string): void;
217
+ /**
218
+ * get the currently set license key
219
+ */
220
+ declare function getApexTreeLicense(): string | null;
221
+ /**
222
+ * angular provider function for license configuration
223
+ * use this in your app config or module providers
224
+ *
225
+ * @example
226
+ * ```typescript
227
+ * // standalone app (app.config.ts)
228
+ * import { provideApexTreeLicense } from 'ngx-apextree';
229
+ *
230
+ * export const appConfig: ApplicationConfig = {
231
+ * providers: [
232
+ * provideApexTreeLicense('your-license-key-here'),
233
+ * ]
234
+ * };
235
+ *
236
+ * // module-based app (app.module.ts)
237
+ * @NgModule({
238
+ * providers: [
239
+ * provideApexTreeLicense('your-license-key-here'),
240
+ * ]
241
+ * })
242
+ * export class AppModule { }
243
+ * ```
244
+ */
245
+ declare function provideApexTreeLicense(license: string): Provider[];
246
+
247
+ export { APEXTREE_LICENSE_KEY, NgxApextreeComponent, getApexTreeLicense, provideApexTreeLicense, setApexTreeLicense };
248
+ export type { ApexTreeGraph, ApexTreeOptions, EdgeOptions, ExpandCollapseOptions, FontOptions, NodeClickEvent, NodeOptions, NodeStylingOptions, TooltipOptions, TreeDirection, TreeNode };