@odoo/o-spreadsheet 19.3.19 → 19.3.20

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.3.19
6
- * @date 2026-09-04T07:38:14.356Z
7
- * @hash c8c526d
5
+ * @version 19.3.20
6
+ * @date 2026-09-10T05:38:03.233Z
7
+ * @hash e488e8d
8
8
  */
9
9
 
10
10
  import { App, Component, blockDom, markRaw, onMounted, onPatched, onWillPatch, onWillStart, onWillUnmount, onWillUpdateProps, status, toRaw, useChildSubEnv, useComponent, useEffect, useEnv, useExternalListener, useRef, useState, useSubEnv, whenReady, xml } from "@odoo/owl";
@@ -9625,7 +9625,7 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
9625
9625
  const point = dataset.data[i];
9626
9626
  const xPosition = point.x;
9627
9627
  let yPosition = 0;
9628
- if (chart.config.type === "line" || chart.config.type === "radar") yPosition = value < 0 ? point.y + 10 : point.y - 10;
9628
+ if (dataset.type === "line" || dataset.type === "radar") yPosition = value < 0 ? point.y + 10 : point.y - 10;
9629
9629
  else {
9630
9630
  const yZeroLine = yAxisScale.getPixelForValue(0);
9631
9631
  const distanceFromAxisOrigin = Math.abs(yZeroLine - point.y);
@@ -18573,7 +18573,7 @@ const RemoveDuplicateTerms = { Errors: {
18573
18573
  ["MoreThanOneRangeSelected"]: _t("Please select only one range of cells"),
18574
18574
  ["EmptySelectedRange"]: _t("Please select a range of cells containing values."),
18575
18575
  ["NoColumnsProvided"]: _t("Please select at latest one column to analyze."),
18576
- ["WillRemoveExistingMerge"]: _t("This operation is not possible due to a merge. Please remove the merges first than try again.")
18576
+ ["WillRemoveExistingMerge"]: _t("Cannot perform this action on merged cells. Unmerge the cells and try again.")
18577
18577
  } };
18578
18578
  const DVTerms = {
18579
18579
  DateIs: {
@@ -26814,7 +26814,7 @@ var AbstractComposerStore = class extends SpreadsheetStore {
26814
26814
  col: range.zone.left,
26815
26815
  row: range.zone.top
26816
26816
  });
26817
- if (spreadZone) return this.getters.getRangeFromZone(sheetId, spreadZone);
26817
+ if (spreadZone) return this.getters.getRangeFromZone(range.sheetId, spreadZone);
26818
26818
  return range;
26819
26819
  }
26820
26820
  updateAutoCompleteProvider() {
@@ -32825,433 +32825,6 @@ var ChartRangeDataSourceComponent = class extends Component {
32825
32825
  }
32826
32826
  };
32827
32827
 
32828
- //#endregion
32829
- //#region src/helpers/figures/chart.ts
32830
- var SpreadsheetChart = class SpreadsheetChart {
32831
- getters;
32832
- sheetId;
32833
- definition;
32834
- chartTypeBuilder;
32835
- dataSourceBuilder;
32836
- dataSource;
32837
- constructor(getters, sheetId, definition, chartTypeBuilder, dataSourceBuilder) {
32838
- this.getters = getters;
32839
- this.sheetId = sheetId;
32840
- this.definition = definition;
32841
- this.chartTypeBuilder = chartTypeBuilder;
32842
- this.dataSourceBuilder = dataSourceBuilder;
32843
- this.dataSource = definition.dataSource;
32844
- }
32845
- static fromStrDefinition(getters, sheetId, definition) {
32846
- const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
32847
- const chartTypeBuilder = chartTypeRegistry.get(definition.type);
32848
- const dataSource = dataSourceBuilder.fromExternalDefinition(definition.dataSource ?? { type: "none" }, sheetId, getters);
32849
- const rangeDefinition = {
32850
- ...chartTypeBuilder.fromStrDefinition(definition, sheetId, getters),
32851
- dataSource
32852
- };
32853
- return new SpreadsheetChart(getters, sheetId, SpreadsheetChart.deleteInvalidKeys(rangeDefinition), chartTypeBuilder, dataSourceBuilder);
32854
- }
32855
- static fromDefinition(getters, sheetId, definition) {
32856
- const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
32857
- return new SpreadsheetChart(getters, sheetId, definition, chartTypeRegistry.get(definition.type), dataSourceBuilder);
32858
- }
32859
- static validate(validator, definition) {
32860
- const chartTypeBuilder = chartTypeRegistry.get(definition.type);
32861
- const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
32862
- return validator.batchValidations(() => chartTypeBuilder.validateDefinition(validator, definition), () => dataSourceBuilder.validate(definition.dataSource ?? { type: "none" }, validator))(void 0);
32863
- }
32864
- static transformDefinition(chartSheetId, definition, rangeAdapters) {
32865
- const chartTypeBuilder = chartTypeRegistry.get(definition.type);
32866
- if (!definition.dataSource) return chartTypeBuilder.transformDefinition(definition, chartSheetId, rangeAdapters);
32867
- const newDataSource = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none").transform(definition.dataSource, chartSheetId, rangeAdapters);
32868
- return {
32869
- ...chartTypeBuilder.transformDefinition(definition, chartSheetId, rangeAdapters),
32870
- dataSource: newDataSource
32871
- };
32872
- }
32873
- getRangeDefinition() {
32874
- return {
32875
- ...this.definition,
32876
- dataSource: this.dataSource
32877
- };
32878
- }
32879
- getDefinition() {
32880
- return {
32881
- ...this.chartTypeBuilder.toStrDefinition(this.definition, this.sheetId, this.getters),
32882
- dataSource: this.dataSource && this.dataSourceBuilder.getDefinition(this.dataSource, this.sheetId, this.getters)
32883
- };
32884
- }
32885
- updateRanges(rangeAdapters) {
32886
- return {
32887
- ...this.chartTypeBuilder.updateRanges(this.definition, rangeAdapters, this.sheetId),
32888
- dataSource: this.dataSource && this.dataSourceBuilder.adaptRanges(this.dataSource, rangeAdapters)
32889
- };
32890
- }
32891
- duplicateInDuplicatedSheet(sheetIdFrom, sheetIdTo) {
32892
- const newDataSource = this.dataSource && this.dataSourceBuilder.duplicateInDuplicatedSheet(this.dataSource, sheetIdFrom, sheetIdTo, this.getters);
32893
- const definition = {
32894
- ...this.chartTypeBuilder.duplicateInDuplicatedSheet(this.definition, sheetIdFrom, sheetIdTo, this.getters),
32895
- dataSource: newDataSource
32896
- };
32897
- return SpreadsheetChart.fromDefinition(this.getters, sheetIdTo, definition).getDefinition();
32898
- }
32899
- copyInSheetId(sheetIdTo) {
32900
- return {
32901
- ...this.chartTypeBuilder.copyInSheetId(this.definition, this.sheetId, sheetIdTo, this.getters),
32902
- dataSource: this.dataSource
32903
- };
32904
- }
32905
- getContextCreation() {
32906
- const definition = this.getDefinition();
32907
- return {
32908
- ...this.dataSourceBuilder.getContextCreation(definition.dataSource ?? { type: "none" }),
32909
- ...this.chartTypeBuilder.getContextCreation(definition, this.dataSourceBuilder, definition.dataSource)
32910
- };
32911
- }
32912
- getDefinitionForExcel(getters) {
32913
- const definition = this.definition;
32914
- const excelDataSets = this.dataSourceBuilder.toExcelDataSets(this.dataSource, "dataSetStyles" in definition ? definition.dataSetStyles : {}, getters);
32915
- if (excelDataSets === void 0) return;
32916
- return this.chartTypeBuilder.getDefinitionForExcel(getters, definition, excelDataSets);
32917
- }
32918
- getData(getters, chartId) {
32919
- const dataSource = this.dataSource;
32920
- return dataSource ? this.dataSourceBuilder.extractData(dataSource, chartId, getters) : {
32921
- dataSetsValues: [],
32922
- labelValues: []
32923
- };
32924
- }
32925
- getRuntime(getters, chartId) {
32926
- const dataSource = this.dataSource;
32927
- const dataExtractors = dataSource ? {
32928
- extractData: () => this.dataSourceBuilder.extractData(dataSource, chartId, getters),
32929
- extractHierarchicalData: () => this.dataSourceBuilder.extractHierarchicalData(dataSource, chartId, getters)
32930
- } : {
32931
- extractData: () => ({
32932
- dataSetsValues: [],
32933
- labelValues: []
32934
- }),
32935
- extractHierarchicalData: () => ({
32936
- dataSetsValues: [],
32937
- labelValues: []
32938
- })
32939
- };
32940
- return this.chartTypeBuilder.getRuntime(getters, this.definition, dataExtractors, this.sheetId, {
32941
- onClick: (event, items, chartJsChart) => {
32942
- return this.dataSourceBuilder.onDataSetClick?.(this.definition.type, chartId, event, items, chartJsChart, getters);
32943
- },
32944
- onHover: (event, items, chartJsChart) => this.dataSourceBuilder.onDataSetHover?.(this.definition.type, chartId, event, items, chartJsChart)
32945
- });
32946
- }
32947
- static deleteInvalidKeys(definition) {
32948
- definition = { ...definition };
32949
- const keys = new Set(chartTypeRegistry.get(definition.type).allowedDefinitionKeys);
32950
- for (const key of Object.keys(definition)) if (!keys.has(key)) delete definition[key];
32951
- return definition;
32952
- }
32953
- };
32954
-
32955
- //#endregion
32956
- //#region src/helpers/figures/charts/chart_data_sources.ts
32957
- const EMPTY = Object.freeze({ value: null });
32958
- const ONE = Object.freeze({ value: 1 });
32959
- const ChartRangeDataSourceHandler = {
32960
- supportedChartTypes: CHART_TYPES,
32961
- fromExternalDefinition(dataSource, defaultSheetId, getters) {
32962
- const dataSets = createDataSets(getters, defaultSheetId, dataSource);
32963
- const labelRange = createValidRange(getters, defaultSheetId, dataSource.labelRange);
32964
- return {
32965
- ...dataSource,
32966
- dataSets,
32967
- labelRange
32968
- };
32969
- },
32970
- fromContextCreation(context) {
32971
- return {
32972
- type: "range",
32973
- dataSets: [],
32974
- dataSetsHaveTitle: false,
32975
- labelRange: context.auxiliaryRange,
32976
- ...context.dataSource
32977
- };
32978
- },
32979
- fromHierarchicalContextCreation(context) {
32980
- if (context.dataSource?.type !== "range" || context.hierarchicalDataSource !== void 0 && context.hierarchicalDataSource.type !== "range") return {
32981
- type: "range",
32982
- dataSets: [],
32983
- dataSetsHaveTitle: false
32984
- };
32985
- let dataSource = {
32986
- type: "range",
32987
- dataSets: [],
32988
- dataSetsHaveTitle: context.dataSource?.dataSetsHaveTitle ?? false,
32989
- labelRange: context.dataSource?.dataSets?.[0]?.dataRange
32990
- };
32991
- if (context.hierarchicalDataSource?.dataSets.length) dataSource = context.hierarchicalDataSource;
32992
- else if (context.auxiliaryRange) dataSource = {
32993
- ...dataSource,
32994
- dataSets: [{
32995
- dataRange: context.auxiliaryRange,
32996
- dataSetId: "0"
32997
- }]
32998
- };
32999
- return dataSource;
33000
- },
33001
- validate: (dataSource, validator) => validator.checkValidations(dataSource, checkDataset, checkLabelRange),
33002
- transform(dataSource, defaultSheetId, { adaptRangeString }) {
33003
- let labelRange;
33004
- if (dataSource.labelRange) {
33005
- const { changeType, range: adaptedRange } = adaptRangeString(defaultSheetId, dataSource.labelRange);
33006
- if (changeType !== "REMOVE") labelRange = adaptedRange;
33007
- }
33008
- const dataSets = [];
33009
- for (const dataSet of dataSource.dataSets) {
33010
- const newDataSet = { ...dataSet };
33011
- const { changeType, range: adaptedRange } = adaptRangeString(defaultSheetId, dataSet.dataRange);
33012
- if (changeType !== "REMOVE") {
33013
- newDataSet.dataRange = adaptedRange;
33014
- dataSets.push(newDataSet);
33015
- }
33016
- }
33017
- return {
33018
- ...dataSource,
33019
- dataSets,
33020
- labelRange
33021
- };
33022
- },
33023
- extractData: (dataSource, chartId, getters) => getChartData(getters, dataSource),
33024
- extractHierarchicalData(dataSource, chartId, getters) {
33025
- const dataSets = dataSource.dataSets;
33026
- const labelRange = dataSource.labelRange;
33027
- const labelValues = getChartLabelValues(getters, dataSets, labelRange);
33028
- const dataSetsValues = getHierarchicalDatasetValues(getters, dataSets);
33029
- const data = {
33030
- labelValues,
33031
- dataSetsValues
33032
- };
33033
- if (shouldRemoveFirstLabel(labelValues.length, dataSetsValues[0]?.data.length + (dataSetsValues[0]?.label !== void 0 ? 1 : 0), dataSource.dataSetsHaveTitle || false)) labelValues.shift();
33034
- return data;
33035
- },
33036
- adaptRanges(dataSource, { applyChange }) {
33037
- const dataSetsWithUndefined = dataSource.dataSets.map((ds) => {
33038
- const { range: adaptedRangeStr, changeType } = applyChange(ds.dataRange);
33039
- if (changeType === "REMOVE") return;
33040
- let labelCell = void 0;
33041
- if (ds.labelCell) {
33042
- const { range: adaptedLabelCellRange, changeType: labelCellChangeType } = applyChange(ds.labelCell);
33043
- if (labelCellChangeType !== "REMOVE") labelCell = adaptedLabelCellRange;
33044
- }
33045
- return {
33046
- ...ds,
33047
- dataRange: adaptedRangeStr,
33048
- labelCell
33049
- };
33050
- }).filter(isDefined);
33051
- let labelRange = dataSource.labelRange;
33052
- if (labelRange) {
33053
- const { range: adaptedLabelRange, changeType } = applyChange(labelRange);
33054
- if (changeType === "REMOVE") labelRange = void 0;
33055
- else labelRange = adaptedLabelRange;
33056
- }
33057
- const dataSets = dataSetsWithUndefined;
33058
- return {
33059
- ...dataSource,
33060
- dataSets,
33061
- labelRange: labelRange?.invalidSheetName || labelRange?.invalidXc ? void 0 : labelRange
33062
- };
33063
- },
33064
- getDefinition(dataSource, defaultSheetId, getters) {
33065
- return {
33066
- labelRange: dataSource.labelRange ? getters.getRangeString(dataSource.labelRange, defaultSheetId) : void 0,
33067
- type: "range",
33068
- dataSets: dataSource.dataSets.map((dataSet) => ({
33069
- dataSetId: dataSet.dataSetId,
33070
- dataRange: getters.getRangeString(dataSet.dataRange, defaultSheetId)
33071
- })),
33072
- dataSetsHaveTitle: dataSource.dataSetsHaveTitle
33073
- };
33074
- },
33075
- /**
33076
- * Duplicate the dataSets. All ranges on sheetIdFrom are adapted to target
33077
- * sheetIdTo.
33078
- */
33079
- duplicateInDuplicatedSheet(dataSource, sheetIdFrom, sheetIdTo, getters) {
33080
- return {
33081
- ...dataSource,
33082
- labelRange: duplicateLabelRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, dataSource.labelRange),
33083
- dataSets: dataSource.dataSets.map((ds) => ({
33084
- ...ds,
33085
- dataRange: duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, ds.dataRange)
33086
- }))
33087
- };
33088
- },
33089
- getContextCreation: (dataSource) => ({
33090
- auxiliaryRange: dataSource.labelRange,
33091
- dataSource
33092
- }),
33093
- getHierarchicalContextCreation(dataSource) {
33094
- const leafRange = dataSource.dataSets.at(-1)?.dataRange;
33095
- const dataSetsHaveTitle = dataSource.dataSetsHaveTitle;
33096
- return {
33097
- auxiliaryRange: leafRange,
33098
- hierarchicalDataSource: dataSource,
33099
- dataSource: dataSource.labelRange ? {
33100
- type: "range",
33101
- dataSets: [{
33102
- dataRange: dataSource.labelRange,
33103
- dataSetId: "0"
33104
- }],
33105
- dataSetsHaveTitle
33106
- } : {
33107
- type: "range",
33108
- dataSets: [],
33109
- dataSetsHaveTitle
33110
- }
33111
- };
33112
- },
33113
- toExcelDataSets(dataSource, dataSetStyles, getters) {
33114
- const dataSets = dataSource.dataSets;
33115
- const labelRange = dataSource.labelRange;
33116
- const excelDataSets = dataSets.map((ds) => toExcelDataset(getters, dataSetStyles, ds)).filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
33117
- const datasetLength = dataSets[0] ? getZoneArea(dataSets[0].dataRange.zone) : void 0;
33118
- return {
33119
- dataSets: excelDataSets,
33120
- labelRange: toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel(labelRange ? getZoneArea(labelRange.zone) : 0, datasetLength, dataSource.dataSetsHaveTitle))
33121
- };
33122
- }
33123
- };
33124
- function getChartData(getters, dataSource) {
33125
- const dataSets = dataSource.dataSets;
33126
- const labelRange = dataSource.labelRange;
33127
- const labelValues = getChartLabelValues(getters, dataSets, labelRange);
33128
- const dataSetsValues = getChartDatasetValues(getters, dataSets);
33129
- const data = {
33130
- labelValues,
33131
- dataSetsValues
33132
- };
33133
- const numberOfDataPoints = dataSetsValues.length ? dataSetsValues[0]?.data.length + (dataSetsValues[0]?.label !== void 0 ? 1 : 0) : 0;
33134
- if (shouldRemoveFirstLabel(labelValues.length, numberOfDataPoints, dataSource.dataSetsHaveTitle || false)) labelValues.shift();
33135
- return data;
33136
- }
33137
- function getChartDatasetValues(getters, dataSets) {
33138
- const datasetValues = [];
33139
- for (const [dsIndex, ds] of Object.entries(dataSets)) {
33140
- let label = `${ChartTerms.Series} ${parseInt(dsIndex) + 1}`;
33141
- let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
33142
- if (ds.labelCell) {
33143
- const { sheetId, zone } = ds.labelCell;
33144
- const cell = getters.getEvaluatedCell({
33145
- sheetId,
33146
- col: zone.left,
33147
- row: zone.top
33148
- });
33149
- if (cell) label = cell.formattedValue;
33150
- }
33151
- let data = ds.dataRange ? getData(getters, ds) : [];
33152
- if (data.every((cell) => !cell.value || isTextResult(cell)) && data.filter(isTextResult).length > 1) data = data.map((cell) => cell.value && !isErrorResult(cell) ? ONE : EMPTY);
33153
- else if (data.every((cell) => !isNumberResult(cell))) hidden = true;
33154
- datasetValues.push({
33155
- data,
33156
- label,
33157
- hidden,
33158
- dataSetId: ds.dataSetId
33159
- });
33160
- }
33161
- return datasetValues;
33162
- }
33163
- function getChartLabelValues(getters, dataSets, labelRange) {
33164
- if (labelRange) {
33165
- const { left } = labelRange.zone;
33166
- if (!labelRange.invalidXc && !labelRange.invalidSheetName && !getters.isColHidden(labelRange.sheetId, left)) return getters.getVisibleRangeValues(labelRange);
33167
- }
33168
- if (dataSets[0]) {
33169
- const dataLength = getData(getters, dataSets[0]).length;
33170
- return Array.from({ length: dataLength }, () => ({ value: "" }));
33171
- }
33172
- return [];
33173
- }
33174
- /**
33175
- * Get the values for a hierarchical dataset. The values can be defined in a tree-like structure
33176
- * in the sheet, and this function will fill up the blanks.
33177
- *
33178
- * @example the following dataset:
33179
- *
33180
- * 2024 Q1 W1 100
33181
- * W2 200
33182
- *
33183
- * will have the same value as the dataset:
33184
- * 2024 Q1 W1 100
33185
- * 2024 Q1 W2 200
33186
- */
33187
- function getHierarchicalDatasetValues(getters, dataSets) {
33188
- dataSets = dataSets.filter((ds) => !getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left));
33189
- const datasetValues = dataSets.map((ds) => ({
33190
- data: [],
33191
- label: "",
33192
- dataSetId: ds.dataSetId
33193
- }));
33194
- const locale = getters.getLocale();
33195
- const dataSetsData = dataSets.map((ds) => getData(getters, ds)).map((values) => values.map(({ value, format }) => value === null ? EMPTY : { value: formatValue(value, {
33196
- format,
33197
- locale
33198
- }) }));
33199
- if (!dataSetsData.length) return datasetValues;
33200
- const minLength = Math.min(...dataSetsData.map((ds) => ds.length));
33201
- let currentValues = [];
33202
- const leafDatasetIndex = dataSets.length - 1;
33203
- for (let i = 0; i < minLength; i++) for (let dsIndex = 0; dsIndex < dataSetsData.length; dsIndex++) {
33204
- let cell = dataSetsData[dsIndex][i];
33205
- if ((cell === void 0 || cell.value === null) && dsIndex !== leafDatasetIndex) cell = currentValues[dsIndex];
33206
- if (cell?.value !== currentValues[dsIndex]?.value) {
33207
- currentValues = currentValues.slice(0, dsIndex);
33208
- currentValues[dsIndex] = cell;
33209
- }
33210
- datasetValues[dsIndex].data.push(cell ?? EMPTY);
33211
- }
33212
- return datasetValues.filter((ds) => ds.data.some((d) => d.value !== null));
33213
- }
33214
- /**
33215
- * Get the data from a dataSet
33216
- */
33217
- function getData(getters, ds) {
33218
- if (ds.dataRange) {
33219
- const labelCellZone = ds.labelCell ? [ds.labelCell.zone] : [];
33220
- const dataZone = recomputeZones([ds.dataRange.zone], labelCellZone)[0];
33221
- if (dataZone === void 0) return [];
33222
- const dataRange = getters.getRangeFromZone(ds.dataRange.sheetId, dataZone);
33223
- return getters.getVisibleRangeValues(dataRange).map((cell) => cell.value === "" ? EMPTY : cell);
33224
- }
33225
- return [];
33226
- }
33227
- const ChartNeverDataSourceHandler = {
33228
- supportedChartTypes: [],
33229
- fromExternalDefinition: () => ({ type: "none" }),
33230
- fromContextCreation: () => ({ type: "none" }),
33231
- fromHierarchicalContextCreation: () => ({ type: "none" }),
33232
- validate: () => "Success",
33233
- transform: () => ({ type: "none" }),
33234
- extractData: () => ({
33235
- dataSetsValues: [],
33236
- labelValues: []
33237
- }),
33238
- extractHierarchicalData: () => ({
33239
- dataSetsValues: [],
33240
- labelValues: []
33241
- }),
33242
- adaptRanges: (dataSource) => dataSource,
33243
- getDefinition: (dataSource) => dataSource,
33244
- duplicateInDuplicatedSheet: (dataSource) => dataSource,
33245
- getContextCreation: () => ({}),
33246
- getHierarchicalContextCreation: () => ({}),
33247
- toExcelDataSets: () => ({
33248
- dataSets: [],
33249
- labelRange: void 0
33250
- })
33251
- };
33252
- chartDataSourceRegistry.add("range", ChartRangeDataSourceHandler);
33253
- chartDataSourceRegistry.add("none", ChartNeverDataSourceHandler);
33254
-
33255
32828
  //#endregion
