@acorex/charts 21.0.1-next.7 → 21.0.1-next.70

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.
Files changed (33) hide show
  1. package/fesm2022/acorex-charts-bar-chart.mjs +37 -23
  2. package/fesm2022/acorex-charts-bar-chart.mjs.map +1 -1
  3. package/fesm2022/acorex-charts-chart-legend.mjs +3 -3
  4. package/fesm2022/acorex-charts-chart-legend.mjs.map +1 -1
  5. package/fesm2022/acorex-charts-chart-tooltip.mjs +13 -4
  6. package/fesm2022/acorex-charts-chart-tooltip.mjs.map +1 -1
  7. package/fesm2022/acorex-charts-donut-chart.mjs +83 -99
  8. package/fesm2022/acorex-charts-donut-chart.mjs.map +1 -1
  9. package/fesm2022/acorex-charts-funnel-chart.mjs +275 -0
  10. package/fesm2022/acorex-charts-funnel-chart.mjs.map +1 -0
  11. package/fesm2022/acorex-charts-gauge-chart.mjs +157 -86
  12. package/fesm2022/acorex-charts-gauge-chart.mjs.map +1 -1
  13. package/fesm2022/acorex-charts-heatmap-chart.mjs +281 -0
  14. package/fesm2022/acorex-charts-heatmap-chart.mjs.map +1 -0
  15. package/fesm2022/acorex-charts-hierarchy-chart.mjs +3 -3
  16. package/fesm2022/acorex-charts-hierarchy-chart.mjs.map +1 -1
  17. package/fesm2022/acorex-charts-line-chart.mjs +37 -23
  18. package/fesm2022/acorex-charts-line-chart.mjs.map +1 -1
  19. package/fesm2022/acorex-charts.mjs +3 -3
  20. package/fesm2022/acorex-charts.mjs.map +1 -1
  21. package/funnel-chart/README.md +3 -0
  22. package/heatmap-chart/README.md +3 -0
  23. package/package.json +19 -13
  24. package/{bar-chart/index.d.ts → types/acorex-charts-bar-chart.d.ts} +7 -6
  25. package/{chart-tooltip/index.d.ts → types/acorex-charts-chart-tooltip.d.ts} +1 -0
  26. package/{donut-chart/index.d.ts → types/acorex-charts-donut-chart.d.ts} +12 -11
  27. package/types/acorex-charts-funnel-chart.d.ts +108 -0
  28. package/{gauge-chart/index.d.ts → types/acorex-charts-gauge-chart.d.ts} +16 -5
  29. package/types/acorex-charts-heatmap-chart.d.ts +111 -0
  30. package/{hierarchy-chart/index.d.ts → types/acorex-charts-hierarchy-chart.d.ts} +4 -3
  31. package/{line-chart/index.d.ts → types/acorex-charts-line-chart.d.ts} +5 -1
  32. /package/{chart-legend/index.d.ts → types/acorex-charts-chart-legend.d.ts} +0 -0
  33. /package/{index.d.ts → types/acorex-charts.d.ts} +0 -0
@@ -73,7 +73,9 @@ class AXBarChartComponent extends AXChartComponent {
73
73
  X_AXIS_TITLE_FONT_SIZE = 14;
74
74
  X_AXIS_TITLE_GAP = 14;
75
75
  X_AXIS_TITLE_BLOCK_HEIGHT = 24;
76
- TOP_EDGE_PADDING = 6;
76
+ TOP_EDGE_PADDING = 8;
77
+ BOTTOM_EDGE_PADDING = 8;
78
+ HORIZONTAL_EDGE_PADDING = 12;
77
79
  FALLBACK_PLOT_HEIGHT = 240;
78
80
  MIN_PLOT_HEIGHT = 120;
79
81
  MIN_TOTAL_WIDTH = 200;
@@ -111,6 +113,8 @@ class AXBarChartComponent extends AXChartComponent {
111
113
  percentage: '0%',
112
114
  color: '',
113
115
  }, ...(ngDevMode ? [{ debugName: "_tooltipData" }] : []));
116
+ _tooltipRafId = null;
117
+ _pendingTooltipCoords = null;
114
118
  // Signals for component state
115
119
  _initialized = signal(false, ...(ngDevMode ? [{ debugName: "_initialized" }] : []));
