@odoo/o-spreadsheet 19.4.11 → 19.4.12

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.4.11
6
- * @date 2026-09-04T07:50:39.272Z
7
- * @hash 7660254
5
+ * @version 19.4.12
6
+ * @date 2026-09-10T05:38:01.898Z
7
+ * @hash cdb63b4
8
8
  */
9
9
 
10
10
  (function(exports, _odoo_owl) {
@@ -7854,7 +7854,8 @@ set(value) {
7854
7854
  "UPDATE_TABLE",
7855
7855
  "UPDATE_FILTER",
7856
7856
  "UNDO",
7857
- "REDO"
7857
+ "REDO",
7858
+ "UPDATE_COLOR_SCHEME"
7858
7859
  ]);
7859
7860
  const invalidateDependenciesCommands = /* @__PURE__ */ new Set(["MOVE_RANGES"]);
7860
7861
  const invalidateCFEvaluationCommands = /* @__PURE__ */ new Set([
@@ -10250,7 +10251,7 @@ set(value) {
10250
10251
  const point = dataset.data[i];
10251
10252
  const xPosition = point.x;
10252
10253
  let yPosition = 0;
10253
- if (chart.config.type === "line" || chart.config.type === "radar") yPosition = value < 0 ? point.y + 10 : point.y - 10;
10254
+ if (dataset.type === "line" || dataset.type === "radar") yPosition = value < 0 ? point.y + 10 : point.y - 10;
10254
10255
  else if (chart.config.type === "bubble") yPosition = point.y;
10255
10256
  else {
10256
10257
  const yZeroLine = yAxisScale.getPixelForValue(0);
@@ -15853,7 +15854,7 @@ set(value) {
15853
15854
  ["MoreThanOneRangeSelected"]: _t("Please select only one range of cells"),
15854
15855
  ["EmptySelectedRange"]: _t("Please select a range of cells containing values."),
15855
15856
  ["NoColumnsProvided"]: _t("Please select at latest one column to analyze."),
15856
- ["WillRemoveExistingMerge"]: _t("This operation is not possible due to a merge. Please remove the merges first than try again.")
15857
+ ["WillRemoveExistingMerge"]: _t("Cannot perform this action on merged cells. Unmerge the cells and try again.")
15857
15858
  } };
15858
15859
  const DVTerms = {
15859
15860
  DateIs: {
@@ -30185,433 +30186,6 @@ set(value) {
30185
30186
  }
30186
30187
  };
30187
30188
 
30188
- //#endregion
30189
- //#region src/helpers/figures/chart.ts
30190
- var SpreadsheetChart = class SpreadsheetChart {
30191
- getters;
30192
- sheetId;
30193
- definition;
30194
- chartTypeBuilder;
30195
- dataSourceBuilder;
30196
- dataSource;
30197
- constructor(getters, sheetId, definition, chartTypeBuilder, dataSourceBuilder) {
30198
- this.getters = getters;
30199
- this.sheetId = sheetId;
30200
- this.definition = definition;
30201
- this.chartTypeBuilder = chartTypeBuilder;
30202
- this.dataSourceBuilder = dataSourceBuilder;
30203
- this.dataSource = definition.dataSource;
30204
- }
30205
- static fromStrDefinition(getters, sheetId, definition) {
30206
- const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
30207
- const chartTypeBuilder = chartTypeRegistry.get(definition.type);
30208
- const dataSource = dataSourceBuilder.fromExternalDefinition(definition.dataSource ?? { type: "none" }, sheetId, getters);
30209
- const rangeDefinition = {
30210
- ...chartTypeBuilder.fromStrDefinition(definition, sheetId, getters),
30211
- dataSource
30212
- };
30213
- return new SpreadsheetChart(getters, sheetId, SpreadsheetChart.deleteInvalidKeys(rangeDefinition), chartTypeBuilder, dataSourceBuilder);
30214
- }
30215
- static fromDefinition(getters, sheetId, definition) {
30216
- const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
30217
- return new SpreadsheetChart(getters, sheetId, definition, chartTypeRegistry.get(definition.type), dataSourceBuilder);
30218
- }
30219
- static validate(validator, definition) {
30220
- const chartTypeBuilder = chartTypeRegistry.get(definition.type);
30221
- const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
30222
- return validator.batchValidations(() => chartTypeBuilder.validateDefinition(validator, definition), () => dataSourceBuilder.validate(definition.dataSource ?? { type: "none" }, validator))(void 0);
30223
- }
30224
- static transformDefinition(chartSheetId, definition, rangeAdapters) {
30225
- const chartTypeBuilder = chartTypeRegistry.get(definition.type);
30226
- if (!definition.dataSource) return chartTypeBuilder.transformDefinition(definition, chartSheetId, rangeAdapters);
30227
- const newDataSource = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none").transform(definition.dataSource, chartSheetId, rangeAdapters);
30228
- return {
30229
- ...chartTypeBuilder.transformDefinition(definition, chartSheetId, rangeAdapters),
30230
- dataSource: newDataSource
30231
- };
30232
- }
30233
- getRangeDefinition() {
30234
- return {
30235
- ...this.definition,
30236
- dataSource: this.dataSource
30237
- };
30238
- }
30239
- getDefinition() {
30240
- return {
30241
- ...this.chartTypeBuilder.toStrDefinition(this.definition, this.sheetId, this.getters),
30242
- dataSource: this.dataSource && this.dataSourceBuilder.getDefinition(this.dataSource, this.sheetId, this.getters)
30243
- };
30244
- }
30245
- updateRanges(rangeAdapters) {
30246
- return {
30247
- ...this.chartTypeBuilder.updateRanges(this.definition, rangeAdapters, this.sheetId),
30248
- dataSource: this.dataSource && this.dataSourceBuilder.adaptRanges(this.dataSource, rangeAdapters)
30249
- };
30250
- }
30251
- duplicateInDuplicatedSheet(sheetIdFrom, sheetIdTo) {
30252
- const newDataSource = this.dataSource && this.dataSourceBuilder.duplicateInDuplicatedSheet(this.dataSource, sheetIdFrom, sheetIdTo, this.getters);
30253
- const definition = {
30254
- ...this.chartTypeBuilder.duplicateInDuplicatedSheet(this.definition, sheetIdFrom, sheetIdTo, this.getters),
30255
- dataSource: newDataSource
30256
- };
30257
- return SpreadsheetChart.fromDefinition(this.getters, sheetIdTo, definition).getDefinition();
30258
- }
30259
- copyInSheetId(sheetIdTo) {
30260
- return {
30261
- ...this.chartTypeBuilder.copyInSheetId(this.definition, this.sheetId, sheetIdTo, this.getters),
30262
- dataSource: this.dataSource
30263
- };
30264
- }
30265
- getContextCreation() {
30266
- const definition = this.getDefinition();
30267
- return {
30268
- ...this.dataSourceBuilder.getContextCreation(definition.dataSource ?? { type: "none" }),
30269
- ...this.chartTypeBuilder.getContextCreation(definition, this.dataSourceBuilder, definition.dataSource)
30270
- };
30271
- }
30272
- getDefinitionForExcel(getters) {
30273
- const definition = this.definition;
30274
- const excelDataSets = this.dataSourceBuilder.toExcelDataSets(this.dataSource, "dataSetStyles" in definition ? definition.dataSetStyles : {}, getters);
30275
- if (excelDataSets === void 0) return;
30276
- return this.chartTypeBuilder.getDefinitionForExcel(getters, definition, excelDataSets);
30277
- }
30278
- getData(getters, chartId) {
30279
- const dataSource = this.dataSource;
30280
- return dataSource ? this.dataSourceBuilder.extractData(dataSource, chartId, getters) : {
30281
- dataSetsValues: [],
30282
- labelValues: []
30283
- };
30284
- }
30285
- getRuntime(getters, chartId) {
30286
- const dataSource = this.dataSource;
30287
- const dataExtractors = dataSource ? {
30288
- extractData: () => this.dataSourceBuilder.extractData(dataSource, chartId, getters),
30289
- extractHierarchicalData: () => this.dataSourceBuilder.extractHierarchicalData(dataSource, chartId, getters)
30290
- } : {
30291
- extractData: () => ({
30292
- dataSetsValues: [],
30293
- labelValues: []
30294
- }),
30295
- extractHierarchicalData: () => ({
30296
- dataSetsValues: [],
30297
- labelValues: []
30298
- })
30299
- };
30300
- return this.chartTypeBuilder.getRuntime(getters, this.definition, dataExtractors, this.sheetId, {
30301
- onClick: (event, items, chartJsChart) => {
30302
- return this.dataSourceBuilder.onDataSetClick?.(this.definition.type, chartId, event, items, chartJsChart, getters);
30303
- },
30304
- onHover: (event, items, chartJsChart) => this.dataSourceBuilder.onDataSetHover?.(this.definition.type, chartId, event, items, chartJsChart)
30305
- });
30306
- }
30307
- static deleteInvalidKeys(definition) {
30308
- definition = { ...definition };
30309
- const keys = new Set(chartTypeRegistry.get(definition.type).allowedDefinitionKeys);
30310
- for (const key of Object.keys(definition)) if (!keys.has(key)) delete definition[key];
30311
- return definition;
30312
- }
30313
- };
30314
-
30315
- //#endregion
30316
- //#region src/helpers/figures/charts/chart_data_sources.ts
30317
- const EMPTY = Object.freeze({ value: null });
30318
- const ONE = Object.freeze({ value: 1 });
30319
- const ChartRangeDataSourceHandler = {
30320
- supportedChartTypes: CHART_TYPES,
30321
- fromExternalDefinition(dataSource, defaultSheetId, getters) {
30322
- const dataSets = createDataSets(getters, defaultSheetId, dataSource);
30323
- const labelRange = createValidRange(getters, defaultSheetId, dataSource.labelRange);
30324
- return {
30325
- ...dataSource,
30326
- dataSets,
30327
- labelRange
30328
- };
30329
- },
30330
- fromContextCreation(context) {
30331
- return {
30332
- type: "range",
30333
- dataSets: [],
30334
- dataSetsHaveTitle: false,
30335
- labelRange: context.auxiliaryRange,
30336
- ...context.dataSource
30337
- };
30338
- },
30339
- fromHierarchicalContextCreation(context) {
30340
- if (context.dataSource?.type !== "range" || context.hierarchicalDataSource !== void 0 && context.hierarchicalDataSource.type !== "range") return {
30341
- type: "range",
30342
- dataSets: [],
30343
- dataSetsHaveTitle: false
30344
- };
30345
- let dataSource = {
30346
- type: "range",
30347
- dataSets: [],
30348
- dataSetsHaveTitle: context.dataSource?.dataSetsHaveTitle ?? false,
30349
- labelRange: context.dataSource?.dataSets?.[0]?.dataRange
30350
- };
30351
- if (context.hierarchicalDataSource?.dataSets.length) dataSource = context.hierarchicalDataSource;
30352
- else if (context.auxiliaryRange) dataSource = {
30353
- ...dataSource,
30354
- dataSets: [{
30355
- dataRange: context.auxiliaryRange,
30356
- dataSetId: "0"
30357
- }]
30358
- };
30359
- return dataSource;
30360
- },
30361
- validate: (dataSource, validator) => validator.checkValidations(dataSource, checkDataset, checkLabelRange),
30362
- transform(dataSource, defaultSheetId, { adaptRangeString }) {
30363
- let labelRange;
30364
- if (dataSource.labelRange) {
30365
- const { changeType, range: adaptedRange } = adaptRangeString(defaultSheetId, dataSource.labelRange);
30366
- if (changeType !== "REMOVE") labelRange = adaptedRange;
30367
- }
30368
- const dataSets = [];
30369
- for (const dataSet of dataSource.dataSets) {
30370
- const newDataSet = { ...dataSet };
30371
- const { changeType, range: adaptedRange } = adaptRangeString(defaultSheetId, dataSet.dataRange);
30372
- if (changeType !== "REMOVE") {
30373
- newDataSet.dataRange = adaptedRange;
30374
- dataSets.push(newDataSet);
30375
- }
30376
- }
30377
- return {
30378
- ...dataSource,
30379
- dataSets,
30380
- labelRange
30381
- };
30382
- },
30383
- extractData: (dataSource, chartId, getters) => getChartData(getters, dataSource),
30384
- extractHierarchicalData(dataSource, chartId, getters) {
30385
- const dataSets = dataSource.dataSets;
30386
- const labelRange = dataSource.labelRange;
30387
- const labelValues = getChartLabelValues(getters, dataSets, labelRange);
30388
- const dataSetsValues = getHierarchicalDatasetValues(getters, dataSets);
30389
- const data = {
30390
- labelValues,
30391
- dataSetsValues
30392
- };
30393
- if (shouldRemoveFirstLabel(labelValues.length, dataSetsValues[0]?.data.length + (dataSetsValues[0]?.label !== void 0 ? 1 : 0), dataSource.dataSetsHaveTitle || false)) labelValues.shift();
30394
- return data;
30395
- },
30396
- adaptRanges(dataSource, { applyChange }) {
30397
- const dataSetsWithUndefined = dataSource.dataSets.map((ds) => {
30398
- const { range: adaptedRangeStr, changeType } = applyChange(ds.dataRange);
30399
- if (changeType === "REMOVE") return;
30400
- let labelCell = void 0;
30401
- if (ds.labelCell) {
30402
- const { range: adaptedLabelCellRange, changeType: labelCellChangeType } = applyChange(ds.labelCell);
30403
- if (labelCellChangeType !== "REMOVE") labelCell = adaptedLabelCellRange;
30404
- }
30405
- return {
30406
- ...ds,
30407
- dataRange: adaptedRangeStr,
30408
- labelCell
30409
- };
30410
- }).filter(isDefined);
30411
- let labelRange = dataSource.labelRange;
30412
- if (labelRange) {
30413
- const { range: adaptedLabelRange, changeType } = applyChange(labelRange);
30414
- if (changeType === "REMOVE") labelRange = void 0;
30415
- else labelRange = adaptedLabelRange;
30416
- }
30417
- const dataSets = dataSetsWithUndefined;
30418
- return {
30419
- ...dataSource,
30420
- dataSets,
30421
- labelRange: labelRange?.invalidSheetName || labelRange?.invalidXc ? void 0 : labelRange
30422
- };
30423
- },
30424
- getDefinition(dataSource, defaultSheetId, getters) {
30425
- return {
30426
- labelRange: dataSource.labelRange ? getters.getRangeString(dataSource.labelRange, defaultSheetId) : void 0,
30427
- type: "range",
30428
- dataSets: dataSource.dataSets.map((dataSet) => ({
30429
- dataSetId: dataSet.dataSetId,
30430
- dataRange: getters.getRangeString(dataSet.dataRange, defaultSheetId)
30431
- })),
30432
- dataSetsHaveTitle: dataSource.dataSetsHaveTitle
30433
- };
30434
- },
30435
- /**
30436
- * Duplicate the dataSets. All ranges on sheetIdFrom are adapted to target
30437
- * sheetIdTo.
30438
- */
30439
- duplicateInDuplicatedSheet(dataSource, sheetIdFrom, sheetIdTo, getters) {
30440
- return {
30441
- ...dataSource,
30442
- labelRange: duplicateLabelRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, dataSource.labelRange),
30443
- dataSets: dataSource.dataSets.map((ds) => ({
30444
- ...ds,
30445
- dataRange: duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, ds.dataRange)
30446
- }))
30447
- };
30448
- },
30449
- getContextCreation: (dataSource) => ({
30450
- auxiliaryRange: dataSource.labelRange,
30451
- dataSource
30452
- }),
30453
- getHierarchicalContextCreation(dataSource) {
30454
- const leafRange = dataSource.dataSets.at(-1)?.dataRange;
30455
- const dataSetsHaveTitle = dataSource.dataSetsHaveTitle;
30456
- return {
30457
- auxiliaryRange: leafRange,
30458
- hierarchicalDataSource: dataSource,
30459
- dataSource: dataSource.labelRange ? {
30460
- type: "range",
30461
- dataSets: [{
30462
- dataRange: dataSource.labelRange,
30463
- dataSetId: "0"
30464
- }],
30465
- dataSetsHaveTitle
30466
- } : {
30467
- type: "range",
30468
- dataSets: [],
30469
- dataSetsHaveTitle
30470
- }
30471
- };
30472
- },
30473
- toExcelDataSets(dataSource, dataSetStyles, getters) {
30474
- const dataSets = dataSource.dataSets;
30475
- const labelRange = dataSource.labelRange;
30476
- const excelDataSets = dataSets.map((ds) => toExcelDataset(getters, dataSetStyles, ds)).filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
30477
- const datasetLength = dataSets[0] ? getZoneArea(dataSets[0].dataRange.zone) : void 0;
30478
- return {
30479
- dataSets: excelDataSets,
30480
- labelRange: toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel(labelRange ? getZoneArea(labelRange.zone) : 0, datasetLength, dataSource.dataSetsHaveTitle))
30481
- };
30482
- }
30483
- };
30484
- function getChartData(getters, dataSource) {
30485
- const dataSets = dataSource.dataSets;
30486
- const labelRange = dataSource.labelRange;
30487
- const labelValues = getChartLabelValues(getters, dataSets, labelRange);
30488
- const dataSetsValues = getChartDatasetValues(getters, dataSets);
30489
- const data = {
30490
- labelValues,
30491
- dataSetsValues
30492
- };
30493
- const numberOfDataPoints = dataSetsValues.length ? dataSetsValues[0]?.data.length + (dataSetsValues[0]?.label !== void 0 ? 1 : 0) : 0;
30494
- if (shouldRemoveFirstLabel(labelValues.length, numberOfDataPoints, dataSource.dataSetsHaveTitle || false)) labelValues.shift();
30495
- return data;
30496
- }
30497
- function getChartDatasetValues(getters, dataSets) {
30498
- const datasetValues = [];
30499
- for (const [dsIndex, ds] of Object.entries(dataSets)) {
30500
- let label = `${ChartTerms.Series} ${parseInt(dsIndex) + 1}`;
30501
- let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
30502
- if (ds.labelCell) {
30503
- const { sheetId, zone } = ds.labelCell;
30504
- const cell = getters.getEvaluatedCell({
30505
- sheetId,
30506
- col: zone.left,
30507
- row: zone.top
30508
- });
30509
- if (cell) label = cell.formattedValue;
30510
- }
30511
- let data = ds.dataRange ? getData(getters, ds) : [];
30512
- if (data.every((cell) => !cell.value || isTextResult(cell)) && data.filter(isTextResult).length > 1) data = data.map((cell) => cell.value && !isErrorResult(cell) ? ONE : EMPTY);
30513
- else if (data.every((cell) => !isNumberResult(cell))) hidden = true;
30514
- datasetValues.push({
30515
- data,
30516
- label,
30517
- hidden,
30518
- dataSetId: ds.dataSetId
30519
- });
30520
- }
30521
- return datasetValues;
30522
- }
30523
- function getChartLabelValues(getters, dataSets, labelRange) {
30524
- if (labelRange) {
30525
- const { left } = labelRange.zone;
30526
- if (!labelRange.invalidXc && !labelRange.invalidSheetName && !getters.isColHidden(labelRange.sheetId, left)) return getters.getVisibleRangeValues(labelRange);
30527
- }
30528
- if (dataSets[0]) {
30529
- const dataLength = getData(getters, dataSets[0]).length;
30530
- return Array.from({ length: dataLength }, () => ({ value: "" }));
30531
- }
30532
- return [];
30533
- }
30534
- /**
30535
- * Get the values for a hierarchical dataset. The values can be defined in a tree-like structure
30536
- * in the sheet, and this function will fill up the blanks.
30537
- *
30538
- * @example the following dataset:
30539
- *
30540
- * 2024 Q1 W1 100
30541
- * W2 200
30542
- *
30543
- * will have the same value as the dataset:
30544
- * 2024 Q1 W1 100
30545
- * 2024 Q1 W2 200
30546
- */
30547
- function getHierarchicalDatasetValues(getters, dataSets) {
30548
- dataSets = dataSets.filter((ds) => !getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left));
30549
- const datasetValues = dataSets.map((ds) => ({
30550
- data: [],
30551
- label: "",
30552
- dataSetId: ds.dataSetId
30553
- }));
30554
- const locale = getters.getLocale();
30555
- const dataSetsData = dataSets.map((ds) => getData(getters, ds)).map((values) => values.map(({ value, format }) => value === null ? EMPTY : { value: formatValue(value, {
30556
- format,
30557
- locale
30558
- }) }));
30559
- if (!dataSetsData.length) return datasetValues;
30560
- const minLength = Math.min(...dataSetsData.map((ds) => ds.length));
30561
- let currentValues = [];
30562
- const leafDatasetIndex = dataSets.length - 1;
30563
- for (let i = 0; i < minLength; i++) for (let dsIndex = 0; dsIndex < dataSetsData.length; dsIndex++) {
30564
- let cell = dataSetsData[dsIndex][i];
30565
- if ((cell === void 0 || cell.value === null) && dsIndex !== leafDatasetIndex) cell = currentValues[dsIndex];
30566
- if (cell?.value !== currentValues[dsIndex]?.value) {
30567
- currentValues = currentValues.slice(0, dsIndex);
30568
- currentValues[dsIndex] = cell;
30569
- }
30570
- datasetValues[dsIndex].data.push(cell ?? EMPTY);
30571
- }
30572
- return datasetValues.filter((ds) => ds.data.some((d) => d.value !== null));
30573
- }
30574
- /**
30575
- * Get the data from a dataSet
30576
- */
30577
- function getData(getters, ds) {
30578
- if (ds.dataRange) {
30579
- const labelCellZone = ds.labelCell ? [ds.labelCell.zone] : [];
30580
- const dataZone = recomputeZones([ds.dataRange.zone], labelCellZone)[0];
30581
- if (dataZone === void 0) return [];
30582
- const dataRange = getters.getRangeFromZone(ds.dataRange.sheetId, dataZone);
30583
- return getters.getVisibleRangeValues(dataRange).map((cell) => cell.value === "" ? EMPTY : cell);
30584
- }
30585
- return [];
30586
- }
30587
- const ChartNeverDataSourceHandler = {
30588
- supportedChartTypes: [],
30589
- fromExternalDefinition: () => ({ type: "none" }),
30590
- fromContextCreation: () => ({ type: "none" }),
30591
- fromHierarchicalContextCreation: () => ({ type: "none" }),
30592
- validate: () => "Success",
30593
- transform: () => ({ type: "none" }),
30594
- extractData: () => ({
30595
- dataSetsValues: [],
30596
- labelValues: []
30597
- }),
30598
- extractHierarchicalData: () => ({
30599
- dataSetsValues: [],
30600
- labelValues: []
30601
- }),
30602
- adaptRanges: (dataSource) => dataSource,
30603
- getDefinition: (dataSource) => dataSource,
30604
- duplicateInDuplicatedSheet: (dataSource) => dataSource,
30605
- getContextCreation: () => ({}),
30606
- getHierarchicalContextCreation: () => ({}),
30607
- toExcelDataSets: () => ({
30608
- dataSets: [],
30609
- labelRange: void 0
30610
- })
30611
- };
30612
- chartDataSourceRegistry.add("range", ChartRangeDataSourceHandler);
30613
- chartDataSourceRegistry.add("none", ChartNeverDataSourceHandler);
30614
-
30615
30189
  //#endregion
30616
30190
  //#region src/types/chart/calendar_chart.ts
30617
30191
  const CALENDAR_CHART_GRANULARITIES = [
@@ -30638,41 +30212,6 @@ set(value) {
30638
30212
  value,
30639
30213
  label: ALL_PERIODS[value]
30640
30214
  }));
