@odoo/o-spreadsheet 19.4.10 → 19.4.12

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.
@@ -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 19.4.10
6
- * @date 2026-08-29T09:17:27.429Z
7
- * @hash d7a0f18
5
+ * @version 19.4.12
6
+ * @date 2026-09-10T05:38:01.898Z
7
+ * @hash cdb63b4
8
8
  */
9
9
 
10
10
  (function(exports, _odoo_owl) {
@@ -447,6 +447,7 @@ _odoo_owl = __toESM(_odoo_owl, 1);
447
447
  const COMPOSER_ASSISTANT_COLOR = "light-dark(#9B359B, #B972A6)";
448
448
  const COLOR_TRANSPARENT = "#00000000";
449
449
  const TABLE_HOVER_BACKGROUND_COLOR = "#017E8414";
450
+ const DEFAULT_CHART_BACKGROUND_COLOR = "#FFFFFF";
450
451
  const CHART_WATERFALL_POSITIVE_COLOR = "#4EA7F2";
451
452
  const CHART_WATERFALL_NEGATIVE_COLOR = "#EA6175";
452
453
  const CHART_WATERFALL_SUBTOTAL_COLOR = "#AAAAAA";
@@ -7853,7 +7854,8 @@ set(value) {
7853
7854
  "UPDATE_TABLE",
7854
7855
  "UPDATE_FILTER",
7855
7856
  "UNDO",
7856
- "REDO"
7857
+ "REDO",
7858
+ "UPDATE_COLOR_SCHEME"
7857
7859
  ]);
7858
7860
  const invalidateDependenciesCommands = /* @__PURE__ */ new Set(["MOVE_RANGES"]);
7859
7861
  const invalidateCFEvaluationCommands = /* @__PURE__ */ new Set([
@@ -8994,6 +8996,259 @@ set(value) {
8994
8996
  }
8995
8997
  };
8996
8998
 
8999
+ //#endregion
9000
+ //#region src/xlsx/constants.ts
9001
+ /** In XLSX color format (no #) */
9002
+ const AUTO_COLOR = "000000";
9003
+ const XLSX_ICONSET_MAP = {
9004
+ arrows: "3Arrows",
9005
+ smiley: "3Symbols",
9006
+ dots: "3TrafficLights1"
9007
+ };
9008
+ const NAMESPACE = {
9009
+ styleSheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
9010
+ sst: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
9011
+ Relationships: "http://schemas.openxmlformats.org/package/2006/relationships",
9012
+ Types: "http://schemas.openxmlformats.org/package/2006/content-types",
9013
+ worksheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
9014
+ workbook: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
9015
+ drawing: "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
9016
+ table: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
9017
+ revision: "http://schemas.microsoft.com/office/spreadsheetml/2014/revision",
9018
+ revision3: "http://schemas.microsoft.com/office/spreadsheetml/2016/revision3",
9019
+ markupCompatibility: "http://schemas.openxmlformats.org/markup-compatibility/2006"
9020
+ };
9021
+ const DRAWING_NS_A = "http://schemas.openxmlformats.org/drawingml/2006/main";
9022
+ const DRAWING_NS_C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
9023
+ const CONTENT_TYPES = {
9024
+ workbook: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
9025
+ macroEnabledWorkbook: "application/vnd.ms-excel.sheet.macroEnabled.main+xml",
9026
+ templateWorkbook: "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml",
9027
+ macroEnabledTemplateWorkbook: "application/vnd.ms-excel.template.macroEnabled.main+xml",
9028
+ excelAddInWorkbook: "application/vnd.ms-excel.addin.macroEnabled.main+xml",
9029
+ sheet: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
9030
+ metadata: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
9031
+ sharedStrings: "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
9032
+ styles: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
9033
+ drawing: "application/vnd.openxmlformats-officedocument.drawing+xml",
9034
+ chart: "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
9035
+ themes: "application/vnd.openxmlformats-officedocument.theme+xml",
9036
+ table: "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml",
9037
+ pivot: "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml",
9038
+ externalLink: "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml"
9039
+ };
9040
+ const XLSX_RELATION_TYPE = {
9041
+ document: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
9042
+ sheet: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
9043
+ metadata: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata",
9044
+ sharedStrings: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings",
9045
+ styles: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
9046
+ drawing: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
9047
+ chart: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
9048
+ theme: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
9049
+ table: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table",
9050
+ hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
9051
+ image: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
9052
+ };
9053
+ const ARRAY_FORMULA_URI = "bdbb8cdc-fa1e-496e-a857-3c3f30c029c3";
9054
+ const RELATIONSHIP_NSR = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
9055
+ const HEIGHT_FACTOR = .75;
9056
+ /**
9057
+ * Excel says its default column width is 8.43 characters (64px)
9058
+ * which makes WIDTH_FACTOR = 0.1317, but it doesn't work well
9059
+ * 0.143 is a value from dev's experiments.
9060
+ */
9061
+ const WIDTH_FACTOR = .143;
9062
+ /** unit : maximum number of characters a column can hold at the standard font size. What. */
9063
+ const EXCEL_DEFAULT_COL_WIDTH = 8.43;
9064
+ /** unit : points */
9065
+ const EXCEL_DEFAULT_ROW_HEIGHT = 12.75;
9066
+ const FORCE_DEFAULT_ARGS_FUNCTIONS = {
9067
+ FLOOR: [{
9068
+ type: "NUMBER",
9069
+ value: 1
9070
+ }],
9071
+ CEILING: [{
9072
+ type: "NUMBER",
9073
+ value: 1
9074
+ }],
9075
+ ROUND: [{
9076
+ type: "NUMBER",
9077
+ value: 0
9078
+ }],
9079
+ ROUNDUP: [{
9080
+ type: "NUMBER",
9081
+ value: 0
9082
+ }],
9083
+ ROUNDDOWN: [{
9084
+ type: "NUMBER",
9085
+ value: 0
9086
+ }],
9087
+ IFERROR: [{
9088
+ type: "NUMBER",
9089
+ value: 0
9090
+ }]
9091
+ };
9092
+ /**
9093
+ * This list contains all "future" functions that are not compatible with older versions of Excel
9094
+ * For more information, see https://docs.microsoft.com/en-us/openspecs/office_standards/ms-xlsx/5d1b6d44-6fc1-4ecd-8fef-0b27406cc2bf
9095
+ */
9096
+ const NON_RETROCOMPATIBLE_FUNCTIONS = [
9097
+ "ACOT",
9098
+ "ACOTH",
9099
+ "AGGREGATE",
9100
+ "ARABIC",
9101
+ "BASE",
9102
+ "BETA.DIST",
9103
+ "BETA.INV",
9104
+ "BINOM.DIST",
9105
+ "BINOM.DIST.RANGE",
9106
+ "BINOM.INV",
9107
+ "BITAND",
9108
+ "BITLSHIFT",
9109
+ "BITOR",
9110
+ "BITRSHIFT",
9111
+ "BITXOR",
9112
+ "BYCOL",
9113
+ "BYROW",
9114
+ "CEILING.MATH",
9115
+ "CEILING.PRECISE",
9116
+ "CHISQ.DIST",
9117
+ "CHISQ.DIST.RT",
9118
+ "CHISQ.INV",
9119
+ "CHISQ.INV.RT",
9120
+ "CHISQ.TEST",
9121
+ "CHOOSECOLS",
9122
+ "CHOOSEROWS",
9123
+ "COMBINA",
9124
+ "CONCAT",
9125
+ "CONFIDENCE.NORM",
9126
+ "CONFIDENCE.T",
9127
+ "COT",
9128
+ "COTH",
9129
+ "COVARIANCE.P",
9130
+ "COVARIANCE.S",
9131
+ "CSC",
9132
+ "CSCH",
9133
+ "DAYS",
9134
+ "DECIMAL",
9135
+ "DROP",
9136
+ "ERF.PRECISE",
9137
+ "ERFC.PRECISE",
9138
+ "EXPAND",
9139
+ "EXPON.DIST",
9140
+ "F.DIST",
9141
+ "F.DIST.RT",
9142
+ "F.INV",
9143
+ "F.INV.RT",
9144
+ "F.TEST",
9145
+ "FIELDVALUE",
9146
+ "FILTERXML",
9147
+ "FLOOR.MATH",
9148
+ "FLOOR.PRECISE",
9149
+ "FORECAST.ETS",
9150
+ "FORECAST.ETS.CONFINT",
9151
+ "FORECAST.ETS.SEASONALITY",
9152
+ "FORECAST.ETS.STAT",
9153
+ "FORECAST.LINEAR",
9154
+ "FORMULATEXT",
9155
+ "GAMMA",
9156
+ "GAMMA.DIST",
9157
+ "GAMMA.INV",
9158
+ "GAMMALN.PRECISE",
9159
+ "GAUSS",
9160
+ "HSTACK",
9161
+ "HYPGEOM.DIST",
9162
+ "IFNA",
9163
+ "IFS",
9164
+ "IMCOSH",
9165
+ "IMCOT",
9166
+ "IMCSC",
9167
+ "IMCSCH",
9168
+ "IMSEC",
9169
+ "IMSECH",
9170
+ "IMSINH",
9171
+ "IMTAN",
9172
+ "ISFORMULA",
9173
+ "ISOMITTED",
9174
+ "ISOWEEKNUM",
9175
+ "LAMBDA",
9176
+ "LET",
9177
+ "LOGNORM.DIST",
9178
+ "LOGNORM.INV",
9179
+ "MAKEARRAY",
9180
+ "MAP",
9181
+ "MAXIFS",
9182
+ "MINIFS",
9183
+ "MODE.MULT",
9184
+ "MODE.SNGL",
9185
+ "MUNIT",
9186
+ "NEGBINOM.DIST",
9187
+ "NORM.DIST",
9188
+ "NORM.INV",
9189
+ "NORM.S.DIST",
9190
+ "NORM.S.INV",
9191
+ "NUMBERVALUE",
9192
+ "PDURATION",
9193
+ "PERCENTILE.EXC",
9194
+ "PERCENTILE.INC",
9195
+ "PERCENTRANK.EXC",
9196
+ "PERCENTRANK.INC",
9197
+ "PERMUTATIONA",
9198
+ "PHI",
9199
+ "POISSON.DIST",
9200
+ "PQSOURCE",
9201
+ "PYTHON_STR",
9202
+ "PYTHON_TYPE",
9203
+ "PYTHON_TYPENAME",
9204
+ "QUARTILE.EXC",
9205
+ "QUARTILE.INC",
9206
+ "QUERYSTRING",
9207
+ "RANDARRAY",
9208
+ "RANK.AVG",
9209
+ "RANK.EQ",
9210
+ "REDUCE",
9211
+ "RRI",
9212
+ "SCAN",
9213
+ "SEC",
9214
+ "SECH",
9215
+ "SEQUENCE",
9216
+ "SHEET",
9217
+ "SHEETS",
9218
+ "SKEW.P",
9219
+ "SORTBY",
9220
+ "STDEV.P",
9221
+ "STDEV.S",
9222
+ "SWITCH",
9223
+ "T.DIST",
9224
+ "T.DIST.2T",
9225
+ "T.DIST.RT",
9226
+ "T.INV",
9227
+ "T.INV.2T",
9228
+ "T.TEST",
9229
+ "TAKE",
9230
+ "TEXTAFTER",
9231
+ "TEXTBEFORE",
9232
+ "TEXTJOIN",
9233
+ "TEXTSPLIT",
9234
+ "TOCOL",
9235
+ "TOROW",
9236
+ "UNICHAR",
9237
+ "UNICODE",
9238
+ "UNIQUE",
9239
+ "VAR.P",
9240
+ "VAR.S",
9241
+ "VSTACK",
9242
+ "WEBSERVICE",
9243
+ "WEIBULL.DIST",
9244
+ "WRAPCOLS",
9245
+ "WRAPROWS",
9246
+ "XLOOKUP",
9247
+ "XOR",
9248
+ "Z.TEST"
9249
+ ];
9250
+ const CONTENT_TYPES_FILE = "[Content_Types].xml";
9251
+
8997
9252
  //#endregion
8998
9253
  //#region src/helpers/color.ts
8999
9254
  const RBA_REGEX = /rgba?\(|\s+|\)/gi;
@@ -9695,259 +9950,6 @@ set(value) {
9695
9950
  return r << 16 | g << 8 | b;
9696
9951
  }
9697
9952
 
9698
- //#endregion
9699
- //#region src/xlsx/constants.ts
9700
- /** In XLSX color format (no #) */
9701
- const AUTO_COLOR = "000000";
9702
- const XLSX_ICONSET_MAP = {
9703
- arrows: "3Arrows",
9704
- smiley: "3Symbols",
9705
- dots: "3TrafficLights1"
9706
- };
9707
- const NAMESPACE = {
9708
- styleSheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
9709
- sst: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
9710
- Relationships: "http://schemas.openxmlformats.org/package/2006/relationships",
9711
- Types: "http://schemas.openxmlformats.org/package/2006/content-types",
9712
- worksheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
9713
- workbook: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
9714
- drawing: "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
9715
- table: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
9716
- revision: "http://schemas.microsoft.com/office/spreadsheetml/2014/revision",
9717
- revision3: "http://schemas.microsoft.com/office/spreadsheetml/2016/revision3",
9718
- markupCompatibility: "http://schemas.openxmlformats.org/markup-compatibility/2006"
9719
- };
9720
- const DRAWING_NS_A = "http://schemas.openxmlformats.org/drawingml/2006/main";
9721
- const DRAWING_NS_C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
9722
- const CONTENT_TYPES = {
9723
- workbook: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
9724
- macroEnabledWorkbook: "application/vnd.ms-excel.sheet.macroEnabled.main+xml",
9725
- templateWorkbook: "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml",
9726
- macroEnabledTemplateWorkbook: "application/vnd.ms-excel.template.macroEnabled.main+xml",
9727
- excelAddInWorkbook: "application/vnd.ms-excel.addin.macroEnabled.main+xml",
9728
- sheet: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
9729
- metadata: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
9730
- sharedStrings: "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
9731
- styles: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
9732
- drawing: "application/vnd.openxmlformats-officedocument.drawing+xml",
9733
- chart: "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
9734
- themes: "application/vnd.openxmlformats-officedocument.theme+xml",
9735
- table: "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml",
9736
- pivot: "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml",
9737
- externalLink: "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml"
9738
- };
9739
- const XLSX_RELATION_TYPE = {
9740
- document: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
9741
- sheet: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
9742
- metadata: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata",
9743
- sharedStrings: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings",
9744
- styles: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
9745
- drawing: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
9746
- chart: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
9747
- theme: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
9748
- table: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table",
9749
- hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
9750
- image: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
9751
- };
9752
- const ARRAY_FORMULA_URI = "bdbb8cdc-fa1e-496e-a857-3c3f30c029c3";
9753
- const RELATIONSHIP_NSR = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
9754
- const HEIGHT_FACTOR = .75;
9755
- /**
9756
- * Excel says its default column width is 8.43 characters (64px)
9757
- * which makes WIDTH_FACTOR = 0.1317, but it doesn't work well
9758
- * 0.143 is a value from dev's experiments.
9759
- */
9760
- const WIDTH_FACTOR = .143;
9761
- /** unit : maximum number of characters a column can hold at the standard font size. What. */
9762
- const EXCEL_DEFAULT_COL_WIDTH = 8.43;
9763
- /** unit : points */
9764
- const EXCEL_DEFAULT_ROW_HEIGHT = 12.75;
9765
- const FORCE_DEFAULT_ARGS_FUNCTIONS = {
9766
- FLOOR: [{
9767
- type: "NUMBER",
9768
- value: 1
9769
- }],
9770
- CEILING: [{
9771
- type: "NUMBER",
9772
- value: 1
9773
- }],
9774
- ROUND: [{
9775
- type: "NUMBER",
9776
- value: 0
9777
- }],
9778
- ROUNDUP: [{
9779
- type: "NUMBER",
9780
- value: 0
9781
- }],
9782
- ROUNDDOWN: [{
9783
- type: "NUMBER",
9784
- value: 0
9785
- }],
9786
- IFERROR: [{
9787
- type: "NUMBER",
9788
- value: 0
9789
- }]
9790
- };
9791
- /**
9792
- * This list contains all "future" functions that are not compatible with older versions of Excel
9793
- * For more information, see https://docs.microsoft.com/en-us/openspecs/office_standards/ms-xlsx/5d1b6d44-6fc1-4ecd-8fef-0b27406cc2bf
9794
- */
9795
- const NON_RETROCOMPATIBLE_FUNCTIONS = [
9796
- "ACOT",
9797
- "ACOTH",
9798
- "AGGREGATE",
9799
- "ARABIC",
9800
- "BASE",
9801
- "BETA.DIST",
9802
- "BETA.INV",
9803
- "BINOM.DIST",
9804
- "BINOM.DIST.RANGE",
9805
- "BINOM.INV",
9806
- "BITAND",
9807
- "BITLSHIFT",
9808
- "BITOR",
9809
- "BITRSHIFT",
9810
- "BITXOR",
9811
- "BYCOL",
9812
- "BYROW",
9813
- "CEILING.MATH",
9814
- "CEILING.PRECISE",
9815
- "CHISQ.DIST",
9816
- "CHISQ.DIST.RT",
9817
- "CHISQ.INV",
9818
- "CHISQ.INV.RT",
9819
- "CHISQ.TEST",
9820
- "CHOOSECOLS",
9821
- "CHOOSEROWS",
9822
- "COMBINA",
9823
- "CONCAT",
9824
- "CONFIDENCE.NORM",
9825
- "CONFIDENCE.T",
9826
- "COT",
9827
- "COTH",
9828
- "COVARIANCE.P",
9829
- "COVARIANCE.S",
9830
- "CSC",
9831
- "CSCH",
9832
- "DAYS",
9833
- "DECIMAL",
9834
- "DROP",
9835
- "ERF.PRECISE",
9836
- "ERFC.PRECISE",
9837
- "EXPAND",
9838
- "EXPON.DIST",
9839
- "F.DIST",
9840
- "F.DIST.RT",
9841
- "F.INV",
9842
- "F.INV.RT",
9843
- "F.TEST",
9844
- "FIELDVALUE",
9845
- "FILTERXML",
9846
- "FLOOR.MATH",
9847
- "FLOOR.PRECISE",
9848
- "FORECAST.ETS",
9849
- "FORECAST.ETS.CONFINT",
9850
- "FORECAST.ETS.SEASONALITY",
9851
- "FORECAST.ETS.STAT",
9852
- "FORECAST.LINEAR",
9853
- "FORMULATEXT",
9854
- "GAMMA",
9855
- "GAMMA.DIST",
9856
- "GAMMA.INV",
9857
- "GAMMALN.PRECISE",
9858
- "GAUSS",
9859
- "HSTACK",
9860
- "HYPGEOM.DIST",
9861
- "IFNA",
9862
- "IFS",
9863
- "IMCOSH",
9864
- "IMCOT",
9865
- "IMCSC",
9866
- "IMCSCH",
9867
- "IMSEC",
9868
- "IMSECH",
9869
- "IMSINH",
9870
- "IMTAN",
9871
- "ISFORMULA",
9872
- "ISOMITTED",
9873
- "ISOWEEKNUM",
9874
- "LAMBDA",
9875
- "LET",
9876
- "LOGNORM.DIST",
9877
- "LOGNORM.INV",
9878
- "MAKEARRAY",
9879
- "MAP",
9880
- "MAXIFS",
9881
- "MINIFS",
9882
- "MODE.MULT",
9883
- "MODE.SNGL",
9884
- "MUNIT",
9885
- "NEGBINOM.DIST",
9886
- "NORM.DIST",
9887
- "NORM.INV",
9888
- "NORM.S.DIST",
9889
- "NORM.S.INV",
9890
- "NUMBERVALUE",
9891
- "PDURATION",
9892
- "PERCENTILE.EXC",
9893
- "PERCENTILE.INC",
9894
- "PERCENTRANK.EXC",
9895
- "PERCENTRANK.INC",
9896
- "PERMUTATIONA",
9897
- "PHI",
9898
- "POISSON.DIST",
9899
- "PQSOURCE",
9900
- "PYTHON_STR",
9901
- "PYTHON_TYPE",
9902
- "PYTHON_TYPENAME",
9903
- "QUARTILE.EXC",
9904
- "QUARTILE.INC",
9905
- "QUERYSTRING",
9906
- "RANDARRAY",
9907
- "RANK.AVG",
9908
- "RANK.EQ",
9909
- "REDUCE",
9910
- "RRI",
9911
- "SCAN",
9912
- "SEC",
9913
- "SECH",
9914
- "SEQUENCE",
9915
- "SHEET",
9916
- "SHEETS",
9917
- "SKEW.P",
9918
- "SORTBY",
9919
- "STDEV.P",
9920
- "STDEV.S",
9921
- "SWITCH",
9922
- "T.DIST",
9923
- "T.DIST.2T",
9924
- "T.DIST.RT",
9925
- "T.INV",
9926
- "T.INV.2T",
9927
- "T.TEST",
9928
- "TAKE",
9929
- "TEXTAFTER",
9930
- "TEXTBEFORE",
9931
- "TEXTJOIN",
9932
- "TEXTSPLIT",
9933
- "TOCOL",
9934
- "TOROW",
9935
- "UNICHAR",
9936
- "UNICODE",
9937
- "UNIQUE",
9938
- "VAR.P",
9939
- "VAR.S",
9940
- "VSTACK",
9941
- "WEBSERVICE",
9942
- "WEIBULL.DIST",
9943
- "WRAPCOLS",
9944
- "WRAPROWS",
9945
- "XLOOKUP",
9946
- "XOR",
9947
- "Z.TEST"
9948
- ];
9949
- const CONTENT_TYPES_FILE = "[Content_Types].xml";
9950
-
9951
9953
  //#endregion
9952
9954
  //#region src/helpers/figures/charts/chart_common.ts
9953
9955
  const TREND_LINE_XAXIS_ID = "x1";
@@ -10213,10 +10215,10 @@ set(value) {
10213
10215
  drawLineOrBarOrRadarChartValues(chart, options, ctx);
10214
10216
  break;
10215
10217
  case "bar":
10216
- options.horizontal ? drawHorizontalBarChartValues(chart, options, ctx) : drawLineOrBarOrRadarChartValues(chart, options, ctx);
10218
+ options.horizontal ? drawHorizontalBarChartValues(chart, options, ctx, { offsetFromAxisOrigin: true }) : drawLineOrBarOrRadarChartValues(chart, options, ctx);
10217
10219
  break;
10218
10220
  case "pyramid":
10219
- drawHorizontalBarChartValues(chart, options, ctx);
10221
+ drawHorizontalBarChartValues(chart, options, ctx, { offsetFromAxisOrigin: true });
10220
10222
  break;
10221
10223
  case "calendar":
10222
10224
  drawBarChartValues(chart, options, ctx);
@@ -10225,7 +10227,7 @@ set(value) {
10225
10227
  drawBubbleChartValues(chart, options, ctx);
10226
10228
  break;
10227
10229
  case "funnel":
10228
- drawHorizontalBarChartValues(chart, options, ctx);
10230
+ drawHorizontalBarChartValues(chart, options, ctx, { offsetFromAxisOrigin: false });
10229
10231
  break;
10230
10232
  }
10231
10233
  ctx.restore();
@@ -10249,7 +10251,7 @@ set(value) {
10249
10251
  const point = dataset.data[i];
10250
10252
  const xPosition = point.x;
10251
10253
  let yPosition = 0;
10252
- if (chart.config.type === "line" || chart.config.type === "radar") yPosition = value < 0 ? point.y + 10 : point.y - 10;
10254
+ if (dataset.type === "line" || dataset.type === "radar") yPosition = value < 0 ? point.y + 10 : point.y - 10;
10253
10255
  else if (chart.config.type === "bubble") yPosition = point.y;
10254
10256
  else {
10255
10257
  const yZeroLine = yAxisScale.getPixelForValue(0);
@@ -10300,23 +10302,33 @@ set(value) {
10300
10302
  const yMax = chart.chartArea.bottom;
10301
10303
  const yMin = chart.chartArea.top;
10302
10304
  const textsPositions = {};
10305
+ const canDrawTextInsideBubble = (chartElement, textSize) => {
10306
+ const radius = chartElement.options.radius ?? globalThis.Chart?.defaults.elements.point.radius ?? 3;
10307
+ return textSize.height < radius * 2;
10308
+ };
10303
10309
  for (const dataset of chart._metasets) for (let i = 0; i < dataset._parsed.length; i++) {
10304
10310
  const value = dataset._parsed[i].y;
10305
10311
  if (isNaN(value)) continue;
10312
+ const valueToDisplay = options.callback(Number(value), dataset, i);
10306
10313
  const point = dataset.data[i];
10307
10314
  const xPosition = point.x;
10308
10315
  let yPosition = Math.max(Math.min(point.y, yMax), yMin);
10316
+ const textSize = getTextDimensions(valueToDisplay, ctx);
10317
+ if (!canDrawTextInsideBubble(point, textSize)) yPosition = value < 0 ? point.y + 10 : point.y - 10;
10309
10318
  if (!textsPositions[xPosition]) textsPositions[xPosition] = [];
10310
10319
  for (const otherPosition of textsPositions[xPosition] || []) if (Math.abs(otherPosition - yPosition) < MINIMAL_VERTICAL_DISTANCE) yPosition = otherPosition + MINIMAL_VERTICAL_DISTANCE * (value < 0 ? 1 : -1);
10311
10320
  textsPositions[xPosition].push(yPosition);
10312
- const color = point.options.backgroundColor ?? "#ffffff";
10313
- if (hexToHSLA(toHex(color)).a === 1) ctx.fillStyle = chartFontColor(color);
10314
- else ctx.fillStyle = "#000000";
10315
- const valueToDisplay = options.callback(Number(value), dataset, i);
10316
- ctx.fillText(valueToDisplay, xPosition, yPosition);
10321
+ if (canDrawTextInsideBubble(point, textSize)) {
10322
+ ctx.strokeStyle = point.options.backgroundColor;
10323
+ ctx.fillStyle = options.background(Number(value), dataset, i) || "#ffffff";
10324
+ } else {
10325
+ ctx.strokeStyle = options.background(Number(value), dataset, i) || "#ffffff";
10326
+ ctx.fillStyle = point.options.backgroundColor;
10327
+ }
10328
+ drawTextWithBackground(valueToDisplay, xPosition, yPosition, ctx);
10317
10329
  }
10318
10330
  }
10319
- function drawHorizontalBarChartValues(chart, options, ctx) {
10331
+ function drawHorizontalBarChartValues(chart, options, ctx, args) {
10320
10332
  const textsPositions = {};
10321
10333
  for (const dataset of chart._metasets) {
10322
10334
  if (isTrendLineAxis(dataset.xAxisID) || isLineOverlayOnBarChart(options, dataset)) continue;
@@ -10331,7 +10343,7 @@ set(value) {
10331
10343
  const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
10332
10344
  const PADDING = 3;
10333
10345
  let xPosition;
10334
- if (distanceFromAxisOrigin < textWidth) xPosition = value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
10346
+ if (args.offsetFromAxisOrigin && distanceFromAxisOrigin < textWidth) xPosition = value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
10335
10347
  else xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
10336
10348
  if (!textsPositions[yPosition]) textsPositions[yPosition] = [];
10337
10349
  for (const otherPosition of textsPositions[yPosition]) if (Math.abs(otherPosition - xPosition) < textWidth) xPosition = value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
@@ -10366,6 +10378,9 @@ set(value) {
10366
10378
  drawTextWithBackground(displayValue, x, y, ctx);
10367
10379
  }
10368
10380
  }
10381
+ function getTextDimensions(text, ctx) {
10382
+ return computeCachedTextDimension(ctx, text, computeTextFont({ fontSize: globalThis.Chart?.defaults.font.size ?? 12 }, "px"));
10383
+ }
10369
10384
 
10370
10385
  //#endregion
10371
10386
  //#region src/types/chart/tree_map_chart.ts
@@ -15839,7 +15854,7 @@ set(value) {
15839
15854
  ["MoreThanOneRangeSelected"]: _t("Please select only one range of cells"),
15840
15855
  ["EmptySelectedRange"]: _t("Please select a range of cells containing values."),
15841
15856
  ["NoColumnsProvided"]: _t("Please select at latest one column to analyze."),
15842
- ["WillRemoveExistingMerge"]: _t("This operation is not possible due to a merge. Please remove the merges first than try again.")
15857
+ ["WillRemoveExistingMerge"]: _t("Cannot perform this action on merged cells. Unmerge the cells and try again.")
15843
15858
  } };
15844
15859
  const DVTerms = {
15845
15860
  DateIs: {
@@ -30171,433 +30186,6 @@ set(value) {
30171
30186
  }
30172
30187
  };
30173
30188
 
30174
- //#endregion
30175
- //#region src/helpers/figures/chart.ts
30176
- var SpreadsheetChart = class SpreadsheetChart {
30177
- getters;
30178
- sheetId;
30179
- definition;
30180
- chartTypeBuilder;
30181
- dataSourceBuilder;
30182
- dataSource;
30183
- constructor(getters, sheetId, definition, chartTypeBuilder, dataSourceBuilder) {
30184
- this.getters = getters;
30185
- this.sheetId = sheetId;
30186
- this.definition = definition;
30187
- this.chartTypeBuilder = chartTypeBuilder;
30188
- this.dataSourceBuilder = dataSourceBuilder;
30189
- this.dataSource = definition.dataSource;
30190
- }
30191
- static fromStrDefinition(getters, sheetId, definition) {
30192
- const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
30193
- const chartTypeBuilder = chartTypeRegistry.get(definition.type);
30194
- const dataSource = dataSourceBuilder.fromExternalDefinition(definition.dataSource ?? { type: "none" }, sheetId, getters);
30195
- const rangeDefinition = {
30196
- ...chartTypeBuilder.fromStrDefinition(definition, sheetId, getters),
30197
- dataSource
30198
- };
30199
- return new SpreadsheetChart(getters, sheetId, SpreadsheetChart.deleteInvalidKeys(rangeDefinition), chartTypeBuilder, dataSourceBuilder);
30200
- }
30201
- static fromDefinition(getters, sheetId, definition) {
30202
- const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
30203
- return new SpreadsheetChart(getters, sheetId, definition, chartTypeRegistry.get(definition.type), dataSourceBuilder);
30204
- }
30205
- static validate(validator, definition) {
30206
- const chartTypeBuilder = chartTypeRegistry.get(definition.type);
30207
- const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
30208
- return validator.batchValidations(() => chartTypeBuilder.validateDefinition(validator, definition), () => dataSourceBuilder.validate(definition.dataSource ?? { type: "none" }, validator))(void 0);
30209
- }
30210
- static transformDefinition(chartSheetId, definition, rangeAdapters) {
30211
- const chartTypeBuilder = chartTypeRegistry.get(definition.type);
30212
- if (!definition.dataSource) return chartTypeBuilder.transformDefinition(definition, chartSheetId, rangeAdapters);
30213
- const newDataSource = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none").transform(definition.dataSource, chartSheetId, rangeAdapters);
30214
- return {
30215
- ...chartTypeBuilder.transformDefinition(definition, chartSheetId, rangeAdapters),
30216
- dataSource: newDataSource
30217
- };
30218
- }
30219
- getRangeDefinition() {
30220
- return {
30221
- ...this.definition,
30222
- dataSource: this.dataSource
30223
- };
30224
- }
30225
- getDefinition() {
30226
- return {
30227
- ...this.chartTypeBuilder.toStrDefinition(this.definition, this.sheetId, this.getters),
30228
- dataSource: this.dataSource && this.dataSourceBuilder.getDefinition(this.dataSource, this.sheetId, this.getters)
30229
- };
30230
- }
30231
- updateRanges(rangeAdapters) {
30232
- return {
30233
- ...this.chartTypeBuilder.updateRanges(this.definition, rangeAdapters, this.sheetId),
30234
- dataSource: this.dataSource && this.dataSourceBuilder.adaptRanges(this.dataSource, rangeAdapters)
30235
- };
30236
- }
30237
- duplicateInDuplicatedSheet(sheetIdFrom, sheetIdTo) {
30238
- const newDataSource = this.dataSource && this.dataSourceBuilder.duplicateInDuplicatedSheet(this.dataSource, sheetIdFrom, sheetIdTo, this.getters);
30239
- const definition = {
30240
- ...this.chartTypeBuilder.duplicateInDuplicatedSheet(this.definition, sheetIdFrom, sheetIdTo, this.getters),
30241
- dataSource: newDataSource
30242
- };
30243
- return SpreadsheetChart.fromDefinition(this.getters, sheetIdTo, definition).getDefinition();
30244
- }
30245
- copyInSheetId(sheetIdTo) {
30246
- return {
30247
- ...this.chartTypeBuilder.copyInSheetId(this.definition, this.sheetId, sheetIdTo, this.getters),
30248
- dataSource: this.dataSource
30249
- };
30250
- }
30251
- getContextCreation() {
30252
- const definition = this.getDefinition();
30253
- return {
30254
- ...this.dataSourceBuilder.getContextCreation(definition.dataSource ?? { type: "none" }),
30255
- ...this.chartTypeBuilder.getContextCreation(definition, this.dataSourceBuilder, definition.dataSource)
30256
- };
30257
- }
30258
- getDefinitionForExcel(getters) {
30259
- const definition = this.definition;
30260
- const excelDataSets = this.dataSourceBuilder.toExcelDataSets(this.dataSource, "dataSetStyles" in definition ? definition.dataSetStyles : {}, getters);
30261
- if (excelDataSets === void 0) return;
30262
- return this.chartTypeBuilder.getDefinitionForExcel(getters, definition, excelDataSets);
30263
- }
30264
- getData(getters, chartId) {
30265
- const dataSource = this.dataSource;
30266
- return dataSource ? this.dataSourceBuilder.extractData(dataSource, chartId, getters) : {
30267
- dataSetsValues: [],
30268
- labelValues: []
30269
- };
30270
- }
30271
- getRuntime(getters, chartId) {
30272
- const dataSource = this.dataSource;
30273
- const dataExtractors = dataSource ? {
30274
- extractData: () => this.dataSourceBuilder.extractData(dataSource, chartId, getters),
30275
- extractHierarchicalData: () => this.dataSourceBuilder.extractHierarchicalData(dataSource, chartId, getters)
30276
- } : {
30277
- extractData: () => ({
30278
- dataSetsValues: [],
30279
- labelValues: []
30280
- }),
30281
- extractHierarchicalData: () => ({
30282
- dataSetsValues: [],
30283
- labelValues: []
30284
- })
30285
- };
30286
- return this.chartTypeBuilder.getRuntime(getters, this.definition, dataExtractors, this.sheetId, {
30287
- onClick: (event, items, chartJsChart) => {
30288
- return this.dataSourceBuilder.onDataSetClick?.(this.definition.type, chartId, event, items, chartJsChart, getters);
30289
- },
30290
- onHover: (event, items, chartJsChart) => this.dataSourceBuilder.onDataSetHover?.(this.definition.type, chartId, event, items, chartJsChart)
30291
- });
30292
- }
30293
- static deleteInvalidKeys(definition) {
30294
- definition = { ...definition };
30295
- const keys = new Set(chartTypeRegistry.get(definition.type).allowedDefinitionKeys);
30296
- for (const key of Object.keys(definition)) if (!keys.has(key)) delete definition[key];
30297
- return definition;
30298
- }
30299
- };
30300
-
30301
- //#endregion
30302
- //#region src/helpers/figures/charts/chart_data_sources.ts
30303
- const EMPTY = Object.freeze({ value: null });
30304
- const ONE = Object.freeze({ value: 1 });
30305
- const ChartRangeDataSourceHandler = {
30306
- supportedChartTypes: CHART_TYPES,
30307
- fromExternalDefinition(dataSource, defaultSheetId, getters) {
30308
- const dataSets = createDataSets(getters, defaultSheetId, dataSource);
30309
- const labelRange = createValidRange(getters, defaultSheetId, dataSource.labelRange);
30310
- return {
30311
- ...dataSource,
30312
- dataSets,
30313
- labelRange
30314
- };
30315
- },
30316
- fromContextCreation(context) {
30317
- return {
30318
- type: "range",
30319
- dataSets: [],
30320
- dataSetsHaveTitle: false,
30321
- labelRange: context.auxiliaryRange,
30322
- ...context.dataSource
30323
- };
30324
- },
30325
- fromHierarchicalContextCreation(context) {
30326
- if (context.dataSource?.type !== "range" || context.hierarchicalDataSource !== void 0 && context.hierarchicalDataSource.type !== "range") return {
30327
- type: "range",
30328
- dataSets: [],
30329
- dataSetsHaveTitle: false
30330
- };
30331
- let dataSource = {
30332
- type: "range",
30333
- dataSets: [],
30334
- dataSetsHaveTitle: context.dataSource?.dataSetsHaveTitle ?? false,
30335
- labelRange: context.dataSource?.dataSets?.[0]?.dataRange
30336
- };
30337
- if (context.hierarchicalDataSource?.dataSets.length) dataSource = context.hierarchicalDataSource;
30338
- else if (context.auxiliaryRange) dataSource = {
30339
- ...dataSource,
30340
- dataSets: [{
30341
- dataRange: context.auxiliaryRange,
30342
- dataSetId: "0"
30343
- }]
30344
- };
30345
- return dataSource;
30346
- },
30347
- validate: (dataSource, validator) => validator.checkValidations(dataSource, checkDataset, checkLabelRange),
30348
- transform(dataSource, defaultSheetId, { adaptRangeString }) {
30349
- let labelRange;
30350
- if (dataSource.labelRange) {
30351
- const { changeType, range: adaptedRange } = adaptRangeString(defaultSheetId, dataSource.labelRange);
30352
- if (changeType !== "REMOVE") labelRange = adaptedRange;
30353
- }
30354
- const dataSets = [];
30355
- for (const dataSet of dataSource.dataSets) {
30356
- const newDataSet = { ...dataSet };
30357
- const { changeType, range: adaptedRange } = adaptRangeString(defaultSheetId, dataSet.dataRange);
30358
- if (changeType !== "REMOVE") {
30359
- newDataSet.dataRange = adaptedRange;
30360
- dataSets.push(newDataSet);
30361
- }
30362
- }
30363
- return {
30364
- ...dataSource,
30365
- dataSets,
30366
- labelRange
30367
- };
30368
- },
30369
- extractData: (dataSource, chartId, getters) => getChartData(getters, dataSource),
30370
- extractHierarchicalData(dataSource, chartId, getters) {
30371
- const dataSets = dataSource.dataSets;
30372
- const labelRange = dataSource.labelRange;
30373
- const labelValues = getChartLabelValues(getters, dataSets, labelRange);
30374
- const dataSetsValues = getHierarchicalDatasetValues(getters, dataSets);
30375
- const data = {
30376
- labelValues,
30377
- dataSetsValues
30378
- };
30379
- if (shouldRemoveFirstLabel(labelValues.length, dataSetsValues[0]?.data.length + (dataSetsValues[0]?.label !== void 0 ? 1 : 0), dataSource.dataSetsHaveTitle || false)) labelValues.shift();
30380
- return data;
30381
- },
30382
- adaptRanges(dataSource, { applyChange }) {
30383
- const dataSetsWithUndefined = dataSource.dataSets.map((ds) => {
30384
- const { range: adaptedRangeStr, changeType } = applyChange(ds.dataRange);
30385
- if (changeType === "REMOVE") return;
30386
- let labelCell = void 0;
30387
- if (ds.labelCell) {
30388
- const { range: adaptedLabelCellRange, changeType: labelCellChangeType } = applyChange(ds.labelCell);
30389
- if (labelCellChangeType !== "REMOVE") labelCell = adaptedLabelCellRange;
30390
- }
30391
- return {
30392
- ...ds,
30393
- dataRange: adaptedRangeStr,
30394
- labelCell
30395
- };
30396
- }).filter(isDefined);
30397
- let labelRange = dataSource.labelRange;
30398
- if (labelRange) {
30399
- const { range: adaptedLabelRange, changeType } = applyChange(labelRange);
30400
- if (changeType === "REMOVE") labelRange = void 0;
30401
- else labelRange = adaptedLabelRange;
30402
- }
30403
- const dataSets = dataSetsWithUndefined;
30404
- return {
30405
- ...dataSource,
30406
- dataSets,
30407
- labelRange: labelRange?.invalidSheetName || labelRange?.invalidXc ? void 0 : labelRange
30408
- };
30409
- },
30410
- getDefinition(dataSource, defaultSheetId, getters) {
30411
- return {
30412
- labelRange: dataSource.labelRange ? getters.getRangeString(dataSource.labelRange, defaultSheetId) : void 0,
30413
- type: "range",
30414
- dataSets: dataSource.dataSets.map((dataSet) => ({
30415
- dataSetId: dataSet.dataSetId,
30416
- dataRange: getters.getRangeString(dataSet.dataRange, defaultSheetId)
30417
- })),
30418
- dataSetsHaveTitle: dataSource.dataSetsHaveTitle
30419
- };
30420
- },
30421
- /**
30422
- * Duplicate the dataSets. All ranges on sheetIdFrom are adapted to target
30423
- * sheetIdTo.
30424
- */
30425
- duplicateInDuplicatedSheet(dataSource, sheetIdFrom, sheetIdTo, getters) {
30426
- return {
30427
- ...dataSource,
30428
- labelRange: duplicateLabelRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, dataSource.labelRange),
30429
- dataSets: dataSource.dataSets.map((ds) => ({
30430
- ...ds,
30431
- dataRange: duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, ds.dataRange)
30432
- }))
30433
- };
30434
- },
30435
- getContextCreation: (dataSource) => ({
30436
- auxiliaryRange: dataSource.labelRange,
30437
- dataSource
30438
- }),
30439
- getHierarchicalContextCreation(dataSource) {
30440
- const leafRange = dataSource.dataSets.at(-1)?.dataRange;
30441
- const dataSetsHaveTitle = dataSource.dataSetsHaveTitle;
30442
- return {
30443
- auxiliaryRange: leafRange,
30444
- hierarchicalDataSource: dataSource,
30445
- dataSource: dataSource.labelRange ? {
30446
- type: "range",
30447
- dataSets: [{
30448
- dataRange: dataSource.labelRange,
30449
- dataSetId: "0"
30450
- }],
30451
- dataSetsHaveTitle
30452
- } : {
30453
- type: "range",
30454
- dataSets: [],
30455
- dataSetsHaveTitle
30456
- }
30457
- };
30458
- },
30459
- toExcelDataSets(dataSource, dataSetStyles, getters) {
30460
- const dataSets = dataSource.dataSets;
30461
- const labelRange = dataSource.labelRange;
30462
- const excelDataSets = dataSets.map((ds) => toExcelDataset(getters, dataSetStyles, ds)).filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
30463
- const datasetLength = dataSets[0] ? getZoneArea(dataSets[0].dataRange.zone) : void 0;
30464
- return {
30465
- dataSets: excelDataSets,
30466
- labelRange: toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel(labelRange ? getZoneArea(labelRange.zone) : 0, datasetLength, dataSource.dataSetsHaveTitle))
30467
- };
30468
- }
30469
- };
30470
- function getChartData(getters, dataSource) {
30471
- const dataSets = dataSource.dataSets;
30472
- const labelRange = dataSource.labelRange;
30473
- const labelValues = getChartLabelValues(getters, dataSets, labelRange);
30474
- const dataSetsValues = getChartDatasetValues(getters, dataSets);
30475
- const data = {
30476
- labelValues,
30477
- dataSetsValues
30478
- };
30479
- const numberOfDataPoints = dataSetsValues.length ? dataSetsValues[0]?.data.length + (dataSetsValues[0]?.label !== void 0 ? 1 : 0) : 0;
30480
- if (shouldRemoveFirstLabel(labelValues.length, numberOfDataPoints, dataSource.dataSetsHaveTitle || false)) labelValues.shift();
30481
- return data;
30482
- }
30483
- function getChartDatasetValues(getters, dataSets) {
30484
- const datasetValues = [];
30485
- for (const [dsIndex, ds] of Object.entries(dataSets)) {
30486
- let label = `${ChartTerms.Series} ${parseInt(dsIndex) + 1}`;
30487
- let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
30488
- if (ds.labelCell) {
30489
- const { sheetId, zone } = ds.labelCell;
30490
- const cell = getters.getEvaluatedCell({
30491
- sheetId,
30492
- col: zone.left,
30493
- row: zone.top
30494
- });
30495
- if (cell) label = cell.formattedValue;
30496
- }
30497
- let data = ds.dataRange ? getData(getters, ds) : [];
30498
- if (data.every((cell) => !cell.value || isTextResult(cell)) && data.filter(isTextResult).length > 1) data = data.map((cell) => cell.value && !isErrorResult(cell) ? ONE : EMPTY);
30499
- else if (data.every((cell) => !isNumberResult(cell))) hidden = true;
30500
- datasetValues.push({
30501
- data,
30502
- label,
30503
- hidden,
30504
- dataSetId: ds.dataSetId
30505
- });
30506
- }
30507
- return datasetValues;
30508
- }
30509
- function getChartLabelValues(getters, dataSets, labelRange) {
30510
- if (labelRange) {
30511
- const { left } = labelRange.zone;
30512
- if (!labelRange.invalidXc && !labelRange.invalidSheetName && !getters.isColHidden(labelRange.sheetId, left)) return getters.getVisibleRangeValues(labelRange);
30513
- }
30514
- if (dataSets[0]) {
30515
- const dataLength = getData(getters, dataSets[0]).length;
30516
- return Array.from({ length: dataLength }, () => ({ value: "" }));
30517
- }
30518
- return [];
30519
- }
30520
- /**
30521
- * Get the values for a hierarchical dataset. The values can be defined in a tree-like structure
30522
- * in the sheet, and this function will fill up the blanks.
30523
- *
30524
- * @example the following dataset:
30525
- *
30526
- * 2024 Q1 W1 100
30527
- * W2 200
30528
- *
30529
- * will have the same value as the dataset:
30530
- * 2024 Q1 W1 100
30531
- * 2024 Q1 W2 200
30532
- */
30533
- function getHierarchicalDatasetValues(getters, dataSets) {
30534
- dataSets = dataSets.filter((ds) => !getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left));
30535
- const datasetValues = dataSets.map((ds) => ({
30536
- data: [],
30537
- label: "",
30538
- dataSetId: ds.dataSetId
30539
- }));
30540
- const locale = getters.getLocale();
30541
- const dataSetsData = dataSets.map((ds) => getData(getters, ds)).map((values) => values.map(({ value, format }) => value === null ? EMPTY : { value: formatValue(value, {
30542
- format,
30543
- locale
30544
- }) }));
30545
- if (!dataSetsData.length) return datasetValues;
30546
- const minLength = Math.min(...dataSetsData.map((ds) => ds.length));
30547
- let currentValues = [];
30548
- const leafDatasetIndex = dataSets.length - 1;
30549
- for (let i = 0; i < minLength; i++) for (let dsIndex = 0; dsIndex < dataSetsData.length; dsIndex++) {
30550
- let cell = dataSetsData[dsIndex][i];
30551
- if ((cell === void 0 || cell.value === null) && dsIndex !== leafDatasetIndex) cell = currentValues[dsIndex];
30552
- if (cell?.value !== currentValues[dsIndex]?.value) {
30553
- currentValues = currentValues.slice(0, dsIndex);
30554
- currentValues[dsIndex] = cell;
30555
- }
30556
- datasetValues[dsIndex].data.push(cell ?? EMPTY);
30557
- }
30558
- return datasetValues.filter((ds) => ds.data.some((d) => d.value !== null));
30559
- }
30560
- /**
30561
- * Get the data from a dataSet
30562
- */
30563
- function getData(getters, ds) {
30564
- if (ds.dataRange) {
30565
- const labelCellZone = ds.labelCell ? [ds.labelCell.zone] : [];
30566
- const dataZone = recomputeZones([ds.dataRange.zone], labelCellZone)[0];
30567
- if (dataZone === void 0) return [];
30568
- const dataRange = getters.getRangeFromZone(ds.dataRange.sheetId, dataZone);
30569
- return getters.getVisibleRangeValues(dataRange).map((cell) => cell.value === "" ? EMPTY : cell);
30570
- }
30571
- return [];
30572
- }
30573
- const ChartNeverDataSourceHandler = {
30574
- supportedChartTypes: [],
30575
- fromExternalDefinition: () => ({ type: "none" }),
30576
- fromContextCreation: () => ({ type: "none" }),
30577
- fromHierarchicalContextCreation: () => ({ type: "none" }),
30578
- validate: () => "Success",
30579
- transform: () => ({ type: "none" }),
30580
- extractData: () => ({
30581
- dataSetsValues: [],
30582
- labelValues: []
30583
- }),
30584
- extractHierarchicalData: () => ({
30585
- dataSetsValues: [],
30586
- labelValues: []
30587
- }),
30588
- adaptRanges: (dataSource) => dataSource,
30589
- getDefinition: (dataSource) => dataSource,
30590
- duplicateInDuplicatedSheet: (dataSource) => dataSource,
30591
- getContextCreation: () => ({}),
30592
- getHierarchicalContextCreation: () => ({}),
30593
- toExcelDataSets: () => ({
30594
- dataSets: [],
30595
- labelRange: void 0
30596
- })
30597
- };
30598
- chartDataSourceRegistry.add("range", ChartRangeDataSourceHandler);
30599
- chartDataSourceRegistry.add("none", ChartNeverDataSourceHandler);
30600
-
30601
30189
  //#endregion
30602
30190
  //#region src/types/chart/calendar_chart.ts
30603
30191
  const CALENDAR_CHART_GRANULARITIES = [
@@ -30624,41 +30212,6 @@ set(value) {
30624
30212
  value,
30625
30213
  label: ALL_PERIODS[value]
30626
30214
  }));
30627
- getGroupByOptions() {
30628
- const sheetId = this.env.model.getters.getFigureSheetId(this.env.model.getters.getFigureIdFromChartId(this.props.chartId));
30629
- const definition = SpreadsheetChart.fromStrDefinition(this.env.model.getters, sheetId, this.props.definition).getRangeDefinition();
30630
- const labels = getBarChartData(definition, getChartData(this.env.model.getters, definition.dataSource), this.env.model.getters).labels.filter((l) => isDateTime(l, DEFAULT_LOCALE));
30631
- if (labels.length === 0) return [];
30632
- const dates = labels.map((label) => toJsDate(label, this.env.model.getters.getLocale()));
30633
- const uniqueYears = /* @__PURE__ */ new Set();
30634
- const uniqueMonths = /* @__PURE__ */ new Set();
30635
- const uniqueDays = /* @__PURE__ */ new Set();
30636
- const uniqueHours = /* @__PURE__ */ new Set();
30637
- const uniqueMinutes = /* @__PURE__ */ new Set();
30638
- const uniqueSeconds = /* @__PURE__ */ new Set();
30639
- for (const date of dates) {
30640
- uniqueYears.add(date.getFullYear());
30641
- uniqueMonths.add(date.getMonth());
30642
- uniqueDays.add(date.getDate());
30643
- uniqueHours.add(date.getHours());
30644
- uniqueMinutes.add(date.getMinutes());
30645
- uniqueSeconds.add(date.getSeconds());
30646
- }
30647
- return this.groupByChoices.filter((groupBy) => {
30648
- switch (groupBy.value) {
30649
- case "year": return uniqueYears.size > 1;
30650
- case "quarter_number":
30651
- case "month_number": return uniqueMonths.size > 1;
30652
- case "iso_week_number":
30653
- case "day_of_month":
30654
- case "day_of_week": return uniqueDays.size > 1;
30655
- case "hour_number": return uniqueHours.size > 1;
30656
- case "minute_number": return uniqueMinutes.size > 1;
30657
- case "second_number": return uniqueSeconds.size > 1;
30658
- default: return false;
30659
- }
30660
- });
30661
- }
30662
30215
  getGroupByType(currentAxis) {
30663
30216
  return (currentAxis === "horizontal" ? this.props.definition.horizontalGroupBy : this.props.definition.verticalGroupBy) || "year";
30664
30217
  }
@@ -31231,7 +30784,7 @@ set(value) {
31231
30784
  spreadsheetRect = useSpreadsheetRect();
31232
30785
  bubbleRef = (0, _odoo_owl.signal)(null);
31233
30786
  setup() {
31234
- (0, _odoo_owl.useEffect)(() => {
30787
+ useLayoutEffect(() => {
31235
30788
  const el = this.bubbleRef();
31236
30789
  if (!el) return;
31237
30790
  const anchorRect = this.props.anchorRect;
@@ -31292,9 +30845,10 @@ set(value) {
31292
30845
  compositionActive = false;
31293
30846
  spreadsheetRect = useSpreadsheetRect();
31294
30847
  lastHoveredTokenIndex = void 0;
31295
- debouncedHover = debounce((tokenIndex, hoveredRect) => {
30848
+ debouncedHover = debounce((tokenIndex, composerContent, hoveredRect) => {
31296
30849
  const selection = this.contentHelper.getCurrentSelection();
31297
- if (selection.start !== selection.end) return;
30850
+ const currentContent = this.props.composerStore.currentContent;
30851
+ if (selection.start !== selection.end || currentContent !== composerContent) return;
31298
30852
  const currentHoveredContext = this.props.composerStore.hoveredTokens;
31299
30853
  this.props.composerStore.hoverToken(tokenIndex);
31300
30854
  if (!deepEquals(currentHoveredContext, this.props.composerStore.hoveredTokens)) this.composerState.hoveredRect = hoveredRect;
@@ -31614,7 +31168,8 @@ set(value) {
31614
31168
  onTokenHover(tokenIndex, hoveredRect) {
31615
31169
  if (this.lastHoveredTokenIndex !== tokenIndex) {
31616
31170
  this.lastHoveredTokenIndex = tokenIndex;
31617
- this.debouncedHover(tokenIndex, hoveredRect);
31171
+ const composerContent = this.props.composerStore.currentContent;
31172
+ this.debouncedHover(tokenIndex, composerContent, hoveredRect);
31618
31173
  }
31619
31174
  }
31620
31175
  /**
@@ -32643,7 +32198,7 @@ set(value) {
32643
32198
  col: range.zone.left,
32644
32199
  row: range.zone.top
32645
32200
  });
32646
- if (spreadZone) return this.getters.getRangeFromZone(sheetId, spreadZone);
32201
+ if (spreadZone) return this.getters.getRangeFromZone(range.sheetId, spreadZone);
32647
32202
  return range;
32648
32203
  }
32649
32204
  updateAutoCompleteProvider() {
@@ -33856,6 +33411,133 @@ set(value) {
33856
33411
  }
33857
33412
  };
33858
33413
 
33414
+ //#endregion
33415
+ //#region src/helpers/figures/chart.ts
33416
+ var SpreadsheetChart = class SpreadsheetChart {
33417
+ getters;
33418
+ sheetId;
33419
+ definition;
33420
+ chartTypeBuilder;
33421
+ dataSourceBuilder;
33422
+ dataSource;
33423
+ constructor(getters, sheetId, definition, chartTypeBuilder, dataSourceBuilder) {
33424
+ this.getters = getters;
33425
+ this.sheetId = sheetId;
33426
+ this.definition = definition;
33427
+ this.chartTypeBuilder = chartTypeBuilder;
33428
+ this.dataSourceBuilder = dataSourceBuilder;
33429
+ this.dataSource = definition.dataSource;
33430
+ }
33431
+ static fromStrDefinition(getters, sheetId, definition) {
33432
+ const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
33433
+ const chartTypeBuilder = chartTypeRegistry.get(definition.type);
33434
+ const dataSource = dataSourceBuilder.fromExternalDefinition(definition.dataSource ?? { type: "none" }, sheetId, getters);
33435
+ const rangeDefinition = {
33436
+ ...chartTypeBuilder.fromStrDefinition(definition, sheetId, getters),
33437
+ dataSource
33438
+ };
33439
+ return new SpreadsheetChart(getters, sheetId, SpreadsheetChart.deleteInvalidKeys(rangeDefinition), chartTypeBuilder, dataSourceBuilder);
33440
+ }
33441
+ static fromDefinition(getters, sheetId, definition) {
33442
+ const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
33443
+ return new SpreadsheetChart(getters, sheetId, definition, chartTypeRegistry.get(definition.type), dataSourceBuilder);
33444
+ }
33445
+ static validate(validator, definition) {
33446
+ const chartTypeBuilder = chartTypeRegistry.get(definition.type);
33447
+ const dataSourceBuilder = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none");
33448
+ return validator.batchValidations(() => chartTypeBuilder.validateDefinition(validator, definition), () => dataSourceBuilder.validate(definition.dataSource ?? { type: "none" }, validator))(void 0);
33449
+ }
33450
+ static transformDefinition(chartSheetId, definition, rangeAdapters) {
33451
+ const chartTypeBuilder = chartTypeRegistry.get(definition.type);
33452
+ if (!definition.dataSource) return chartTypeBuilder.transformDefinition(definition, chartSheetId, rangeAdapters);
33453
+ const newDataSource = chartDataSourceRegistry.get(definition.dataSource?.type ?? "none").transform(definition.dataSource, chartSheetId, rangeAdapters);
33454
+ return {
33455
+ ...chartTypeBuilder.transformDefinition(definition, chartSheetId, rangeAdapters),
33456
+ dataSource: newDataSource
33457
+ };
33458
+ }
33459
+ getRangeDefinition() {
33460
+ return {
33461
+ ...this.definition,
33462
+ dataSource: this.dataSource
33463
+ };
33464
+ }
33465
+ getDefinition() {
33466
+ return {
33467
+ ...this.chartTypeBuilder.toStrDefinition(this.definition, this.sheetId, this.getters),
33468
+ dataSource: this.dataSource && this.dataSourceBuilder.getDefinition(this.dataSource, this.sheetId, this.getters)
33469
+ };
33470
+ }
33471
+ updateRanges(rangeAdapters) {
33472
+ return {
33473
+ ...this.chartTypeBuilder.updateRanges(this.definition, rangeAdapters, this.sheetId),
33474
+ dataSource: this.dataSource && this.dataSourceBuilder.adaptRanges(this.dataSource, rangeAdapters)
33475
+ };
33476
+ }
33477
+ duplicateInDuplicatedSheet(sheetIdFrom, sheetIdTo) {
33478
+ const newDataSource = this.dataSource && this.dataSourceBuilder.duplicateInDuplicatedSheet(this.dataSource, sheetIdFrom, sheetIdTo, this.getters);
33479
+ const definition = {
33480
+ ...this.chartTypeBuilder.duplicateInDuplicatedSheet(this.definition, sheetIdFrom, sheetIdTo, this.getters),
33481
+ dataSource: newDataSource
33482
+ };
33483
+ return SpreadsheetChart.fromDefinition(this.getters, sheetIdTo, definition).getDefinition();
33484
+ }
33485
+ copyInSheetId(sheetIdTo) {
33486
+ return {
33487
+ ...this.chartTypeBuilder.copyInSheetId(this.definition, this.sheetId, sheetIdTo, this.getters),
33488
+ dataSource: this.dataSource
33489
+ };
33490
+ }
33491
+ getContextCreation() {
33492
+ const definition = this.getDefinition();
33493
+ return {
33494
+ ...this.dataSourceBuilder.getContextCreation(definition.dataSource ?? { type: "none" }),
33495
+ ...this.chartTypeBuilder.getContextCreation(definition, this.dataSourceBuilder, definition.dataSource)
33496
+ };
33497
+ }
33498
+ getDefinitionForExcel(getters) {
33499
+ const definition = this.definition;
33500
+ const excelDataSets = this.dataSourceBuilder.toExcelDataSets(this.dataSource, "dataSetStyles" in definition ? definition.dataSetStyles : {}, getters);
33501
+ if (excelDataSets === void 0) return;
33502
+ return this.chartTypeBuilder.getDefinitionForExcel(getters, definition, excelDataSets);
33503
+ }
33504
+ getData(getters, chartId) {
33505
+ const dataSource = this.dataSource;
33506
+ return dataSource ? this.dataSourceBuilder.extractData(dataSource, chartId, getters) : {
33507
+ dataSetsValues: [],
33508
+ labelValues: []
33509
+ };
33510
+ }
33511
+ getRuntime(getters, chartId) {
33512
+ const dataSource = this.dataSource;
33513
+ const dataExtractors = dataSource ? {
33514
+ extractData: () => this.dataSourceBuilder.extractData(dataSource, chartId, getters),
33515
+ extractHierarchicalData: () => this.dataSourceBuilder.extractHierarchicalData(dataSource, chartId, getters)
33516
+ } : {
33517
+ extractData: () => ({
33518
+ dataSetsValues: [],
33519
+ labelValues: []
33520
+ }),
33521
+ extractHierarchicalData: () => ({
33522
+ dataSetsValues: [],
33523
+ labelValues: []
33524
+ })
33525
+ };
33526
+ return this.chartTypeBuilder.getRuntime(getters, this.definition, dataExtractors, this.sheetId, {
33527
+ onClick: (event, items, chartJsChart) => {
33528
+ return this.dataSourceBuilder.onDataSetClick?.(this.definition.type, chartId, event, items, chartJsChart, getters);
33529
+ },
33530
+ onHover: (event, items, chartJsChart) => this.dataSourceBuilder.onDataSetHover?.(this.definition.type, chartId, event, items, chartJsChart)
33531
+ });
33532
+ }
33533
+ static deleteInvalidKeys(definition) {
33534
+ definition = { ...definition };
33535
+ const keys = new Set(chartTypeRegistry.get(definition.type).allowedDefinitionKeys);
33536
+ for (const key of Object.keys(definition)) if (!keys.has(key)) delete definition[key];
33537
+ return definition;
33538
+ }
33539
+ };
33540
+
33859
33541
  //#endregion
33860
33542
  //#region src/components/side_panel/chart/main_chart_panel/main_chart_panel_store.ts
33861
33543
  var MainChartPanelStore = class extends SpreadsheetStore {
@@ -37077,7 +36759,7 @@ set(value) {
37077
36759
  }
37078
36760
  get specificRangeMatchesCount() {
37079
36761
  const range = this.searchOptions.specificRange;
37080
- if (!range) return "";
36762
+ if (!range || range.invalidSheetName || range.invalidXc) return "";
37081
36763
  const { specificRangeMatchesCount: count, specificRangeHiddenMatchesCount: hidden, searchOptions } = this.store;
37082
36764
  const { sheetId, zone } = range;
37083
36765
  let label = count === 1 ? _t("1 match in range %(range)s of '%(sheetName)s'", {
@@ -41270,7 +40952,13 @@ set(value) {
41270
40952
  }
41271
40953
  onSelectionChanged(ranges) {
41272
40954
  this.state.rangeHasChanged = true;
41273
- this.state.range = ranges[0];
40955
+ if (ranges.length === 0) {
40956
+ this.state.range = void 0;
40957
+ return;
40958
+ }
40959
+ const sheetId = this.env.model.getters.getActiveSheetId();
40960
+ const range = this.env.model.getters.getRangeFromSheetXC(sheetId, ranges[0]);
40961
+ this.state.range = this.env.model.getters.getRangeString(range, "forceSheetReference", { useBoundedReference: true });
41274
40962
  }
41275
40963
  onSelectionConfirmed() {
41276
40964
  if (this.state.range) {
@@ -47459,6 +47147,11 @@ set(value) {
47459
47147
  });
47460
47148
  return icon?.onClick ? icon : void 0;
47461
47149
  }
47150
+ get isFooterVisible() {
47151
+ const { y } = this.env.model.getters.getMainViewportCoordinates();
47152
+ const { height } = this.env.model.getters.getSheetViewDimension();
47153
+ return !this.env.model.getters.isReadonly() && height - y > 46;
47154
+ }
47462
47155
  };
47463
47156
 
47464
47157
  //#endregion
@@ -51029,6 +50722,7 @@ set(value) {
51029
50722
  return "Success";
51030
50723
  case "UPDATE_CAROUSEL":
51031
50724
  if (!this.carousels[cmd.sheetId]?.[cmd.figureId]) return "InvalidFigureId";
50725
+ for (const item of cmd.definition.items) if (item.type === "chart" && !this.getters.getChart(item.chartId)) return "ChartDoesNotExist";
51032
50726
  return "Success";
51033
50727
  }
51034
50728
  return "Success";
@@ -56252,7 +55946,7 @@ set(value) {
56252
55946
  if (rangeError) return [[rangeError]];
56253
55947
  const sheetId = range.sheetId;
56254
55948
  const zone = range.zone;
56255
- const _zone = intersection(zone, this.getters.getSheetZone(sheetId));
55949
+ const _zone = this.getters.clipRangeToSheet(range)?.zone;
56256
55950
  if (!_zone) return [[]];
56257
55951
  const { top, left, bottom, right } = zone;
56258
55952
  const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
@@ -56556,6 +56250,7 @@ set(value) {
56556
56250
  }
56557
56251
  getCellsDependingOn(ranges, visited = new RangeSet()) {
56558
56252
  visited = visited.copy();
56253
+ let initialRangesToRemove = visited.copy();
56559
56254
  const queue = Array.from(ranges).reverse();
56560
56255
  while (queue.length > 0) {
56561
56256
  const range = queue.pop();
@@ -56571,8 +56266,9 @@ set(value) {
56571
56266
  for (const interval of overlappingIntervals) impactedRanges.add(interval.dependents);
56572
56267
  }
56573
56268
  queue.push(...impactedRanges.difference(visited));
56269
+ initialRangesToRemove = initialRangesToRemove.difference(impactedRanges);
56574
56270
  }
56575
- for (const range of ranges) visited.delete(range);
56271
+ for (const range of initialRangesToRemove) visited.delete(range);
56576
56272
  return visited;
56577
56273
  }
56578
56274
  getOrCreateIntervalTree(sheetId, col) {
@@ -57240,10 +56936,10 @@ set(value) {
57240
56936
  updateDependencies(position) {
57241
56937
  this.formulaDependencies().removeAllDependencies(position);
57242
56938
  const dependencies = this.getDirectDependencies(position);
57243
- this.formulaDependencies().addDependencies(position, dependencies);
56939
+ this.formulaDependencies().addDependencies(position, this.getters.clipRangesToSheet(dependencies));
57244
56940
  }
57245
56941
  addDependencies(position, dependencies) {
57246
- this.formulaDependencies().addDependencies(position, dependencies);
56942
+ this.formulaDependencies().addDependencies(position, this.getters.clipRangesToSheet(dependencies));
57247
56943
  this.computeDependencies(dependencies);
57248
56944
  }
57249
56945
  computeDependencies(dependencies) {
@@ -57316,7 +57012,8 @@ set(value) {
57316
57012
  const graph = new FormulaDependencyGraph();
57317
57013
  for (const sheetId of this.getters.getSheetIds()) for (const cell of this.getters.getCells(sheetId)) if (cell.isFormula) {
57318
57014
  const cellPosition = this.getters.getCellPosition(cell.id);
57319
- graph.addDependencies(cellPosition, cell.compiledFormula.rangeDependencies);
57015
+ const dependencies = this.getters.clipRangesToSheet(cell.compiledFormula.rangeDependencies);
57016
+ graph.addDependencies(cellPosition, dependencies);
57320
57017
  }
57321
57018
  return graph;
57322
57019
  });
@@ -63297,7 +62994,8 @@ set(value) {
63297
62994
  "getGeoJsonFeatures",
63298
62995
  "geoFeatureNameToId",
63299
62996
  "getGeoChartAvailableRegions",
63300
- "getAvailableChartRegions"
62997
+ "getAvailableChartRegions",
62998
+ "loadUsedGeoJsonFeatures"
63301
62999
  ];
63302
63000
  geoJsonService;
63303
63001
  geoJsonCache = {};
@@ -63380,6 +63078,23 @@ set(value) {
63380
63078
  }
63381
63079
  return this.geoJsonService.geoFeatureNameToId(region, featureName);
63382
63080
  }
63081
+ loadUsedGeoJsonFeatures() {
63082
+ const regions = this.getters.getSheetIds().flatMap((sheetId) => this.getters.getChartIds(sheetId).map((chartId) => {
63083
+ const definition = this.getters.getChartDefinition(chartId);
63084
+ return definition.type === "geo" ? definition.region || this.getters.getGeoChartAvailableRegions()[0]?.id : void 0;
63085
+ })).filter(isDefined);
63086
+ const uniqueRegions = Array.from(new Set(regions));
63087
+ if (uniqueRegions.length && !this.geoJsonService) {
63088
+ console.error("No geoJsonService provided to the model");
63089
+ return Promise.resolve();
63090
+ }
63091
+ for (const region of uniqueRegions) this.getGeoJsonFeatures(region);
63092
+ const promises = uniqueRegions.map((region) => {
63093
+ const cachedGeoJson = this.geoJsonCache[region];
63094
+ return cachedGeoJson instanceof Promise ? cachedGeoJson : Promise.resolve();
63095
+ });
63096
+ return Promise.all(promises).then(() => {});
63097
+ }
63383
63098
  convertToGeoJson(json) {
63384
63099
  if (!json) return null;
63385
63100
  if (json.type === "Topology") {
@@ -66464,7 +66179,7 @@ set(value) {
66464
66179
  let height = lastRowEnd - this.offsetCorrectionY;
66465
66180
  if (this.canScrollVertically) {
66466
66181
  height = Math.max(height, this.viewportHeight);
66467
- if (lastRowEnd + 46 > height && !this.getters.isReadonly()) height += 46;
66182
+ if (lastRowEnd + 46 > height && !this.getters.isReadonly() && this.viewportHeight > 46) height += 46;
66468
66183
  }
66469
66184
  return {
66470
66185
  width,
@@ -70248,7 +69963,7 @@ set(value) {
70248
69963
  if (!this.getters.isDashboard()) {
70249
69964
  ctx.strokeStyle = GRAY_400;
70250
69965
  ctx.lineWidth = 1;
70251
- ctx.strokeRect(x, y, figure.width, figure.height);
69966
+ ctx.strokeRect(x + .5, y + .5, figure.width - 1, figure.height - 1);
70252
69967
  }
70253
69968
  }
70254
69969
  }
@@ -70457,12 +70172,11 @@ set(value) {
70457
70172
  const { width: printWidth, height: printHeight } = this.pageDimensionWithMargins;
70458
70173
  const start = dimension === "COL" ? printZone.left : printZone.top;
70459
70174
  const end = dimension === "COL" ? printZone.right : printZone.bottom;
70460
- const getHeaderSize = dimension === "COL" ? this.getters.getColDimensions : this.getters.getRowDimensions;
70461
70175
  const max = dimension === "COL" ? printWidth : printHeight;
70462
70176
  const breaks = [];
70463
70177
  let current = 0;
70464
70178
  for (let i = start; i <= end; i++) {
70465
- const headerSize = getHeaderSize(sheetId, i).size * zoom;
70179
+ const headerSize = this.getters.isHeaderHidden(sheetId, dimension, i) ? 0 : this.getters.getHeaderSize(sheetId, dimension, i) * zoom;
70466
70180
  current += headerSize;
70467
70181
  if (current >= max) {
70468
70182
  breaks.push(i);
@@ -71913,7 +71627,10 @@ set(value) {
71913
71627
  sidePanel;
71914
71628
  spreadsheetRef = (0, _odoo_owl.signal)(null);
71915
71629
  spreadsheetRect = useSpreadsheetRect();
71916
- state = (0, _odoo_owl.proxy)({ printModeEnabled: false });
71630
+ state = (0, _odoo_owl.proxy)({
71631
+ printModeEnabled: false,
71632
+ colorThemeBeforePrint: "light"
71633
+ });
71917
71634
  _focusGrid;
71918
71635
  isViewportTooSmall = false;
71919
71636
  notificationStore;
@@ -71925,7 +71642,7 @@ set(value) {
71925
71642
  const properties = {};
71926
71643
  properties["--os-scrollbar-width"] = `${this.env.model.getters.getScrollBarWidth()}px`;
71927
71644
  properties["--os-dark-mode-filter"] = DARK_MODE_FILTER_STRING;
71928
- properties["color-scheme"] = this.props.model.getters.isDarkMode() ? "dark" : "light";
71645
+ properties["color-scheme"] = this.colorScheme;
71929
71646
  if (this.state.printModeEnabled) properties["display"] = `block`;
71930
71647
  else {
71931
71648
  if (this.env.model.getters.isDashboard()) properties["grid-template-rows"] = `auto`;
@@ -71965,7 +71682,7 @@ set(value) {
71965
71682
  askConfirmation: (text, confirm, cancel) => this.notificationStore.askConfirmation(text, confirm, cancel),
71966
71683
  raiseError: (text, cb) => this.notificationStore.raiseError(text, cb),
71967
71684
  isMobile: isMobileOS,
71968
- printSpreadsheet: () => this.state.printModeEnabled = true
71685
+ printSpreadsheet: this.enterPrintMode.bind(this)
71969
71686
  });
71970
71687
  this.notificationStore.updateNotificationCallbacks({ ...this.props });
71971
71688
  useLayoutEffect(() => {
@@ -71982,7 +71699,7 @@ set(value) {
71982
71699
  useExternalListener(document.body, "wheel", () => {});
71983
71700
  useExternalListener(window, "keydown", async (event) => {
71984
71701
  if (keyboardEventToShortcutString(event) === "Ctrl+P") {
71985
- this.state.printModeEnabled = true;
71702
+ this.enterPrintMode();
71986
71703
  event.stopPropagation();
71987
71704
  event.preventDefault();
71988
71705
  }
@@ -72095,9 +71812,21 @@ set(value) {
72095
71812
  getSpreadSheetClasses() {
72096
71813
  return [this.env.isSmall ? "o-spreadsheet-mobile" : "", this.props.model.getters.isDarkMode() ? "dark" : ""].join(" ");
72097
71814
  }
71815
+ enterPrintMode() {
71816
+ if (this.state.printModeEnabled) return;
71817
+ this.state.colorThemeBeforePrint = this.props.model.getters.isDarkMode() ? "dark" : "light";
71818
+ this.env.model.dispatch("UPDATE_COLOR_SCHEME", { colorScheme: "light" });
71819
+ this.state.printModeEnabled = true;
71820
+ }
72098
71821
  exitPrintMode() {
71822
+ if (!this.state.printModeEnabled) return;
71823
+ this.env.model.dispatch("UPDATE_COLOR_SCHEME", { colorScheme: this.state.colorThemeBeforePrint });
72099
71824
  this.state.printModeEnabled = false;
72100
71825
  }
71826
+ get colorScheme() {
71827
+ if (this.state.printModeEnabled) return this.state.colorThemeBeforePrint;
71828
+ return this.props.model.getters.isDarkMode() ? "dark" : "light";
71829
+ }
72101
71830
  };
72102
71831
 
72103
71832
  //#endregion
@@ -72972,6 +72701,8 @@ set(value) {
72972
72701
  "extendRange",
72973
72702
  "getRangeString",
72974
72703
  "getRangeFromSheetXC",
72704
+ "clipRangesToSheet",
72705
+ "clipRangeToSheet",
72975
72706
  "createAdaptedRanges",
72976
72707
  "getRangeData",
72977
72708
  "getRangeDataFromXc",
@@ -73010,6 +72741,22 @@ set(value) {
73010
72741
  addRangeProvider(provider) {
73011
72742
  this.providers.push(provider);
73012
72743
  }
72744
+ clipRangeToSheet(range) {
72745
+ if (range.invalidXc) return range;
72746
+ const sheetZone = this.getters.getSheetZone(range.sheetId);
72747
+ if (isZoneInside(range.zone, sheetZone)) return range;
72748
+ const newZone = intersection(range.zone, sheetZone);
72749
+ if (!newZone) return;
72750
+ return this.getters.getRangeFromZone(range.sheetId, newZone);
72751
+ }
72752
+ clipRangesToSheet(ranges) {
72753
+ const clippedRanges = [];
72754
+ for (const range of ranges) {
72755
+ const clippedRange = this.clipRangeToSheet(range);
72756
+ if (clippedRange) clippedRanges.push(clippedRange);
72757
+ }
72758
+ return clippedRanges;
72759
+ }
73013
72760
  createAdaptedRanges(ranges, offsetX, offsetY, sheetId) {
73014
72761
  return ranges.map((range) => {
73015
72762
  if (!isZoneValid(range.zone)) return range;
@@ -76243,6 +75990,8 @@ set(value) {
76243
75990
  this.range = new RangeAdapterPlugin(this.coreGetters);
76244
75991
  this.coreGetters.getRangeString = this.range.getRangeString.bind(this.range);
76245
75992
  this.coreGetters.getRangeFromSheetXC = this.range.getRangeFromSheetXC.bind(this.range);
75993
+ this.coreGetters.clipRangesToSheet = this.range.clipRangesToSheet.bind(this.range);
75994
+ this.coreGetters.clipRangeToSheet = this.range.clipRangeToSheet.bind(this.range);
76246
75995
  this.coreGetters.createAdaptedRanges = this.range.createAdaptedRanges.bind(this.range);
76247
75996
  this.coreGetters.getRangeData = this.range.getRangeData.bind(this.range);
76248
75997
  this.coreGetters.getRangeDataFromXc = this.range.getRangeDataFromXc.bind(this.range);
@@ -78205,6 +77954,306 @@ set(value) {
78205
77954
  //#region src/components/popover/popover_builders.ts
78206
77955
  cellPopoverRegistry.add("ErrorToolTip", ErrorToolTipPopoverBuilder).add("LinkCell", LinkCellPopoverBuilder).add("LinkEditor", LinkEditorPopoverBuilder).add("FilterMenu", FilterMenuPopoverBuilder);
78207
77956
 
77957
+ //#endregion
77958
+ //#region src/helpers/figures/charts/chart_data_sources.ts
77959
+ const EMPTY = Object.freeze({ value: null });
77960
+ const ONE = Object.freeze({ value: 1 });
77961
+ const ChartRangeDataSourceHandler = {
77962
+ supportedChartTypes: CHART_TYPES,
77963
+ fromExternalDefinition(dataSource, defaultSheetId, getters) {
77964
+ const dataSets = createDataSets(getters, defaultSheetId, dataSource);
77965
+ const labelRange = createValidRange(getters, defaultSheetId, dataSource.labelRange);
77966
+ return {
77967
+ ...dataSource,
77968
+ dataSets,
77969
+ labelRange
77970
+ };
77971
+ },
77972
+ fromContextCreation(context) {
77973
+ return {
77974
+ type: "range",
77975
+ dataSets: [],
77976
+ dataSetsHaveTitle: false,
77977
+ labelRange: context.auxiliaryRange,
77978
+ ...context.dataSource
77979
+ };
77980
+ },
77981
+ fromHierarchicalContextCreation(context) {
77982
+ if (context.dataSource?.type !== "range" || context.hierarchicalDataSource !== void 0 && context.hierarchicalDataSource.type !== "range") return {
77983
+ type: "range",
77984
+ dataSets: [],
77985
+ dataSetsHaveTitle: false
77986
+ };
77987
+ let dataSource = {
77988
+ type: "range",
77989
+ dataSets: [],
77990
+ dataSetsHaveTitle: context.dataSource?.dataSetsHaveTitle ?? false,
77991
+ labelRange: context.dataSource?.dataSets?.[0]?.dataRange
77992
+ };
77993
+ if (context.hierarchicalDataSource?.dataSets.length) dataSource = context.hierarchicalDataSource;
77994
+ else if (context.auxiliaryRange) dataSource = {
77995
+ ...dataSource,
77996
+ dataSets: [{
77997
+ dataRange: context.auxiliaryRange,
77998
+ dataSetId: "0"
77999
+ }]
78000
+ };
78001
+ return dataSource;
78002
+ },
78003
+ validate: (dataSource, validator) => validator.checkValidations(dataSource, checkDataset, checkLabelRange),
78004
+ transform(dataSource, defaultSheetId, { adaptRangeString }) {
78005
+ let labelRange;
78006
+ if (dataSource.labelRange) {
78007
+ const { changeType, range: adaptedRange } = adaptRangeString(defaultSheetId, dataSource.labelRange);
78008
+ if (changeType !== "REMOVE") labelRange = adaptedRange;
78009
+ }
78010
+ const dataSets = [];
78011
+ for (const dataSet of dataSource.dataSets) {
78012
+ const newDataSet = { ...dataSet };
78013
+ const { changeType, range: adaptedRange } = adaptRangeString(defaultSheetId, dataSet.dataRange);
78014
+ if (changeType !== "REMOVE") {
78015
+ newDataSet.dataRange = adaptedRange;
78016
+ dataSets.push(newDataSet);
78017
+ }
78018
+ }
78019
+ return {
78020
+ ...dataSource,
78021
+ dataSets,
78022
+ labelRange
78023
+ };
78024
+ },
78025
+ extractData: (dataSource, chartId, getters) => getChartData(getters, dataSource),
78026
+ extractHierarchicalData(dataSource, chartId, getters) {
78027
+ const dataSets = dataSource.dataSets;
78028
+ const labelRange = dataSource.labelRange;
78029
+ const labelValues = getChartLabelValues(getters, dataSets, labelRange);
78030
+ const dataSetsValues = getHierarchicalDatasetValues(getters, dataSets);
78031
+ const data = {
78032
+ labelValues,
78033
+ dataSetsValues
78034
+ };
78035
+ if (shouldRemoveFirstLabel(labelValues.length, dataSetsValues[0]?.data.length + (dataSetsValues[0]?.label !== void 0 ? 1 : 0), dataSource.dataSetsHaveTitle || false)) labelValues.shift();
78036
+ return data;
78037
+ },
78038
+ adaptRanges(dataSource, { applyChange }) {
78039
+ const dataSetsWithUndefined = dataSource.dataSets.map((ds) => {
78040
+ const { range: adaptedRangeStr, changeType } = applyChange(ds.dataRange);
78041
+ if (changeType === "REMOVE") return;
78042
+ let labelCell = void 0;
78043
+ if (ds.labelCell) {
78044
+ const { range: adaptedLabelCellRange, changeType: labelCellChangeType } = applyChange(ds.labelCell);
78045
+ if (labelCellChangeType !== "REMOVE") labelCell = adaptedLabelCellRange;
78046
+ }
78047
+ return {
78048
+ ...ds,
78049
+ dataRange: adaptedRangeStr,
78050
+ labelCell
78051
+ };
78052
+ }).filter(isDefined);
78053
+ let labelRange = dataSource.labelRange;
78054
+ if (labelRange) {
78055
+ const { range: adaptedLabelRange, changeType } = applyChange(labelRange);
78056
+ if (changeType === "REMOVE") labelRange = void 0;
78057
+ else labelRange = adaptedLabelRange;
78058
+ }
78059
+ const dataSets = dataSetsWithUndefined;
78060
+ return {
78061
+ ...dataSource,
78062
+ dataSets,
78063
+ labelRange: labelRange?.invalidSheetName || labelRange?.invalidXc ? void 0 : labelRange
78064
+ };
78065
+ },
78066
+ getDefinition(dataSource, defaultSheetId, getters) {
78067
+ return {
78068
+ labelRange: dataSource.labelRange ? getters.getRangeString(dataSource.labelRange, defaultSheetId) : void 0,
78069
+ type: "range",
78070
+ dataSets: dataSource.dataSets.map((dataSet) => ({
78071
+ dataSetId: dataSet.dataSetId,
78072
+ dataRange: getters.getRangeString(dataSet.dataRange, defaultSheetId)
78073
+ })),
78074
+ dataSetsHaveTitle: dataSource.dataSetsHaveTitle
78075
+ };
78076
+ },
78077
+ /**
78078
+ * Duplicate the dataSets. All ranges on sheetIdFrom are adapted to target
78079
+ * sheetIdTo.
78080
+ */
78081
+ duplicateInDuplicatedSheet(dataSource, sheetIdFrom, sheetIdTo, getters) {
78082
+ return {
78083
+ ...dataSource,
78084
+ labelRange: duplicateLabelRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, dataSource.labelRange),
78085
+ dataSets: dataSource.dataSets.map((ds) => ({
78086
+ ...ds,
78087
+ dataRange: duplicateRangeInDuplicatedSheet(sheetIdFrom, sheetIdTo, ds.dataRange)
78088
+ }))
78089
+ };
78090
+ },
78091
+ getContextCreation: (dataSource) => ({
78092
+ auxiliaryRange: dataSource.labelRange,
78093
+ dataSource
78094
+ }),
78095
+ getHierarchicalContextCreation(dataSource) {
78096
+ const leafRange = dataSource.dataSets.at(-1)?.dataRange;
78097
+ const dataSetsHaveTitle = dataSource.dataSetsHaveTitle;
78098
+ return {
78099
+ auxiliaryRange: leafRange,
78100
+ hierarchicalDataSource: dataSource,
78101
+ dataSource: dataSource.labelRange ? {
78102
+ type: "range",
78103
+ dataSets: [{
78104
+ dataRange: dataSource.labelRange,
78105
+ dataSetId: "0"
78106
+ }],
78107
+ dataSetsHaveTitle
78108
+ } : {
78109
+ type: "range",
78110
+ dataSets: [],
78111
+ dataSetsHaveTitle
78112
+ }
78113
+ };
78114
+ },
78115
+ toExcelDataSets(dataSource, dataSetStyles, getters) {
78116
+ const dataSets = dataSource.dataSets;
78117
+ const labelRange = dataSource.labelRange;
78118
+ const excelDataSets = dataSets.map((ds) => toExcelDataset(getters, dataSetStyles, ds)).filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
78119
+ const datasetLength = dataSets[0] ? getZoneArea(dataSets[0].dataRange.zone) : void 0;
78120
+ return {
78121
+ dataSets: excelDataSets,
78122
+ labelRange: toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel(labelRange ? getZoneArea(labelRange.zone) : 0, datasetLength, dataSource.dataSetsHaveTitle))
78123
+ };
78124
+ }
78125
+ };
78126
+ function getChartData(getters, dataSource) {
78127
+ const dataSets = dataSource.dataSets;
78128
+ const labelRange = dataSource.labelRange;
78129
+ const labelValues = getChartLabelValues(getters, dataSets, labelRange);
78130
+ const dataSetsValues = getChartDatasetValues(getters, dataSets);
78131
+ const data = {
78132
+ labelValues,
78133
+ dataSetsValues
78134
+ };
78135
+ const numberOfDataPoints = dataSetsValues.length ? dataSetsValues[0]?.data.length + (dataSetsValues[0]?.label !== void 0 ? 1 : 0) : 0;
78136
+ if (shouldRemoveFirstLabel(labelValues.length, numberOfDataPoints, dataSource.dataSetsHaveTitle || false)) labelValues.shift();
78137
+ return data;
78138
+ }
78139
+ function getChartDatasetValues(getters, dataSets) {
78140
+ const datasetValues = [];
78141
+ for (const [dsIndex, ds] of Object.entries(dataSets)) {
78142
+ let label = `${ChartTerms.Series} ${parseInt(dsIndex) + 1}`;
78143
+ let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
78144
+ if (ds.labelCell) {
78145
+ const { sheetId, zone } = ds.labelCell;
78146
+ const cell = getters.getEvaluatedCell({
78147
+ sheetId,
78148
+ col: zone.left,
78149
+ row: zone.top
78150
+ });
78151
+ if (cell) label = cell.formattedValue;
78152
+ }
78153
+ let data = ds.dataRange ? getData(getters, ds) : [];
78154
+ if (data.every((cell) => !cell.value || isTextResult(cell)) && data.filter(isTextResult).length > 1) data = data.map((cell) => cell.value && !isErrorResult(cell) ? ONE : EMPTY);
78155
+ else if (data.every((cell) => !isNumberResult(cell))) hidden = true;
78156
+ datasetValues.push({
78157
+ data,
78158
+ label,
78159
+ hidden,
78160
+ dataSetId: ds.dataSetId
78161
+ });
78162
+ }
78163
+ return datasetValues;
78164
+ }
78165
+ function getChartLabelValues(getters, dataSets, labelRange) {
78166
+ if (labelRange) {
78167
+ const { left } = labelRange.zone;
78168
+ if (!labelRange.invalidXc && !labelRange.invalidSheetName && !getters.isColHidden(labelRange.sheetId, left)) return getters.getVisibleRangeValues(labelRange);
78169
+ }
78170
+ if (dataSets[0]) {
78171
+ const dataLength = getData(getters, dataSets[0]).length;
78172
+ return Array.from({ length: dataLength }, () => ({ value: "" }));
78173
+ }
78174
+ return [];
78175
+ }
78176
+ /**
78177
+ * Get the values for a hierarchical dataset. The values can be defined in a tree-like structure
78178
+ * in the sheet, and this function will fill up the blanks.
78179
+ *
78180
+ * @example the following dataset:
78181
+ *
78182
+ * 2024 Q1 W1 100
78183
+ * W2 200
78184
+ *
78185
+ * will have the same value as the dataset:
78186
+ * 2024 Q1 W1 100
78187
+ * 2024 Q1 W2 200
78188
+ */
78189
+ function getHierarchicalDatasetValues(getters, dataSets) {
78190
+ dataSets = dataSets.filter((ds) => !getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left));
78191
+ const datasetValues = dataSets.map((ds) => ({
78192
+ data: [],
78193
+ label: "",
78194
+ dataSetId: ds.dataSetId
78195
+ }));
78196
+ const locale = getters.getLocale();
78197
+ const dataSetsData = dataSets.map((ds) => getData(getters, ds)).map((values) => values.map(({ value, format }) => value === null ? EMPTY : { value: formatValue(value, {
78198
+ format,
78199
+ locale
78200
+ }) }));
78201
+ if (!dataSetsData.length) return datasetValues;
78202
+ const minLength = Math.min(...dataSetsData.map((ds) => ds.length));
78203
+ let currentValues = [];
78204
+ const leafDatasetIndex = dataSets.length - 1;
78205
+ for (let i = 0; i < minLength; i++) for (let dsIndex = 0; dsIndex < dataSetsData.length; dsIndex++) {
78206
+ let cell = dataSetsData[dsIndex][i];
78207
+ if ((cell === void 0 || cell.value === null) && dsIndex !== leafDatasetIndex) cell = currentValues[dsIndex];
78208
+ if (cell?.value !== currentValues[dsIndex]?.value) {
78209
+ currentValues = currentValues.slice(0, dsIndex);
78210
+ currentValues[dsIndex] = cell;
78211
+ }
78212
+ datasetValues[dsIndex].data.push(cell ?? EMPTY);
78213
+ }
78214
+ return datasetValues.filter((ds) => ds.data.some((d) => d.value !== null));
78215
+ }
78216
+ /**
78217
+ * Get the data from a dataSet
78218
+ */
78219
+ function getData(getters, ds) {
78220
+ if (ds.dataRange) {
78221
+ const labelCellZone = ds.labelCell ? [ds.labelCell.zone] : [];
78222
+ const dataZone = recomputeZones([ds.dataRange.zone], labelCellZone)[0];
78223
+ if (dataZone === void 0) return [];
78224
+ const dataRange = getters.getRangeFromZone(ds.dataRange.sheetId, dataZone);
78225
+ return getters.getVisibleRangeValues(dataRange).map((cell) => cell.value === "" ? EMPTY : cell);
78226
+ }
78227
+ return [];
78228
+ }
78229
+ const ChartNeverDataSourceHandler = {
78230
+ supportedChartTypes: [],
78231
+ fromExternalDefinition: () => ({ type: "none" }),
78232
+ fromContextCreation: () => ({ type: "none" }),
78233
+ fromHierarchicalContextCreation: () => ({ type: "none" }),
78234
+ validate: () => "Success",
78235
+ transform: () => ({ type: "none" }),
78236
+ extractData: () => ({
78237
+ dataSetsValues: [],
78238
+ labelValues: []
78239
+ }),
78240
+ extractHierarchicalData: () => ({
78241
+ dataSetsValues: [],
78242
+ labelValues: []
78243
+ }),
78244
+ adaptRanges: (dataSource) => dataSource,
78245
+ getDefinition: (dataSource) => dataSource,
78246
+ duplicateInDuplicatedSheet: (dataSource) => dataSource,
78247
+ getContextCreation: () => ({}),
78248
+ getHierarchicalContextCreation: () => ({}),
78249
+ toExcelDataSets: () => ({
78250
+ dataSets: [],
78251
+ labelRange: void 0
78252
+ })
78253
+ };
78254
+ chartDataSourceRegistry.add("range", ChartRangeDataSourceHandler);
78255
+ chartDataSourceRegistry.add("none", ChartNeverDataSourceHandler);
78256
+
78208
78257
  //#endregion
78209
78258
  //#region src/registries/auto_completes/data_validation_auto_complete.ts
78210
78259
  autoCompleteProviders.add("dataValidation", {
@@ -79128,14 +79177,13 @@ set(value) {
79128
79177
  },
79129
79178
  getDefinitionForExcel(getters, definition, { dataSets, labelRange }) {
79130
79179
  if (definition.dataSource.type !== "range") return;
79131
- const chartData = getPyramidChartData(definition, getChartData(getters, definition.dataSource), getters);
79132
- const { dataSetsValues } = chartData;
79180
+ const { dataSetsValues } = getPyramidChartData(definition, getChartData(getters, definition.dataSource), getters);
79133
79181
  const maxValue = Math.max(...dataSetsValues.map((dataSet) => Math.max(...dataSet.data.map((cell) => isNumberResult(cell) ? Math.abs(cell.value) : -Infinity))));
79134
79182
  return {
79135
79183
  ...definition,
79136
79184
  horizontal: true,
79137
- backgroundColor: toXlsxHexColor(chartData.background || "#FFFFFF"),
79138
- fontColor: toXlsxHexColor(chartFontColor(chartData.background)),
79185
+ backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
79186
+ fontColor: toXlsxHexColor(chartFontColor(definition.background)),
79139
79187
  dataSets,
79140
79188
  labelRange,
79141
79189
  verticalAxis: getDefinedAxis(definition),
@@ -87790,8 +87838,8 @@ exports.stores = stores;
87790
87838
  exports.tokenColors = tokenColors;
87791
87839
  exports.tokenize = tokenize;
87792
87840
 
87793
- __info__.version = "19.4.10";
87794
- __info__.date = "2026-08-29T09:17:27.429Z";
87795
- __info__.hash = "d7a0f18";
87841
+ __info__.version = "19.4.12";
87842
+ __info__.date = "2026-09-10T05:38:01.898Z";
87843
+ __info__.hash = "cdb63b4";
87796
87844
 
87797
87845
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);