116
120
  _rendered = signal(false, ...(ngDevMode ? [{ debugName: "_rendered" }] : []));
@@ -272,9 +276,13 @@ class AXBarChartComponent extends AXChartComponent {
272
276
  * Cleans up chart resources
273
277
  */
274
278
  cleanupChart() {
279
+ if (this._tooltipRafId != null) {
280
+ cancelAnimationFrame(this._tooltipRafId);
281
+ this._tooltipRafId = null;
282
+ }
283
+ this._pendingTooltipCoords = null;
275
284
  const container = this.chartContainerEl()?.nativeElement;
276
285
  if (container) {
277
- // Only remove chart SVG and message containers to preserve tooltip component
278
286
  this.d3?.select(container).selectAll('svg, .ax-chart-message-container').remove();
279
287
  }
280
288
  this.svg = undefined;
@@ -299,6 +307,8 @@ class AXBarChartComponent extends AXChartComponent {
299
307
  const leftPaddingForYAxis = showYAxis
300
308
  ? this.calculateMaxYAxisTickLabelWidth() + this.AXIS_TICK_PADDING + yAxisTitlePadding + yAxisTitleThickness
301
309
  : 0;
310
+ const leftInnerPadding = leftPaddingForYAxis + this.HORIZONTAL_EDGE_PADDING;
311
+ const rightInnerPadding = this.HORIZONTAL_EDGE_PADDING;
302
312
  // Estimate internal bottom padding for X-axis ticks/labels/title
303
313
  let bottomPaddingForXAxis = 0;
304
314
  if (showXAxis) {
@@ -314,7 +324,7 @@ class AXBarChartComponent extends AXChartComponent {
314
324
  return flat.reduce((a, b) => (a.length > b.label.length ? a : b.label), '');
315
325
  })();
316
326
  const baseWidth = options.width ?? containerWidth;
317
- const workingWidth = Math.max(1, baseWidth - leftPaddingForYAxis);
327
+ const workingWidth = Math.max(1, baseWidth - leftInnerPadding - rightInnerPadding);
318
328
  const dynamicFontSize = Math.max(10, Math.min(14, Math.round(workingWidth / 50)));
319
329
  // Use truncated label length for calculation (same logic as actual rendering)
320
330
  const maxLabelLength = barCount > this.MANY_ITEMS_THRESHOLD ? 10 : this.MAX_LABEL_LENGTH;
@@ -333,17 +343,17 @@ class AXBarChartComponent extends AXChartComponent {
333
343
  // Determine plotting dimensions with sensible fallbacks
334
344
  const baseWidth = options.width ?? containerWidth;
335
345
  const totalWidth = Math.max(this.MIN_TOTAL_WIDTH, baseWidth > 0 ? baseWidth : this.MIN_TOTAL_WIDTH);
336
- const plotWidth = Math.max(0, totalWidth - leftPaddingForYAxis);
346
+ const plotWidth = Math.max(0, totalWidth - leftInnerPadding - rightInnerPadding);
337
347
  const plotHeight = this.calculatePlotHeight(options.height, containerHeight, bottomPaddingForXAxis);
338
348
  this.width = plotWidth;
339
349
  this.height = plotHeight;
340
350
  // Create SVG with explicit pixel dimensions to avoid collapse
341
- const totalHeight = this.height + bottomPaddingForXAxis + this.TOP_EDGE_PADDING;
351
+ const totalHeight = this.height + bottomPaddingForXAxis + this.TOP_EDGE_PADDING + this.BOTTOM_EDGE_PADDING;
342
352
  const svg = this.d3
343
353
  .select(containerElement)
344
354
  .append('svg')
345
355
  .attr('width', '100%')
346
- .attr('height', String(totalHeight))
356
+ .attr('height', '100%')
347
357
  .attr('viewBox', `0 0 ${totalWidth} ${totalHeight}`)
348
358
  .attr('preserveAspectRatio', 'xMidYMid meet');
349
359
  this.svg = svg;
@@ -351,7 +361,7 @@ class AXBarChartComponent extends AXChartComponent {
351
361
  this.chart = this.svg
352
362
  .append('g')
353
363
  .attr('class', 'chart-content')
354
- .attr('transform', `translate(${leftPaddingForYAxis},${this.TOP_EDGE_PADDING})`);
364
+ .attr('transform', `translate(${leftInnerPadding},${this.TOP_EDGE_PADDING})`);
355
365
  }
356
366
  /**
357
367
  * Calculates plot height based on options and container dimensions
@@ -934,20 +944,24 @@ class AXBarChartComponent extends AXChartComponent {
934
944
  this._tooltipVisible.set(true);
935
945
  }
936
946
  }
937
- /**
938
- * Updates tooltip position based on mouse coordinates
939
- * Enhanced to handle overflow issues by positioning tooltips more intelligently
940
- */
941
947
  updateTooltipPosition(event) {
942
- const containerEl = this.chartContainerEl()?.nativeElement;
943
- if (!containerEl)
948
+ this._pendingTooltipCoords = { x: event.clientX, y: event.clientY };
949
+ if (this._tooltipRafId != null)
944
950
  return;
945
- const containerRect = containerEl.getBoundingClientRect();
946
- const tooltipEl = containerEl.querySelector('.chart-tooltip');
947
- const tooltipRect = tooltipEl ? tooltipEl.getBoundingClientRect() : null;
948
- // Enhanced positioning logic for better tooltip placement
949
- const pos = this.computeEnhancedTooltipPosition(containerRect, tooltipRect, event.clientX, event.clientY);
950
- this._tooltipPosition.set(pos);
951
+ this._tooltipRafId = requestAnimationFrame(() => {
952
+ this._tooltipRafId = null;
953
+ const coords = this._pendingTooltipCoords;
954
+ if (!coords)
955
+ return;
956
+ const containerEl = this.chartContainerEl()?.nativeElement;
957
+ if (!containerEl)
958
+ return;
959
+ const containerRect = containerEl.getBoundingClientRect();
960
+ const tooltipEl = containerEl.querySelector('.chart-tooltip');
961
+ const tooltipRect = tooltipEl ? tooltipEl.getBoundingClientRect() : null;
962
+ const pos = this.computeEnhancedTooltipPosition(containerRect, tooltipRect, coords.x, coords.y);
963
+ this._tooltipPosition.set(pos);
964
+ });
951
965
  }
952
966
  /**
953
967
  * Enhanced tooltip positioning that considers chart boundaries and prevents overflow
@@ -1324,12 +1338,12 @@ class AXBarChartComponent extends AXChartComponent {
1324
1338
  container.append('div').attr('class', 'ax-chart-message-text ax-bar-chart-no-data-text').text(text);
1325
1339
  container.append('div').attr('class', 'ax-chart-message-help ax-bar-chart-no-data-help').text(helpText);
1326
1340
  }
1327
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AXBarChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1328
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.15", type: AXBarChartComponent, isStandalone: true, selector: "ax-bar-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { barClick: "barClick" }, viewQueries: [{ propertyName: "chartContainerEl", first: true, predicate: ["chartContainer"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-bar-chart\" role=\"img\" #chartContainer>\n <!-- Shared tooltip component -->\n <ax-chart-tooltip\n [visible]=\"tooltipVisible()\"\n [position]=\"tooltipPosition()\"\n [data]=\"tooltipData()\"\n [showPercentage]=\"true\"\n ></ax-chart-tooltip>\n</div>\n", styles: ["ax-bar-chart{display:block;width:100%;height:100%;min-height:200px;--ax-comp-bar-chart-axis-label-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-labels-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-data-labels-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-grid-lines-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-bg-color: 0, 0, 0, 0}ax-bar-chart .ax-bar-chart{width:100%;height:100%;position:relative;display:flex;align-items:center;justify-content:center;border-radius:.5rem;background-color:rgba(var(--ax-comp-bar-chart-bg-color))}ax-bar-chart .ax-bar-chart svg{width:100%;height:100%;max-width:100%;max-height:100%;overflow:hidden}ax-bar-chart .ax-bar-chart svg g:has(text){font-family:inherit}ax-bar-chart .ax-bar-chart .ax-bar-chart-data-label{pointer-events:none;-webkit-user-select:none;user-select:none}ax-bar-chart .ax-bar-chart .ax-bar-chart-data-label[data-inside-bar=true]{fill:#fff;font-weight:600;text-shadow:0 0 2px rgba(0,0,0,.3)}ax-bar-chart .ax-bar-chart-no-data-message{text-align:center;background-color:rgb(var(--ax-comp-bar-chart-bg-color));padding:1.5rem;border-radius:.5rem;border:1px solid rgba(var(--ax-sys-color-surface));width:80%;max-width:300px}ax-bar-chart .ax-bar-chart-no-data-message .ax-bar-chart-no-data-icon{opacity:.6;margin-bottom:.75rem}ax-bar-chart .ax-bar-chart-no-data-message .ax-bar-chart-no-data-text{font-size:1rem;font-weight:600;margin-bottom:.5rem}ax-bar-chart .ax-bar-chart-no-data-message .ax-bar-chart-no-data-help{font-size:.8rem;opacity:.6}\n"], dependencies: [{ kind: "component", type: AXChartTooltipComponent, selector: "ax-chart-tooltip", inputs: ["data", "position", "visible", "showPercentage", "style"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1341
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: AXBarChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1342
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.1.3", type: AXBarChartComponent, isStandalone: true, selector: "ax-bar-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { barClick: "barClick" }, viewQueries: [{ propertyName: "chartContainerEl", first: true, predicate: ["chartContainer"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-bar-chart\" role=\"img\" #chartContainer>\n <!-- Shared tooltip component -->\n <ax-chart-tooltip\n [visible]=\"tooltipVisible()\"\n [position]=\"tooltipPosition()\"\n [data]=\"tooltipData()\"\n [showPercentage]=\"true\"\n ></ax-chart-tooltip>\n</div>\n", styles: ["ax-bar-chart{display:block;width:100%;height:100%;min-height:clamp(220px,38vw,360px);--ax-comp-bar-chart-axis-label-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-labels-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-data-labels-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-grid-lines-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-bg-color: 0, 0, 0, 0}ax-bar-chart .ax-bar-chart{width:100%;height:100%;position:relative;box-sizing:border-box;padding:clamp(.5rem,1.2vw,.875rem);border-radius:.5rem;overflow:hidden;background-color:rgba(var(--ax-comp-bar-chart-bg-color))}ax-bar-chart .ax-bar-chart svg{display:block;width:100%;height:100%;max-width:100%;max-height:100%}ax-bar-chart .ax-bar-chart svg g:has(text){font-family:inherit}ax-bar-chart .ax-bar-chart .ax-bar-chart-data-label{pointer-events:none;-webkit-user-select:none;user-select:none}ax-bar-chart .ax-bar-chart .ax-bar-chart-data-label[data-inside-bar=true]{fill:#fff;font-weight:600;text-shadow:0 0 2px rgba(0,0,0,.3)}ax-bar-chart .ax-bar-chart-no-data-message{text-align:center;background-color:rgb(var(--ax-comp-bar-chart-bg-color));padding:1.5rem;border-radius:.5rem;border:1px solid rgba(var(--ax-sys-color-surface));width:80%;max-width:300px}ax-bar-chart .ax-bar-chart-no-data-message .ax-bar-chart-no-data-icon{opacity:.6;margin-bottom:.75rem}ax-bar-chart .ax-bar-chart-no-data-message .ax-bar-chart-no-data-text{font-size:1rem;font-weight:600;margin-bottom:.5rem}ax-bar-chart .ax-bar-chart-no-data-message .ax-bar-chart-no-data-help{font-size:.8rem;opacity:.6}\n"], dependencies: [{ kind: "component", type: AXChartTooltipComponent, selector: "ax-chart-tooltip", inputs: ["data", "position", "visible", "showPercentage", "style"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1329
1343
  }
1330
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AXBarChartComponent, decorators: [{
1344
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: AXBarChartComponent, decorators: [{
1331
1345
  type: Component,
1332
- args: [{ selector: 'ax-bar-chart', encapsulation: ViewEncapsulation.None, imports: [AXChartTooltipComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ax-bar-chart\" role=\"img\" #chartContainer>\n <!-- Shared tooltip component -->\n <ax-chart-tooltip\n [visible]=\"tooltipVisible()\"\n [position]=\"tooltipPosition()\"\n [data]=\"tooltipData()\"\n [showPercentage]=\"true\"\n ></ax-chart-tooltip>\n</div>\n", styles: ["ax-bar-chart{display:block;width:100%;height:100%;min-height:200px;--ax-comp-bar-chart-axis-label-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-labels-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-data-labels-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-grid-lines-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-bg-color: 0, 0, 0, 0}ax-bar-chart .ax-bar-chart{width:100%;height:100%;position:relative;display:flex;align-items:center;justify-content:center;border-radius:.5rem;background-color:rgba(var(--ax-comp-bar-chart-bg-color))}ax-bar-chart .ax-bar-chart svg{width:100%;height:100%;max-width:100%;max-height:100%;overflow:hidden}ax-bar-chart .ax-bar-chart svg g:has(text){font-family:inherit}ax-bar-chart .ax-bar-chart .ax-bar-chart-data-label{pointer-events:none;-webkit-user-select:none;user-select:none}ax-bar-chart .ax-bar-chart .ax-bar-chart-data-label[data-inside-bar=true]{fill:#fff;font-weight:600;text-shadow:0 0 2px rgba(0,0,0,.3)}ax-bar-chart .ax-bar-chart-no-data-message{text-align:center;background-color:rgb(var(--ax-comp-bar-chart-bg-color));padding:1.5rem;border-radius:.5rem;border:1px solid rgba(var(--ax-sys-color-surface));width:80%;max-width:300px}ax-bar-chart .ax-bar-chart-no-data-message .ax-bar-chart-no-data-icon{opacity:.6;margin-bottom:.75rem}ax-bar-chart .ax-bar-chart-no-data-message .ax-bar-chart-no-data-text{font-size:1rem;font-weight:600;margin-bottom:.5rem}ax-bar-chart .ax-bar-chart-no-data-message .ax-bar-chart-no-data-help{font-size:.8rem;opacity:.6}\n"] }]
1346
+ args: [{ selector: 'ax-bar-chart', encapsulation: ViewEncapsulation.None, imports: [AXChartTooltipComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ax-bar-chart\" role=\"img\" #chartContainer>\n <!-- Shared tooltip component -->\n <ax-chart-tooltip\n [visible]=\"tooltipVisible()\"\n [position]=\"tooltipPosition()\"\n [data]=\"tooltipData()\"\n [showPercentage]=\"true\"\n ></ax-chart-tooltip>\n</div>\n", styles: ["ax-bar-chart{display:block;width:100%;height:100%;min-height:clamp(220px,38vw,360px);--ax-comp-bar-chart-axis-label-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-labels-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-data-labels-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-grid-lines-color: var(--ax-sys-color-on-lightest-surface);--ax-comp-bar-chart-bg-color: 0, 0, 0, 0}ax-bar-chart .ax-bar-chart{width:100%;height:100%;position:relative;box-sizing:border-box;padding:clamp(.5rem,1.2vw,.875rem);border-radius:.5rem;overflow:hidden;background-color:rgba(var(--ax-comp-bar-chart-bg-color))}ax-bar-chart .ax-bar-chart svg{display:block;width:100%;height:100%;max-width:100%;max-height:100%}ax-bar-chart .ax-bar-chart svg g:has(text){font-family:inherit}ax-bar-chart .ax-bar-chart .ax-bar-chart-data-label{pointer-events:none;-webkit-user-select:none;user-select:none}ax-bar-chart .ax-bar-chart .ax-bar-chart-data-label[data-inside-bar=true]{fill:#fff;font-weight:600;text-shadow:0 0 2px rgba(0,0,0,.3)}ax-bar-chart .ax-bar-chart-no-data-message{text-align:center;background-color:rgb(var(--ax-comp-bar-chart-bg-color));padding:1.5rem;border-radius:.5rem;border:1px solid rgba(var(--ax-sys-color-surface));width:80%;max-width:300px}ax-bar-chart .ax-bar-chart-no-data-message .ax-bar-chart-no-data-icon{opacity:.6;margin-bottom:.75rem}ax-bar-chart .ax-bar-chart-no-data-message .ax-bar-chart-no-data-text{font-size:1rem;font-weight:600;margin-bottom:.5rem}ax-bar-chart .ax-bar-chart-no-data-message .ax-bar-chart-no-data-help{font-size:.8rem;opacity:.6}\n"] }]
1333
1347
  }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], barClick: [{ type: i0.Output, args: ["barClick"] }], chartContainerEl: [{ type: i0.ViewChild, args: ['chartContainer', { isSignal: true }] }] } });
1334
1348
 
1335
1349
  /**