33256
32829
  //#region src/types/chart/calendar_chart.ts
33257
32830
  const CALENDAR_CHART_GRANULARITIES = [
@@ -33278,41 +32851,6 @@ var CalendarChartConfigPanel = class extends GenericChartConfigPanel {
33278
32851
  value,
33279
32852
  label: ALL_PERIODS[value]
33280
32853
  }));
33281
- getGroupByOptions() {
33282
- const sheetId = this.env.model.getters.getFigureSheetId(this.env.model.getters.getFigureIdFromChartId(this.props.chartId));
33283
- const definition = SpreadsheetChart.fromStrDefinition(this.env.model.getters, sheetId, this.props.definition).getRangeDefinition();
33284
- const labels = getBarChartData(definition, getChartData(this.env.model.getters, definition.dataSource), this.env.model.getters).labels.filter((l) => isDateTime(l, DEFAULT_LOCALE));
33285
- if (labels.length === 0) return [];
33286
- const dates = labels.map((label) => toJsDate(label, this.env.model.getters.getLocale()));
33287
- const uniqueYears = /* @__PURE__ */ new Set();
33288
- const uniqueMonths = /* @__PURE__ */ new Set();
33289
- const uniqueDays = /* @__PURE__ */ new Set();
33290
- const uniqueHours = /* @__PURE__ */ new Set();
33291
- const uniqueMinutes = /* @__PURE__ */ new Set();
33292
- const uniqueSeconds = /* @__PURE__ */ new Set();
33293
- for (const date of dates) {
33294
- uniqueYears.add(date.getFullYear());
33295
- uniqueMonths.add(date.getMonth());
33296
- uniqueDays.add(date.getDate());
33297
- uniqueHours.add(date.getHours());
33298
- uniqueMinutes.add(date.getMinutes());
33299
- uniqueSeconds.add(date.getSeconds());
33300
- }
33301
- return this.groupByChoices.filter((groupBy) => {
33302
- switch (groupBy.value) {
33303
- case "year": return uniqueYears.size > 1;
33304
- case "quarter_number":
33305
- case "month_number": return uniqueMonths.size > 1;
33306
- case "iso_week_number":
33307
- case "day_of_month":
33308
- case "day_of_week": return uniqueDays.size > 1;
33309
- case "hour_number": return uniqueHours.size > 1;
33310
- case "minute_number": return uniqueMinutes.size > 1;
33311
- case "second_number": return uniqueSeconds.size > 1;
33312
- default: return false;
33313
- }
33314
- });
33315
- }
33316
32854
  getGroupByType(currentAxis) {
33317
32855
  return (currentAxis === "horizontal" ? this.props.definition.horizontalGroupBy : this.props.definition.verticalGroupBy) || "year";
33318
32856
  }
