@odoo/o-spreadsheet 18.2.17 → 18.2.18

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.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.2.17
6
- * @date 2025-06-12T09:52:15.050Z
7
- * @hash ea64209
5
+ * @version 18.2.18
6
+ * @date 2025-06-19T18:24:41.051Z
7
+ * @hash 024c134
8
8
  */
9
9
 
10
10
  'use strict';
@@ -10368,6 +10368,7 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
10368
10368
  if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden) {
10369
10369
  continue;
10370
10370
  }
10371
+ const yAxisScale = chart.scales[dataset.yAxisID];
10371
10372
  for (let i = 0; i < dataset._parsed.length; i++) {
10372
10373
  const parsedValue = dataset._parsed[i];
10373
10374
  const value = Number(chart.config.type === "radar" ? parsedValue.r : parsedValue.y);
@@ -10378,10 +10379,18 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
10378
10379
  const xPosition = point.x;
10379
10380
  let yPosition = 0;
10380
10381
  if (chart.config.type === "line" || chart.config.type === "radar") {
10381
- yPosition = point.y - 10;
10382
+ yPosition = value < 0 ? point.y + 10 : point.y - 10;
10382
10383
  }
10383
10384
  else {
10384
- yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
10385
+ const yZeroLine = yAxisScale.getPixelForValue(0);
10386
+ const distanceFromAxisOrigin = Math.abs(yZeroLine - point.y);
10387
+ const textHeight = 12; // ChartJS default text height
10388
+ if (distanceFromAxisOrigin < textHeight) {
10389
+ yPosition = value < 0 ? yZeroLine + textHeight / 2 : yZeroLine - textHeight / 2;
10390
+ }
10391
+ else {
10392
+ yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
10393
+ }
10385
10394
  }
10386
10395
  yPosition = Math.min(yPosition, yMax);
10387
10396
  yPosition = Math.max(yPosition, yMin);
@@ -10391,7 +10400,7 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
10391
10400
  }
10392
10401
  for (const otherPosition of textsPositions[xPosition] || []) {
10393
10402
  if (Math.abs(otherPosition - yPosition) < 13) {
10394
- yPosition = otherPosition - 13;
10403
+ yPosition = value < 0 ? otherPosition + 13 : otherPosition - 13;
10395
10404
  }
10396
10405
  }
10397
10406
  textsPositions[xPosition].push(yPosition);
@@ -10410,6 +10419,8 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
10410
10419
  if (isTrendLineAxis(dataset.xAxisID)) {
10411
10420
  return; // ignore trend lines
10412
10421
  }
10422
+ const xAxisScale = chart.scales[dataset.xAxisID];
10423
+ const xZeroLine = xAxisScale.getPixelForValue(0);
10413
10424
  for (let i = 0; i < dataset._parsed.length; i++) {
10414
10425
  const value = Number(dataset._parsed[i].x);
10415
10426
  if (isNaN(value)) {
@@ -10418,17 +10429,27 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
10418
10429
  const displayValue = options.callback(value, dataset, i);
10419
10430
  const point = dataset.data[i];
10420
10431
  const yPosition = point.y;
10421
- let xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
10422
- xPosition = Math.min(xPosition, xMax);
10423
- xPosition = Math.max(xPosition, xMin);
10432
+ const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
10433
+ const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
10434
+ const PADDING = 3;
10435
+ let xPosition;
10436
+ if (distanceFromAxisOrigin < textWidth) {
10437
+ xPosition =
10438
+ value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
10439
+ }
10440
+ else {
10441
+ xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
10442
+ xPosition = Math.min(xPosition, xMax);
10443
+ xPosition = Math.max(xPosition, xMin);
10444
+ }
10424
10445
  // Avoid overlapping texts with same Y
10425
10446
  if (!textsPositions[yPosition]) {
10426
10447
  textsPositions[yPosition] = [];
10427
10448
  }
10428
- const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
10429
10449
  for (const otherPosition of textsPositions[yPosition]) {
10430
10450
  if (Math.abs(otherPosition - xPosition) < textWidth) {
10431
- xPosition = otherPosition + textWidth + 3;
10451
+ xPosition =
10452
+ value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
10432
10453
  }
10433
10454
  }
10434
10455
  textsPositions[yPosition].push(xPosition);
@@ -30112,7 +30133,9 @@ function getPyramidChartShowValues(definition, args) {
30112
30133
  background: definition.background,
30113
30134
  callback: (value, dataset) => {
30114
30135
  value = Math.abs(Number(value));
30115
- return formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
30136
+ return value === 0
30137
+ ? ""
30138
+ : formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
30116
30139
  },
30117
30140
  };
30118
30141
  }
@@ -34781,6 +34804,10 @@ const REMOVE_ROWS_ACTION = (env) => {
34781
34804
  });
