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