@acorex/charts 20.1.5 → 20.1.7
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.
|
@@ -190,7 +190,7 @@ class AXBarChartComponent extends NXComponent {
|
|
|
190
190
|
*/
|
|
191
191
|
setupDimensions(containerElement, options) {
|
|
192
192
|
// Calculate margins based on options
|
|
193
|
-
this.calculateMargins(options);
|
|
193
|
+
this.calculateMargins(options, containerElement.clientWidth);
|
|
194
194
|
// Get container dimensions
|
|
195
195
|
const containerWidth = containerElement.clientWidth;
|
|
196
196
|
const containerHeight = containerElement.clientHeight;
|
|
@@ -221,7 +221,7 @@ class AXBarChartComponent extends NXComponent {
|
|
|
221
221
|
/**
|
|
222
222
|
* Calculates chart margins based on options
|
|
223
223
|
*/
|
|
224
|
-
calculateMargins(options) {
|
|
224
|
+
calculateMargins(options, containerWidth) {
|
|
225
225
|
// Start with default margins
|
|
226
226
|
this.margin = {
|
|
227
227
|
top: 20,
|
|
@@ -229,6 +229,30 @@ class AXBarChartComponent extends NXComponent {
|
|
|
229
229
|
bottom: 30,
|
|
230
230
|
left: 40,
|
|
231
231
|
};
|
|
232
|
+
const visibleData = this.data().filter((d) => !this.isBarHidden(d.id));
|
|
233
|
+
const barCount = visibleData.length;
|
|
234
|
+
// Pre-emptively increase bottom margin if x-axis labels are likely to be rotated.
|
|
235
|
+
// This is an estimation before scales and full dimensions are calculated.
|
|
236
|
+
if (barCount > 0 && containerWidth > 0) {
|
|
237
|
+
const workingWidth = containerWidth - this.margin.left - this.margin.right;
|
|
238
|
+
if (workingWidth > 0) {
|
|
239
|
+
const availableWidthPerBar = workingWidth / barCount;
|
|
240
|
+
const longestLabel = visibleData.reduce((a, b) => (a.label.length > b.label.length ? a : b), {
|
|
241
|
+
label: '',
|
|
242
|
+
}).label;
|
|
243
|
+
// Estimate font size using the same logic as in createAxes, but with workingWidth.
|
|
244
|
+
const estimatedFontSize = Math.max(11, Math.min(15, Math.round(workingWidth / 45)));
|
|
245
|
+
// Estimate label width (using 0.6 as an average character width-to-height ratio).
|
|
246
|
+
const estimatedLongestLabelWidth = longestLabel.length * estimatedFontSize * 0.6;
|
|
247
|
+
// If estimated label width is greater than the space available, rotation will occur.
|
|
248
|
+
if (estimatedLongestLabelWidth > availableWidthPerBar) {
|
|
249
|
+
// Add space for rotated labels. The height of the rotated label's bounding box
|
|
250
|
+
// is roughly its length * sin(45 degrees). Add some padding.
|
|
251
|
+
const requiredExtraMargin = estimatedLongestLabelWidth * Math.sin(Math.PI / 4) + 10;
|
|
252
|
+
this.margin.bottom += Math.min(60, requiredExtraMargin); // Cap max extra margin.
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
232
256
|
// Adjust margins if axis labels are present
|
|
233
257
|
if (options.xAxisLabel) {
|
|
234
258
|
const xLabelLength = options.xAxisLabel.length;
|
|
@@ -289,11 +313,25 @@ class AXBarChartComponent extends NXComponent {
|
|
|
289
313
|
.call(this.d3.axisBottom(this.xScale));
|
|
290
314
|
// Style the axis text
|
|
291
315
|
const dynamicXAxisTickFontSize = Math.max(11, Math.min(15, Math.round(this.width / 45)));
|
|
292
|
-
this.xAxis
|
|
316
|
+
const xAxisTicks = this.xAxis
|
|
293
317
|
.selectAll('text')
|
|
294
318
|
.style('font-size', `${dynamicXAxisTickFontSize}px`)
|
|
295
319
|
.style('font-weight', '400')
|
|
296
320
|
.style('fill', 'rgba(var(--ax-comp-bar-chart-labels-color), 0.7)');
|
|
321
|
+
// Automatically rotate labels if they are likely to overlap
|
|
322
|
+
if (this.xScale.domain().length > 0) {
|
|
323
|
+
const step = this.xScale.step();
|
|
324
|
+
const longestLabel = this.xScale.domain().reduce((a, b) => (a.length > b.length ? a : b), '');
|
|
325
|
+
// Using 0.55 as a safer estimate for char width-to-height ratio
|
|
326
|
+
const estimatedLongestLabelWidth = longestLabel.length * dynamicXAxisTickFontSize * 0.55;
|
|
327
|
+
if (estimatedLongestLabelWidth > step) {
|
|
328
|
+
xAxisTicks
|
|
329
|
+
.attr('transform', 'rotate(-45)')
|
|
330
|
+
.style('text-anchor', 'end')
|
|
331
|
+
.attr('dx', '-0.8em')
|
|
332
|
+
.attr('dy', '0.15em');
|
|
333
|
+
}
|
|
334
|
+
}
|
|
297
335
|
// Style all lines in the x-axis (path, ticks)
|
|
298
336
|
this.xAxis.selectAll('line, path').style('stroke', 'rgb(var(--ax-comp-bar-chart-grid-lines-color))');
|
|
299
337
|
// Add X axis label if provided
|