@acorex/charts 20.9.3 → 20.9.4

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.
@@ -240,6 +240,7 @@ declare class AXBarChartComponent extends AXChartComponent implements OnDestroy,
240
240
  */
241
241
  private handleBarHover;
242
242
  private updateTooltipPosition;
243
+ private scheduleTooltipPosition;
243
244
  /**
244
245
  * Enhanced tooltip positioning that considers chart boundaries and prevents overflow
245
246
  */
@@ -270,6 +270,7 @@ declare class AXDonutChartComponent extends AXChartComponent implements OnDestro
270
270
  */
271
271
  private handleSegmentLeave;
272
272
  private updateTooltipPosition;
273
+ private scheduleTooltipPosition;
273
274
  /**
274
275
  * Adds center display with total value
275
276
  */
@@ -221,7 +221,7 @@ class AXBarChartComponent extends AXChartComponent {
221
221
  const visibleSingleData = isClustered ? [] : this.visibleData();
222
222
  const groupedData = isClustered ? inputValue : [];
223
223
  // Clear existing chart SVG and messages (do not remove tooltip component)
224
- this.d3.select(containerElement).selectAll('svg, .ax-chart-message-container').remove();
224
+ this.clearChartArea(containerElement);
225
225
  // Early return if no data
226
226
  if (!Array.isArray(inputValue) || inputValue.length === 0) {
227
227
  this.showNoDataMessage(containerElement);
@@ -264,7 +264,7 @@ class AXBarChartComponent extends AXChartComponent {
264
264
  this._pendingTooltipCoords = null;
265
265
  const container = this.chartContainerEl()?.nativeElement;
266
266
  if (container) {
267
- this.d3?.select(container).selectAll('svg, .ax-chart-message-container').remove();
267
+ this.clearChartArea(container);
268
268
  }
269
269
  this.svg = undefined;
270
270
  this.chart = undefined;
@@ -920,24 +920,35 @@ class AXBarChartComponent extends AXChartComponent {
920
920
  percentage: `${percentage}%`,
921
921
  color: color,
922
922
  });
923
- this.updateTooltipPosition(event);
924
923
  this._tooltipVisible.set(true);
924
+ this.updateTooltipPosition(event);
925
925
  }
926
926
  }
