@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
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -2901,6 +2901,7 @@ const availableConditionalFormatOperators = new Set([
|
|
|
2901
2901
|
"isEmpty",
|
|
2902
2902
|
"isNotEqual",
|
|
2903
2903
|
"isEqual",
|
|
2904
|
+
"customFormula",
|
|
2904
2905
|
]);
|
|
2905
2906
|
|
|
2906
2907
|
const availableDataValidationOperators = new Set([
|
|
@@ -5033,11 +5034,11 @@ function isTextFormat(format) {
|
|
|
5033
5034
|
}
|
|
5034
5035
|
}
|
|
5035
5036
|
|
|
5036
|
-
function evaluateLiteral(literalCell, localeFormat) {
|
|
5037
|
+
function evaluateLiteral(literalCell, localeFormat, position) {
|
|
5037
5038
|
const value = isTextFormat(localeFormat.format) && literalCell.parsedValue !== null
|
|
5038
5039
|
? literalCell.content
|
|
5039
5040
|
: literalCell.parsedValue;
|
|
5040
|
-
const functionResult = { value, format: localeFormat.format };
|
|
5041
|
+
const functionResult = { value, format: localeFormat.format, origin: position };
|
|
5041
5042
|
return createEvaluatedCell(functionResult, localeFormat.locale);
|
|
5042
5043
|
}
|
|
5043
5044
|
function parseLiteral(content, locale) {
|
|
@@ -5059,10 +5060,11 @@ function parseLiteral(content, locale) {
|
|
|
5059
5060
|
}
|
|
5060
5061
|
return content;
|
|
5061
5062
|
}
|
|
5062
|
-
function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell) {
|
|
5063
|
+
function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell, origin) {
|
|
5063
5064
|
const link = detectLink(functionResult.value);
|
|
5064
5065
|
if (!link) {
|
|
5065
|
-
|
|
5066
|
+
const evaluateCell = _createEvaluatedCell(functionResult, locale, cell);
|
|
5067
|
+
return addOrigin(evaluateCell, functionResult.origin ?? origin);
|
|
5066
5068
|
}
|
|
5067
5069
|
const value = parseLiteral(link.label, locale);
|
|
5068
5070
|
const format = functionResult.format ||
|
|
@@ -5073,10 +5075,10 @@ function createEvaluatedCell(functionResult, locale = DEFAULT_LOCALE, cell) {
|
|
|
5073
5075
|
value,
|
|
5074
5076
|
format,
|
|
5075
5077
|
};
|
|
5076
|
-
return {
|
|
5078
|
+
return addOrigin({
|
|
5077
5079
|
..._createEvaluatedCell(linkPayload, locale, cell),
|
|
5078
5080
|
link,
|
|
5079
|
-
};
|
|
5081
|
+
}, functionResult.origin ?? origin);
|
|
5080
5082
|
}
|
|
5081
5083
|
function _createEvaluatedCell(functionResult, locale, cell) {
|
|
5082
5084
|
let { value, format, message } = functionResult;
|
|
@@ -5166,6 +5168,17 @@ function errorCell(value, message) {
|
|
|
5166
5168
|
defaultAlign: "center",
|
|
5167
5169
|
};
|
|
5168
5170
|
}
|
|
5171
|
+
function addOrigin(cell, origin) {
|
|
5172
|
+
if (cell.value === null) {
|
|
5173
|
+
// ignore empty cells to allow sharing the same object instance
|
|
5174
|
+
return cell;
|
|
5175
|
+
}
|
|
5176
|
+
if ("origin" in cell) {
|
|
5177
|
+
return cell;
|
|
5178
|
+
}
|
|
5179
|
+
cell.origin = origin;
|
|
5180
|
+
return cell;
|
|
5181
|
+
}
|
|
5169
5182
|
|
|
5170
5183
|
function toCriterionDateNumber(dateValue) {
|
|
5171
5184
|
const today = DateTime.now();
|
|
@@ -7846,6 +7859,7 @@ function changeCFRuleLocale(rule, changeContentLocale) {
|
|
|
7846
7859
|
case "isGreaterOrEqualTo":
|
|
7847
7860
|
case "isLessThan":
|
|
7848
7861
|
case "isLessOrEqualTo":
|
|
7862
|
+
case "customFormula":
|
|
7849
7863
|
rule.values = rule.values.map((v) => changeContentLocale(v));
|
|
7850
7864
|
return rule;
|
|
7851
7865
|
case "beginsWithText":
|
|
@@ -10534,6 +10548,7 @@ const EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS = 100;
|
|
|
10534
10548
|
/** The possible values for the XLSX polynomial trendline order are defined by the ST_Order simple type (§21.2.3.29) */
|
|
10535
10549
|
const MAX_XLSX_POLYNOMIAL_DEGREE = 6;
|
|
10536
10550
|
const FIRST_NUMFMT_ID = 164;
|
|
10551
|
+
const DEFAULT_DOUGHNUT_CHART_HOLE_SIZE = 50;
|
|
10537
10552
|
const FORCE_DEFAULT_ARGS_FUNCTIONS = {
|
|
10538
10553
|
FLOOR: [{ type: "NUMBER", value: 1 }],
|
|
10539
10554
|
CEILING: [{ type: "NUMBER", value: 1 }],
|
|
@@ -19033,13 +19048,19 @@ const COLUMN = {
|
|
|
19033
19048
|
if (isEvaluationError(cellReference?.value)) {
|
|
19034
19049
|
return cellReference;
|
|
19035
19050
|
}
|
|
19036
|
-
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
return
|
|
19051
|
+
if (cellReference === undefined) {
|
|
19052
|
+
if (this.__originCellPosition?.col === undefined) {
|
|
19053
|
+
return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
|
|
19054
|
+
}
|
|
19055
|
+
return this.__originCellPosition.col + 1;
|
|
19056
|
+
}
|
|
19057
|
+
const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
|
|
19058
|
+
if (zone.left === zone.right) {
|
|
19059
|
+
return zone.left + 1;
|
|
19041
19060
|
}
|
|
19042
|
-
return
|
|
19061
|
+
return generateMatrix(zone.right - zone.left + 1, 1, (col, row) => ({
|
|
19062
|
+
value: zone.left + col + 1,
|
|
19063
|
+
}));
|
|
19043
19064
|
},
|
|
19044
19065
|
isExported: true,
|
|
19045
19066
|
};
|
|
@@ -19270,13 +19291,19 @@ const ROW = {
|
|
|
19270
19291
|
if (isEvaluationError(cellReference?.value)) {
|
|
19271
19292
|
return cellReference;
|
|
19272
19293
|
}
|
|
19273
|
-
|
|
19274
|
-
|
|
19275
|
-
|
|
19276
|
-
|
|
19277
|
-
return
|
|
19294
|
+
if (cellReference === undefined) {
|
|
19295
|
+
if (this.__originCellPosition?.row === undefined) {
|
|
19296
|
+
return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
|
|
19297
|
+
}
|
|
19298
|
+
return this.__originCellPosition.row + 1;
|
|
19299
|
+
}
|
|
19300
|
+
const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
|
|
19301
|
+
if (zone.top === zone.bottom) {
|
|
19302
|
+
return zone.top + 1;
|
|
19278
19303
|
}
|
|
19279
|
-
return
|
|
19304
|
+
return generateMatrix(1, zone.bottom - zone.top + 1, (col, row) => ({
|
|
19305
|
+
value: zone.top + row + 1,
|
|
19306
|
+
}));
|
|
19280
19307
|
},
|
|
19281
19308
|
isExported: true,
|
|
19282
19309
|
};
|
|
@@ -22853,6 +22880,16 @@ class AbstractChart {
|
|
|
22853
22880
|
static getDefinitionFromContextCreation(context) {
|
|
22854
22881
|
throw new Error("This method should be implemented by sub class");
|
|
22855
22882
|
}
|
|
22883
|
+
getCommonDataSetAttributesForExcel(labelRange, dataSets, shouldRemoveFirstLabel) {
|
|
22884
|
+
const excelDataSets = dataSets
|
|
22885
|
+
.map((ds) => toExcelDataset(this.getters, ds))
|
|
22886
|
+
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
22887
|
+
const excelLabelRange = toExcelLabelRange(this.getters, labelRange, shouldRemoveFirstLabel);
|
|
22888
|
+
return {
|
|
22889
|
+
dataSets: excelDataSets,
|
|
22890
|
+
labelRange: excelLabelRange,
|
|
22891
|
+
};
|
|
22892
|
+
}
|
|
22856
22893
|
}
|
|
22857
22894
|
|
|
22858
22895
|
function getBaselineText(baseline, keyValue, baselineMode, humanize, locale) {
|
|
@@ -26335,6 +26372,7 @@ class BarChart extends AbstractChart {
|
|
|
26335
26372
|
labelRange: context.auxiliaryRange || undefined,
|
|
26336
26373
|
axesDesign: context.axesDesign,
|
|
26337
26374
|
showValues: context.showValues,
|
|
26375
|
+
horizontal: context.horizontal,
|
|
26338
26376
|
};
|
|
26339
26377
|
}
|
|
26340
26378
|
getContextCreation() {
|
|
@@ -26392,10 +26430,7 @@ class BarChart extends AbstractChart {
|
|
|
26392
26430
|
};
|
|
26393
26431
|
}
|
|
26394
26432
|
getDefinitionForExcel() {
|
|
26395
|
-
const dataSets = this.dataSets
|
|
26396
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
26397
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
26398
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
26433
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
26399
26434
|
const definition = this.getDefinition();
|
|
26400
26435
|
return {
|
|
26401
26436
|
...definition,
|
|
@@ -26983,10 +27018,7 @@ class ComboChart extends AbstractChart {
|
|
|
26983
27018
|
if (this.aggregated) {
|
|
26984
27019
|
return undefined;
|
|
26985
27020
|
}
|
|
26986
|
-
const dataSets = this.dataSets
|
|
26987
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
26988
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
26989
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27021
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
26990
27022
|
const definition = this.getDefinition();
|
|
26991
27023
|
return {
|
|
26992
27024
|
...definition,
|
|
@@ -27725,10 +27757,7 @@ class LineChart extends AbstractChart {
|
|
|
27725
27757
|
return new LineChart(definition, this.sheetId, this.getters);
|
|
27726
27758
|
}
|
|
27727
27759
|
getDefinitionForExcel() {
|
|
27728
|
-
const dataSets = this.dataSets
|
|
27729
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
27730
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
27731
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27760
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27732
27761
|
const definition = this.getDefinition();
|
|
27733
27762
|
return {
|
|
27734
27763
|
...definition,
|
|
@@ -27816,7 +27845,8 @@ class PieChart extends AbstractChart {
|
|
|
27816
27845
|
type: "pie",
|
|
27817
27846
|
labelRange: context.auxiliaryRange || undefined,
|
|
27818
27847
|
aggregated: context.aggregated ?? false,
|
|
27819
|
-
isDoughnut:
|
|
27848
|
+
isDoughnut: context.isDoughnut,
|
|
27849
|
+
pieHolePercentage: context.pieHolePercentage,
|
|
27820
27850
|
showValues: context.showValues,
|
|
27821
27851
|
};
|
|
27822
27852
|
}
|
|
@@ -27864,10 +27894,7 @@ class PieChart extends AbstractChart {
|
|
|
27864
27894
|
return new PieChart(definition, sheetId, this.getters);
|
|
27865
27895
|
}
|
|
27866
27896
|
getDefinitionForExcel() {
|
|
27867
|
-
const dataSets = this.dataSets
|
|
27868
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
27869
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
27870
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27897
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
27871
27898
|
return {
|
|
27872
27899
|
...this.getDefinition(),
|
|
27873
27900
|
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
@@ -28012,8 +28039,22 @@ class PyramidChart extends AbstractChart {
|
|
|
28012
28039
|
showValues: this.showValues,
|
|
28013
28040
|
};
|
|
28014
28041
|
}
|
|
28015
|
-
getDefinitionForExcel() {
|
|
28016
|
-
|
|
28042
|
+
getDefinitionForExcel(getters) {
|
|
28043
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
28044
|
+
const definition = this.getDefinition();
|
|
28045
|
+
const chartData = getPyramidChartData(definition, this.dataSets, this.labelRange, getters);
|
|
28046
|
+
const { dataSetsValues } = chartData;
|
|
28047
|
+
const maxValue = Math.max(...dataSetsValues.map((dataSet) => Math.max(...dataSet.data.map(Math.abs))));
|
|
28048
|
+
return {
|
|
28049
|
+
...definition,
|
|
28050
|
+
horizontal: true,
|
|
28051
|
+
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
28052
|
+
fontColor: toXlsxHexColor(chartFontColor(this.background)),
|
|
28053
|
+
dataSets,
|
|
28054
|
+
labelRange,
|
|
28055
|
+
verticalAxis: getDefinedAxis(definition),
|
|
28056
|
+
maxValue,
|
|
28057
|
+
};
|
|
28017
28058
|
}
|
|
28018
28059
|
updateRanges(applyChange) {
|
|
28019
28060
|
const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
|
|
@@ -28156,10 +28197,7 @@ class RadarChart extends AbstractChart {
|
|
|
28156
28197
|
if (this.aggregated) {
|
|
28157
28198
|
return undefined;
|
|
28158
28199
|
}
|
|
28159
|
-
const dataSets = this.dataSets
|
|
28160
|
-
.map((ds) => toExcelDataset(this.getters, ds))
|
|
28161
|
-
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
28162
|
-
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
28200
|
+
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
28163
28201
|
const definition = this.getDefinition();
|
|
28164
28202
|
return {
|
|
28165
28203
|
...definition,
|
|
@@ -32606,6 +32644,9 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
32606
32644
|
get isAutoCompleteDisplayed() {
|
|
32607
32645
|
return !!this.autoComplete.provider;
|
|
32608
32646
|
}
|
|
32647
|
+
get canBeToggled() {
|
|
32648
|
+
return this.autoComplete.provider?.canBeToggled ?? true;
|
|
32649
|
+
}
|
|
32609
32650
|
cycleReferences() {
|
|
32610
32651
|
const locale = this.getters.getLocale();
|
|
32611
32652
|
const updated = cycleFixedReference(this.composerSelection, this._currentContent, locale);
|
|
@@ -33135,6 +33176,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
33135
33176
|
proposals,
|
|
33136
33177
|
selectProposal: provider.selectProposal,
|
|
33137
33178
|
autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
|
|
33179
|
+
canBeToggled: provider.canBeToggled,
|
|
33138
33180
|
};
|
|
33139
33181
|
}
|
|
33140
33182
|
if (exactMatch && this._currentContent !== this.initialContent) {
|
|
@@ -33157,6 +33199,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
33157
33199
|
proposals,
|
|
33158
33200
|
selectProposal: provider.selectProposal,
|
|
33159
33201
|
autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
|
|
33202
|
+
canBeToggled: provider.canBeToggled,
|
|
33160
33203
|
};
|
|
33161
33204
|
}
|
|
33162
33205
|
}
|
|
@@ -33727,9 +33770,13 @@ class Composer extends Component {
|
|
|
33727
33770
|
}
|
|
33728
33771
|
}
|
|
33729
33772
|
closeAssistant() {
|
|
33773
|
+
if (!this.props.composerStore.canBeToggled)
|
|
33774
|
+
return;
|
|
33730
33775
|
this.assistant.forcedClosed = true;
|
|
33731
33776
|
}
|
|
33732
33777
|
openAssistant() {
|
|
33778
|
+
if (!this.props.composerStore.canBeToggled)
|
|
33779
|
+
return;
|
|
33733
33780
|
this.assistant.forcedClosed = false;
|
|
33734
33781
|
}
|
|
33735
33782
|
onWheel(event) {
|
|
@@ -33919,7 +33966,7 @@ class Composer extends Component {
|
|
|
33919
33966
|
return [...new Set(argsToFocus)];
|
|
33920
33967
|
}
|
|
33921
33968
|
autoComplete(value) {
|
|
33922
|
-
if (!value || this.assistant.forcedClosed) {
|
|
33969
|
+
if (!value || (this.assistant.forcedClosed && this.props.composerStore.canBeToggled)) {
|
|
33923
33970
|
return;
|
|
33924
33971
|
}
|
|
33925
33972
|
this.props.composerStore.insertAutoCompleteValue(value);
|
|
@@ -37497,7 +37544,7 @@ const CF_OPERATOR_TYPE_CONVERSION_MAP = {
|
|
|
37497
37544
|
/** Conversion map CF types in XLSX <=> Cf types in o_spreadsheet */
|
|
37498
37545
|
const CF_TYPE_CONVERSION_MAP = {
|
|
37499
37546
|
aboveAverage: undefined,
|
|
37500
|
-
expression:
|
|
37547
|
+
expression: "customFormula",
|
|
37501
37548
|
cellIs: undefined, // exist but isn't an operator in o_spreadsheet
|
|
37502
37549
|
colorScale: undefined, // exist but isn't an operator in o_spreadsheet
|
|
37503
37550
|
dataBar: undefined,
|
|
@@ -38101,7 +38148,6 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
38101
38148
|
case "containsErrors":
|
|
38102
38149
|
case "notContainsErrors":
|
|
38103
38150
|
case "duplicateValues":
|
|
38104
|
-
case "expression":
|
|
38105
38151
|
case "top10":
|
|
38106
38152
|
case "uniqueValues":
|
|
38107
38153
|
case "timePeriod":
|
|
@@ -38134,6 +38180,12 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
38134
38180
|
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
38135
38181
|
values.push(rule.text);
|
|
38136
38182
|
break;
|
|
38183
|
+
case "expression":
|
|
38184
|
+
if (!rule.formula?.length)
|
|
38185
|
+
continue;
|
|
38186
|
+
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
38187
|
+
values.push(`=${rule.formula[0]}`);
|
|
38188
|
+
break;
|
|
38137
38189
|
case "containsBlanks":
|
|
38138
38190
|
case "notContainsBlanks":
|
|
38139
38191
|
operator = CF_TYPE_CONVERSION_MAP[rule.type];
|
|
@@ -38363,6 +38415,8 @@ function convertOperator(operator) {
|
|
|
38363
38415
|
return "equal";
|
|
38364
38416
|
case "isNotEqual":
|
|
38365
38417
|
return "notEqual";
|
|
38418
|
+
case "customFormula":
|
|
38419
|
+
return "";
|
|
38366
38420
|
}
|
|
38367
38421
|
}
|
|
38368
38422
|
// -------------------------------------
|
|
@@ -38698,6 +38752,9 @@ function convertChartData(chartData) {
|
|
|
38698
38752
|
aggregated: false,
|
|
38699
38753
|
cumulative: chartData.cumulative || false,
|
|
38700
38754
|
labelsAsText: false,
|
|
38755
|
+
horizontal: chartData.horizontal,
|
|
38756
|
+
isDoughnut: chartData.isDoughnut,
|
|
38757
|
+
pieHolePercentage: chartData.pieHolePercentage,
|
|
38701
38758
|
};
|
|
38702
38759
|
try {
|
|
38703
38760
|
const ChartClass = chartRegistry.get(chartData.type);
|
|
@@ -39974,6 +40031,12 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
39974
40031
|
const barChartGrouping = this.extractChildAttr(rootChartElement, "c:grouping", "val", {
|
|
39975
40032
|
default: "clustered",
|
|
39976
40033
|
}).asString();
|
|
40034
|
+
const chartDirection = this.extractChildAttr(rootChartElement, "c:barDir", "val", {
|
|
40035
|
+
default: "col",
|
|
40036
|
+
}).asString();
|
|
40037
|
+
const chartHoleSize = this.extractChildAttr(rootChartElement, "c:holeSize", "val", {
|
|
40038
|
+
default: "0",
|
|
40039
|
+
}).asNum();
|
|
39977
40040
|
return {
|
|
39978
40041
|
title: { text: chartTitle },
|
|
39979
40042
|
type: CHART_TYPE_CONVERSION_MAP[chartType],
|
|
@@ -39987,6 +40050,9 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
39987
40050
|
}).asString()],
|
|
39988
40051
|
stacked: barChartGrouping === "stacked",
|
|
39989
40052
|
fontColor: "000000",
|
|
40053
|
+
horizontal: chartDirection === "bar",
|
|
40054
|
+
isDoughnut: chartHoleSize > 0,
|
|
40055
|
+
pieHolePercentage: chartHoleSize,
|
|
39990
40056
|
};
|
|
39991
40057
|
})[0];
|
|
39992
40058
|
}
|
|
@@ -50977,6 +51043,9 @@ class PieChartDesignPanel extends Component {
|
|
|
50977
51043
|
pieHolePercentage,
|
|
50978
51044
|
});
|
|
50979
51045
|
}
|
|
51046
|
+
get defaultHoleSize() {
|
|
51047
|
+
return DEFAULT_DOUGHNUT_CHART_HOLE_SIZE;
|
|
51048
|
+
}
|
|
50980
51049
|
}
|
|
50981
51050
|
|
|
50982
51051
|
class RadarChartDesignPanel extends Component {
|
|
@@ -55700,9 +55769,15 @@ class SpreadsheetPivot {
|
|
|
55700
55769
|
return domain.reduce((current, acc) => this.filterDataEntriesFromDomainNode(current, acc), dataEntries);
|
|
55701
55770
|
}
|
|
55702
55771
|
filterDataEntriesFromDomainNode(dataEntries, domain) {
|
|
55703
|
-
const { field, value } = domain;
|
|
55772
|
+
const { field, value, type } = domain;
|
|
55704
55773
|
const { nameWithGranularity } = this.getDimension(field);
|
|
55705
|
-
return dataEntries.filter((entry) =>
|
|
55774
|
+
return dataEntries.filter((entry) => {
|
|
55775
|
+
const cellValue = entry[nameWithGranularity]?.value;
|
|
55776
|
+
if (type === "char") {
|
|
55777
|
+
return String(cellValue) === String(value);
|
|
55778
|
+
}
|
|
55779
|
+
return cellValue === value;
|
|
55780
|
+
});
|
|
55706
55781
|
}
|
|
55707
55782
|
getDimension(nameWithGranularity) {
|
|
55708
55783
|
return this.definition.getDimension(nameWithGranularity);
|
|
@@ -65654,7 +65729,7 @@ class SpreadingRelation {
|
|
|
65654
65729
|
const EMPTY_ARRAY = [];
|
|
65655
65730
|
|
|
65656
65731
|
const MAX_ITERATION = 30;
|
|
65657
|
-
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
|
|
65732
|
+
const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell({ ...new CircularDependencyError(), origin: undefined }));
|
|
65658
65733
|
const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
|
|
65659
65734
|
class Evaluator {
|
|
65660
65735
|
context;
|
|
@@ -65888,11 +65963,12 @@ class Evaluator {
|
|
|
65888
65963
|
this.cellsBeingComputed.add(cellId);
|
|
65889
65964
|
return cell.isFormula
|
|
65890
65965
|
? this.computeFormulaCell(position, cell)
|
|
65891
|
-
: evaluateLiteral(cell, localeFormat);
|
|
65966
|
+
: evaluateLiteral(cell, localeFormat, position);
|
|
65892
65967
|
}
|
|
65893
65968
|
catch (e) {
|
|
65894
65969
|
e.value = e?.value || CellErrorType.GenericError;
|
|
65895
65970
|
e.message = e?.message || implementationErrorMessage;
|
|
65971
|
+
e.origin = position;
|
|
65896
65972
|
return createEvaluatedCell(e);
|
|
65897
65973
|
}
|
|
65898
65974
|
finally {
|
|
@@ -65909,7 +65985,7 @@ class Evaluator {
|
|
|
65909
65985
|
computeFormulaCell(formulaPosition, cellData) {
|
|
65910
65986
|
const formulaReturn = updateEvalContextAndExecute(cellData.compiledFormula, this.compilationParams, formulaPosition.sheetId, this.buildSafeGetSymbolValue(), formulaPosition);
|
|
65911
65987
|
if (!isMatrix(formulaReturn)) {
|
|
65912
|
-
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(formulaReturn), this.getters.getLocale(), cellData);
|
|
65988
|
+
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(formulaReturn), this.getters.getLocale(), cellData, formulaPosition);
|
|
65913
65989
|
if (evaluatedCell.type === CellValueType.error) {
|
|
65914
65990
|
evaluatedCell.errorOriginPosition = formulaReturn.errorOriginPosition ?? formulaPosition;
|
|
65915
65991
|
}
|
|
@@ -65985,7 +66061,7 @@ class Evaluator {
|
|
|
65985
66061
|
const spreadValues = (i, j) => {
|
|
65986
66062
|
const position = { sheetId, col: i + col, row: j + row };
|
|
65987
66063
|
const cell = this.getters.getCell(position);
|
|
65988
|
-
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell);
|
|
66064
|
+
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell, position);
|
|
65989
66065
|
if (evaluatedCell.type === CellValueType.error) {
|
|
65990
66066
|
evaluatedCell.errorOriginPosition = matrixResult[i][j].errorOriginPosition ?? position;
|
|
65991
66067
|
}
|
|
@@ -66658,7 +66734,7 @@ class EvaluationChartPlugin extends CoreViewPlugin {
|
|
|
66658
66734
|
continue;
|
|
66659
66735
|
}
|
|
66660
66736
|
const figureId = figure.id;
|
|
66661
|
-
const figureData = this.getters.getChart(figureId)?.getDefinitionForExcel();
|
|
66737
|
+
const figureData = this.getters.getChart(figureId)?.getDefinitionForExcel(this.getters);
|
|
66662
66738
|
if (figureData) {
|
|
66663
66739
|
figures.push({
|
|
66664
66740
|
...figure,
|
|
@@ -67571,6 +67647,23 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
|
|
|
67571
67647
|
static getters = ["getRowSize", "getHeaderSize", "getMaxAnchorOffset"];
|
|
67572
67648
|
tallestCellInRow = {};
|
|
67573
67649
|
ctx = document.createElement("canvas").getContext("2d");
|
|
67650
|
+
beforeHandle(cmd) {
|
|
67651
|
+
switch (cmd.type) {
|
|
67652
|
+
// Ensure rows are updated before "UPDATE_CELL" is dispatched from cell plugin.
|
|
67653
|
+
// "UPDATE_CELL" uses the Sheet core plugin to access row data.
|
|
67654
|
+
// If "ADD_COLUMNS_ROWS" has not been processed yet by header_sizes_ui,
|
|
67655
|
+
// size updates may apply to incorrect (pre-insert) rows.
|
|
67656
|
+
case "ADD_COLUMNS_ROWS":
|
|
67657
|
+
if (cmd.dimension === "COL") {
|
|
67658
|
+
return;
|
|
67659
|
+
}
|
|
67660
|
+
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
67661
|
+
const newCells = Array(cmd.quantity).fill(undefined);
|
|
67662
|
+
const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
|
|
67663
|
+
this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
|
|
67664
|
+
break;
|
|
67665
|
+
}
|
|
67666
|
+
}
|
|
67574
67667
|
handle(cmd) {
|
|
67575
67668
|
switch (cmd.type) {
|
|
67576
67669
|
case "START":
|
|
@@ -67600,16 +67693,6 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
|
|
|
67600
67693
|
this.history.update("tallestCellInRow", cmd.sheetId, tallestCells);
|
|
67601
67694
|
break;
|
|
67602
67695
|
}
|
|
67603
|
-
case "ADD_COLUMNS_ROWS": {
|
|
67604
|
-
if (cmd.dimension === "COL") {
|
|
67605
|
-
return;
|
|
67606
|
-
}
|
|
67607
|
-
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
67608
|
-
const newCells = Array(cmd.quantity).fill(undefined);
|
|
67609
|
-
const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
|
|
67610
|
-
this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
|
|
67611
|
-
break;
|
|
67612
|
-
}
|
|
67613
67696
|
case "RESIZE_COLUMNS_ROWS":
|
|
67614
67697
|
{
|
|
67615
67698
|
const sheetId = cmd.sheetId;
|
|
@@ -74158,6 +74241,14 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
74158
74241
|
const isBasedBefore = cmd.base < start;
|
|
74159
74242
|
const deltaCol = isBasedBefore && isCol ? thickness : 0;
|
|
74160
74243
|
const deltaRow = isBasedBefore && !isCol ? thickness : 0;
|
|
74244
|
+
const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
|
|
74245
|
+
const originalSize = Object.fromEntries(toRemove.map((element) => {
|
|
74246
|
+
const size = isCol
|
|
74247
|
+
? this.getters.getColSize(cmd.sheetId, element)
|
|
74248
|
+
: this.getters.getUserRowSize(cmd.sheetId, element);
|
|
74249
|
+
const isDefaultCol = isCol && size === DEFAULT_CELL_WIDTH;
|
|
74250
|
+
return [element, isDefaultCol ? undefined : size];
|
|
74251
|
+
}));
|
|
74161
74252
|
const target = [
|
|
74162
74253
|
{
|
|
74163
74254
|
left: isCol ? start + deltaCol : 0,
|
|
@@ -74188,13 +74279,12 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
74188
74279
|
const col = selection.left;
|
|
74189
74280
|
const row = selection.top;
|
|
74190
74281
|
this.setSelectionMixin({ zone: selection, cell: { col, row } }, [selection]);
|
|
74191
|
-
const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
|
|
74192
74282
|
let currentIndex = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
74193
74283
|
const resizingGroups = {};
|
|
74194
74284
|
for (const element of toRemove) {
|
|
74195
|
-
const size =
|
|
74285
|
+
const size = originalSize[element];
|
|
74196
74286
|
const currentSize = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, currentIndex);
|
|
74197
|
-
if (size !== currentSize) {
|
|
74287
|
+
if (size && size !== currentSize) {
|
|
74198
74288
|
resizingGroups[size] ??= [];
|
|
74199
74289
|
resizingGroups[size].push(currentIndex);
|
|
74200
74290
|
currentIndex += 1;
|
|
@@ -75620,6 +75710,7 @@ const coreViewsPluginRegistry = new Registry()
|
|
|
75620
75710
|
|
|
75621
75711
|
autoCompleteProviders.add("dataValidation", {
|
|
75622
75712
|
displayAllOnInitialContent: true,
|
|
75713
|
+
canBeToggled: false,
|
|
75623
75714
|
getProposals(tokenAtCursor, content) {
|
|
75624
75715
|
if (isFormula(content)) {
|
|
75625
75716
|
return [];
|
|
@@ -77185,14 +77276,12 @@ class BottomBarSheet extends Component {
|
|
|
77185
77276
|
this.editionState = "initializing";
|
|
77186
77277
|
}
|
|
77187
77278
|
stopEdition() {
|
|
77188
|
-
|
|
77189
|
-
if (!this.state.isEditing || !input)
|
|
77279
|
+
if (!this.state.isEditing || !this.sheetNameRef.el)
|
|
77190
77280
|
return;
|
|
77191
77281
|
this.state.isEditing = false;
|
|
77192
77282
|
this.editionState = "initializing";
|
|
77193
|
-
|
|
77283
|
+
this.sheetNameRef.el.blur();
|
|
77194
77284
|
const inputValue = this.getInputContent() || "";
|
|
77195
|
-
input.innerText = inputValue;
|
|
77196
77285
|
interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
|
|
77197
77286
|
}
|
|
77198
77287
|
cancelEdition() {
|
|
@@ -81610,6 +81699,9 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81610
81699
|
case "combo":
|
|
81611
81700
|
plot = addComboChart(chart.data);
|
|
81612
81701
|
break;
|
|
81702
|
+
case "pyramid":
|
|
81703
|
+
plot = addPyramidChart(chart.data);
|
|
81704
|
+
break;
|
|
81613
81705
|
case "line":
|
|
81614
81706
|
plot = addLineChart(chart.data);
|
|
81615
81707
|
break;
|
|
@@ -81617,12 +81709,12 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81617
81709
|
plot = addScatterChart(chart.data);
|
|
81618
81710
|
break;
|
|
81619
81711
|
case "pie":
|
|
81620
|
-
plot = addDoughnutChart(chart.data, chartSheetIndex, data
|
|
81712
|
+
plot = addDoughnutChart(chart.data, chartSheetIndex, data);
|
|
81621
81713
|
break;
|
|
81622
81714
|
case "radar":
|
|
81623
81715
|
plot = addRadarChart(chart.data);
|
|
81624
81716
|
}
|
|
81625
|
-
let position = "
|
|
81717
|
+
let position = "none";
|
|
81626
81718
|
switch (chart.data.legendPosition) {
|
|
81627
81719
|
case "bottom":
|
|
81628
81720
|
position = "b";
|
|
@@ -81652,7 +81744,7 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
81652
81744
|
${plot}
|
|
81653
81745
|
${shapeProperty({ backgroundColor: chart.data.backgroundColor })}
|
|
81654
81746
|
</c:plotArea>
|
|
81655
|
-
${addLegend(position, fontColor)}
|
|
81747
|
+
${position !== "none" ? addLegend(position, fontColor) : ""}
|
|
81656
81748
|
</c:chart>
|
|
81657
81749
|
</c:chartSpace>
|
|
81658
81750
|
`;
|
|
@@ -81810,6 +81902,7 @@ function addBarChart(chart) {
|
|
|
81810
81902
|
//
|
|
81811
81903
|
// overlap and gapWitdh seems to be by default at -20 and 20 in chart.js.
|
|
81812
81904
|
// See https://www.chartjs.org/docs/latest/charts/bar.html and https://www.chartjs.org/docs/latest/charts/bar.html#barpercentage-vs-categorypercentage
|
|
81905
|
+
const chartDirection = chart.horizontal ? "bar" : "col";
|
|
81813
81906
|
const dataSetsColors = chart.dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
81814
81907
|
const colors = new ColorGenerator(chart.dataSets.length, dataSetsColors);
|
|
81815
81908
|
const leftDataSetsNodes = [];
|
|
@@ -81846,7 +81939,7 @@ function addBarChart(chart) {
|
|
|
81846
81939
|
${leftDataSetsNodes.length
|
|
81847
81940
|
? escapeXml /*xml*/ `
|
|
81848
81941
|
<c:barChart>
|
|
81849
|
-
<c:barDir val="
|
|
81942
|
+
<c:barDir val="${chartDirection}"/>
|
|
81850
81943
|
<c:grouping val="${grouping}"/>
|
|
81851
81944
|
<c:overlap val="${overlap}"/>
|
|
81852
81945
|
<c:gapWidth val="70"/>
|
|
@@ -81856,8 +81949,12 @@ function addBarChart(chart) {
|
|
|
81856
81949
|
<c:axId val="${catAxId}" />
|
|
81857
81950
|
<c:axId val="${valAxId}" />
|
|
81858
81951
|
</c:barChart>
|
|
81859
|
-
${
|
|
81860
|
-
|
|
81952
|
+
${chartDirection === "col"
|
|
81953
|
+
? addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.x?.title, chart.fontColor)
|
|
81954
|
+
: addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.y?.title, chart.fontColor, undefined, "maxMin")}
|
|
81955
|
+
${chartDirection === "col"
|
|
81956
|
+
? addAx("l", "c:valAx", valAxId, catAxId, chart.axesDesign?.y?.title, chart.fontColor)
|
|
81957
|
+
: addAx("l", "c:valAx", valAxId, catAxId, chart.axesDesign?.x?.title, chart.fontColor, undefined, undefined, "max")}
|
|
81861
81958
|
`
|
|
81862
81959
|
: ""}
|
|
81863
81960
|
${rightDataSetsNodes.length
|
|
@@ -81983,7 +82080,7 @@ function addComboChart(chart) {
|
|
|
81983
82080
|
: ""}
|
|
81984
82081
|
${!useRightAxisForBarSerie || leftDataSetsNodes.length
|
|
81985
82082
|
? escapeXml /*xml*/ `
|
|
81986
|
-
${addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.x?.title, chart.fontColor,
|
|
82083
|
+
${addAx("b", "c:catAx", catAxId, valAxId, chart.axesDesign?.x?.title, chart.fontColor, 0)}
|
|
81987
82084
|
${addAx("l", "c:valAx", valAxId, catAxId, chart.axesDesign?.y?.title, chart.fontColor)}
|
|
81988
82085
|
`
|
|
81989
82086
|
: ""}
|
|
@@ -81995,6 +82092,94 @@ function addComboChart(chart) {
|
|
|
81995
82092
|
: ""}
|
|
81996
82093
|
`;
|
|
81997
82094
|
}
|
|
82095
|
+
function addPyramidChart(chart) {
|
|
82096
|
+
const dataSets = chart.dataSets;
|
|
82097
|
+
const dataSetsColors = dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
82098
|
+
const colors = new ColorGenerator(dataSets.length, dataSetsColors);
|
|
82099
|
+
const leftDataSet = dataSets[0];
|
|
82100
|
+
const rightDataSet = dataSets[1];
|
|
82101
|
+
const firstColor = toXlsxHexColor(colors.next());
|
|
82102
|
+
const secondColor = toXlsxHexColor(colors.next());
|
|
82103
|
+
const { maxValue, majorUnit } = getPyramidChartHorizontalAxisConfig(chart.maxValue);
|
|
82104
|
+
const labelRangeEl = chart.labelRange
|
|
82105
|
+
? escapeXml `<c:cat>${stringRef(chart.labelRange)}</c:cat>`
|
|
82106
|
+
: "";
|
|
82107
|
+
const leftBarDataSetNode = escapeXml /*xml*/ `
|
|
82108
|
+
<c:ser>
|
|
82109
|
+
<c:idx val="0"/>
|
|
82110
|
+
<c:order val="0"/>
|
|
82111
|
+
<c:invertIfNegative val="0" />
|
|
82112
|
+
${extractDataSetLabel(leftDataSet.label)}
|
|
82113
|
+
${shapeProperty({
|
|
82114
|
+
backgroundColor: firstColor,
|
|
82115
|
+
line: { color: firstColor },
|
|
82116
|
+
})}
|
|
82117
|
+
${labelRangeEl}
|
|
82118
|
+
<!-- x-coordinate values -->
|
|
82119
|
+
<c:val>
|
|
82120
|
+
${numberRef(leftDataSet.range)}
|
|
82121
|
+
</c:val>
|
|
82122
|
+
</c:ser>
|
|
82123
|
+
`;
|
|
82124
|
+
const rightBarDataSetNode = escapeXml /*xml*/ `
|
|
82125
|
+
<c:ser>
|
|
82126
|
+
<c:idx val="1"/>
|
|
82127
|
+
<c:order val="1"/>
|
|
82128
|
+
<c:invertIfNegative val="0" />
|
|
82129
|
+
${extractDataSetLabel(rightDataSet.label)}
|
|
82130
|
+
${shapeProperty({
|
|
82131
|
+
backgroundColor: secondColor,
|
|
82132
|
+
line: { color: secondColor },
|
|
82133
|
+
})}
|
|
82134
|
+
${chart.labelRange ? escapeXml /*xml*/ `<c:cat>${stringRef(chart.labelRange)}</c:cat>` : ""}
|
|
82135
|
+
<!-- x-coordinate values -->
|
|
82136
|
+
<c:val>
|
|
82137
|
+
${numberRef(rightDataSet.range)}
|
|
82138
|
+
</c:val>
|
|
82139
|
+
</c:ser>
|
|
82140
|
+
`;
|
|
82141
|
+
return escapeXml /*xml*/ `
|
|
82142
|
+
<c:barChart>
|
|
82143
|
+
<c:barDir val="bar"/>
|
|
82144
|
+
<c:grouping val="clustered"/>
|
|
82145
|
+
<c:varyColors val="0" />
|
|
82146
|
+
${leftBarDataSetNode}
|
|
82147
|
+
<c:gapWidth val="50" />
|
|
82148
|
+
<c:axId val="${catAxId}" />
|
|
82149
|
+
<c:axId val="${valAxId}" />
|
|
82150
|
+
</c:barChart>
|
|
82151
|
+
<c:barChart>
|
|
82152
|
+
<c:barDir val="bar"/>
|
|
82153
|
+
<c:grouping val="clustered"/>
|
|
82154
|
+
<c:varyColors val="0" />
|
|
82155
|
+
${rightBarDataSetNode}
|
|
82156
|
+
<c:gapWidth val="50" />
|
|
82157
|
+
<c:axId val="${secondaryCatAxId}" />
|
|
82158
|
+
<c:axId val="${secondaryValAxId}" />
|
|
82159
|
+
</c:barChart>
|
|
82160
|
+
${addAx("r", "c:catAx", catAxId, valAxId, chart.axesDesign?.y?.title, chart.fontColor, 0, "maxMin", "autoZero", "high")}
|
|
82161
|
+
${addAx("b", "c:valAx", valAxId, catAxId, chart.axesDesign?.x?.title, chart.fontColor, 0, "maxMin", "max", "nextTo", maxValue, majorUnit, "#0;#0")}
|
|
82162
|
+
${addAx("t", "c:valAx", secondaryValAxId, secondaryCatAxId, undefined, chart.fontColor, 1)}
|
|
82163
|
+
${addAx("l", "c:catAx", secondaryCatAxId, secondaryValAxId, undefined, chart.fontColor, 1, "maxMin")}
|
|
82164
|
+
`;
|
|
82165
|
+
}
|
|
82166
|
+
function getPyramidChartHorizontalAxisConfig(maxValue) {
|
|
82167
|
+
const adjustMaxToDivisibleBy = (value, divisor) => {
|
|
82168
|
+
let adjusted = Math.ceil(value);
|
|
82169
|
+
while (adjusted % divisor !== 0) {
|
|
82170
|
+
adjusted++;
|
|
82171
|
+
}
|
|
82172
|
+
return adjusted;
|
|
82173
|
+
};
|
|
82174
|
+
const tickCount = 4;
|
|
82175
|
+
const interval = tickCount - 1;
|
|
82176
|
+
const adjustedMax = adjustMaxToDivisibleBy(maxValue, interval);
|
|
82177
|
+
const majorUnit = adjustedMax / interval;
|
|
82178
|
+
return {
|
|
82179
|
+
maxValue: adjustedMax,
|
|
82180
|
+
majorUnit,
|
|
82181
|
+
};
|
|
82182
|
+
}
|
|
81998
82183
|
function addLineChart(chart) {
|
|
81999
82184
|
const dataSetsColors = chart.dataSets.map((ds) => ds.backgroundColor ?? "");
|
|
82000
82185
|
const colors = new ColorGenerator(chart.dataSets.length, dataSetsColors);
|
|
@@ -82187,7 +82372,7 @@ function addRadarChart(chart) {
|
|
|
82187
82372
|
`}
|
|
82188
82373
|
`;
|
|
82189
82374
|
}
|
|
82190
|
-
function addDoughnutChart(chart, chartSheetIndex, data
|
|
82375
|
+
function addDoughnutChart(chart, chartSheetIndex, data) {
|
|
82191
82376
|
const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
|
|
82192
82377
|
const colors = new ColorGenerator(maxLength);
|
|
82193
82378
|
const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
|
|
@@ -82225,7 +82410,7 @@ function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSiz
|
|
|
82225
82410
|
return escapeXml /*xml*/ `
|
|
82226
82411
|
<c:doughnutChart>
|
|
82227
82412
|
<c:varyColors val="1" />
|
|
82228
|
-
<c:holeSize val="${
|
|
82413
|
+
<c:holeSize val="${chart.pieHolePercentage ?? (chart.isDoughnut ? DEFAULT_DOUGHNUT_CHART_HOLE_SIZE : 0)}" />
|
|
82229
82414
|
${insertDataLabels()}
|
|
82230
82415
|
${joinXmlNodes(dataSetsNodes)}
|
|
82231
82416
|
</c:doughnutChart>
|
|
@@ -82244,25 +82429,35 @@ function insertDataLabels({ showLeaderLines } = { showLeaderLines: false }) {
|
|
|
82244
82429
|
</dLbls>
|
|
82245
82430
|
`;
|
|
82246
82431
|
}
|
|
82247
|
-
function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, deleteAxis = 0) {
|
|
82432
|
+
function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, deleteAxis = 0, orientation = "minMax", crossPosition, tickLabelPosition = "nextTo", maxValue, majorUnit, format = "General") {
|
|
82248
82433
|
// Each Axis present inside a graph needs to be identified by an unsigned integer in order to be referenced by its crossAxis.
|
|
82249
82434
|
// I.e. x-axis, will reference y-axis and vice-versa.
|
|
82250
82435
|
const color = title?.color ? toXlsxHexColor(title.color) : defaultFontColor;
|
|
82251
82436
|
const fontSize = title?.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE;
|
|
82437
|
+
const crossBetweenEl = axisName === "c:valAx" ? escapeXml `<c:crossBetween val="between" />` : "";
|
|
82438
|
+
const maxValueEl = maxValue ? escapeXml `<c:max val="${maxValue}" />` : "";
|
|
82439
|
+
const minValueEl = maxValue ? escapeXml `<c:min val="${-maxValue}" />` : "";
|
|
82440
|
+
const majorUnitEl = majorUnit ? escapeXml `<c:majorUnit val="${majorUnit}" />` : "";
|
|
82252
82441
|
return escapeXml /*xml*/ `
|
|
82253
82442
|
<${axisName}>
|
|
82254
82443
|
<c:axId val="${axId}"/>
|
|
82255
82444
|
<c:crossAx val="${crossAxId}"/> <!-- reference to the other axe of the chart -->
|
|
82256
|
-
<c:crosses val="${position === "b" || position === "l" ? "min" : "max"}"/>
|
|
82445
|
+
<c:crosses val="${crossPosition || (position === "b" || position === "l" ? "min" : "max")}"/>
|
|
82446
|
+
<c:auto val="1"/>
|
|
82447
|
+
${crossBetweenEl}
|
|
82257
82448
|
<c:delete val="${deleteAxis}"/> <!-- by default, axis are not displayed -->
|
|
82258
82449
|
<c:scaling>
|
|
82259
|
-
<c:orientation val="
|
|
82450
|
+
<c:orientation val="${orientation}" />
|
|
82451
|
+
${maxValueEl}
|
|
82452
|
+
${minValueEl}
|
|
82260
82453
|
</c:scaling>
|
|
82454
|
+
${majorUnitEl}
|
|
82261
82455
|
<c:axPos val="${position}" />
|
|
82456
|
+
<c:tickLblPos val="${tickLabelPosition}" />
|
|
82262
82457
|
${insertMajorGridLines()}
|
|
82263
82458
|
<c:majorTickMark val="out" />
|
|
82264
82459
|
<c:minorTickMark val="none" />
|
|
82265
|
-
<c:numFmt formatCode="
|
|
82460
|
+
<c:numFmt formatCode="${format}" sourceLinked="${format === "General" ? "1" : "0"}" />
|
|
82266
82461
|
<c:title>
|
|
82267
82462
|
${insertText(title?.text ?? "", color, fontSize, title)}
|
|
82268
82463
|
</c:title>
|
|
@@ -82457,7 +82652,10 @@ function addConditionalFormatting(dxfs, conditionalFormats) {
|
|
|
82457
82652
|
function addCellIsRule(cf, rule, dxfs) {
|
|
82458
82653
|
const ruleAttributes = commonCfAttributes(cf);
|
|
82459
82654
|
const operator = convertOperator(rule.operator);
|
|
82460
|
-
ruleAttributes.push(...cellRuleTypeAttributes(rule)
|
|
82655
|
+
ruleAttributes.push(...cellRuleTypeAttributes(rule));
|
|
82656
|
+
if (operator.length) {
|
|
82657
|
+
ruleAttributes.push(["operator", operator]);
|
|
82658
|
+
}
|
|
82461
82659
|
const formulas = cellRuleFormula(cf.ranges, rule).map((formula) => escapeXml /*xml*/ `<formula>${formula}</formula>`);
|
|
82462
82660
|
const dxf = {
|
|
82463
82661
|
font: {
|
|
@@ -82503,6 +82701,8 @@ function cellRuleFormula(ranges, rule) {
|
|
|
82503
82701
|
case "isLessThan":
|
|
82504
82702
|
case "isLessOrEqualTo":
|
|
82505
82703
|
return [values[0]];
|
|
82704
|
+
case "customFormula":
|
|
82705
|
+
return values[0].startsWith("=") ? [values[0].slice(1)] : [values[0]];
|
|
82506
82706
|
case "isBetween":
|
|
82507
82707
|
case "isNotBetween":
|
|
82508
82708
|
return [values[0], values[1]];
|
|
@@ -82531,6 +82731,8 @@ function cellRuleTypeAttributes(rule) {
|
|
|
82531
82731
|
case "isBetween":
|
|
82532
82732
|
case "isNotBetween":
|
|
82533
82733
|
return [["type", "cellIs"]];
|
|
82734
|
+
case "customFormula":
|
|
82735
|
+
return [["type", "expression"]];
|
|
82534
82736
|
}
|
|
82535
82737
|
}
|
|
82536
82738
|
function addDataBarRule(cf, rule) {
|
|
@@ -84583,6 +84785,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
84583
84785
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
84584
84786
|
|
|
84585
84787
|
|
|
84586
|
-
__info__.version = "18.5.0-alpha.
|
|
84587
|
-
__info__.date = "2025-07-
|
|
84588
|
-
__info__.hash = "
|
|
84788
|
+
__info__.version = "18.5.0-alpha.3";
|
|
84789
|
+
__info__.date = "2025-07-28T13:43:05.981Z";
|
|
84790
|
+
__info__.hash = "53dfee8";
|