@odoo/o-spreadsheet 19.5.0-alpha.2 → 19.5.0-alpha.3

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 19.5.0-alpha.2
6
- * @date 2026-07-13T06:26:20.354Z
7
- * @hash a4d2f90
5
+ * @version 19.5.0-alpha.3
6
+ * @date 2026-07-14T10:17:06.949Z
7
+ * @hash c029184
8
8
  */
9
9
 
10
10
  (function(exports, _odoo_owl) {
@@ -1249,6 +1249,12 @@ _odoo_owl = __toESM(_odoo_owl, 1);
1249
1249
  }
1250
1250
  };
1251
1251
  }
1252
+ function repeat(array, times) {
1253
+ const len = array.length;
1254
+ const result = new Array(len * times);
1255
+ for (let t = 0; t < times; t++) for (let i = 0; i < len; i++) result[t * len + i] = array[i];
1256
+ return result;
1257
+ }
1252
1258
 
1253
1259
  //#endregion
1254
1260
  //#region src/helpers/coordinates.ts
@@ -10134,6 +10140,7 @@ set(value) {
10134
10140
  //#endregion
10135
10141
  //#region src/components/figures/chart/chartJs/chartjs_show_values_plugin.ts
10136
10142
  const MINIMAL_VERTICAL_DISTANCE = 13;
10143
+ const HORIZONTAL_PADDING = 3;
10137
10144
  function isLineOverlayOnBarChart(options, dataset) {
10138
10145
  return options.type === "bar" && dataset.type === "line";
10139
10146
  }
@@ -10143,175 +10150,276 @@ set(value) {
10143
10150
  afterDatasetsDraw(chart, args, options) {
10144
10151
  if (!options.showValues) return;
10145
10152
  if (!chart._metasets?.[0]?.data) return;
10146
- const ctx = chart.ctx;
10147
- ctx.save();
10148
- ctx.textAlign = "center";
10149
- ctx.textBaseline = "middle";
10150
- ctx.miterLimit = 1;
10151
10153
  switch (options.type) {
10152
10154
  case "pie":
10153
- drawPieChartValues(chart, options, ctx);
10155
+ drawPieValues(chart, options);
10154
10156
  break;
10155
10157
  case "line":
10156
10158
  case "scatter":
10159
+ drawLineValues(chart, options);
10160
+ break;
10157
10161
  case "combo":
10158
10162
  case "waterfall":
10163
+ drawComboValues(chart, options);
10164
+ break;
10159
10165
  case "radar":
10160
- drawLineOrBarOrRadarChartValues(chart, options, ctx);
10166
+ drawRadarValues(chart, options);
10161
10167
  break;
10162
10168
  case "bar":
10163
- options.horizontal ? drawHorizontalBarChartValues(chart, options, ctx) : drawLineOrBarOrRadarChartValues(chart, options, ctx);
10169
+ options.horizontal ? drawHorizontalBarValues(chart, options) : drawVerticalBarValues(chart, options);
10164
10170
  break;
10165
10171
  case "pyramid":
10166
- drawHorizontalBarChartValues(chart, options, ctx);
10172
+ drawHorizontalBarValues(chart, options);
10167
10173
  break;
10168
10174
  case "calendar":
10169
- drawBarChartValues(chart, options, ctx);
10175
+ drawCalendarValues(chart, options);
10170
10176
  break;
10171
10177
  case "bubble":
10172
- drawBubbleChartValues(chart, options, ctx);
10178
+ drawBubbleValues(chart, options);
10173
10179
  break;
10174
10180
  case "funnel":
10175
- drawHorizontalBarChartValues(chart, options, ctx);
10181
+ drawFunnelValues(chart, options);
10176
10182
  break;
10177
10183
  }
10178
- ctx.restore();
10179
10184
  }
10180
10185
  };
10181
- function drawTextWithBackground(text, x, y, ctx) {
10182
- ctx.lineWidth = 3;
10183
- ctx.strokeText(text, x, y);
10184
- ctx.lineWidth = 1;
10185
- ctx.fillText(text, x, y);
10186
- }
10187
- function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
10186
+ function drawValues(args) {
10187
+ const { chart, options, getNumberValue, direction } = args;
10188
+ const ctx = chart.ctx;
10189
+ ctx.save();
10190
+ ctx.textAlign = "center";
10191
+ ctx.textBaseline = "middle";
10192
+ ctx.miterLimit = 1;
10188
10193
  const textsPositions = {};
10189
10194
  for (const dataset of chart._metasets) {
10190
- if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden || isLineOverlayOnBarChart(options, dataset)) continue;
10191
- const yAxisScale = chart.scales[dataset.yAxisID];
10195
+ if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden) continue;
10192
10196
  for (let i = 0; i < dataset._parsed.length; i++) {
10193
- const parsedValue = dataset._parsed[i];
10194
- const value = Number(chart.config.type === "radar" ? parsedValue.r : parsedValue.y);
10195
- if (isNaN(value)) continue;
10196
- const point = dataset.data[i];
10197
- const xPosition = point.x;
10198
- let yPosition = 0;
10199
- if (chart.config.type === "line" || chart.config.type === "radar") yPosition = value < 0 ? point.y + 10 : point.y - 10;
10200
- else if (chart.config.type === "bubble") yPosition = point.y;
10201
- else {
10202
- const yZeroLine = yAxisScale.getPixelForValue(0);
10203
- const distanceFromAxisOrigin = Math.abs(yZeroLine - point.y);
10204
- const textHeight = globalThis.Chart?.defaults.font.size ?? 12;
10205
- if (distanceFromAxisOrigin < textHeight) yPosition = value < 0 ? yZeroLine + textHeight / 2 : yZeroLine - textHeight / 2;
10206
- else yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
10207
- }
10208
- if (!textsPositions[xPosition]) textsPositions[xPosition] = [];
10209
- for (const otherPosition of textsPositions[xPosition] || []) if (Math.abs(otherPosition - yPosition) < MINIMAL_VERTICAL_DISTANCE) yPosition = otherPosition + MINIMAL_VERTICAL_DISTANCE * (value < 0 ? 1 : -1);
10210
- textsPositions[xPosition].push(yPosition);
10211
- ctx.fillStyle = point.options.backgroundColor;
10212
- ctx.strokeStyle = options.background(Number(value), dataset, i) || "#ffffff";
10213
- drawTextWithBackground(options.callback(Number(value), dataset, i), xPosition, yPosition, ctx);
10197
+ const numberValue = getNumberValue(dataset, i);
10198
+ if (numberValue === void 0 || isNaN(numberValue)) continue;
10199
+ const chartElement = dataset.data[i];
10200
+ const elementColor = chartElement.options.backgroundColor;
10201
+ if (!elementColor || colorToRGBA(elementColor).a !== 1) continue;
10202
+ const valueToDisplay = options.callback(numberValue, dataset, i);
10203
+ const textSize = getTextDimensions(valueToDisplay, ctx);
10204
+ const callbackArgs = {
10205
+ dataset,
10206
+ chartElement,
10207
+ numberValue,
10208
+ valueIndex: i,
10209
+ textSize,
10210
+ options,
10211
+ chart
10212
+ };
10213
+ const position = args.getValuePosition(callbackArgs);
10214
+ if (args.shouldSkipValue?.(callbackArgs)) continue;
10215
+ if (direction === "vertical") {
10216
+ const key = Math.round(position.x);
10217
+ if (!textsPositions[key]) textsPositions[key] = [];
10218
+ for (const otherPosition of textsPositions[key] || []) if (Math.abs(otherPosition - position.y) < MINIMAL_VERTICAL_DISTANCE) position.y = otherPosition + MINIMAL_VERTICAL_DISTANCE * (numberValue < 0 ? 1 : -1);
10219
+ textsPositions[key].push(position.y);
10220
+ } else {
10221
+ const key = Math.round(position.y);
10222
+ if (!textsPositions[key]) textsPositions[key] = [];
10223
+ for (const otherPosition of textsPositions[key]) if (Math.abs(otherPosition - position.x) < textSize.width) position.x = numberValue < 0 ? otherPosition - textSize.width - HORIZONTAL_PADDING : otherPosition + textSize.width + HORIZONTAL_PADDING;
10224
+ textsPositions[key].push(position.x);
10225
+ }
10226
+ const { strokeColor, textColor } = args.getTextColors(callbackArgs);
10227
+ if (!!strokeColor) {
10228
+ ctx.strokeStyle = strokeColor;
10229
+ ctx.lineWidth = 3;
10230
+ ctx.strokeText(valueToDisplay, position.x, position.y);
10231
+ }
10232
+ ctx.fillStyle = textColor;
10233
+ ctx.lineWidth = 1;
10234
+ ctx.fillText(valueToDisplay, position.x, position.y);
10214
10235
  }
10215
10236
  }
