@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