34782
34805
  };
34783
34806
  const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
34807
+ if ((dimension === "COL" && env.model.getters.getActiveRows().size > 0) ||
34808
+ (dimension === "ROW" && env.model.getters.getActiveCols().size > 0)) {
34809
+ return false;
34810
+ }
34784
34811
  const sheetId = env.model.getters.getActiveSheetId();
34785
34812
  const selectedElements = env.model.getters.getElementsFromSelection(dimension);
34786
34813
  const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
@@ -37760,11 +37787,11 @@ class OTRegistry extends Registry {
37760
37787
  * transformation function given
37761
37788
  */
37762
37789
  addTransformation(executed, toTransforms, fn) {
37763
- for (let toTransform of toTransforms) {
37764
- if (!this.content[toTransform]) {
37765
- this.content[toTransform] = new Map();
37766
- }
37767
- this.content[toTransform].set(executed, fn);
37790
+ if (!this.content[executed]) {
37791
+ this.content[executed] = new Map();
37792
+ }
37793
+ for (const toTransform of toTransforms) {
37794
+ this.content[executed].set(toTransform, fn);
37768
37795
  }
37769
37796
  return this;
37770
37797
  }
@@ -37773,7 +37800,7 @@ class OTRegistry extends Registry {
37773
37800
  * that the executed command happened.
37774
37801
  */
37775
37802
  getTransformation(toTransform, executed) {
37776
- return this.content[toTransform] && this.content[toTransform].get(executed);
37803
+ return this.content[executed] && this.content[executed].get(toTransform);
37777
37804
  }
37778
37805
  }
37779
37806
  const otRegistry = new OTRegistry();
@@ -64767,10 +64794,20 @@ function transform(toTransform, executed) {
64767
64794
  */
64768
64795
  function transformAll(toTransform, executed) {
64769
64796
  let transformedCommands = [...toTransform];
64797
+ const possibleTransformations = new Set(otRegistry.getKeys());
64770
64798
  for (const executedCommand of executed) {
64771
- transformedCommands = transformedCommands
64772
- .map((cmd) => transform(cmd, executedCommand))
64773
- .filter(isDefined);
64799
+ // If the executed command is not in the registry, we skip it
64800
+ // because we know there won't be any transformation impacting the
64801
+ // commands to transform.
64802
+ if (possibleTransformations.has(executedCommand.type)) {
64803
+ transformedCommands = transformedCommands.reduce((acc, cmd) => {
64804
+ const transformed = transform(cmd, executedCommand);
64805
+ if (transformed) {
64806
+ acc.push(transformed);
64807
+ }
64808
+ return acc;
64809
+ }, []);
64810
+ }
64774
64811
  }
64775
64812
  return transformedCommands;
64776
64813
  }
@@ -66459,7 +66496,7 @@ class SheetUIPlugin extends UIPlugin {
66459
66496
  }
66460
66497
  const position = this.getters.getCellPosition(cell.id);
66461
66498
  const colSize = this.getters.getColSize(sheetId, position.col);
66462
- if (cell.isFormula) {
66499
+ if (cell.isFormula || this.getters.getArrayFormulaSpreadingOn(position)) {
66463
66500
  const content = this.getters.getEvaluatedCell(position).formattedValue;
66464
66501
  const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
66465
66502
  if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) {
@@ -77015,6 +77052,6 @@ exports.tokenColors = tokenColors;
77015
77052
  exports.tokenize = tokenize;
77016
77053
 
77017
77054
 
77018
- __info__.version = "18.2.17";
77019
- __info__.date = "2025-06-12T09:52:15.050Z";
77020
- __info__.hash = "ea64209";
77055
+ __info__.version = "18.2.18";
77056
+ __info__.date = "2025-06-19T18:24:41.051Z";
77057
+ __info__.hash = "024c134";
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.2.17
6
- * @date 2025-06-12T09:52:15.050Z
7
- * @hash ea64209
5
+ * @version 18.2.18
6
+ * @date 2025-06-19T18:24:41.051Z
7
+ * @hash 024c134
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -10366,6 +10366,7 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
10366
10366
  if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden) {
10367
10367
  continue;
10368
10368
  }
10369
+ const yAxisScale = chart.scales[dataset.yAxisID];
10369
10370
  for (let i = 0; i < dataset._parsed.length; i++) {
10370
10371
  const parsedValue = dataset._parsed[i];
10371
10372
  const value = Number(chart.config.type === "radar" ? parsedValue.r : parsedValue.y);
@@ -10376,10 +10377,18 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
10376
10377
  const xPosition = point.x;
10377
10378
  let yPosition = 0;
10378
10379
  if (chart.config.type === "line" || chart.config.type === "radar") {
10379
- yPosition = point.y - 10;
10380
+ yPosition = value < 0 ? point.y + 10 : point.y - 10;
10380
10381
  }
10381
10382
  else {
10382
- yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
10383
+ const yZeroLine = yAxisScale.getPixelForValue(0);
10384
+ const distanceFromAxisOrigin = Math.abs(yZeroLine - point.y);
10385
+ const textHeight = 12; // ChartJS default text height
10386
+ if (distanceFromAxisOrigin < textHeight) {
10387
+ yPosition = value < 0 ? yZeroLine + textHeight / 2 : yZeroLine - textHeight / 2;
10388
+ }
10389
+ else {
10390
+ yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
10391
+ }
10383
10392
  }
10384
10393
  yPosition = Math.min(yPosition, yMax);
10385
10394
  yPosition = Math.max(yPosition, yMin);
@@ -10389,7 +10398,7 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
10389
10398
  }
10390
10399
  for (const otherPosition of textsPositions[xPosition] || []) {
10391
10400
  if (Math.abs(otherPosition - yPosition) < 13) {
10392
- yPosition = otherPosition - 13;
10401
+ yPosition = value < 0 ? otherPosition + 13 : otherPosition - 13;
10393
10402
  }
10394
10403
  }
10395
10404
  textsPositions[xPosition].push(yPosition);
@@ -10408,6 +10417,8 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
10408
10417
  if (isTrendLineAxis(dataset.xAxisID)) {
10409
10418
  return; // ignore trend lines
10410
10419
  }
10420
+ const xAxisScale = chart.scales[dataset.xAxisID];
10421
+ const xZeroLine = xAxisScale.getPixelForValue(0);
10411
10422
  for (let i = 0; i < dataset._parsed.length; i++) {
10412
10423
  const value = Number(dataset._parsed[i].x);
10413
10424
  if (isNaN(value)) {
@@ -10416,17 +10427,27 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
10416
10427
  const displayValue = options.callback(value, dataset, i);
10417
10428
  const point = dataset.data[i];
10418
10429
  const yPosition = point.y;
10419
- let xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
10420
- xPosition = Math.min(xPosition, xMax);
10421
- xPosition = Math.max(xPosition, xMin);
10430
+ const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
10431
+ const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
10432
+ const PADDING = 3;
10433
+ let xPosition;
10434
+ if (distanceFromAxisOrigin < textWidth) {
10435
+ xPosition =
10436
+ value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
10437
+ }
10438
+ else {
10439
+ xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
10440
+ xPosition = Math.min(xPosition, xMax);
10441
+ xPosition = Math.max(xPosition, xMin);
10442
+ }
10422
10443
  // Avoid overlapping texts with same Y
10423
10444
  if (!textsPositions[yPosition]) {
10424
10445
  textsPositions[yPosition] = [];
10425
10446
  }
10426
- const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
10427
10447
  for (const otherPosition of textsPositions[yPosition]) {
10428
10448
  if (Math.abs(otherPosition - xPosition) < textWidth) {
10429
- xPosition = otherPosition + textWidth + 3;
10449
+ xPosition =
10450
+ value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
10430
10451
  }
10431
10452
  }
10432
10453
  textsPositions[yPosition].push(xPosition);
@@ -30110,7 +30131,9 @@ function getPyramidChartShowValues(definition, args) {
30110
30131
  background: definition.background,
30111
30132
  callback: (value, dataset) => {
30112
30133
  value = Math.abs(Number(value));
30113
- return formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
30134
+ return value === 0
30135
+ ? ""
30136
+ : formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
30114
30137
  },
30115
30138
  };
30116
30139
  }
@@ -34779,6 +34802,10 @@ const REMOVE_ROWS_ACTION = (env) => {
34779
34802
  });
34780
34803
  };
34781
34804
  const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
34805
+ if ((dimension === "COL" && env.model.getters.getActiveRows().size > 0) ||
34806
+ (dimension === "ROW" && env.model.getters.getActiveCols().size > 0)) {
34807
+ return false;
34808
+ }
34782
34809
  const sheetId = env.model.getters.getActiveSheetId();
34783
34810
  const selectedElements = env.model.getters.getElementsFromSelection(dimension);
34784
34811
  const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
@@ -37758,11 +37785,11 @@ class OTRegistry extends Registry {
37758
37785
  * transformation function given
37759
37786
  */
37760
37787
  addTransformation(executed, toTransforms, fn) {
37761
- for (let toTransform of toTransforms) {
37762
- if (!this.content[toTransform]) {
37763
- this.content[toTransform] = new Map();
37764
- }
37765
- this.content[toTransform].set(executed, fn);
37788
+ if (!this.content[executed]) {
37789
+ this.content[executed] = new Map();
37790
+ }
37791
+ for (const toTransform of toTransforms) {
37792
+ this.content[executed].set(toTransform, fn);
37766
37793
  }
37767
37794
  return this;
37768
37795
  }
@@ -37771,7 +37798,7 @@ class OTRegistry extends Registry {
37771
37798
  * that the executed command happened.
37772
37799
  */
37773
37800
  getTransformation(toTransform, executed) {
37774
- return this.content[toTransform] && this.content[toTransform].get(executed);
37801
+ return this.content[executed] && this.content[executed].get(toTransform);
37775
37802
  }
37776
37803
  }
37777
37804
  const otRegistry = new OTRegistry();
@@ -64765,10 +64792,20 @@ function transform(toTransform, executed) {
64765
64792
  */
64766
64793
  function transformAll(toTransform, executed) {
64767
64794
  let transformedCommands = [...toTransform];
64795
+ const possibleTransformations = new Set(otRegistry.getKeys());
64768
64796
  for (const executedCommand of executed) {
64769
- transformedCommands = transformedCommands
64770
- .map((cmd) => transform(cmd, executedCommand))
64771
- .filter(isDefined);
64797
+ // If the executed command is not in the registry, we skip it
64798
+ // because we know there won't be any transformation impacting the
64799
+ // commands to transform.
64800
+ if (possibleTransformations.has(executedCommand.type)) {
64801
+ transformedCommands = transformedCommands.reduce((acc, cmd) => {
64802
+ const transformed = transform(cmd, executedCommand);
64803
+ if (transformed) {
64804
+ acc.push(transformed);
64805
+ }
64806
+ return acc;
64807
+ }, []);
64808
+ }
64772
64809
  }
64773
64810
  return transformedCommands;
64774
64811
  }
@@ -66457,7 +66494,7 @@ class SheetUIPlugin extends UIPlugin {
66457
66494
  }
66458
66495
  const position = this.getters.getCellPosition(cell.id);
66459
66496
  const colSize = this.getters.getColSize(sheetId, position.col);
66460
- if (cell.isFormula) {
66497
+ if (cell.isFormula || this.getters.getArrayFormulaSpreadingOn(position)) {
66461
66498
  const content = this.getters.getEvaluatedCell(position).formattedValue;
66462
66499
  const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
66463
66500
  if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) {
@@ -76968,6 +77005,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
76968
77005
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
76969
77006
 
76970
77007
 
76971
- __info__.version = "18.2.17";
76972
- __info__.date = "2025-06-12T09:52:15.050Z";
76973
- __info__.hash = "ea64209";
77008
+ __info__.version = "18.2.18";
77009
+ __info__.date = "2025-06-19T18:24:41.051Z";
77010
+ __info__.hash = "024c134";
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.2.17
6
- * @date 2025-06-12T09:52:15.050Z
7
- * @hash ea64209
5
+ * @version 18.2.18
6
+ * @date 2025-06-19T18:24:41.051Z
7
+ * @hash 024c134
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -10367,6 +10367,7 @@ stores.inject(MyMetaStore, storeInstance);
10367
10367
  if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden) {
10368
10368
  continue;
10369
10369
  }
10370
+ const yAxisScale = chart.scales[dataset.yAxisID];
10370
10371
  for (let i = 0; i < dataset._parsed.length; i++) {
10371
10372
  const parsedValue = dataset._parsed[i];
10372
10373
  const value = Number(chart.config.type === "radar" ? parsedValue.r : parsedValue.y);
@@ -10377,10 +10378,18 @@ stores.inject(MyMetaStore, storeInstance);
10377
10378
  const xPosition = point.x;
10378
10379
  let yPosition = 0;
10379
10380
  if (chart.config.type === "line" || chart.config.type === "radar") {
10380
- yPosition = point.y - 10;
10381
+ yPosition = value < 0 ? point.y + 10 : point.y - 10;
10381
10382
  }
10382
10383
  else {
10383
- yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
10384
+ const yZeroLine = yAxisScale.getPixelForValue(0);
10385
+ const distanceFromAxisOrigin = Math.abs(yZeroLine - point.y);
10386
+ const textHeight = 12; // ChartJS default text height
10387
+ if (distanceFromAxisOrigin < textHeight) {
10388
+ yPosition = value < 0 ? yZeroLine + textHeight / 2 : yZeroLine - textHeight / 2;
10389
+ }
10390
+ else {
10391
+ yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
10392
+ }
10384
10393
  }
10385
10394
  yPosition = Math.min(yPosition, yMax);
10386
10395
  yPosition = Math.max(yPosition, yMin);
@@ -10390,7 +10399,7 @@ stores.inject(MyMetaStore, storeInstance);
10390
10399
  }
10391
10400
  for (const otherPosition of textsPositions[xPosition] || []) {
10392
10401
  if (Math.abs(otherPosition - yPosition) < 13) {
10393
- yPosition = otherPosition - 13;
10402
+ yPosition = value < 0 ? otherPosition + 13 : otherPosition - 13;
10394
10403
  }
10395
10404
  }
10396
10405
  textsPositions[xPosition].push(yPosition);
@@ -10409,6 +10418,8 @@ stores.inject(MyMetaStore, storeInstance);
10409
10418
  if (isTrendLineAxis(dataset.xAxisID)) {
10410
10419
  return; // ignore trend lines
10411
10420
  }
10421
+ const xAxisScale = chart.scales[dataset.xAxisID];
10422
+ const xZeroLine = xAxisScale.getPixelForValue(0);
10412
10423
  for (let i = 0; i < dataset._parsed.length; i++) {
10413
10424
  const value = Number(dataset._parsed[i].x);
10414
10425
  if (isNaN(value)) {
@@ -10417,17 +10428,27 @@ stores.inject(MyMetaStore, storeInstance);
10417
10428
  const displayValue = options.callback(value, dataset, i);
10418
10429
  const point = dataset.data[i];
10419
10430
  const yPosition = point.y;
10420
- let xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
10421
- xPosition = Math.min(xPosition, xMax);
10422
- xPosition = Math.max(xPosition, xMin);
10431
+ const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
10432
+ const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
10433
+ const PADDING = 3;
10434
+ let xPosition;
10435
+ if (distanceFromAxisOrigin < textWidth) {
10436
+ xPosition =
10437
+ value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
10438
+ }
10439
+ else {
10440
+ xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
10441
+ xPosition = Math.min(xPosition, xMax);
10442
+ xPosition = Math.max(xPosition, xMin);
10443
+ }
10423
10444
  // Avoid overlapping texts with same Y
10424
10445
  if (!textsPositions[yPosition]) {
10425
10446
  textsPositions[yPosition] = [];
10426
10447
  }
10427
- const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
10428
10448
  for (const otherPosition of textsPositions[yPosition]) {
10429
10449
  if (Math.abs(otherPosition - xPosition) < textWidth) {
10430
- xPosition = otherPosition + textWidth + 3;
10450
+ xPosition =
10451
+ value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
10431
10452
  }
10432
10453
  }
10433
10454
  textsPositions[yPosition].push(xPosition);
@@ -30111,7 +30132,9 @@ stores.inject(MyMetaStore, storeInstance);
30111
30132
  background: definition.background,
30112
30133
  callback: (value, dataset) => {
30113
30134
  value = Math.abs(Number(value));
30114
- return formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
30135
+ return value === 0
30136
+ ? ""
30137
+ : formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
30115
30138
  },
30116
30139
  };
30117
30140
  }
@@ -34780,6 +34803,10 @@ stores.inject(MyMetaStore, storeInstance);
34780
34803
  });
34781
34804
  };
34782
34805
  const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
34806
+ if ((dimension === "COL" && env.model.getters.getActiveRows().size > 0) ||
34807
+ (dimension === "ROW" && env.model.getters.getActiveCols().size > 0)) {
34808
+ return false;
34809
+ }
34783
34810
  const sheetId = env.model.getters.getActiveSheetId();
34784
34811
  const selectedElements = env.model.getters.getElementsFromSelection(dimension);
34785
34812
  const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
@@ -37759,11 +37786,11 @@ stores.inject(MyMetaStore, storeInstance);
37759
37786
  * transformation function given
37760
37787
  */
37761
37788
  addTransformation(executed, toTransforms, fn) {
37762
- for (let toTransform of toTransforms) {
37763
- if (!this.content[toTransform]) {
37764
- this.content[toTransform] = new Map();
37765
- }
37766
- this.content[toTransform].set(executed, fn);
37789
+ if (!this.content[executed]) {
37790
+ this.content[executed] = new Map();
37791
+ }
37792
+ for (const toTransform of toTransforms) {
37793
+ this.content[executed].set(toTransform, fn);
37767
37794
  }
37768
37795
  return this;
37769
37796
  }
@@ -37772,7 +37799,7 @@ stores.inject(MyMetaStore, storeInstance);
37772
37799
  * that the executed command happened.
37773
37800
  */
37774
37801
  getTransformation(toTransform, executed) {
37775
- return this.content[toTransform] && this.content[toTransform].get(executed);
37802
+ return this.content[executed] && this.content[executed].get(toTransform);
37776
37803
  }
37777
37804
  }
37778
37805
  const otRegistry = new OTRegistry();
@@ -64766,10 +64793,20 @@ stores.inject(MyMetaStore, storeInstance);
64766
64793
  */
64767
64794
  function transformAll(toTransform, executed) {
64768
64795
  let transformedCommands = [...toTransform];
64796
+ const possibleTransformations = new Set(otRegistry.getKeys());
64769
64797
  for (const executedCommand of executed) {
64770
- transformedCommands = transformedCommands
64771
- .map((cmd) => transform(cmd, executedCommand))
64772
- .filter(isDefined);
64798
+ // If the executed command is not in the registry, we skip it
64799
+ // because we know there won't be any transformation impacting the
64800
+ // commands to transform.
64801
+ if (possibleTransformations.has(executedCommand.type)) {
64802
+ transformedCommands = transformedCommands.reduce((acc, cmd) => {
64803
+ const transformed = transform(cmd, executedCommand);
64804
+ if (transformed) {
64805
+ acc.push(transformed);
64806
+ }
64807
+ return acc;
64808
+ }, []);
64809
+ }
64773
64810
  }
64774
64811
  return transformedCommands;
64775
64812
  }
@@ -66458,7 +66495,7 @@ stores.inject(MyMetaStore, storeInstance);
66458
66495
  }
66459
66496
  const position = this.getters.getCellPosition(cell.id);
66460
66497
  const colSize = this.getters.getColSize(sheetId, position.col);
66461
- if (cell.isFormula) {
66498
+ if (cell.isFormula || this.getters.getArrayFormulaSpreadingOn(position)) {
66462
66499
  const content = this.getters.getEvaluatedCell(position).formattedValue;
66463
66500
  const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
66464
66501
  if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) {
@@ -77014,9 +77051,9 @@ stores.inject(MyMetaStore, storeInstance);
77014
77051
  exports.tokenize = tokenize;
77015
77052
 
77016
77053
 
77017
- __info__.version = "18.2.17";
77018
- __info__.date = "2025-06-12T09:52:15.050Z";
77019
- __info__.hash = "ea64209";
77054
+ __info__.version = "18.2.18";
77055
+ __info__.date = "2025-06-19T18:24:41.051Z";
77056
+ __info__.hash = "024c134";
77020
77057
 
77021
77058
 
77022
77059
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);