30641
- getGroupByOptions() {
30642
- const sheetId = this.env.model.getters.getFigureSheetId(this.env.model.getters.getFigureIdFromChartId(this.props.chartId));
30643
- const definition = SpreadsheetChart.fromStrDefinition(this.env.model.getters, sheetId, this.props.definition).getRangeDefinition();
30644
- const labels = getBarChartData(definition, getChartData(this.env.model.getters, definition.dataSource), this.env.model.getters).labels.filter((l) => isDateTime(l, DEFAULT_LOCALE));
30645
- if (labels.length === 0) return [];
30646
- const dates = labels.map((label) => toJsDate(label, this.env.model.getters.getLocale()));
30647
- const uniqueYears = /* @__PURE__ */ new Set();
30648
- const uniqueMonths = /* @__PURE__ */ new Set();
30649
- const uniqueDays = /* @__PURE__ */ new Set();
30650
- const uniqueHours = /* @__PURE__ */ new Set();
30651
- const uniqueMinutes = /* @__PURE__ */ new Set();
30652
- const uniqueSeconds = /* @__PURE__ */ new Set();
30653
- for (const date of dates) {
30654
- uniqueYears.add(date.getFullYear());
30655
- uniqueMonths.add(date.getMonth());
30656
- uniqueDays.add(date.getDate());
30657
- uniqueHours.add(date.getHours());
30658
- uniqueMinutes.add(date.getMinutes());
30659
- uniqueSeconds.add(date.getSeconds());
30660
- }
30661
- return this.groupByChoices.filter((groupBy) => {
30662
- switch (groupBy.value) {
30663
- case "year": return uniqueYears.size > 1;
30664
- case "quarter_number":
30665
- case "month_number": return uniqueMonths.size > 1;
30666
- case "iso_week_number":
30667
- case "day_of_month":
30668
- case "day_of_week": return uniqueDays.size > 1;
30669
- case "hour_number": return uniqueHours.size > 1;
30670
- case "minute_number": return uniqueMinutes.size > 1;
30671
- case "second_number": return uniqueSeconds.size > 1;
30672
- default: return false;
30673
- }
30674
- });
30675
- }
30676
30215
  getGroupByType(currentAxis) {
30677
30216
  return (currentAxis === "horizontal" ? this.props.definition.horizontalGroupBy : this.props.definition.verticalGroupBy) || "year";
30678
30217
  }
