@acorex/charts 21.0.3-next.25 → 21.0.3-next.28
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/{types/acorex-charts-bar-chart.d.ts → bar-chart/index.d.ts} +3 -28
- package/{types/acorex-charts-donut-chart.d.ts → donut-chart/index.d.ts} +4 -22
- package/fesm2022/acorex-charts-bar-chart.mjs +66 -91
- package/fesm2022/acorex-charts-bar-chart.mjs.map +1 -1
- package/fesm2022/acorex-charts-chart-legend.mjs +13 -13
- package/fesm2022/acorex-charts-chart-legend.mjs.map +1 -1
- package/fesm2022/acorex-charts-chart-tooltip.mjs +11 -11
- package/fesm2022/acorex-charts-chart-tooltip.mjs.map +1 -1
- package/fesm2022/acorex-charts-donut-chart.mjs +50 -75
- package/fesm2022/acorex-charts-donut-chart.mjs.map +1 -1
- package/fesm2022/acorex-charts-funnel-chart.mjs +19 -19
- package/fesm2022/acorex-charts-funnel-chart.mjs.map +1 -1
- package/fesm2022/acorex-charts-gauge-chart.mjs +64 -45
- package/fesm2022/acorex-charts-gauge-chart.mjs.map +1 -1
- package/fesm2022/acorex-charts-heatmap-chart.mjs +16 -19
- package/fesm2022/acorex-charts-heatmap-chart.mjs.map +1 -1
- package/fesm2022/acorex-charts-hierarchy-chart.mjs +39 -80
- package/fesm2022/acorex-charts-hierarchy-chart.mjs.map +1 -1
- package/fesm2022/acorex-charts-line-chart.mjs +42 -109
- package/fesm2022/acorex-charts-line-chart.mjs.map +1 -1
- package/fesm2022/acorex-charts.mjs +69 -5
- package/fesm2022/acorex-charts.mjs.map +1 -1
- package/{types/acorex-charts-funnel-chart.d.ts → funnel-chart/index.d.ts} +3 -25
- package/{types/acorex-charts-gauge-chart.d.ts → gauge-chart/index.d.ts} +6 -21
- package/{types/acorex-charts-heatmap-chart.d.ts → heatmap-chart/index.d.ts} +2 -28
- package/{types/acorex-charts-hierarchy-chart.d.ts → hierarchy-chart/index.d.ts} +2 -27
- package/{types/acorex-charts.d.ts → index.d.ts} +52 -2
- package/{types/acorex-charts-line-chart.d.ts → line-chart/index.d.ts} +2 -38
- package/package.json +15 -16
- /package/{types/acorex-charts-chart-legend.d.ts → chart-legend/index.d.ts} +0 -0
- /package/{types/acorex-charts-chart-tooltip.d.ts → chart-tooltip/index.d.ts} +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as _acorex_charts_bar_chart from '@acorex/charts/bar-chart';
|
|
2
1
|
import * as _acorex_charts from '@acorex/charts';
|
|
3
2
|
import { NXNativeEvent, AXAnimationEasing, AXChartComponent, AXChartComponentBase } from '@acorex/charts';
|
|
4
3
|
import * as d3 from 'd3';
|
|
@@ -72,6 +71,7 @@ interface AXBarChartOption {
|
|
|
72
71
|
yAxisLabel?: string;
|
|
73
72
|
rotateXAxisLabels?: boolean | 'auto';
|
|
74
73
|
showTooltip?: boolean;
|
|
74
|
+
/** Percent of band width used by each bar (0–100). Default: 80. Values ≤ 1 are treated as fractions. */
|
|
75
75
|
barWidth?: number;
|
|
76
76
|
cornerRadius?: number;
|
|
77
77
|
animationDuration?: number;
|
|
@@ -161,32 +161,8 @@ declare class AXBarChartComponent extends AXChartComponent implements OnDestroy,
|
|
|
161
161
|
protected tooltipData: _angular_core.Signal<AXChartTooltipData>;
|
|
162
162
|
private configToken;
|
|
163
163
|
private chartColors;
|
|
164
|
-
protected effectiveOptions: _angular_core.Signal<
|
|
165
|
-
|
|
166
|
-
height?: number;
|
|
167
|
-
showXAxis?: boolean;
|
|
168
|
-
showYAxis?: boolean;
|
|
169
|
-
showGrid?: boolean;
|
|
170
|
-
showDataLabels?: boolean;
|
|
171
|
-
xAxisLabel?: string;
|
|
172
|
-
yAxisLabel?: string;
|
|
173
|
-
rotateXAxisLabels?: boolean | "auto";
|
|
174
|
-
showTooltip?: boolean;
|
|
175
|
-
barWidth?: number;
|
|
176
|
-
cornerRadius?: number;
|
|
177
|
-
animationDuration?: number;
|
|
178
|
-
animationDelay?: number;
|
|
179
|
-
animationEasing?: _acorex_charts.AXAnimationEasing;
|
|
180
|
-
messages?: _acorex_charts_bar_chart.AXBarChartMessages;
|
|
181
|
-
}>;
|
|
182
|
-
protected effectiveMessages: _angular_core.Signal<{
|
|
183
|
-
noData: string;
|
|
184
|
-
noDataHelp: string;
|
|
185
|
-
allHidden: string;
|
|
186
|
-
allHiddenHelp: string;
|
|
187
|
-
noDataIcon: string;
|
|
188
|
-
allHiddenIcon: string;
|
|
189
|
-
}>;
|
|
164
|
+
protected effectiveOptions: _angular_core.Signal<AXBarChartOption>;
|
|
165
|
+
protected effectiveMessages: _angular_core.Signal<Required<_acorex_charts.AXChartMessages>>;
|
|
190
166
|
private readonly hiddenBars;
|
|
191
167
|
private readonly hiddenSeries;
|
|
192
168
|
private readonly isClusteredMode;
|
|
@@ -319,7 +295,6 @@ declare class AXBarChartComponent extends AXChartComponent implements OnDestroy,
|
|
|
319
295
|
*/
|
|
320
296
|
private getYAxisTickFontSizeBasedOnHeight;
|
|
321
297
|
private buildXAxisCommon;
|
|
322
|
-
private showMessage;
|
|
323
298
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXBarChartComponent, never>;
|
|
324
299
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXBarChartComponent, "ax-bar-chart", never, { "data": { "alias": "data"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; }, { "barClick": "barClick"; }, never, never, true, never>;
|
|
325
300
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as _acorex_charts_donut_chart from '@acorex/charts/donut-chart';
|
|
2
1
|
import * as _acorex_charts from '@acorex/charts';
|
|
3
2
|
import { AXAnimationEasing, AXChartComponent, AXChartComponentBase } from '@acorex/charts';
|
|
4
3
|
import * as d3 from 'd3';
|
|
@@ -156,18 +155,7 @@ declare class AXDonutChartComponent extends AXChartComponent implements OnDestro
|
|
|
156
155
|
protected tooltipData: _angular_core.Signal<AXChartTooltipData>;
|
|
157
156
|
private configToken;
|
|
158
157
|
private chartColors;
|
|
159
|
-
protected effectiveOptions: _angular_core.Signal<
|
|
160
|
-
width?: number;
|
|
161
|
-
height?: number;
|
|
162
|
-
totalLabel?: string;
|
|
163
|
-
showTooltip?: boolean;
|
|
164
|
-
showDataLabels?: boolean;
|
|
165
|
-
donutWidth?: number;
|
|
166
|
-
cornerRadius?: number;
|
|
167
|
-
animationDuration?: number;
|
|
168
|
-
animationEasing?: _acorex_charts.AXAnimationEasing;
|
|
169
|
-
messages?: _acorex_charts_donut_chart.AXDonutChartMessages;
|
|
170
|
-
}>;
|
|
158
|
+
protected effectiveOptions: _angular_core.Signal<AXDonutChartOption>;
|
|
171
159
|
private readonly TOOLTIP_GAP;
|
|
172
160
|
private readonly HIGHLIGHT_TRANSITION_DURATION;
|
|
173
161
|
private readonly HIGHLIGHT_TRANSITION_NAME;
|
|
@@ -178,14 +166,9 @@ declare class AXDonutChartComponent extends AXChartComponent implements OnDestro
|
|
|
178
166
|
private readonly CHART_INSET;
|
|
179
167
|
private readonly DIMMED_OPACITY;
|
|
180
168
|
private readonly VISIBLE_OPACITY;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
allHidden: string;
|
|
185
|
-
allHiddenHelp: string;
|
|
186
|
-
noDataIcon: string;
|
|
187
|
-
allHiddenIcon: string;
|
|
188
|
-
}>;
|
|
169
|
+
private readonly instanceId;
|
|
170
|
+
private get segmentShadowFilterId();
|
|
171
|
+
protected effectiveMessages: _angular_core.Signal<Required<_acorex_charts.AXChartMessages>>;
|
|
189
172
|
protected chartDataArray: _angular_core.Signal<AXDonutChartData[]>;
|
|
190
173
|
protected getColor(index: number): string;
|
|
191
174
|
protected isSegmentHidden(id: string): boolean;
|
|
@@ -299,7 +282,6 @@ declare class AXDonutChartComponent extends AXChartComponent implements OnDestro
|
|
|
299
282
|
* Cleans up chart resources
|
|
300
283
|
*/
|
|
301
284
|
cleanupChart(): void;
|
|
302
|
-
private renderMessage;
|
|
303
285
|
/**
|
|
304
286
|
* Gets an accessibility label describing the donut chart for screen readers
|
|
305
287
|
* @returns Descriptive string for screen readers
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AXChartComponent, AX_CHART_COLOR_PALETTE, formatLargeNumber, getEasingFunction, getChartColor } from '@acorex/charts';
|
|
1
|
+
import { AX_CHART_DEFAULT_MESSAGES, AXChartComponent, AX_CHART_COLOR_PALETTE, mergeChartOptions, mergeChartMessages, resolveBarWidthFraction, formatLargeNumber, getEasingFunction, renderChartEmptyMessage, getChartColor } from '@acorex/charts';
|
|
2
2
|
import { AXChartTooltipComponent } from '@acorex/charts/chart-tooltip';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
4
|
import { InjectionToken, input, output, viewChild, signal, inject, computed, afterNextRender, effect, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
|
|
@@ -15,12 +15,8 @@ const AXBarChartDefaultConfig = {
|
|
|
15
15
|
animationDuration: 800,
|
|
16
16
|
animationEasing: 'cubic-out',
|
|
17
17
|
messages: {
|
|
18
|
-
|
|
19
|
-
noDataHelp: 'Please provide data to display the chart',
|
|
20
|
-
allHidden: 'All bars are hidden',
|
|
21
|
-
allHiddenHelp: 'Click on legend items to show bars',
|
|
18
|
+
...AX_CHART_DEFAULT_MESSAGES,
|
|
22
19
|
noDataIcon: 'fa-light fa-chart-column',
|
|
23
|
-
allHiddenIcon: 'fa-light fa-eye-slash',
|
|
24
20
|
},
|
|
25
21
|
};
|
|
26
22
|
const AX_BAR_CHART_CONFIG = new InjectionToken('AX_BAR_CHART_CONFIG', {
|
|
@@ -28,11 +24,14 @@ const AX_BAR_CHART_CONFIG = new InjectionToken('AX_BAR_CHART_CONFIG', {
|
|
|
28
24
|
factory: () => AXBarChartDefaultConfig,
|
|
29
25
|
});
|
|
30
26
|
function barChartConfig(config = {}) {
|
|
31
|
-
|
|
27
|
+
return {
|
|
32
28
|
...AXBarChartDefaultConfig,
|
|
33
29
|
...config,
|
|
30
|
+
messages: {
|
|
31
|
+
...AXBarChartDefaultConfig.messages,
|
|
32
|
+
...config.messages,
|
|
33
|
+
},
|
|
34
34
|
};
|
|
35
|
-
return result;
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
/**
|
|
@@ -42,9 +41,9 @@ function barChartConfig(config = {}) {
|
|
|
42
41
|
class AXBarChartComponent extends AXChartComponent {
|
|
43
42
|
// Inputs
|
|
44
43
|
/** Chart data input */
|
|
45
|
-
data = input([], ...(ngDevMode ? [{ debugName: "data" }] :
|
|
44
|
+
data = input([], ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
46
45
|
/** Chart options input */
|
|
47
|
-
options = input({}, ...(ngDevMode ? [{ debugName: "options" }] :
|
|
46
|
+
options = input({}, ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
48
47
|
// Outputs
|
|
49
48
|
/** Emitted when a bar is clicked */
|
|
50
49
|
barClick = output();
|
|
@@ -103,21 +102,21 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
103
102
|
MANY_ITEMS_THRESHOLD = 20;
|
|
104
103
|
VERY_MANY_ITEMS_THRESHOLD = 50;
|
|
105
104
|
// Animation state
|
|
106
|
-
_initialAnimationComplete = signal(false, ...(ngDevMode ? [{ debugName: "_initialAnimationComplete" }] :
|
|
105
|
+
_initialAnimationComplete = signal(false, ...(ngDevMode ? [{ debugName: "_initialAnimationComplete" }] : []));
|
|
107
106
|
// Tooltip state
|
|
108
|
-
_tooltipVisible = signal(false, ...(ngDevMode ? [{ debugName: "_tooltipVisible" }] :
|
|
109
|
-
_tooltipPosition = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "_tooltipPosition" }] :
|
|
107
|
+
_tooltipVisible = signal(false, ...(ngDevMode ? [{ debugName: "_tooltipVisible" }] : []));
|
|
108
|
+
_tooltipPosition = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "_tooltipPosition" }] : []));
|
|
110
109
|
_tooltipData = signal({
|
|
111
110
|
title: '',
|
|
112
111
|
value: '0',
|
|
113
112
|
percentage: '0%',
|
|
114
113
|
color: '',
|
|
115
|
-
}, ...(ngDevMode ? [{ debugName: "_tooltipData" }] :
|
|
114
|
+
}, ...(ngDevMode ? [{ debugName: "_tooltipData" }] : []));
|
|
116
115
|
_tooltipRafId = null;
|
|
117
116
|
_pendingTooltipCoords = null;
|
|
118
117
|
// Signals for component state
|
|
119
|
-
_initialized = signal(false, ...(ngDevMode ? [{ debugName: "_initialized" }] :
|
|
120
|
-
_rendered = signal(false, ...(ngDevMode ? [{ debugName: "_rendered" }] :
|
|
118
|
+
_initialized = signal(false, ...(ngDevMode ? [{ debugName: "_initialized" }] : []));
|
|
119
|
+
_rendered = signal(false, ...(ngDevMode ? [{ debugName: "_rendered" }] : []));
|
|
121
120
|
// Tooltip accessors
|
|
122
121
|
tooltipVisible = this._tooltipVisible.asReadonly();
|
|
123
122
|
tooltipPosition = this._tooltipPosition.asReadonly();
|
|
@@ -129,27 +128,9 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
129
128
|
// Inject AXPlatform
|
|
130
129
|
// Removed unused AXPlatform injection
|
|
131
130
|
// Configuration with defaults
|
|
132
|
-
effectiveOptions = computed(() => {
|
|
133
|
-
return {
|
|
134
|
-
...this.configToken,
|
|
135
|
-
...this.options(),
|
|
136
|
-
};
|
|
137
|
-
}, ...(ngDevMode ? [{ debugName: "effectiveOptions" }] : /* istanbul ignore next */ []));
|
|
131
|
+
effectiveOptions = computed(() => mergeChartOptions(this.configToken, this.options()), ...(ngDevMode ? [{ debugName: "effectiveOptions" }] : []));
|
|
138
132
|
// Messages with defaults
|
|
139
|
-
effectiveMessages = computed(() => {
|
|
140
|
-
const defaultMessages = {
|
|
141
|
-
noData: 'No data available',
|
|
142
|
-
noDataHelp: 'Please provide data to display the chart',
|
|
143
|
-
allHidden: 'All bars are hidden',
|
|
144
|
-
allHiddenHelp: 'Click on legend items to show bars',
|
|
145
|
-
noDataIcon: 'fa-light fa-chart-column',
|
|
146
|
-
allHiddenIcon: 'fa-light fa-eye-slash',
|
|
147
|
-
};
|
|
148
|
-
return {
|
|
149
|
-
...defaultMessages,
|
|
150
|
-
...this.effectiveOptions().messages,
|
|
151
|
-
};
|
|
152
|
-
}, ...(ngDevMode ? [{ debugName: "effectiveMessages" }] : /* istanbul ignore next */ []));
|
|
133
|
+
effectiveMessages = computed(() => mergeChartMessages(this.configToken.messages, this.options()?.messages), ...(ngDevMode ? [{ debugName: "effectiveMessages" }] : []));
|
|
153
134
|
// Track hidden bars and series
|
|
154
135
|
hiddenBars = new Set();
|
|
155
136
|
hiddenSeries = new Set();
|
|
@@ -157,14 +138,14 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
157
138
|
isClusteredMode = computed(() => {
|
|
158
139
|
const value = this.data();
|
|
159
140
|
return Array.isArray(value) && value.length > 0 && 'chartData' in value[0];
|
|
160
|
-
}, ...(ngDevMode ? [{ debugName: "isClusteredMode" }] :
|
|
141
|
+
}, ...(ngDevMode ? [{ debugName: "isClusteredMode" }] : []));
|
|
161
142
|
visibleData = computed(() => {
|
|
162
143
|
const value = this.data() || [];
|
|
163
144
|
if (this.isClusteredMode()) {
|
|
164
145
|
return value;
|
|
165
146
|
}
|
|
166
147
|
return value.filter((d) => !this.hiddenBars.has(d.id));
|
|
167
|
-
}, ...(ngDevMode ? [{ debugName: "visibleData" }] :
|
|
148
|
+
}, ...(ngDevMode ? [{ debugName: "visibleData" }] : []));
|
|
168
149
|
hasVisibleData = computed(() => {
|
|
169
150
|
const value = this.data();
|
|
170
151
|
if (!Array.isArray(value) || value.length === 0)
|
|
@@ -173,10 +154,10 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
173
154
|
const groups = value;
|
|
174
155
|
const seriesLabels = this.getClusterSeriesLabels(groups);
|
|
175
156
|
const visibleSeries = seriesLabels.filter((s) => !this.hiddenSeries.has(s));
|
|
176
|
-
return groups.some((g) => visibleSeries.some((
|
|
157
|
+
return groups.some((g) => visibleSeries.some((label) => !!g.chartData.find((item) => item.label === label)));
|
|
177
158
|
}
|
|
178
159
|
return value.some((d) => !this.hiddenBars.has(d.id));
|
|
179
|
-
}, ...(ngDevMode ? [{ debugName: "hasVisibleData" }] :
|
|
160
|
+
}, ...(ngDevMode ? [{ debugName: "hasVisibleData" }] : []));
|
|
180
161
|
// Type guard helper
|
|
181
162
|
isClusteredData(value) {
|
|
182
163
|
return Array.isArray(value) && value.length > 0 && 'chartData' in value[0];
|
|
@@ -371,7 +352,7 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
371
352
|
return Math.max(this.MIN_PLOT_HEIGHT, optionHeight - bottomPadding);
|
|
372
353
|
}
|
|
373
354
|
if (containerHeight > 0) {
|
|
374
|
-
return Math.max(this.MIN_PLOT_HEIGHT, containerHeight - bottomPadding
|
|
355
|
+
return Math.max(this.MIN_PLOT_HEIGHT, containerHeight - bottomPadding);
|
|
375
356
|
}
|
|
376
357
|
return this.FALLBACK_PLOT_HEIGHT;
|
|
377
358
|
}
|
|
@@ -389,10 +370,8 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
389
370
|
* Creates x and y scales for the chart
|
|
390
371
|
*/
|
|
391
372
|
setupScales(data) {
|
|
392
|
-
|
|
393
|
-
const
|
|
394
|
-
// Calculate padding based on barWidth (inverse relationship)
|
|
395
|
-
const padding = Math.max(this.MIN_PADDING, 1 - barWidthPercent);
|
|
373
|
+
const barWidthFraction = resolveBarWidthFraction(this.effectiveOptions().barWidth);
|
|
374
|
+
const padding = Math.max(this.MIN_PADDING, 1 - barWidthFraction);
|
|
396
375
|
// Create x scale (band scale for categorical data)
|
|
397
376
|
this.xScale = this.d3
|
|
398
377
|
.scaleBand()
|
|
@@ -430,8 +409,8 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
430
409
|
// Y scale across all visible values (support negative values)
|
|
431
410
|
const allVisibleValues = [];
|
|
432
411
|
for (const g of groups) {
|
|
433
|
-
visibleSeries.forEach((
|
|
434
|
-
const item = g.chartData
|
|
412
|
+
visibleSeries.forEach((label) => {
|
|
413
|
+
const item = g.chartData.find((d) => d.label === label);
|
|
435
414
|
if (item && typeof item.value === 'number')
|
|
436
415
|
allVisibleValues.push(item.value);
|
|
437
416
|
});
|
|
@@ -572,8 +551,8 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
572
551
|
const seriesLabels = groups.length > 0 ? this.getClusterSeriesLabels(groups) : [];
|
|
573
552
|
const visibleSeries = seriesLabels.filter((s) => !this.hiddenSeries.has(s));
|
|
574
553
|
for (const g of groups) {
|
|
575
|
-
visibleSeries.forEach((
|
|
576
|
-
const item = g.chartData
|
|
554
|
+
visibleSeries.forEach((label) => {
|
|
555
|
+
const item = g.chartData.find((d) => d.label === label);
|
|
577
556
|
if (item && typeof item.value === 'number')
|
|
578
557
|
maxValue = Math.max(maxValue, item.value);
|
|
579
558
|
});
|
|
@@ -789,7 +768,15 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
789
768
|
.attr('transform', (g) => `translate(${this.xScale(g.id)},0)`);
|
|
790
769
|
const barGroups = groupSel
|
|
791
770
|
.selectAll('.ax-bar-chart-bar-group')
|
|
792
|
-
.data((g) => visibleSeries.map((label
|
|
771
|
+
.data((g) => visibleSeries.map((label) => {
|
|
772
|
+
const seriesIndex = seriesLabels.indexOf(label);
|
|
773
|
+
return {
|
|
774
|
+
group: g,
|
|
775
|
+
seriesLabel: label,
|
|
776
|
+
seriesIndex,
|
|
777
|
+
item: g.chartData.find((d) => d.label === label) ?? g.chartData[seriesIndex],
|
|
778
|
+
};
|
|
779
|
+
}))
|
|
793
780
|
.enter()
|
|
794
781
|
.append('g')
|
|
795
782
|
.style('cursor', 'pointer')
|
|
@@ -805,8 +792,7 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
805
792
|
return `M${x},${y} L${x},${y} L${x + width},${y} L${x + width},${y} Z`;
|
|
806
793
|
})
|
|
807
794
|
.attr('fill', (d) => {
|
|
808
|
-
|
|
809
|
-
return item?.color || this.getColor(d.seriesIndex);
|
|
795
|
+
return d.item?.color || this.getColor(d.seriesIndex);
|
|
810
796
|
});
|
|
811
797
|
if (this.effectiveOptions().showDataLabels !== false) {
|
|
812
798
|
barGroups
|
|
@@ -820,10 +806,9 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
820
806
|
.style('fill', 'rgb(var(--ax-comp-bar-chart-data-labels-color))')
|
|
821
807
|
.style('opacity', 0)
|
|
822
808
|
.text((d) => {
|
|
823
|
-
const value = d.
|
|
809
|
+
const value = d.item?.value;
|
|
824
810
|
if (value === undefined)
|
|
825
811
|
return '';
|
|
826
|
-
// Format large numbers in data labels
|
|
827
812
|
return value >= 1000 ? formatLargeNumber(value) : value;
|
|
828
813
|
});
|
|
829
814
|
const animationDelay = this.effectiveOptions().animationDelay ?? this.DEFAULT_ANIMATION_DELAY;
|
|
@@ -833,10 +818,9 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
833
818
|
.duration(animationDuration)
|
|
834
819
|
.delay((_d, i) => i * animationDelay + this.LABEL_ANIMATION_DELAY)
|
|
835
820
|
.attr('y', (d) => {
|
|
836
|
-
|
|
837
|
-
if (!item)
|
|
821
|
+
if (!d.item)
|
|
838
822
|
return this.height;
|
|
839
|
-
const barTop = this.yScale(item.value);
|
|
823
|
+
const barTop = this.yScale(d.item.value);
|
|
840
824
|
// If bar is near the top (100% or close), position label inside the bar
|
|
841
825
|
if (barTop < this.MIN_TOP_SPACE_FOR_LABEL) {
|
|
842
826
|
return barTop + this.LABEL_OFFSET;
|
|
@@ -845,10 +829,9 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
845
829
|
return barTop - this.LABEL_OFFSET;
|
|
846
830
|
})
|
|
847
831
|
.attr('data-inside-bar', (d) => {
|
|
848
|
-
|
|
849
|
-
if (!item)
|
|
832
|
+
if (!d.item)
|
|
850
833
|
return 'false';
|
|
851
|
-
const barTop = this.yScale(item.value);
|
|
834
|
+
const barTop = this.yScale(d.item.value);
|
|
852
835
|
return barTop < this.MIN_TOP_SPACE_FOR_LABEL ? 'true' : 'false';
|
|
853
836
|
})
|
|
854
837
|
.style('opacity', 1)
|
|
@@ -863,9 +846,8 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
863
846
|
.transition()
|
|
864
847
|
.duration(this.HOVER_TRANSITION_DURATION)
|
|
865
848
|
.style('filter', 'brightness(0.7) drop-shadow(0 0 2px rgba(0,0,0,0.1))');
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
this.handleBarHover(event, item, d.group);
|
|
849
|
+
if (d.item)
|
|
850
|
+
this.handleBarHover(event, d.item, d.group);
|
|
869
851
|
})
|
|
870
852
|
.on('mousemove', (event) => {
|
|
871
853
|
if (this._initialAnimationComplete())
|
|
@@ -881,9 +863,8 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
881
863
|
.on('click', (event, d) => {
|
|
882
864
|
if (!this._initialAnimationComplete())
|
|
883
865
|
return;
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
this.handleBarClick(event, item);
|
|
866
|
+
if (d.item)
|
|
867
|
+
this.handleBarClick(event, d.item);
|
|
887
868
|
});
|
|
888
869
|
const animationDelay = this.effectiveOptions().animationDelay ?? this.DEFAULT_ANIMATION_DELAY;
|
|
889
870
|
bars
|
|
@@ -893,8 +874,7 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
893
874
|
.attrTween('d', (d) => {
|
|
894
875
|
const x = this.xSubScale(d.seriesLabel);
|
|
895
876
|
const width = this.xSubScale.bandwidth();
|
|
896
|
-
const
|
|
897
|
-
const finalHeight = item ? this.height - this.yScale(item.value) : 0;
|
|
877
|
+
const finalHeight = d.item ? this.height - this.yScale(d.item.value) : 0;
|
|
898
878
|
return (t) => {
|
|
899
879
|
const currentHeight = finalHeight * t;
|
|
900
880
|
const currentY = this.height - currentHeight;
|
|
@@ -1024,15 +1004,23 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
1024
1004
|
* Shows a message when no data is available
|
|
1025
1005
|
*/
|
|
1026
1006
|
showNoDataMessage(containerElement) {
|
|
1027
|
-
this.
|
|
1028
|
-
|
|
1007
|
+
const messages = this.effectiveMessages();
|
|
1008
|
+
renderChartEmptyMessage(this.d3, containerElement, {
|
|
1009
|
+
icon: messages.noDataIcon,
|
|
1010
|
+
title: messages.noData,
|
|
1011
|
+
help: messages.noDataHelp,
|
|
1012
|
+
});
|
|
1029
1013
|
}
|
|
1030
1014
|
/**
|
|
1031
1015
|
* Shows a message when all bars are hidden
|
|
1032
1016
|
*/
|
|
1033
1017
|
showAllBarsHiddenMessage(containerElement) {
|
|
1034
|
-
this.
|
|
1035
|
-
|
|
1018
|
+
const messages = this.effectiveMessages();
|
|
1019
|
+
renderChartEmptyMessage(this.d3, containerElement, {
|
|
1020
|
+
icon: messages.allHiddenIcon,
|
|
1021
|
+
title: messages.allHidden,
|
|
1022
|
+
help: messages.allHiddenHelp,
|
|
1023
|
+
});
|
|
1036
1024
|
}
|
|
1037
1025
|
/**
|
|
1038
1026
|
* Gets the color for a bar based on its index
|
|
@@ -1237,7 +1225,7 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
1237
1225
|
return this.chartContainerEl()?.nativeElement ?? null;
|
|
1238
1226
|
}
|
|
1239
1227
|
clearChartArea(containerElement) {
|
|
1240
|
-
this.d3.select(containerElement).selectAll('svg, .ax-chart-message-container').remove();
|
|
1228
|
+
this.d3.select(containerElement).selectAll('svg, .ax-chart-empty, .ax-chart-message-container').remove();
|
|
1241
1229
|
}
|
|
1242
1230
|
/**
|
|
1243
1231
|
* Truncates long labels with ellipsis
|
|
@@ -1325,26 +1313,13 @@ class AXBarChartComponent extends AXChartComponent {
|
|
|
1325
1313
|
this.createXAxisTitle(axesGroup, options.xAxisLabel, tickAreaHeight, gapBelowTicks);
|
|
1326
1314
|
}
|
|
1327
1315
|
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
const container = this.d3
|
|
1331
|
-
.select(containerElement)
|
|
1332
|
-
.append('div')
|
|
1333
|
-
.attr('class', `ax-chart-message-container ax-bar-chart-message-background ${specificClass}`);
|
|
1334
|
-
container
|
|
1335
|
-
.append('div')
|
|
1336
|
-
.attr('class', 'ax-chart-message-icon ax-bar-chart-no-data-icon')
|
|
1337
|
-
.html(`<i class="${iconClass} fa-2x"></i>`);
|
|
1338
|
-
container.append('div').attr('class', 'ax-chart-message-text ax-bar-chart-no-data-text').text(text);
|
|
1339
|
-
container.append('div').attr('class', 'ax-chart-message-help ax-bar-chart-no-data-help').text(helpText);
|
|
1340
|
-
}
|
|
1341
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXBarChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1342
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.9", 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;min-height:0;box-sizing:border-box;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 });
|
|
1316
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXBarChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1317
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.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-chart-empty{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;display:flex;align-items:center;justify-content:center;box-sizing:border-box;padding:1rem;pointer-events:none}.ax-chart-empty__card{text-align:center;padding:1.5rem;border-radius:.5rem;border:1px solid rgba(var(--ax-sys-color-surface));width:80%;max-width:300px;box-sizing:border-box}.ax-chart-empty__icon{opacity:.6;margin-bottom:.75rem}.ax-chart-empty__title{font-size:1rem;font-weight:600;margin-bottom:.5rem}.ax-chart-empty__help{font-size:.8rem;opacity:.6}ax-bar-chart{display:block;width:100%;height:100%;min-height:clamp(220px,38vw,360px);box-sizing:border-box;--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;min-height:0;box-sizing:border-box;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)}\n"], dependencies: [{ kind: "component", type: AXChartTooltipComponent, selector: "ax-chart-tooltip", inputs: ["data", "position", "visible", "showPercentage", "style"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1343
1318
|
}
|
|
1344
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1319
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXBarChartComponent, decorators: [{
|
|
1345
1320
|
type: Component,
|
|
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;min-height:0;box-sizing:border-box;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)}
|
|
1347
|
-
}], ctorParameters: () => []
|
|
1321
|
+
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-chart-empty{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;display:flex;align-items:center;justify-content:center;box-sizing:border-box;padding:1rem;pointer-events:none}.ax-chart-empty__card{text-align:center;padding:1.5rem;border-radius:.5rem;border:1px solid rgba(var(--ax-sys-color-surface));width:80%;max-width:300px;box-sizing:border-box}.ax-chart-empty__icon{opacity:.6;margin-bottom:.75rem}.ax-chart-empty__title{font-size:1rem;font-weight:600;margin-bottom:.5rem}.ax-chart-empty__help{font-size:.8rem;opacity:.6}ax-bar-chart{display:block;width:100%;height:100%;min-height:clamp(220px,38vw,360px);box-sizing:border-box;--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;min-height:0;box-sizing:border-box;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)}\n"] }]
|
|
1322
|
+
}], ctorParameters: () => [] });
|
|
1348
1323
|
|
|
1349
1324
|
/**
|
|
1350
1325
|
* Generated bundle index. Do not edit.
|