927
927
  updateTooltipPosition(event) {
928
928
  this._pendingTooltipCoords = { x: event.clientX, y: event.clientY };
929
929
  if (this._tooltipRafId != null)
930
930
  return;
931
+ this.scheduleTooltipPosition(0);
932
+ }
933
+ scheduleTooltipPosition(attempt) {
931
934
  this._tooltipRafId = requestAnimationFrame(() => {
932
- this._tooltipRafId = null;
933
935
  const coords = this._pendingTooltipCoords;
934
- if (!coords)
936
+ if (!coords) {
937
+ this._tooltipRafId = null;
935
938
  return;
939
+ }
936
940
  const containerEl = this.chartContainerEl()?.nativeElement;
937
- if (!containerEl)
941
+ if (!containerEl) {
942
+ this._tooltipRafId = null;
938
943
  return;
939
- const containerRect = containerEl.getBoundingClientRect();
944
+ }
940
945
  const tooltipEl = containerEl.querySelector('.chart-tooltip');
946
+ if (!tooltipEl && this._tooltipVisible() && attempt < 3) {
947
+ this.scheduleTooltipPosition(attempt + 1);
948
+ return;
949
+ }
950
+ this._tooltipRafId = null;
951
+ const containerRect = containerEl.getBoundingClientRect();
941
952
  const tooltipRect = tooltipEl ? tooltipEl.getBoundingClientRect() : null;
942
953
  const pos = this.computeEnhancedTooltipPosition(containerRect, tooltipRect, coords.x, coords.y);
943
954
  this._tooltipPosition.set(pos);
@@ -947,51 +958,42 @@ class AXBarChartComponent extends AXChartComponent {
947
958
  * Enhanced tooltip positioning that considers chart boundaries and prevents overflow
948
959
  */
949
960
  computeEnhancedTooltipPosition(containerRect, tooltipRect, clientX, clientY) {
950
- const cursorX = clientX - containerRect.left;
951
- const cursorY = clientY - containerRect.top;
961
+ const containerLeft = containerRect.left;
962
+ const containerTop = containerRect.top;
963
+ const containerRight = containerRect.right;
964
+ const containerBottom = containerRect.bottom;
952
965
  if (!tooltipRect) {
953
- // Default positioning when tooltip dimensions are unknown
954
966
  return {
955
- x: Math.min(cursorX + this.TOOLTIP_GAP, containerRect.width - this.TOOLTIP_GAP),
956
- y: Math.max(this.TOOLTIP_GAP, Math.min(cursorY, containerRect.height - this.TOOLTIP_GAP)),
967
+ x: Math.min(clientX + this.TOOLTIP_GAP, containerRight - this.TOOLTIP_GAP),
968
+ y: Math.max(containerTop + this.TOOLTIP_GAP, Math.min(clientY + this.TOOLTIP_GAP, containerBottom - this.TOOLTIP_GAP)),
957
969
  };
958
970
  }
959
- // Calculate available space in each direction
960
- const spaceRight = containerRect.width - cursorX;
961
- const spaceLeft = cursorX;
962
- const spaceBelow = containerRect.height - cursorY;
963
- const spaceAbove = cursorY;
964
- // Determine best horizontal position
971
+ const spaceRight = containerRight - clientX;
972
+ const spaceLeft = clientX - containerLeft;
973
+ const spaceBelow = containerBottom - clientY;
974
+ const spaceAbove = clientY - containerTop;
965
975
  let x;
966
976
  if (spaceRight >= tooltipRect.width + this.TOOLTIP_GAP) {
967
- // Position to the right of cursor
968
- x = cursorX + this.TOOLTIP_GAP;
977
+ x = clientX + this.TOOLTIP_GAP;
969
978
  }
970
979
  else if (spaceLeft >= tooltipRect.width + this.TOOLTIP_GAP) {
971
- // Position to the left of cursor
972
- x = cursorX - tooltipRect.width - this.TOOLTIP_GAP;
980
+ x = clientX - tooltipRect.width - this.TOOLTIP_GAP;
973
981
  }
974
982
  else {
975
- // Center horizontally if neither side has enough space
976
- x = Math.max(this.TOOLTIP_GAP, Math.min((containerRect.width - tooltipRect.width) / 2, containerRect.width - tooltipRect.width - this.TOOLTIP_GAP));
983
+ x = Math.max(containerLeft + this.TOOLTIP_GAP, Math.min(containerLeft + (containerRect.width - tooltipRect.width) / 2, containerRight - tooltipRect.width - this.TOOLTIP_GAP));
977
984
  }
978
- // Calculate best vertical position
979
985
  let y;
980
986
  if (spaceBelow >= tooltipRect.height + this.TOOLTIP_GAP) {
981
- // Position below cursor
982
- y = cursorY + this.TOOLTIP_GAP;
987
+ y = clientY + this.TOOLTIP_GAP;
983
988
  }
984
989
  else if (spaceAbove >= tooltipRect.height + this.TOOLTIP_GAP) {
985
- // Position above cursor
986
- y = cursorY - tooltipRect.height - this.TOOLTIP_GAP;
990
+ y = clientY - tooltipRect.height - this.TOOLTIP_GAP;
987
991
  }
988
992
  else {
989
- // Center vertically if neither direction has enough space
990
- y = Math.max(this.TOOLTIP_GAP, Math.min((containerRect.height - tooltipRect.height) / 2, containerRect.height - tooltipRect.height - this.TOOLTIP_GAP));
993
+ y = Math.max(containerTop + this.TOOLTIP_GAP, Math.min(containerTop + (containerRect.height - tooltipRect.height) / 2, containerBottom - tooltipRect.height - this.TOOLTIP_GAP));
991
994
  }
992
- // Ensure tooltip stays within container bounds
993
- x = Math.max(this.TOOLTIP_GAP, Math.min(x, containerRect.width - tooltipRect.width - this.TOOLTIP_GAP));
994
- y = Math.max(this.TOOLTIP_GAP, Math.min(y, containerRect.height - tooltipRect.height - this.TOOLTIP_GAP));
995
+ x = Math.max(containerLeft + this.TOOLTIP_GAP, Math.min(x, containerRight - tooltipRect.width - this.TOOLTIP_GAP));
996
+ y = Math.max(containerTop + this.TOOLTIP_GAP, Math.min(y, containerBottom - tooltipRect.height - this.TOOLTIP_GAP));
995
997
  return { x, y };
996
998
  }
997
999
  /**
@@ -1176,10 +1178,7 @@ class AXBarChartComponent extends AXChartComponent {
1176
1178
  this.hiddenBars.delete(id);
1177
1179
  if (wasAllHidden) {
1178
1180
  if (this.chartContainerEl()?.nativeElement) {
1179
- this.d3
1180
- ?.select(this.chartContainerEl().nativeElement)
1181
- .selectAll('svg, .ax-chart-message-container')
1182
- .remove();
1181
+ this.clearChartArea(this.chartContainerEl().nativeElement);
1183
1182
  setTimeout(() => {
1184
1183
  this.createChart();
1185
1184
  }, 0);
@@ -1204,7 +1203,7 @@ class AXBarChartComponent extends AXChartComponent {
1204
1203
  this.hiddenSeries.delete(id);
1205
1204
  if (wasAllHidden) {
1206
1205
  if (this.chartContainerEl()?.nativeElement) {
1207
- this.d3?.select(this.chartContainerEl().nativeElement).selectAll('svg, .ax-chart-message-container').remove();
1206
+ this.clearChartArea(this.chartContainerEl().nativeElement);
1208
1207
  setTimeout(() => {
1209
1208
  this.createChart();
1210
1209
  }, 0);
@@ -1225,6 +1224,8 @@ class AXBarChartComponent extends AXChartComponent {
1225
1224
  return this.chartContainerEl()?.nativeElement ?? null;
1226
1225
  }
1227
1226
  clearChartArea(containerElement) {
1227
+ if (!this.d3)
1228
+ return;
1228
1229
  this.d3.select(containerElement).selectAll('svg, .ax-chart-empty, .ax-chart-message-container').remove();
1229
1230
  }
1230
1231
  /**