@acorex/charts 0.0.1
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/README.md +72 -0
- package/bar-chart/README.md +3 -0
- package/bar-chart/index.d.ts +211 -0
- package/chart-legend/index.d.ts +104 -0
- package/chart-tooltip/README.md +3 -0
- package/chart-tooltip/index.d.ts +54 -0
- package/donut-chart/README.md +3 -0
- package/donut-chart/index.d.ts +251 -0
- package/fesm2022/acorex-charts-bar-chart.mjs +772 -0
- package/fesm2022/acorex-charts-bar-chart.mjs.map +1 -0
- package/fesm2022/acorex-charts-chart-legend.mjs +109 -0
- package/fesm2022/acorex-charts-chart-legend.mjs.map +1 -0
- package/fesm2022/acorex-charts-chart-tooltip.mjs +74 -0
- package/fesm2022/acorex-charts-chart-tooltip.mjs.map +1 -0
- package/fesm2022/acorex-charts-donut-chart.mjs +758 -0
- package/fesm2022/acorex-charts-donut-chart.mjs.map +1 -0
- package/fesm2022/acorex-charts-gauge-chart.mjs +686 -0
- package/fesm2022/acorex-charts-gauge-chart.mjs.map +1 -0
- package/fesm2022/acorex-charts-hierarchy-chart.mjs +700 -0
- package/fesm2022/acorex-charts-hierarchy-chart.mjs.map +1 -0
- package/fesm2022/acorex-charts-line-chart.mjs +995 -0
- package/fesm2022/acorex-charts-line-chart.mjs.map +1 -0
- package/fesm2022/acorex-charts.mjs +41 -0
- package/fesm2022/acorex-charts.mjs.map +1 -0
- package/gauge-chart/README.md +3 -0
- package/gauge-chart/index.d.ts +218 -0
- package/hierarchy-chart/README.md +61 -0
- package/hierarchy-chart/index.d.ts +368 -0
- package/index.d.ts +14 -0
- package/line-chart/README.md +3 -0
- package/line-chart/index.d.ts +184 -0
- package/package.json +52 -0
|
@@ -0,0 +1,772 @@
|
|
|
1
|
+
import { NXComponent } from '@acorex/cdk/common';
|
|
2
|
+
import { AX_CHART_COLOR_PALETTE, getChartColor } from '@acorex/charts';
|
|
3
|
+
import { AXChartTooltipComponent } from '@acorex/charts/chart-tooltip';
|
|
4
|
+
import { AXPlatform } from '@acorex/core/platform';
|
|
5
|
+
import * as i0 from '@angular/core';
|
|
6
|
+
import { InjectionToken, inject, input, output, viewChild, signal, computed, afterNextRender, effect, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
|
|
7
|
+
import { AX_GLOBAL_CONFIG } from '@acorex/core/config';
|
|
8
|
+
import { set } from 'lodash-es';
|
|
9
|
+
|
|
10
|
+
const AXBarChartDefaultConfig = {
|
|
11
|
+
showXAxis: true,
|
|
12
|
+
showYAxis: true,
|
|
13
|
+
showGrid: true,
|
|
14
|
+
showDataLabels: true,
|
|
15
|
+
showTooltip: true,
|
|
16
|
+
barWidth: 80,
|
|
17
|
+
cornerRadius: 4,
|
|
18
|
+
animationDuration: 800,
|
|
19
|
+
animationEasing: 'cubic-out',
|
|
20
|
+
};
|
|
21
|
+
const AX_BAR_CHART_CONFIG = new InjectionToken('AX_BAR_CHART_CONFIG', {
|
|
22
|
+
providedIn: 'root',
|
|
23
|
+
factory: () => {
|
|
24
|
+
const global = inject(AX_GLOBAL_CONFIG);
|
|
25
|
+
set(global, 'chart.barChart', AXBarChartDefaultConfig);
|
|
26
|
+
return AXBarChartDefaultConfig;
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
function barChartConfig(config = {}) {
|
|
30
|
+
const result = {
|
|
31
|
+
...AXBarChartDefaultConfig,
|
|
32
|
+
...config,
|
|
33
|
+
};
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Bar Chart Component
|
|
39
|
+
* Renders data as vertical bars with interactive hover effects and animations
|
|
40
|
+
*/
|
|
41
|
+
class AXBarChartComponent extends NXComponent {
|
|
42
|
+
// Inputs
|
|
43
|
+
/** Chart data input */
|
|
44
|
+
data = input([]);
|
|
45
|
+
/** Chart options input */
|
|
46
|
+
options = input({});
|
|
47
|
+
// Outputs
|
|
48
|
+
/** Emitted when a bar is clicked */
|
|
49
|
+
barClick = output();
|
|
50
|
+
// Chart container reference
|
|
51
|
+
chartContainerEl = viewChild.required('chartContainer');
|
|
52
|
+
// D3 reference - loaded asynchronously
|
|
53
|
+
d3;
|
|
54
|
+
// Chart elements
|
|
55
|
+
svg;
|
|
56
|
+
chart;
|
|
57
|
+
xScale;
|
|
58
|
+
yScale;
|
|
59
|
+
xAxis;
|
|
60
|
+
yAxis;
|
|
61
|
+
// Chart dimensions
|
|
62
|
+
width;
|
|
63
|
+
height;
|
|
64
|
+
margin = { top: 20, right: 20, bottom: 30, left: 40 };
|
|
65
|
+
// Animation state
|
|
66
|
+
_initialAnimationComplete = signal(false);
|
|
67
|
+
// Tooltip state
|
|
68
|
+
_tooltipVisible = signal(false);
|
|
69
|
+
_tooltipPosition = signal({ x: 0, y: 0 });
|
|
70
|
+
_tooltipData = signal({
|
|
71
|
+
title: '',
|
|
72
|
+
value: '0',
|
|
73
|
+
percentage: '0%',
|
|
74
|
+
color: '',
|
|
75
|
+
});
|
|
76
|
+
// Signals for component state
|
|
77
|
+
_initialized = signal(false);
|
|
78
|
+
_rendered = signal(false);
|
|
79
|
+
// Tooltip accessors
|
|
80
|
+
tooltipVisible = this._tooltipVisible.asReadonly();
|
|
81
|
+
tooltipPosition = this._tooltipPosition.asReadonly();
|
|
82
|
+
tooltipData = this._tooltipData.asReadonly();
|
|
83
|
+
// Inject configuration
|
|
84
|
+
configToken = inject(AX_BAR_CHART_CONFIG);
|
|
85
|
+
// Inject the chart colors
|
|
86
|
+
chartColors = inject(AX_CHART_COLOR_PALETTE);
|
|
87
|
+
// Inject AXPlatform
|
|
88
|
+
platform = inject(AXPlatform);
|
|
89
|
+
// Configuration with defaults
|
|
90
|
+
effectiveOptions = computed(() => {
|
|
91
|
+
return {
|
|
92
|
+
...this.configToken,
|
|
93
|
+
...this.options(),
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
// Track hidden bars
|
|
97
|
+
hiddenBars = new Set();
|
|
98
|
+
constructor() {
|
|
99
|
+
super();
|
|
100
|
+
// Dynamically load D3 and initialize the chart when the component is ready
|
|
101
|
+
afterNextRender(() => {
|
|
102
|
+
this._initialized.set(true);
|
|
103
|
+
this.loadD3();
|
|
104
|
+
// Create chart after D3 is loaded and container is available
|
|
105
|
+
if (this.d3 && this.chartContainerEl()) {
|
|
106
|
+
this.createChart();
|
|
107
|
+
this._rendered.set(true);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
// Watch for changes to redraw the chart
|
|
111
|
+
effect(() => {
|
|
112
|
+
// Access inputs to track them
|
|
113
|
+
this.data();
|
|
114
|
+
this.effectiveOptions();
|
|
115
|
+
// Only update if already rendered
|
|
116
|
+
if (this._rendered()) {
|
|
117
|
+
this.updateChart();
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
ngOnDestroy() {
|
|
122
|
+
this.cleanupChart();
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Loads D3.js dynamically
|
|
126
|
+
*/
|
|
127
|
+
async loadD3() {
|
|
128
|
+
try {
|
|
129
|
+
this.d3 = await import('d3');
|
|
130
|
+
// If container is ready, create chart
|
|
131
|
+
if (this._initialized() && this.chartContainerEl()) {
|
|
132
|
+
this.createChart();
|
|
133
|
+
this._rendered.set(true);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.error('Failed to load D3.js:', error);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Creates the bar chart SVG and renders all elements
|
|
142
|
+
*/
|
|
143
|
+
createChart() {
|
|
144
|
+
if (!this.d3 || !this.chartContainerEl()?.nativeElement)
|
|
145
|
+
return;
|
|
146
|
+
const containerElement = this.chartContainerEl().nativeElement;
|
|
147
|
+
const data = this.data() || [];
|
|
148
|
+
// Filter out hidden bars for visible data
|
|
149
|
+
const visibleData = data.filter((d) => !this.isBarHidden(d.id));
|
|
150
|
+
// Clear existing chart
|
|
151
|
+
this.d3.select(containerElement).selectAll('svg').remove();
|
|
152
|
+
// Early return if no data
|
|
153
|
+
if (!data.length) {
|
|
154
|
+
this.showNoDataMessage(containerElement);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
// Early return if all bars are hidden
|
|
158
|
+
if (visibleData.length === 0) {
|
|
159
|
+
this.showAllBarsHiddenMessage(containerElement);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// Get options and setup dimensions
|
|
163
|
+
const chartOptions = this.effectiveOptions();
|
|
164
|
+
this.setupDimensions(containerElement, chartOptions);
|
|
165
|
+
// Create scales and axes using visible data
|
|
166
|
+
this.setupScales(visibleData);
|
|
167
|
+
this.createAxes(chartOptions);
|
|
168
|
+
// Render the bars
|
|
169
|
+
this.renderBars(data);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Updates the chart when inputs change
|
|
173
|
+
*/
|
|
174
|
+
updateChart() {
|
|
175
|
+
this.createChart();
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Cleans up chart resources
|
|
179
|
+
*/
|
|
180
|
+
cleanupChart() {
|
|
181
|
+
if (this.svg) {
|
|
182
|
+
this.d3?.select(this.chartContainerEl()?.nativeElement).selectAll('svg').remove();
|
|
183
|
+
this.svg = null;
|
|
184
|
+
this.chart = null;
|
|
185
|
+
}
|
|
186
|
+
this._tooltipVisible.set(false);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Sets up chart dimensions and creates SVG with responsive attributes
|
|
190
|
+
*/
|
|
191
|
+
setupDimensions(containerElement, options) {
|
|
192
|
+
// Calculate margins based on options
|
|
193
|
+
this.calculateMargins(options);
|
|
194
|
+
// Get container dimensions
|
|
195
|
+
const containerWidth = containerElement.clientWidth;
|
|
196
|
+
const containerHeight = containerElement.clientHeight;
|
|
197
|
+
// If options specify width and height, use those, otherwise default to container size
|
|
198
|
+
const minDim = Math.min(200, containerWidth, containerHeight); // Ensure reasonable minimum
|
|
199
|
+
if (options.width && options.height) {
|
|
200
|
+
// Explicit dimensions provided
|
|
201
|
+
this.width = options.width - this.margin.left - this.margin.right;
|
|
202
|
+
this.height = options.height - this.margin.top - this.margin.bottom;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
// Responsive dimensions
|
|
206
|
+
this.width = Math.max(containerWidth, minDim) - this.margin.left - this.margin.right;
|
|
207
|
+
this.height = Math.max(containerHeight, minDim) - this.margin.top - this.margin.bottom;
|
|
208
|
+
}
|
|
209
|
+
// Create responsive SVG that scales with its container
|
|
210
|
+
const svg = this.d3
|
|
211
|
+
.select(containerElement)
|
|
212
|
+
.append('svg')
|
|
213
|
+
.attr('width', '100%')
|
|
214
|
+
.attr('height', '100%')
|
|
215
|
+
.attr('viewBox', `0 0 ${this.width + this.margin.left + this.margin.right} ${this.height + this.margin.top + this.margin.bottom}`)
|
|
216
|
+
.attr('preserveAspectRatio', 'xMidYMid meet');
|
|
217
|
+
this.svg = svg;
|
|
218
|
+
// Create chart group with margins
|
|
219
|
+
this.chart = this.svg.append('g').attr('transform', `translate(${this.margin.left},${this.margin.top})`);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Calculates chart margins based on options
|
|
223
|
+
*/
|
|
224
|
+
calculateMargins(options) {
|
|
225
|
+
// Start with default margins
|
|
226
|
+
this.margin = {
|
|
227
|
+
top: 20,
|
|
228
|
+
right: 20,
|
|
229
|
+
bottom: 30,
|
|
230
|
+
left: 40,
|
|
231
|
+
};
|
|
232
|
+
// Adjust margins if axis labels are present
|
|
233
|
+
if (options.xAxisLabel) {
|
|
234
|
+
const xLabelLength = options.xAxisLabel.length;
|
|
235
|
+
const extraBottomMargin = Math.min(20, Math.max(10, xLabelLength * 0.8));
|
|
236
|
+
this.margin.bottom = Math.max(this.margin.bottom, 30 + extraBottomMargin);
|
|
237
|
+
}
|
|
238
|
+
if (options.yAxisLabel) {
|
|
239
|
+
const yLabelLength = options.yAxisLabel.length;
|
|
240
|
+
const extraLeftMargin = Math.min(20, Math.max(10, yLabelLength * 0.8));
|
|
241
|
+
this.margin.left = Math.max(this.margin.left, 40 + extraLeftMargin);
|
|
242
|
+
}
|
|
243
|
+
// Ensure minimum margins for axes
|
|
244
|
+
if (options.showXAxis !== false) {
|
|
245
|
+
this.margin.bottom = Math.max(this.margin.bottom, 35);
|
|
246
|
+
}
|
|
247
|
+
if (options.showYAxis !== false) {
|
|
248
|
+
this.margin.left = Math.max(this.margin.left, 45);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Creates x and y scales for the chart
|
|
253
|
+
*/
|
|
254
|
+
setupScales(data) {
|
|
255
|
+
// Get the bar width percentage (default 80%)
|
|
256
|
+
const barWidthPercent = this.effectiveOptions().barWidth ?? 60 / 100;
|
|
257
|
+
// Calculate padding based on barWidth (inverse relationship)
|
|
258
|
+
const padding = Math.max(0.1, 1 - barWidthPercent);
|
|
259
|
+
// Create x scale (band scale for categorical data)
|
|
260
|
+
this.xScale = this.d3
|
|
261
|
+
.scaleBand()
|
|
262
|
+
.domain(data.map((d) => d.label))
|
|
263
|
+
.range([0, this.width])
|
|
264
|
+
.padding(padding);
|
|
265
|
+
// Create y scale (linear scale for values)
|
|
266
|
+
this.yScale = this.d3
|
|
267
|
+
.scaleLinear()
|
|
268
|
+
.domain([0, this.d3.max(data, (d) => d.value) || 0])
|
|
269
|
+
.nice()
|
|
270
|
+
.range([this.height, 0]);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Creates x and y axes with grid lines
|
|
274
|
+
*/
|
|
275
|
+
createAxes(options) {
|
|
276
|
+
// Only create axes if they are enabled in options
|
|
277
|
+
const showXAxis = options.showXAxis !== false;
|
|
278
|
+
const showYAxis = options.showYAxis !== false;
|
|
279
|
+
const showGrid = options.showGrid !== false;
|
|
280
|
+
const isRtl = this.platform.isRtl();
|
|
281
|
+
// Create a group for all axes
|
|
282
|
+
const axesGroup = this.chart.append('g').attr('class', 'ax-bar-chart-axes');
|
|
283
|
+
if (showXAxis) {
|
|
284
|
+
// Create X axis
|
|
285
|
+
this.xAxis = axesGroup
|
|
286
|
+
.append('g')
|
|
287
|
+
.attr('class', 'ax-bar-chart-axis-x')
|
|
288
|
+
.attr('transform', `translate(0,${this.height})`)
|
|
289
|
+
.call(this.d3.axisBottom(this.xScale));
|
|
290
|
+
// Style the axis text
|
|
291
|
+
const dynamicXAxisTickFontSize = Math.max(11, Math.min(15, Math.round(this.width / 45)));
|
|
292
|
+
this.xAxis
|
|
293
|
+
.selectAll('text')
|
|
294
|
+
.style('font-size', `${dynamicXAxisTickFontSize}px`)
|
|
295
|
+
.style('font-weight', '400')
|
|
296
|
+
.style('fill', 'rgba(var(--ax-comp-bar-chart-labels-color), 0.7)');
|
|
297
|
+
// Style all lines in the x-axis (path, ticks)
|
|
298
|
+
this.xAxis.selectAll('line, path').style('stroke', 'rgb(var(--ax-comp-bar-chart-grid-lines-color))');
|
|
299
|
+
// Add X axis label if provided
|
|
300
|
+
if (options.xAxisLabel) {
|
|
301
|
+
const labelY = this.height + this.margin.bottom * 0.8;
|
|
302
|
+
axesGroup
|
|
303
|
+
.append('text')
|
|
304
|
+
.attr('class', 'ax-bar-chart-axis-label ax-x-axis-label')
|
|
305
|
+
.attr('text-anchor', 'middle')
|
|
306
|
+
.attr('dominant-baseline', 'middle')
|
|
307
|
+
.attr('x', this.width / 2)
|
|
308
|
+
.attr('y', labelY)
|
|
309
|
+
.style('font-size', '14px')
|
|
310
|
+
.style('font-weight', '500')
|
|
311
|
+
.style('fill', 'rgb(var(--ax-comp-bar-chart-axis-label-color))')
|
|
312
|
+
.text(options.xAxisLabel);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (showYAxis) {
|
|
316
|
+
// Create Y axis
|
|
317
|
+
this.yAxis = axesGroup.append('g').attr('class', 'ax-bar-chart-axis-y').call(this.d3.axisLeft(this.yScale));
|
|
318
|
+
// Style the axis text
|
|
319
|
+
const dynamicYAxisTickFontSize = Math.max(11, Math.min(15, Math.round(this.height / 30)));
|
|
320
|
+
const yTickTexts = this.yAxis
|
|
321
|
+
.selectAll('text')
|
|
322
|
+
.style('font-size', `${dynamicYAxisTickFontSize}px`)
|
|
323
|
+
.style('font-weight', '400')
|
|
324
|
+
.style('fill', 'rgba(var(--ax-comp-bar-chart-labels-color), 0.7)');
|
|
325
|
+
if (isRtl) {
|
|
326
|
+
yTickTexts.attr('text-anchor', 'start');
|
|
327
|
+
}
|
|
328
|
+
// Style all lines in the y-axis (path, ticks)
|
|
329
|
+
this.yAxis.selectAll('line, path').style('stroke', 'rgb(var(--ax-comp-bar-chart-grid-lines-color))');
|
|
330
|
+
// Add Y axis label if provided
|
|
331
|
+
if (options.yAxisLabel) {
|
|
332
|
+
const labelX = -this.height / 2;
|
|
333
|
+
const labelY = -this.margin.left * 0.8;
|
|
334
|
+
axesGroup
|
|
335
|
+
.append('text')
|
|
336
|
+
.attr('class', 'ax-bar-chart-axis-label ax-y-axis-label')
|
|
337
|
+
.attr('text-anchor', 'middle')
|
|
338
|
+
.attr('dominant-baseline', 'middle')
|
|
339
|
+
.attr('transform', 'rotate(-90)')
|
|
340
|
+
.attr('x', labelX)
|
|
341
|
+
.attr('y', labelY)
|
|
342
|
+
.style('font-size', '14px')
|
|
343
|
+
.style('font-weight', '500')
|
|
344
|
+
.style('fill', 'rgb(var(--ax-comp-bar-chart-axis-label-color))')
|
|
345
|
+
.text(options.yAxisLabel);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (showGrid) {
|
|
349
|
+
// Add horizontal grid lines
|
|
350
|
+
this.chart
|
|
351
|
+
.append('g')
|
|
352
|
+
.attr('class', 'ax-bar-chart-grid')
|
|
353
|
+
.call(this.d3
|
|
354
|
+
.axisLeft(this.yScale)
|
|
355
|
+
.tickSize(-this.width)
|
|
356
|
+
.tickFormat(() => ''))
|
|
357
|
+
.selectAll('line')
|
|
358
|
+
.style('stroke', 'rgb(var(--ax-comp-bar-chart-grid-lines-color))')
|
|
359
|
+
.style('stroke-opacity', 0.2);
|
|
360
|
+
// Remove unneeded elements from grid
|
|
361
|
+
this.chart.select('.ax-bar-chart-grid').selectAll('path, text').remove();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Renders the bars with animations
|
|
366
|
+
*/
|
|
367
|
+
renderBars(data) {
|
|
368
|
+
// Filter out hidden bars
|
|
369
|
+
const visibleData = data.filter((d) => !this.isBarHidden(d.id));
|
|
370
|
+
const originalFullData = this.data(); // Get the original full data set
|
|
371
|
+
// Reset animation state
|
|
372
|
+
this._initialAnimationComplete.set(false);
|
|
373
|
+
// Get corner radius from options
|
|
374
|
+
const radius = this.effectiveOptions().cornerRadius;
|
|
375
|
+
// Get animation options
|
|
376
|
+
const animationDuration = this.effectiveOptions().animationDuration;
|
|
377
|
+
const animationEasing = this.getEasingFunction(this.effectiveOptions().animationEasing);
|
|
378
|
+
// Create a container for all bars
|
|
379
|
+
const barsContainer = this.chart.append('g').attr('class', 'ax-bar-chart-bars-container');
|
|
380
|
+
// Create groups for each bar to handle transformations
|
|
381
|
+
const barGroups = barsContainer
|
|
382
|
+
.selectAll('.ax-bar-chart-bar-group')
|
|
383
|
+
.data(visibleData)
|
|
384
|
+
.enter()
|
|
385
|
+
.append('g')
|
|
386
|
+
.style('cursor', 'pointer')
|
|
387
|
+
.attr('class', 'ax-bar-chart-bar-group');
|
|
388
|
+
// Add bars inside groups
|
|
389
|
+
const bars = barGroups
|
|
390
|
+
.append('rect')
|
|
391
|
+
.attr('class', 'ax-bar-chart-bar')
|
|
392
|
+
.attr('x', (d) => this.xScale(d.label))
|
|
393
|
+
.attr('width', this.xScale.bandwidth())
|
|
394
|
+
.attr('y', this.height) // Start from bottom for animation
|
|
395
|
+
.attr('height', 0) // Start with height 0 for animation
|
|
396
|
+
.attr('rx', radius) // Rounded corners
|
|
397
|
+
.attr('ry', radius) // Rounded corners
|
|
398
|
+
.attr('fill', (d) => {
|
|
399
|
+
// Find the index of the current bar (d) in the original data array
|
|
400
|
+
const originalIndex = originalFullData.findIndex((item) => item.id === d.id);
|
|
401
|
+
// Use the original color if provided, otherwise get color from palette using original index
|
|
402
|
+
// Fallback to index 0 if not found, though this shouldn't happen with valid data.
|
|
403
|
+
return d.color || this.getColor(originalIndex !== -1 ? originalIndex : 0);
|
|
404
|
+
});
|
|
405
|
+
// Add data labels if they're enabled
|
|
406
|
+
if (this.effectiveOptions().showDataLabels !== false) {
|
|
407
|
+
barGroups
|
|
408
|
+
.append('text')
|
|
409
|
+
.attr('class', 'ax-bar-chart-data-label')
|
|
410
|
+
.attr('text-anchor', 'middle')
|
|
411
|
+
.attr('x', (d) => this.xScale(d.label) + this.xScale.bandwidth() / 2)
|
|
412
|
+
.attr('y', this.height) // Start from bottom for animation
|
|
413
|
+
.style('font-size', 'clamp(8px, 2vmin, 12px)')
|
|
414
|
+
.style('font-weight', '500')
|
|
415
|
+
.style('fill', 'rgb(var(--ax-comp-bar-chart-data-labels-color))')
|
|
416
|
+
.style('opacity', 0) // Start invisible for animation
|
|
417
|
+
.text((d) => d.value);
|
|
418
|
+
// Animate data labels
|
|
419
|
+
barGroups
|
|
420
|
+
.selectAll('.ax-bar-chart-data-label')
|
|
421
|
+
.transition()
|
|
422
|
+
.duration(animationDuration)
|
|
423
|
+
.delay((d, i) => i * 50 + 100) // Slightly delayed after bar animation
|
|
424
|
+
.attr('y', (d) => this.yScale(d.value) - 8) // Position above bar
|
|
425
|
+
.style('opacity', 1)
|
|
426
|
+
.ease(animationEasing);
|
|
427
|
+
}
|
|
428
|
+
// Set up event handlers on each group
|
|
429
|
+
barGroups
|
|
430
|
+
.on('mouseenter', (event, d) => {
|
|
431
|
+
// Only apply hover effects if initial animation is complete
|
|
432
|
+
if (!this._initialAnimationComplete())
|
|
433
|
+
return;
|
|
434
|
+
const barEl = this.d3.select(event.currentTarget).select('rect');
|
|
435
|
+
// Standard hover effect - darken the bar slightly and add a subtle shadow
|
|
436
|
+
barEl.transition().duration(150).style('filter', 'brightness(0.7) drop-shadow(0 0 2px rgba(0,0,0,0.1))');
|
|
437
|
+
this.handleBarHover(event, d);
|
|
438
|
+
})
|
|
439
|
+
.on('mousemove', (event) => {
|
|
440
|
+
// Only update tooltip if initial animation is complete
|
|
441
|
+
if (this._initialAnimationComplete()) {
|
|
442
|
+
this.updateTooltipPosition(event);
|
|
443
|
+
}
|
|
444
|
+
})
|
|
445
|
+
.on('mouseleave', (event, d) => {
|
|
446
|
+
// Only apply hover effects if initial animation is complete
|
|
447
|
+
if (!this._initialAnimationComplete())
|
|
448
|
+
return;
|
|
449
|
+
const barEl = this.d3.select(event.currentTarget).select('rect');
|
|
450
|
+
// Remove hover effect
|
|
451
|
+
barEl.transition().duration(150).style('filter', null);
|
|
452
|
+
this._tooltipVisible.set(false);
|
|
453
|
+
})
|
|
454
|
+
.on('click', (event, d) => {
|
|
455
|
+
// Only trigger click events if initial animation is complete
|
|
456
|
+
if (this._initialAnimationComplete()) {
|
|
457
|
+
this.handleBarClick(event, d);
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
// Add animation
|
|
461
|
+
bars
|
|
462
|
+
.transition()
|
|
463
|
+
.duration(animationDuration)
|
|
464
|
+
.delay((d, i) => i * 50) // Stagger each bar animation
|
|
465
|
+
.attr('y', (d) => this.yScale(d.value))
|
|
466
|
+
.attr('height', (d) => this.height - this.yScale(d.value))
|
|
467
|
+
.ease(animationEasing) // Use the configured easing function
|
|
468
|
+
.end() // Wait for all animations to complete
|
|
469
|
+
.then(() => {
|
|
470
|
+
// Mark animation as complete to enable hover effects
|
|
471
|
+
this._initialAnimationComplete.set(true);
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Gets the appropriate D3 easing function based on the option string
|
|
476
|
+
*/
|
|
477
|
+
getEasingFunction(easing) {
|
|
478
|
+
switch (easing) {
|
|
479
|
+
case 'linear':
|
|
480
|
+
return this.d3.easeLinear;
|
|
481
|
+
case 'ease':
|
|
482
|
+
return this.d3.easePolyInOut;
|
|
483
|
+
case 'ease-in':
|
|
484
|
+
return this.d3.easePolyIn;
|
|
485
|
+
case 'ease-out':
|
|
486
|
+
return this.d3.easePolyOut;
|
|
487
|
+
case 'ease-in-out':
|
|
488
|
+
return this.d3.easePolyInOut;
|
|
489
|
+
case 'cubic':
|
|
490
|
+
return this.d3.easeCubic;
|
|
491
|
+
case 'cubic-in':
|
|
492
|
+
return this.d3.easeCubicIn;
|
|
493
|
+
case 'cubic-out':
|
|
494
|
+
return this.d3.easeCubicOut;
|
|
495
|
+
case 'cubic-in-out':
|
|
496
|
+
return this.d3.easeCubicInOut;
|
|
497
|
+
default:
|
|
498
|
+
return this.d3.easeCubicOut; // Default easing
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Handles bar hover event and shows tooltip
|
|
503
|
+
*/
|
|
504
|
+
handleBarHover(event, datum) {
|
|
505
|
+
if (this.effectiveOptions().showTooltip !== false) {
|
|
506
|
+
const index = this.data().findIndex((item) => item.id === datum.id);
|
|
507
|
+
const color = datum.color || this.getColor(index);
|
|
508
|
+
// Calculate percentage of total
|
|
509
|
+
const total = this.data().reduce((sum, item) => sum + item.value, 0);
|
|
510
|
+
const percentage = total > 0 ? ((datum.value / total) * 100).toFixed(1) : '0';
|
|
511
|
+
this._tooltipData.set({
|
|
512
|
+
title: datum.tooltipLabel || datum.label,
|
|
513
|
+
value: datum.value.toString(),
|
|
514
|
+
percentage: `${percentage}%`,
|
|
515
|
+
color: color,
|
|
516
|
+
});
|
|
517
|
+
this.updateTooltipPosition(event);
|
|
518
|
+
this._tooltipVisible.set(true);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Updates tooltip position based on mouse coordinates
|
|
523
|
+
*/
|
|
524
|
+
updateTooltipPosition(event) {
|
|
525
|
+
const container = this.chartContainerEl().nativeElement.getBoundingClientRect();
|
|
526
|
+
const tooltipEl = this.chartContainerEl().nativeElement.querySelector('.chart-tooltip');
|
|
527
|
+
if (!tooltipEl) {
|
|
528
|
+
const x = event.clientX - container.left;
|
|
529
|
+
const y = event.clientY - container.top;
|
|
530
|
+
this._tooltipPosition.set({ x, y });
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
const tooltipRect = tooltipEl.getBoundingClientRect();
|
|
534
|
+
let x = event.clientX - container.left;
|
|
535
|
+
const y = event.clientY - container.top;
|
|
536
|
+
// Adjust position if near the right edge
|
|
537
|
+
if (x + tooltipRect.width + 10 > container.width) {
|
|
538
|
+
x = x - tooltipRect.width - 10;
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
x = x + 10;
|
|
542
|
+
}
|
|
543
|
+
this._tooltipPosition.set({ x, y });
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Handles bar click event
|
|
547
|
+
*/
|
|
548
|
+
handleBarClick(event, datum) {
|
|
549
|
+
this.barClick.emit({ item: datum, event: { nativeEvent: event, sender: this } });
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Shows a message when no data is available
|
|
553
|
+
*/
|
|
554
|
+
showNoDataMessage(containerElement) {
|
|
555
|
+
// Clear existing contents first
|
|
556
|
+
this.d3.select(containerElement).selectAll('*').remove();
|
|
557
|
+
const messageContainer = this.d3
|
|
558
|
+
.select(containerElement)
|
|
559
|
+
.append('div')
|
|
560
|
+
// Apply generic container class, specific bar chart background class, and existing specific class
|
|
561
|
+
.attr('class', 'ax-chart-message-container ax-bar-chart-message-background ax-bar-chart-no-data-message');
|
|
562
|
+
// Add an icon
|
|
563
|
+
messageContainer
|
|
564
|
+
.append('div')
|
|
565
|
+
// Apply generic icon class and specific bar chart icon class
|
|
566
|
+
.attr('class', 'ax-chart-message-icon ax-bar-chart-no-data-icon')
|
|
567
|
+
.html('<i class="fa-light fa-chart-column fa-2x"></i>');
|
|
568
|
+
// Add text message
|
|
569
|
+
messageContainer
|
|
570
|
+
.append('div')
|
|
571
|
+
// Apply generic text class and specific bar chart text class
|
|
572
|
+
.attr('class', 'ax-chart-message-text ax-bar-chart-no-data-text')
|
|
573
|
+
.text('No data available');
|
|
574
|
+
// Add help text
|
|
575
|
+
messageContainer
|
|
576
|
+
.append('div')
|
|
577
|
+
// Apply generic help class and specific bar chart help class
|
|
578
|
+
.attr('class', 'ax-chart-message-help ax-bar-chart-no-data-help')
|
|
579
|
+
.text('Please provide data to display the chart');
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Shows a message when all bars are hidden
|
|
583
|
+
*/
|
|
584
|
+
showAllBarsHiddenMessage(containerElement) {
|
|
585
|
+
// Clear existing contents first
|
|
586
|
+
this.d3.select(containerElement).selectAll('*').remove();
|
|
587
|
+
const messageContainer = this.d3
|
|
588
|
+
.select(containerElement)
|
|
589
|
+
.append('div')
|
|
590
|
+
// Apply generic container class, specific bar chart background class, and existing specific class
|
|
591
|
+
.attr('class', 'ax-chart-message-container ax-bar-chart-message-background ax-bar-chart-no-data-message');
|
|
592
|
+
// Add an icon
|
|
593
|
+
messageContainer
|
|
594
|
+
.append('div')
|
|
595
|
+
// Apply generic icon class and specific bar chart icon class
|
|
596
|
+
.attr('class', 'ax-chart-message-icon ax-bar-chart-no-data-icon')
|
|
597
|
+
.html('<i class="fa-light fa-eye-slash fa-2x"></i>');
|
|
598
|
+
// Add text message
|
|
599
|
+
messageContainer
|
|
600
|
+
.append('div')
|
|
601
|
+
// Apply generic text class and specific bar chart text class
|
|
602
|
+
.attr('class', 'ax-chart-message-text ax-bar-chart-no-data-text')
|
|
603
|
+
.text('All bars are hidden');
|
|
604
|
+
// Add help text
|
|
605
|
+
messageContainer
|
|
606
|
+
.append('div')
|
|
607
|
+
// Apply generic help class and specific bar chart help class
|
|
608
|
+
.attr('class', 'ax-chart-message-help ax-bar-chart-no-data-help')
|
|
609
|
+
.text('Click on legend items to show bars');
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Gets the color for a bar based on its index
|
|
613
|
+
*/
|
|
614
|
+
getColor(index) {
|
|
615
|
+
return getChartColor(index, this.chartColors);
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Checks if a bar is hidden
|
|
619
|
+
*/
|
|
620
|
+
isBarHidden(id) {
|
|
621
|
+
return this.hiddenBars.has(id);
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Implementation of AXChartLegendCompatible interface
|
|
625
|
+
* Returns legend items based on the chart data
|
|
626
|
+
*/
|
|
627
|
+
getLegendItems() {
|
|
628
|
+
const data = this.data() || [];
|
|
629
|
+
const total = data.reduce((sum, item) => sum + (typeof item.value === 'number' ? item.value : 0), 0);
|
|
630
|
+
return data.map((item, index) => {
|
|
631
|
+
const value = typeof item.value === 'number' ? item.value : 0;
|
|
632
|
+
const percentage = total > 0 ? (value / total) * 100 : 0;
|
|
633
|
+
return {
|
|
634
|
+
id: item.id,
|
|
635
|
+
name: item.label || `Item ${index + 1}`,
|
|
636
|
+
value: item.value,
|
|
637
|
+
percentage,
|
|
638
|
+
color: item.color || this.getColor(index),
|
|
639
|
+
hidden: this.isBarHidden(item.id),
|
|
640
|
+
};
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Implementation of AXChartLegendCompatible interface
|
|
645
|
+
* Highlights a specific bar by ID
|
|
646
|
+
*/
|
|
647
|
+
highlightSegment(id) {
|
|
648
|
+
if (!this.svg)
|
|
649
|
+
return;
|
|
650
|
+
// If the bar is hidden, we shouldn't try to highlight it
|
|
651
|
+
if (id !== null && this.isBarHidden(id)) {
|
|
652
|
+
// Just unhighlight everything when trying to highlight a hidden bar
|
|
653
|
+
this.svg
|
|
654
|
+
.selectAll('.ax-bar-chart-bar')
|
|
655
|
+
.classed('ax-bar-chart-highlighted', false)
|
|
656
|
+
.classed('ax-bar-chart-dimmed', false)
|
|
657
|
+
.attr('opacity', 1)
|
|
658
|
+
.attr('filter', null)
|
|
659
|
+
.attr('stroke', null)
|
|
660
|
+
.attr('stroke-width', null)
|
|
661
|
+
.attr('stroke-opacity', null);
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
if (id === null) {
|
|
665
|
+
// If id is null, unhighlight everything
|
|
666
|
+
this.svg
|
|
667
|
+
.selectAll('.ax-bar-chart-bar')
|
|
668
|
+
.classed('ax-bar-chart-highlighted', false)
|
|
669
|
+
.classed('ax-bar-chart-dimmed', false)
|
|
670
|
+
.attr('opacity', 1)
|
|
671
|
+
.attr('filter', null)
|
|
672
|
+
.attr('stroke', null)
|
|
673
|
+
.attr('stroke-width', null)
|
|
674
|
+
.attr('stroke-opacity', null);
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
// Find the target bar
|
|
678
|
+
const targetBar = this.svg.selectAll('.ax-bar-chart-bar').filter((d) => d?.id === id);
|
|
679
|
+
// Safety check - if no matching bar is found, do nothing
|
|
680
|
+
if (targetBar.empty())
|
|
681
|
+
return;
|
|
682
|
+
// Check if the target bar is currently highlighted
|
|
683
|
+
const isCurrentlyHighlighted = targetBar.classed('ax-bar-chart-highlighted');
|
|
684
|
+
if (isCurrentlyHighlighted) {
|
|
685
|
+
// If already highlighted, unhighlight all bars
|
|
686
|
+
this.svg
|
|
687
|
+
.selectAll('.ax-bar-chart-bar')
|
|
688
|
+
.classed('ax-bar-chart-highlighted', false)
|
|
689
|
+
.classed('ax-bar-chart-dimmed', false)
|
|
690
|
+
.attr('opacity', 1)
|
|
691
|
+
.attr('filter', null)
|
|
692
|
+
.attr('stroke', null)
|
|
693
|
+
.attr('stroke-width', null)
|
|
694
|
+
.attr('stroke-opacity', null);
|
|
695
|
+
}
|
|
696
|
+
else {
|
|
697
|
+
// Reset all bars first
|
|
698
|
+
this.svg
|
|
699
|
+
.selectAll('.ax-bar-chart-bar')
|
|
700
|
+
.classed('ax-bar-chart-highlighted', false)
|
|
701
|
+
.classed('ax-bar-chart-dimmed', false)
|
|
702
|
+
.attr('opacity', 1)
|
|
703
|
+
.attr('filter', null)
|
|
704
|
+
.attr('stroke', null)
|
|
705
|
+
.attr('stroke-width', null)
|
|
706
|
+
.attr('stroke-opacity', null);
|
|
707
|
+
// Highlight the target bar
|
|
708
|
+
targetBar
|
|
709
|
+
.classed('ax-bar-chart-highlighted', true)
|
|
710
|
+
.attr('filter', 'drop-shadow(0 0 4px rgba(0, 0, 0, 0.3))')
|
|
711
|
+
.attr('stroke', '#000')
|
|
712
|
+
.attr('stroke-width', '1px')
|
|
713
|
+
.attr('stroke-opacity', '0.3')
|
|
714
|
+
.style('transition', 'all 0.2s ease-in-out');
|
|
715
|
+
// Dim other bars
|
|
716
|
+
this.svg
|
|
717
|
+
.selectAll('.ax-bar-chart-bar')
|
|
718
|
+
.filter((d) => d?.id !== id)
|
|
719
|
+
.classed('ax-bar-chart-dimmed', true)
|
|
720
|
+
.attr('opacity', 0.5)
|
|
721
|
+
.style('transition', 'opacity 0.2s ease-in-out');
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* Implementation of AXChartLegendCompatible interface
|
|
726
|
+
* Toggles visibility of a bar by ID
|
|
727
|
+
* @returns New visibility state (true = visible, false = hidden)
|
|
728
|
+
*/
|
|
729
|
+
toggleSegment(id) {
|
|
730
|
+
const wasAllHidden = this.data().length > 0 && this.data().every((d) => this.isBarHidden(d.id));
|
|
731
|
+
if (this.hiddenBars.has(id)) {
|
|
732
|
+
// Making a bar visible
|
|
733
|
+
this.hiddenBars.delete(id);
|
|
734
|
+
// If all bars were previously hidden, we need to ensure the message is cleared
|
|
735
|
+
if (wasAllHidden) {
|
|
736
|
+
// Force complete DOM cleanup and redraw
|
|
737
|
+
if (this.chartContainerEl()?.nativeElement) {
|
|
738
|
+
// Clear everything in the container
|
|
739
|
+
this.d3?.select(this.chartContainerEl().nativeElement).selectAll('*').remove();
|
|
740
|
+
// Force full redraw
|
|
741
|
+
setTimeout(() => {
|
|
742
|
+
this.createChart();
|
|
743
|
+
}, 0);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
else {
|
|
747
|
+
// Normal update for other cases
|
|
748
|
+
this.updateChart();
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
else {
|
|
752
|
+
// Hiding a bar
|
|
753
|
+
this.hiddenBars.add(id);
|
|
754
|
+
this.updateChart();
|
|
755
|
+
}
|
|
756
|
+
// Return the new visibility state
|
|
757
|
+
return !this.hiddenBars.has(id);
|
|
758
|
+
}
|
|
759
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: AXBarChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
760
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.0.4", 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\" #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: var(--ax-sys-color-lightest-surface)}ax-bar-chart .ax-bar-chart{width:100%;height:100%;position:relative;display:flex;align-items:center;justify-content:center;border-radius:.5rem;overflow:hidden;color:rgb(var(--ax-sys-color-on-lightest-surface));background-color:rgb(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:visible}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;box-shadow:0 2px 12px #00000014;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 });
|
|
761
|
+
}
|
|
762
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: AXBarChartComponent, decorators: [{
|
|
763
|
+
type: Component,
|
|
764
|
+
args: [{ selector: 'ax-bar-chart', encapsulation: ViewEncapsulation.None, imports: [AXChartTooltipComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ax-bar-chart\" #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: var(--ax-sys-color-lightest-surface)}ax-bar-chart .ax-bar-chart{width:100%;height:100%;position:relative;display:flex;align-items:center;justify-content:center;border-radius:.5rem;overflow:hidden;color:rgb(var(--ax-sys-color-on-lightest-surface));background-color:rgb(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:visible}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;box-shadow:0 2px 12px #00000014;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"] }]
|
|
765
|
+
}], ctorParameters: () => [] });
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Generated bundle index. Do not edit.
|
|
769
|
+
*/
|
|
770
|
+
|
|
771
|
+
export { AXBarChartComponent, AXBarChartDefaultConfig, AX_BAR_CHART_CONFIG, barChartConfig };
|
|
772
|
+
//# sourceMappingURL=acorex-charts-bar-chart.mjs.map
|