@@ -34518,6 +34056,133 @@ var ChartTypePicker = class extends Component {
34518
34056
  }
34519
34057
  };
34520
34058
 
34059
+ //#endregion
34060
+ //#region src/helpers/figures/chart.ts
34061
+ var SpreadsheetChart = class SpreadsheetChart {
34062
+ getters;
34063
+ sheetId;
34064
+ definition;
34065
+ chartTypeBuilder;
34066
+ dataSourceBuilder;
34067
+ dataSource;
34068
+ constructor(getters, sheetId, definition, chartTypeBuilder, dataSourceBuilder) {
34069
+ this.getters = getters;
34070
+ this.sheetId = sheetId;
34071
+ this.definition = definition;
34072
+ this.chartTypeBuilder = chartTypeBuilder;
34073
+ this.dataSourceBuilder = dataSourceBuilder;
34074
+ this.dataSource = definition.dataSource;
34075
+ }
34076
+ static fromStrDefinition(getters, sheetId, definition) {
34077
+ const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
34078
+ const chartTypeBuilder = chartTypeRegistry.get(definition.type);
34079
+ const dataSource = dataSourceBuilder.fromExternalDefinition(definition.dataSource ?? { type: "none" }, sheetId, getters);
34080
+ const rangeDefinition = {
34081
+ ...chartTypeBuilder.fromStrDefinition(definition, sheetId, getters),
34082
+ dataSource
34083
+ };
34084
+ return new SpreadsheetChart(getters, sheetId, SpreadsheetChart.deleteInvalidKeys(rangeDefinition), chartTypeBuilder, dataSourceBuilder);
34085
+ }
34086
+ static fromDefinition(getters, sheetId, definition) {
34087
+ const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
34088
+ return new SpreadsheetChart(getters, sheetId, definition, chartTypeRegistry.get(definition.type), dataSourceBuilder);
34089
+ }
34090
+ static validate(validator, definition) {
34091
+ const chartTypeBuilder = chartTypeRegistry.get(definition.type);
34092
+ const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
34093
+ return validator.batchValidations(() => chartTypeBuilder.validateDefinition(validator, definition), () => dataSourceBuilder.validate(definition.dataSource ?? { type: "none" }, validator))(void 0);
34094
+ }
34095
+ static transformDefinition(chartSheetId, definition, rangeAdapters) {
34096
+ const chartTypeBuilder = chartTypeRegistry.get(definition.type);
34097
+ if (!definition.dataSource) return chartTypeBuilder.transformDefinition(definition, chartSheetId, rangeAdapters);
34098
+ const newDataSource = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none").transform(definition.dataSource, chartSheetId, rangeAdapters);
34099
+ return {
34100
+ ...chartTypeBuilder.transformDefinition(definition, chartSheetId, rangeAdapters),
34101
+ dataSource: newDataSource
34102
+ };
34103
+ }
34104
+ getRangeDefinition() {
34105
+ return {
34106
+ ...this.definition,
34107
+ dataSource: this.dataSource
34108
+ };
34109
+ }
34110
+ getDefinition() {
34111
+ return {
34112
+ ...this.chartTypeBuilder.toStrDefinition(this.definition, this.sheetId, this.getters),
34113
+ dataSource: this.dataSource && this.dataSourceBuilder.getDefinition(this.dataSource, this.sheetId, this.getters)
34114
+ };
34115
+ }
34116
+ updateRanges(rangeAdapters) {
34117
+ return {
34118
+ ...this.chartTypeBuilder.updateRanges(this.definition, rangeAdapters, this.sheetId),
34119
+ dataSource: this.dataSource && this.dataSourceBuilder.adaptRanges(this.dataSource, rangeAdapters)
34120
+ };
34121
+ }
34122
+ duplicateInDuplicatedSheet(sheetIdFrom, sheetIdTo) {
34123
+ const newDataSource = this.dataSource && this.dataSourceBuilder.duplicateInDuplicatedSheet(this.dataSource, sheetIdFrom, sheetIdTo, this.getters);
34124
+ const definition = {
34125
+ ...this.chartTypeBuilder.duplicateInDuplicatedSheet(this.definition, sheetIdFrom, sheetIdTo, this.getters),
34126
+ dataSource: newDataSource
34127
+ };
34128
+ return SpreadsheetChart.fromDefinition(this.getters, sheetIdTo, definition).getDefinition();
34129
+ }
34130
+ copyInSheetId(sheetIdTo) {
34131
+ return {
34132
+ ...this.chartTypeBuilder.copyInSheetId(this.definition, this.sheetId, sheetIdTo, this.getters),
34133
+ dataSource: this.dataSource
34134
+ };
34135
+ }
34136
+ getContextCreation() {
34137
+ const definition = this.getDefinition();
34138
+ return {
34139
+ ...this.dataSourceBuilder.getContextCreation(definition.dataSource ?? { type: "none" }),
34140
+ ...this.chartTypeBuilder.getContextCreation(definition, this.dataSourceBuilder, definition.dataSource)
34141
+ };
34142
+ }
34143
+ getDefinitionForExcel(getters) {
34144
+ const definition = this.definition;
34145
+ const excelDataSets = this.dataSourceBuilder.toExcelDataSets(this.dataSource, "dataSetStyles" in definition ? definition.dataSetStyles : {}, getters);
34146
+ if (excelDataSets === void 0) return;
34147
+ return this.chartTypeBuilder.getDefinitionForExcel(getters, definition, excelDataSets);
34148
+ }
34149
+ getData(getters, chartId) {
34150
+ const dataSource = this.dataSource;
34151
+ return dataSource ? this.dataSourceBuilder.extractData(dataSource, chartId, getters) : {
34152
+ dataSetsValues: [],
34153
+ labelValues: []
34154
+ };
34155
+ }
34156
+ getRuntime(getters, chartId) {
34157
+ const dataSource = this.dataSource;
34158
+ const dataExtractors = dataSource ? {
34159
+ extractData: () => this.dataSourceBuilder.extractData(dataSource, chartId, getters),
34160
+ extractHierarchicalData: () => this.dataSourceBuilder.extractHierarchicalData(dataSource, chartId, getters)
34161
+ } : {
34162
+ extractData: () => ({
34163
+ dataSetsValues: [],
34164
+ labelValues: []
34165
+ }),
34166
+ extractHierarchicalData: () => ({
34167
+ dataSetsValues: [],
34168
+ labelValues: []
34169
+ })
34170
+ };
34171
+ return this.chartTypeBuilder.getRuntime(getters, this.definition, dataExtractors, this.sheetId, {
34172
+ onClick: (event, items, chartJsChart) => {
34173
+ return this.dataSourceBuilder.onDataSetClick?.(this.definition.type, chartId, event, items, chartJsChart, getters);
34174
+ },
34175
+ onHover: (event, items, chartJsChart) => this.dataSourceBuilder.onDataSetHover?.(this.definition.type, chartId, event, items, chartJsChart)
34176
+ });
34177
+ }
34178
+ static deleteInvalidKeys(definition) {
34179
+ definition = { ...definition };
34180
+ const keys = new Set(chartTypeRegistry.get(definition.type).allowedDefinitionKeys);
34181
+ for (const key of Object.keys(definition)) if (!keys.has(key)) delete definition[key];
34182
+ return definition;
34183
+ }
34184
+ };
34185
+
34521
34186
  //#endregion
