@odoo/o-spreadsheet 18.5.0-alpha.1 → 18.5.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/o-spreadsheet.cjs.js +439 -135
- package/dist/o-spreadsheet.d.ts +60 -6
- package/dist/o-spreadsheet.esm.js +439 -135
- package/dist/o-spreadsheet.iife.js +439 -135
- package/dist/o-spreadsheet.iife.min.js +456 -401
- package/dist/o_spreadsheet.xml +36 -32
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.5.0-alpha.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.5.0-alpha.3
|
|
6
|
+
* @date 2025-07-28T13:43:05.981Z
|
|
7
|
+
* @hash 53dfee8
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -852,6 +852,7 @@ const specialWhiteSpaceSpecialCharacters = [
|
|
|
852
852
|
];
|
|
853
853
|
const specialWhiteSpaceRegexp = new RegExp(specialWhiteSpaceSpecialCharacters.join("|"), "g");
|
|
854
854
|
const newLineRegexp = /(\r\n|\r)/g;
|
|
855
|
+
const whiteSpaceCharacters = specialWhiteSpaceSpecialCharacters.concat([" "]);
|
|
855
856
|
/**
|
|
856
857
|
* Replace all different newlines characters by \n
|
|
857
858
|
*/
|
|
@@ -1988,8 +1989,9 @@ const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
|
|
|
1988
1989
|
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
|
|
1989
1990
|
const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
|
|
1990
1991
|
const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
|
|
1991
|
-
const
|
|
1992
|
-
const
|
|
1992
|
+
const whiteSpaceChars = whiteSpaceCharacters.join("");
|
|
1993
|
+
const dateSeparatorsRegex = new RegExp(`\/|-|${whiteSpaceCharacters.join("|")}`);
|
|
1994
|
+
const dateRegexp = new RegExp(`^(\\d{1,4})[\/${whiteSpaceChars}\-](\\d{1,4})([\/${whiteSpaceChars}\-](\\d{1,4}))?$`);
|
|
1993
1995
|
const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
|
|
1994
1996
|
/** Convert a value number representing a date, or return undefined if it isn't possible */
|
|
1995
1997
|
function valueToDateNumber(value, locale) {
|
|
@@ -2899,6 +2901,7 @@ const availableConditionalFormatOperators = new Set([
|
|
|
2899
2901
|
"isEmpty",
|
|
2900
2902
|
"isNotEqual",
|
|
2901
2903
|
"isEqual",
|
|
2904
|
+
"customFormula",
|
|
2902
2905
|
]);
|
|
2903
2906
|
|
|
2904
2907
|
const availableDataValidationOperators = new Set([
|
|
@@ -5031,11 +5034,11 @@ function isTextFormat(format) {
|
|
|
5031
5034
|
}
|
|
5032
5035
|
}
|
|
5033
5036
|
|
|
5034
|
-
function evaluateLiteral(literalCell, localeFormat) {
|
|
5037
|
+
function evaluateLiteral(literalCell, localeFormat, position) {
|
|
5035
5038
|
const value = isTextFormat(localeFormat.format) && literalCell.parsedValue !== null
|
|
5036
5039
|
? literalCell.content
|
|
5037
5040
|
: literalCell.parsedValue;
|
|
5038
|
-
const functionResult = { value, format: localeFormat.format };
|
|
5041
|
+
const functionResult = { value, format: localeFormat.format, origin: position };
|
|
5039
5042
|
return createEvaluatedCell(functionResult, localeFormat.locale);
|
|
5040
5043
|
}
|
|
5041
5044
|
function parseLiteral(content, locale) {
|
|
@@ -5057,10 +5060,11 @@ function parseLiteral(content, locale) {
|
|
|
5057
5060
|
}
|
|
5058
5061
|
return content;
|
|
5059
5062
|
}
|
|
5060
|
-
function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell) {
|
|
5063
|
+
function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell, origin) {
|
|
5061
5064
|
const link = detectLink(functionResult.value);
|
|
5062
5065
|
if (!link) {
|
|
5063
|
-
|
|
5066
|
+
const evaluateCell = _createEvaluatedCell(functionResult, locale, cell);
|
|
5067
|
+
return addOrigin(evaluateCell, functionResult.origin ?? origin);
|
|
5064
5068
|
}
|
|
5065
5069
|
const value = parseLiteral(link.label, locale);
|
|
5066
5070
|
const format = functionResult.format ||
|
|
@@ -5071,10 +5075,10 @@ function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell) {
|
|
|
5071
5075
|
value,
|
|
5072
5076
|
format,
|
|
5073
5077
|
};
|
|
5074
|
-
return {
|
|
5078
|
+
return addOrigin({
|
|
5075
5079
|
..._createEvaluatedCell(linkPayload, locale, cell),
|
|
5076
5080
|
link,
|
|
5077
|
-
};
|
|
5081
|
+
}, functionResult.origin ?? origin);
|
|
5078
5082
|
}
|
|
5079
5083
|
function _createEvaluatedCell(functionResult, locale, cell) {
|
|
5080
5084
|
let { value, format, message } = functionResult;
|
|
@@ -5164,6 +5168,17 @@ function errorCell(value, message) {
|
|
|
5164
5168
|
defaultAlign: "center",
|
|
5165
5169
|
};
|
|
5166
5170
|
}
|
|
5171
|
+
function addOrigin(cell, origin) {
|
|
5172
|
+
if (cell.value === null) {
|
|
5173
|
+
// ignore empty cells to allow sharing the same object instance
|
|
5174
|
+
return cell;
|
|
5175
|
+
}
|
|
5176
|
+
if ("origin" in cell) {
|
|
5177
|
+
return cell;
|
|
5178
|
+
}
|
|
5179
|
+
cell.origin = origin;
|
|
5180
|
+
return cell;
|
|
5181
|
+
}
|
|
5167
5182
|
|
|
5168
5183
|
function toCriterionDateNumber(dateValue) {
|
|
5169
5184
|
const today = DateTime.now();
|
|
@@ -6924,6 +6939,8 @@ function splitWordToSpecificWidth(ctx, word, width, style) {
|
|
|
6924
6939
|
function splitTextToWidth(ctx, text, style, width) {
|
|
6925
6940
|
if (!style)
|
|
6926
6941
|
style = {};
|
|
6942
|
+
if (isMarkdownLink(text))
|
|
6943
|
+
text = parseMarkdownLink(text).label;
|
|
6927
6944
|
const brokenText = [];
|
|
6928
6945
|
// Checking if text contains NEWLINE before split makes it very slightly slower if text contains it,
|
|
6929
6946
|
// but 5-10x faster if it doesn't
|
|
@@ -7842,6 +7859,7 @@ function changeCFRuleLocale(rule, changeContentLocale) {
|
|
|
7842
7859
|
case "isGreaterOrEqualTo":
|
|
7843
7860
|
case "isLessThan":
|
|
7844
7861
|
case "isLessOrEqualTo":
|
|
7862
|
+
case "customFormula":
|
|
7845
7863
|
rule.values = rule.values.map((v) => changeContentLocale(v));
|
|
7846
7864
|
return rule;
|
|
7847
7865
|
case "beginsWithText":
|
|
@@ -8764,6 +8782,10 @@ function toNormalizedPivotValue(dimension, groupValue) {
|
|
|
8764
8782
|
if (groupValue === null || groupValue === "null") {
|
|
8765
8783
|
return null;
|
|
8766
8784
|
}
|
|
8785
|
+
const extractedGroupValue = typeof groupValue === "object" ? groupValue.value : groupValue;
|
|
8786
|
+
if (isEvaluationError(extractedGroupValue)) {
|
|
8787
|
+
return extractedGroupValue;
|
|
8788
|
+
}
|
|
8767
8789
|
const groupValueString = typeof groupValue === "boolean"
|
|
8768
8790
|
? toString(groupValue).toLocaleLowerCase()
|
|
8769
8791
|
: toString(groupValue);
|
|
@@ -10526,6 +10548,7 @@ const EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS = 100;
|
|
|
10526
10548
|
/** The possible values for the XLSX polynomial trendline order are defined by the ST_Order simple type (§21.2.3.29) */
|
|
10527
10549
|
const MAX_XLSX_POLYNOMIAL_DEGREE = 6;
|
|
10528
10550
|
const FIRST_NUMFMT_ID = 164;
|
|
10551
|
+
const DEFAULT_DOUGHNUT_CHART_HOLE_SIZE = 50;
|
|
10529
10552
|
const FORCE_DEFAULT_ARGS_FUNCTIONS = {
|
|
10530
10553
|
FLOOR: [{ type: "NUMBER", value: 1 }],
|
|
10531
10554
|
CEILING: [{ type: "NUMBER", value: 1 }],
|
|
@@ -19025,13 +19048,19 @@ const COLUMN = {
|
|
|
19025
19048
|
if (isEvaluationError(cellReference?.value)) {
|
|
19026
19049
|
return cellReference;
|
|
19027
19050
|
}
|
|
19028
|
-
|
|
19029
|
-
|
|
19030
|
-
|
|
19031
|
-
|
|
19032
|
-
return
|
|
19051
|
+
if (cellReference === undefined) {
|
|
19052
|
+
if (this.__originCellPosition?.col === undefined) {
|
|
19053
|
+
return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
|
|
19054
|
+
}
|
|
19055
|
+
return this.__originCellPosition.col + 1;
|
|
19056
|
+
}
|
|
19057
|
+
const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
|
|
19058
|
+
if (zone.left === zone.right) {
|
|
19059
|
+
return zone.left + 1;
|
|
19033
19060
|
}
|
|
19034
|
-
return
|
|
19061
|
+
return generateMatrix(zone.right - zone.left + 1, 1, (col, row) => ({
|
|
19062
|
+
value: zone.left + col + 1,
|
|
19063
|
+
}));
|
|
19035
19064
|
},
|
|
19036
19065
|
isExported: true,
|
|
19037
19066
|
};
|
|
@@ -19262,13 +19291,19 @@ const ROW = {
|
|
|
19262
19291
|
if (isEvaluationError(cellReference?.value)) {
|
|
19263
19292
|
return cellReference;
|
|
19264
19293
|
}
|
|
19265
|
-
|
|
19266
|
-
|
|
19267
|
-
|
|
19268
|
-
|
|
19269
|
-
return
|
|
19294
|
+
if (cellReference === undefined) {
|
|
19295
|
+
if (this.__originCellPosition?.row === undefined) {
|
|
19296
|
+
return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
|
|
19297
|
+
}
|
|
19298
|
+
return this.__originCellPosition.row + 1;
|
|
19270
19299
|
}
|
|
19271
|
-
|
|
19300
|
+
const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
|
|
19301
|
+
if (zone.top === zone.bottom) {
|
|
19302
|
+
return zone.top + 1;
|
|
19303
|
+
}
|
|
19304
|
+
return generateMatrix(1, zone.bottom - zone.top + 1, (col, row) => ({
|
|
19305
|
+
value: zone.top + row + 1,
|
|
19306
|
+
}));
|
|
19272
19307
|
},
|
|
19273
19308
|
isExported: true,
|
|
19274
19309
|
};
|
|
@@ -22845,6 +22880,16 @@ class AbstractChart {
|
|
|
22845
22880
|
static getDefinitionFromContextCreation(context) {
|
|
22846
22881
|
throw new Error("This method should be implemented by sub class");
|
|
22847
22882
|
}
|
|
22883
|
+
getCommonDataSetAttributesForExcel(labelRange, dataSets, shouldRemoveFirstLabel) {
|
|
22884
|
+
const excelDataSets = dataSets
|
|
22885
|
+
.map((ds) => toExcelDataset(this.getters, ds))
|
|
22886
|
+
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
22887
|
+
const excelLabelRange = toExcelLabelRange(this.getters, labelRange, shouldRemoveFirstLabel);
|
|
22888
|
+
return {
|
|
22889
|
+
dataSets: excelDataSets,
|
|
22890
|
+
labelRange: excelLabelRange,
|
|
22891
|
+
};
|
|
22892
|
+
}
|
|
22848
22893
|
}
|
|
22849
22894
|
|
|
22850
22895
|
function getBaselineText(baseline, keyValue, baselineMode, humanize, locale) {
|
|
@@ -26327,6 +26372,7 @@ class BarChart extends AbstractChart {
|
|
|
26327
26372
|
labelRange: context.auxiliaryRange || undefined,
|
|
26328
26373
|
axesDesign: context.axesDesign,
|
|
26329
26374
|
showValues: context.showValues,
|
|
26375
|
+
horizontal: context.horizontal,
|
|
26330
26376
|
};
|
|
26331
26377
|
}
|
|
26332
26378
|
getContextCreation() {
|
|
@@ -26384,10 +26430,7 @@ class BarChart extends AbstractChart {
|
|
|
26384
26430
|
};
|
|
26385
26431
|
}
|
|
26386
26432
|
getDefinitionForExcel() {
|
|
26387
|
-
const dataSets = this.dataSets
|
|
26388
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
26389
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
26390
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
26433
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
26391
26434
|
const definition = this.getDefinition();
|
|
26392
26435
|
return {
|
|
26393
26436
|
...definition,
|
|
@@ -26975,10 +27018,7 @@ class ComboChart extends AbstractChart {
|
|
|
26975
27018
|
if (this.aggregated) {
|
|
26976
27019
|
return undefined;
|
|
26977
27020
|
}
|
|
26978
|
-
const dataSets = this.dataSets
|
|
26979
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
26980
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
26981
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27021
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
26982
27022
|
const definition = this.getDefinition();
|
|
26983
27023
|
return {
|
|
26984
27024
|
...definition,
|
|
@@ -27446,7 +27486,9 @@ function getSectionThresholdValue(sheetId, threshold, minValue, maxValue, getter
|
|
|
27446
27486
|
}
|
|
27447
27487
|
function getFormulaNumberValue(sheetId, formula, getters) {
|
|
27448
27488
|
const value = getters.evaluateFormula(sheetId, formula);
|
|
27449
|
-
return
|
|
27489
|
+
return isMultipleElementMatrix(value)
|
|
27490
|
+
? undefined
|
|
27491
|
+
: tryToNumber(toScalar(value), getters.getLocale());
|
|
27450
27492
|
}
|
|
27451
27493
|
function getInvalidGaugeRuntime(chart, getters) {
|
|
27452
27494
|
return {
|
|
@@ -27715,10 +27757,7 @@ class LineChart extends AbstractChart {
|
|
|
27715
27757
|
return new LineChart(definition, this.sheetId, this.getters);
|
|
27716
27758
|
}
|
|
27717
27759
|
getDefinitionForExcel() {
|
|
27718
|
-
const dataSets = this.dataSets
|
|
27719
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
27720
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
27721
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27760
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27722
27761
|
const definition = this.getDefinition();
|
|
27723
27762
|
return {
|
|
27724
27763
|
...definition,
|
|
@@ -27806,7 +27845,8 @@ class PieChart extends AbstractChart {
|
|
|
27806
27845
|
type: "pie",
|
|
27807
27846
|
labelRange: context.auxiliaryRange || undefined,
|
|
27808
27847
|
aggregated: context.aggregated ?? false,
|
|
27809
|
-
isDoughnut:
|
|
27848
|
+
isDoughnut: context.isDoughnut,
|
|
27849
|
+
pieHolePercentage: context.pieHolePercentage,
|
|
27810
27850
|
showValues: context.showValues,
|
|
27811
27851
|
};
|
|
27812
27852
|
}
|
|
@@ -27854,10 +27894,7 @@ class PieChart extends AbstractChart {
|
|
|
27854
27894
|
return new PieChart(definition, sheetId, this.getters);
|
|
27855
27895
|
}
|
|
27856
27896
|
getDefinitionForExcel() {
|
|
27857
|
-
const dataSets = this.dataSets
|
|
27858
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
27859
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
27860
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27897
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27861
27898
|
return {
|
|
27862
27899
|
...this.getDefinition(),
|
|
27863
27900
|
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
@@ -28002,8 +28039,22 @@ class PyramidChart extends AbstractChart {
|
|
|
28002
28039
|
showValues: this.showValues,
|
|
28003
28040
|
};
|
|
28004
28041
|
}
|
|
28005
|
-
getDefinitionForExcel() {
|
|
28006
|
-
|
|
28042
|
+
getDefinitionForExcel(getters) {
|
|
28043
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
28044
|
+
const definition = this.getDefinition();
|
|
28045
|
+
const chartData = getPyramidChartData(definition, this.dataSets, this.labelRange, getters);
|
|
28046
|
+
const { dataSetsValues } = chartData;
|
|
28047
|
+
const maxValue = Math.max(...dataSetsValues.map((dataSet) => Math.max(...dataSet.data.map(Math.abs))));
|
|
28048
|
+
return {
|
|
28049
|
+
...definition,
|
|
28050
|
+
horizontal: true,
|
|
28051
|
+
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
28052
|
+
fontColor: toXlsxHexColor(chartFontColor(this.background)),
|
|
28053
|
+
dataSets,
|
|
28054
|
+
labelRange,
|
|
28055
|
+
verticalAxis: getDefinedAxis(definition),
|
|
28056
|
+
maxValue,
|
|
28057
|
+
};
|
|
28007
28058
|
}
|
|
28008
28059
|
updateRanges(applyChange) {
|
|
28009
28060
|
const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
|
|
@@ -28146,10 +28197,7 @@ class RadarChart extends AbstractChart {
|
|
|
28146
28197
|
if (this.aggregated) {
|
|
28147
28198
|
return undefined;
|
|
28148
28199
|
}
|
|
28149
|
-
const dataSets = this.dataSets
|
|
28150
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
28151
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
28152
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
28200
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
28153
28201
|
const definition = this.getDefinition();
|
|
28154
28202
|
return {
|
|
28155
28203
|
...definition,
|
|
@@ -31071,6 +31119,9 @@ class ErrorToolTip extends Component {
|
|
|
31071
31119
|
return undefined;
|
|
31072
31120
|
}
|
|
31073
31121
|
get errorOriginPositionString() {
|
|
31122
|
+
if (this.env.model.getters.isDashboard()) {
|
|
31123
|
+
return "";
|
|
31124
|
+
}
|
|
31074
31125
|
const evaluationError = this.evaluationError;
|
|
31075
31126
|
const position = evaluationError?.errorOriginPosition;
|
|
31076
31127
|
if (!position || deepEquals(position, this.props.cellPosition)) {
|
|
@@ -32593,6 +32644,9 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
32593
32644
|
get isAutoCompleteDisplayed() {
|
|
32594
32645
|
return !!this.autoComplete.provider;
|
|
32595
32646
|
}
|
|
32647
|
+
get canBeToggled() {
|
|
32648
|
+
return this.autoComplete.provider?.canBeToggled ?? true;
|
|
32649
|
+
}
|
|
32596
32650
|
cycleReferences() {
|
|
32597
32651
|
const locale = this.getters.getLocale();
|
|
32598
32652
|
const updated = cycleFixedReference(this.composerSelection, this._currentContent, locale);
|
|
@@ -33122,6 +33176,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
33122
33176
|
proposals,
|
|
33123
33177
|
selectProposal: provider.selectProposal,
|
|
33124
33178
|
autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
|
|
33179
|
+
canBeToggled: provider.canBeToggled,
|
|
33125
33180
|
};
|
|
33126
33181
|
}
|
|
33127
33182
|
if (exactMatch && this._currentContent !== this.initialContent) {
|
|
@@ -33144,6 +33199,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
33144
33199
|
proposals,
|
|
33145
33200
|
selectProposal: provider.selectProposal,
|
|
33146
33201
|
autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
|
|
33202
|
+
canBeToggled: provider.canBeToggled,
|
|
33147
33203
|
};
|
|
33148
33204
|
}
|
|
33149
33205
|
}
|
|
@@ -33714,9 +33770,13 @@ class Composer extends Component {
|
|
|
33714
33770
|
}
|
|
33715
33771
|
}
|
|
33716
33772
|
closeAssistant() {
|
|
33773
|
+
if (!this.props.composerStore.canBeToggled)
|
|
33774
|
+
return;
|
|
33717
33775
|
this.assistant.forcedClosed = true;
|
|
33718
33776
|
}
|
|
33719
33777
|
openAssistant() {
|
|
33778
|
+
if (!this.props.composerStore.canBeToggled)
|
|
33779
|
+
return;
|
|
33720
33780
|
this.assistant.forcedClosed = false;
|
|
33721
33781
|
}
|
|
33722
33782
|
onWheel(event) {
|
|
@@ -33906,7 +33966,7 @@ class Composer extends Component {
|
|
|
33906
33966
|
return [...new Set(argsToFocus)];
|
|
33907
33967
|
}
|
|
33908
33968
|
autoComplete(value) {
|
|
33909
|
-
if (!value || this.assistant.forcedClosed) {
|
|
33969
|
+
if (!value || (this.assistant.forcedClosed && this.props.composerStore.canBeToggled)) {
|
|
33910
33970
|
return;
|
|
33911
33971
|
}
|
|
33912
33972
|
this.props.composerStore.insertAutoCompleteValue(value);
|
|
@@ -37484,7 +37544,7 @@ const CF_OPERATOR_TYPE_CONVERSION_MAP = {
|
|
|
37484
37544
|
/** Conversion map CF types in XLSX <=> Cf types in o_spreadsheet */
|
|
37485
37545
|
const CF_TYPE_CONVERSION_MAP = {
|
|
37486
37546
|
aboveAverage: undefined,
|
|
37487
|
-
expression:
|
|
37547
|
+
expression: "customFormula",
|
|
37488
37548
|
cellIs: undefined, // exist but isn't an operator in o_spreadsheet
|
|
37489
37549
|
colorScale: undefined, // exist but isn't an operator in o_spreadsheet
|
|
37490
37550
|
dataBar: undefined,
|
|
@@ -38088,7 +38148,6 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
38088
38148
|
case "containsErrors":
|
|
38089
38149
|
case "notContainsErrors":
|
|
38090
38150
|
case "duplicateValues":
|
|
38091
|
-
case "expression":
|
|
38092
38151
|
case "top10":
|
|
38093
38152
|
case "uniqueValues":
|
|
38094
38153
|
case "timePeriod":
|
|
@@ -38121,6 +38180,12 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
38121
38180
|
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
38122
38181
|
values.push(rule.text);
|
|
38123
38182
|
break;
|
|
38183
|
+
case "expression":
|
|
38184
|
+
if (!rule.formula?.length)
|
|
38185
|
+
continue;
|
|
38186
|
+
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
38187
|
+
values.push(`=${rule.formula[0]}`);
|
|
38188
|
+
break;
|
|
38124
38189
|
case "containsBlanks":
|
|
38125
38190
|
case "notContainsBlanks":
|
|
38126
38191
|
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
@@ -38350,6 +38415,8 @@ function convertOperator(operator) {
|
|
|
38350
38415
|
return "equal";
|
|
38351
38416
|
case "isNotEqual":
|
|
38352
38417
|
return "notEqual";
|
|
38418
|
+
case "customFormula":
|
|
38419
|
+
return "";
|
|
38353
38420
|
}
|
|
38354
38421
|
}
|
|
38355
38422
|
// -------------------------------------
|
|
@@ -38685,6 +38752,9 @@ function convertChartData(chartData) {
|
|
|
38685
38752
|
aggregated: false,
|
|
38686
38753
|
cumulative: chartData.cumulative || false,
|
|
38687
38754
|
labelsAsText: false,
|
|
38755
|
+
horizontal: chartData.horizontal,
|
|
38756
|
+
isDoughnut: chartData.isDoughnut,
|
|
38757
|
+
pieHolePercentage: chartData.pieHolePercentage,
|
|
38688
38758
|
};
|
|
38689
38759
|
try {
|
|
38690
38760
|
const ChartClass = chartRegistry.get(chartData.type);
|
|
@@ -39219,40 +39289,112 @@ function convertPivotTableConfig(pivotTable) {
|
|
|
39219
39289
|
* In all the sheets, replace the table-only references in the formula cells with standard references.
|
|
39220
39290
|
*/
|
|
39221
39291
|
function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
|
|
39292
|
+
let deconstructedSheets = null;
|
|
39222
39293
|
for (const tableSheet of convertedSheets) {
|
|
39223
39294
|
const tables = xlsxSheets.find((s) => isSheetNameEqual(s.sheetName, tableSheet.name)).tables;
|
|
39295
|
+
if (!tables || tables.length === 0) {
|
|
39296
|
+
continue;
|
|
39297
|
+
}
|
|
39298
|
+
// Only deconstruct sheets if we are sure there are tables to process
|
|
39299
|
+
if (!deconstructedSheets) {
|
|
39300
|
+
deconstructedSheets = deconstructSheets(convertedSheets);
|
|
39301
|
+
}
|
|
39224
39302
|
for (const table of tables) {
|
|
39225
|
-
const
|
|
39226
|
-
|
|
39227
|
-
for (const xc in
|
|
39228
|
-
const
|
|
39229
|
-
let
|
|
39230
|
-
|
|
39231
|
-
|
|
39232
|
-
|
|
39233
|
-
let endIndex = refIndex + tabRef.length;
|
|
39234
|
-
let openBrackets = 1;
|
|
39235
|
-
while (openBrackets > 0 && endIndex < cellContent.length) {
|
|
39236
|
-
if (cellContent[endIndex] === "[") {
|
|
39237
|
-
openBrackets++;
|
|
39238
|
-
}
|
|
39239
|
-
else if (cellContent[endIndex] === "]") {
|
|
39240
|
-
openBrackets--;
|
|
39241
|
-
}
|
|
39242
|
-
endIndex++;
|
|
39243
|
-
}
|
|
39244
|
-
const reference = cellContent.slice(refIndex + tabRef.length, endIndex - 1);
|
|
39245
|
-
const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
|
|
39246
|
-
const convertedRef = convertTableReference(sheetPrefix, reference, table, xc);
|
|
39247
|
-
cellContent =
|
|
39248
|
-
cellContent.slice(0, refIndex) + convertedRef + cellContent.slice(endIndex);
|
|
39303
|
+
for (const sheetId in deconstructedSheets) {
|
|
39304
|
+
const sheet = convertedSheets.find((s) => s.id === sheetId);
|
|
39305
|
+
for (const xc in deconstructedSheets[sheetId]) {
|
|
39306
|
+
const deconstructedCell = deconstructedSheets[sheetId][xc];
|
|
39307
|
+
for (let i = deconstructedCell.length - 3; i >= 0; i -= 2) {
|
|
39308
|
+
const possibleTable = deconstructedSheets[sheetId][xc][i];
|
|
39309
|
+
if (!possibleTable.endsWith(table.name)) {
|
|
39310
|
+
continue;
|
|
39249
39311
|
}
|
|
39312
|
+
const possibleRef = deconstructedSheets[sheetId][xc][i + 1];
|
|
39313
|
+
const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
|
|
39314
|
+
const convertedRef = convertTableReference(sheetPrefix, possibleRef, table, xc);
|
|
39315
|
+
deconstructedSheets[sheetId][xc][i + 2] =
|
|
39316
|
+
possibleTable.slice(0, possibleTable.indexOf(table.name)) +
|
|
39317
|
+
convertedRef +
|
|
39318
|
+
deconstructedSheets[sheetId][xc][i + 2];
|
|
39319
|
+
deconstructedSheets[sheetId][xc].splice(i, 2);
|
|
39320
|
+
}
|
|
39321
|
+
// sheet.cells[xc] = cellContent;
|
|
39322
|
+
}
|
|
39323
|
+
}
|
|
39324
|
+
}
|
|
39325
|
+
}
|
|
39326
|
+
if (!deconstructedSheets) {
|
|
39327
|
+
return;
|
|
39328
|
+
}
|
|
39329
|
+
for (const sheetId in deconstructedSheets) {
|
|
39330
|
+
const sheet = convertedSheets.find((s) => s.id === sheetId);
|
|
39331
|
+
for (const xc in deconstructedSheets[sheetId]) {
|
|
39332
|
+
const deconstructedCell = deconstructedSheets[sheetId][xc];
|
|
39333
|
+
if (deconstructedCell.length === 1) {
|
|
39334
|
+
sheet.cells[xc] = deconstructedCell[0];
|
|
39335
|
+
continue;
|
|
39336
|
+
}
|
|
39337
|
+
let newContent = "";
|
|
39338
|
+
for (let i = 0; i < deconstructedCell.length; i += 2) {
|
|
39339
|
+
newContent += deconstructedCell[i] + "[" + deconstructedCell[i + 1] + "]";
|
|
39340
|
+
}
|
|
39341
|
+
newContent += deconstructedCell[deconstructedCell.length - 1];
|
|
39342
|
+
sheet.cells[xc] = newContent;
|
|
39343
|
+
}
|
|
39344
|
+
}
|
|
39345
|
+
}
|
|
39346
|
+
/**
|
|
39347
|
+
* Deconstruct the content of the cells in the sheets to extract possible table references.
|
|
39348
|
+
* Example from "=AVERAGE(Table1[colName1])-AVERAGE(Table2[colName2])":
|
|
39349
|
+
* return --> ["=AVERAGE(Table1", "colName1", ")-AVERAGE(Table2", "colName2", ")"]
|
|
39350
|
+
*/
|
|
39351
|
+
function deconstructSheets(convertedSheets) {
|
|
39352
|
+
const deconstructedSheets = {};
|
|
39353
|
+
for (const sheet of convertedSheets) {
|
|
39354
|
+
for (const xc in sheet.cells) {
|
|
39355
|
+
const cellContent = sheet.cells[xc];
|
|
39356
|
+
if (!cellContent || !cellContent.startsWith("=")) {
|
|
39357
|
+
continue;
|
|
39358
|
+
}
|
|
39359
|
+
const startIndex = cellContent.indexOf("[");
|
|
39360
|
+
if (startIndex === -1) {
|
|
39361
|
+
continue;
|
|
39362
|
+
}
|
|
39363
|
+
const deconstructedCell = [];
|
|
39364
|
+
let possibleTable = cellContent.slice(0, startIndex);
|
|
39365
|
+
let possibleRef = "";
|
|
39366
|
+
let openBrackets = 1;
|
|
39367
|
+
let mainPossibleTableIndex = 0;
|
|
39368
|
+
let mainOpenBracketIndex = startIndex;
|
|
39369
|
+
for (let index = startIndex + 1; index < cellContent.length; index++) {
|
|
39370
|
+
if (cellContent[index] === "[") {
|
|
39371
|
+
if (openBrackets === 0) {
|
|
39372
|
+
possibleTable = cellContent.slice(mainPossibleTableIndex, index);
|
|
39373
|
+
mainOpenBracketIndex = index;
|
|
39250
39374
|
}
|
|
39251
|
-
|
|
39375
|
+
openBrackets++;
|
|
39376
|
+
continue;
|
|
39252
39377
|
}
|
|
39378
|
+
if (cellContent[index] === "]") {
|
|
39379
|
+
openBrackets--;
|
|
39380
|
+
if (openBrackets === 0) {
|
|
39381
|
+
possibleRef = cellContent.slice(mainOpenBracketIndex + 1, index);
|
|
39382
|
+
deconstructedCell.push(possibleTable);
|
|
39383
|
+
deconstructedCell.push(possibleRef);
|
|
39384
|
+
mainPossibleTableIndex = index + 1;
|
|
39385
|
+
}
|
|
39386
|
+
}
|
|
39387
|
+
}
|
|
39388
|
+
if (deconstructedCell.length) {
|
|
39389
|
+
if (!deconstructedSheets[sheet.id]) {
|
|
39390
|
+
deconstructedSheets[sheet.id] = {};
|
|
39391
|
+
}
|
|
39392
|
+
deconstructedCell.push(cellContent.slice(mainPossibleTableIndex));
|
|
39393
|
+
deconstructedSheets[sheet.id][xc] = [...deconstructedCell];
|
|
39253
39394
|
}
|
|
39254
39395
|
}
|
|
39255
39396
|
}
|
|
39397
|
+
return deconstructedSheets;
|
|
39256
39398
|
}
|
|
39257
39399
|
/**
|
|
39258
39400
|
* Convert table-specific references in formulas into standard references. A table reference is composed of columns names,
|
|
@@ -39889,6 +40031,12 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
39889
40031
|
const barChartGrouping = this.extractChildAttr(rootChartElement, "c:grouping", "val", {
|
|
39890
40032
|
default: "clustered",
|
|
39891
40033
|
}).asString();
|
|
40034
|
+
const chartDirection = this.extractChildAttr(rootChartElement, "c:barDir", "val", {
|
|
40035
|
+
default: "col",
|
|
40036
|
+
}).asString();
|
|
40037
|
+
const chartHoleSize = this.extractChildAttr(rootChartElement, "c:holeSize", "val", {
|
|
40038
|
+
default: "0",
|
|
40039
|
+
}).asNum();
|
|
39892
40040
|
return {
|
|
39893
40041
|
title: { text: chartTitle },
|
|
39894
40042
|
type: CHART_TYPE_CONVERSION_MAP[chartType],
|
|
@@ -39902,6 +40050,9 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
39902
40050
|
}).asString()],
|
|
39903
40051
|
stacked: barChartGrouping === "stacked",
|
|
39904
40052
|
fontColor: "000000",
|
|
40053
|
+
horizontal: chartDirection === "bar",
|
|
40054
|
+
isDoughnut: chartHoleSize > 0,
|
|
40055
|
+
pieHolePercentage: chartHoleSize,
|
|
39905
40056
|
};
|
|
39906
40057
|
})[0];
|
|
39907
40058
|
}
|
|
@@ -45564,10 +45715,10 @@ class CellComposerStore extends AbstractComposerStore {
|
|
|
45564
45715
|
const cellValue = isFormula(content)
|
|
45565
45716
|
? this.getters.evaluateFormula(this.sheetId, content)
|
|
45566
45717
|
: parseLiteral(content, this.getters.getLocale());
|
|
45567
|
-
if (
|
|
45718
|
+
if (isMultipleElementMatrix(cellValue)) {
|
|
45568
45719
|
return true;
|
|
45569
45720
|
}
|
|
45570
|
-
const validationResult = this.getters.getValidationResultForCellValue(cellValue, cellPosition);
|
|
45721
|
+
const validationResult = this.getters.getValidationResultForCellValue(toScalar(cellValue), cellPosition);
|
|
45571
45722
|
if (!validationResult.isValid && validationResult.rule.isBlocking) {
|
|
45572
45723
|
return false;
|
|
45573
45724
|
}
|
|
@@ -50679,10 +50830,10 @@ class GaugeChartDesignPanel extends Component {
|
|
|
50679
50830
|
return tryToNumber(value, locale) !== undefined;
|
|
50680
50831
|
}
|
|
50681
50832
|
const evaluatedValue = this.env.model.getters.evaluateFormula(this.sheetId, value);
|
|
50682
|
-
if (
|
|
50833
|
+
if (isMultipleElementMatrix(evaluatedValue)) {
|
|
50683
50834
|
return false;
|
|
50684
50835
|
}
|
|
50685
|
-
return tryToNumber(evaluatedValue, locale) !== undefined;
|
|
50836
|
+
return tryToNumber(toScalar(evaluatedValue), locale) !== undefined;
|
|
50686
50837
|
}
|
|
50687
50838
|
get sheetId() {
|
|
50688
50839
|
const chart = this.env.model.getters.getChart(this.props.figureId);
|
|
@@ -50892,6 +51043,9 @@ class PieChartDesignPanel extends Component {
|
|
|
50892
51043
|
pieHolePercentage,
|
|
50893
51044
|
});
|
|
50894
51045
|
}
|
|
51046
|
+
get defaultHoleSize() {
|
|
51047
|
+
return DEFAULT_DOUGHNUT_CHART_HOLE_SIZE;
|
|
51048
|
+
}
|
|
50895
51049
|
}
|
|
50896
51050
|
|
|
50897
51051
|
class RadarChartDesignPanel extends Component {
|
|
@@ -51536,12 +51690,32 @@ class ChartPanel extends Component {
|
|
|
51536
51690
|
static template = "o-spreadsheet-ChartPanel";
|
|
51537
51691
|
static components = { Section, ChartTypePicker };
|
|
51538
51692
|
static props = { onCloseSidePanel: Function, figureId: String };
|
|
51693
|
+
panelContentRef;
|
|
51694
|
+
scrollPositions = {
|
|
51695
|
+
configuration: 0,
|
|
51696
|
+
design: 0,
|
|
51697
|
+
};
|
|
51539
51698
|
store;
|
|
51540
51699
|
get figureId() {
|
|
51541
51700
|
return this.props.figureId;
|
|
51542
51701
|
}
|
|
51543
51702
|
setup() {
|
|
51544
51703
|
this.store = useLocalStore(MainChartPanelStore);
|
|
51704
|
+
this.panelContentRef = useRef("panelContent");
|
|
51705
|
+
useEffect(() => {
|
|
51706
|
+
const el = this.panelContentRef.el;
|
|
51707
|
+
const activePanel = this.store.panel;
|
|
51708
|
+
if (el) {
|
|
51709
|
+
el.scrollTop = this.scrollPositions[activePanel];
|
|
51710
|
+
}
|
|
51711
|
+
}, () => [this.store.panel]);
|
|
51712
|
+
}
|
|
51713
|
+
switchPanel(panel) {
|
|
51714
|
+
const el = this.panelContentRef.el;
|
|
51715
|
+
if (el) {
|
|
51716
|
+
this.scrollPositions[this.store.panel] = el.scrollTop;
|
|
51717
|
+
}
|
|
51718
|
+
this.store.activatePanel(panel);
|
|
51545
51719
|
}
|
|
51546
51720
|
updateChart(figureId, updateDefinition) {
|
|
51547
51721
|
if (figureId !== this.figureId) {
|
|
@@ -55493,10 +55667,7 @@ class SpreadsheetPivot {
|
|
|
55493
55667
|
if (finalCell.value === null) {
|
|
55494
55668
|
return { value: _t("(Undefined)") };
|
|
55495
55669
|
}
|
|
55496
|
-
return
|
|
55497
|
-
value: finalCell.value,
|
|
55498
|
-
format: finalCell.format,
|
|
55499
|
-
};
|
|
55670
|
+
return finalCell;
|
|
55500
55671
|
}
|
|
55501
55672
|
getPivotCellValueAndFormat(measureId, domain) {
|
|
55502
55673
|
const dataEntries = this.filterDataEntriesFromDomain(this.dataEntries, domain);
|
|
@@ -55598,9 +55769,15 @@ class SpreadsheetPivot {
|
|
|
55598
55769
|
return domain.reduce((current, acc) => this.filterDataEntriesFromDomainNode(current, acc), dataEntries);
|
|
55599
55770
|
}
|
|
55600
55771
|
filterDataEntriesFromDomainNode(dataEntries, domain) {
|
|
55601
|
-
const { field, value } = domain;
|
|
55772
|
+
const { field, value, type } = domain;
|
|
55602
55773
|
const { nameWithGranularity } = this.getDimension(field);
|
|
55603
|
-
return dataEntries.filter((entry) =>
|
|
55774
|
+
return dataEntries.filter((entry) => {
|
|
55775
|
+
const cellValue = entry[nameWithGranularity]?.value;
|
|
55776
|
+
if (type === "char") {
|
|
55777
|
+
return String(cellValue) === String(value);
|
|
55778
|
+
}
|
|
55779
|
+
return cellValue === value;
|
|
55780
|
+
});
|
|
55604
55781
|
}
|
|
55605
55782
|
getDimension(nameWithGranularity) {
|
|
55606
55783
|
return this.definition.getDimension(nameWithGranularity);
|
|
@@ -55734,7 +55911,6 @@ pivotRegistry.add("SPREADSHEET", {
|
|
|
55734
55911
|
ui: SpreadsheetPivot,
|
|
55735
55912
|
definition: SpreadsheetPivotRuntimeDefinition,
|
|
55736
55913
|
externalData: false,
|
|
55737
|
-
onIterationEndEvaluation: (pivot) => pivot.markAsDirtyForEvaluation(),
|
|
55738
55914
|
dateGranularities: [...dateGranularities],
|
|
55739
55915
|
datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
|
|
55740
55916
|
isMeasureCandidate: (field) => field.type !== "boolean",
|
|
@@ -64385,7 +64561,7 @@ const onIterationEndEvaluationRegistry = new Registry();
|
|
|
64385
64561
|
onIterationEndEvaluationRegistry.add("pivots", (getters) => {
|
|
64386
64562
|
for (const pivotId of getters.getPivotIds()) {
|
|
64387
64563
|
const pivot = getters.getPivot(pivotId);
|
|
64388
|
-
|
|
64564
|
+
pivot.markAsDirtyForEvaluation?.();
|
|
64389
64565
|
}
|
|
64390
64566
|
});
|
|
64391
64567
|
|
|
@@ -65553,7 +65729,7 @@ class SpreadingRelation {
|
|
|
65553
65729
|
const EMPTY_ARRAY = [];
|
|
65554
65730
|
|
|
65555
65731
|
const MAX_ITERATION = 30;
|
|
65556
|
-
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
|
|
65732
|
+
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell({ ...new CircularDependencyError(), origin: undefined }));
|
|
65557
65733
|
const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
|
|
65558
65734
|
class Evaluator {
|
|
65559
65735
|
context;
|
|
@@ -65787,11 +65963,12 @@ class Evaluator {
|
|
|
65787
65963
|
this.cellsBeingComputed.add(cellId);
|
|
65788
65964
|
return cell.isFormula
|
|
65789
65965
|
? this.computeFormulaCell(position, cell)
|
|
65790
|
-
: evaluateLiteral(cell, localeFormat);
|
|
65966
|
+
: evaluateLiteral(cell, localeFormat, position);
|
|
65791
65967
|
}
|
|
65792
65968
|
catch (e) {
|
|
65793
65969
|
e.value = e?.value || CellErrorType.GenericError;
|
|
65794
65970
|
e.message = e?.message || implementationErrorMessage;
|
|
65971
|
+
e.origin = position;
|
|
65795
65972
|
return createEvaluatedCell(e);
|
|
65796
65973
|
}
|
|
65797
65974
|
finally {
|
|
@@ -65808,7 +65985,7 @@ class Evaluator {
|
|
|
65808
65985
|
computeFormulaCell(formulaPosition, cellData) {
|
|
65809
65986
|
const formulaReturn = updateEvalContextAndExecute(cellData.compiledFormula, this.compilationParams, formulaPosition.sheetId, this.buildSafeGetSymbolValue(), formulaPosition);
|
|
65810
65987
|
if (!isMatrix(formulaReturn)) {
|
|
65811
|
-
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(formulaReturn), this.getters.getLocale(), cellData);
|
|
65988
|
+
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(formulaReturn), this.getters.getLocale(), cellData, formulaPosition);
|
|
65812
65989
|
if (evaluatedCell.type === CellValueType.error) {
|
|
65813
65990
|
evaluatedCell.errorOriginPosition = formulaReturn.errorOriginPosition ?? formulaPosition;
|
|
65814
65991
|
}
|
|
@@ -65884,7 +66061,7 @@ class Evaluator {
|
|
|
65884
66061
|
const spreadValues = (i, j) => {
|
|
65885
66062
|
const position = { sheetId, col: i + col, row: j + row };
|
|
65886
66063
|
const cell = this.getters.getCell(position);
|
|
65887
|
-
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell);
|
|
66064
|
+
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell, position);
|
|
65888
66065
|
if (evaluatedCell.type === CellValueType.error) {
|
|
65889
66066
|
evaluatedCell.errorOriginPosition = matrixResult[i][j].errorOriginPosition ?? position;
|
|
65890
66067
|
}
|
|
@@ -66557,7 +66734,7 @@ class EvaluationChartPlugin extends CoreViewPlugin {
|
|
|
66557
66734
|
continue;
|
|
66558
66735
|
}
|
|
66559
66736
|
const figureId = figure.id;
|
|
66560
|
-
const figureData = this.getters.getChart(figureId)?.getDefinitionForExcel();
|
|
66737
|
+
const figureData = this.getters.getChart(figureId)?.getDefinitionForExcel(this.getters);
|
|
66561
66738
|
if (figureData) {
|
|
66562
66739
|
figures.push({
|
|
66563
66740
|
...figure,
|
|
@@ -66849,12 +67026,12 @@ class EvaluationConditionalFormatPlugin extends CoreViewPlugin {
|
|
|
66849
67026
|
}
|
|
66850
67027
|
return this.getters.evaluateFormula(sheetId, value) ?? "";
|
|
66851
67028
|
});
|
|
66852
|
-
if (evaluatedCriterionValues.some(
|
|
67029
|
+
if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
|
|
66853
67030
|
return false;
|
|
66854
67031
|
}
|
|
66855
67032
|
const evaluatedCriterion = {
|
|
66856
67033
|
type: rule.operator,
|
|
66857
|
-
values: evaluatedCriterionValues,
|
|
67034
|
+
values: evaluatedCriterionValues.map(toScalar),
|
|
66858
67035
|
};
|
|
66859
67036
|
return evaluator.isValueValid(cell.value ?? "", evaluatedCriterion, this.getters, sheetId);
|
|
66860
67037
|
}
|
|
@@ -67014,10 +67191,10 @@ class EvaluationDataValidationPlugin extends CoreViewPlugin {
|
|
|
67014
67191
|
const evaluator = criterionEvaluatorRegistry.get(criterion.type);
|
|
67015
67192
|
const offset = this.getCellOffsetInRule(cellPosition, rule);
|
|
67016
67193
|
const evaluatedCriterionValues = this.getEvaluatedCriterionValues(sheetId, offset, criterion);
|
|
67017
|
-
if (evaluatedCriterionValues.some(
|
|
67194
|
+
if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
|
|
67018
67195
|
return undefined;
|
|
67019
67196
|
}
|
|
67020
|
-
const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues };
|
|
67197
|
+
const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues.map(toScalar) };
|
|
67021
67198
|
if (evaluator.isValueValid(cellValue, evaluatedCriterion, this.getters, sheetId)) {
|
|
67022
67199
|
return undefined;
|
|
67023
67200
|
}
|
|
@@ -67470,6 +67647,23 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
|
|
|
67470
67647
|
static getters = ["getRowSize", "getHeaderSize", "getMaxAnchorOffset"];
|
|
67471
67648
|
tallestCellInRow = {};
|
|
67472
67649
|
ctx = document.createElement("canvas").getContext("2d");
|
|
67650
|
+
beforeHandle(cmd) {
|
|
67651
|
+
switch (cmd.type) {
|
|
67652
|
+
// Ensure rows are updated before "UPDATE_CELL" is dispatched from cell plugin.
|
|
67653
|
+
// "UPDATE_CELL" uses the Sheet core plugin to access row data.
|
|
67654
|
+
// If "ADD_COLUMNS_ROWS" has not been processed yet by header_sizes_ui,
|
|
67655
|
+
// size updates may apply to incorrect (pre-insert) rows.
|
|
67656
|
+
case "ADD_COLUMNS_ROWS":
|
|
67657
|
+
if (cmd.dimension === "COL") {
|
|
67658
|
+
return;
|
|
67659
|
+
}
|
|
67660
|
+
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
67661
|
+
const newCells = Array(cmd.quantity).fill(undefined);
|
|
67662
|
+
const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
|
|
67663
|
+
this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
|
|
67664
|
+
break;
|
|
67665
|
+
}
|
|
67666
|
+
}
|
|
67473
67667
|
handle(cmd) {
|
|
67474
67668
|
switch (cmd.type) {
|
|
67475
67669
|
case "START":
|
|
@@ -67499,16 +67693,6 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
|
|
|
67499
67693
|
this.history.update("tallestCellInRow", cmd.sheetId, tallestCells);
|
|
67500
67694
|
break;
|
|
67501
67695
|
}
|
|
67502
|
-
case "ADD_COLUMNS_ROWS": {
|
|
67503
|
-
if (cmd.dimension === "COL") {
|
|
67504
|
-
return;
|
|
67505
|
-
}
|
|
67506
|
-
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
67507
|
-
const newCells = Array(cmd.quantity).fill(undefined);
|
|
67508
|
-
const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
|
|
67509
|
-
this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
|
|
67510
|
-
break;
|
|
67511
|
-
}
|
|
67512
67696
|
case "RESIZE_COLUMNS_ROWS":
|
|
67513
67697
|
{
|
|
67514
67698
|
const sheetId = cmd.sheetId;
|
|
@@ -67660,13 +67844,13 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
67660
67844
|
super(custom, params);
|
|
67661
67845
|
this.getters = params.getters;
|
|
67662
67846
|
}
|
|
67663
|
-
|
|
67847
|
+
markAsDirtyForEvaluation() {
|
|
67664
67848
|
this.cache = {};
|
|
67665
67849
|
this.rankAsc = {};
|
|
67666
67850
|
this.rankDesc = {};
|
|
67667
67851
|
this.runningTotal = {};
|
|
67668
67852
|
this.runningTotalInPercent = {};
|
|
67669
|
-
super.
|
|
67853
|
+
super.markAsDirtyForEvaluation?.();
|
|
67670
67854
|
}
|
|
67671
67855
|
getPivotCellValueAndFormat(measureName, domain) {
|
|
67672
67856
|
return this.getMeasureDisplayValue(measureName, domain);
|
|
@@ -67791,7 +67975,7 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
67791
67975
|
return this.getSubTreeMatchingDomain(node.children, domain, domainLevel + 1);
|
|
67792
67976
|
}
|
|
67793
67977
|
}
|
|
67794
|
-
return
|
|
67978
|
+
return [];
|
|
67795
67979
|
}
|
|
67796
67980
|
treeToLeafDomains(tree, parentDomain = []) {
|
|
67797
67981
|
const domains = [];
|
|
@@ -73530,12 +73714,12 @@ class FilterEvaluationPlugin extends UIPlugin {
|
|
|
73530
73714
|
}
|
|
73531
73715
|
return this.getters.evaluateFormula(sheetId, value) ?? "";
|
|
73532
73716
|
});
|
|
73533
|
-
if (evaluatedCriterionValues.some(
|
|
73717
|
+
if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
|
|
73534
73718
|
continue;
|
|
73535
73719
|
}
|
|
73536
73720
|
const evaluatedCriterion = {
|
|
73537
73721
|
type: filterValue.type,
|
|
73538
|
-
values: evaluatedCriterionValues,
|
|
73722
|
+
values: evaluatedCriterionValues.map(toScalar),
|
|
73539
73723
|
dateValue: filterValue.dateValue,
|
|
73540
73724
|
};
|
|
73541
73725
|
for (let row = filteredZone.top; row <= filteredZone.bottom; row++) {
|
|
@@ -74057,6 +74241,14 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
74057
74241
|
const isBasedBefore = cmd.base < start;
|
|
74058
74242
|
const deltaCol = isBasedBefore && isCol ? thickness : 0;
|
|
74059
74243
|
const deltaRow = isBasedBefore && !isCol ? thickness : 0;
|
|
74244
|
+
const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
|
|
74245
|
+
const originalSize = Object.fromEntries(toRemove.map((element) => {
|
|
74246
|
+
const size = isCol
|
|
74247
|
+
? this.getters.getColSize(cmd.sheetId, element)
|
|
74248
|
+
: this.getters.getUserRowSize(cmd.sheetId, element);
|
|
74249
|
+
const isDefaultCol = isCol && size === DEFAULT_CELL_WIDTH;
|
|
74250
|
+
return [element, isDefaultCol ? undefined : size];
|
|
74251
|
+
}));
|
|
74060
74252
|
const target = [
|
|
74061
74253
|
{
|
|
74062
74254
|
left: isCol ? start + deltaCol : 0,
|
|
@@ -74087,13 +74279,12 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
74087
74279
|
const col = selection.left;
|
|
74088
74280
|
const row = selection.top;
|
|
74089
74281
|
this.setSelectionMixin({ zone: selection, cell: { col, row } }, [selection]);
|
|
74090
|
-
const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
|
|
74091
74282
|
let currentIndex = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
74092
74283
|
const resizingGroups = {};
|
|
74093
74284
|
for (const element of toRemove) {
|
|
74094
|
-
const size =
|
|
74285
|
+
const size = originalSize[element];
|
|
74095
74286
|
const currentSize = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, currentIndex);
|
|
74096
|
-
if (size !== currentSize) {
|
|
74287
|
+
if (size && size !== currentSize) {
|
|
74097
74288
|
resizingGroups[size] ??= [];
|
|
74098
74289
|
resizingGroups[size].push(currentIndex);
|
|
74099
74290
|
currentIndex += 1;
|
|
@@ -75519,6 +75710,7 @@ const coreViewsPluginRegistry = new Registry()
|
|
|
75519
75710
|
|
|
75520
75711
|
autoCompleteProviders.add("dataValidation", {
|
|
75521
75712
|
displayAllOnInitialContent: true,
|
|
75713
|
+
canBeToggled: false,
|
|
75522
75714
|
getProposals(tokenAtCursor, content) {
|
|
75523
75715
|
if (isFormula(content)) {
|
|
75524
75716
|
return [];
|
|
@@ -77084,14 +77276,12 @@ class BottomBarSheet extends Component {
|
|
|
77084
77276
|
this.editionState = "initializing";
|
|
77085
77277
|
}
|
|
77086
77278
|
stopEdition() {
|
|
77087
|
-
|
|
77088
|
-
if (!this.state.isEditing || !input)
|
|
77279
|
+
if (!this.state.isEditing || !this.sheetNameRef.el)
|
|
77089
77280
|
return;
|
|
77090
77281
|
this.state.isEditing = false;
|
|
77091
77282
|
this.editionState = "initializing";
|
|
77092
|
-
|
|
77283
|
+
this.sheetNameRef.el.blur();
|
|
77093
77284
|
const inputValue = this.getInputContent() || "";
|
|
77094
|
-
input.innerText = inputValue;
|
|
77095
77285
|
interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
|
|
77096
77286
|
}
|
|
77097
77287
|
cancelEdition() {
|
|
@@ -81509,6 +81699,9 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81509
81699
|
case "combo":
|
|
81510
81700
|
plot = addComboChart(chart.data);
|
|
81511
81701
|
break;
|
|
81702
|
+
case "pyramid":
|
|
81703
|
+
plot = addPyramidChart(chart.data);
|
|
81704
|
+
break;
|
|
81512
81705
|
case "line":
|
|
81513
81706
|
plot = addLineChart(chart.data);
|
|
81514
81707
|
break;
|
|
@@ -81516,12 +81709,12 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81516
81709
|
plot = addScatterChart(chart.data);
|
|
81517
81710
|
break;
|
|
81518
81711
|
case "pie":
|
|
81519
|
-
plot = addDoughnutChart(chart.data, chartSheetIndex, data
|
|
81712
|
+
plot = addDoughnutChart(chart.data, chartSheetIndex, data);
|
|
81520
81713
|
break;
|
|
81521
81714
|
case "radar":
|
|
81522
81715
|
plot = addRadarChart(chart.data);
|
|
81523
81716
|
}
|
|
81524
|
-
let position = "
|
|
81717
|
+
let position = "none";
|
|
81525
81718
|
switch (chart.data.legendPosition) {
|
|
81526
81719
|
case "bottom":
|
|
81527
81720
|
position = "b";
|
|
@@ -81551,7 +81744,7 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81551
81744
|
${plot}
|
|
81552
81745
|
${shapeProperty({ backgroundColor: chart.data.backgroundColor })}
|
|
81553
81746
|
</c:plotArea>
|
|
81554
|
-
${addLegend(position, fontColor)}
|
|
81747
|
+
${position !== "none" ? addLegend(position, fontColor) : ""}
|
|
81555
81748
|
</c:chart>
|
|
81556
81749
|
</c:chartSpace>
|
|
81557
81750
|
`;
|
|
@@ -81709,6 +81902,7 @@ function addBarChart(chart) {
|
|
|
81709
81902
|
//
|
|
81710
81903
|
// overlap and gapWitdh seems to be by default at -20 and 20 in chart.js.
|
|
81711
81904
|
// See https://www.chartjs.org/docs/latest/charts/bar.html and https://www.chartjs.org/docs/latest/charts/bar.html#barpercentage-vs-categorypercentage
|
|
81905
|
+
const chartDirection = chart.horizontal ? "bar" : "col";
|
|
81712
81906
|
const dataSetsColors = chart.dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
81713
81907
|
const colors = new ColorGenerator(chart.dataSets.length, dataSetsColors);
|
|
81714
81908
|
const leftDataSetsNodes = [];
|
|
@@ -81745,7 +81939,7 @@ function addBarChart(chart) {
|
|
|
81745
81939
|
${leftDataSetsNodes.length
|
|
81746
81940
|
? escapeXml /*xml*/ `
|
|
81747
81941
|
<c:barChart>
|
|
81748
|
-
<c:barDir val="
|
|
81942
|
+
<c:barDir val="${chartDirection}"/>
|
|
81749
81943
|
<c:grouping val="${grouping}"/>
|
|
81750
81944
|
<c:overlap val="${overlap}"/>
|
|
81751
81945
|
<c:gapWidth val="70"/>
|
|
@@ -81755,8 +81949,12 @@ function addBarChart(chart) {
|
|
|
81755
81949
|
<c:axId val="${catAxId}" />
|
|
81756
81950
|
<c:axId val="${valAxId}" />
|
|
81757
81951
|
</c:barChart>
|
|
81758
|
-
${
|
|
81759
|
-
|
|
81952
|
+
${chartDirection === "col"
|
|
81953
|
+
? addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.x?.title, chart.fontColor)
|
|
81954
|
+
: addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.y?.title, chart.fontColor, undefined, "maxMin")}
|
|
81955
|
+
${chartDirection === "col"
|
|
81956
|
+
? addAx("l", "c:valAx", valAxId, catAxId, chart.axesDesign?.y?.title, chart.fontColor)
|
|
81957
|
+
: addAx("l", "c:valAx", valAxId, catAxId, chart.axesDesign?.x?.title, chart.fontColor, undefined, undefined, "max")}
|
|
81760
81958
|
`
|
|
81761
81959
|
: ""}
|
|
81762
81960
|
${rightDataSetsNodes.length
|
|
@@ -81882,7 +82080,7 @@ function addComboChart(chart) {
|
|
|
81882
82080
|
: ""}
|
|
81883
82081
|
${!useRightAxisForBarSerie || leftDataSetsNodes.length
|
|
81884
82082
|
? escapeXml /*xml*/ `
|
|
81885
|
-
${addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.x?.title, chart.fontColor,
|
|
82083
|
+
${addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.x?.title, chart.fontColor, 0)}
|
|
81886
82084
|
${addAx("l", "c:valAx", valAxId, catAxId, chart.axesDesign?.y?.title, chart.fontColor)}
|
|
81887
82085
|
`
|
|
81888
82086
|
: ""}
|
|
@@ -81894,6 +82092,94 @@ function addComboChart(chart) {
|
|
|
81894
82092
|
: ""}
|
|
81895
82093
|
`;
|
|
81896
82094
|
}
|
|
82095
|
+
function addPyramidChart(chart) {
|
|
82096
|
+
const dataSets = chart.dataSets;
|
|
82097
|
+
const dataSetsColors = dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
82098
|
+
const colors = new ColorGenerator(dataSets.length, dataSetsColors);
|
|
82099
|
+
const leftDataSet = dataSets[0];
|
|
82100
|
+
const rightDataSet = dataSets[1];
|
|
82101
|
+
const firstColor = toXlsxHexColor(colors.next());
|
|
82102
|
+
const secondColor = toXlsxHexColor(colors.next());
|
|
82103
|
+
const { maxValue, majorUnit } = getPyramidChartHorizontalAxisConfig(chart.maxValue);
|
|
82104
|
+
const labelRangeEl = chart.labelRange
|
|
82105
|
+
? escapeXml `<c:cat>${stringRef(chart.labelRange)}</c:cat>`
|
|
82106
|
+
: "";
|
|
82107
|
+
const leftBarDataSetNode = escapeXml /*xml*/ `
|
|
82108
|
+
<c:ser>
|
|
82109
|
+
<c:idx val="0"/>
|
|
82110
|
+
<c:order val="0"/>
|
|
82111
|
+
<c:invertIfNegative val="0" />
|
|
82112
|
+
${extractDataSetLabel(leftDataSet.label)}
|
|
82113
|
+
${shapeProperty({
|
|
82114
|
+
backgroundColor: firstColor,
|
|
82115
|
+
line: { color: firstColor },
|
|
82116
|
+
})}
|
|
82117
|
+
${labelRangeEl}
|
|
82118
|
+
<!-- x-coordinate values -->
|
|
82119
|
+
<c:val>
|
|
82120
|
+
${numberRef(leftDataSet.range)}
|
|
82121
|
+
</c:val>
|
|
82122
|
+
</c:ser>
|
|
82123
|
+
`;
|
|
82124
|
+
const rightBarDataSetNode = escapeXml /*xml*/ `
|
|
82125
|
+
<c:ser>
|
|
82126
|
+
<c:idx val="1"/>
|
|
82127
|
+
<c:order val="1"/>
|
|
82128
|
+
<c:invertIfNegative val="0" />
|
|
82129
|
+
${extractDataSetLabel(rightDataSet.label)}
|
|
82130
|
+
${shapeProperty({
|
|
82131
|
+
backgroundColor: secondColor,
|
|
82132
|
+
line: { color: secondColor },
|
|
82133
|
+
})}
|
|
82134
|
+
${chart.labelRange ? escapeXml /*xml*/ `<c:cat>${stringRef(chart.labelRange)}</c:cat>` : ""}
|
|
82135
|
+
<!-- x-coordinate values -->
|
|
82136
|
+
<c:val>
|
|
82137
|
+
${numberRef(rightDataSet.range)}
|
|
82138
|
+
</c:val>
|
|
82139
|
+
</c:ser>
|
|
82140
|
+
`;
|
|
82141
|
+
return escapeXml /*xml*/ `
|
|
82142
|
+
<c:barChart>
|
|
82143
|
+
<c:barDir val="bar"/>
|
|
82144
|
+
<c:grouping val="clustered"/>
|
|
82145
|
+
<c:varyColors val="0" />
|
|
82146
|
+
${leftBarDataSetNode}
|
|
82147
|
+
<c:gapWidth val="50" />
|
|
82148
|
+
<c:axId val="${catAxId}" />
|
|
82149
|
+
<c:axId val="${valAxId}" />
|
|
82150
|
+
</c:barChart>
|
|
82151
|
+
<c:barChart>
|
|
82152
|
+
<c:barDir val="bar"/>
|
|
82153
|
+
<c:grouping val="clustered"/>
|
|
82154
|
+
<c:varyColors val="0" />
|
|
82155
|
+
${rightBarDataSetNode}
|
|
82156
|
+
<c:gapWidth val="50" />
|
|
82157
|
+
<c:axId val="${secondaryCatAxId}" />
|
|
82158
|
+
<c:axId val="${secondaryValAxId}" />
|
|
82159
|
+
</c:barChart>
|
|
82160
|
+
${addAx("r", "c:catAx", catAxId, valAxId, chart.axesDesign?.y?.title, chart.fontColor, 0, "maxMin", "autoZero", "high")}
|
|
82161
|
+
${addAx("b", "c:valAx", valAxId, catAxId, chart.axesDesign?.x?.title, chart.fontColor, 0, "maxMin", "max", "nextTo", maxValue, majorUnit, "#0;#0")}
|
|
82162
|
+
${addAx("t", "c:valAx", secondaryValAxId, secondaryCatAxId, undefined, chart.fontColor, 1)}
|
|
82163
|
+
${addAx("l", "c:catAx", secondaryCatAxId, secondaryValAxId, undefined, chart.fontColor, 1, "maxMin")}
|
|
82164
|
+
`;
|
|
82165
|
+
}
|
|
82166
|
+
function getPyramidChartHorizontalAxisConfig(maxValue) {
|
|
82167
|
+
const adjustMaxToDivisibleBy = (value, divisor) => {
|
|
82168
|
+
let adjusted = Math.ceil(value);
|
|
82169
|
+
while (adjusted % divisor !== 0) {
|
|
82170
|
+
adjusted++;
|
|
82171
|
+
}
|
|
82172
|
+
return adjusted;
|
|
82173
|
+
};
|
|
82174
|
+
const tickCount = 4;
|
|
82175
|
+
const interval = tickCount - 1;
|
|
82176
|
+
const adjustedMax = adjustMaxToDivisibleBy(maxValue, interval);
|
|
82177
|
+
const majorUnit = adjustedMax / interval;
|
|
82178
|
+
return {
|
|
82179
|
+
maxValue: adjustedMax,
|
|
82180
|
+
majorUnit,
|
|
82181
|
+
};
|
|
82182
|
+
}
|
|
81897
82183
|
function addLineChart(chart) {
|
|
81898
82184
|
const dataSetsColors = chart.dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
81899
82185
|
const colors = new ColorGenerator(chart.dataSets.length, dataSetsColors);
|
|
@@ -82086,7 +82372,7 @@ function addRadarChart(chart) {
|
|
|
82086
82372
|
`}
|
|
82087
82373
|
`;
|
|
82088
82374
|
}
|
|
82089
|
-
function addDoughnutChart(chart, chartSheetIndex, data
|
|
82375
|
+
function addDoughnutChart(chart, chartSheetIndex, data) {
|
|
82090
82376
|
const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
|
|
82091
82377
|
const colors = new ColorGenerator(maxLength);
|
|
82092
82378
|
const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
|
|
@@ -82124,7 +82410,7 @@ function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSiz
|
|
|
82124
82410
|
return escapeXml /*xml*/ `
|
|
82125
82411
|
<c:doughnutChart>
|
|
82126
82412
|
<c:varyColors val="1" />
|
|
82127
|
-
<c:holeSize val="${
|
|
82413
|
+
<c:holeSize val="${chart.pieHolePercentage ?? (chart.isDoughnut ? DEFAULT_DOUGHNUT_CHART_HOLE_SIZE : 0)}" />
|
|
82128
82414
|
${insertDataLabels()}
|
|
82129
82415
|
${joinXmlNodes(dataSetsNodes)}
|
|
82130
82416
|
</c:doughnutChart>
|
|
@@ -82143,25 +82429,35 @@ function insertDataLabels({ showLeaderLines } = { showLeaderLines: false }) {
|
|
|
82143
82429
|
</dLbls>
|
|
82144
82430
|
`;
|
|
82145
82431
|
}
|
|
82146
|
-
function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, deleteAxis = 0) {
|
|
82432
|
+
function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, deleteAxis = 0, orientation = "minMax", crossPosition, tickLabelPosition = "nextTo", maxValue, majorUnit, format = "General") {
|
|
82147
82433
|
// Each Axis present inside a graph needs to be identified by an unsigned integer in order to be referenced by its crossAxis.
|
|
82148
82434
|
// I.e. x-axis, will reference y-axis and vice-versa.
|
|
82149
82435
|
const color = title?.color ? toXlsxHexColor(title.color) : defaultFontColor;
|
|
82150
82436
|
const fontSize = title?.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE;
|
|
82437
|
+
const crossBetweenEl = axisName === "c:valAx" ? escapeXml `<c:crossBetween val="between" />` : "";
|
|
82438
|
+
const maxValueEl = maxValue ? escapeXml `<c:max val="${maxValue}" />` : "";
|
|
82439
|
+
const minValueEl = maxValue ? escapeXml `<c:min val="${-maxValue}" />` : "";
|
|
82440
|
+
const majorUnitEl = majorUnit ? escapeXml `<c:majorUnit val="${majorUnit}" />` : "";
|
|
82151
82441
|
return escapeXml /*xml*/ `
|
|
82152
82442
|
<${axisName}>
|
|
82153
82443
|
<c:axId val="${axId}"/>
|
|
82154
82444
|
<c:crossAx val="${crossAxId}"/> <!-- reference to the other axe of the chart -->
|
|
82155
|
-
<c:crosses val="${position === "b" || position === "l" ? "min" : "max"}"/>
|
|
82445
|
+
<c:crosses val="${crossPosition || (position === "b" || position === "l" ? "min" : "max")}"/>
|
|
82446
|
+
<c:auto val="1"/>
|
|
82447
|
+
${crossBetweenEl}
|
|
82156
82448
|
<c:delete val="${deleteAxis}"/> <!-- by default, axis are not displayed -->
|
|
82157
82449
|
<c:scaling>
|
|
82158
|
-
<c:orientation val="
|
|
82450
|
+
<c:orientation val="${orientation}" />
|
|
82451
|
+
${maxValueEl}
|
|
82452
|
+
${minValueEl}
|
|
82159
82453
|
</c:scaling>
|
|
82454
|
+
${majorUnitEl}
|
|
82160
82455
|
<c:axPos val="${position}" />
|
|
82456
|
+
<c:tickLblPos val="${tickLabelPosition}" />
|
|
82161
82457
|
${insertMajorGridLines()}
|
|
82162
82458
|
<c:majorTickMark val="out" />
|
|
82163
82459
|
<c:minorTickMark val="none" />
|
|
82164
|
-
<c:numFmt formatCode="
|
|
82460
|
+
<c:numFmt formatCode="${format}" sourceLinked="${format === "General" ? "1" : "0"}" />
|
|
82165
82461
|
<c:title>
|
|
82166
82462
|
${insertText(title?.text ?? "", color, fontSize, title)}
|
|
82167
82463
|
</c:title>
|
|
@@ -82356,7 +82652,10 @@ function addConditionalFormatting(dxfs, conditionalFormats) {
|
|
|
82356
82652
|
function addCellIsRule(cf, rule, dxfs) {
|
|
82357
82653
|
const ruleAttributes = commonCfAttributes(cf);
|
|
82358
82654
|
const operator = convertOperator(rule.operator);
|
|
82359
|
-
ruleAttributes.push(...cellRuleTypeAttributes(rule)
|
|
82655
|
+
ruleAttributes.push(...cellRuleTypeAttributes(rule));
|
|
82656
|
+
if (operator.length) {
|
|
82657
|
+
ruleAttributes.push(["operator", operator]);
|
|
82658
|
+
}
|
|
82360
82659
|
const formulas = cellRuleFormula(cf.ranges, rule).map((formula) => escapeXml /*xml*/ `<formula>${formula}</formula>`);
|
|
82361
82660
|
const dxf = {
|
|
82362
82661
|
font: {
|
|
@@ -82402,6 +82701,8 @@ function cellRuleFormula(ranges, rule) {
|
|
|
82402
82701
|
case "isLessThan":
|
|
82403
82702
|
case "isLessOrEqualTo":
|
|
82404
82703
|
return [values[0]];
|
|
82704
|
+
case "customFormula":
|
|
82705
|
+
return values[0].startsWith("=") ? [values[0].slice(1)] : [values[0]];
|
|
82405
82706
|
case "isBetween":
|
|
82406
82707
|
case "isNotBetween":
|
|
82407
82708
|
return [values[0], values[1]];
|
|
@@ -82430,6 +82731,8 @@ function cellRuleTypeAttributes(rule) {
|
|
|
82430
82731
|
case "isBetween":
|
|
82431
82732
|
case "isNotBetween":
|
|
82432
82733
|
return [["type", "cellIs"]];
|
|
82734
|
+
case "customFormula":
|
|
82735
|
+
return [["type", "expression"]];
|
|
82433
82736
|
}
|
|
82434
82737
|
}
|
|
82435
82738
|
function addDataBarRule(cf, rule) {
|
|
@@ -84463,6 +84766,7 @@ const stores = {
|
|
|
84463
84766
|
PivotSidePanelStore,
|
|
84464
84767
|
PivotMeasureDisplayPanelStore,
|
|
84465
84768
|
ClientFocusStore,
|
|
84769
|
+
GridRenderer,
|
|
84466
84770
|
};
|
|
84467
84771
|
function addFunction(functionName, functionDescription) {
|
|
84468
84772
|
functionRegistry.add(functionName, functionDescription);
|
|
@@ -84481,6 +84785,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
84481
84785
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
84482
84786
|
|
|
84483
84787
|
|
|
84484
|
-
__info__.version = "18.5.0-alpha.
|
|
84485
|
-
__info__.date = "2025-
|
|
84486
|
-
__info__.hash = "
|
|
84788
|
+
__info__.version = "18.5.0-alpha.3";
|
|
84789
|
+
__info__.date = "2025-07-28T13:43:05.981Z";
|
|
84790
|
+
__info__.hash = "53dfee8";
|