@@ -31245,7 +30784,7 @@ set(value) {
31245
30784
  spreadsheetRect = useSpreadsheetRect();
31246
30785
  bubbleRef = (0, _odoo_owl.signal)(null);
31247
30786
  setup() {
31248
- (0, _odoo_owl.useEffect)(() => {
30787
+ useLayoutEffect(() => {
31249
30788
  const el = this.bubbleRef();
31250
30789
  if (!el) return;
31251
30790
  const anchorRect = this.props.anchorRect;
@@ -32659,7 +32198,7 @@ set(value) {
32659
32198
  col: range.zone.left,
32660
32199
  row: range.zone.top
32661
32200
  });
32662
- if (spreadZone) return this.getters.getRangeFromZone(sheetId, spreadZone);
32201
+ if (spreadZone) return this.getters.getRangeFromZone(range.sheetId, spreadZone);
32663
32202
  return range;
32664
32203
  }
32665
32204
  updateAutoCompleteProvider() {
@@ -33872,6 +33411,133 @@ set(value) {
33872
33411
  }
33873
33412
  };
33874
33413
 
33414
+ //#endregion
33415
+ //#region src/helpers/figures/chart.ts
33416
+ var SpreadsheetChart = class SpreadsheetChart {
33417
+ getters;
33418
+ sheetId;
33419
+ definition;
33420
+ chartTypeBuilder;
33421
+ dataSourceBuilder;
33422
+ dataSource;
33423
+ constructor(getters, sheetId, definition, chartTypeBuilder, dataSourceBuilder) {
33424
+ this.getters = getters;
33425
+ this.sheetId = sheetId;
33426
+ this.definition = definition;
33427
+ this.chartTypeBuilder = chartTypeBuilder;
33428
+ this.dataSourceBuilder = dataSourceBuilder;
33429
+ this.dataSource = definition.dataSource;
33430
+ }
33431
+ static fromStrDefinition(getters, sheetId, definition) {
33432
+ const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
33433
+ const chartTypeBuilder = chartTypeRegistry.get(definition.type);
33434
+ const dataSource = dataSourceBuilder.fromExternalDefinition(definition.dataSource ?? { type: "none" }, sheetId, getters);
33435
+ const rangeDefinition = {
33436
+ ...chartTypeBuilder.fromStrDefinition(definition, sheetId, getters),
33437
+ dataSource
33438
+ };
33439
+ return new SpreadsheetChart(getters, sheetId, SpreadsheetChart.deleteInvalidKeys(rangeDefinition), chartTypeBuilder, dataSourceBuilder);
33440
+ }
33441
+ static fromDefinition(getters, sheetId, definition) {
33442
+ const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
33443
+ return new SpreadsheetChart(getters, sheetId, definition, chartTypeRegistry.get(definition.type), dataSourceBuilder);
33444
+ }
33445
+ static validate(validator, definition) {
33446
+ const chartTypeBuilder = chartTypeRegistry.get(definition.type);
33447
+ const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
33448
+ return validator.batchValidations(() => chartTypeBuilder.validateDefinition(validator, definition), () => dataSourceBuilder.validate(definition.dataSource ?? { type: "none" }, validator))(void 0);
33449
+ }
33450
+ static transformDefinition(chartSheetId, definition, rangeAdapters) {
33451
+ const chartTypeBuilder = chartTypeRegistry.get(definition.type);
33452
+ if (!definition.dataSource) return chartTypeBuilder.transformDefinition(definition, chartSheetId, rangeAdapters);
33453
+ const newDataSource = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none").transform(definition.dataSource, chartSheetId, rangeAdapters);
33454
+ return {
33455
+ ...chartTypeBuilder.transformDefinition(definition, chartSheetId, rangeAdapters),
33456
+ dataSource: newDataSource
33457
+ };
33458
+ }
33459
+ getRangeDefinition() {
33460
+ return {
33461
+ ...this.definition,
33462
+ dataSource: this.dataSource
33463
+ };
33464
+ }
33465
+ getDefinition() {
33466
+ return {
33467
+ ...this.chartTypeBuilder.toStrDefinition(this.definition, this.sheetId, this.getters),
33468
+ dataSource: this.dataSource && this.dataSourceBuilder.getDefinition(this.dataSource, this.sheetId, this.getters)
33469
+ };
33470
+ }
33471
+ updateRanges(rangeAdapters) {
33472
+ return {
33473
+ ...this.chartTypeBuilder.updateRanges(this.definition, rangeAdapters, this.sheetId),
33474
+ dataSource: this.dataSource && this.dataSourceBuilder.adaptRanges(this.dataSource, rangeAdapters)
33475
+ };
33476
+ }
33477
+ duplicateInDuplicatedSheet(sheetIdFrom, sheetIdTo) {
33478
+ const newDataSource = this.dataSource && this.dataSourceBuilder.duplicateInDuplicatedSheet(this.dataSource, sheetIdFrom, sheetIdTo, this.getters);
33479
+ const definition = {
33480
+ ...this.chartTypeBuilder.duplicateInDuplicatedSheet(this.definition, sheetIdFrom, sheetIdTo, this.getters),
33481
+ dataSource: newDataSource
33482
+ };
33483
+ return SpreadsheetChart.fromDefinition(this.getters, sheetIdTo, definition).getDefinition();
33484
+ }
33485
+ copyInSheetId(sheetIdTo) {
33486
+ return {
33487
+ ...this.chartTypeBuilder.copyInSheetId(this.definition, this.sheetId, sheetIdTo, this.getters),
33488
+ dataSource: this.dataSource
33489
+ };
33490
+ }
33491
+ getContextCreation() {
33492
+ const definition = this.getDefinition();
33493
+ return {
33494
+ ...this.dataSourceBuilder.getContextCreation(definition.dataSource ?? { type: "none" }),
33495
+ ...this.chartTypeBuilder.getContextCreation(definition, this.dataSourceBuilder, definition.dataSource)
33496
+ };
33497
+ }
33498
+ getDefinitionForExcel(getters) {
33499
+ const definition = this.definition;
33500
+ const excelDataSets = this.dataSourceBuilder.toExcelDataSets(this.dataSource, "dataSetStyles" in definition ? definition.dataSetStyles : {}, getters);
33501
+ if (excelDataSets === void 0) return;
33502
+ return this.chartTypeBuilder.getDefinitionForExcel(getters, definition, excelDataSets);
33503
+ }
33504
+ getData(getters, chartId) {
33505
+ const dataSource = this.dataSource;
33506
+ return dataSource ? this.dataSourceBuilder.extractData(dataSource, chartId, getters) : {
33507
+ dataSetsValues: [],
33508
+ labelValues: []
33509
+ };
33510
+ }
33511
+ getRuntime(getters, chartId) {
33512
+ const dataSource = this.dataSource;
33513
+ const dataExtractors = dataSource ? {
33514
+ extractData: () => this.dataSourceBuilder.extractData(dataSource, chartId, getters),
33515
+ extractHierarchicalData: () => this.dataSourceBuilder.extractHierarchicalData(dataSource, chartId, getters)
33516
+ } : {
33517
+ extractData: () => ({
33518
+ dataSetsValues: [],
33519
+ labelValues: []
33520
+ }),
33521
+ extractHierarchicalData: () => ({
33522
+ dataSetsValues: [],
33523
+ labelValues: []
33524
+ })
33525
+ };
33526
+ return this.chartTypeBuilder.getRuntime(getters, this.definition, dataExtractors, this.sheetId, {
33527
+ onClick: (event, items, chartJsChart) => {
33528
+ return this.dataSourceBuilder.onDataSetClick?.(this.definition.type, chartId, event, items, chartJsChart, getters);
33529
+ },
33530
+ onHover: (event, items, chartJsChart) => this.dataSourceBuilder.onDataSetHover?.(this.definition.type, chartId, event, items, chartJsChart)
33531
+ });
33532
+ }
33533
+ static deleteInvalidKeys(definition) {
33534
+ definition = { ...definition };
33535
+ const keys = new Set(chartTypeRegistry.get(definition.type).allowedDefinitionKeys);
33536
+ for (const key of Object.keys(definition)) if (!keys.has(key)) delete definition[key];
33537
+ return definition;
33538
+ }
33539
+ };
33540
+
33875
33541
  //#endregion
33876
33542
  //#region src/components/side_panel/chart/main_chart_panel/main_chart_panel_store.ts
33877
33543
  var MainChartPanelStore = class extends SpreadsheetStore {
@@ -37093,7 +36759,7 @@ set(value) {
37093
36759
  }
37094
36760
  get specificRangeMatchesCount() {
37095
36761
  const range = this.searchOptions.specificRange;
37096
- if (!range) return "";
36762
+ if (!range || range.invalidSheetName || range.invalidXc) return "";
37097
36763
  const { specificRangeMatchesCount: count, specificRangeHiddenMatchesCount: hidden, searchOptions } = this.store;
37098
36764
  const { sheetId, zone } = range;
37099
36765
  let label = count === 1 ? _t("1 match in range %(range)s of '%(sheetName)s'", {
@@ -47481,6 +47147,11 @@ set(value) {
47481
47147
  });
47482
47148
  return icon?.onClick ? icon : void 0;
47483
47149
  }
47150
+ get isFooterVisible() {
47151
+ const { y } = this.env.model.getters.getMainViewportCoordinates();
47152
+ const { height } = this.env.model.getters.getSheetViewDimension();
47153
+ return !this.env.model.getters.isReadonly() && height - y > 46;
47154
+ }
47484
47155
  };
47485
47156
 
47486
47157
  //#endregion
@@ -56275,7 +55946,7 @@ set(value) {
56275
55946
  if (rangeError) return [[rangeError]];
56276
55947
  const sheetId = range.sheetId;
56277
55948
  const zone = range.zone;
56278
- const _zone = intersection(zone, this.getters.getSheetZone(sheetId));
55949
+ const _zone = this.getters.clipRangeToSheet(range)?.zone;
56279
55950
  if (!_zone) return [[]];
56280
55951
  const { top, left, bottom, right } = zone;
56281
55952
  const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
@@ -57265,10 +56936,10 @@ set(value) {
57265
56936
  updateDependencies(position) {
57266
56937
  this.formulaDependencies().removeAllDependencies(position);
57267
56938
  const dependencies = this.getDirectDependencies(position);
57268
- this.formulaDependencies().addDependencies(position, dependencies);
56939
+ this.formulaDependencies().addDependencies(position, this.getters.clipRangesToSheet(dependencies));
57269
56940
  }
57270
56941
  addDependencies(position, dependencies) {
57271
- this.formulaDependencies().addDependencies(position, dependencies);
56942
+ this.formulaDependencies().addDependencies(position, this.getters.clipRangesToSheet(dependencies));
57272
56943
  this.computeDependencies(dependencies);
57273
56944
  }
57274
56945
  computeDependencies(dependencies) {
@@ -57341,7 +57012,8 @@ set(value) {
57341
57012
  const graph = new FormulaDependencyGraph();
57342
57013
  for (const sheetId of this.getters.getSheetIds()) for (const cell of this.getters.getCells(sheetId)) if (cell.isFormula) {
57343
57014
  const cellPosition = this.getters.getCellPosition(cell.id);
57344
- graph.addDependencies(cellPosition, cell.compiledFormula.rangeDependencies);
57015
+ const dependencies = this.getters.clipRangesToSheet(cell.compiledFormula.rangeDependencies);
57016
+ graph.addDependencies(cellPosition, dependencies);
57345
57017
  }
57346
57018
  return graph;
57347
57019
  });
@@ -63322,7 +62994,8 @@ set(value) {
63322
62994
  "getGeoJsonFeatures",
63323
62995
  "geoFeatureNameToId",
63324
62996
  "getGeoChartAvailableRegions",
63325
- "getAvailableChartRegions"
62997
+ "getAvailableChartRegions",
62998
+ "loadUsedGeoJsonFeatures"
63326
62999
  ];
63327
63000
  geoJsonService;
63328
63001
  geoJsonCache = {};
@@ -63405,6 +63078,23 @@ set(value) {
63405
63078
  }
63406
63079
  return this.geoJsonService.geoFeatureNameToId(region, featureName);
63407
63080
  }
63081
+ loadUsedGeoJsonFeatures() {
63082
+ const regions = this.getters.getSheetIds().flatMap((sheetId) => this.getters.getChartIds(sheetId).map((chartId) => {
63083
+ const definition = this.getters.getChartDefinition(chartId);
63084
+ return definition.type === "geo" ? definition.region || this.getters.getGeoChartAvailableRegions()[0]?.id : void 0;
63085
+ })).filter(isDefined);
63086
+ const uniqueRegions = Array.from(new Set(regions));
63087
+ if (uniqueRegions.length && !this.geoJsonService) {
63088
+ console.error("No geoJsonService provided to the model");
63089
+ return Promise.resolve();
63090
+ }
63091
+ for (const region of uniqueRegions) this.getGeoJsonFeatures(region);
63092
+ const promises = uniqueRegions.map((region) => {
63093
+ const cachedGeoJson = this.geoJsonCache[region];
63094
+ return cachedGeoJson instanceof Promise ? cachedGeoJson : Promise.resolve();
63095
+ });
63096
+ return Promise.all(promises).then(() => {});
63097
+ }
63408
63098
  convertToGeoJson(json) {
63409
63099
  if (!json) return null;
63410
63100
  if (json.type === "Topology") {
@@ -66489,7 +66179,7 @@ set(value) {
66489
66179
  let height = lastRowEnd - this.offsetCorrectionY;
66490
66180
  if (this.canScrollVertically) {
66491
66181
  height = Math.max(height, this.viewportHeight);
66492
- if (lastRowEnd + 46 > height && !this.getters.isReadonly()) height += 46;
66182
+ if (lastRowEnd + 46 > height && !this.getters.isReadonly() && this.viewportHeight > 46) height += 46;
66493
66183
  }
66494
66184
  return {
66495
66185
  width,
@@ -70482,12 +70172,11 @@ set(value) {
70482
70172
  const { width: printWidth, height: printHeight } = this.pageDimensionWithMargins;
70483
70173
  const start = dimension === "COL" ? printZone.left : printZone.top;
70484
70174
  const end = dimension === "COL" ? printZone.right : printZone.bottom;
70485
- const getHeaderSize = dimension === "COL" ? this.getters.getColDimensions : this.getters.getRowDimensions;
70486
70175
  const max = dimension === "COL" ? printWidth : printHeight;
70487
70176
  const breaks = [];
70488
70177
  let current = 0;
70489
70178
  for (let i = start; i <= end; i++) {
70490
- const headerSize = getHeaderSize(sheetId, i).size * zoom;
70179
+ const headerSize = this.getters.isHeaderHidden(sheetId, dimension, i) ? 0 : this.getters.getHeaderSize(sheetId, dimension, i) * zoom;
70491
70180
  current += headerSize;
70492
70181
  if (current >= max) {
70493
70182
  breaks.push(i);
@@ -71938,7 +71627,10 @@ set(value) {
71938
71627
  sidePanel;
71939
71628
  spreadsheetRef = (0, _odoo_owl.signal)(null);
71940
71629
  spreadsheetRect = useSpreadsheetRect();
71941
- state = (0, _odoo_owl.proxy)({ printModeEnabled: false });
71630
+ state = (0, _odoo_owl.proxy)({
71631
+ printModeEnabled: false,
71632
+ colorThemeBeforePrint: "light"
71633
+ });
71942
71634
  _focusGrid;
71943
71635
  isViewportTooSmall = false;
71944
71636
  notificationStore;
@@ -71950,7 +71642,7 @@ set(value) {
71950
71642
  const properties = {};
71951
71643
  properties["--os-scrollbar-width"] = `${this.env.model.getters.getScrollBarWidth()}px`;
71952
71644
  properties["--os-dark-mode-filter"] = DARK_MODE_FILTER_STRING;
71953
- properties["color-scheme"] = this.props.model.getters.isDarkMode() ? "dark" : "light";
71645
+ properties["color-scheme"] = this.colorScheme;
71954
71646
  if (this.state.printModeEnabled) properties["display"] = `block`;
71955
71647
  else {
71956
71648
  if (this.env.model.getters.isDashboard()) properties["grid-template-rows"] = `auto`;
@@ -71990,7 +71682,7 @@ set(value) {
71990
71682
  askConfirmation: (text, confirm, cancel) => this.notificationStore.askConfirmation(text, confirm, cancel),
71991
71683
  raiseError: (text, cb) => this.notificationStore.raiseError(text, cb),
71992
71684
  isMobile: isMobileOS,
71993
- printSpreadsheet: () => this.state.printModeEnabled = true
71685
+ printSpreadsheet: this.enterPrintMode.bind(this)
71994
71686
  });
71995
71687
  this.notificationStore.updateNotificationCallbacks({ ...this.props });
71996
71688
  useLayoutEffect(() => {
@@ -72007,7 +71699,7 @@ set(value) {
72007
71699
  useExternalListener(document.body, "wheel", () => {});
72008
71700
  useExternalListener(window, "keydown", async (event) => {
72009
71701
  if (keyboardEventToShortcutString(event) === "Ctrl+P") {
72010
- this.state.printModeEnabled = true;
71702
+ this.enterPrintMode();
72011
71703
  event.stopPropagation();
72012
71704
  event.preventDefault();
72013
71705
  }
@@ -72120,9 +71812,21 @@ set(value) {
72120
71812
  getSpreadSheetClasses() {
72121
71813
  return [this.env.isSmall ? "o-spreadsheet-mobile" : "", this.props.model.getters.isDarkMode() ? "dark" : ""].join(" ");
72122
71814
  }
71815
+ enterPrintMode() {
71816
+ if (this.state.printModeEnabled) return;
71817
+ this.state.colorThemeBeforePrint = this.props.model.getters.isDarkMode() ? "dark" : "light";
71818
+ this.env.model.dispatch("UPDATE_COLOR_SCHEME", { colorScheme: "light" });
71819
+ this.state.printModeEnabled = true;
71820
+ }
72123
71821
  exitPrintMode() {
71822
+ if (!this.state.printModeEnabled) return;
71823
+ this.env.model.dispatch("UPDATE_COLOR_SCHEME", { colorScheme: this.state.colorThemeBeforePrint });
72124
71824
  this.state.printModeEnabled = false;
72125
71825
  }
71826
+ get colorScheme() {
71827
+ if (this.state.printModeEnabled) return this.state.colorThemeBeforePrint;
71828
+ return this.props.model.getters.isDarkMode() ? "dark" : "light";
71829
+ }
72126
71830
  };
72127
71831
 
72128
71832
  //#endregion
@@ -72997,6 +72701,8 @@ set(value) {
72997
72701
  "extendRange",
72998
72702
  "getRangeString",
72999
72703
  "getRangeFromSheetXC",
72704
+ "clipRangesToSheet",
72705
+ "clipRangeToSheet",
73000
72706
  "createAdaptedRanges",
73001
72707
  "getRangeData",
73002
72708
  "getRangeDataFromXc",
@@ -73035,6 +72741,22 @@ set(value) {
73035
72741
  addRangeProvider(provider) {
73036
72742
  this.providers.push(provider);
73037
72743
  }
72744
+ clipRangeToSheet(range) {
72745
+ if (range.invalidXc) return range;
72746
+ const sheetZone = this.getters.getSheetZone(range.sheetId);
72747
+ if (isZoneInside(range.zone, sheetZone)) return range;
72748
+ const newZone = intersection(range.zone, sheetZone);
72749
+ if (!newZone) return;
72750
+ return this.getters.getRangeFromZone(range.sheetId, newZone);
72751
+ }
72752
+ clipRangesToSheet(ranges) {
72753
+ const clippedRanges = [];
72754
+ for (const range of ranges) {
72755
+ const clippedRange = this.clipRangeToSheet(range);
72756
+ if (clippedRange) clippedRanges.push(clippedRange);
72757
+ }
72758
+ return clippedRanges;
72759
+ }
73038
72760
  createAdaptedRanges(ranges, offsetX, offsetY, sheetId) {
73039
72761
  return ranges.map((range) => {
73040
72762
  if (!isZoneValid(range.zone)) return range;
@@ -76268,6 +75990,8 @@ set(value) {
76268
75990
  this.range = new RangeAdapterPlugin(this.coreGetters);
76269
75991
  this.coreGetters.getRangeString = this.range.getRangeString.bind(this.range);
76270
75992
  this.coreGetters.getRangeFromSheetXC = this.range.getRangeFromSheetXC.bind(this.range);
75993
+ this.coreGetters.clipRangesToSheet = this.range.clipRangesToSheet.bind(this.range);
75994
+ this.coreGetters.clipRangeToSheet = this.range.clipRangeToSheet.bind(this.range);
76271
75995
  this.coreGetters.createAdaptedRanges = this.range.createAdaptedRanges.bind(this.range);
76272
75996
  this.coreGetters.getRangeData = this.range.getRangeData.bind(this.range);
76273
75997
  this.coreGetters.getRangeDataFromXc = this.range.getRangeDataFromXc.bind(this.range);
@@ -78230,6 +77954,306 @@ set(value) {
78230
77954
  //#region src/components/popover/popover_builders.ts
78231
77955
  cellPopoverRegistry.add("ErrorToolTip", ErrorToolTipPopoverBuilder).add("LinkCell", LinkCellPopoverBuilder).add("LinkEditor", LinkEditorPopoverBuilder).add("FilterMenu", FilterMenuPopoverBuilder);
78232
77956
 
77957
+ //#endregion
77958
+ //#region src/helpers/figures/charts/chart_data_sources.ts
77959
+ const EMPTY = Object.freeze({ value: null });
77960
+ const ONE = Object.freeze({ value: 1 });
77961
+ const ChartRangeDataSourceHandler = {
77962
+ supportedChartTypes: CHART_TYPES,
77963
+ fromExternalDefinition(dataSource, defaultSheetId, getters) {
77964
+ const dataSets = createDataSets(getters, defaultSheetId, dataSource);
77965
+ const labelRange = createValidRange(getters, defaultSheetId, dataSource.labelRange);
77966
+ return {
77967
+ ...dataSource,
77968
+ dataSets,
77969
+ labelRange
77970
+ };
77971
+ },
77972
+ fromContextCreation(context) {
77973
+ return {
77974
+ type: "range",
77975
+ dataSets: [],
77976
+ dataSetsHaveTitle: false,
77977
+ labelRange: context.auxiliaryRange,
77978
+ ...context.dataSource
77979
+ };
77980
+ },
77981
+ fromHierarchicalContextCreation(context) {
77982
+ if (context.dataSource?.type !== "range" || context.hierarchicalDataSource !== void 0 && context.hierarchicalDataSource.type !== "range") return {
77983
+ type: "range",
77984
+ dataSets: [],
77985
+ dataSetsHaveTitle: false
77986
+ };
77987
+ let dataSource = {
77988
+ type: "range",
77989
+ dataSets: [],
77990
+ dataSetsHaveTitle: context.dataSource?.dataSetsHaveTitle ?? false,
77991
+ labelRange: context.dataSource?.dataSets?.[0]?.dataRange
77992
+ };
77993
+ if (context.hierarchicalDataSource?.dataSets.length) dataSource = context.hierarchicalDataSource;
77994
+ else if (context.auxiliaryRange) dataSource = {
77995
+ ...dataSource,
77996
+ dataSets: [{
77997
+ dataRange: context.auxiliaryRange,
77998
+ dataSetId: "0"
77999
+ }]
78000
+ };
78001
+ return dataSource;
78002
+ },
78003
+ validate: (dataSource, validator) => validator.checkValidations(dataSource, checkDataset, checkLabelRange),
78004
+ transform(dataSource, defaultSheetId, { adaptRangeString }) {
78005
+ let labelRange;
78006
+ if (dataSource.labelRange) {
78007
+ const { changeType, range: adaptedRange } = adaptRangeString(defaultSheetId, dataSource.labelRange);
78008
+ if (changeType !== "REMOVE") labelRange = adaptedRange;
78009
+ }
78010
+ const dataSets = [];
78011
+ for (const dataSet of dataSource.dataSets) {
78012
+ const newDataSet = { ...dataSet };
78013
+ const { changeType, range: adaptedRange } = adaptRangeString(defaultSheetId, dataSet.dataRange);
78014
+ if (changeType !== "REMOVE") {
78015
+ newDataSet.dataRange = adaptedRange;
78016
+ dataSets.push(newDataSet);
78017
+ }
78018
+ }
78019
+ return {
78020
+ ...dataSource,
78021
+ dataSets,
78022
+ labelRange
78023
+ };
78024
+ },
78025
+ extractData: (dataSource, chartId, getters) => getChartData(getters, dataSource),
78026
+ extractHierarchicalData(dataSource, chartId, getters) {
78027
+ const dataSets = dataSource.dataSets;
78028
+ const labelRange = dataSource.labelRange;
78029
+ const labelValues = getChartLabelValues(getters, dataSets, labelRange);
78030
+ const dataSetsValues = getHierarchicalDatasetValues(getters, dataSets);
78031
+ const data = {
78032
+ labelValues,
78033
+ dataSetsValues
78034
+ };
78035
+ if (shouldRemoveFirstLabel(labelValues.length, dataSetsValues[0]?.data.length + (dataSetsValues[0]?.label !== void 0 ? 1 : 0), dataSource.dataSetsHaveTitle || false)) labelValues.shift();
78036
+ return data;
78037
+ },
78038
+ adaptRanges(dataSource, { applyChange }) {
78039
+ const dataSetsWithUndefined = dataSource.dataSets.map((ds) => {
78040
+ const { range: adaptedRangeStr, changeType } = applyChange(ds.dataRange);
78041
+ if (changeType === "REMOVE") return;
78042
+ let labelCell = void 0;
78043
+ if (ds.labelCell) {
78044
+ const { range: adaptedLabelCellRange, changeType: labelCellChangeType } = applyChange(ds.labelCell);
78045
+ if (labelCellChangeType !== "REMOVE") labelCell = adaptedLabelCellRange;
78046
+ }
78047
+ return {
78048
+ ...ds,
78049
+ dataRange: adaptedRangeStr,
78050
+ labelCell
78051
+ };
78052
+ }).filter(isDefined);
78053
+ let labelRange = dataSource.labelRange;
78054
+ if (labelRange) {
78055
+ const { range: adaptedLabelRange, changeType } = applyChange(labelRange);
78056
+ if (changeType === "REMOVE") labelRange = void 0;
78057
+ else labelRange = adaptedLabelRange;
78058
+ }
78059
+ const dataSets = dataSetsWithUndefined;
78060
+ return {
78061
+ ...dataSource,
78062
+ dataSets,
78063
+ labelRange: labelRange?.invalidSheetName || labelRange?.invalidXc ? void 0 : labelRange
78064
+ };
78065
+ },
78066
+ getDefinition(dataSource, defaultSheetId, getters) {
78067
+ return {
78068
+ labelRange: dataSource.labelRange ? getters.getRangeString(dataSource.labelRange, defaultSheetId) : void 0,
78069
+ type: "range",
78070
+ dataSets: dataSource.dataSets.map((dataSet) => ({
78071
+ dataSetId: dataSet.dataSetId,
78072
+ dataRange: getters.getRangeString(dataSet.dataRange, defaultSheetId)
78073
+ })),
78074
+ dataSetsHaveTitle: dataSource.dataSetsHaveTitle
78075
+ };
78076
+ },
78077
+ /**
78078
+ * Duplicate the dataSets. All ranges on sheetIdFrom are adapted to target
78079
+ * sheetIdTo.
78080
+ */
78081
+ duplicateInDuplicatedSheet(dataSource, sheetIdFrom, sheetIdTo, getters) {
78082
+ return {
78083
+ ...dataSource,
78084
+ labelRange: duplicateLabelRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, dataSource.labelRange),
78085
+ dataSets: dataSource.dataSets.map((ds) => ({
78086
+ ...ds,
78087
+ dataRange: duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, ds.dataRange)
78088
+ }))
78089
+ };
78090
+ },
78091
+ getContextCreation: (dataSource) => ({
78092
+ auxiliaryRange: dataSource.labelRange,
78093
+ dataSource
78094
+ }),
78095
+ getHierarchicalContextCreation(dataSource) {
78096
+ const leafRange = dataSource.dataSets.at(-1)?.dataRange;
78097
+ const dataSetsHaveTitle = dataSource.dataSetsHaveTitle;
78098
+ return {
78099
+ auxiliaryRange: leafRange,
78100
+ hierarchicalDataSource: dataSource,
78101
+ dataSource: dataSource.labelRange ? {
78102
+ type: "range",
78103
+ dataSets: [{
78104
+ dataRange: dataSource.labelRange,
78105
+ dataSetId: "0"
78106
+ }],
78107
+ dataSetsHaveTitle
78108
+ } : {
78109
+ type: "range",
78110
+ dataSets: [],
78111
+ dataSetsHaveTitle
78112
+ }
78113
+ };
78114
+ },
78115
+ toExcelDataSets(dataSource, dataSetStyles, getters) {
78116
+ const dataSets = dataSource.dataSets;
78117
+ const labelRange = dataSource.labelRange;
78118
+ const excelDataSets = dataSets.map((ds) => toExcelDataset(getters, dataSetStyles, ds)).filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
78119
+ const datasetLength = dataSets[0] ? getZoneArea(dataSets[0].dataRange.zone) : void 0;
78120
+ return {
78121
+ dataSets: excelDataSets,
78122
+ labelRange: toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel(labelRange ? getZoneArea(labelRange.zone) : 0, datasetLength, dataSource.dataSetsHaveTitle))
78123
+ };
78124
+ }
78125
+ };
78126
+ function getChartData(getters, dataSource) {
78127
+ const dataSets = dataSource.dataSets;
78128
+ const labelRange = dataSource.labelRange;
78129
+ const labelValues = getChartLabelValues(getters, dataSets, labelRange);
78130
+ const dataSetsValues = getChartDatasetValues(getters, dataSets);
78131
+ const data = {
78132
+ labelValues,
78133
+ dataSetsValues
78134
+ };
78135
+ const numberOfDataPoints = dataSetsValues.length ? dataSetsValues[0]?.data.length + (dataSetsValues[0]?.label !== void 0 ? 1 : 0) : 0;
78136
+ if (shouldRemoveFirstLabel(labelValues.length, numberOfDataPoints, dataSource.dataSetsHaveTitle || false)) labelValues.shift();
78137
+ return data;
78138
+ }
78139
+ function getChartDatasetValues(getters, dataSets) {
78140
+ const datasetValues = [];
78141
+ for (const [dsIndex, ds] of Object.entries(dataSets)) {
78142
+ let label = `${ChartTerms.Series} ${parseInt(dsIndex) + 1}`;
78143
+ let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
78144
+ if (ds.labelCell) {
78145
+ const { sheetId, zone } = ds.labelCell;
78146
+ const cell = getters.getEvaluatedCell({
78147
+ sheetId,
78148
+ col: zone.left,
78149
+ row: zone.top
78150
+ });
78151
+ if (cell) label = cell.formattedValue;
78152
+ }
78153
+ let data = ds.dataRange ? getData(getters, ds) : [];
78154
+ if (data.every((cell) => !cell.value || isTextResult(cell)) && data.filter(isTextResult).length > 1) data = data.map((cell) => cell.value && !isErrorResult(cell) ? ONE : EMPTY);
78155
+ else if (data.every((cell) => !isNumberResult(cell))) hidden = true;
78156
+ datasetValues.push({
78157
+ data,
78158
+ label,
78159
+ hidden,
78160
+ dataSetId: ds.dataSetId
78161
+ });
78162
+ }
78163
+ return datasetValues;
78164
+ }
78165
+ function getChartLabelValues(getters, dataSets, labelRange) {
78166
+ if (labelRange) {
78167
+ const { left } = labelRange.zone;
78168
+ if (!labelRange.invalidXc && !labelRange.invalidSheetName && !getters.isColHidden(labelRange.sheetId, left)) return getters.getVisibleRangeValues(labelRange);
78169
+ }
78170
+ if (dataSets[0]) {
78171
+ const dataLength = getData(getters, dataSets[0]).length;
78172
+ return Array.from({ length: dataLength }, () => ({ value: "" }));
78173
+ }
78174
+ return [];
78175
+ }
78176
+ /**
78177
+ * Get the values for a hierarchical dataset. The values can be defined in a tree-like structure
78178
+ * in the sheet, and this function will fill up the blanks.
78179
+ *
78180
+ * @example the following dataset:
78181
+ *
78182
+ * 2024 Q1 W1 100
78183
+ * W2 200
78184
+ *
78185
+ * will have the same value as the dataset:
78186
+ * 2024 Q1 W1 100
78187
+ * 2024 Q1 W2 200
78188
+ */
78189
+ function getHierarchicalDatasetValues(getters, dataSets) {
78190
+ dataSets = dataSets.filter((ds) => !getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left));
78191
+ const datasetValues = dataSets.map((ds) => ({
78192
+ data: [],
78193
+ label: "",
78194
+ dataSetId: ds.dataSetId
78195
+ }));
78196
+ const locale = getters.getLocale();
78197
+ const dataSetsData = dataSets.map((ds) => getData(getters, ds)).map((values) => values.map(({ value, format }) => value === null ? EMPTY : { value: formatValue(value, {
78198
+ format,
78199
+ locale
78200
+ }) }));
78201
+ if (!dataSetsData.length) return datasetValues;
78202
+ const minLength = Math.min(...dataSetsData.map((ds) => ds.length));
78203
+ let currentValues = [];
78204
+ const leafDatasetIndex = dataSets.length - 1;
78205
+ for (let i = 0; i < minLength; i++) for (let dsIndex = 0; dsIndex < dataSetsData.length; dsIndex++) {
78206
+ let cell = dataSetsData[dsIndex][i];
78207
+ if ((cell === void 0 || cell.value === null) && dsIndex !== leafDatasetIndex) cell = currentValues[dsIndex];
78208
+ if (cell?.value !== currentValues[dsIndex]?.value) {
78209
+ currentValues = currentValues.slice(0, dsIndex);
78210
+ currentValues[dsIndex] = cell;
78211
+ }
78212
+ datasetValues[dsIndex].data.push(cell ?? EMPTY);
78213
+ }
78214
+ return datasetValues.filter((ds) => ds.data.some((d) => d.value !== null));
78215
+ }
78216
+ /**
78217
+ * Get the data from a dataSet
78218
+ */
78219
+ function getData(getters, ds) {
78220
+ if (ds.dataRange) {
78221
+ const labelCellZone = ds.labelCell ? [ds.labelCell.zone] : [];
78222
+ const dataZone = recomputeZones([ds.dataRange.zone], labelCellZone)[0];
78223
+ if (dataZone === void 0) return [];
78224
+ const dataRange = getters.getRangeFromZone(ds.dataRange.sheetId, dataZone);
78225
+ return getters.getVisibleRangeValues(dataRange).map((cell) => cell.value === "" ? EMPTY : cell);
78226
+ }
78227
+ return [];
78228
+ }
78229
+ const ChartNeverDataSourceHandler = {
78230
+ supportedChartTypes: [],
78231
+ fromExternalDefinition: () => ({ type: "none" }),
78232
+ fromContextCreation: () => ({ type: "none" }),
78233
+ fromHierarchicalContextCreation: () => ({ type: "none" }),
78234
+ validate: () => "Success",
78235
+ transform: () => ({ type: "none" }),
78236
+ extractData: () => ({
78237
+ dataSetsValues: [],
78238
+ labelValues: []
78239
+ }),
78240
+ extractHierarchicalData: () => ({
78241
+ dataSetsValues: [],
78242
+ labelValues: []
78243
+ }),
78244
+ adaptRanges: (dataSource) => dataSource,
78245
+ getDefinition: (dataSource) => dataSource,
78246
+ duplicateInDuplicatedSheet: (dataSource) => dataSource,
78247
+ getContextCreation: () => ({}),
78248
+ getHierarchicalContextCreation: () => ({}),
78249
+ toExcelDataSets: () => ({
78250
+ dataSets: [],
78251
+ labelRange: void 0
78252
+ })
78253
+ };
78254
+ chartDataSourceRegistry.add("range", ChartRangeDataSourceHandler);
78255
+ chartDataSourceRegistry.add("none", ChartNeverDataSourceHandler);
78256
+
78233
78257
  //#endregion
78234
78258
  //#region src/registries/auto_completes/data_validation_auto_complete.ts
78235
78259
  autoCompleteProviders.add("dataValidation", {
@@ -87814,8 +87838,8 @@ exports.stores = stores;
87814
87838
  exports.tokenColors = tokenColors;
87815
87839
  exports.tokenize = tokenize;
87816
87840
 
87817
- __info__.version = "19.4.11";
87818
- __info__.date = "2026-09-04T07:50:39.272Z";
87819
- __info__.hash = "7660254";
87841
+ __info__.version = "19.4.12";
87842
+ __info__.date = "2026-09-10T05:38:01.898Z";
87843
+ __info__.hash = "cdb63b4";
87820
87844
 
87821
87845
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);