@odoo/o-spreadsheet 18.5.0-alpha.2 → 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 +290 -88
- package/dist/o-spreadsheet.d.ts +21 -4
- package/dist/o-spreadsheet.esm.js +290 -88
- package/dist/o-spreadsheet.iife.js +290 -88
- package/dist/o-spreadsheet.iife.min.js +443 -388
- package/dist/o_spreadsheet.xml +10 -8
- 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-07-
|
|
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';
|
|
@@ -2903,6 +2903,7 @@ const availableConditionalFormatOperators = new Set([
|
|
|
2903
2903
|
"isEmpty",
|
|
2904
2904
|
"isNotEqual",
|
|
2905
2905
|
"isEqual",
|
|
2906
|
+
"customFormula",
|
|
2906
2907
|
]);
|
|
2907
2908
|
|
|
2908
2909
|
const availableDataValidationOperators = new Set([
|
|
@@ -5035,11 +5036,11 @@ function isTextFormat(format) {
|
|
|
5035
5036
|
}
|
|
5036
5037
|
}
|
|
5037
5038
|
|
|
5038
|
-
function evaluateLiteral(literalCell, localeFormat) {
|
|
5039
|
+
function evaluateLiteral(literalCell, localeFormat, position) {
|
|
5039
5040
|
const value = isTextFormat(localeFormat.format) && literalCell.parsedValue !== null
|
|
5040
5041
|
? literalCell.content
|
|
5041
5042
|
: literalCell.parsedValue;
|
|
5042
|
-
const functionResult = { value, format: localeFormat.format };
|
|
5043
|
+
const functionResult = { value, format: localeFormat.format, origin: position };
|
|
5043
5044
|
return createEvaluatedCell(functionResult, localeFormat.locale);
|
|
5044
5045
|
}
|
|
5045
5046
|
function parseLiteral(content, locale) {
|
|
@@ -5061,10 +5062,11 @@ function parseLiteral(content, locale) {
|
|
|
5061
5062
|
}
|
|
5062
5063
|
return content;
|
|
5063
5064
|
}
|
|
5064
|
-
function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell) {
|
|
5065
|
+
function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell, origin) {
|
|
5065
5066
|
const link = detectLink(functionResult.value);
|
|
5066
5067
|
if (!link) {
|
|
5067
|
-
|
|
5068
|
+
const evaluateCell = _createEvaluatedCell(functionResult, locale, cell);
|
|
5069
|
+
return addOrigin(evaluateCell, functionResult.origin ?? origin);
|
|
5068
5070
|
}
|
|
5069
5071
|
const value = parseLiteral(link.label, locale);
|
|
5070
5072
|
const format = functionResult.format ||
|
|
@@ -5075,10 +5077,10 @@ function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell) {
|
|
|
5075
5077
|
value,
|
|
5076
5078
|
format,
|
|
5077
5079
|
};
|
|
5078
|
-
return {
|
|
5080
|
+
return addOrigin({
|
|
5079
5081
|
..._createEvaluatedCell(linkPayload, locale, cell),
|
|
5080
5082
|
link,
|
|
5081
|
-
};
|
|
5083
|
+
}, functionResult.origin ?? origin);
|
|
5082
5084
|
}
|
|
5083
5085
|
function _createEvaluatedCell(functionResult, locale, cell) {
|
|
5084
5086
|
let { value, format, message } = functionResult;
|
|
@@ -5168,6 +5170,17 @@ function errorCell(value, message) {
|
|
|
5168
5170
|
defaultAlign: "center",
|
|
5169
5171
|
};
|
|
5170
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
|
+
}
|
|
5171
5184
|
|
|
5172
5185
|
function toCriterionDateNumber(dateValue) {
|
|
5173
5186
|
const today = DateTime.now();
|
|
@@ -7848,6 +7861,7 @@ function changeCFRuleLocale(rule, changeContentLocale) {
|
|
|
7848
7861
|
case "isGreaterOrEqualTo":
|
|
7849
7862
|
case "isLessThan":
|
|
7850
7863
|
case "isLessOrEqualTo":
|
|
7864
|
+
case "customFormula":
|
|
7851
7865
|
rule.values = rule.values.map((v) => changeContentLocale(v));
|
|
7852
7866
|
return rule;
|
|
7853
7867
|
case "beginsWithText":
|
|
@@ -10536,6 +10550,7 @@ const EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS = 100;
|
|
|
10536
10550
|
/** The possible values for the XLSX polynomial trendline order are defined by the ST_Order simple type (§21.2.3.29) */
|
|
10537
10551
|
const MAX_XLSX_POLYNOMIAL_DEGREE = 6;
|
|
10538
10552
|
const FIRST_NUMFMT_ID = 164;
|
|
10553
|
+
const DEFAULT_DOUGHNUT_CHART_HOLE_SIZE = 50;
|
|
10539
10554
|
const FORCE_DEFAULT_ARGS_FUNCTIONS = {
|
|
10540
10555
|
FLOOR: [{ type: "NUMBER", value: 1 }],
|
|
10541
10556
|
CEILING: [{ type: "NUMBER", value: 1 }],
|
|
@@ -19035,13 +19050,19 @@ const COLUMN = {
|
|
|
19035
19050
|
if (isEvaluationError(cellReference?.value)) {
|
|
19036
19051
|
return cellReference;
|
|
19037
19052
|
}
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
|
|
19042
|
-
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;
|
|
19043
19062
|
}
|
|
19044
|
-
return
|
|
19063
|
+
return generateMatrix(zone.right - zone.left + 1, 1, (col, row) => ({
|
|
19064
|
+
value: zone.left + col + 1,
|
|
19065
|
+
}));
|
|
19045
19066
|
},
|
|
19046
19067
|
isExported: true,
|
|
19047
19068
|
};
|
|
@@ -19272,13 +19293,19 @@ const ROW = {
|
|
|
19272
19293
|
if (isEvaluationError(cellReference?.value)) {
|
|
19273
19294
|
return cellReference;
|
|
19274
19295
|
}
|
|
19275
|
-
|
|
19276
|
-
|
|
19277
|
-
|
|
19278
|
-
|
|
19279
|
-
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;
|
|
19301
|
+
}
|
|
19302
|
+
const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
|
|
19303
|
+
if (zone.top === zone.bottom) {
|
|
19304
|
+
return zone.top + 1;
|
|
19280
19305
|
}
|
|
19281
|
-
return
|
|
19306
|
+
return generateMatrix(1, zone.bottom - zone.top + 1, (col, row) => ({
|
|
19307
|
+
value: zone.top + row + 1,
|
|
19308
|
+
}));
|
|
19282
19309
|
},
|
|
19283
19310
|
isExported: true,
|
|
19284
19311
|
};
|
|
@@ -22855,6 +22882,16 @@ class AbstractChart {
|
|
|
22855
22882
|
static getDefinitionFromContextCreation(context) {
|
|
22856
22883
|
throw new Error("This method should be implemented by sub class");
|
|
22857
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
|
+
}
|
|
22858
22895
|
}
|
|
22859
22896
|
|
|
22860
22897
|
function getBaselineText(baseline, keyValue, baselineMode, humanize, locale) {
|
|
@@ -26337,6 +26374,7 @@ class BarChart extends AbstractChart {
|
|
|
26337
26374
|
labelRange: context.auxiliaryRange || undefined,
|
|
26338
26375
|
axesDesign: context.axesDesign,
|
|
26339
26376
|
showValues: context.showValues,
|
|
26377
|
+
horizontal: context.horizontal,
|
|
26340
26378
|
};
|
|
26341
26379
|
}
|
|
26342
26380
|
getContextCreation() {
|
|
@@ -26394,10 +26432,7 @@ class BarChart extends AbstractChart {
|
|
|
26394
26432
|
};
|
|
26395
26433
|
}
|
|
26396
26434
|
getDefinitionForExcel() {
|
|
26397
|
-
const dataSets = this.dataSets
|
|
26398
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
26399
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
26400
|
-
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));
|
|
26401
26436
|
const definition = this.getDefinition();
|
|
26402
26437
|
return {
|
|
26403
26438
|
...definition,
|
|
@@ -26985,10 +27020,7 @@ class ComboChart extends AbstractChart {
|
|
|
26985
27020
|
if (this.aggregated) {
|
|
26986
27021
|
return undefined;
|
|
26987
27022
|
}
|
|
26988
|
-
const dataSets = this.dataSets
|
|
26989
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
26990
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
26991
|
-
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));
|
|
26992
27024
|
const definition = this.getDefinition();
|
|
26993
27025
|
return {
|
|
26994
27026
|
...definition,
|
|
@@ -27727,10 +27759,7 @@ class LineChart extends AbstractChart {
|
|
|
27727
27759
|
return new LineChart(definition, this.sheetId, this.getters);
|
|
27728
27760
|
}
|
|
27729
27761
|
getDefinitionForExcel() {
|
|
27730
|
-
const dataSets = this.dataSets
|
|
27731
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
27732
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
27733
|
-
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));
|
|
27734
27763
|
const definition = this.getDefinition();
|
|
27735
27764
|
return {
|
|
27736
27765
|
...definition,
|
|
@@ -27818,7 +27847,8 @@ class PieChart extends AbstractChart {
|
|
|
27818
27847
|
type: "pie",
|
|
27819
27848
|
labelRange: context.auxiliaryRange || undefined,
|
|
27820
27849
|
aggregated: context.aggregated ?? false,
|
|
27821
|
-
isDoughnut:
|
|
27850
|
+
isDoughnut: context.isDoughnut,
|
|
27851
|
+
pieHolePercentage: context.pieHolePercentage,
|
|
27822
27852
|
showValues: context.showValues,
|
|
27823
27853
|
};
|
|
27824
27854
|
}
|
|
@@ -27866,10 +27896,7 @@ class PieChart extends AbstractChart {
|
|
|
27866
27896
|
return new PieChart(definition, sheetId, this.getters);
|
|
27867
27897
|
}
|
|
27868
27898
|
getDefinitionForExcel() {
|
|
27869
|
-
const dataSets = this.dataSets
|
|
27870
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
27871
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
27872
|
-
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));
|
|
27873
27900
|
return {
|
|
27874
27901
|
...this.getDefinition(),
|
|
27875
27902
|
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
@@ -28014,8 +28041,22 @@ class PyramidChart extends AbstractChart {
|
|
|
28014
28041
|
showValues: this.showValues,
|
|
28015
28042
|
};
|
|
28016
28043
|
}
|
|
28017
|
-
getDefinitionForExcel() {
|
|
28018
|
-
|
|
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
|
+
};
|
|
28019
28060
|
}
|
|
28020
28061
|
updateRanges(applyChange) {
|
|
28021
28062
|
const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
|
|
@@ -28158,10 +28199,7 @@ class RadarChart extends AbstractChart {
|
|
|
28158
28199
|
if (this.aggregated) {
|
|
28159
28200
|
return undefined;
|
|
28160
28201
|
}
|
|
28161
|
-
const dataSets = this.dataSets
|
|
28162
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
28163
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
28164
|
-
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));
|
|
28165
28203
|
const definition = this.getDefinition();
|
|
28166
28204
|
return {
|
|
28167
28205
|
...definition,
|
|
@@ -32608,6 +32646,9 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
32608
32646
|
get isAutoCompleteDisplayed() {
|
|
32609
32647
|
return !!this.autoComplete.provider;
|
|
32610
32648
|
}
|
|
32649
|
+
get canBeToggled() {
|
|
32650
|
+
return this.autoComplete.provider?.canBeToggled ?? true;
|
|
32651
|
+
}
|
|
32611
32652
|
cycleReferences() {
|
|
32612
32653
|
const locale = this.getters.getLocale();
|
|
32613
32654
|
const updated = cycleFixedReference(this.composerSelection, this._currentContent, locale);
|
|
@@ -33137,6 +33178,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
33137
33178
|
proposals,
|
|
33138
33179
|
selectProposal: provider.selectProposal,
|
|
33139
33180
|
autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
|
|
33181
|
+
canBeToggled: provider.canBeToggled,
|
|
33140
33182
|
};
|
|
33141
33183
|
}
|
|
33142
33184
|
if (exactMatch && this._currentContent !== this.initialContent) {
|
|
@@ -33159,6 +33201,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
33159
33201
|
proposals,
|
|
33160
33202
|
selectProposal: provider.selectProposal,
|
|
33161
33203
|
autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
|
|
33204
|
+
canBeToggled: provider.canBeToggled,
|
|
33162
33205
|
};
|
|
33163
33206
|
}
|
|
33164
33207
|
}
|
|
@@ -33729,9 +33772,13 @@ class Composer extends owl.Component {
|
|
|
33729
33772
|
}
|
|
33730
33773
|
}
|
|
33731
33774
|
closeAssistant() {
|
|
33775
|
+
if (!this.props.composerStore.canBeToggled)
|
|
33776
|
+
return;
|
|
33732
33777
|
this.assistant.forcedClosed = true;
|
|
33733
33778
|
}
|
|
33734
33779
|
openAssistant() {
|
|
33780
|
+
if (!this.props.composerStore.canBeToggled)
|
|
33781
|
+
return;
|
|
33735
33782
|
this.assistant.forcedClosed = false;
|
|
33736
33783
|
}
|
|
33737
33784
|
onWheel(event) {
|
|
@@ -33921,7 +33968,7 @@ class Composer extends owl.Component {
|
|
|
33921
33968
|
return [...new Set(argsToFocus)];
|
|
33922
33969
|
}
|
|
33923
33970
|
autoComplete(value) {
|
|
33924
|
-
if (!value || this.assistant.forcedClosed) {
|
|
33971
|
+
if (!value || (this.assistant.forcedClosed && this.props.composerStore.canBeToggled)) {
|
|
33925
33972
|
return;
|
|
33926
33973
|
}
|
|
33927
33974
|
this.props.composerStore.insertAutoCompleteValue(value);
|
|
@@ -37499,7 +37546,7 @@ const CF_OPERATOR_TYPE_CONVERSION_MAP = {
|
|
|
37499
37546
|
/** Conversion map CF types in XLSX <=> Cf types in o_spreadsheet */
|
|
37500
37547
|
const CF_TYPE_CONVERSION_MAP = {
|
|
37501
37548
|
aboveAverage: undefined,
|
|
37502
|
-
expression:
|
|
37549
|
+
expression: "customFormula",
|
|
37503
37550
|
cellIs: undefined, // exist but isn't an operator in o_spreadsheet
|
|
37504
37551
|
colorScale: undefined, // exist but isn't an operator in o_spreadsheet
|
|
37505
37552
|
dataBar: undefined,
|
|
@@ -38103,7 +38150,6 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
38103
38150
|
case "containsErrors":
|
|
38104
38151
|
case "notContainsErrors":
|
|
38105
38152
|
case "duplicateValues":
|
|
38106
|
-
case "expression":
|
|
38107
38153
|
case "top10":
|
|
38108
38154
|
case "uniqueValues":
|
|
38109
38155
|
case "timePeriod":
|
|
@@ -38136,6 +38182,12 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
38136
38182
|
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
38137
38183
|
values.push(rule.text);
|
|
38138
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;
|
|
38139
38191
|
case "containsBlanks":
|
|
38140
38192
|
case "notContainsBlanks":
|
|
38141
38193
|
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
@@ -38365,6 +38417,8 @@ function convertOperator(operator) {
|
|
|
38365
38417
|
return "equal";
|
|
38366
38418
|
case "isNotEqual":
|
|
38367
38419
|
return "notEqual";
|
|
38420
|
+
case "customFormula":
|
|
38421
|
+
return "";
|
|
38368
38422
|
}
|
|
38369
38423
|
}
|
|
38370
38424
|
// -------------------------------------
|
|
@@ -38700,6 +38754,9 @@ function convertChartData(chartData) {
|
|
|
38700
38754
|
aggregated: false,
|
|
38701
38755
|
cumulative: chartData.cumulative || false,
|
|
38702
38756
|
labelsAsText: false,
|
|
38757
|
+
horizontal: chartData.horizontal,
|
|
38758
|
+
isDoughnut: chartData.isDoughnut,
|
|
38759
|
+
pieHolePercentage: chartData.pieHolePercentage,
|
|
38703
38760
|
};
|
|
38704
38761
|
try {
|
|
38705
38762
|
const ChartClass = chartRegistry.get(chartData.type);
|
|
@@ -39976,6 +40033,12 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
39976
40033
|
const barChartGrouping = this.extractChildAttr(rootChartElement, "c:grouping", "val", {
|
|
39977
40034
|
default: "clustered",
|
|
39978
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();
|
|
39979
40042
|
return {
|
|
39980
40043
|
title: { text: chartTitle },
|
|
39981
40044
|
type: CHART_TYPE_CONVERSION_MAP[chartType],
|
|
@@ -39989,6 +40052,9 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
39989
40052
|
}).asString()],
|
|
39990
40053
|
stacked: barChartGrouping === "stacked",
|
|
39991
40054
|
fontColor: "000000",
|
|
40055
|
+
horizontal: chartDirection === "bar",
|
|
40056
|
+
isDoughnut: chartHoleSize > 0,
|
|
40057
|
+
pieHolePercentage: chartHoleSize,
|
|
39992
40058
|
};
|
|
39993
40059
|
})[0];
|
|
39994
40060
|
}
|
|
@@ -50979,6 +51045,9 @@ class PieChartDesignPanel extends owl.Component {
|
|
|
50979
51045
|
pieHolePercentage,
|
|
50980
51046
|
});
|
|
50981
51047
|
}
|
|
51048
|
+
get defaultHoleSize() {
|
|
51049
|
+
return DEFAULT_DOUGHNUT_CHART_HOLE_SIZE;
|
|
51050
|
+
}
|
|
50982
51051
|
}
|
|
50983
51052
|
|
|
50984
51053
|
class RadarChartDesignPanel extends owl.Component {
|
|
@@ -55702,9 +55771,15 @@ class SpreadsheetPivot {
|
|
|
55702
55771
|
return domain.reduce((current, acc) => this.filterDataEntriesFromDomainNode(current, acc), dataEntries);
|
|
55703
55772
|
}
|
|
55704
55773
|
filterDataEntriesFromDomainNode(dataEntries, domain) {
|
|
55705
|
-
const { field, value } = domain;
|
|
55774
|
+
const { field, value, type } = domain;
|
|
55706
55775
|
const { nameWithGranularity } = this.getDimension(field);
|
|
55707
|
-
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
|
+
});
|
|
55708
55783
|
}
|
|
55709
55784
|
getDimension(nameWithGranularity) {
|
|
55710
55785
|
return this.definition.getDimension(nameWithGranularity);
|
|
@@ -65656,7 +65731,7 @@ class SpreadingRelation {
|
|
|
65656
65731
|
const EMPTY_ARRAY = [];
|
|
65657
65732
|
|
|
65658
65733
|
const MAX_ITERATION = 30;
|
|
65659
|
-
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
|
|
65734
|
+
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell({ ...new CircularDependencyError(), origin: undefined }));
|
|
65660
65735
|
const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
|
|
65661
65736
|
class Evaluator {
|
|
65662
65737
|
context;
|
|
@@ -65890,11 +65965,12 @@ class Evaluator {
|
|
|
65890
65965
|
this.cellsBeingComputed.add(cellId);
|
|
65891
65966
|
return cell.isFormula
|
|
65892
65967
|
? this.computeFormulaCell(position, cell)
|
|
65893
|
-
: evaluateLiteral(cell, localeFormat);
|
|
65968
|
+
: evaluateLiteral(cell, localeFormat, position);
|
|
65894
65969
|
}
|
|
65895
65970
|
catch (e) {
|
|
65896
65971
|
e.value = e?.value || CellErrorType.GenericError;
|
|
65897
65972
|
e.message = e?.message || implementationErrorMessage;
|
|
65973
|
+
e.origin = position;
|
|
65898
65974
|
return createEvaluatedCell(e);
|
|
65899
65975
|
}
|
|
65900
65976
|
finally {
|
|
@@ -65911,7 +65987,7 @@ class Evaluator {
|
|
|
65911
65987
|
computeFormulaCell(formulaPosition, cellData) {
|
|
65912
65988
|
const formulaReturn = updateEvalContextAndExecute(cellData.compiledFormula, this.compilationParams, formulaPosition.sheetId, this.buildSafeGetSymbolValue(), formulaPosition);
|
|
65913
65989
|
if (!isMatrix(formulaReturn)) {
|
|
65914
|
-
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(formulaReturn), this.getters.getLocale(), cellData);
|
|
65990
|
+
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(formulaReturn), this.getters.getLocale(), cellData, formulaPosition);
|
|
65915
65991
|
if (evaluatedCell.type === CellValueType.error) {
|
|
65916
65992
|
evaluatedCell.errorOriginPosition = formulaReturn.errorOriginPosition ?? formulaPosition;
|
|
65917
65993
|
}
|
|
@@ -65987,7 +66063,7 @@ class Evaluator {
|
|
|
65987
66063
|
const spreadValues = (i, j) => {
|
|
65988
66064
|
const position = { sheetId, col: i + col, row: j + row };
|
|
65989
66065
|
const cell = this.getters.getCell(position);
|
|
65990
|
-
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell);
|
|
66066
|
+
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell, position);
|
|
65991
66067
|
if (evaluatedCell.type === CellValueType.error) {
|
|
65992
66068
|
evaluatedCell.errorOriginPosition = matrixResult[i][j].errorOriginPosition ?? position;
|
|
65993
66069
|
}
|
|
@@ -66660,7 +66736,7 @@ class EvaluationChartPlugin extends CoreViewPlugin {
|
|
|
66660
66736
|
continue;
|
|
66661
66737
|
}
|
|
66662
66738
|
const figureId = figure.id;
|
|
66663
|
-
const figureData = this.getters.getChart(figureId)?.getDefinitionForExcel();
|
|
66739
|
+
const figureData = this.getters.getChart(figureId)?.getDefinitionForExcel(this.getters);
|
|
66664
66740
|
if (figureData) {
|
|
66665
66741
|
figures.push({
|
|
66666
66742
|
...figure,
|
|
@@ -67573,6 +67649,23 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
|
|
|
67573
67649
|
static getters = ["getRowSize", "getHeaderSize", "getMaxAnchorOffset"];
|
|
67574
67650
|
tallestCellInRow = {};
|
|
67575
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
|
+
}
|
|
67576
67669
|
handle(cmd) {
|
|
67577
67670
|
switch (cmd.type) {
|
|
67578
67671
|
case "START":
|
|
@@ -67602,16 +67695,6 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
|
|
|
67602
67695
|
this.history.update("tallestCellInRow", cmd.sheetId, tallestCells);
|
|
67603
67696
|
break;
|
|
67604
67697
|
}
|
|
67605
|
-
case "ADD_COLUMNS_ROWS": {
|
|
67606
|
-
if (cmd.dimension === "COL") {
|
|
67607
|
-
return;
|
|
67608
|
-
}
|
|
67609
|
-
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
67610
|
-
const newCells = Array(cmd.quantity).fill(undefined);
|
|
67611
|
-
const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
|
|
67612
|
-
this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
|
|
67613
|
-
break;
|
|
67614
|
-
}
|
|
67615
67698
|
case "RESIZE_COLUMNS_ROWS":
|
|
67616
67699
|
{
|
|
67617
67700
|
const sheetId = cmd.sheetId;
|
|
@@ -74160,6 +74243,14 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
74160
74243
|
const isBasedBefore = cmd.base < start;
|
|
74161
74244
|
const deltaCol = isBasedBefore && isCol ? thickness : 0;
|
|
74162
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
|
+
}));
|
|
74163
74254
|
const target = [
|
|
74164
74255
|
{
|
|
74165
74256
|
left: isCol ? start + deltaCol : 0,
|
|
@@ -74190,13 +74281,12 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
74190
74281
|
const col = selection.left;
|
|
74191
74282
|
const row = selection.top;
|
|
74192
74283
|
this.setSelectionMixin({ zone: selection, cell: { col, row } }, [selection]);
|
|
74193
|
-
const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
|
|
74194
74284
|
let currentIndex = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
74195
74285
|
const resizingGroups = {};
|
|
74196
74286
|
for (const element of toRemove) {
|
|
74197
|
-
const size =
|
|
74287
|
+
const size = originalSize[element];
|
|
74198
74288
|
const currentSize = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, currentIndex);
|
|
74199
|
-
if (size !== currentSize) {
|
|
74289
|
+
if (size && size !== currentSize) {
|
|
74200
74290
|
resizingGroups[size] ??= [];
|
|
74201
74291
|
resizingGroups[size].push(currentIndex);
|
|
74202
74292
|
currentIndex += 1;
|
|
@@ -75622,6 +75712,7 @@ const coreViewsPluginRegistry = new Registry()
|
|
|
75622
75712
|
|
|
75623
75713
|
autoCompleteProviders.add("dataValidation", {
|
|
75624
75714
|
displayAllOnInitialContent: true,
|
|
75715
|
+
canBeToggled: false,
|
|
75625
75716
|
getProposals(tokenAtCursor, content) {
|
|
75626
75717
|
if (isFormula(content)) {
|
|
75627
75718
|
return [];
|
|
@@ -77187,14 +77278,12 @@ class BottomBarSheet extends owl.Component {
|
|
|
77187
77278
|
this.editionState = "initializing";
|
|
77188
77279
|
}
|
|
77189
77280
|
stopEdition() {
|
|
77190
|
-
|
|
77191
|
-
if (!this.state.isEditing || !input)
|
|
77281
|
+
if (!this.state.isEditing || !this.sheetNameRef.el)
|
|
77192
77282
|
return;
|
|
77193
77283
|
this.state.isEditing = false;
|
|
77194
77284
|
this.editionState = "initializing";
|
|
77195
|
-
|
|
77285
|
+
this.sheetNameRef.el.blur();
|
|
77196
77286
|
const inputValue = this.getInputContent() || "";
|
|
77197
|
-
input.innerText = inputValue;
|
|
77198
77287
|
interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
|
|
77199
77288
|
}
|
|
77200
77289
|
cancelEdition() {
|
|
@@ -81612,6 +81701,9 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81612
81701
|
case "combo":
|
|
81613
81702
|
plot = addComboChart(chart.data);
|
|
81614
81703
|
break;
|
|
81704
|
+
case "pyramid":
|
|
81705
|
+
plot = addPyramidChart(chart.data);
|
|
81706
|
+
break;
|
|
81615
81707
|
case "line":
|
|
81616
81708
|
plot = addLineChart(chart.data);
|
|
81617
81709
|
break;
|
|
@@ -81619,12 +81711,12 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81619
81711
|
plot = addScatterChart(chart.data);
|
|
81620
81712
|
break;
|
|
81621
81713
|
case "pie":
|
|
81622
|
-
plot = addDoughnutChart(chart.data, chartSheetIndex, data
|
|
81714
|
+
plot = addDoughnutChart(chart.data, chartSheetIndex, data);
|
|
81623
81715
|
break;
|
|
81624
81716
|
case "radar":
|
|
81625
81717
|
plot = addRadarChart(chart.data);
|
|
81626
81718
|
}
|
|
81627
|
-
let position = "
|
|
81719
|
+
let position = "none";
|
|
81628
81720
|
switch (chart.data.legendPosition) {
|
|
81629
81721
|
case "bottom":
|
|
81630
81722
|
position = "b";
|
|
@@ -81654,7 +81746,7 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81654
81746
|
${plot}
|
|
81655
81747
|
${shapeProperty({ backgroundColor: chart.data.backgroundColor })}
|
|
81656
81748
|
</c:plotArea>
|
|
81657
|
-
${addLegend(position, fontColor)}
|
|
81749
|
+
${position !== "none" ? addLegend(position, fontColor) : ""}
|
|
81658
81750
|
</c:chart>
|
|
81659
81751
|
</c:chartSpace>
|
|
81660
81752
|
`;
|
|
@@ -81812,6 +81904,7 @@ function addBarChart(chart) {
|
|
|
81812
81904
|
//
|
|
81813
81905
|
// overlap and gapWitdh seems to be by default at -20 and 20 in chart.js.
|
|
81814
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";
|
|
81815
81908
|
const dataSetsColors = chart.dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
81816
81909
|
const colors = new ColorGenerator(chart.dataSets.length, dataSetsColors);
|
|
81817
81910
|
const leftDataSetsNodes = [];
|
|
@@ -81848,7 +81941,7 @@ function addBarChart(chart) {
|
|
|
81848
81941
|
${leftDataSetsNodes.length
|
|
81849
81942
|
? escapeXml /*xml*/ `
|
|
81850
81943
|
<c:barChart>
|
|
81851
|
-
<c:barDir val="
|
|
81944
|
+
<c:barDir val="${chartDirection}"/>
|
|
81852
81945
|
<c:grouping val="${grouping}"/>
|
|
81853
81946
|
<c:overlap val="${overlap}"/>
|
|
81854
81947
|
<c:gapWidth val="70"/>
|
|
@@ -81858,8 +81951,12 @@ function addBarChart(chart) {
|
|
|
81858
81951
|
<c:axId val="${catAxId}" />
|
|
81859
81952
|
<c:axId val="${valAxId}" />
|
|
81860
81953
|
</c:barChart>
|
|
81861
|
-
${
|
|
81862
|
-
|
|
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")}
|
|
81863
81960
|
`
|
|
81864
81961
|
: ""}
|
|
81865
81962
|
${rightDataSetsNodes.length
|
|
@@ -81985,7 +82082,7 @@ function addComboChart(chart) {
|
|
|
81985
82082
|
: ""}
|
|
81986
82083
|
${!useRightAxisForBarSerie || leftDataSetsNodes.length
|
|
81987
82084
|
? escapeXml /*xml*/ `
|
|
81988
|
-
${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)}
|
|
81989
82086
|
${addAx("l", "c:valAx", valAxId, catAxId, chart.axesDesign?.y?.title, chart.fontColor)}
|
|
81990
82087
|
`
|
|
81991
82088
|
: ""}
|
|
@@ -81997,6 +82094,94 @@ function addComboChart(chart) {
|
|
|
81997
82094
|
: ""}
|
|
81998
82095
|
`;
|
|
81999
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
|
+
}
|
|
82000
82185
|
function addLineChart(chart) {
|
|
82001
82186
|
const dataSetsColors = chart.dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
82002
82187
|
const colors = new ColorGenerator(chart.dataSets.length, dataSetsColors);
|
|
@@ -82189,7 +82374,7 @@ function addRadarChart(chart) {
|
|
|
82189
82374
|
`}
|
|
82190
82375
|
`;
|
|
82191
82376
|
}
|
|
82192
|
-
function addDoughnutChart(chart, chartSheetIndex, data
|
|
82377
|
+
function addDoughnutChart(chart, chartSheetIndex, data) {
|
|
82193
82378
|
const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
|
|
82194
82379
|
const colors = new ColorGenerator(maxLength);
|
|
82195
82380
|
const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
|
|
@@ -82227,7 +82412,7 @@ function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSiz
|
|
|
82227
82412
|
return escapeXml /*xml*/ `
|
|
82228
82413
|
<c:doughnutChart>
|
|
82229
82414
|
<c:varyColors val="1" />
|
|
82230
|
-
<c:holeSize val="${
|
|
82415
|
+
<c:holeSize val="${chart.pieHolePercentage ?? (chart.isDoughnut ? DEFAULT_DOUGHNUT_CHART_HOLE_SIZE : 0)}" />
|
|
82231
82416
|
${insertDataLabels()}
|
|
82232
82417
|
${joinXmlNodes(dataSetsNodes)}
|
|
82233
82418
|
</c:doughnutChart>
|
|
@@ -82246,25 +82431,35 @@ function insertDataLabels({ showLeaderLines } = { showLeaderLines: false }) {
|
|
|
82246
82431
|
</dLbls>
|
|
82247
82432
|
`;
|
|
82248
82433
|
}
|
|
82249
|
-
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") {
|
|
82250
82435
|
// Each Axis present inside a graph needs to be identified by an unsigned integer in order to be referenced by its crossAxis.
|
|
82251
82436
|
// I.e. x-axis, will reference y-axis and vice-versa.
|
|
82252
82437
|
const color = title?.color ? toXlsxHexColor(title.color) : defaultFontColor;
|
|
82253
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}" />` : "";
|
|
82254
82443
|
return escapeXml /*xml*/ `
|
|
82255
82444
|
<${axisName}>
|
|
82256
82445
|
<c:axId val="${axId}"/>
|
|
82257
82446
|
<c:crossAx val="${crossAxId}"/> <!-- reference to the other axe of the chart -->
|
|
82258
|
-
<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}
|
|
82259
82450
|
<c:delete val="${deleteAxis}"/> <!-- by default, axis are not displayed -->
|
|
82260
82451
|
<c:scaling>
|
|
82261
|
-
<c:orientation val="
|
|
82452
|
+
<c:orientation val="${orientation}" />
|
|
82453
|
+
${maxValueEl}
|
|
82454
|
+
${minValueEl}
|
|
82262
82455
|
</c:scaling>
|
|
82456
|
+
${majorUnitEl}
|
|
82263
82457
|
<c:axPos val="${position}" />
|
|
82458
|
+
<c:tickLblPos val="${tickLabelPosition}" />
|
|
82264
82459
|
${insertMajorGridLines()}
|
|
82265
82460
|
<c:majorTickMark val="out" />
|
|
82266
82461
|
<c:minorTickMark val="none" />
|
|
82267
|
-
<c:numFmt formatCode="
|
|
82462
|
+
<c:numFmt formatCode="${format}" sourceLinked="${format === "General" ? "1" : "0"}" />
|
|
82268
82463
|
<c:title>
|
|
82269
82464
|
${insertText(title?.text ?? "", color, fontSize, title)}
|
|
82270
82465
|
</c:title>
|
|
@@ -82459,7 +82654,10 @@ function addConditionalFormatting(dxfs, conditionalFormats) {
|
|
|
82459
82654
|
function addCellIsRule(cf, rule, dxfs) {
|
|
82460
82655
|
const ruleAttributes = commonCfAttributes(cf);
|
|
82461
82656
|
const operator = convertOperator(rule.operator);
|
|
82462
|
-
ruleAttributes.push(...cellRuleTypeAttributes(rule)
|
|
82657
|
+
ruleAttributes.push(...cellRuleTypeAttributes(rule));
|
|
82658
|
+
if (operator.length) {
|
|
82659
|
+
ruleAttributes.push(["operator", operator]);
|
|
82660
|
+
}
|
|
82463
82661
|
const formulas = cellRuleFormula(cf.ranges, rule).map((formula) => escapeXml /*xml*/ `<formula>${formula}</formula>`);
|
|
82464
82662
|
const dxf = {
|
|
82465
82663
|
font: {
|
|
@@ -82505,6 +82703,8 @@ function cellRuleFormula(ranges, rule) {
|
|
|
82505
82703
|
case "isLessThan":
|
|
82506
82704
|
case "isLessOrEqualTo":
|
|
82507
82705
|
return [values[0]];
|
|
82706
|
+
case "customFormula":
|
|
82707
|
+
return values[0].startsWith("=") ? [values[0].slice(1)] : [values[0]];
|
|
82508
82708
|
case "isBetween":
|
|
82509
82709
|
case "isNotBetween":
|
|
82510
82710
|
return [values[0], values[1]];
|
|
@@ -82533,6 +82733,8 @@ function cellRuleTypeAttributes(rule) {
|
|
|
82533
82733
|
case "isBetween":
|
|
82534
82734
|
case "isNotBetween":
|
|
82535
82735
|
return [["type", "cellIs"]];
|
|
82736
|
+
case "customFormula":
|
|
82737
|
+
return [["type", "expression"]];
|
|
82536
82738
|
}
|
|
82537
82739
|
}
|
|
82538
82740
|
function addDataBarRule(cf, rule) {
|
|
@@ -84633,6 +84835,6 @@ exports.tokenColors = tokenColors;
|
|
|
84633
84835
|
exports.tokenize = tokenize;
|
|
84634
84836
|
|
|
84635
84837
|
|
|
84636
|
-
__info__.version = "18.5.0-alpha.
|
|
84637
|
-
__info__.date = "2025-07-
|
|
84638
|
-
__info__.hash = "
|
|
84838
|
+
__info__.version = "18.5.0-alpha.3";
|
|
84839
|
+
__info__.date = "2025-07-28T13:43:05.981Z";
|
|
84840
|
+
__info__.hash = "53dfee8";
|