@odoo/o-spreadsheet 18.1.12 → 18.1.13
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 +132 -110
- package/dist/o-spreadsheet.d.ts +7 -5
- package/dist/o-spreadsheet.esm.js +132 -110
- package/dist/o-spreadsheet.iife.js +132 -110
- package/dist/o-spreadsheet.iife.min.js +370 -368
- package/dist/o_spreadsheet.xml +9 -6
- 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.1.
|
|
6
|
-
* @date 2025-03-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.1.13
|
|
6
|
+
* @date 2025-03-26T12:48:31.680Z
|
|
7
|
+
* @hash 45ec54c
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -1121,7 +1121,10 @@
|
|
|
1121
1121
|
}
|
|
1122
1122
|
else if (stringVals.length === 4) {
|
|
1123
1123
|
const alpha = parseFloat(stringVals.pop() || "1");
|
|
1124
|
-
|
|
1124
|
+
if (isNaN(alpha)) {
|
|
1125
|
+
throw new Error("invalid alpha value");
|
|
1126
|
+
}
|
|
1127
|
+
alphaHex = Math.round(alpha * 255);
|
|
1125
1128
|
}
|
|
1126
1129
|
const vals = stringVals.map((val) => parseInt(val, 10));
|
|
1127
1130
|
if (alphaHex !== 255) {
|
|
@@ -6991,7 +6994,7 @@
|
|
|
6991
6994
|
*/
|
|
6992
6995
|
function canonicalizeNumberContent(content, locale) {
|
|
6993
6996
|
return content.startsWith("=")
|
|
6994
|
-
? canonicalizeFormula
|
|
6997
|
+
? canonicalizeFormula(content, locale)
|
|
6995
6998
|
: canonicalizeNumberLiteral(content, locale);
|
|
6996
6999
|
}
|
|
6997
7000
|
/**
|
|
@@ -7006,7 +7009,7 @@
|
|
|
7006
7009
|
*/
|
|
7007
7010
|
function canonicalizeContent(content, locale) {
|
|
7008
7011
|
return content.startsWith("=")
|
|
7009
|
-
? canonicalizeFormula
|
|
7012
|
+
? canonicalizeFormula(content, locale)
|
|
7010
7013
|
: canonicalizeLiteral(content, locale);
|
|
7011
7014
|
}
|
|
7012
7015
|
/**
|
|
@@ -7022,15 +7025,21 @@
|
|
|
7022
7025
|
? localizeFormula(content, locale)
|
|
7023
7026
|
: localizeLiteral(content, locale);
|
|
7024
7027
|
}
|
|
7028
|
+
/** Change a number string to its canonical form (en_US locale) */
|
|
7029
|
+
function canonicalizeNumberValue(content, locale) {
|
|
7030
|
+
return content.startsWith("=")
|
|
7031
|
+
? canonicalizeFormula(content, locale)
|
|
7032
|
+
: canonicalizeNumberLiteral(content, locale);
|
|
7033
|
+
}
|
|
7025
7034
|
/** Change a formula to its canonical form (en_US locale) */
|
|
7026
|
-
function canonicalizeFormula
|
|
7027
|
-
return _localizeFormula
|
|
7035
|
+
function canonicalizeFormula(formula, locale) {
|
|
7036
|
+
return _localizeFormula(formula, locale, DEFAULT_LOCALE);
|
|
7028
7037
|
}
|
|
7029
7038
|
/** Change a formula from the canonical form to the given locale */
|
|
7030
7039
|
function localizeFormula(formula, locale) {
|
|
7031
|
-
return _localizeFormula
|
|
7040
|
+
return _localizeFormula(formula, DEFAULT_LOCALE, locale);
|
|
7032
7041
|
}
|
|
7033
|
-
function _localizeFormula
|
|
7042
|
+
function _localizeFormula(formula, fromLocale, toLocale) {
|
|
7034
7043
|
if (fromLocale.formulaArgSeparator === toLocale.formulaArgSeparator &&
|
|
7035
7044
|
fromLocale.decimalSeparator === toLocale.decimalSeparator) {
|
|
7036
7045
|
return formula;
|
|
@@ -7185,37 +7194,6 @@
|
|
|
7185
7194
|
return locale.dateFormat + " " + locale.timeFormat;
|
|
7186
7195
|
}
|
|
7187
7196
|
|
|
7188
|
-
/** Change a number string to its canonical form (en_US locale) */
|
|
7189
|
-
function canonicalizeNumberValue(content, locale) {
|
|
7190
|
-
return content.startsWith("=")
|
|
7191
|
-
? canonicalizeFormula(content, locale)
|
|
7192
|
-
: canonicalizeNumberLiteral(content, locale);
|
|
7193
|
-
}
|
|
7194
|
-
/** Change a formula to its canonical form (en_US locale) */
|
|
7195
|
-
function canonicalizeFormula(formula, locale) {
|
|
7196
|
-
return _localizeFormula(formula, locale, DEFAULT_LOCALE);
|
|
7197
|
-
}
|
|
7198
|
-
function _localizeFormula(formula, fromLocale, toLocale) {
|
|
7199
|
-
if (fromLocale.formulaArgSeparator === toLocale.formulaArgSeparator &&
|
|
7200
|
-
fromLocale.decimalSeparator === toLocale.decimalSeparator) {
|
|
7201
|
-
return formula;
|
|
7202
|
-
}
|
|
7203
|
-
const tokens = tokenize(formula, fromLocale);
|
|
7204
|
-
let localizedFormula = "";
|
|
7205
|
-
for (const token of tokens) {
|
|
7206
|
-
if (token.type === "NUMBER") {
|
|
7207
|
-
localizedFormula += token.value.replace(fromLocale.decimalSeparator, toLocale.decimalSeparator);
|
|
7208
|
-
}
|
|
7209
|
-
else if (token.type === "ARG_SEPARATOR") {
|
|
7210
|
-
localizedFormula += toLocale.formulaArgSeparator;
|
|
7211
|
-
}
|
|
7212
|
-
else {
|
|
7213
|
-
localizedFormula += token.value;
|
|
7214
|
-
}
|
|
7215
|
-
}
|
|
7216
|
-
return localizedFormula;
|
|
7217
|
-
}
|
|
7218
|
-
|
|
7219
7197
|
function boolAnd(args) {
|
|
7220
7198
|
let foundBoolean = false;
|
|
7221
7199
|
let acc = true;
|
|
@@ -9590,6 +9568,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9590
9568
|
}
|
|
9591
9569
|
|
|
9592
9570
|
const TREND_LINE_XAXIS_ID = "x1";
|
|
9571
|
+
const MOVING_AVERAGE_TREND_LINE_XAXIS_ID = "xMovingAverage";
|
|
9593
9572
|
/**
|
|
9594
9573
|
* This file contains helpers that are common to different charts (mainly
|
|
9595
9574
|
* line, bar and pie charts)
|
|
@@ -9930,6 +9909,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9930
9909
|
}
|
|
9931
9910
|
return pieColors;
|
|
9932
9911
|
}
|
|
9912
|
+
function isTrendLineAxis(axisID) {
|
|
9913
|
+
return axisID === TREND_LINE_XAXIS_ID || axisID === MOVING_AVERAGE_TREND_LINE_XAXIS_ID;
|
|
9914
|
+
}
|
|
9933
9915
|
|
|
9934
9916
|
/** This is a chartJS plugin that will draw the values of each data next to the point/bar/pie slice */
|
|
9935
9917
|
const chartShowValuesPlugin = {
|
|
@@ -9974,7 +9956,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9974
9956
|
const yMin = chart.chartArea.top;
|
|
9975
9957
|
const textsPositions = {};
|
|
9976
9958
|
for (const dataset of chart._metasets) {
|
|
9977
|
-
if (dataset.
|
|
9959
|
+
if (isTrendLineAxis(dataset.axisID) || dataset.hidden) {
|
|
9978
9960
|
continue;
|
|
9979
9961
|
}
|
|
9980
9962
|
for (let i = 0; i < dataset._parsed.length; i++) {
|
|
@@ -10017,7 +9999,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10017
9999
|
const xMin = chart.chartArea.left;
|
|
10018
10000
|
const textsPositions = {};
|
|
10019
10001
|
for (const dataset of chart._metasets) {
|
|
10020
|
-
if (dataset.
|
|
10002
|
+
if (isTrendLineAxis(dataset.axisID)) {
|
|
10021
10003
|
return; // ignore trend lines
|
|
10022
10004
|
}
|
|
10023
10005
|
for (let i = 0; i < dataset._parsed.length; i++) {
|
|
@@ -20381,11 +20363,26 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
20381
20363
|
const _searchFor = toString(searchFor).toLowerCase();
|
|
20382
20364
|
const _textToSearch = toString(textToSearch).toLowerCase();
|
|
20383
20365
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
20384
|
-
|
|
20385
|
-
|
|
20366
|
+
if (_textToSearch === "") {
|
|
20367
|
+
return {
|
|
20368
|
+
value: CellErrorType.GenericError,
|
|
20369
|
+
message: _t("The text_to_search must be non-empty."),
|
|
20370
|
+
};
|
|
20371
|
+
}
|
|
20372
|
+
if (_startingAt < 1) {
|
|
20373
|
+
return {
|
|
20374
|
+
value: CellErrorType.GenericError,
|
|
20375
|
+
message: _t("The starting_at (%s) must be greater than or equal to 1.", _startingAt),
|
|
20376
|
+
};
|
|
20377
|
+
}
|
|
20386
20378
|
const result = _textToSearch.indexOf(_searchFor, _startingAt - 1);
|
|
20387
|
-
|
|
20388
|
-
|
|
20379
|
+
if (result === -1) {
|
|
20380
|
+
return {
|
|
20381
|
+
value: CellErrorType.GenericError,
|
|
20382
|
+
message: _t("In [[FUNCTION_NAME]] evaluation, cannot find '%s' within '%s'.", _searchFor, _textToSearch),
|
|
20383
|
+
};
|
|
20384
|
+
}
|
|
20385
|
+
return { value: result + 1 };
|
|
20389
20386
|
},
|
|
20390
20387
|
isExported: true,
|
|
20391
20388
|
};
|
|
@@ -21720,11 +21717,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
21720
21717
|
}
|
|
21721
21718
|
}
|
|
21722
21719
|
function compileTokensOrThrow(tokens) {
|
|
21723
|
-
const { dependencies,
|
|
21724
|
-
const cacheKey = compilationCacheKey(tokens
|
|
21720
|
+
const { dependencies, literalValues, symbols } = formulaArguments(tokens);
|
|
21721
|
+
const cacheKey = compilationCacheKey(tokens);
|
|
21725
21722
|
if (!functionCache[cacheKey]) {
|
|
21726
21723
|
const ast = parseTokens([...tokens]);
|
|
21727
21724
|
const scope = new Scope();
|
|
21725
|
+
let stringCount = 0;
|
|
21726
|
+
let numberCount = 0;
|
|
21727
|
+
let dependencyCount = 0;
|
|
21728
21728
|
if (ast.type === "BIN_OPERATION" && ast.value === ":") {
|
|
21729
21729
|
throw new BadExpressionError(_t("Invalid formula"));
|
|
21730
21730
|
}
|
|
@@ -21798,16 +21798,15 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
21798
21798
|
case "BOOLEAN":
|
|
21799
21799
|
return code.return(`{ value: ${ast.value} }`);
|
|
21800
21800
|
case "NUMBER":
|
|
21801
|
-
return code.return(`
|
|
21801
|
+
return code.return(`this.literalValues.numbers[${numberCount++}]`);
|
|
21802
21802
|
case "STRING":
|
|
21803
|
-
return code.return(`
|
|
21803
|
+
return code.return(`this.literalValues.strings[${stringCount++}]`);
|
|
21804
21804
|
case "REFERENCE":
|
|
21805
|
-
const referenceIndex = dependencies.indexOf(ast.value);
|
|
21806
21805
|
if ((!isMeta && ast.value.includes(":")) || hasRange) {
|
|
21807
|
-
return code.return(`range(deps[${
|
|
21806
|
+
return code.return(`range(deps[${dependencyCount++}])`);
|
|
21808
21807
|
}
|
|
21809
21808
|
else {
|
|
21810
|
-
return code.return(`ref(deps[${
|
|
21809
|
+
return code.return(`ref(deps[${dependencyCount++}], ${isMeta ? "true" : "false"})`);
|
|
21811
21810
|
}
|
|
21812
21811
|
case "FUNCALL":
|
|
21813
21812
|
const args = compileFunctionArgs(ast).map((arg) => arg.assignResultToVariable());
|
|
@@ -21839,7 +21838,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
21839
21838
|
const compiledFormula = {
|
|
21840
21839
|
execute: functionCache[cacheKey],
|
|
21841
21840
|
dependencies,
|
|
21842
|
-
|
|
21841
|
+
literalValues,
|
|
21843
21842
|
symbols,
|
|
21844
21843
|
tokens,
|
|
21845
21844
|
isBadExpression: false,
|
|
@@ -21852,33 +21851,31 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
21852
21851
|
* References, numbers and strings are replaced with placeholders because
|
|
21853
21852
|
* the compiled formula does not depend on their actual value.
|
|
21854
21853
|
* Both `=A1+1+"2"` and `=A2+2+"3"` are compiled to the exact same function.
|
|
21855
|
-
*
|
|
21856
21854
|
* Spaces are also ignored to compute the cache key.
|
|
21857
21855
|
*
|
|
21858
|
-
* A formula `=A1+A2+SUM(2, 2, "2")` have the cache key `=|
|
|
21856
|
+
* A formula `=A1+A2+SUM(2, 2, "2")` have the cache key `=|C|+|C|+SUM(|N|,|N|,|S|)`
|
|
21859
21857
|
*/
|
|
21860
|
-
function compilationCacheKey(tokens
|
|
21858
|
+
function compilationCacheKey(tokens) {
|
|
21861
21859
|
let cacheKey = "";
|
|
21862
21860
|
for (const token of tokens) {
|
|
21863
21861
|
switch (token.type) {
|
|
21864
21862
|
case "STRING":
|
|
21865
|
-
|
|
21866
|
-
cacheKey += `|S${constantValues.strings.indexOf(value)}|`;
|
|
21863
|
+
cacheKey += "|S|";
|
|
21867
21864
|
break;
|
|
21868
21865
|
case "NUMBER":
|
|
21869
|
-
cacheKey +=
|
|
21866
|
+
cacheKey += "|N|";
|
|
21870
21867
|
break;
|
|
21871
21868
|
case "REFERENCE":
|
|
21872
21869
|
case "INVALID_REFERENCE":
|
|
21873
21870
|
if (token.value.includes(":")) {
|
|
21874
|
-
cacheKey +=
|
|
21871
|
+
cacheKey += "|R|";
|
|
21875
21872
|
}
|
|
21876
21873
|
else {
|
|
21877
|
-
cacheKey +=
|
|
21874
|
+
cacheKey += "|C|";
|
|
21878
21875
|
}
|
|
21879
21876
|
break;
|
|
21880
21877
|
case "SPACE":
|
|
21881
|
-
|
|
21878
|
+
// ignore spaces
|
|
21882
21879
|
break;
|
|
21883
21880
|
default:
|
|
21884
21881
|
cacheKey += token.value;
|
|
@@ -21891,7 +21888,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
21891
21888
|
* Return formula arguments which are references, strings and numbers.
|
|
21892
21889
|
*/
|
|
21893
21890
|
function formulaArguments(tokens) {
|
|
21894
|
-
const
|
|
21891
|
+
const literalValues = {
|
|
21895
21892
|
numbers: [],
|
|
21896
21893
|
strings: [],
|
|
21897
21894
|
};
|
|
@@ -21905,15 +21902,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
21905
21902
|
break;
|
|
21906
21903
|
case "STRING":
|
|
21907
21904
|
const value = removeStringQuotes(token.value);
|
|
21908
|
-
|
|
21909
|
-
constantValues.strings.push(value);
|
|
21910
|
-
}
|
|
21905
|
+
literalValues.strings.push({ value });
|
|
21911
21906
|
break;
|
|
21912
21907
|
case "NUMBER": {
|
|
21913
21908
|
const value = parseNumber(token.value, DEFAULT_LOCALE);
|
|
21914
|
-
|
|
21915
|
-
constantValues.numbers.push(value);
|
|
21916
|
-
}
|
|
21909
|
+
literalValues.numbers.push({ value });
|
|
21917
21910
|
break;
|
|
21918
21911
|
}
|
|
21919
21912
|
case "SYMBOL": {
|
|
@@ -21924,7 +21917,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
21924
21917
|
}
|
|
21925
21918
|
return {
|
|
21926
21919
|
dependencies,
|
|
21927
|
-
|
|
21920
|
+
literalValues,
|
|
21928
21921
|
symbols,
|
|
21929
21922
|
};
|
|
21930
21923
|
}
|
|
@@ -22845,9 +22838,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22845
22838
|
/** In XLSX color format (no #) */
|
|
22846
22839
|
const AUTO_COLOR = "000000";
|
|
22847
22840
|
const XLSX_ICONSET_MAP = {
|
|
22848
|
-
|
|
22841
|
+
arrows: "3Arrows",
|
|
22849
22842
|
smiley: "3Symbols",
|
|
22850
|
-
|
|
22843
|
+
dots: "3TrafficLights1",
|
|
22851
22844
|
};
|
|
22852
22845
|
const NAMESPACE = {
|
|
22853
22846
|
styleSheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
|
|
@@ -23518,6 +23511,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
23518
23511
|
};
|
|
23519
23512
|
/** Map between legend position in XLSX file and human readable position */
|
|
23520
23513
|
const DRAWING_LEGEND_POSITION_CONVERSION_MAP = {
|
|
23514
|
+
none: "none",
|
|
23521
23515
|
b: "bottom",
|
|
23522
23516
|
t: "top",
|
|
23523
23517
|
l: "left",
|
|
@@ -26280,7 +26274,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
26280
26274
|
default: "ffffff",
|
|
26281
26275
|
}).asString(),
|
|
26282
26276
|
legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(rootChartElement, "c:legendPos", "val", {
|
|
26283
|
-
default: "
|
|
26277
|
+
default: "none",
|
|
26284
26278
|
}).asString()],
|
|
26285
26279
|
stacked: barChartGrouping === "stacked",
|
|
26286
26280
|
fontColor: "000000",
|
|
@@ -26314,7 +26308,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
26314
26308
|
default: "ffffff",
|
|
26315
26309
|
}).asString(),
|
|
26316
26310
|
legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(chartElement, "c:legendPos", "val", {
|
|
26317
|
-
default: "
|
|
26311
|
+
default: "none",
|
|
26318
26312
|
}).asString()],
|
|
26319
26313
|
stacked: barChartGrouping === "stacked",
|
|
26320
26314
|
fontColor: "000000",
|
|
@@ -28926,7 +28920,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28926
28920
|
}
|
|
28927
28921
|
}
|
|
28928
28922
|
else if (dataSets.length === 1) {
|
|
28929
|
-
|
|
28923
|
+
const dataLength = getData(getters, dataSets[0]).length;
|
|
28924
|
+
for (let i = 0; i < dataLength; i++) {
|
|
28930
28925
|
labels.formattedValues.push("");
|
|
28931
28926
|
labels.values.push("");
|
|
28932
28927
|
}
|
|
@@ -29109,7 +29104,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29109
29104
|
function getScatterChartDatasets(definition, args) {
|
|
29110
29105
|
const dataSets = getLineChartDatasets(definition, args);
|
|
29111
29106
|
for (const dataSet of dataSets) {
|
|
29112
|
-
if (dataSet.xAxisID
|
|
29107
|
+
if (!isTrendLineAxis(dataSet.xAxisID)) {
|
|
29113
29108
|
dataSet.showLine = false;
|
|
29114
29109
|
}
|
|
29115
29110
|
}
|
|
@@ -29236,7 +29231,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29236
29231
|
const borderColor = config.color || lightenColor(rgbaToHex(defaultBorderColor), 0.5);
|
|
29237
29232
|
return {
|
|
29238
29233
|
type: "line",
|
|
29239
|
-
xAxisID:
|
|
29234
|
+
xAxisID: config.type === "trailingMovingAverage"
|
|
29235
|
+
? MOVING_AVERAGE_TREND_LINE_XAXIS_ID
|
|
29236
|
+
: TREND_LINE_XAXIS_ID,
|
|
29240
29237
|
yAxisID: dataset.yAxisID,
|
|
29241
29238
|
label: dataset.label ? _t("Trend line for %s", dataset.label) : "",
|
|
29242
29239
|
data,
|
|
@@ -29311,22 +29308,19 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29311
29308
|
const { dataSetsValues } = args;
|
|
29312
29309
|
const dataSetsLength = Math.max(0, ...dataSetsValues.map((ds) => ds?.data?.length ?? 0));
|
|
29313
29310
|
const colors = getPieColors(new ColorGenerator(dataSetsLength), dataSetsValues);
|
|
29311
|
+
const fontColor = chartFontColor(definition.background);
|
|
29314
29312
|
return {
|
|
29315
29313
|
...getLegendDisplayOptions(definition),
|
|
29316
29314
|
labels: {
|
|
29317
|
-
color: chartFontColor(definition.background),
|
|
29318
29315
|
usePointStyle: true,
|
|
29319
|
-
|
|
29320
|
-
|
|
29321
|
-
//@ts-ignore
|
|
29322
|
-
c.data.labels.map((label, index) => ({
|
|
29323
|
-
text: label,
|
|
29316
|
+
generateLabels: (c) => c.data.labels?.map((label, index) => ({
|
|
29317
|
+
text: String(label),
|
|
29324
29318
|
strokeStyle: colors[index],
|
|
29325
29319
|
fillStyle: colors[index],
|
|
29326
29320
|
pointStyle: "rect",
|
|
29327
|
-
hidden: false,
|
|
29328
29321
|
lineWidth: 2,
|
|
29329
|
-
|
|
29322
|
+
fontColor,
|
|
29323
|
+
})) || [],
|
|
29330
29324
|
filter: (legendItem, data) => {
|
|
29331
29325
|
return "datasetIndex" in legendItem
|
|
29332
29326
|
? !data.datasets[legendItem.datasetIndex].hidden
|
|
@@ -29459,7 +29453,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29459
29453
|
color: fontColor,
|
|
29460
29454
|
usePointStyle: true,
|
|
29461
29455
|
generateLabels: (chart) => chart.data.datasets.map((dataset, index) => {
|
|
29462
|
-
if (dataset["xAxisID"]
|
|
29456
|
+
if (isTrendLineAxis(dataset["xAxisID"])) {
|
|
29463
29457
|
return {
|
|
29464
29458
|
text: dataset.label ?? "",
|
|
29465
29459
|
fontColor,
|
|
@@ -29517,6 +29511,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29517
29511
|
offset: false,
|
|
29518
29512
|
display: false,
|
|
29519
29513
|
};
|
|
29514
|
+
scales[MOVING_AVERAGE_TREND_LINE_XAXIS_ID] = {
|
|
29515
|
+
...scales.x,
|
|
29516
|
+
offset: false,
|
|
29517
|
+
display: false,
|
|
29518
|
+
};
|
|
29520
29519
|
}
|
|
29521
29520
|
return scales;
|
|
29522
29521
|
}
|
|
@@ -29550,6 +29549,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29550
29549
|
...scales.x,
|
|
29551
29550
|
display: false,
|
|
29552
29551
|
};
|
|
29552
|
+
scales[MOVING_AVERAGE_TREND_LINE_XAXIS_ID] = {
|
|
29553
|
+
...scales.x,
|
|
29554
|
+
display: false,
|
|
29555
|
+
};
|
|
29553
29556
|
if (axisType === "category" || axisType === "time") {
|
|
29554
29557
|
/* We add a second x axis here to draw the trend lines, with the labels length being
|
|
29555
29558
|
* set so that the second axis points match the classical x axis
|
|
@@ -29558,6 +29561,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29558
29561
|
scales[TREND_LINE_XAXIS_ID]["type"] = "category";
|
|
29559
29562
|
scales[TREND_LINE_XAXIS_ID]["labels"] = range(0, maxLength).map((x) => x.toString());
|
|
29560
29563
|
scales[TREND_LINE_XAXIS_ID]["offset"] = false;
|
|
29564
|
+
scales[MOVING_AVERAGE_TREND_LINE_XAXIS_ID]["type"] = "category";
|
|
29565
|
+
scales[MOVING_AVERAGE_TREND_LINE_XAXIS_ID]["offset"] = false;
|
|
29561
29566
|
}
|
|
29562
29567
|
}
|
|
29563
29568
|
return scales;
|
|
@@ -29803,9 +29808,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29803
29808
|
return {
|
|
29804
29809
|
callbacks: {
|
|
29805
29810
|
title: function (tooltipItems) {
|
|
29806
|
-
return tooltipItems.some((item) => item.dataset.xAxisID
|
|
29807
|
-
? undefined
|
|
29808
|
-
: "";
|
|
29811
|
+
return tooltipItems.some((item) => !isTrendLineAxis(item.dataset.xAxisID)) ? undefined : "";
|
|
29809
29812
|
},
|
|
29810
29813
|
label: function (tooltipItem) {
|
|
29811
29814
|
const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
|
|
@@ -29828,7 +29831,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29828
29831
|
if (axisType === "linear") {
|
|
29829
29832
|
tooltip.callbacks.label = (tooltipItem) => {
|
|
29830
29833
|
const dataSetPoint = tooltipItem.parsed.y;
|
|
29831
|
-
let label = tooltipItem.dataset.xAxisID
|
|
29834
|
+
let label = isTrendLineAxis(tooltipItem.dataset.xAxisID)
|
|
29832
29835
|
? ""
|
|
29833
29836
|
: tooltipItem.parsed.x;
|
|
29834
29837
|
if (typeof label === "string" && isNumber(label, locale)) {
|
|
@@ -29853,8 +29856,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29853
29856
|
};
|
|
29854
29857
|
}
|
|
29855
29858
|
tooltip.callbacks.title = function (tooltipItems) {
|
|
29856
|
-
const displayTooltipTitle = axisType !== "linear" &&
|
|
29857
|
-
tooltipItems.some((item) => item.dataset.xAxisID !== TREND_LINE_XAXIS_ID);
|
|
29859
|
+
const displayTooltipTitle = axisType !== "linear" && tooltipItems.some((item) => !isTrendLineAxis(item.dataset.xAxisID));
|
|
29858
29860
|
return displayTooltipTitle ? undefined : "";
|
|
29859
29861
|
};
|
|
29860
29862
|
return tooltip;
|
|
@@ -34011,6 +34013,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34011
34013
|
CHART_COMMON_OPTIONS: CHART_COMMON_OPTIONS,
|
|
34012
34014
|
GaugeChart: GaugeChart,
|
|
34013
34015
|
LineChart: LineChart,
|
|
34016
|
+
MOVING_AVERAGE_TREND_LINE_XAXIS_ID: MOVING_AVERAGE_TREND_LINE_XAXIS_ID,
|
|
34014
34017
|
PieChart: PieChart,
|
|
34015
34018
|
ScorecardChart: ScorecardChart$1,
|
|
34016
34019
|
TREND_LINE_XAXIS_ID: TREND_LINE_XAXIS_ID,
|
|
@@ -34040,6 +34043,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34040
34043
|
getDefinedAxis: getDefinedAxis,
|
|
34041
34044
|
getPieColors: getPieColors,
|
|
34042
34045
|
getSmartChartDefinition: getSmartChartDefinition,
|
|
34046
|
+
isTrendLineAxis: isTrendLineAxis,
|
|
34043
34047
|
shouldRemoveFirstLabel: shouldRemoveFirstLabel,
|
|
34044
34048
|
toExcelDataset: toExcelDataset,
|
|
34045
34049
|
toExcelLabelRange: toExcelLabelRange,
|
|
@@ -36087,9 +36091,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
36087
36091
|
}
|
|
36088
36092
|
}
|
|
36089
36093
|
}
|
|
36090
|
-
|
|
36091
|
-
// =|N0|+|N1|+|N0| -> =|N|+|N|+|N|
|
|
36092
|
-
const normalizedFormula = cell.compiledFormula.normalizedFormula.replace(/(|\w)(\d)(|)/g, "$1$3");
|
|
36094
|
+
const normalizedFormula = cell.compiledFormula.normalizedFormula;
|
|
36093
36095
|
return hash(fingerprintVector) + normalizedFormula;
|
|
36094
36096
|
}
|
|
36095
36097
|
getLiteralFingerprint(position) {
|
|
@@ -39080,9 +39082,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
39080
39082
|
if (!runtime || !("chartJsConfig" in runtime)) {
|
|
39081
39083
|
return [];
|
|
39082
39084
|
}
|
|
39083
|
-
return runtime.chartJsConfig.data.datasets
|
|
39085
|
+
return runtime.chartJsConfig.data.datasets
|
|
39086
|
+
.filter((d) => !isTrendLineAxis(d["xAxisID"] ?? ""))
|
|
39087
|
+
.map((d) => d.label);
|
|
39084
39088
|
}
|
|
39085
|
-
|
|
39089
|
+
updateEditedSeries(ev) {
|
|
39086
39090
|
this.state.index = ev.target.selectedIndex;
|
|
39087
39091
|
}
|
|
39088
39092
|
updateDataSeriesColor(color) {
|
|
@@ -39095,7 +39099,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
39095
39099
|
};
|
|
39096
39100
|
this.props.updateChart(this.props.figureId, { dataSets });
|
|
39097
39101
|
}
|
|
39098
|
-
|
|
39102
|
+
getDataSeriesColor() {
|
|
39099
39103
|
const dataSets = this.props.definition.dataSets;
|
|
39100
39104
|
if (!dataSets?.[this.state.index])
|
|
39101
39105
|
return "";
|
|
@@ -39115,7 +39119,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
39115
39119
|
};
|
|
39116
39120
|
this.props.updateChart(this.props.figureId, { dataSets });
|
|
39117
39121
|
}
|
|
39118
|
-
|
|
39122
|
+
getDataSeriesLabel() {
|
|
39119
39123
|
const dataSets = this.props.definition.dataSets;
|
|
39120
39124
|
return dataSets[this.state.index]?.label || this.getDataSeries()[this.state.index];
|
|
39121
39125
|
}
|
|
@@ -39228,7 +39232,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
39228
39232
|
}
|
|
39229
39233
|
this.updateTrendLineValue(index, { window });
|
|
39230
39234
|
}
|
|
39231
|
-
|
|
39235
|
+
getDataSeriesColor(index) {
|
|
39232
39236
|
const dataSets = this.props.definition.dataSets;
|
|
39233
39237
|
if (!dataSets?.[index])
|
|
39234
39238
|
return "";
|
|
@@ -39239,7 +39243,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
39239
39243
|
}
|
|
39240
39244
|
getTrendLineColor(index) {
|
|
39241
39245
|
return (this.getTrendLineConfiguration(index)?.color ??
|
|
39242
|
-
setColorAlpha(this.
|
|
39246
|
+
setColorAlpha(this.getDataSeriesColor(index), 0.5));
|
|
39243
39247
|
}
|
|
39244
39248
|
updateTrendLineColor(index, color) {
|
|
39245
39249
|
this.updateTrendLineValue(index, { color });
|
|
@@ -70322,7 +70326,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
70322
70326
|
border: 1px solid;
|
|
70323
70327
|
font-family: ${DEFAULT_FONT};
|
|
70324
70328
|
|
|
70325
|
-
|
|
70329
|
+
/* In readonly we always show the fx icon if the composer is empty, not matter the focus */
|
|
70330
|
+
.o-composer:empty:not(:focus):not(.active)::before,
|
|
70331
|
+
&.o-topbar-composer-readonly .o-composer:empty::before {
|
|
70326
70332
|
content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
|
|
70327
70333
|
position: relative;
|
|
70328
70334
|
top: 20%;
|
|
@@ -73663,10 +73669,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
73663
73669
|
continue;
|
|
73664
73670
|
}
|
|
73665
73671
|
const cfValueObjectNodes = cfValueObject.map((attrs) => escapeXml /*xml*/ `<cfvo ${formatAttributes(attrs)} />`);
|
|
73672
|
+
const iconSetAttrs = [["iconSet", getIconSet(rule.icons)]];
|
|
73673
|
+
if (isIconSetReversed(rule.icons)) {
|
|
73674
|
+
iconSetAttrs.push(["reverse", "1"]);
|
|
73675
|
+
}
|
|
73666
73676
|
conditionalFormats.push(escapeXml /*xml*/ `
|
|
73667
73677
|
<conditionalFormatting sqref="${range}">
|
|
73668
73678
|
<cfRule ${formatAttributes(ruleAttributes)}>
|
|
73669
|
-
<iconSet
|
|
73679
|
+
<iconSet ${formatAttributes(iconSetAttrs)}>
|
|
73670
73680
|
${joinXmlNodes(cfValueObjectNodes)}
|
|
73671
73681
|
</iconSet>
|
|
73672
73682
|
</cfRule>
|
|
@@ -73684,9 +73694,21 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
73684
73694
|
["stopIfTrue", cf.stopIfTrue ? 1 : 0],
|
|
73685
73695
|
];
|
|
73686
73696
|
}
|
|
73697
|
+
function isIconSetReversed(iconSet) {
|
|
73698
|
+
const defaultIconSet = ICON_SETS[detectIconsType(iconSet)];
|
|
73699
|
+
return iconSet.upper === defaultIconSet.bad && iconSet.lower === defaultIconSet.good;
|
|
73700
|
+
}
|
|
73687
73701
|
function getIconSet(iconSet) {
|
|
73688
|
-
return XLSX_ICONSET_MAP[
|
|
73689
|
-
|
|
73702
|
+
return XLSX_ICONSET_MAP[detectIconsType(iconSet)];
|
|
73703
|
+
}
|
|
73704
|
+
/**
|
|
73705
|
+
* Partial detection based on "upper" point only.
|
|
73706
|
+
* We support any arbitrary icon in the set, while excel doesn't allow
|
|
73707
|
+
* mixing icons from different types.
|
|
73708
|
+
*/
|
|
73709
|
+
function detectIconsType(iconSet) {
|
|
73710
|
+
const type = Object.keys(ICON_SETS).find((type) => Object.values(ICON_SETS[type]).includes(iconSet.upper)) || "dots";
|
|
73711
|
+
return type;
|
|
73690
73712
|
}
|
|
73691
73713
|
function thresholdAttributes(threshold, position) {
|
|
73692
73714
|
const type = getExcelThresholdType(threshold.type, position);
|
|
@@ -75603,9 +75625,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
75603
75625
|
exports.tokenize = tokenize;
|
|
75604
75626
|
|
|
75605
75627
|
|
|
75606
|
-
__info__.version = "18.1.
|
|
75607
|
-
__info__.date = "2025-03-
|
|
75608
|
-
__info__.hash = "
|
|
75628
|
+
__info__.version = "18.1.13";
|
|
75629
|
+
__info__.date = "2025-03-26T12:48:31.680Z";
|
|
75630
|
+
__info__.hash = "45ec54c";
|
|
75609
75631
|
|
|
75610
75632
|
|
|
75611
75633
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|