@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
|
'use strict';
|
|
@@ -854,6 +854,7 @@ const specialWhiteSpaceSpecialCharacters = [
|
|
|
854
854
|
];
|
|
855
855
|
const specialWhiteSpaceRegexp = new RegExp(specialWhiteSpaceSpecialCharacters.join("|"), "g");
|
|
856
856
|
const newLineRegexp = /(\r\n|\r)/g;
|
|
857
|
+
const whiteSpaceCharacters = specialWhiteSpaceSpecialCharacters.concat([" "]);
|
|
857
858
|
/**
|
|
858
859
|
* Replace all different newlines characters by \n
|
|
859
860
|
*/
|
|
@@ -1990,8 +1991,9 @@ const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
|
|
|
1990
1991
|
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
|
|
1991
1992
|
const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
|
|
1992
1993
|
const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
|
|
1993
|
-
const
|
|
1994
|
-
const
|
|
1994
|
+
const whiteSpaceChars = whiteSpaceCharacters.join("");
|
|
1995
|
+
const dateSeparatorsRegex = new RegExp(`\/|-|${whiteSpaceCharacters.join("|")}`);
|
|
1996
|
+
const dateRegexp = new RegExp(`^(\\d{1,4})[\/${whiteSpaceChars}\-](\\d{1,4})([\/${whiteSpaceChars}\-](\\d{1,4}))?$`);
|
|
1995
1997
|
const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
|
|
1996
1998
|
/** Convert a value number representing a date, or return undefined if it isn't possible */
|
|
1997
1999
|
function valueToDateNumber(value, locale) {
|
|
@@ -2901,6 +2903,7 @@ const availableConditionalFormatOperators = new Set([
|
|
|
2901
2903
|
"isEmpty",
|
|
2902
2904
|
"isNotEqual",
|
|
2903
2905
|
"isEqual",
|
|
2906
|
+
"customFormula",
|
|
2904
2907
|
]);
|
|
2905
2908
|
|
|
2906
2909
|
const availableDataValidationOperators = new Set([
|
|
@@ -5033,11 +5036,11 @@ function isTextFormat(format) {
|
|
|
5033
5036
|
}
|
|
5034
5037
|
}
|
|
5035
5038
|
|
|
5036
|
-
function evaluateLiteral(literalCell, localeFormat) {
|
|
5039
|
+
function evaluateLiteral(literalCell, localeFormat, position) {
|
|
5037
5040
|
const value = isTextFormat(localeFormat.format) && literalCell.parsedValue !== null
|
|
5038
5041
|
? literalCell.content
|
|
5039
5042
|
: literalCell.parsedValue;
|
|
5040
|
-
const functionResult = { value, format: localeFormat.format };
|
|
5043
|
+
const functionResult = { value, format: localeFormat.format, origin: position };
|
|
5041
5044
|
return createEvaluatedCell(functionResult, localeFormat.locale);
|
|
5042
5045
|
}
|
|
5043
5046
|
function parseLiteral(content, locale) {
|
|
@@ -5059,10 +5062,11 @@ function parseLiteral(content, locale) {
|
|
|
5059
5062
|
}
|
|
5060
5063
|
return content;
|
|
5061
5064
|
}
|
|
5062
|
-
function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell) {
|
|
5065
|
+
function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell, origin) {
|
|
5063
5066
|
const link = detectLink(functionResult.value);
|
|
5064
5067
|
if (!link) {
|
|
5065
|
-
|
|
5068
|
+
const evaluateCell = _createEvaluatedCell(functionResult, locale, cell);
|
|
5069
|
+
return addOrigin(evaluateCell, functionResult.origin ?? origin);
|
|
5066
5070
|
}
|
|
5067
5071
|
const value = parseLiteral(link.label, locale);
|
|
5068
5072
|
const format = functionResult.format ||
|
|
@@ -5073,10 +5077,10 @@ function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell) {
|
|
|
5073
5077
|
value,
|
|
5074
5078
|
format,
|
|
5075
5079
|
};
|
|
5076
|
-
return {
|
|
5080
|
+
return addOrigin({
|
|
5077
5081
|
..._createEvaluatedCell(linkPayload, locale, cell),
|
|
5078
5082
|
link,
|
|
5079
|
-
};
|
|
5083
|
+
}, functionResult.origin ?? origin);
|
|
5080
5084
|
}
|
|
5081
5085
|
function _createEvaluatedCell(functionResult, locale, cell) {
|
|
5082
5086
|
let { value, format, message } = functionResult;
|
|
@@ -5166,6 +5170,17 @@ function errorCell(value, message) {
|
|
|
5166
5170
|
defaultAlign: "center",
|
|
5167
5171
|
};
|
|
5168
5172
|
}
|
|
5173
|
+
function addOrigin(cell, origin) {
|
|
5174
|
+
if (cell.value === null) {
|
|
5175
|
+
// ignore empty cells to allow sharing the same object instance
|
|
5176
|
+
return cell;
|
|
5177
|
+
}
|
|
5178
|
+
if ("origin" in cell) {
|
|
5179
|
+
return cell;
|
|
5180
|
+
}
|
|
5181
|
+
cell.origin = origin;
|
|
5182
|
+
return cell;
|
|
5183
|
+
}
|
|
5169
5184
|
|
|
5170
5185
|
function toCriterionDateNumber(dateValue) {
|
|
5171
5186
|
const today = DateTime.now();
|
|
@@ -6926,6 +6941,8 @@ function splitWordToSpecificWidth(ctx, word, width, style) {
|
|
|
6926
6941
|
function splitTextToWidth(ctx, text, style, width) {
|
|
6927
6942
|
if (!style)
|
|
6928
6943
|
style = {};
|
|
6944
|
+
if (isMarkdownLink(text))
|
|
6945
|
+
text = parseMarkdownLink(text).label;
|
|
6929
6946
|
const brokenText = [];
|
|
6930
6947
|
// Checking if text contains NEWLINE before split makes it very slightly slower if text contains it,
|
|
6931
6948
|
// but 5-10x faster if it doesn't
|
|
@@ -7844,6 +7861,7 @@ function changeCFRuleLocale(rule, changeContentLocale) {
|
|
|
7844
7861
|
case "isGreaterOrEqualTo":
|
|
7845
7862
|
case "isLessThan":
|
|
7846
7863
|
case "isLessOrEqualTo":
|
|
7864
|
+
case "customFormula":
|
|
7847
7865
|
rule.values = rule.values.map((v) => changeContentLocale(v));
|
|
7848
7866
|
return rule;
|
|
7849
7867
|
case "beginsWithText":
|
|
@@ -8766,6 +8784,10 @@ function toNormalizedPivotValue(dimension, groupValue) {
|
|
|
8766
8784
|
if (groupValue === null || groupValue === "null") {
|
|
8767
8785
|
return null;
|
|
8768
8786
|
}
|
|
8787
|
+
const extractedGroupValue = typeof groupValue === "object" ? groupValue.value : groupValue;
|
|
8788
|
+
if (isEvaluationError(extractedGroupValue)) {
|
|
8789
|
+
return extractedGroupValue;
|
|
8790
|
+
}
|
|
8769
8791
|
const groupValueString = typeof groupValue === "boolean"
|
|
8770
8792
|
? toString(groupValue).toLocaleLowerCase()
|
|
8771
8793
|
: toString(groupValue);
|
|
@@ -10528,6 +10550,7 @@ const EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS = 100;
|
|
|
10528
10550
|
/** The possible values for the XLSX polynomial trendline order are defined by the ST_Order simple type (§21.2.3.29) */
|
|
10529
10551
|
const MAX_XLSX_POLYNOMIAL_DEGREE = 6;
|
|
10530
10552
|
const FIRST_NUMFMT_ID = 164;
|
|
10553
|
+
const DEFAULT_DOUGHNUT_CHART_HOLE_SIZE = 50;
|
|
10531
10554
|
const FORCE_DEFAULT_ARGS_FUNCTIONS = {
|
|
10532
10555
|
FLOOR: [{ type: "NUMBER", value: 1 }],
|
|
10533
10556
|
CEILING: [{ type: "NUMBER", value: 1 }],
|
|
@@ -19027,13 +19050,19 @@ const COLUMN = {
|
|
|
19027
19050
|
if (isEvaluationError(cellReference?.value)) {
|
|
19028
19051
|
return cellReference;
|
|
19029
19052
|
}
|
|
19030
|
-
|
|
19031
|
-
|
|
19032
|
-
|
|
19033
|
-
|
|
19034
|
-
return
|
|
19053
|
+
if (cellReference === undefined) {
|
|
19054
|
+
if (this.__originCellPosition?.col === undefined) {
|
|
19055
|
+
return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
|
|
19056
|
+
}
|
|
19057
|
+
return this.__originCellPosition.col + 1;
|
|
19058
|
+
}
|
|
19059
|
+
const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
|
|
19060
|
+
if (zone.left === zone.right) {
|
|
19061
|
+
return zone.left + 1;
|
|
19035
19062
|
}
|
|
19036
|
-
return
|
|
19063
|
+
return generateMatrix(zone.right - zone.left + 1, 1, (col, row) => ({
|
|
19064
|
+
value: zone.left + col + 1,
|
|
19065
|
+
}));
|
|
19037
19066
|
},
|
|
19038
19067
|
isExported: true,
|
|
19039
19068
|
};
|
|
@@ -19264,13 +19293,19 @@ const ROW = {
|
|
|
19264
19293
|
if (isEvaluationError(cellReference?.value)) {
|
|
19265
19294
|
return cellReference;
|
|
19266
19295
|
}
|
|
19267
|
-
|
|
19268
|
-
|
|
19269
|
-
|
|
19270
|
-
|
|
19271
|
-
return
|
|
19296
|
+
if (cellReference === undefined) {
|
|
19297
|
+
if (this.__originCellPosition?.row === undefined) {
|
|
19298
|
+
return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
|
|
19299
|
+
}
|
|
19300
|
+
return this.__originCellPosition.row + 1;
|
|
19272
19301
|
}
|
|
19273
|
-
|
|
19302
|
+
const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
|
|
19303
|
+
if (zone.top === zone.bottom) {
|
|
19304
|
+
return zone.top + 1;
|
|
19305
|
+
}
|
|
19306
|
+
return generateMatrix(1, zone.bottom - zone.top + 1, (col, row) => ({
|
|
19307
|
+
value: zone.top + row + 1,
|
|
19308
|
+
}));
|
|
19274
19309
|
},
|
|
19275
19310
|
isExported: true,
|
|
19276
19311
|
};
|
|
@@ -22847,6 +22882,16 @@ class AbstractChart {
|
|
|
22847
22882
|
static getDefinitionFromContextCreation(context) {
|
|
22848
22883
|
throw new Error("This method should be implemented by sub class");
|
|
22849
22884
|
}
|
|
22885
|
+
getCommonDataSetAttributesForExcel(labelRange, dataSets, shouldRemoveFirstLabel) {
|
|
22886
|
+
const excelDataSets = dataSets
|
|
22887
|
+
.map((ds) => toExcelDataset(this.getters, ds))
|
|
22888
|
+
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
22889
|
+
const excelLabelRange = toExcelLabelRange(this.getters, labelRange, shouldRemoveFirstLabel);
|
|
22890
|
+
return {
|
|
22891
|
+
dataSets: excelDataSets,
|
|
22892
|
+
labelRange: excelLabelRange,
|
|
22893
|
+
};
|
|
22894
|
+
}
|
|
22850
22895
|
}
|
|
22851
22896
|
|
|
22852
22897
|
function getBaselineText(baseline, keyValue, baselineMode, humanize, locale) {
|
|
@@ -26329,6 +26374,7 @@ class BarChart extends AbstractChart {
|
|
|
26329
26374
|
labelRange: context.auxiliaryRange || undefined,
|
|
26330
26375
|
axesDesign: context.axesDesign,
|
|
26331
26376
|
showValues: context.showValues,
|
|
26377
|
+
horizontal: context.horizontal,
|
|
26332
26378
|
};
|
|
26333
26379
|
}
|
|
26334
26380
|
getContextCreation() {
|
|
@@ -26386,10 +26432,7 @@ class BarChart extends AbstractChart {
|
|
|
26386
26432
|
};
|
|
26387
26433
|
}
|
|
26388
26434
|
getDefinitionForExcel() {
|
|
26389
|
-
const dataSets = this.dataSets
|
|
26390
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
26391
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
26392
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
26435
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
26393
26436
|
const definition = this.getDefinition();
|
|
26394
26437
|
return {
|
|
26395
26438
|
...definition,
|
|
@@ -26977,10 +27020,7 @@ class ComboChart extends AbstractChart {
|
|
|
26977
27020
|
if (this.aggregated) {
|
|
26978
27021
|
return undefined;
|
|
26979
27022
|
}
|
|
26980
|
-
const dataSets = this.dataSets
|
|
26981
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
26982
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
26983
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27023
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
26984
27024
|
const definition = this.getDefinition();
|
|
26985
27025
|
return {
|
|
26986
27026
|
...definition,
|
|
@@ -27448,7 +27488,9 @@ function getSectionThresholdValue(sheetId, threshold, minValue, maxValue, getter
|
|
|
27448
27488
|
}
|
|
27449
27489
|
function getFormulaNumberValue(sheetId, formula, getters) {
|
|
27450
27490
|
const value = getters.evaluateFormula(sheetId, formula);
|
|
27451
|
-
return
|
|
27491
|
+
return isMultipleElementMatrix(value)
|
|
27492
|
+
? undefined
|
|
27493
|
+
: tryToNumber(toScalar(value), getters.getLocale());
|
|
27452
27494
|
}
|
|
27453
27495
|
function getInvalidGaugeRuntime(chart, getters) {
|
|
27454
27496
|
return {
|
|
@@ -27717,10 +27759,7 @@ class LineChart extends AbstractChart {
|
|
|
27717
27759
|
return new LineChart(definition, this.sheetId, this.getters);
|
|
27718
27760
|
}
|
|
27719
27761
|
getDefinitionForExcel() {
|
|
27720
|
-
const dataSets = this.dataSets
|
|
27721
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
27722
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
27723
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27762
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27724
27763
|
const definition = this.getDefinition();
|
|
27725
27764
|
return {
|
|
27726
27765
|
...definition,
|
|
@@ -27808,7 +27847,8 @@ class PieChart extends AbstractChart {
|
|
|
27808
27847
|
type: "pie",
|
|
27809
27848
|
labelRange: context.auxiliaryRange || undefined,
|
|
27810
27849
|
aggregated: context.aggregated ?? false,
|
|
27811
|
-
isDoughnut:
|
|
27850
|
+
isDoughnut: context.isDoughnut,
|
|
27851
|
+
pieHolePercentage: context.pieHolePercentage,
|
|
27812
27852
|
showValues: context.showValues,
|
|
27813
27853
|
};
|
|
27814
27854
|
}
|
|
@@ -27856,10 +27896,7 @@ class PieChart extends AbstractChart {
|
|
|
27856
27896
|
return new PieChart(definition, sheetId, this.getters);
|
|
27857
27897
|
}
|
|
27858
27898
|
getDefinitionForExcel() {
|
|
27859
|
-
const dataSets = this.dataSets
|
|
27860
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
27861
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
27862
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27899
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27863
27900
|
return {
|
|
27864
27901
|
...this.getDefinition(),
|
|
27865
27902
|
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
@@ -28004,8 +28041,22 @@ class PyramidChart extends AbstractChart {
|
|
|
28004
28041
|
showValues: this.showValues,
|
|
28005
28042
|
};
|
|
28006
28043
|
}
|
|
28007
|
-
getDefinitionForExcel() {
|
|
28008
|
-
|
|
28044
|
+
getDefinitionForExcel(getters) {
|
|
28045
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
28046
|
+
const definition = this.getDefinition();
|
|
28047
|
+
const chartData = getPyramidChartData(definition, this.dataSets, this.labelRange, getters);
|
|
28048
|
+
const { dataSetsValues } = chartData;
|
|
28049
|
+
const maxValue = Math.max(...dataSetsValues.map((dataSet) => Math.max(...dataSet.data.map(Math.abs))));
|
|
28050
|
+
return {
|
|
28051
|
+
...definition,
|
|
28052
|
+
horizontal: true,
|
|
28053
|
+
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
28054
|
+
fontColor: toXlsxHexColor(chartFontColor(this.background)),
|
|
28055
|
+
dataSets,
|
|
28056
|
+
labelRange,
|
|
28057
|
+
verticalAxis: getDefinedAxis(definition),
|
|
28058
|
+
maxValue,
|
|
28059
|
+
};
|
|
28009
28060
|
}
|
|
28010
28061
|
updateRanges(applyChange) {
|
|
28011
28062
|
const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
|
|
@@ -28148,10 +28199,7 @@ class RadarChart extends AbstractChart {
|
|
|
28148
28199
|
if (this.aggregated) {
|
|
28149
28200
|
return undefined;
|
|
28150
28201
|
}
|
|
28151
|
-
const dataSets = this.dataSets
|
|
28152
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
28153
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
28154
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
28202
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
28155
28203
|
const definition = this.getDefinition();
|
|
28156
28204
|
return {
|
|
28157
28205
|
...definition,
|
|
@@ -31073,6 +31121,9 @@ class ErrorToolTip extends owl.Component {
|
|
|
31073
31121
|
return undefined;
|
|
31074
31122
|
}
|
|
31075
31123
|
get errorOriginPositionString() {
|
|
31124
|
+
if (this.env.model.getters.isDashboard()) {
|
|
31125
|
+
return "";
|
|
31126
|
+
}
|
|
31076
31127
|
const evaluationError = this.evaluationError;
|
|
31077
31128
|
const position = evaluationError?.errorOriginPosition;
|
|
31078
31129
|
if (!position || deepEquals(position, this.props.cellPosition)) {
|
|
@@ -32595,6 +32646,9 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
32595
32646
|
get isAutoCompleteDisplayed() {
|
|
32596
32647
|
return !!this.autoComplete.provider;
|
|
32597
32648
|
}
|
|
32649
|
+
get canBeToggled() {
|
|
32650
|
+
return this.autoComplete.provider?.canBeToggled ?? true;
|
|
32651
|
+
}
|
|
32598
32652
|
cycleReferences() {
|
|
32599
32653
|
const locale = this.getters.getLocale();
|
|
32600
32654
|
const updated = cycleFixedReference(this.composerSelection, this._currentContent, locale);
|
|
@@ -33124,6 +33178,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
33124
33178
|
proposals,
|
|
33125
33179
|
selectProposal: provider.selectProposal,
|
|
33126
33180
|
autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
|
|
33181
|
+
canBeToggled: provider.canBeToggled,
|
|
33127
33182
|
};
|
|
33128
33183
|
}
|
|
33129
33184
|
if (exactMatch && this._currentContent !== this.initialContent) {
|
|
@@ -33146,6 +33201,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
33146
33201
|
proposals,
|
|
33147
33202
|
selectProposal: provider.selectProposal,
|
|
33148
33203
|
autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
|
|
33204
|
+
canBeToggled: provider.canBeToggled,
|
|
33149
33205
|
};
|
|
33150
33206
|
}
|
|
33151
33207
|
}
|
|
@@ -33716,9 +33772,13 @@ class Composer extends owl.Component {
|
|
|
33716
33772
|
}
|
|
33717
33773
|
}
|
|
33718
33774
|
closeAssistant() {
|
|
33775
|
+
if (!this.props.composerStore.canBeToggled)
|
|
33776
|
+
return;
|
|
33719
33777
|
this.assistant.forcedClosed = true;
|
|
33720
33778
|
}
|
|
33721
33779
|
openAssistant() {
|
|
33780
|
+
if (!this.props.composerStore.canBeToggled)
|
|
33781
|
+
return;
|
|
33722
33782
|
this.assistant.forcedClosed = false;
|
|
33723
33783
|
}
|
|
33724
33784
|
onWheel(event) {
|
|
@@ -33908,7 +33968,7 @@ class Composer extends owl.Component {
|
|
|
33908
33968
|
return [...new Set(argsToFocus)];
|
|
33909
33969
|
}
|
|
33910
33970
|
autoComplete(value) {
|
|
33911
|
-
if (!value || this.assistant.forcedClosed) {
|
|
33971
|
+
if (!value || (this.assistant.forcedClosed && this.props.composerStore.canBeToggled)) {
|
|
33912
33972
|
return;
|
|
33913
33973
|
}
|
|
33914
33974
|
this.props.composerStore.insertAutoCompleteValue(value);
|
|
@@ -37486,7 +37546,7 @@ const CF_OPERATOR_TYPE_CONVERSION_MAP = {
|
|
|
37486
37546
|
/** Conversion map CF types in XLSX <=> Cf types in o_spreadsheet */
|
|
37487
37547
|
const CF_TYPE_CONVERSION_MAP = {
|
|
37488
37548
|
aboveAverage: undefined,
|
|
37489
|
-
expression:
|
|
37549
|
+
expression: "customFormula",
|
|
37490
37550
|
cellIs: undefined, // exist but isn't an operator in o_spreadsheet
|
|
37491
37551
|
colorScale: undefined, // exist but isn't an operator in o_spreadsheet
|
|
37492
37552
|
dataBar: undefined,
|
|
@@ -38090,7 +38150,6 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
38090
38150
|
case "containsErrors":
|
|
38091
38151
|
case "notContainsErrors":
|
|
38092
38152
|
case "duplicateValues":
|
|
38093
|
-
case "expression":
|
|
38094
38153
|
case "top10":
|
|
38095
38154
|
case "uniqueValues":
|
|
38096
38155
|
case "timePeriod":
|
|
@@ -38123,6 +38182,12 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
38123
38182
|
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
38124
38183
|
values.push(rule.text);
|
|
38125
38184
|
break;
|
|
38185
|
+
case "expression":
|
|
38186
|
+
if (!rule.formula?.length)
|
|
38187
|
+
continue;
|
|
38188
|
+
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
38189
|
+
values.push(`=${rule.formula[0]}`);
|
|
38190
|
+
break;
|
|
38126
38191
|
case "containsBlanks":
|
|
38127
38192
|
case "notContainsBlanks":
|
|
38128
38193
|
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
@@ -38352,6 +38417,8 @@ function convertOperator(operator) {
|
|
|
38352
38417
|
return "equal";
|
|
38353
38418
|
case "isNotEqual":
|
|
38354
38419
|
return "notEqual";
|
|
38420
|
+
case "customFormula":
|
|
38421
|
+
return "";
|
|
38355
38422
|
}
|
|
38356
38423
|
}
|
|
38357
38424
|
// -------------------------------------
|
|
@@ -38687,6 +38754,9 @@ function convertChartData(chartData) {
|
|
|
38687
38754
|
aggregated: false,
|
|
38688
38755
|
cumulative: chartData.cumulative || false,
|
|
38689
38756
|
labelsAsText: false,
|
|
38757
|
+
horizontal: chartData.horizontal,
|
|
38758
|
+
isDoughnut: chartData.isDoughnut,
|
|
38759
|
+
pieHolePercentage: chartData.pieHolePercentage,
|
|
38690
38760
|
};
|
|
38691
38761
|
try {
|
|
38692
38762
|
const ChartClass = chartRegistry.get(chartData.type);
|
|
@@ -39221,40 +39291,112 @@ function convertPivotTableConfig(pivotTable) {
|
|
|
39221
39291
|
* In all the sheets, replace the table-only references in the formula cells with standard references.
|
|
39222
39292
|
*/
|
|
39223
39293
|
function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
|
|
39294
|
+
let deconstructedSheets = null;
|
|
39224
39295
|
for (const tableSheet of convertedSheets) {
|
|
39225
39296
|
const tables = xlsxSheets.find((s) => isSheetNameEqual(s.sheetName, tableSheet.name)).tables;
|
|
39297
|
+
if (!tables || tables.length === 0) {
|
|
39298
|
+
continue;
|
|
39299
|
+
}
|
|
39300
|
+
// Only deconstruct sheets if we are sure there are tables to process
|
|
39301
|
+
if (!deconstructedSheets) {
|
|
39302
|
+
deconstructedSheets = deconstructSheets(convertedSheets);
|
|
39303
|
+
}
|
|
39226
39304
|
for (const table of tables) {
|
|
39227
|
-
const
|
|
39228
|
-
|
|
39229
|
-
for (const xc in
|
|
39230
|
-
const
|
|
39231
|
-
let
|
|
39232
|
-
|
|
39233
|
-
|
|
39234
|
-
|
|
39235
|
-
let endIndex = refIndex + tabRef.length;
|
|
39236
|
-
let openBrackets = 1;
|
|
39237
|
-
while (openBrackets > 0 && endIndex < cellContent.length) {
|
|
39238
|
-
if (cellContent[endIndex] === "[") {
|
|
39239
|
-
openBrackets++;
|
|
39240
|
-
}
|
|
39241
|
-
else if (cellContent[endIndex] === "]") {
|
|
39242
|
-
openBrackets--;
|
|
39243
|
-
}
|
|
39244
|
-
endIndex++;
|
|
39245
|
-
}
|
|
39246
|
-
const reference = cellContent.slice(refIndex + tabRef.length, endIndex - 1);
|
|
39247
|
-
const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
|
|
39248
|
-
const convertedRef = convertTableReference(sheetPrefix, reference, table, xc);
|
|
39249
|
-
cellContent =
|
|
39250
|
-
cellContent.slice(0, refIndex) + convertedRef + cellContent.slice(endIndex);
|
|
39305
|
+
for (const sheetId in deconstructedSheets) {
|
|
39306
|
+
const sheet = convertedSheets.find((s) => s.id === sheetId);
|
|
39307
|
+
for (const xc in deconstructedSheets[sheetId]) {
|
|
39308
|
+
const deconstructedCell = deconstructedSheets[sheetId][xc];
|
|
39309
|
+
for (let i = deconstructedCell.length - 3; i >= 0; i -= 2) {
|
|
39310
|
+
const possibleTable = deconstructedSheets[sheetId][xc][i];
|
|
39311
|
+
if (!possibleTable.endsWith(table.name)) {
|
|
39312
|
+
continue;
|
|
39251
39313
|
}
|
|
39314
|
+
const possibleRef = deconstructedSheets[sheetId][xc][i + 1];
|
|
39315
|
+
const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
|
|
39316
|
+
const convertedRef = convertTableReference(sheetPrefix, possibleRef, table, xc);
|
|
39317
|
+
deconstructedSheets[sheetId][xc][i + 2] =
|
|
39318
|
+
possibleTable.slice(0, possibleTable.indexOf(table.name)) +
|
|
39319
|
+
convertedRef +
|
|
39320
|
+
deconstructedSheets[sheetId][xc][i + 2];
|
|
39321
|
+
deconstructedSheets[sheetId][xc].splice(i, 2);
|
|
39322
|
+
}
|
|
39323
|
+
// sheet.cells[xc] = cellContent;
|
|
39324
|
+
}
|
|
39325
|
+
}
|
|
39326
|
+
}
|
|
39327
|
+
}
|
|
39328
|
+
if (!deconstructedSheets) {
|
|
39329
|
+
return;
|
|
39330
|
+
}
|
|
39331
|
+
for (const sheetId in deconstructedSheets) {
|
|
39332
|
+
const sheet = convertedSheets.find((s) => s.id === sheetId);
|
|
39333
|
+
for (const xc in deconstructedSheets[sheetId]) {
|
|
39334
|
+
const deconstructedCell = deconstructedSheets[sheetId][xc];
|
|
39335
|
+
if (deconstructedCell.length === 1) {
|
|
39336
|
+
sheet.cells[xc] = deconstructedCell[0];
|
|
39337
|
+
continue;
|
|
39338
|
+
}
|
|
39339
|
+
let newContent = "";
|
|
39340
|
+
for (let i = 0; i < deconstructedCell.length; i += 2) {
|
|
39341
|
+
newContent += deconstructedCell[i] + "[" + deconstructedCell[i + 1] + "]";
|
|
39342
|
+
}
|
|
39343
|
+
newContent += deconstructedCell[deconstructedCell.length - 1];
|
|
39344
|
+
sheet.cells[xc] = newContent;
|
|
39345
|
+
}
|
|
39346
|
+
}
|
|
39347
|
+
}
|
|
39348
|
+
/**
|
|
39349
|
+
* Deconstruct the content of the cells in the sheets to extract possible table references.
|
|
39350
|
+
* Example from "=AVERAGE(Table1[colName1])-AVERAGE(Table2[colName2])":
|
|
39351
|
+
* return --> ["=AVERAGE(Table1", "colName1", ")-AVERAGE(Table2", "colName2", ")"]
|
|
39352
|
+
*/
|
|
39353
|
+
function deconstructSheets(convertedSheets) {
|
|
39354
|
+
const deconstructedSheets = {};
|
|
39355
|
+
for (const sheet of convertedSheets) {
|
|
39356
|
+
for (const xc in sheet.cells) {
|
|
39357
|
+
const cellContent = sheet.cells[xc];
|
|
39358
|
+
if (!cellContent || !cellContent.startsWith("=")) {
|
|
39359
|
+
continue;
|
|
39360
|
+
}
|
|
39361
|
+
const startIndex = cellContent.indexOf("[");
|
|
39362
|
+
if (startIndex === -1) {
|
|
39363
|
+
continue;
|
|
39364
|
+
}
|
|
39365
|
+
const deconstructedCell = [];
|
|
39366
|
+
let possibleTable = cellContent.slice(0, startIndex);
|
|
39367
|
+
let possibleRef = "";
|
|
39368
|
+
let openBrackets = 1;
|
|
39369
|
+
let mainPossibleTableIndex = 0;
|
|
39370
|
+
let mainOpenBracketIndex = startIndex;
|
|
39371
|
+
for (let index = startIndex + 1; index < cellContent.length; index++) {
|
|
39372
|
+
if (cellContent[index] === "[") {
|
|
39373
|
+
if (openBrackets === 0) {
|
|
39374
|
+
possibleTable = cellContent.slice(mainPossibleTableIndex, index);
|
|
39375
|
+
mainOpenBracketIndex = index;
|
|
39252
39376
|
}
|
|
39253
|
-
|
|
39377
|
+
openBrackets++;
|
|
39378
|
+
continue;
|
|
39254
39379
|
}
|
|
39380
|
+
if (cellContent[index] === "]") {
|
|
39381
|
+
openBrackets--;
|
|
39382
|
+
if (openBrackets === 0) {
|
|
39383
|
+
possibleRef = cellContent.slice(mainOpenBracketIndex + 1, index);
|
|
39384
|
+
deconstructedCell.push(possibleTable);
|
|
39385
|
+
deconstructedCell.push(possibleRef);
|
|
39386
|
+
mainPossibleTableIndex = index + 1;
|
|
39387
|
+
}
|
|
39388
|
+
}
|
|
39389
|
+
}
|
|
39390
|
+
if (deconstructedCell.length) {
|
|
39391
|
+
if (!deconstructedSheets[sheet.id]) {
|
|
39392
|
+
deconstructedSheets[sheet.id] = {};
|
|
39393
|
+
}
|
|
39394
|
+
deconstructedCell.push(cellContent.slice(mainPossibleTableIndex));
|
|
39395
|
+
deconstructedSheets[sheet.id][xc] = [...deconstructedCell];
|
|
39255
39396
|
}
|
|
39256
39397
|
}
|
|
39257
39398
|
}
|
|
39399
|
+
return deconstructedSheets;
|
|
39258
39400
|
}
|
|
39259
39401
|
/**
|
|
39260
39402
|
* Convert table-specific references in formulas into standard references. A table reference is composed of columns names,
|
|
@@ -39891,6 +40033,12 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
39891
40033
|
const barChartGrouping = this.extractChildAttr(rootChartElement, "c:grouping", "val", {
|
|
39892
40034
|
default: "clustered",
|
|
39893
40035
|
}).asString();
|
|
40036
|
+
const chartDirection = this.extractChildAttr(rootChartElement, "c:barDir", "val", {
|
|
40037
|
+
default: "col",
|
|
40038
|
+
}).asString();
|
|
40039
|
+
const chartHoleSize = this.extractChildAttr(rootChartElement, "c:holeSize", "val", {
|
|
40040
|
+
default: "0",
|
|
40041
|
+
}).asNum();
|
|
39894
40042
|
return {
|
|
39895
40043
|
title: { text: chartTitle },
|
|
39896
40044
|
type: CHART_TYPE_CONVERSION_MAP[chartType],
|
|
@@ -39904,6 +40052,9 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
39904
40052
|
}).asString()],
|
|
39905
40053
|
stacked: barChartGrouping === "stacked",
|
|
39906
40054
|
fontColor: "000000",
|
|
40055
|
+
horizontal: chartDirection === "bar",
|
|
40056
|
+
isDoughnut: chartHoleSize > 0,
|
|
40057
|
+
pieHolePercentage: chartHoleSize,
|
|
39907
40058
|
};
|
|
39908
40059
|
})[0];
|
|
39909
40060
|
}
|
|
@@ -45566,10 +45717,10 @@ class CellComposerStore extends AbstractComposerStore {
|
|
|
45566
45717
|
const cellValue = isFormula(content)
|
|
45567
45718
|
? this.getters.evaluateFormula(this.sheetId, content)
|
|
45568
45719
|
: parseLiteral(content, this.getters.getLocale());
|
|
45569
|
-
if (
|
|
45720
|
+
if (isMultipleElementMatrix(cellValue)) {
|
|
45570
45721
|
return true;
|
|
45571
45722
|
}
|
|
45572
|
-
const validationResult = this.getters.getValidationResultForCellValue(cellValue, cellPosition);
|
|
45723
|
+
const validationResult = this.getters.getValidationResultForCellValue(toScalar(cellValue), cellPosition);
|
|
45573
45724
|
if (!validationResult.isValid && validationResult.rule.isBlocking) {
|
|
45574
45725
|
return false;
|
|
45575
45726
|
}
|
|
@@ -50681,10 +50832,10 @@ class GaugeChartDesignPanel extends owl.Component {
|
|
|
50681
50832
|
return tryToNumber(value, locale) !== undefined;
|
|
50682
50833
|
}
|
|
50683
50834
|
const evaluatedValue = this.env.model.getters.evaluateFormula(this.sheetId, value);
|
|
50684
|
-
if (
|
|
50835
|
+
if (isMultipleElementMatrix(evaluatedValue)) {
|
|
50685
50836
|
return false;
|
|
50686
50837
|
}
|
|
50687
|
-
return tryToNumber(evaluatedValue, locale) !== undefined;
|
|
50838
|
+
return tryToNumber(toScalar(evaluatedValue), locale) !== undefined;
|
|
50688
50839
|
}
|
|
50689
50840
|
get sheetId() {
|
|
50690
50841
|
const chart = this.env.model.getters.getChart(this.props.figureId);
|
|
@@ -50894,6 +51045,9 @@ class PieChartDesignPanel extends owl.Component {
|
|
|
50894
51045
|
pieHolePercentage,
|
|
50895
51046
|
});
|
|
50896
51047
|
}
|
|
51048
|
+
get defaultHoleSize() {
|
|
51049
|
+
return DEFAULT_DOUGHNUT_CHART_HOLE_SIZE;
|
|
51050
|
+
}
|
|
50897
51051
|
}
|
|
50898
51052
|
|
|
50899
51053
|
class RadarChartDesignPanel extends owl.Component {
|
|
@@ -51538,12 +51692,32 @@ class ChartPanel extends owl.Component {
|
|
|
51538
51692
|
static template = "o-spreadsheet-ChartPanel";
|
|
51539
51693
|
static components = { Section, ChartTypePicker };
|
|
51540
51694
|
static props = { onCloseSidePanel: Function, figureId: String };
|
|
51695
|
+
panelContentRef;
|
|
51696
|
+
scrollPositions = {
|
|
51697
|
+
configuration: 0,
|
|
51698
|
+
design: 0,
|
|
51699
|
+
};
|
|
51541
51700
|
store;
|
|
51542
51701
|
get figureId() {
|
|
51543
51702
|
return this.props.figureId;
|
|
51544
51703
|
}
|
|
51545
51704
|
setup() {
|
|
51546
51705
|
this.store = useLocalStore(MainChartPanelStore);
|
|
51706
|
+
this.panelContentRef = owl.useRef("panelContent");
|
|
51707
|
+
owl.useEffect(() => {
|
|
51708
|
+
const el = this.panelContentRef.el;
|
|
51709
|
+
const activePanel = this.store.panel;
|
|
51710
|
+
if (el) {
|
|
51711
|
+
el.scrollTop = this.scrollPositions[activePanel];
|
|
51712
|
+
}
|
|
51713
|
+
}, () => [this.store.panel]);
|
|
51714
|
+
}
|
|
51715
|
+
switchPanel(panel) {
|
|
51716
|
+
const el = this.panelContentRef.el;
|
|
51717
|
+
if (el) {
|
|
51718
|
+
this.scrollPositions[this.store.panel] = el.scrollTop;
|
|
51719
|
+
}
|
|
51720
|
+
this.store.activatePanel(panel);
|
|
51547
51721
|
}
|
|
51548
51722
|
updateChart(figureId, updateDefinition) {
|
|
51549
51723
|
if (figureId !== this.figureId) {
|
|
@@ -55495,10 +55669,7 @@ class SpreadsheetPivot {
|
|
|
55495
55669
|
if (finalCell.value === null) {
|
|
55496
55670
|
return { value: _t("(Undefined)") };
|
|
55497
55671
|
}
|
|
55498
|
-
return
|
|
55499
|
-
value: finalCell.value,
|
|
55500
|
-
format: finalCell.format,
|
|
55501
|
-
};
|
|
55672
|
+
return finalCell;
|
|
55502
55673
|
}
|
|
55503
55674
|
getPivotCellValueAndFormat(measureId, domain) {
|
|
55504
55675
|
const dataEntries = this.filterDataEntriesFromDomain(this.dataEntries, domain);
|
|
@@ -55600,9 +55771,15 @@ class SpreadsheetPivot {
|
|
|
55600
55771
|
return domain.reduce((current, acc) => this.filterDataEntriesFromDomainNode(current, acc), dataEntries);
|
|
55601
55772
|
}
|
|
55602
55773
|
filterDataEntriesFromDomainNode(dataEntries, domain) {
|
|
55603
|
-
const { field, value } = domain;
|
|
55774
|
+
const { field, value, type } = domain;
|
|
55604
55775
|
const { nameWithGranularity } = this.getDimension(field);
|
|
55605
|
-
return dataEntries.filter((entry) =>
|
|
55776
|
+
return dataEntries.filter((entry) => {
|
|
55777
|
+
const cellValue = entry[nameWithGranularity]?.value;
|
|
55778
|
+
if (type === "char") {
|
|
55779
|
+
return String(cellValue) === String(value);
|
|
55780
|
+
}
|
|
55781
|
+
return cellValue === value;
|
|
55782
|
+
});
|
|
55606
55783
|
}
|
|
55607
55784
|
getDimension(nameWithGranularity) {
|
|
55608
55785
|
return this.definition.getDimension(nameWithGranularity);
|
|
@@ -55736,7 +55913,6 @@ pivotRegistry.add("SPREADSHEET", {
|
|
|
55736
55913
|
ui: SpreadsheetPivot,
|
|
55737
55914
|
definition: SpreadsheetPivotRuntimeDefinition,
|
|
55738
55915
|
externalData: false,
|
|
55739
|
-
onIterationEndEvaluation: (pivot) => pivot.markAsDirtyForEvaluation(),
|
|
55740
55916
|
dateGranularities: [...dateGranularities],
|
|
55741
55917
|
datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
|
|
55742
55918
|
isMeasureCandidate: (field) => field.type !== "boolean",
|
|
@@ -64387,7 +64563,7 @@ const onIterationEndEvaluationRegistry = new Registry();
|
|
|
64387
64563
|
onIterationEndEvaluationRegistry.add("pivots", (getters) => {
|
|
64388
64564
|
for (const pivotId of getters.getPivotIds()) {
|
|
64389
64565
|
const pivot = getters.getPivot(pivotId);
|
|
64390
|
-
|
|
64566
|
+
pivot.markAsDirtyForEvaluation?.();
|
|
64391
64567
|
}
|
|
64392
64568
|
});
|
|
64393
64569
|
|
|
@@ -65555,7 +65731,7 @@ class SpreadingRelation {
|
|
|
65555
65731
|
const EMPTY_ARRAY = [];
|
|
65556
65732
|
|
|
65557
65733
|
const MAX_ITERATION = 30;
|
|
65558
|
-
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
|
|
65734
|
+
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell({ ...new CircularDependencyError(), origin: undefined }));
|
|
65559
65735
|
const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
|
|
65560
65736
|
class Evaluator {
|
|
65561
65737
|
context;
|
|
@@ -65789,11 +65965,12 @@ class Evaluator {
|
|
|
65789
65965
|
this.cellsBeingComputed.add(cellId);
|
|
65790
65966
|
return cell.isFormula
|
|
65791
65967
|
? this.computeFormulaCell(position, cell)
|
|
65792
|
-
: evaluateLiteral(cell, localeFormat);
|
|
65968
|
+
: evaluateLiteral(cell, localeFormat, position);
|
|
65793
65969
|
}
|
|
65794
65970
|
catch (e) {
|
|
65795
65971
|
e.value = e?.value || CellErrorType.GenericError;
|
|
65796
65972
|
e.message = e?.message || implementationErrorMessage;
|
|
65973
|
+
e.origin = position;
|
|
65797
65974
|
return createEvaluatedCell(e);
|
|
65798
65975
|
}
|
|
65799
65976
|
finally {
|
|
@@ -65810,7 +65987,7 @@ class Evaluator {
|
|
|
65810
65987
|
computeFormulaCell(formulaPosition, cellData) {
|
|
65811
65988
|
const formulaReturn = updateEvalContextAndExecute(cellData.compiledFormula, this.compilationParams, formulaPosition.sheetId, this.buildSafeGetSymbolValue(), formulaPosition);
|
|
65812
65989
|
if (!isMatrix(formulaReturn)) {
|
|
65813
|
-
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(formulaReturn), this.getters.getLocale(), cellData);
|
|
65990
|
+
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(formulaReturn), this.getters.getLocale(), cellData, formulaPosition);
|
|
65814
65991
|
if (evaluatedCell.type === CellValueType.error) {
|
|
65815
65992
|
evaluatedCell.errorOriginPosition = formulaReturn.errorOriginPosition ?? formulaPosition;
|
|
65816
65993
|
}
|
|
@@ -65886,7 +66063,7 @@ class Evaluator {
|
|
|
65886
66063
|
const spreadValues = (i, j) => {
|
|
65887
66064
|
const position = { sheetId, col: i + col, row: j + row };
|
|
65888
66065
|
const cell = this.getters.getCell(position);
|
|
65889
|
-
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell);
|
|
66066
|
+
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell, position);
|
|
65890
66067
|
if (evaluatedCell.type === CellValueType.error) {
|
|
65891
66068
|
evaluatedCell.errorOriginPosition = matrixResult[i][j].errorOriginPosition ?? position;
|
|
65892
66069
|
}
|
|
@@ -66559,7 +66736,7 @@ class EvaluationChartPlugin extends CoreViewPlugin {
|
|
|
66559
66736
|
continue;
|
|
66560
66737
|
}
|
|
66561
66738
|
const figureId = figure.id;
|
|
66562
|
-
const figureData = this.getters.getChart(figureId)?.getDefinitionForExcel();
|
|
66739
|
+
const figureData = this.getters.getChart(figureId)?.getDefinitionForExcel(this.getters);
|
|
66563
66740
|
if (figureData) {
|
|
66564
66741
|
figures.push({
|
|
66565
66742
|
...figure,
|
|
@@ -66851,12 +67028,12 @@ class EvaluationConditionalFormatPlugin extends CoreViewPlugin {
|
|
|
66851
67028
|
}
|
|
66852
67029
|
return this.getters.evaluateFormula(sheetId, value) ?? "";
|
|
66853
67030
|
});
|
|
66854
|
-
if (evaluatedCriterionValues.some(
|
|
67031
|
+
if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
|
|
66855
67032
|
return false;
|
|
66856
67033
|
}
|
|
66857
67034
|
const evaluatedCriterion = {
|
|
66858
67035
|
type: rule.operator,
|
|
66859
|
-
values: evaluatedCriterionValues,
|
|
67036
|
+
values: evaluatedCriterionValues.map(toScalar),
|
|
66860
67037
|
};
|
|
66861
67038
|
return evaluator.isValueValid(cell.value ?? "", evaluatedCriterion, this.getters, sheetId);
|
|
66862
67039
|
}
|
|
@@ -67016,10 +67193,10 @@ class EvaluationDataValidationPlugin extends CoreViewPlugin {
|
|
|
67016
67193
|
const evaluator = criterionEvaluatorRegistry.get(criterion.type);
|
|
67017
67194
|
const offset = this.getCellOffsetInRule(cellPosition, rule);
|
|
67018
67195
|
const evaluatedCriterionValues = this.getEvaluatedCriterionValues(sheetId, offset, criterion);
|
|
67019
|
-
if (evaluatedCriterionValues.some(
|
|
67196
|
+
if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
|
|
67020
67197
|
return undefined;
|
|
67021
67198
|
}
|
|
67022
|
-
const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues };
|
|
67199
|
+
const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues.map(toScalar) };
|
|
67023
67200
|
if (evaluator.isValueValid(cellValue, evaluatedCriterion, this.getters, sheetId)) {
|
|
67024
67201
|
return undefined;
|
|
67025
67202
|
}
|
|
@@ -67472,6 +67649,23 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
|
|
|
67472
67649
|
static getters = ["getRowSize", "getHeaderSize", "getMaxAnchorOffset"];
|
|
67473
67650
|
tallestCellInRow = {};
|
|
67474
67651
|
ctx = document.createElement("canvas").getContext("2d");
|
|
67652
|
+
beforeHandle(cmd) {
|
|
67653
|
+
switch (cmd.type) {
|
|
67654
|
+
// Ensure rows are updated before "UPDATE_CELL" is dispatched from cell plugin.
|
|
67655
|
+
// "UPDATE_CELL" uses the Sheet core plugin to access row data.
|
|
67656
|
+
// If "ADD_COLUMNS_ROWS" has not been processed yet by header_sizes_ui,
|
|
67657
|
+
// size updates may apply to incorrect (pre-insert) rows.
|
|
67658
|
+
case "ADD_COLUMNS_ROWS":
|
|
67659
|
+
if (cmd.dimension === "COL") {
|
|
67660
|
+
return;
|
|
67661
|
+
}
|
|
67662
|
+
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
67663
|
+
const newCells = Array(cmd.quantity).fill(undefined);
|
|
67664
|
+
const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
|
|
67665
|
+
this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
|
|
67666
|
+
break;
|
|
67667
|
+
}
|
|
67668
|
+
}
|
|
67475
67669
|
handle(cmd) {
|
|
67476
67670
|
switch (cmd.type) {
|
|
67477
67671
|
case "START":
|
|
@@ -67501,16 +67695,6 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
|
|
|
67501
67695
|
this.history.update("tallestCellInRow", cmd.sheetId, tallestCells);
|
|
67502
67696
|
break;
|
|
67503
67697
|
}
|
|
67504
|
-
case "ADD_COLUMNS_ROWS": {
|
|
67505
|
-
if (cmd.dimension === "COL") {
|
|
67506
|
-
return;
|
|
67507
|
-
}
|
|
67508
|
-
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
67509
|
-
const newCells = Array(cmd.quantity).fill(undefined);
|
|
67510
|
-
const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
|
|
67511
|
-
this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
|
|
67512
|
-
break;
|
|
67513
|
-
}
|
|
67514
67698
|
case "RESIZE_COLUMNS_ROWS":
|
|
67515
67699
|
{
|
|
67516
67700
|
const sheetId = cmd.sheetId;
|
|
@@ -67662,13 +67846,13 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
67662
67846
|
super(custom, params);
|
|
67663
67847
|
this.getters = params.getters;
|
|
67664
67848
|
}
|
|
67665
|
-
|
|
67849
|
+
markAsDirtyForEvaluation() {
|
|
67666
67850
|
this.cache = {};
|
|
67667
67851
|
this.rankAsc = {};
|
|
67668
67852
|
this.rankDesc = {};
|
|
67669
67853
|
this.runningTotal = {};
|
|
67670
67854
|
this.runningTotalInPercent = {};
|
|
67671
|
-
super.
|
|
67855
|
+
super.markAsDirtyForEvaluation?.();
|
|
67672
67856
|
}
|
|
67673
67857
|
getPivotCellValueAndFormat(measureName, domain) {
|
|
67674
67858
|
return this.getMeasureDisplayValue(measureName, domain);
|
|
@@ -67793,7 +67977,7 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
67793
67977
|
return this.getSubTreeMatchingDomain(node.children, domain, domainLevel + 1);
|
|
67794
67978
|
}
|
|
67795
67979
|
}
|
|
67796
|
-
return
|
|
67980
|
+
return [];
|
|
67797
67981
|
}
|
|
67798
67982
|
treeToLeafDomains(tree, parentDomain = []) {
|
|
67799
67983
|
const domains = [];
|
|
@@ -73532,12 +73716,12 @@ class FilterEvaluationPlugin extends UIPlugin {
|
|
|
73532
73716
|
}
|
|
73533
73717
|
return this.getters.evaluateFormula(sheetId, value) ?? "";
|
|
73534
73718
|
});
|
|
73535
|
-
if (evaluatedCriterionValues.some(
|
|
73719
|
+
if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
|
|
73536
73720
|
continue;
|
|
73537
73721
|
}
|
|
73538
73722
|
const evaluatedCriterion = {
|
|
73539
73723
|
type: filterValue.type,
|
|
73540
|
-
values: evaluatedCriterionValues,
|
|
73724
|
+
values: evaluatedCriterionValues.map(toScalar),
|
|
73541
73725
|
dateValue: filterValue.dateValue,
|
|
73542
73726
|
};
|
|
73543
73727
|
for (let row = filteredZone.top; row <= filteredZone.bottom; row++) {
|
|
@@ -74059,6 +74243,14 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
74059
74243
|
const isBasedBefore = cmd.base < start;
|
|
74060
74244
|
const deltaCol = isBasedBefore && isCol ? thickness : 0;
|
|
74061
74245
|
const deltaRow = isBasedBefore && !isCol ? thickness : 0;
|
|
74246
|
+
const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
|
|
74247
|
+
const originalSize = Object.fromEntries(toRemove.map((element) => {
|
|
74248
|
+
const size = isCol
|
|
74249
|
+
? this.getters.getColSize(cmd.sheetId, element)
|
|
74250
|
+
: this.getters.getUserRowSize(cmd.sheetId, element);
|
|
74251
|
+
const isDefaultCol = isCol && size === DEFAULT_CELL_WIDTH;
|
|
74252
|
+
return [element, isDefaultCol ? undefined : size];
|
|
74253
|
+
}));
|
|
74062
74254
|
const target = [
|
|
74063
74255
|
{
|
|
74064
74256
|
left: isCol ? start + deltaCol : 0,
|
|
@@ -74089,13 +74281,12 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
74089
74281
|
const col = selection.left;
|
|
74090
74282
|
const row = selection.top;
|
|
74091
74283
|
this.setSelectionMixin({ zone: selection, cell: { col, row } }, [selection]);
|
|
74092
|
-
const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
|
|
74093
74284
|
let currentIndex = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
74094
74285
|
const resizingGroups = {};
|
|
74095
74286
|
for (const element of toRemove) {
|
|
74096
|
-
const size =
|
|
74287
|
+
const size = originalSize[element];
|
|
74097
74288
|
const currentSize = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, currentIndex);
|
|
74098
|
-
if (size !== currentSize) {
|
|
74289
|
+
if (size && size !== currentSize) {
|
|
74099
74290
|
resizingGroups[size] ??= [];
|
|
74100
74291
|
resizingGroups[size].push(currentIndex);
|
|
74101
74292
|
currentIndex += 1;
|
|
@@ -75521,6 +75712,7 @@ const coreViewsPluginRegistry = new Registry()
|
|
|
75521
75712
|
|
|
75522
75713
|
autoCompleteProviders.add("dataValidation", {
|
|
75523
75714
|
displayAllOnInitialContent: true,
|
|
75715
|
+
canBeToggled: false,
|
|
75524
75716
|
getProposals(tokenAtCursor, content) {
|
|
75525
75717
|
if (isFormula(content)) {
|
|
75526
75718
|
return [];
|
|
@@ -77086,14 +77278,12 @@ class BottomBarSheet extends owl.Component {
|
|
|
77086
77278
|
this.editionState = "initializing";
|
|
77087
77279
|
}
|
|
77088
77280
|
stopEdition() {
|
|
77089
|
-
|
|
77090
|
-
if (!this.state.isEditing || !input)
|
|
77281
|
+
if (!this.state.isEditing || !this.sheetNameRef.el)
|
|
77091
77282
|
return;
|
|
77092
77283
|
this.state.isEditing = false;
|
|
77093
77284
|
this.editionState = "initializing";
|
|
77094
|
-
|
|
77285
|
+
this.sheetNameRef.el.blur();
|
|
77095
77286
|
const inputValue = this.getInputContent() || "";
|
|
77096
|
-
input.innerText = inputValue;
|
|
77097
77287
|
interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
|
|
77098
77288
|
}
|
|
77099
77289
|
cancelEdition() {
|
|
@@ -81511,6 +81701,9 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81511
81701
|
case "combo":
|
|
81512
81702
|
plot = addComboChart(chart.data);
|
|
81513
81703
|
break;
|
|
81704
|
+
case "pyramid":
|
|
81705
|
+
plot = addPyramidChart(chart.data);
|
|
81706
|
+
break;
|
|
81514
81707
|
case "line":
|
|
81515
81708
|
plot = addLineChart(chart.data);
|
|
81516
81709
|
break;
|
|
@@ -81518,12 +81711,12 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81518
81711
|
plot = addScatterChart(chart.data);
|
|
81519
81712
|
break;
|
|
81520
81713
|
case "pie":
|
|
81521
|
-
plot = addDoughnutChart(chart.data, chartSheetIndex, data
|
|
81714
|
+
plot = addDoughnutChart(chart.data, chartSheetIndex, data);
|
|
81522
81715
|
break;
|
|
81523
81716
|
case "radar":
|
|
81524
81717
|
plot = addRadarChart(chart.data);
|
|
81525
81718
|
}
|
|
81526
|
-
let position = "
|
|
81719
|
+
let position = "none";
|
|
81527
81720
|
switch (chart.data.legendPosition) {
|
|
81528
81721
|
case "bottom":
|
|
81529
81722
|
position = "b";
|
|
@@ -81553,7 +81746,7 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81553
81746
|
${plot}
|
|
81554
81747
|
${shapeProperty({ backgroundColor: chart.data.backgroundColor })}
|
|
81555
81748
|
</c:plotArea>
|
|
81556
|
-
${addLegend(position, fontColor)}
|
|
81749
|
+
${position !== "none" ? addLegend(position, fontColor) : ""}
|
|
81557
81750
|
</c:chart>
|
|
81558
81751
|
</c:chartSpace>
|
|
81559
81752
|
`;
|
|
@@ -81711,6 +81904,7 @@ function addBarChart(chart) {
|
|
|
81711
81904
|
//
|
|
81712
81905
|
// overlap and gapWitdh seems to be by default at -20 and 20 in chart.js.
|
|
81713
81906
|
// See https://www.chartjs.org/docs/latest/charts/bar.html and https://www.chartjs.org/docs/latest/charts/bar.html#barpercentage-vs-categorypercentage
|
|
81907
|
+
const chartDirection = chart.horizontal ? "bar" : "col";
|
|
81714
81908
|
const dataSetsColors = chart.dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
81715
81909
|
const colors = new ColorGenerator(chart.dataSets.length, dataSetsColors);
|
|
81716
81910
|
const leftDataSetsNodes = [];
|
|
@@ -81747,7 +81941,7 @@ function addBarChart(chart) {
|
|
|
81747
81941
|
${leftDataSetsNodes.length
|
|
81748
81942
|
? escapeXml /*xml*/ `
|
|
81749
81943
|
<c:barChart>
|
|
81750
|
-
<c:barDir val="
|
|
81944
|
+
<c:barDir val="${chartDirection}"/>
|
|
81751
81945
|
<c:grouping val="${grouping}"/>
|
|
81752
81946
|
<c:overlap val="${overlap}"/>
|
|
81753
81947
|
<c:gapWidth val="70"/>
|
|
@@ -81757,8 +81951,12 @@ function addBarChart(chart) {
|
|
|
81757
81951
|
<c:axId val="${catAxId}" />
|
|
81758
81952
|
<c:axId val="${valAxId}" />
|
|
81759
81953
|
</c:barChart>
|
|
81760
|
-
${
|
|
81761
|
-
|
|
81954
|
+
${chartDirection === "col"
|
|
81955
|
+
? addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.x?.title, chart.fontColor)
|
|
81956
|
+
: addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.y?.title, chart.fontColor, undefined, "maxMin")}
|
|
81957
|
+
${chartDirection === "col"
|
|
81958
|
+
? addAx("l", "c:valAx", valAxId, catAxId, chart.axesDesign?.y?.title, chart.fontColor)
|
|
81959
|
+
: addAx("l", "c:valAx", valAxId, catAxId, chart.axesDesign?.x?.title, chart.fontColor, undefined, undefined, "max")}
|
|
81762
81960
|
`
|
|
81763
81961
|
: ""}
|
|
81764
81962
|
${rightDataSetsNodes.length
|
|
@@ -81884,7 +82082,7 @@ function addComboChart(chart) {
|
|
|
81884
82082
|
: ""}
|
|
81885
82083
|
${!useRightAxisForBarSerie || leftDataSetsNodes.length
|
|
81886
82084
|
? escapeXml /*xml*/ `
|
|
81887
|
-
${addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.x?.title, chart.fontColor,
|
|
82085
|
+
${addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.x?.title, chart.fontColor, 0)}
|
|
81888
82086
|
${addAx("l", "c:valAx", valAxId, catAxId, chart.axesDesign?.y?.title, chart.fontColor)}
|
|
81889
82087
|
`
|
|
81890
82088
|
: ""}
|
|
@@ -81896,6 +82094,94 @@ function addComboChart(chart) {
|
|
|
81896
82094
|
: ""}
|
|
81897
82095
|
`;
|
|
81898
82096
|
}
|
|
82097
|
+
function addPyramidChart(chart) {
|
|
82098
|
+
const dataSets = chart.dataSets;
|
|
82099
|
+
const dataSetsColors = dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
82100
|
+
const colors = new ColorGenerator(dataSets.length, dataSetsColors);
|
|
82101
|
+
const leftDataSet = dataSets[0];
|
|
82102
|
+
const rightDataSet = dataSets[1];
|
|
82103
|
+
const firstColor = toXlsxHexColor(colors.next());
|
|
82104
|
+
const secondColor = toXlsxHexColor(colors.next());
|
|
82105
|
+
const { maxValue, majorUnit } = getPyramidChartHorizontalAxisConfig(chart.maxValue);
|
|
82106
|
+
const labelRangeEl = chart.labelRange
|
|
82107
|
+
? escapeXml `<c:cat>${stringRef(chart.labelRange)}</c:cat>`
|
|
82108
|
+
: "";
|
|
82109
|
+
const leftBarDataSetNode = escapeXml /*xml*/ `
|
|
82110
|
+
<c:ser>
|
|
82111
|
+
<c:idx val="0"/>
|
|
82112
|
+
<c:order val="0"/>
|
|
82113
|
+
<c:invertIfNegative val="0" />
|
|
82114
|
+
${extractDataSetLabel(leftDataSet.label)}
|
|
82115
|
+
${shapeProperty({
|
|
82116
|
+
backgroundColor: firstColor,
|
|
82117
|
+
line: { color: firstColor },
|
|
82118
|
+
})}
|
|
82119
|
+
${labelRangeEl}
|
|
82120
|
+
<!-- x-coordinate values -->
|
|
82121
|
+
<c:val>
|
|
82122
|
+
${numberRef(leftDataSet.range)}
|
|
82123
|
+
</c:val>
|
|
82124
|
+
</c:ser>
|
|
82125
|
+
`;
|
|
82126
|
+
const rightBarDataSetNode = escapeXml /*xml*/ `
|
|
82127
|
+
<c:ser>
|
|
82128
|
+
<c:idx val="1"/>
|
|
82129
|
+
<c:order val="1"/>
|
|
82130
|
+
<c:invertIfNegative val="0" />
|
|
82131
|
+
${extractDataSetLabel(rightDataSet.label)}
|
|
82132
|
+
${shapeProperty({
|
|
82133
|
+
backgroundColor: secondColor,
|
|
82134
|
+
line: { color: secondColor },
|
|
82135
|
+
})}
|
|
82136
|
+
${chart.labelRange ? escapeXml /*xml*/ `<c:cat>${stringRef(chart.labelRange)}</c:cat>` : ""}
|
|
82137
|
+
<!-- x-coordinate values -->
|
|
82138
|
+
<c:val>
|
|
82139
|
+
${numberRef(rightDataSet.range)}
|
|
82140
|
+
</c:val>
|
|
82141
|
+
</c:ser>
|
|
82142
|
+
`;
|
|
82143
|
+
return escapeXml /*xml*/ `
|
|
82144
|
+
<c:barChart>
|
|
82145
|
+
<c:barDir val="bar"/>
|
|
82146
|
+
<c:grouping val="clustered"/>
|
|
82147
|
+
<c:varyColors val="0" />
|
|
82148
|
+
${leftBarDataSetNode}
|
|
82149
|
+
<c:gapWidth val="50" />
|
|
82150
|
+
<c:axId val="${catAxId}" />
|
|
82151
|
+
<c:axId val="${valAxId}" />
|
|
82152
|
+
</c:barChart>
|
|
82153
|
+
<c:barChart>
|
|
82154
|
+
<c:barDir val="bar"/>
|
|
82155
|
+
<c:grouping val="clustered"/>
|
|
82156
|
+
<c:varyColors val="0" />
|
|
82157
|
+
${rightBarDataSetNode}
|
|
82158
|
+
<c:gapWidth val="50" />
|
|
82159
|
+
<c:axId val="${secondaryCatAxId}" />
|
|
82160
|
+
<c:axId val="${secondaryValAxId}" />
|
|
82161
|
+
</c:barChart>
|
|
82162
|
+
${addAx("r", "c:catAx", catAxId, valAxId, chart.axesDesign?.y?.title, chart.fontColor, 0, "maxMin", "autoZero", "high")}
|
|
82163
|
+
${addAx("b", "c:valAx", valAxId, catAxId, chart.axesDesign?.x?.title, chart.fontColor, 0, "maxMin", "max", "nextTo", maxValue, majorUnit, "#0;#0")}
|
|
82164
|
+
${addAx("t", "c:valAx", secondaryValAxId, secondaryCatAxId, undefined, chart.fontColor, 1)}
|
|
82165
|
+
${addAx("l", "c:catAx", secondaryCatAxId, secondaryValAxId, undefined, chart.fontColor, 1, "maxMin")}
|
|
82166
|
+
`;
|
|
82167
|
+
}
|
|
82168
|
+
function getPyramidChartHorizontalAxisConfig(maxValue) {
|
|
82169
|
+
const adjustMaxToDivisibleBy = (value, divisor) => {
|
|
82170
|
+
let adjusted = Math.ceil(value);
|
|
82171
|
+
while (adjusted % divisor !== 0) {
|
|
82172
|
+
adjusted++;
|
|
82173
|
+
}
|
|
82174
|
+
return adjusted;
|
|
82175
|
+
};
|
|
82176
|
+
const tickCount = 4;
|
|
82177
|
+
const interval = tickCount - 1;
|
|
82178
|
+
const adjustedMax = adjustMaxToDivisibleBy(maxValue, interval);
|
|
82179
|
+
const majorUnit = adjustedMax / interval;
|
|
82180
|
+
return {
|
|
82181
|
+
maxValue: adjustedMax,
|
|
82182
|
+
majorUnit,
|
|
82183
|
+
};
|
|
82184
|
+
}
|
|
81899
82185
|
function addLineChart(chart) {
|
|
81900
82186
|
const dataSetsColors = chart.dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
81901
82187
|
const colors = new ColorGenerator(chart.dataSets.length, dataSetsColors);
|
|
@@ -82088,7 +82374,7 @@ function addRadarChart(chart) {
|
|
|
82088
82374
|
`}
|
|
82089
82375
|
`;
|
|
82090
82376
|
}
|
|
82091
|
-
function addDoughnutChart(chart, chartSheetIndex, data
|
|
82377
|
+
function addDoughnutChart(chart, chartSheetIndex, data) {
|
|
82092
82378
|
const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
|
|
82093
82379
|
const colors = new ColorGenerator(maxLength);
|
|
82094
82380
|
const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
|
|
@@ -82126,7 +82412,7 @@ function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSiz
|
|
|
82126
82412
|
return escapeXml /*xml*/ `
|
|
82127
82413
|
<c:doughnutChart>
|
|
82128
82414
|
<c:varyColors val="1" />
|
|
82129
|
-
<c:holeSize val="${
|
|
82415
|
+
<c:holeSize val="${chart.pieHolePercentage ?? (chart.isDoughnut ? DEFAULT_DOUGHNUT_CHART_HOLE_SIZE : 0)}" />
|
|
82130
82416
|
${insertDataLabels()}
|
|
82131
82417
|
${joinXmlNodes(dataSetsNodes)}
|
|
82132
82418
|
</c:doughnutChart>
|
|
@@ -82145,25 +82431,35 @@ function insertDataLabels({ showLeaderLines } = { showLeaderLines: false }) {
|
|
|
82145
82431
|
</dLbls>
|
|
82146
82432
|
`;
|
|
82147
82433
|
}
|
|
82148
|
-
function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, deleteAxis = 0) {
|
|
82434
|
+
function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, deleteAxis = 0, orientation = "minMax", crossPosition, tickLabelPosition = "nextTo", maxValue, majorUnit, format = "General") {
|
|
82149
82435
|
// Each Axis present inside a graph needs to be identified by an unsigned integer in order to be referenced by its crossAxis.
|
|
82150
82436
|
// I.e. x-axis, will reference y-axis and vice-versa.
|
|
82151
82437
|
const color = title?.color ? toXlsxHexColor(title.color) : defaultFontColor;
|
|
82152
82438
|
const fontSize = title?.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE;
|
|
82439
|
+
const crossBetweenEl = axisName === "c:valAx" ? escapeXml `<c:crossBetween val="between" />` : "";
|
|
82440
|
+
const maxValueEl = maxValue ? escapeXml `<c:max val="${maxValue}" />` : "";
|
|
82441
|
+
const minValueEl = maxValue ? escapeXml `<c:min val="${-maxValue}" />` : "";
|
|
82442
|
+
const majorUnitEl = majorUnit ? escapeXml `<c:majorUnit val="${majorUnit}" />` : "";
|
|
82153
82443
|
return escapeXml /*xml*/ `
|
|
82154
82444
|
<${axisName}>
|
|
82155
82445
|
<c:axId val="${axId}"/>
|
|
82156
82446
|
<c:crossAx val="${crossAxId}"/> <!-- reference to the other axe of the chart -->
|
|
82157
|
-
<c:crosses val="${position === "b" || position === "l" ? "min" : "max"}"/>
|
|
82447
|
+
<c:crosses val="${crossPosition || (position === "b" || position === "l" ? "min" : "max")}"/>
|
|
82448
|
+
<c:auto val="1"/>
|
|
82449
|
+
${crossBetweenEl}
|
|
82158
82450
|
<c:delete val="${deleteAxis}"/> <!-- by default, axis are not displayed -->
|
|
82159
82451
|
<c:scaling>
|
|
82160
|
-
<c:orientation val="
|
|
82452
|
+
<c:orientation val="${orientation}" />
|
|
82453
|
+
${maxValueEl}
|
|
82454
|
+
${minValueEl}
|
|
82161
82455
|
</c:scaling>
|
|
82456
|
+
${majorUnitEl}
|
|
82162
82457
|
<c:axPos val="${position}" />
|
|
82458
|
+
<c:tickLblPos val="${tickLabelPosition}" />
|
|
82163
82459
|
${insertMajorGridLines()}
|
|
82164
82460
|
<c:majorTickMark val="out" />
|
|
82165
82461
|
<c:minorTickMark val="none" />
|
|
82166
|
-
<c:numFmt formatCode="
|
|
82462
|
+
<c:numFmt formatCode="${format}" sourceLinked="${format === "General" ? "1" : "0"}" />
|
|
82167
82463
|
<c:title>
|
|
82168
82464
|
${insertText(title?.text ?? "", color, fontSize, title)}
|
|
82169
82465
|
</c:title>
|
|
@@ -82358,7 +82654,10 @@ function addConditionalFormatting(dxfs, conditionalFormats) {
|
|
|
82358
82654
|
function addCellIsRule(cf, rule, dxfs) {
|
|
82359
82655
|
const ruleAttributes = commonCfAttributes(cf);
|
|
82360
82656
|
const operator = convertOperator(rule.operator);
|
|
82361
|
-
ruleAttributes.push(...cellRuleTypeAttributes(rule)
|
|
82657
|
+
ruleAttributes.push(...cellRuleTypeAttributes(rule));
|
|
82658
|
+
if (operator.length) {
|
|
82659
|
+
ruleAttributes.push(["operator", operator]);
|
|
82660
|
+
}
|
|
82362
82661
|
const formulas = cellRuleFormula(cf.ranges, rule).map((formula) => escapeXml /*xml*/ `<formula>${formula}</formula>`);
|
|
82363
82662
|
const dxf = {
|
|
82364
82663
|
font: {
|
|
@@ -82404,6 +82703,8 @@ function cellRuleFormula(ranges, rule) {
|
|
|
82404
82703
|
case "isLessThan":
|
|
82405
82704
|
case "isLessOrEqualTo":
|
|
82406
82705
|
return [values[0]];
|
|
82706
|
+
case "customFormula":
|
|
82707
|
+
return values[0].startsWith("=") ? [values[0].slice(1)] : [values[0]];
|
|
82407
82708
|
case "isBetween":
|
|
82408
82709
|
case "isNotBetween":
|
|
82409
82710
|
return [values[0], values[1]];
|
|
@@ -82432,6 +82733,8 @@ function cellRuleTypeAttributes(rule) {
|
|
|
82432
82733
|
case "isBetween":
|
|
82433
82734
|
case "isNotBetween":
|
|
82434
82735
|
return [["type", "cellIs"]];
|
|
82736
|
+
case "customFormula":
|
|
82737
|
+
return [["type", "expression"]];
|
|
82435
82738
|
}
|
|
82436
82739
|
}
|
|
82437
82740
|
function addDataBarRule(cf, rule) {
|
|
@@ -84465,6 +84768,7 @@ const stores = {
|
|
|
84465
84768
|
PivotSidePanelStore,
|
|
84466
84769
|
PivotMeasureDisplayPanelStore,
|
|
84467
84770
|
ClientFocusStore,
|
|
84771
|
+
GridRenderer,
|
|
84468
84772
|
};
|
|
84469
84773
|
function addFunction(functionName, functionDescription) {
|
|
84470
84774
|
functionRegistry.add(functionName, functionDescription);
|
|
@@ -84531,6 +84835,6 @@ exports.tokenColors = tokenColors;
|
|
|
84531
84835
|
exports.tokenize = tokenize;
|
|
84532
84836
|
|
|
84533
84837
|
|
|
84534
|
-
__info__.version = "18.5.0-alpha.
|
|
84535
|
-
__info__.date = "2025-
|
|
84536
|
-
__info__.hash = "
|
|
84838
|
+
__info__.version = "18.5.0-alpha.3";
|
|
84839
|
+
__info__.date = "2025-07-28T13:43:05.981Z";
|
|
84840
|
+
__info__.hash = "53dfee8";
|