10237
+ ctx.restore();
10216
10238
  }
10217
- function drawBarChartValues(chart, options, ctx) {
10218
- const yMax = chart.chartArea.bottom;
10219
- const yMin = chart.chartArea.top;
10220
- for (const dataset of chart._metasets) {
10221
- if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden) continue;
10222
- const yAxisScale = chart.scales[dataset.yAxisID];
10223
- for (let i = 0; i < dataset._parsed.length; i++) {
10224
- const parsedValue = dataset._parsed[i];
10225
- const value = Number(chart.config.type === "radar" ? parsedValue.r : parsedValue.y);
10226
- if (isNaN(value)) continue;
10227
- const point = dataset.data[i];
10228
- const xPosition = point.x;
10229
- let yPosition = 0;
10230
- const yZeroLine = yAxisScale.getPixelForValue(0);
10231
- const distanceFromAxisOrigin = Math.abs(yZeroLine - point.y);
10232
- const textHeight = globalThis.Chart?.defaults.font.size ?? 12;
10233
- if (distanceFromAxisOrigin < textHeight) yPosition = value < 0 ? yZeroLine + textHeight / 2 : yZeroLine - textHeight / 2;
10234
- else yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
10235
- yPosition = Math.min(yPosition, yMax);
10236
- yPosition = Math.max(yPosition, yMin);
10237
- ctx.strokeStyle = point.options.backgroundColor;
10238
- ctx.fillStyle = options.background(Number(value), dataset, i) || "#ffffff";
10239
- const valueToDisplay = options.callback(Number(value), dataset, i);
10240
- const measures = ctx.measureText(valueToDisplay);
10241
- if (measures.actualBoundingBoxAscent + measures.actualBoundingBoxDescent + 2 > Math.abs(point.height) - 2) continue;
10242
- drawTextWithBackground(valueToDisplay, xPosition, yPosition, ctx);
10243
- }
10244
- }
10245
- }
10246
- function drawBubbleChartValues(chart, options, ctx) {
10247
- const yMax = chart.chartArea.bottom;
10248
- const yMin = chart.chartArea.top;
10249
- const textsPositions = {};
10250
- for (const dataset of chart._metasets) for (let i = 0; i < dataset._parsed.length; i++) {
10251
- const value = dataset._parsed[i].y;
10252
- if (isNaN(value)) continue;
10253
- const point = dataset.data[i];
10254
- const xPosition = point.x;
10255
- let yPosition = Math.max(Math.min(point.y, yMax), yMin);
10256
- if (!textsPositions[xPosition]) textsPositions[xPosition] = [];
10257
- for (const otherPosition of textsPositions[xPosition] || []) if (Math.abs(otherPosition - yPosition) < MINIMAL_VERTICAL_DISTANCE) yPosition = otherPosition + MINIMAL_VERTICAL_DISTANCE * (value < 0 ? 1 : -1);
10258
- textsPositions[xPosition].push(yPosition);
10259
- const color = point.options.backgroundColor ?? "#ffffff";
10260
- if (hexToHSLA(toHex(color)).a === 1) ctx.fillStyle = chartFontColor(color);
10261
- else ctx.fillStyle = "#000000";
10262
- const valueToDisplay = options.callback(Number(value), dataset, i);
10263
- ctx.fillText(valueToDisplay, xPosition, yPosition);
10264
- }
10265
- }
10266
- function drawHorizontalBarChartValues(chart, options, ctx) {
10267
- const textsPositions = {};
10268
- for (const dataset of chart._metasets) {
10269
- if (isTrendLineAxis(dataset.xAxisID) || isLineOverlayOnBarChart(options, dataset)) continue;
10270
- const xZeroLine = chart.scales[dataset.xAxisID].getPixelForValue(0);
10271
- for (let i = 0; i < dataset._parsed.length; i++) {
10272
- const value = Number(dataset._parsed[i].x);
10273
- if (isNaN(value)) continue;
10274
- const displayValue = options.callback(value, dataset, i);
10275
- const point = dataset.data[i];
10276
- const yPosition = point.y;
10277
- const textWidth = computeTextWidth(ctx, displayValue, { fontSize: globalThis.Chart?.defaults.font.size ?? 12 }, "px");
10278
- const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
10279
- const PADDING = 3;
10239
+ function drawVerticalBarValues(chart, options) {
10240
+ drawValues({
10241
+ chart,
10242
+ options,
10243
+ direction: "vertical",
10244
+ getNumberValue: (dataset, i) => Number(dataset._parsed[i].y),
10245
+ getValuePosition: getVerticalBarValuePosition,
10246
+ shouldSkipValue: ({ dataset }) => isLineOverlayOnBarChart(options, dataset),
10247
+ getTextColors: chartBackgroundColoredTextWithElementColoredHalo
10248
+ });
10249
+ }
10250
+ function drawRadarValues(chart, options) {
10251
+ drawValues({
10252
+ chart,
10253
+ options,
10254
+ direction: "vertical",
10255
+ getNumberValue: (dataset, i) => Number(dataset._parsed[i].r),
10256
+ getValuePosition: ({ chartElement }) => ({
10257
+ x: chartElement.x,
10258
+ y: chartElement.y - 10
10259
+ }),
10260
+ shouldSkipValue: () => false,
10261
+ getTextColors: chartElementColoredTextWithChartBackgroundHalo
10262
+ });
10263
+ }
10264
+ function drawLineValues(chart, options) {
10265
+ drawValues({
10266
+ chart,
10267
+ options,
10268
+ direction: "vertical",
10269
+ getNumberValue: (dataset, i) => Number(dataset._parsed[i].y),
10270
+ getValuePosition: ({ chartElement }) => ({
10271
+ x: chartElement.x,
10272
+ y: chartElement.y - 10
10273
+ }),
10274
+ shouldSkipValue: () => false,
10275
+ getTextColors: chartElementColoredTextWithChartBackgroundHalo
10276
+ });
10277
+ }
10278
+ function drawComboValues(chart, options) {
10279
+ drawValues({
10280
+ chart,
10281
+ options,
10282
+ direction: "vertical",
10283
+ getNumberValue: (dataset, i) => Number(dataset._parsed[i].y),
10284
+ getValuePosition: (args) => args.dataset.type === "line" ? {
10285
+ x: args.chartElement.x,
10286
+ y: args.chartElement.y - 10
10287
+ } : getVerticalBarValuePosition(args),
10288
+ shouldSkipValue: () => false,
10289
+ getTextColors: (args) => args.dataset.type === "line" ? chartElementColoredTextWithChartBackgroundHalo(args) : chartBackgroundColoredTextWithElementColoredHalo(args)
10290
+ });
10291
+ }
10292
+ function drawCalendarValues(chart, options) {
10293
+ drawValues({
10294
+ chart,
10295
+ options,
10296
+ direction: "vertical",
10297
+ getNumberValue: (dataset, i) => dataset._parsed[i].y,
10298
+ getValuePosition: ({ chartElement }) => ({
10299
+ x: chartElement.x,
10300
+ y: chartElement.y + chartElement.height / 2
10301
+ }),
10302
+ shouldSkipValue: ({ chartElement, textSize }) => textSize.height + 2 > Math.abs(chartElement.height) - 2,
10303
+ getTextColors: ({ chartElement }) => ({
10304
+ strokeColor: void 0,
10305
+ textColor: chartFontColor(chartElement.options.backgroundColor)
10306
+ })
10307
+ });
10308
+ }
10309
+ function drawBubbleValues(chart, options) {
10310
+ const canDrawTextInsideBubble = (chartElement, textSize) => {
10311
+ const radius = chartElement.options.radius ?? globalThis.Chart?.defaults.elements.point.radius ?? 3;
10312
+ return textSize.height < radius * 2;
10313
+ };
10314
+ drawValues({
10315
+ chart,
10316
+ options,
10317
+ direction: "vertical",
10318
+ getNumberValue: (dataset, i) => dataset._parsed[i].y,
10319
+ getValuePosition: ({ chartElement, textSize }) => ({
10320
+ x: chartElement.x,
10321
+ y: canDrawTextInsideBubble(chartElement, textSize) ? chartElement.y : chartElement.y - 10
10322
+ }),
10323
+ shouldSkipValue: () => false,
10324
+ getTextColors: (args) => {
10325
+ return canDrawTextInsideBubble(args.chartElement, args.textSize) ? chartBackgroundColoredTextWithElementColoredHalo(args) : chartElementColoredTextWithChartBackgroundHalo(args);
10326
+ }
10327
+ });
10328
+ }
10329
+ function drawHorizontalBarValues(chart, options) {
10330
+ drawValues({
10331
+ chart,
10332
+ options,
10333
+ direction: "horizontal",
10334
+ getNumberValue: (dataset, i) => dataset._parsed[i].x,
10335
+ getValuePosition: ({ chartElement, numberValue, textSize, dataset }) => {
10336
+ const xZeroLine = chart.scales[dataset.xAxisID].getPixelForValue(0);
10337
+ const distanceFromAxisOrigin = Math.abs(chartElement.x - xZeroLine);
10280
10338
  let xPosition;
10281
- if (distanceFromAxisOrigin < textWidth) xPosition = value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
10282
- else xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
10283
- if (!textsPositions[yPosition]) textsPositions[yPosition] = [];
10284
- for (const otherPosition of textsPositions[yPosition]) if (Math.abs(otherPosition - xPosition) < textWidth) xPosition = value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
10285
- textsPositions[yPosition].push(xPosition);
10286
- ctx.strokeStyle = point.options.backgroundColor;
10287
- ctx.fillStyle = options.background(Number(value), dataset, i) || "#ffffff";
10288
- drawTextWithBackground(displayValue, xPosition, yPosition, ctx);
10289
- }
10290
- }
10291
- }
10292
- function drawPieChartValues(chart, options, ctx) {
10293
- for (const dataset of chart._metasets) for (let i = 0; i < dataset._parsed.length; i++) {
10294
- const value = Number(dataset._parsed[i]);
10295
- if (isNaN(value) || value === 0) continue;
10296
- const bar = dataset.data[i];
10297
- const { startAngle, endAngle, innerRadius, outerRadius } = bar;
10298
- const midAngle = (startAngle + endAngle) / 2;
10299
- const midRadius = (innerRadius + outerRadius) / 2;
10300
- const x = bar.x + midRadius * Math.cos(midAngle);
10301
- const y = bar.y + midRadius * Math.sin(midAngle);
10302
- const displayValue = options.callback(value, dataset, i);
10303
- const textHeight = globalThis.Chart?.defaults.font.size ?? 12;
10304
- const textWidth = computeTextWidth(ctx, displayValue, { fontSize: textHeight }, "px");
10305
- const radius = outerRadius - innerRadius;
10306
- if (textWidth >= radius || radius < textHeight) continue;
10307
- const sliceAngle = endAngle - startAngle;
10308
- const midWidth = 2 * midRadius * Math.tan(sliceAngle / 2);
10309
- if (sliceAngle < Math.PI / 2 && (textWidth >= midWidth || midWidth < textHeight)) continue;
10310
- const background = options.background(Number(value), dataset, i);
10311
- ctx.fillStyle = chartFontColor(background);
10312
- ctx.strokeStyle = background || "#ffffff";
10313
- drawTextWithBackground(displayValue, x, y, ctx);
10314
- }
10339
+ const sign = numberValue < 0 ? -1 : 1;
10340
+ if (distanceFromAxisOrigin < textSize.width) xPosition = xZeroLine + sign * (textSize.width / 2 + HORIZONTAL_PADDING);
10341
+ else xPosition = chartElement.x - sign * (chartElement.width / 2);
10342
+ return {
10343
+ x: xPosition,
10344
+ y: chartElement.y
10345
+ };
10346
+ },
10347
+ shouldSkipValue: ({ dataset }) => isLineOverlayOnBarChart(options, dataset),
10348
+ getTextColors: chartBackgroundColoredTextWithElementColoredHalo
10349
+ });
10350
+ }
10351
+ function drawFunnelValues(chart, options) {
10352
+ drawValues({
10353
+ chart,
10354
+ options,
10355
+ direction: "horizontal",
10356
+ getNumberValue: (dataset, i) => dataset._parsed[i].x,
10357
+ getValuePosition: ({ chartElement }) => ({
10358
+ x: chartElement.x - chartElement.width / 2,
10359
+ y: chartElement.y
10360
+ }),
10361
+ shouldSkipValue: () => false,
10362
+ getTextColors: chartBackgroundColoredTextWithElementColoredHalo
10363
+ });
10364
+ }
10365
+ function drawPieValues(chart, options) {
10366
+ const getSliceDimensions = (chartElement) => {
10367
+ const { startAngle, endAngle, innerRadius, outerRadius } = chartElement;
10368
+ return {
10369
+ midAngle: (startAngle + endAngle) / 2,
10370
+ midRadius: (innerRadius + outerRadius) / 2
10371
+ };
10372
+ };
10373
+ drawValues({
10374
+ chart,
10375
+ options,
10376
+ direction: "vertical",
10377
+ getNumberValue: (dataset, i) => Number(dataset._parsed[i]),
10378
+ getValuePosition: ({ chartElement }) => {
10379
+ const { midAngle, midRadius } = getSliceDimensions(chartElement);
10380
+ return {
10381
+ x: chartElement.x + midRadius * Math.cos(midAngle),
10382
+ y: chartElement.y + midRadius * Math.sin(midAngle)
10383
+ };
10384
+ },
10385
+ shouldSkipValue: ({ chartElement, textSize }) => {
10386
+ const { midRadius } = getSliceDimensions(chartElement);
10387
+ const sliceAngle = chartElement.endAngle - chartElement.startAngle;
10388
+ const midWidth = 2 * midRadius * Math.tan(sliceAngle / 2);
10389
+ return sliceAngle < Math.PI / 2 && (textSize.width >= midWidth || midWidth < textSize.height);
10390
+ },
10391
+ getTextColors: chartBackgroundColoredTextWithElementColoredHalo
10392
+ });
10393
+ }
10394
+ function getTextDimensions(text, ctx) {
10395
+ return computeCachedTextDimension(ctx, text, computeTextFont({ fontSize: globalThis.Chart?.defaults.font.size ?? 12 }, "px"));
10396
+ }
10397
+ function chartBackgroundColoredTextWithElementColoredHalo(args) {
10398
+ const { dataset, numberValue, valueIndex, chartElement, options } = args;
10399
+ return {
10400
+ strokeColor: chartElement.options.backgroundColor,
10401
+ textColor: options.background(numberValue, dataset, valueIndex) || "#ffffff"
10402
+ };
10403
+ }
10404
+ function chartElementColoredTextWithChartBackgroundHalo(args) {
10405
+ const { dataset, numberValue, valueIndex, chartElement, options } = args;
10406
+ return {
10407
+ strokeColor: options.background(numberValue, dataset, valueIndex) || "#ffffff",
10408
+ textColor: chartElement.options.backgroundColor
10409
+ };
10410
+ }
10411
+ function getVerticalBarValuePosition(args) {
10412
+ const { chartElement, numberValue, dataset, textSize, chart } = args;
10413
+ const yZeroLine = chart.scales[dataset.yAxisID].getPixelForValue(0);
10414
+ const distanceFromAxisOrigin = Math.abs(yZeroLine - chartElement.y);
10415
+ const sign = numberValue < 0 ? -1 : 1;
10416
+ let yPosition = 0;
10417
+ if (distanceFromAxisOrigin < textSize.height) yPosition = yZeroLine - sign * (textSize.height / 2);
10418
+ else yPosition = chartElement.y + sign * (chartElement.height / 2);
10419
+ return {
10420
+ x: chartElement.x,
10421
+ y: yPosition
10422
+ };
10315
10423
  }
10316
10424
 
10317
10425
  //#endregion
@@ -11168,6 +11276,7 @@ set(value) {
11168
11276
  hidden,
11169
11277
  borderColor,
11170
11278
  backgroundColor: borderColor,
11279
+ pointBackgroundColor: borderColor,
11171
11280
  pointRadius: definition.hideDataMarkers ? 0 : 3
11172
11281
  };
11173
11282
  if (fill) {
@@ -28635,23 +28744,11 @@ set(value) {
28635
28744
  }
28636
28745
  function getCalendarChartShowValues(definition, args) {
28637
28746
  const { locale, axisFormats } = args;
28638
- let background = (_value, dataset, index) => definition.background;
28639
- const values = args.dataSetsValues.flat().flatMap((dsv) => dsv?.data.filter(isNumberResult)).map((cell) => cell.value);
28640
- if (values.length) {
28641
- const min = Math.min(...values);
28642
- const max = Math.max(...values);
28643
- const colorScale = getRuntimeColorScale(definition.colorScale ?? schemeToColorScale("oranges"), min, max);
28644
- background = (_value, dataset, index) => {
28645
- const value = dataset._dataset.values[index];
28646
- if (value === void 0) return definition.background;
28647
- return chartFontColor(colorScale(value));
28648
- };
28649
- }
28650
28747
  return {
28651
28748
  type: "calendar",
28652
28749
  horizontal: false,
28653
28750
  showValues: "showValues" in definition ? !!definition.showValues : false,
28654
- background,
28751
+ background: () => definition.background,
28655
28752
  callback: (_value, dataset, index) => {
28656
28753
  const value = dataset._dataset.values[index];
28657
28754
  return value === void 0 ? "" : humanizeNumber({
@@ -53082,11 +53179,16 @@ set(value) {
53082
53179
  const deltaStyle = {};
53083
53180
  let hasDelta = false;
53084
53181
  const styleSheet = this.style[position.sheetId];
53085
- if (!styleSheet) continue;
53086
53182
  for (const key in newDefaultStyle) {
53087
53183
  if (key in cellStyle) continue;
53088
- const defaults = styleSheet[key];
53089
- if (!defaults) continue;
53184
+ const defaults = styleSheet?.[key];
53185
+ if (!defaults) {
53186
+ if (newDefaultStyle[key] !== DEFAULT_STYLE[key]) {
53187
+ deltaStyle[key] = DEFAULT_STYLE[key];
53188
+ hasDelta = true;
53189
+ }
53190
+ continue;
53191
+ }
53090
53192
  const rowDefault = defaults.rowDefault?.[position.row];
53091
53193
  if (rowDefault !== void 0) {
53092
53194
  if (priorities.shouldUseDefaultRow) {
@@ -53128,7 +53230,8 @@ set(value) {
53128
53230
  for (const key in styleSheet) if (!(key in style)) {
53129
53231
  const defaults = styleSheet[key];
53130
53232
  if (!defaults) continue;
53131
- style[key] = defaults.rowDefault?.[position.row] ?? defaults.colDefault?.[position.col] ?? defaults.sheetDefault;
53233
+ const styleValue = defaults.rowDefault?.[position.row] ?? defaults.colDefault?.[position.col] ?? defaults.sheetDefault;
53234
+ if (styleValue !== void 0) style[key] = styleValue;
53132
53235
  }
53133
53236
  return style;
53134
53237
  }
@@ -77063,8 +77166,8 @@ set(value) {
77063
77166
  for (const key in DEFAULT_STYLE) {
77064
77167
  content.style[key] = {
77065
77168
  sheetDefault: this.getters.getDefaultStyle(data.sheetId, key, "SHEET", void 0) ?? DEFAULT_STYLE[key],
77066
- colDefault: {},
77067
- rowDefault: {}
77169
+ colDefault: [],
77170
+ rowDefault: []
77068
77171
  };
77069
77172
  let colIndex = 0;
77070
77173
  for (const col of data.columnsIndexes) {
@@ -77081,20 +77184,41 @@ set(value) {
77081
77184
  }
77082
77185
  return content;
77083
77186
  }
77084
- clearStyleFormat(sheetId, zone) {
77085
- this.dispatch("SET_FORMATTING", {
77086
- sheetId,
77087
- target: [zone],
77088
- format: ""
77089
- });
77187
+ adaptContentToZone(zone, content) {
77188
+ const colRepetition = Math.max(Math.floor((zone.right - zone.left + 1) / content.width), 1);
77189
+ const rowRepetition = Math.max(Math.floor((zone.bottom - zone.top + 1) / content.height), 1);
77190
+ if (colRepetition === 1 && rowRepetition === 1) return content;
77191
+ const newContent = deepCopy(content);
77192
+ newContent.height *= rowRepetition;
77193
+ newContent.width *= colRepetition;
77194
+ if (rowRepetition > 1 && newContent.format.rowDefault) {
77195
+ newContent.format.rowDefault.length = content.height;
77196
+ newContent.format.rowDefault = repeat(newContent.format.rowDefault, rowRepetition);
77197
+ }
77198
+ if (colRepetition > 1 && newContent.format.colDefault) {
77199
+ newContent.format.colDefault.length = content.width;
77200
+ newContent.format.colDefault = repeat(newContent.format.colDefault, colRepetition);
77201
+ }
77202
+ for (const key in content.style) {
77203
+ if (rowRepetition > 1 && newContent.style[key].rowDefault) {
77204
+ newContent.style[key].rowDefault.length = content.height;
77205
+ newContent.style[key].rowDefault = repeat(newContent.style[key].rowDefault, rowRepetition);
77206
+ }
77207
+ if (colRepetition > 1 && newContent.style[key].colDefault) {
77208
+ newContent.style[key].colDefault.length = content.width;
77209
+ newContent.style[key].colDefault = repeat(newContent.style[key].colDefault, colRepetition);
77210
+ }
77211
+ }
77212
+ return newContent;
77090
77213
  }
77091
77214
  paste(target, content, options) {
77092
77215
  const sheetId = target.sheetId;
77093
77216
  if (options.pasteOption === "asValue") return;
77094
77217
  const zones = target.zones;
77095
- if (!options.isCutOperation) for (const zone of zones) for (const pasteZone of splitZoneForPaste(zone, content.width, content.height)) {
77096
- this.pasteStyle(sheetId, pasteZone.left, pasteZone.top, content.width, content.height, content.style);
77097
- this.pasteFormat(sheetId, pasteZone.left, pasteZone.top, content.width, content.height, content.format);
77218
+ if (!options.isCutOperation) for (const zone of zones) {
77219
+ const newContent = this.adaptContentToZone(zone, content);
77220
+ this.pasteStyle(sheetId, zone.left, zone.top, newContent.width, newContent.height, newContent.style);
77221
+ this.pasteFormat(sheetId, zone.left, zone.top, newContent.width, newContent.height, newContent.format);
77098
77222
  }
77099
77223
  else {
77100
77224
  this.clearClippedZones(content);
@@ -77207,7 +77331,7 @@ set(value) {
77207
77331
  const commands = [];
77208
77332
  for (const [zoneStr, [zone, priority]] of Object.entries(zones)) {
77209
77333
  const format = updateCells[zoneStr];
77210
- commands.push([
77334
+ if (format !== void 0) commands.push([
77211
77335
  priority,
77212
77336
  zone,
77213
77337
  format
@@ -87636,8 +87760,8 @@ exports.stores = stores;
87636
87760
  exports.tokenColors = tokenColors;
87637
87761
  exports.tokenize = tokenize;
87638
87762
 
87639
- __info__.version = "19.5.0-alpha.2";
87640
- __info__.date = "2026-07-13T06:26:20.354Z";
87641
- __info__.hash = "a4d2f90";
87763
+ __info__.version = "19.5.0-alpha.3";
87764
+ __info__.date = "2026-07-14T10:17:06.949Z";
87765
+ __info__.hash = "c029184";
87642
87766
 
87643
87767
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);