@acorex/charts 19.13.2
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 +3 -0
- package/bar-chart/lib/bar-chart.component.d.ts +123 -0
- package/bar-chart/lib/bar-chart.config.d.ts +6 -0
- package/bar-chart/lib/bar-chart.type.d.ts +44 -0
- package/chart-tooltip/README.md +3 -0
- package/chart-tooltip/index.d.ts +2 -0
- package/chart-tooltip/lib/chart-tooltip.component.d.ts +43 -0
- package/chart-tooltip/lib/chart-tooltip.type.d.ts +7 -0
- package/donut-chart/README.md +3 -0
- package/donut-chart/index.d.ts +3 -0
- package/donut-chart/lib/donut-chart.component.d.ts +143 -0
- package/donut-chart/lib/donut-chart.config.d.ts +6 -0
- package/donut-chart/lib/donut-chart.type.d.ts +25 -0
- package/fesm2022/acorex-charts-bar-chart.mjs +563 -0
- package/fesm2022/acorex-charts-bar-chart.mjs.map +1 -0
- package/fesm2022/acorex-charts-chart-tooltip.mjs +75 -0
- package/fesm2022/acorex-charts-chart-tooltip.mjs.map +1 -0
- package/fesm2022/acorex-charts-donut-chart.mjs +616 -0
- package/fesm2022/acorex-charts-donut-chart.mjs.map +1 -0
- package/fesm2022/acorex-charts-gauge-chart.mjs +548 -0
- package/fesm2022/acorex-charts-gauge-chart.mjs.map +1 -0
- package/fesm2022/acorex-charts-hierarchy-chart.mjs +652 -0
- package/fesm2022/acorex-charts-hierarchy-chart.mjs.map +1 -0
- package/fesm2022/acorex-charts-line-chart.mjs +738 -0
- package/fesm2022/acorex-charts-line-chart.mjs.map +1 -0
- package/fesm2022/acorex-charts.mjs +8 -0
- package/fesm2022/acorex-charts.mjs.map +1 -0
- package/gauge-chart/README.md +3 -0
- package/gauge-chart/index.d.ts +3 -0
- package/gauge-chart/lib/gauge-chart.component.d.ts +110 -0
- package/gauge-chart/lib/gauge-chart.config.d.ts +6 -0
- package/gauge-chart/lib/gauge-chart.type.d.ts +37 -0
- package/hierarchy-chart/README.md +61 -0
- package/hierarchy-chart/index.d.ts +3 -0
- package/hierarchy-chart/lib/hierarchy-chart.component.d.ts +99 -0
- package/hierarchy-chart/lib/hierarchy-chart.config.d.ts +6 -0
- package/hierarchy-chart/lib/hierarchy-chart.type.d.ts +227 -0
- package/index.d.ts +1 -0
- package/line-chart/README.md +3 -0
- package/line-chart/index.d.ts +3 -0
- package/line-chart/lib/line-chart.component.d.ts +96 -0
- package/line-chart/lib/line-chart.config.d.ts +6 -0
- package/line-chart/lib/line-chart.type.d.ts +61 -0
- package/package.json +48 -0
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
import { AXChartTooltipComponent } from '@acorex/charts/chart-tooltip';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import * as i0 from '@angular/core';
|
|
4
|
+
import { InjectionToken, inject, input, output, viewChild, signal, computed, afterNextRender, effect, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
5
|
+
import { AX_GLOBAL_CONFIG } from '@acorex/core/config';
|
|
6
|
+
import { set } from 'lodash-es';
|
|
7
|
+
|
|
8
|
+
const AXBarChartDefaultConfig = {
|
|
9
|
+
margin: {
|
|
10
|
+
top: 20,
|
|
11
|
+
right: 20,
|
|
12
|
+
bottom: 30,
|
|
13
|
+
left: 40,
|
|
14
|
+
},
|
|
15
|
+
showXAxis: true,
|
|
16
|
+
showYAxis: true,
|
|
17
|
+
showGrid: true,
|
|
18
|
+
showTooltip: true,
|
|
19
|
+
barWidth: 80,
|
|
20
|
+
cornerRadius: 4,
|
|
21
|
+
animationDuration: 800,
|
|
22
|
+
animationEasing: 'cubic-out',
|
|
23
|
+
};
|
|
24
|
+
const AX_BAR_CHART_CONFIG = new InjectionToken('AX_BAR_CHART_CONFIG', {
|
|
25
|
+
providedIn: 'root',
|
|
26
|
+
factory: () => {
|
|
27
|
+
const global = inject(AX_GLOBAL_CONFIG);
|
|
28
|
+
set(global, 'chart.barChart', AXBarChartDefaultConfig);
|
|
29
|
+
return AXBarChartDefaultConfig;
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
function barChartConfig(config = {}) {
|
|
33
|
+
const result = {
|
|
34
|
+
...AXBarChartDefaultConfig,
|
|
35
|
+
...config,
|
|
36
|
+
};
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const AXBarChartColors = {
|
|
41
|
+
// Modern color palette suitable for data visualization
|
|
42
|
+
defaultColors: [
|
|
43
|
+
'#4361ee', // Blue
|
|
44
|
+
'#3a0ca3', // Purple
|
|
45
|
+
'#7209b7', // Violet
|
|
46
|
+
'#f72585', // Pink
|
|
47
|
+
'#4cc9f0', // Light Blue
|
|
48
|
+
'#4895ef', // Sky Blue
|
|
49
|
+
'#560bad', // Deep Purple
|
|
50
|
+
'#f15bb5', // Light Pink
|
|
51
|
+
'#00bbf9', // Cyan
|
|
52
|
+
'#00f5d4', // Teal
|
|
53
|
+
],
|
|
54
|
+
// Get a color from the palette by index with wraparound
|
|
55
|
+
getColor: (index, customPalette) => {
|
|
56
|
+
const palette = customPalette || AXBarChartColors.defaultColors;
|
|
57
|
+
return palette[index % palette.length];
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Bar Chart Component
|
|
62
|
+
* Renders data as vertical bars with interactive hover effects and animations
|
|
63
|
+
*/
|
|
64
|
+
class AXBarChartComponent {
|
|
65
|
+
// Inputs
|
|
66
|
+
/** Chart data input */
|
|
67
|
+
data = input([]);
|
|
68
|
+
/** Chart options input */
|
|
69
|
+
options = input({});
|
|
70
|
+
// Outputs
|
|
71
|
+
/** Emitted when a bar is clicked */
|
|
72
|
+
barClick = output();
|
|
73
|
+
// Chart container reference
|
|
74
|
+
chartContainerEl = viewChild.required('chartContainer');
|
|
75
|
+
// D3 reference - loaded asynchronously
|
|
76
|
+
d3;
|
|
77
|
+
// Chart elements
|
|
78
|
+
svg;
|
|
79
|
+
chart;
|
|
80
|
+
xScale;
|
|
81
|
+
yScale;
|
|
82
|
+
xAxis;
|
|
83
|
+
yAxis;
|
|
84
|
+
// Chart dimensions
|
|
85
|
+
width;
|
|
86
|
+
height;
|
|
87
|
+
margin = { top: 20, right: 20, bottom: 30, left: 40 };
|
|
88
|
+
// Tooltip state
|
|
89
|
+
_tooltipVisible = signal(false);
|
|
90
|
+
_tooltipPosition = signal({ x: 0, y: 0 });
|
|
91
|
+
_tooltipData = signal({
|
|
92
|
+
title: '',
|
|
93
|
+
value: '0',
|
|
94
|
+
percentage: '0%',
|
|
95
|
+
color: '',
|
|
96
|
+
});
|
|
97
|
+
// Signals for component state
|
|
98
|
+
_initialized = signal(false);
|
|
99
|
+
_rendered = signal(false);
|
|
100
|
+
// Tooltip accessors
|
|
101
|
+
tooltipVisible = this._tooltipVisible.asReadonly();
|
|
102
|
+
tooltipPosition = this._tooltipPosition.asReadonly();
|
|
103
|
+
tooltipData = this._tooltipData.asReadonly();
|
|
104
|
+
// Inject configuration
|
|
105
|
+
configToken = inject(AX_BAR_CHART_CONFIG);
|
|
106
|
+
// Configuration with defaults
|
|
107
|
+
effectiveOptions = computed(() => {
|
|
108
|
+
return {
|
|
109
|
+
...this.configToken,
|
|
110
|
+
...this.options(),
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
constructor() {
|
|
114
|
+
// Dynamically load D3 and initialize the chart when the component is ready
|
|
115
|
+
afterNextRender(() => {
|
|
116
|
+
this._initialized.set(true);
|
|
117
|
+
this.loadD3();
|
|
118
|
+
// Create chart after D3 is loaded and container is available
|
|
119
|
+
if (this.d3 && this.chartContainerEl()) {
|
|
120
|
+
this.createChart();
|
|
121
|
+
this._rendered.set(true);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
// Watch for changes to redraw the chart
|
|
125
|
+
effect(() => {
|
|
126
|
+
// Access inputs to track them
|
|
127
|
+
this.data();
|
|
128
|
+
this.effectiveOptions();
|
|
129
|
+
// Only update if already rendered
|
|
130
|
+
if (this._rendered()) {
|
|
131
|
+
this.updateChart();
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
ngOnDestroy() {
|
|
136
|
+
this.cleanupChart();
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Loads D3.js dynamically
|
|
140
|
+
*/
|
|
141
|
+
async loadD3() {
|
|
142
|
+
try {
|
|
143
|
+
this.d3 = await import('d3');
|
|
144
|
+
// If container is ready, create chart
|
|
145
|
+
if (this._initialized() && this.chartContainerEl()) {
|
|
146
|
+
this.createChart();
|
|
147
|
+
this._rendered.set(true);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
console.error('Failed to load D3.js:', error);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Creates the bar chart SVG and renders all elements
|
|
156
|
+
*/
|
|
157
|
+
createChart() {
|
|
158
|
+
if (!this.d3 || !this.chartContainerEl()?.nativeElement)
|
|
159
|
+
return;
|
|
160
|
+
const containerElement = this.chartContainerEl().nativeElement;
|
|
161
|
+
const data = this.data() || [];
|
|
162
|
+
// Clear existing chart
|
|
163
|
+
this.d3.select(containerElement).selectAll('svg').remove();
|
|
164
|
+
// Early return if no data
|
|
165
|
+
if (!data.length) {
|
|
166
|
+
this.showNoDataMessage(containerElement);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
// Get options and setup dimensions
|
|
170
|
+
const chartOptions = this.effectiveOptions();
|
|
171
|
+
this.setupDimensions(containerElement, chartOptions);
|
|
172
|
+
// Create scales and axes
|
|
173
|
+
this.setupScales(data);
|
|
174
|
+
this.createAxes(chartOptions);
|
|
175
|
+
// Render the bars
|
|
176
|
+
this.renderBars(data);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Updates the chart when inputs change
|
|
180
|
+
*/
|
|
181
|
+
updateChart() {
|
|
182
|
+
this.createChart();
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Cleans up chart resources
|
|
186
|
+
*/
|
|
187
|
+
cleanupChart() {
|
|
188
|
+
if (this.svg) {
|
|
189
|
+
this.d3?.select(this.chartContainerEl()?.nativeElement).selectAll('svg').remove();
|
|
190
|
+
this.svg = null;
|
|
191
|
+
this.chart = null;
|
|
192
|
+
}
|
|
193
|
+
this._tooltipVisible.set(false);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Sets up chart dimensions and creates SVG with responsive attributes
|
|
197
|
+
*/
|
|
198
|
+
setupDimensions(containerElement, options) {
|
|
199
|
+
// Calculate margins based on options
|
|
200
|
+
this.calculateMargins(options);
|
|
201
|
+
// Get container dimensions
|
|
202
|
+
const containerWidth = containerElement.clientWidth;
|
|
203
|
+
const containerHeight = containerElement.clientHeight;
|
|
204
|
+
// If options specify width and height, use those, otherwise default to container size
|
|
205
|
+
const minDim = Math.min(200, containerWidth, containerHeight); // Ensure reasonable minimum
|
|
206
|
+
if (options.width && options.height) {
|
|
207
|
+
// Explicit dimensions provided
|
|
208
|
+
this.width = options.width - this.margin.left - this.margin.right;
|
|
209
|
+
this.height = options.height - this.margin.top - this.margin.bottom;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
// Responsive dimensions
|
|
213
|
+
this.width = Math.max(containerWidth, minDim) - this.margin.left - this.margin.right;
|
|
214
|
+
this.height = Math.max(containerHeight, minDim) - this.margin.top - this.margin.bottom;
|
|
215
|
+
}
|
|
216
|
+
// Create responsive SVG that scales with its container
|
|
217
|
+
const svg = this.d3
|
|
218
|
+
.select(containerElement)
|
|
219
|
+
.append('svg')
|
|
220
|
+
.attr('width', '100%')
|
|
221
|
+
.attr('height', '100%')
|
|
222
|
+
.attr('viewBox', `0 0 ${this.width + this.margin.left + this.margin.right} ${this.height + this.margin.top + this.margin.bottom}`)
|
|
223
|
+
.attr('preserveAspectRatio', 'xMidYMid meet');
|
|
224
|
+
this.svg = svg;
|
|
225
|
+
// Create chart group with margins
|
|
226
|
+
this.chart = this.svg.append('g').attr('transform', `translate(${this.margin.left},${this.margin.top})`);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Calculates chart margins based on options
|
|
230
|
+
*/
|
|
231
|
+
calculateMargins(options) {
|
|
232
|
+
// Start with default margins
|
|
233
|
+
this.margin = {
|
|
234
|
+
top: options.margin?.top ?? 20,
|
|
235
|
+
right: options.margin?.right ?? 20,
|
|
236
|
+
bottom: options.margin?.bottom ?? 30,
|
|
237
|
+
left: options.margin?.left ?? 40,
|
|
238
|
+
};
|
|
239
|
+
// Adjust margins if axis labels are present
|
|
240
|
+
if (options.xAxisLabel) {
|
|
241
|
+
const xLabelLength = options.xAxisLabel.length;
|
|
242
|
+
const extraBottomMargin = Math.min(20, Math.max(10, xLabelLength * 0.8));
|
|
243
|
+
this.margin.bottom = Math.max(this.margin.bottom, 30 + extraBottomMargin);
|
|
244
|
+
}
|
|
245
|
+
if (options.yAxisLabel) {
|
|
246
|
+
const yLabelLength = options.yAxisLabel.length;
|
|
247
|
+
const extraLeftMargin = Math.min(20, Math.max(10, yLabelLength * 0.8));
|
|
248
|
+
this.margin.left = Math.max(this.margin.left, 40 + extraLeftMargin);
|
|
249
|
+
}
|
|
250
|
+
// Ensure minimum margins for axes
|
|
251
|
+
if (options.showXAxis !== false) {
|
|
252
|
+
this.margin.bottom = Math.max(this.margin.bottom, 35);
|
|
253
|
+
}
|
|
254
|
+
if (options.showYAxis !== false) {
|
|
255
|
+
this.margin.left = Math.max(this.margin.left, 45);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Creates x and y scales for the chart
|
|
260
|
+
*/
|
|
261
|
+
setupScales(data) {
|
|
262
|
+
// Get the bar width percentage (default 80%)
|
|
263
|
+
const barWidthPercent = this.effectiveOptions().barWidth ?? 60 / 100;
|
|
264
|
+
// Calculate padding based on barWidth (inverse relationship)
|
|
265
|
+
const padding = Math.max(0.1, 1 - barWidthPercent);
|
|
266
|
+
// Create x scale (band scale for categorical data)
|
|
267
|
+
this.xScale = this.d3
|
|
268
|
+
.scaleBand()
|
|
269
|
+
.domain(data.map((d) => d.label))
|
|
270
|
+
.range([0, this.width])
|
|
271
|
+
.padding(padding);
|
|
272
|
+
// Create y scale (linear scale for values)
|
|
273
|
+
this.yScale = this.d3
|
|
274
|
+
.scaleLinear()
|
|
275
|
+
.domain([0, this.d3.max(data, (d) => d.value) || 0])
|
|
276
|
+
.nice()
|
|
277
|
+
.range([this.height, 0]);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Creates x and y axes with grid lines
|
|
281
|
+
*/
|
|
282
|
+
createAxes(options) {
|
|
283
|
+
// Only create axes if they are enabled in options
|
|
284
|
+
const showXAxis = options.showXAxis !== false;
|
|
285
|
+
const showYAxis = options.showYAxis !== false;
|
|
286
|
+
const showGrid = options.showGrid !== false;
|
|
287
|
+
// Create a group for all axes
|
|
288
|
+
const axesGroup = this.chart.append('g').attr('class', 'ax-bar-chart-axes');
|
|
289
|
+
if (showXAxis) {
|
|
290
|
+
// Create X axis
|
|
291
|
+
this.xAxis = axesGroup
|
|
292
|
+
.append('g')
|
|
293
|
+
.attr('class', 'ax-bar-chart-axis-x')
|
|
294
|
+
.attr('transform', `translate(0,${this.height})`)
|
|
295
|
+
.call(this.d3.axisBottom(this.xScale));
|
|
296
|
+
// Style the axis text
|
|
297
|
+
this.xAxis.selectAll('text').style('font-size', '11px').style('font-weight', '400').style('fill', '#666');
|
|
298
|
+
// Add X axis label if provided
|
|
299
|
+
if (options.xAxisLabel) {
|
|
300
|
+
const labelY = this.height + this.margin.bottom * 0.65;
|
|
301
|
+
axesGroup
|
|
302
|
+
.append('text')
|
|
303
|
+
.attr('class', 'ax-bar-chart-axis-label ax-x-axis-label')
|
|
304
|
+
.attr('text-anchor', 'middle')
|
|
305
|
+
.attr('dominant-baseline', 'middle')
|
|
306
|
+
.attr('x', this.width / 2)
|
|
307
|
+
.attr('y', labelY)
|
|
308
|
+
.style('font-size', '13px')
|
|
309
|
+
.style('font-weight', '500')
|
|
310
|
+
.style('fill', '#555')
|
|
311
|
+
.text(options.xAxisLabel);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (showYAxis) {
|
|
315
|
+
// Create Y axis
|
|
316
|
+
this.yAxis = axesGroup.append('g').attr('class', 'ax-bar-chart-axis-y').call(this.d3.axisLeft(this.yScale));
|
|
317
|
+
// Style the axis text
|
|
318
|
+
this.yAxis.selectAll('text').style('font-size', '11px').style('font-weight', '400').style('fill', '#666');
|
|
319
|
+
// Add Y axis label if provided
|
|
320
|
+
if (options.yAxisLabel) {
|
|
321
|
+
const labelX = -this.height / 2;
|
|
322
|
+
const labelY = -this.margin.left * 0.65;
|
|
323
|
+
axesGroup
|
|
324
|
+
.append('text')
|
|
325
|
+
.attr('class', 'ax-bar-chart-axis-label ax-y-axis-label')
|
|
326
|
+
.attr('text-anchor', 'middle')
|
|
327
|
+
.attr('dominant-baseline', 'middle')
|
|
328
|
+
.attr('transform', 'rotate(-90)')
|
|
329
|
+
.attr('x', labelX)
|
|
330
|
+
.attr('y', labelY)
|
|
331
|
+
.style('font-size', '13px')
|
|
332
|
+
.style('font-weight', '500')
|
|
333
|
+
.style('fill', '#555')
|
|
334
|
+
.text(options.yAxisLabel);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (showGrid) {
|
|
338
|
+
// Add horizontal grid lines
|
|
339
|
+
this.chart
|
|
340
|
+
.append('g')
|
|
341
|
+
.attr('class', 'ax-bar-chart-grid')
|
|
342
|
+
.call(this.d3
|
|
343
|
+
.axisLeft(this.yScale)
|
|
344
|
+
.tickSize(-this.width)
|
|
345
|
+
.tickFormat(() => ''))
|
|
346
|
+
.selectAll('.tick')
|
|
347
|
+
.style('color', 'rgb(153 153 153 / 30%)'); // Add gray color to ticks
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Renders the bars with animations
|
|
352
|
+
*/
|
|
353
|
+
renderBars(data) {
|
|
354
|
+
// Get corner radius from options
|
|
355
|
+
const radius = this.effectiveOptions().cornerRadius;
|
|
356
|
+
// Get animation options
|
|
357
|
+
const animationDuration = this.effectiveOptions().animationDuration;
|
|
358
|
+
const animationEasing = this.getEasingFunction(this.effectiveOptions().animationEasing);
|
|
359
|
+
// Create a container for all bars
|
|
360
|
+
const barsContainer = this.chart.append('g').attr('class', 'ax-bar-chart-bars-container');
|
|
361
|
+
// Create groups for each bar to handle transformations
|
|
362
|
+
const barGroups = barsContainer
|
|
363
|
+
.selectAll('.ax-bar-chart-bar-group')
|
|
364
|
+
.data(data)
|
|
365
|
+
.enter()
|
|
366
|
+
.append('g')
|
|
367
|
+
.style('cursor', 'pointer')
|
|
368
|
+
.attr('class', 'ax-bar-chart-bar-group');
|
|
369
|
+
// Add bars inside groups
|
|
370
|
+
const bars = barGroups
|
|
371
|
+
.append('rect')
|
|
372
|
+
.attr('class', 'ax-bar-chart-bar')
|
|
373
|
+
.attr('x', (d) => this.xScale(d.label))
|
|
374
|
+
.attr('width', this.xScale.bandwidth())
|
|
375
|
+
.attr('y', this.height) // Start from bottom for animation
|
|
376
|
+
.attr('height', 0) // Start with height 0 for animation
|
|
377
|
+
.attr('rx', radius) // Rounded corners
|
|
378
|
+
.attr('ry', radius) // Rounded corners
|
|
379
|
+
.attr('fill', (d, i) => d.color || AXBarChartColors.getColor(i));
|
|
380
|
+
// Set up event handlers on each group
|
|
381
|
+
barGroups
|
|
382
|
+
.on('mouseenter', (event, d) => {
|
|
383
|
+
const barEl = this.d3.select(event.currentTarget).select('rect');
|
|
384
|
+
const currentX = parseFloat(barEl.attr('x'));
|
|
385
|
+
const currentY = parseFloat(barEl.attr('y'));
|
|
386
|
+
const currentWidth = parseFloat(barEl.attr('width'));
|
|
387
|
+
const currentHeight = parseFloat(barEl.attr('height'));
|
|
388
|
+
// Calculate horizontal center point of the bar
|
|
389
|
+
const centerX = currentX + currentWidth / 2;
|
|
390
|
+
// Scale amount (5% larger)
|
|
391
|
+
const scaleX = 1.05;
|
|
392
|
+
const scaleY = 1.05;
|
|
393
|
+
// Calculate new dimensions with scaling
|
|
394
|
+
const newWidth = currentWidth * scaleX;
|
|
395
|
+
const newHeight = currentHeight * scaleY;
|
|
396
|
+
// Calculate new position:
|
|
397
|
+
// - Horizontally center-aligned
|
|
398
|
+
// - Vertically grow only upward from the bottom (X-axis)
|
|
399
|
+
const newX = centerX - newWidth / 2;
|
|
400
|
+
// The bottom of the bar stays at the same position (aligned with x-axis)
|
|
401
|
+
const newY = currentY - (newHeight - currentHeight);
|
|
402
|
+
// Apply the new position and size
|
|
403
|
+
barEl
|
|
404
|
+
.transition()
|
|
405
|
+
.duration(200)
|
|
406
|
+
.attr('x', newX)
|
|
407
|
+
.attr('y', newY)
|
|
408
|
+
.attr('width', newWidth)
|
|
409
|
+
.attr('height', newHeight);
|
|
410
|
+
this.handleBarHover(event, d);
|
|
411
|
+
})
|
|
412
|
+
.on('mousemove', (event) => this.updateTooltipPosition(event))
|
|
413
|
+
.on('mouseleave', (event, d) => {
|
|
414
|
+
const barEl = this.d3.select(event.currentTarget).select('rect');
|
|
415
|
+
// Restore original position and size
|
|
416
|
+
barEl
|
|
417
|
+
.transition()
|
|
418
|
+
.duration(200)
|
|
419
|
+
.attr('x', (d) => this.xScale(d.label))
|
|
420
|
+
.attr('y', (d) => this.yScale(d.value))
|
|
421
|
+
.attr('width', this.xScale.bandwidth())
|
|
422
|
+
.attr('height', (d) => this.height - this.yScale(d.value));
|
|
423
|
+
this._tooltipVisible.set(false);
|
|
424
|
+
})
|
|
425
|
+
.on('click', (event, d) => this.handleBarClick(event, d));
|
|
426
|
+
// Add animation
|
|
427
|
+
bars
|
|
428
|
+
.transition()
|
|
429
|
+
.duration(animationDuration)
|
|
430
|
+
.delay((d, i) => i * 50) // Stagger each bar animation
|
|
431
|
+
.attr('y', (d) => this.yScale(d.value))
|
|
432
|
+
.attr('height', (d) => this.height - this.yScale(d.value))
|
|
433
|
+
.ease(animationEasing); // Use the configured easing function
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Gets the appropriate D3 easing function based on the option string
|
|
437
|
+
*/
|
|
438
|
+
getEasingFunction(easing) {
|
|
439
|
+
switch (easing) {
|
|
440
|
+
case 'linear':
|
|
441
|
+
return this.d3.easeLinear;
|
|
442
|
+
case 'ease':
|
|
443
|
+
return this.d3.easePolyInOut;
|
|
444
|
+
case 'ease-in':
|
|
445
|
+
return this.d3.easePolyIn;
|
|
446
|
+
case 'ease-out':
|
|
447
|
+
return this.d3.easePolyOut;
|
|
448
|
+
case 'ease-in-out':
|
|
449
|
+
return this.d3.easePolyInOut;
|
|
450
|
+
case 'cubic':
|
|
451
|
+
return this.d3.easeCubic;
|
|
452
|
+
case 'cubic-in':
|
|
453
|
+
return this.d3.easeCubicIn;
|
|
454
|
+
case 'cubic-out':
|
|
455
|
+
return this.d3.easeCubicOut;
|
|
456
|
+
case 'cubic-in-out':
|
|
457
|
+
return this.d3.easeCubicInOut;
|
|
458
|
+
default:
|
|
459
|
+
return this.d3.easeCubicOut; // Default easing
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Handles bar hover event and shows tooltip
|
|
464
|
+
*/
|
|
465
|
+
handleBarHover(event, datum) {
|
|
466
|
+
if (this.effectiveOptions().showTooltip !== false) {
|
|
467
|
+
const index = this.data().findIndex((item) => item.id === datum.id);
|
|
468
|
+
const color = datum.color || AXBarChartColors.getColor(index);
|
|
469
|
+
// Calculate percentage of total
|
|
470
|
+
const total = this.data().reduce((sum, item) => sum + item.value, 0);
|
|
471
|
+
const percentage = total > 0 ? ((datum.value / total) * 100).toFixed(1) : '0';
|
|
472
|
+
this._tooltipData.set({
|
|
473
|
+
title: datum.label,
|
|
474
|
+
value: datum.value.toString(),
|
|
475
|
+
percentage: `${percentage}%`,
|
|
476
|
+
color: color,
|
|
477
|
+
});
|
|
478
|
+
this.updateTooltipPosition(event);
|
|
479
|
+
this._tooltipVisible.set(true);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Updates tooltip position based on mouse coordinates
|
|
484
|
+
*/
|
|
485
|
+
updateTooltipPosition(event) {
|
|
486
|
+
const container = this.chartContainerEl().nativeElement.getBoundingClientRect();
|
|
487
|
+
const tooltipEl = this.chartContainerEl().nativeElement.querySelector('.chart-tooltip');
|
|
488
|
+
if (!tooltipEl) {
|
|
489
|
+
const x = event.clientX - container.left;
|
|
490
|
+
const y = event.clientY - container.top;
|
|
491
|
+
this._tooltipPosition.set({ x, y });
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
const tooltipRect = tooltipEl.getBoundingClientRect();
|
|
495
|
+
let x = event.clientX - container.left;
|
|
496
|
+
let y = event.clientY - container.top;
|
|
497
|
+
// Adjust position if near the right edge
|
|
498
|
+
if (x + tooltipRect.width + 10 > container.width) {
|
|
499
|
+
x = x - tooltipRect.width - 10;
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
x = x + 10;
|
|
503
|
+
}
|
|
504
|
+
// Adjust vertical position to ensure tooltip stays within container
|
|
505
|
+
if (y + tooltipRect.height / 2 > container.height) {
|
|
506
|
+
y = container.height - tooltipRect.height / 2;
|
|
507
|
+
}
|
|
508
|
+
else if (y - tooltipRect.height / 2 < 0) {
|
|
509
|
+
y = tooltipRect.height / 2;
|
|
510
|
+
}
|
|
511
|
+
this._tooltipPosition.set({ x, y });
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Handles bar click event
|
|
515
|
+
*/
|
|
516
|
+
handleBarClick(event, datum) {
|
|
517
|
+
this.barClick.emit({ item: datum, event });
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Shows a message when no data is available
|
|
521
|
+
*/
|
|
522
|
+
showNoDataMessage(containerElement) {
|
|
523
|
+
const messageContainer = this.d3
|
|
524
|
+
.select(containerElement)
|
|
525
|
+
.append('div')
|
|
526
|
+
.attr('class', 'ax-bar-chart-no-data-message')
|
|
527
|
+
.style('width', '100%')
|
|
528
|
+
.style('height', '100%')
|
|
529
|
+
.style('display', 'flex')
|
|
530
|
+
.style('flex-direction', 'column')
|
|
531
|
+
.style('align-items', 'center')
|
|
532
|
+
.style('justify-content', 'center')
|
|
533
|
+
.style('text-align', 'center');
|
|
534
|
+
// Add an icon
|
|
535
|
+
messageContainer
|
|
536
|
+
.append('div')
|
|
537
|
+
.attr('class', 'ax-bar-chart-no-data-icon')
|
|
538
|
+
.style('margin-bottom', '10px')
|
|
539
|
+
.style('color', 'var(--ax-text-muted, #999)')
|
|
540
|
+
.html('<i class="fa-light fa-chart-bar fa-2x"></i>');
|
|
541
|
+
// Add text message
|
|
542
|
+
messageContainer
|
|
543
|
+
.append('div')
|
|
544
|
+
.attr('class', 'ax-bar-chart-no-data-text')
|
|
545
|
+
.style('font-size', '16px')
|
|
546
|
+
.style('font-weight', '600')
|
|
547
|
+
.style('color', 'var(--ax-text-color, #333)')
|
|
548
|
+
.text('No data available');
|
|
549
|
+
}
|
|
550
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: AXBarChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
551
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.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 }], 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: [":host{display:block;width:100%;height:100%;min-height:200px}.ax-bar-chart{width:100%;height:100%;position:relative;display:flex;align-items:center;justify-content:center;border-radius:.5rem;overflow:hidden}.ax-bar-chart svg{width:100%;height:100%;max-width:100%;max-height:100%;overflow:visible}.ax-bar-chart-bar{transition:all .3s cubic-bezier(.4,0,.2,1);cursor:pointer}.ax-bar-chart-bar:hover{filter:brightness(.9);transform:translateY(-3px)}.ax-bar-chart-axis-x path,.ax-bar-chart-axis-y path{stroke:var(--ax-border-color, #e0e0e0)}.ax-bar-chart-axis-x line,.ax-bar-chart-axis-y line,.ax-bar-chart-grid line{stroke:var(--ax-border-color, #e0e0e0);stroke-dasharray:2,2;stroke-opacity:.5}.ax-bar-chart-grid path{stroke-width:0}.ax-bar-chart-axis-x text,.ax-bar-chart-axis-y text{fill:var(--ax-text-muted, #666);font-size:clamp(8px,2vmin,12px)}.ax-bar-chart-no-data-message{font-family:var(--ax-font-family, system-ui, sans-serif);display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:1rem;width:100%;height:100%}.ax-bar-chart-no-data-icon{margin-bottom:.75rem;color:var(--ax-text-muted, #999)}.ax-bar-chart-no-data-text{font-weight:600;color:var(--ax-text-color, #333)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXChartTooltipComponent, selector: "ax-chart-tooltip", inputs: ["data", "position", "visible", "showPercentage", "style"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
552
|
+
}
|
|
553
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: AXBarChartComponent, decorators: [{
|
|
554
|
+
type: Component,
|
|
555
|
+
args: [{ selector: 'ax-bar-chart', standalone: true, imports: [CommonModule, 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: [":host{display:block;width:100%;height:100%;min-height:200px}.ax-bar-chart{width:100%;height:100%;position:relative;display:flex;align-items:center;justify-content:center;border-radius:.5rem;overflow:hidden}.ax-bar-chart svg{width:100%;height:100%;max-width:100%;max-height:100%;overflow:visible}.ax-bar-chart-bar{transition:all .3s cubic-bezier(.4,0,.2,1);cursor:pointer}.ax-bar-chart-bar:hover{filter:brightness(.9);transform:translateY(-3px)}.ax-bar-chart-axis-x path,.ax-bar-chart-axis-y path{stroke:var(--ax-border-color, #e0e0e0)}.ax-bar-chart-axis-x line,.ax-bar-chart-axis-y line,.ax-bar-chart-grid line{stroke:var(--ax-border-color, #e0e0e0);stroke-dasharray:2,2;stroke-opacity:.5}.ax-bar-chart-grid path{stroke-width:0}.ax-bar-chart-axis-x text,.ax-bar-chart-axis-y text{fill:var(--ax-text-muted, #666);font-size:clamp(8px,2vmin,12px)}.ax-bar-chart-no-data-message{font-family:var(--ax-font-family, system-ui, sans-serif);display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:1rem;width:100%;height:100%}.ax-bar-chart-no-data-icon{margin-bottom:.75rem;color:var(--ax-text-muted, #999)}.ax-bar-chart-no-data-text{font-weight:600;color:var(--ax-text-color, #333)}\n"] }]
|
|
556
|
+
}], ctorParameters: () => [] });
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Generated bundle index. Do not edit.
|
|
560
|
+
*/
|
|
561
|
+
|
|
562
|
+
export { AXBarChartColors, AXBarChartComponent, AXBarChartDefaultConfig, AX_BAR_CHART_CONFIG, barChartConfig };
|
|
563
|
+
//# sourceMappingURL=acorex-charts-bar-chart.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acorex-charts-bar-chart.mjs","sources":["../../../../libs/charts/bar-chart/src/lib/bar-chart.config.ts","../../../../libs/charts/bar-chart/src/lib/bar-chart.component.ts","../../../../libs/charts/bar-chart/src/lib/bar-chart.component.html","../../../../libs/charts/bar-chart/src/acorex-charts-bar-chart.ts"],"sourcesContent":["import { AX_GLOBAL_CONFIG } from '@acorex/core/config';\nimport { InjectionToken, inject } from '@angular/core';\nimport { set } from 'lodash-es';\nimport { AXPBarChartOption } from './bar-chart.type';\n\nexport const AXBarChartDefaultConfig: AXPBarChartOption = {\n margin: {\n top: 20,\n right: 20,\n bottom: 30,\n left: 40,\n },\n showXAxis: true,\n showYAxis: true,\n showGrid: true,\n showTooltip: true,\n barWidth: 80,\n cornerRadius: 4,\n animationDuration: 800,\n animationEasing: 'cubic-out',\n};\n\nexport const AX_BAR_CHART_CONFIG = new InjectionToken<AXPBarChartOption>('AX_BAR_CHART_CONFIG', {\n providedIn: 'root',\n factory: () => {\n const global = inject(AX_GLOBAL_CONFIG);\n set(global, 'chart.barChart', AXBarChartDefaultConfig);\n return AXBarChartDefaultConfig;\n },\n});\n\nexport type PartialBarChartConfig = Partial<AXPBarChartOption>;\n\nexport function barChartConfig(config: PartialBarChartConfig = {}): AXPBarChartOption {\n const result = {\n ...AXBarChartDefaultConfig,\n ...config,\n };\n return result;\n}\n","import { AXChartTooltipComponent, AXChartTooltipData } from '@acorex/charts/chart-tooltip';\nimport { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n OnDestroy,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { AX_BAR_CHART_CONFIG } from './bar-chart.config';\nimport { AXBarChartClickEvent, AXPBarChartData, AXPBarChartOption } from './bar-chart.type';\n\nexport const AXBarChartColors = {\n // Modern color palette suitable for data visualization\n defaultColors: [\n '#4361ee', // Blue\n '#3a0ca3', // Purple\n '#7209b7', // Violet\n '#f72585', // Pink\n '#4cc9f0', // Light Blue\n '#4895ef', // Sky Blue\n '#560bad', // Deep Purple\n '#f15bb5', // Light Pink\n '#00bbf9', // Cyan\n '#00f5d4', // Teal\n ],\n\n // Get a color from the palette by index with wraparound\n getColor: (index: number, customPalette?: string[]): string => {\n const palette = customPalette || AXBarChartColors.defaultColors;\n return palette[index % palette.length];\n },\n};\n\n/**\n * Bar Chart Component\n * Renders data as vertical bars with interactive hover effects and animations\n */\n@Component({\n selector: 'ax-bar-chart',\n templateUrl: './bar-chart.component.html',\n styleUrls: ['./bar-chart.component.scss'],\n standalone: true,\n imports: [CommonModule, AXChartTooltipComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AXBarChartComponent implements OnDestroy {\n // Inputs\n /** Chart data input */\n data = input<AXPBarChartData[]>([]);\n\n /** Chart options input */\n options = input<AXPBarChartOption>({});\n\n // Outputs\n /** Emitted when a bar is clicked */\n barClick = output<AXBarChartClickEvent>();\n\n // Chart container reference\n private readonly chartContainerEl = viewChild.required<ElementRef<HTMLDivElement>>('chartContainer');\n\n // D3 reference - loaded asynchronously\n protected d3!: typeof import('d3');\n\n // Chart elements\n private svg!: any;\n private chart!: any;\n private xScale!: any;\n private yScale!: any;\n private xAxis!: any;\n private yAxis!: any;\n\n // Chart dimensions\n private width!: number;\n private height!: number;\n private margin = { top: 20, right: 20, bottom: 30, left: 40 };\n\n // Tooltip state\n private _tooltipVisible = signal(false);\n private _tooltipPosition = signal({ x: 0, y: 0 });\n private _tooltipData = signal<AXChartTooltipData>({\n title: '',\n value: '0',\n percentage: '0%',\n color: '',\n });\n\n // Signals for component state\n private _initialized = signal(false);\n private _rendered = signal(false);\n\n // Tooltip accessors\n protected tooltipVisible = this._tooltipVisible.asReadonly();\n protected tooltipPosition = this._tooltipPosition.asReadonly();\n protected tooltipData = this._tooltipData.asReadonly();\n\n // Inject configuration\n private configToken = inject(AX_BAR_CHART_CONFIG);\n\n // Configuration with defaults\n protected effectiveOptions = computed(() => {\n return {\n ...this.configToken,\n ...this.options(),\n };\n });\n\n constructor() {\n // Dynamically load D3 and initialize the chart when the component is ready\n afterNextRender(() => {\n this._initialized.set(true);\n this.loadD3();\n // Create chart after D3 is loaded and container is available\n if (this.d3 && this.chartContainerEl()) {\n this.createChart();\n this._rendered.set(true);\n }\n });\n\n // Watch for changes to redraw the chart\n effect(() => {\n // Access inputs to track them\n this.data();\n this.effectiveOptions();\n\n // Only update if already rendered\n if (this._rendered()) {\n this.updateChart();\n }\n });\n }\n\n ngOnDestroy(): void {\n this.cleanupChart();\n }\n\n /**\n * Loads D3.js dynamically\n */\n protected async loadD3(): Promise<void> {\n try {\n this.d3 = await import('d3');\n // If container is ready, create chart\n if (this._initialized() && this.chartContainerEl()) {\n this.createChart();\n this._rendered.set(true);\n }\n } catch (error) {\n console.error('Failed to load D3.js:', error);\n }\n }\n\n /**\n * Creates the bar chart SVG and renders all elements\n */\n protected createChart(): void {\n if (!this.d3 || !this.chartContainerEl()?.nativeElement) return;\n\n const containerElement = this.chartContainerEl().nativeElement;\n const data = this.data() || [];\n\n // Clear existing chart\n this.d3.select(containerElement).selectAll('svg').remove();\n\n // Early return if no data\n if (!data.length) {\n this.showNoDataMessage(containerElement);\n return;\n }\n\n // Get options and setup dimensions\n const chartOptions = this.effectiveOptions();\n this.setupDimensions(containerElement, chartOptions);\n\n // Create scales and axes\n this.setupScales(data);\n this.createAxes(chartOptions);\n\n // Render the bars\n this.renderBars(data);\n }\n\n /**\n * Updates the chart when inputs change\n */\n protected updateChart(): void {\n this.createChart();\n }\n\n /**\n * Cleans up chart resources\n */\n protected cleanupChart(): void {\n if (this.svg) {\n this.d3?.select(this.chartContainerEl()?.nativeElement).selectAll('svg').remove();\n this.svg = null;\n this.chart = null;\n }\n this._tooltipVisible.set(false);\n }\n\n /**\n * Sets up chart dimensions and creates SVG with responsive attributes\n */\n private setupDimensions(containerElement: HTMLElement, options: AXPBarChartOption): void {\n // Calculate margins based on options\n this.calculateMargins(options);\n\n // Get container dimensions\n const containerWidth = containerElement.clientWidth;\n const containerHeight = containerElement.clientHeight;\n\n // If options specify width and height, use those, otherwise default to container size\n const minDim = Math.min(200, containerWidth, containerHeight); // Ensure reasonable minimum\n\n if (options.width && options.height) {\n // Explicit dimensions provided\n this.width = options.width - this.margin.left - this.margin.right;\n this.height = options.height - this.margin.top - this.margin.bottom;\n } else {\n // Responsive dimensions\n this.width = Math.max(containerWidth, minDim) - this.margin.left - this.margin.right;\n this.height = Math.max(containerHeight, minDim) - this.margin.top - this.margin.bottom;\n }\n\n // Create responsive SVG that scales with its container\n const svg = this.d3\n .select(containerElement)\n .append('svg')\n .attr('width', '100%')\n .attr('height', '100%')\n .attr(\n 'viewBox',\n `0 0 ${this.width + this.margin.left + this.margin.right} ${this.height + this.margin.top + this.margin.bottom}`,\n )\n .attr('preserveAspectRatio', 'xMidYMid meet');\n\n this.svg = svg;\n\n // Create chart group with margins\n this.chart = this.svg.append('g').attr('transform', `translate(${this.margin.left},${this.margin.top})`);\n }\n\n /**\n * Calculates chart margins based on options\n */\n private calculateMargins(options: AXPBarChartOption): void {\n // Start with default margins\n this.margin = {\n top: options.margin?.top ?? 20,\n right: options.margin?.right ?? 20,\n bottom: options.margin?.bottom ?? 30,\n left: options.margin?.left ?? 40,\n };\n\n // Adjust margins if axis labels are present\n if (options.xAxisLabel) {\n const xLabelLength = options.xAxisLabel.length;\n const extraBottomMargin = Math.min(20, Math.max(10, xLabelLength * 0.8));\n this.margin.bottom = Math.max(this.margin.bottom, 30 + extraBottomMargin);\n }\n\n if (options.yAxisLabel) {\n const yLabelLength = options.yAxisLabel.length;\n const extraLeftMargin = Math.min(20, Math.max(10, yLabelLength * 0.8));\n this.margin.left = Math.max(this.margin.left, 40 + extraLeftMargin);\n }\n\n // Ensure minimum margins for axes\n if (options.showXAxis !== false) {\n this.margin.bottom = Math.max(this.margin.bottom, 35);\n }\n\n if (options.showYAxis !== false) {\n this.margin.left = Math.max(this.margin.left, 45);\n }\n }\n\n /**\n * Creates x and y scales for the chart\n */\n private setupScales(data: AXPBarChartData[]): void {\n // Get the bar width percentage (default 80%)\n const barWidthPercent = this.effectiveOptions().barWidth ?? 60 / 100;\n // Calculate padding based on barWidth (inverse relationship)\n const padding = Math.max(0.1, 1 - barWidthPercent);\n\n // Create x scale (band scale for categorical data)\n this.xScale = this.d3\n .scaleBand()\n .domain(data.map((d) => d.label))\n .range([0, this.width])\n .padding(padding);\n\n // Create y scale (linear scale for values)\n this.yScale = this.d3\n .scaleLinear()\n .domain([0, this.d3.max(data, (d) => d.value) || 0])\n .nice()\n .range([this.height, 0]);\n }\n\n /**\n * Creates x and y axes with grid lines\n */\n private createAxes(options: AXPBarChartOption): void {\n // Only create axes if they are enabled in options\n const showXAxis = options.showXAxis !== false;\n const showYAxis = options.showYAxis !== false;\n const showGrid = options.showGrid !== false;\n\n // Create a group for all axes\n const axesGroup = this.chart.append('g').attr('class', 'ax-bar-chart-axes');\n\n if (showXAxis) {\n // Create X axis\n this.xAxis = axesGroup\n .append('g')\n .attr('class', 'ax-bar-chart-axis-x')\n .attr('transform', `translate(0,${this.height})`)\n .call(this.d3.axisBottom(this.xScale));\n\n // Style the axis text\n this.xAxis.selectAll('text').style('font-size', '11px').style('font-weight', '400').style('fill', '#666');\n\n // Add X axis label if provided\n if (options.xAxisLabel) {\n const labelY = this.height + this.margin.bottom * 0.65;\n\n axesGroup\n .append('text')\n .attr('class', 'ax-bar-chart-axis-label ax-x-axis-label')\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'middle')\n .attr('x', this.width / 2)\n .attr('y', labelY)\n .style('font-size', '13px')\n .style('font-weight', '500')\n .style('fill', '#555')\n .text(options.xAxisLabel);\n }\n }\n\n if (showYAxis) {\n // Create Y axis\n this.yAxis = axesGroup.append('g').attr('class', 'ax-bar-chart-axis-y').call(this.d3.axisLeft(this.yScale));\n\n // Style the axis text\n this.yAxis.selectAll('text').style('font-size', '11px').style('font-weight', '400').style('fill', '#666');\n\n // Add Y axis label if provided\n if (options.yAxisLabel) {\n const labelX = -this.height / 2;\n const labelY = -this.margin.left * 0.65;\n\n axesGroup\n .append('text')\n .attr('class', 'ax-bar-chart-axis-label ax-y-axis-label')\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'middle')\n .attr('transform', 'rotate(-90)')\n .attr('x', labelX)\n .attr('y', labelY)\n .style('font-size', '13px')\n .style('font-weight', '500')\n .style('fill', '#555')\n .text(options.yAxisLabel);\n }\n }\n\n if (showGrid) {\n // Add horizontal grid lines\n this.chart\n .append('g')\n .attr('class', 'ax-bar-chart-grid')\n .call(\n this.d3\n .axisLeft(this.yScale)\n .tickSize(-this.width)\n .tickFormat(() => ''),\n )\n .selectAll('.tick')\n .style('color', 'rgb(153 153 153 / 30%)'); // Add gray color to ticks\n }\n }\n\n /**\n * Renders the bars with animations\n */\n private renderBars(data: AXPBarChartData[]): void {\n // Get corner radius from options\n const radius = this.effectiveOptions().cornerRadius;\n\n // Get animation options\n const animationDuration = this.effectiveOptions().animationDuration;\n const animationEasing = this.getEasingFunction(this.effectiveOptions().animationEasing);\n\n // Create a container for all bars\n const barsContainer = this.chart.append('g').attr('class', 'ax-bar-chart-bars-container');\n\n // Create groups for each bar to handle transformations\n const barGroups = barsContainer\n .selectAll('.ax-bar-chart-bar-group')\n .data(data)\n .enter()\n .append('g')\n .style('cursor', 'pointer')\n .attr('class', 'ax-bar-chart-bar-group');\n\n // Add bars inside groups\n const bars = barGroups\n .append('rect')\n .attr('class', 'ax-bar-chart-bar')\n .attr('x', (d: AXPBarChartData) => this.xScale(d.label))\n .attr('width', this.xScale.bandwidth())\n .attr('y', this.height) // Start from bottom for animation\n .attr('height', 0) // Start with height 0 for animation\n .attr('rx', radius) // Rounded corners\n .attr('ry', radius) // Rounded corners\n .attr('fill', (d: AXPBarChartData, i: number) => d.color || AXBarChartColors.getColor(i));\n\n // Set up event handlers on each group\n barGroups\n .on('mouseenter', (event: MouseEvent, d: AXPBarChartData) => {\n const barEl = this.d3.select(event.currentTarget).select('rect');\n const currentX = parseFloat(barEl.attr('x'));\n const currentY = parseFloat(barEl.attr('y'));\n const currentWidth = parseFloat(barEl.attr('width'));\n const currentHeight = parseFloat(barEl.attr('height'));\n\n // Calculate horizontal center point of the bar\n const centerX = currentX + currentWidth / 2;\n\n // Scale amount (5% larger)\n const scaleX = 1.05;\n const scaleY = 1.05;\n\n // Calculate new dimensions with scaling\n const newWidth = currentWidth * scaleX;\n const newHeight = currentHeight * scaleY;\n\n // Calculate new position:\n // - Horizontally center-aligned\n // - Vertically grow only upward from the bottom (X-axis)\n const newX = centerX - newWidth / 2;\n // The bottom of the bar stays at the same position (aligned with x-axis)\n const newY = currentY - (newHeight - currentHeight);\n\n // Apply the new position and size\n barEl\n .transition()\n .duration(200)\n .attr('x', newX)\n .attr('y', newY)\n .attr('width', newWidth)\n .attr('height', newHeight);\n\n this.handleBarHover(event, d);\n })\n .on('mousemove', (event: MouseEvent) => this.updateTooltipPosition(event))\n .on('mouseleave', (event: MouseEvent, d: AXPBarChartData) => {\n const barEl = this.d3.select(event.currentTarget).select('rect');\n\n // Restore original position and size\n barEl\n .transition()\n .duration(200)\n .attr('x', (d: AXPBarChartData) => this.xScale(d.label))\n .attr('y', (d: AXPBarChartData) => this.yScale(d.value))\n .attr('width', this.xScale.bandwidth())\n .attr('height', (d: AXPBarChartData) => this.height - this.yScale(d.value));\n\n this._tooltipVisible.set(false);\n })\n .on('click', (event: MouseEvent, d: AXPBarChartData) => this.handleBarClick(event, d));\n\n // Add animation\n bars\n .transition()\n .duration(animationDuration)\n .delay((d: AXPBarChartData, i: number) => i * 50) // Stagger each bar animation\n .attr('y', (d: AXPBarChartData) => this.yScale(d.value))\n .attr('height', (d: AXPBarChartData) => this.height - this.yScale(d.value))\n .ease(animationEasing); // Use the configured easing function\n }\n\n /**\n * Gets the appropriate D3 easing function based on the option string\n */\n private getEasingFunction(easing?: string): any {\n switch (easing) {\n case 'linear':\n return this.d3.easeLinear;\n case 'ease':\n return this.d3.easePolyInOut;\n case 'ease-in':\n return this.d3.easePolyIn;\n case 'ease-out':\n return this.d3.easePolyOut;\n case 'ease-in-out':\n return this.d3.easePolyInOut;\n case 'cubic':\n return this.d3.easeCubic;\n case 'cubic-in':\n return this.d3.easeCubicIn;\n case 'cubic-out':\n return this.d3.easeCubicOut;\n case 'cubic-in-out':\n return this.d3.easeCubicInOut;\n default:\n return this.d3.easeCubicOut; // Default easing\n }\n }\n\n /**\n * Handles bar hover event and shows tooltip\n */\n private handleBarHover(event: MouseEvent, datum: AXPBarChartData): void {\n if (this.effectiveOptions().showTooltip !== false) {\n const index = this.data().findIndex((item) => item.id === datum.id);\n const color = datum.color || AXBarChartColors.getColor(index);\n\n // Calculate percentage of total\n const total = this.data().reduce((sum, item) => sum + item.value, 0);\n const percentage = total > 0 ? ((datum.value / total) * 100).toFixed(1) : '0';\n\n this._tooltipData.set({\n title: datum.label,\n value: datum.value.toString(),\n percentage: `${percentage}%`,\n color: color,\n });\n\n this.updateTooltipPosition(event);\n this._tooltipVisible.set(true);\n }\n }\n\n /**\n * Updates tooltip position based on mouse coordinates\n */\n private updateTooltipPosition(event: MouseEvent): void {\n const container = this.chartContainerEl().nativeElement.getBoundingClientRect();\n const tooltipEl = this.chartContainerEl().nativeElement.querySelector('.chart-tooltip');\n\n if (!tooltipEl) {\n const x = event.clientX - container.left;\n const y = event.clientY - container.top;\n this._tooltipPosition.set({ x, y });\n return;\n }\n\n const tooltipRect = tooltipEl.getBoundingClientRect();\n let x = event.clientX - container.left;\n let y = event.clientY - container.top;\n\n // Adjust position if near the right edge\n if (x + tooltipRect.width + 10 > container.width) {\n x = x - tooltipRect.width - 10;\n } else {\n x = x + 10;\n }\n\n // Adjust vertical position to ensure tooltip stays within container\n if (y + tooltipRect.height / 2 > container.height) {\n y = container.height - tooltipRect.height / 2;\n } else if (y - tooltipRect.height / 2 < 0) {\n y = tooltipRect.height / 2;\n }\n\n this._tooltipPosition.set({ x, y });\n }\n\n /**\n * Handles bar click event\n */\n private handleBarClick(event: MouseEvent, datum: AXPBarChartData): void {\n this.barClick.emit({ item: datum, event });\n }\n\n /**\n * Shows a message when no data is available\n */\n private showNoDataMessage(containerElement: HTMLElement): void {\n const messageContainer = this.d3\n .select(containerElement)\n .append('div')\n .attr('class', 'ax-bar-chart-no-data-message')\n .style('width', '100%')\n .style('height', '100%')\n .style('display', 'flex')\n .style('flex-direction', 'column')\n .style('align-items', 'center')\n .style('justify-content', 'center')\n .style('text-align', 'center');\n\n // Add an icon\n messageContainer\n .append('div')\n .attr('class', 'ax-bar-chart-no-data-icon')\n .style('margin-bottom', '10px')\n .style('color', 'var(--ax-text-muted, #999)')\n .html('<i class=\"fa-light fa-chart-bar fa-2x\"></i>');\n\n // Add text message\n messageContainer\n .append('div')\n .attr('class', 'ax-bar-chart-no-data-text')\n .style('font-size', '16px')\n .style('font-weight', '600')\n .style('color', 'var(--ax-text-color, #333)')\n .text('No data available');\n }\n}\n","<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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|