34522
34187
  //#region src/components/side_panel/chart/main_chart_panel/main_chart_panel_store.ts
34523
34188
  var MainChartPanelStore = class extends SpreadsheetStore {
@@ -36506,7 +36171,7 @@ var FindAndReplacePanel = class extends Component {
36506
36171
  }
36507
36172
  get specificRangeMatchesCount() {
36508
36173
  const range = this.searchOptions.specificRange;
36509
- if (!range) return "";
36174
+ if (!range || range.invalidSheetName || range.invalidXc) return "";
36510
36175
  const { sheetId, zone } = range;
36511
36176
  return _t("%(matches)s matches in range %(range)s of %(sheetName)s", {
36512
36177
  matches: this.store.specificRangeMatchesCount,
@@ -46135,6 +45800,11 @@ var GridOverlay = class extends Component {
46135
45800
  });
46136
45801
  return icon?.onClick ? icon : void 0;
46137
45802
  }
45803
+ get isFooterVisible() {
45804
+ const { y } = this.env.model.getters.getMainViewportCoordinates();
45805
+ const { height } = this.env.model.getters.getSheetViewDimension();
45806
+ return !this.env.model.getters.isReadonly() && height - y > 46;
45807
+ }
46138
45808
  };
46139
45809
 
46140
45810
  //#endregion
@@ -54618,7 +54288,7 @@ var CompilationParametersBuilder = class {
54618
54288
  if (rangeError) return [[rangeError]];
54619
54289
  const sheetId = range.sheetId;
54620
54290
  const zone = range.zone;
54621
- const _zone = intersection(zone, this.getters.getSheetZone(sheetId));
54291
+ const _zone = this.getters.clipRangeToSheet(range)?.zone;
54622
54292
  if (!_zone) return [[]];
54623
54293
  const { top, left, bottom, right } = zone;
54624
54294
  const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
@@ -55601,10 +55271,10 @@ var Evaluator = class {
55601
55271
  updateDependencies(position) {
55602
55272
  this.formulaDependencies().removeAllDependencies(position);
55603
55273
  const dependencies = this.getDirectDependencies(position);
55604
- this.formulaDependencies().addDependencies(position, dependencies);
55274
+ this.formulaDependencies().addDependencies(position, this.getters.clipRangesToSheet(dependencies));
55605
55275
  }
55606
55276
  addDependencies(position, dependencies) {
55607
- this.formulaDependencies().addDependencies(position, dependencies);
55277
+ this.formulaDependencies().addDependencies(position, this.getters.clipRangesToSheet(dependencies));
55608
55278
  this.computeDependencies(dependencies);
55609
55279
  }
55610
55280
  computeDependencies(dependencies) {
@@ -55666,7 +55336,8 @@ var Evaluator = class {
55666
55336
  const graph = new FormulaDependencyGraph();
55667
55337
  for (const sheetId of this.getters.getSheetIds()) for (const cell of this.getters.getCells(sheetId)) if (cell.isFormula) {
55668
55338
  const cellPosition = this.getters.getCellPosition(cell.id);
55669
- graph.addDependencies(cellPosition, cell.compiledFormula.rangeDependencies);
55339
+ const dependencies = this.getters.clipRangesToSheet(cell.compiledFormula.rangeDependencies);
55340
+ graph.addDependencies(cellPosition, dependencies);
55670
55341
  }
55671
55342
  return graph;
55672
55343
  });
@@ -61431,7 +61102,8 @@ var GeoFeaturePlugin = class extends UIPlugin {
61431
61102
  "getGeoJsonFeatures",
61432
61103
  "geoFeatureNameToId",
61433
61104
  "getGeoChartAvailableRegions",
61434
- "getAvailableChartRegions"
61105
+ "getAvailableChartRegions",
61106
+ "loadUsedGeoJsonFeatures"
61435
61107
  ];
61436
61108
  geoJsonService;
61437
61109
  geoJsonCache = {};
@@ -61514,6 +61186,23 @@ var GeoFeaturePlugin = class extends UIPlugin {
61514
61186
  }
61515
61187
  return this.geoJsonService.geoFeatureNameToId(region, featureName);
61516
61188
  }
61189
+ loadUsedGeoJsonFeatures() {
61190
+ const regions = this.getters.getSheetIds().flatMap((sheetId) => this.getters.getChartIds(sheetId).map((chartId) => {
61191
+ const definition = this.getters.getChartDefinition(chartId);
61192
+ return definition.type === "geo" ? definition.region || this.getters.getGeoChartAvailableRegions()[0]?.id : void 0;
61193
+ })).filter(isDefined);
61194
+ const uniqueRegions = Array.from(new Set(regions));
61195
+ if (uniqueRegions.length && !this.geoJsonService) {
61196
+ console.error("No geoJsonService provided to the model");
61197
+ return Promise.resolve();
61198
+ }
61199
+ for (const region of uniqueRegions) this.getGeoJsonFeatures(region);
61200
+ const promises = uniqueRegions.map((region) => {
61201
+ const cachedGeoJson = this.geoJsonCache[region];
61202
+ return cachedGeoJson instanceof Promise ? cachedGeoJson : Promise.resolve();
61203
+ });
61204
+ return Promise.all(promises).then(() => {});
61205
+ }
61517
61206
  convertToGeoJson(json) {
61518
61207
  if (!json) return null;
61519
61208
  if (json.type === "Topology") {
@@ -64575,7 +64264,7 @@ var InternalViewport = class {
64575
64264
  let height = lastRowEnd - this.offsetCorrectionY;
64576
64265
  if (this.canScrollVertically) {
64577
64266
  height = Math.max(height, this.viewportHeight);
64578
- if (lastRowEnd + 46 > height && !this.getters.isReadonly()) height += 46;
64267
+ if (lastRowEnd + 46 > height && !this.getters.isReadonly() && this.viewportHeight > 46) height += 46;
64579
64268
  }
64580
64269
  return {
64581
64270
  width,
@@ -69022,12 +68711,11 @@ var SpreadsheetPrintStore = class extends SpreadsheetStore {
69022
68711
  const { width: printWidth, height: printHeight } = this.pageDimensionWithMargins;
69023
68712
  const start = dimension === "COL" ? printZone.left : printZone.top;
69024
68713
  const end = dimension === "COL" ? printZone.right : printZone.bottom;
69025
- const getHeaderSize = dimension === "COL" ? this.getters.getColDimensions : this.getters.getRowDimensions;
69026
68714
  const max = dimension === "COL" ? printWidth : printHeight;
69027
68715
  const breaks = [];
69028
68716
  let current = 0;
69029
68717
  for (let i = start; i <= end; i++) {
69030
- const headerSize = getHeaderSize(sheetId, i).size * zoom;
68718
+ const headerSize = this.getters.getHeaderSize(sheetId, dimension, i) * zoom;
69031
68719
  current += headerSize;
69032
68720
  if (current >= max) {
69033
68721
  breaks.push(i);
@@ -71512,6 +71200,8 @@ var RangeAdapterPlugin = class {
71512
71200
  "extendRange",
71513
71201
  "getRangeString",
71514
71202
  "getRangeFromSheetXC",
71203
+ "clipRangesToSheet",
71204
+ "clipRangeToSheet",
71515
71205
  "createAdaptedRanges",
71516
71206
  "getRangeData",
71517
71207
  "getRangeDataFromXc",
@@ -71550,6 +71240,22 @@ var RangeAdapterPlugin = class {
71550
71240
  addRangeProvider(provider) {
71551
71241
  this.providers.push(provider);
71552
71242
  }
71243
+ clipRangeToSheet(range) {
71244
+ if (range.invalidXc) return range;
71245
+ const sheetZone = this.getters.getSheetZone(range.sheetId);
71246
+ if (isZoneInside(range.zone, sheetZone)) return range;
71247
+ const newZone = intersection(range.zone, sheetZone);
71248
+ if (!newZone) return;
71249
+ return this.getters.getRangeFromZone(range.sheetId, newZone);
71250
+ }
71251
+ clipRangesToSheet(ranges) {
71252
+ const clippedRanges = [];
71253
+ for (const range of ranges) {
71254
+ const clippedRange = this.clipRangeToSheet(range);
71255
+ if (clippedRange) clippedRanges.push(clippedRange);
71256
+ }
71257
+ return clippedRanges;
71258
+ }
71553
71259
  createAdaptedRanges(ranges, offsetX, offsetY, sheetId) {
71554
71260
  return ranges.map((range) => {
71555
71261
  if (!isZoneValid(range.zone)) return range;
@@ -74747,6 +74453,8 @@ var Model = class Model extends EventBus {
74747
74453
  this.range = new RangeAdapterPlugin(this.coreGetters);
74748
74454
  this.coreGetters.getRangeString = this.range.getRangeString.bind(this.range);
74749
74455
  this.coreGetters.getRangeFromSheetXC = this.range.getRangeFromSheetXC.bind(this.range);
74456
+ this.coreGetters.clipRangesToSheet = this.range.clipRangesToSheet.bind(this.range);
74457
+ this.coreGetters.clipRangeToSheet = this.range.clipRangeToSheet.bind(this.range);
74750
74458
  this.coreGetters.createAdaptedRanges = this.range.createAdaptedRanges.bind(this.range);
74751
74459
  this.coreGetters.getRangeData = this.range.getRangeData.bind(this.range);
74752
74460
  this.coreGetters.getRangeDataFromXc = this.range.getRangeDataFromXc.bind(this.range);
@@ -75153,6 +74861,306 @@ function createCommand(type, payload = {}) {
75153
74861
  return command;
75154
74862
  }
75155
74863
 
74864
+ //#endregion
74865
+ //#region src/helpers/figures/charts/chart_data_sources.ts
74866
+ const EMPTY = Object.freeze({ value: null });
74867
+ const ONE = Object.freeze({ value: 1 });
74868
+ const ChartRangeDataSourceHandler = {
74869
+ supportedChartTypes: CHART_TYPES,
74870
+ fromExternalDefinition(dataSource, defaultSheetId, getters) {
74871
+ const dataSets = createDataSets(getters, defaultSheetId, dataSource);
74872
+ const labelRange = createValidRange(getters, defaultSheetId, dataSource.labelRange);
74873
+ return {
74874
+ ...dataSource,
74875
+ dataSets,
74876
+ labelRange
74877
+ };
74878
+ },
74879
+ fromContextCreation(context) {
74880
+ return {
74881
+ type: "range",
74882
+ dataSets: [],
74883
+ dataSetsHaveTitle: false,
74884
+ labelRange: context.auxiliaryRange,
74885
+ ...context.dataSource
74886
+ };
74887
+ },
74888
+ fromHierarchicalContextCreation(context) {
74889
+ if (context.dataSource?.type !== "range" || context.hierarchicalDataSource !== void 0 && context.hierarchicalDataSource.type !== "range") return {
74890
+ type: "range",
74891
+ dataSets: [],
74892
+ dataSetsHaveTitle: false
74893
+ };
74894
+ let dataSource = {
74895
+ type: "range",
74896
+ dataSets: [],
74897
+ dataSetsHaveTitle: context.dataSource?.dataSetsHaveTitle ?? false,
74898
+ labelRange: context.dataSource?.dataSets?.[0]?.dataRange
74899
+ };
74900
+ if (context.hierarchicalDataSource?.dataSets.length) dataSource = context.hierarchicalDataSource;
74901
+ else if (context.auxiliaryRange) dataSource = {
74902
+ ...dataSource,
74903
+ dataSets: [{
74904
+ dataRange: context.auxiliaryRange,
74905
+ dataSetId: "0"
74906
+ }]
74907
+ };
74908
+ return dataSource;
74909
+ },
74910
+ validate: (dataSource, validator) => validator.checkValidations(dataSource, checkDataset, checkLabelRange),
74911
+ transform(dataSource, defaultSheetId, { adaptRangeString }) {
74912
+ let labelRange;
74913
+ if (dataSource.labelRange) {
74914
+ const { changeType, range: adaptedRange } = adaptRangeString(defaultSheetId, dataSource.labelRange);
74915
+ if (changeType !== "REMOVE") labelRange = adaptedRange;
74916
+ }
74917
+ const dataSets = [];
74918
+ for (const dataSet of dataSource.dataSets) {
74919
+ const newDataSet = { ...dataSet };
74920
+ const { changeType, range: adaptedRange } = adaptRangeString(defaultSheetId, dataSet.dataRange);
74921
+ if (changeType !== "REMOVE") {
74922
+ newDataSet.dataRange = adaptedRange;
74923
+ dataSets.push(newDataSet);
74924
+ }
74925
+ }
74926
+ return {
74927
+ ...dataSource,
74928
+ dataSets,
74929
+ labelRange
74930
+ };
74931
+ },
74932
+ extractData: (dataSource, chartId, getters) => getChartData(getters, dataSource),
74933
+ extractHierarchicalData(dataSource, chartId, getters) {
74934
+ const dataSets = dataSource.dataSets;
74935
+ const labelRange = dataSource.labelRange;
74936
+ const labelValues = getChartLabelValues(getters, dataSets, labelRange);
74937
+ const dataSetsValues = getHierarchicalDatasetValues(getters, dataSets);
74938
+ const data = {
74939
+ labelValues,
74940
+ dataSetsValues
74941
+ };
74942
+ if (shouldRemoveFirstLabel(labelValues.length, dataSetsValues[0]?.data.length + (dataSetsValues[0]?.label !== void 0 ? 1 : 0), dataSource.dataSetsHaveTitle || false)) labelValues.shift();
74943
+ return data;
74944
+ },
74945
+ adaptRanges(dataSource, { applyChange }) {
74946
+ const dataSetsWithUndefined = dataSource.dataSets.map((ds) => {
74947
+ const { range: adaptedRangeStr, changeType } = applyChange(ds.dataRange);
74948
+ if (changeType === "REMOVE") return;
74949
+ let labelCell = void 0;
74950
+ if (ds.labelCell) {
74951
+ const { range: adaptedLabelCellRange, changeType: labelCellChangeType } = applyChange(ds.labelCell);
74952
+ if (labelCellChangeType !== "REMOVE") labelCell = adaptedLabelCellRange;
74953
+ }
74954
+ return {
74955
+ ...ds,
74956
+ dataRange: adaptedRangeStr,
74957
+ labelCell
74958
+ };
74959
+ }).filter(isDefined);
74960
+ let labelRange = dataSource.labelRange;
74961
+ if (labelRange) {
74962
+ const { range: adaptedLabelRange, changeType } = applyChange(labelRange);
74963
+ if (changeType === "REMOVE") labelRange = void 0;
74964
+ else labelRange = adaptedLabelRange;
74965
+ }
74966
+ const dataSets = dataSetsWithUndefined;
74967
+ return {
74968
+ ...dataSource,
74969
+ dataSets,
74970
+ labelRange: labelRange?.invalidSheetName || labelRange?.invalidXc ? void 0 : labelRange
74971
+ };
74972
+ },
74973
+ getDefinition(dataSource, defaultSheetId, getters) {
74974
+ return {
74975
+ labelRange: dataSource.labelRange ? getters.getRangeString(dataSource.labelRange, defaultSheetId) : void 0,
74976
+ type: "range",
74977
+ dataSets: dataSource.dataSets.map((dataSet) => ({
74978
+ dataSetId: dataSet.dataSetId,
74979
+ dataRange: getters.getRangeString(dataSet.dataRange, defaultSheetId)
74980
+ })),
74981
+ dataSetsHaveTitle: dataSource.dataSetsHaveTitle
74982
+ };
74983
+ },
74984
+ /**
74985
+ * Duplicate the dataSets. All ranges on sheetIdFrom are adapted to target
74986
+ * sheetIdTo.
74987
+ */
74988
+ duplicateInDuplicatedSheet(dataSource, sheetIdFrom, sheetIdTo, getters) {
74989
+ return {
74990
+ ...dataSource,
74991
+ labelRange: duplicateLabelRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, dataSource.labelRange),
74992
+ dataSets: dataSource.dataSets.map((ds) => ({
74993
+ ...ds,
74994
+ dataRange: duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, ds.dataRange)
74995
+ }))
74996
+ };
74997
+ },
74998
+ getContextCreation: (dataSource) => ({
74999
+ auxiliaryRange: dataSource.labelRange,
75000
+ dataSource
75001
+ }),
75002
+ getHierarchicalContextCreation(dataSource) {
75003
+ const leafRange = dataSource.dataSets.at(-1)?.dataRange;
75004
+ const dataSetsHaveTitle = dataSource.dataSetsHaveTitle;
75005
+ return {
75006
+ auxiliaryRange: leafRange,
75007
+ hierarchicalDataSource: dataSource,
75008
+ dataSource: dataSource.labelRange ? {
75009
+ type: "range",
75010
+ dataSets: [{
75011
+ dataRange: dataSource.labelRange,
75012
+ dataSetId: "0"
75013
+ }],
75014
+ dataSetsHaveTitle
75015
+ } : {
75016
+ type: "range",
75017
+ dataSets: [],
75018
+ dataSetsHaveTitle
75019
+ }
75020
+ };
75021
+ },
75022
+ toExcelDataSets(dataSource, dataSetStyles, getters) {
75023
+ const dataSets = dataSource.dataSets;
75024
+ const labelRange = dataSource.labelRange;
75025
+ const excelDataSets = dataSets.map((ds) => toExcelDataset(getters, dataSetStyles, ds)).filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
75026
+ const datasetLength = dataSets[0] ? getZoneArea(dataSets[0].dataRange.zone) : void 0;
75027
+ return {
75028
+ dataSets: excelDataSets,
75029
+ labelRange: toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel(labelRange ? getZoneArea(labelRange.zone) : 0, datasetLength, dataSource.dataSetsHaveTitle))
75030
+ };
75031
+ }
75032
+ };
75033
+ function getChartData(getters, dataSource) {
75034
+ const dataSets = dataSource.dataSets;
75035
+ const labelRange = dataSource.labelRange;
75036
+ const labelValues = getChartLabelValues(getters, dataSets, labelRange);
75037
+ const dataSetsValues = getChartDatasetValues(getters, dataSets);
75038
+ const data = {
75039
+ labelValues,
75040
+ dataSetsValues
75041
+ };
75042
+ const numberOfDataPoints = dataSetsValues.length ? dataSetsValues[0]?.data.length + (dataSetsValues[0]?.label !== void 0 ? 1 : 0) : 0;
75043
+ if (shouldRemoveFirstLabel(labelValues.length, numberOfDataPoints, dataSource.dataSetsHaveTitle || false)) labelValues.shift();
75044
+ return data;
75045
+ }
75046
+ function getChartDatasetValues(getters, dataSets) {
75047
+ const datasetValues = [];
75048
+ for (const [dsIndex, ds] of Object.entries(dataSets)) {
75049
+ let label = `${ChartTerms.Series} ${parseInt(dsIndex) + 1}`;
75050
+ let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
75051
+ if (ds.labelCell) {
75052
+ const { sheetId, zone } = ds.labelCell;
75053
+ const cell = getters.getEvaluatedCell({
75054
+ sheetId,
75055
+ col: zone.left,
75056
+ row: zone.top
75057
+ });
75058
+ if (cell) label = cell.formattedValue;
75059
+ }
75060
+ let data = ds.dataRange ? getData(getters, ds) : [];
75061
+ if (data.every((cell) => !cell.value || isTextResult(cell)) && data.filter(isTextResult).length > 1) data = data.map((cell) => cell.value && !isErrorResult(cell) ? ONE : EMPTY);
75062
+ else if (data.every((cell) => !isNumberResult(cell))) hidden = true;
75063
+ datasetValues.push({
75064
+ data,
75065
+ label,
75066
+ hidden,
75067
+ dataSetId: ds.dataSetId
75068
+ });
75069
+ }
75070
+ return datasetValues;
75071
+ }
75072
+ function getChartLabelValues(getters, dataSets, labelRange) {
75073
+ if (labelRange) {
75074
+ const { left } = labelRange.zone;
75075
+ if (!labelRange.invalidXc && !labelRange.invalidSheetName && !getters.isColHidden(labelRange.sheetId, left)) return getters.getVisibleRangeValues(labelRange);
75076
+ }
75077
+ if (dataSets[0]) {
75078
+ const dataLength = getData(getters, dataSets[0]).length;
75079
+ return Array.from({ length: dataLength }, () => ({ value: "" }));
75080
+ }
75081
+ return [];
75082
+ }
75083
+ /**
75084
+ * Get the values for a hierarchical dataset. The values can be defined in a tree-like structure
75085
+ * in the sheet, and this function will fill up the blanks.
75086
+ *
75087
+ * @example the following dataset:
75088
+ *
75089
+ * 2024 Q1 W1 100
75090
+ * W2 200
75091
+ *
75092
+ * will have the same value as the dataset:
75093
+ * 2024 Q1 W1 100
75094
+ * 2024 Q1 W2 200
75095
+ */
75096
+ function getHierarchicalDatasetValues(getters, dataSets) {
75097
+ dataSets = dataSets.filter((ds) => !getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left));
75098
+ const datasetValues = dataSets.map((ds) => ({
75099
+ data: [],
75100
+ label: "",
75101
+ dataSetId: ds.dataSetId
75102
+ }));
75103
+ const locale = getters.getLocale();
75104
+ const dataSetsData = dataSets.map((ds) => getData(getters, ds)).map((values) => values.map(({ value, format }) => value === null ? EMPTY : { value: formatValue(value, {
75105
+ format,
75106
+ locale
75107
+ }) }));
75108
+ if (!dataSetsData.length) return datasetValues;
75109
+ const minLength = Math.min(...dataSetsData.map((ds) => ds.length));
75110
+ let currentValues = [];
75111
+ const leafDatasetIndex = dataSets.length - 1;
75112
+ for (let i = 0; i < minLength; i++) for (let dsIndex = 0; dsIndex < dataSetsData.length; dsIndex++) {
75113
+ let cell = dataSetsData[dsIndex][i];
75114
+ if ((cell === void 0 || cell.value === null) && dsIndex !== leafDatasetIndex) cell = currentValues[dsIndex];
75115
+ if (cell?.value !== currentValues[dsIndex]?.value) {
75116
+ currentValues = currentValues.slice(0, dsIndex);
75117
+ currentValues[dsIndex] = cell;
75118
+ }
75119
+ datasetValues[dsIndex].data.push(cell ?? EMPTY);
75120
+ }
75121
+ return datasetValues.filter((ds) => ds.data.some((d) => d.value !== null));
75122
+ }
75123
+ /**
75124
+ * Get the data from a dataSet
75125
+ */
75126
+ function getData(getters, ds) {
75127
+ if (ds.dataRange) {
75128
+ const labelCellZone = ds.labelCell ? [ds.labelCell.zone] : [];
75129
+ const dataZone = recomputeZones([ds.dataRange.zone], labelCellZone)[0];
75130
+ if (dataZone === void 0) return [];
75131
+ const dataRange = getters.getRangeFromZone(ds.dataRange.sheetId, dataZone);
75132
+ return getters.getVisibleRangeValues(dataRange).map((cell) => cell.value === "" ? EMPTY : cell);
75133
+ }
75134
+ return [];
75135
+ }
75136
+ const ChartNeverDataSourceHandler = {
75137
+ supportedChartTypes: [],
75138
+ fromExternalDefinition: () => ({ type: "none" }),
75139
+ fromContextCreation: () => ({ type: "none" }),
75140
+ fromHierarchicalContextCreation: () => ({ type: "none" }),
75141
+ validate: () => "Success",
75142
+ transform: () => ({ type: "none" }),
75143
+ extractData: () => ({
75144
+ dataSetsValues: [],
75145
+ labelValues: []
75146
+ }),
75147
+ extractHierarchicalData: () => ({
75148
+ dataSetsValues: [],
75149
+ labelValues: []
75150
+ }),
75151
+ adaptRanges: (dataSource) => dataSource,
75152
+ getDefinition: (dataSource) => dataSource,
75153
+ duplicateInDuplicatedSheet: (dataSource) => dataSource,
75154
+ getContextCreation: () => ({}),
75155
+ getHierarchicalContextCreation: () => ({}),
75156
+ toExcelDataSets: () => ({
75157
+ dataSets: [],
75158
+ labelRange: void 0
75159
+ })
75160
+ };
75161
+ chartDataSourceRegistry.add("range", ChartRangeDataSourceHandler);
75162
+ chartDataSourceRegistry.add("none", ChartNeverDataSourceHandler);
75163
+
75156
75164
  //#endregion
75157
75165
  //#region src/helpers/figures/charts/calendar_chart.ts
75158
75166
  function checkDateGranularity(definition) {
@@ -84770,6 +84778,6 @@ const chartHelpers = {
84770
84778
  //#endregion
84771
84779
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CompiledFormula, CorePlugin, CoreViewPlugin, DEFAULT_LOCALE, DEFAULT_LOCALES, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, canExecuteInReadonly, categories, chartHelpers, components, constants, convertAstNodes, coreTypes, createAutocompleteArgumentsProvider, findCellInNewZone, functionCache, getCaretDownSvg, getCaretUpSvg, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, isCoreCommand, isSheetDependent, iterateAstNodes, links, load, lockedSheetAllowedCommands, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
84772
84780
 
84773
- __info__.version = "19.3.19";
84774
- __info__.date = "2026-09-04T07:38:14.356Z";
84775
- __info__.hash = "c8c526d";
84781
+ __info__.version = "19.3.20";
84782
+ __info__.date = "2026-09-10T05:38:03.233Z";
84783
+ __info__.hash = "e488e8d";