@odoo/o-spreadsheet 19.5.0-alpha.19 → 19.5.0-alpha.20
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 +230 -157
- package/dist/o_spreadsheet.css +49 -36
- package/dist/o_spreadsheet.esm.js +230 -157
- package/dist/o_spreadsheet.iife.js +230 -157
- package/dist/o_spreadsheet.min.iife.js +287 -287
- package/dist/o_spreadsheet.xml +14 -10
- package/dist/types/components/spreadsheet/spreadsheet.d.ts +1 -2
- package/dist/types/helpers/color.d.ts +1 -1
- package/dist/types/helpers/data_analysis.d.ts +4 -3
- package/dist/types/plugins/ui_plugin.d.ts +1 -4
- package/dist/types/types/chart/chart_suggestion.d.ts +2 -1
- package/dist/types/types/model.d.ts +0 -3
- package/dist/types/types/rendering.d.ts +18 -1
- 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 19.5.0-alpha.
|
|
6
|
-
* @date 2026-09-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.5.0-alpha.20
|
|
6
|
+
* @date 2026-09-16T08:02:11.430Z
|
|
7
|
+
* @hash 4784627
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function(exports, _odoo_owl) {
|
|
@@ -8830,7 +8830,7 @@ set(value) {
|
|
|
8830
8830
|
* stored in the theme so that, after the dark-mode CSS filter is applied, the
|
|
8831
8831
|
* desired color is actually shown.
|
|
8832
8832
|
*
|
|
8833
|
-
* This function computes
|
|
8833
|
+
* This function computes an approximate inverse of the DARK_MODE_FILTER chain.
|
|
8834
8834
|
*/
|
|
8835
8835
|
function adaptForDarkMode(displayedColor) {
|
|
8836
8836
|
const { r, g, b, a } = colorToRGBA(displayedColor);
|
|
@@ -9978,34 +9978,49 @@ set(value) {
|
|
|
9978
9978
|
const BACKGROUND_HEADER_COLOR = "#F8F9FA";
|
|
9979
9979
|
const BACKGROUND_HEADER_SELECTED_COLOR = "#E8EAED";
|
|
9980
9980
|
const BACKGROUND_HEADER_ACTIVE_COLOR = "#595959";
|
|
9981
|
+
function adaptColorsForDarkMode(colors) {
|
|
9982
|
+
return Object.fromEntries(Object.entries(colors).map(([key, color]) => [key, adaptForDarkMode(color)]));
|
|
9983
|
+
}
|
|
9984
|
+
const LIGHT_COLORS = {
|
|
9985
|
+
chartBackgroundColor: "#FFFFFF",
|
|
9986
|
+
gridBorderColor: "#CECFCF",
|
|
9987
|
+
gridBorderColorOnDefaultBackground: "#E2E3E3",
|
|
9988
|
+
headerBackgroundColor: BACKGROUND_HEADER_COLOR,
|
|
9989
|
+
headerActiveBackgroundColor: BACKGROUND_HEADER_ACTIVE_COLOR,
|
|
9990
|
+
headerSelectedBackgroundColor: BACKGROUND_HEADER_SELECTED_COLOR,
|
|
9991
|
+
headerTextColor: TEXT_HEADER_COLOR,
|
|
9992
|
+
headerBorderColor: HEADER_BORDER_COLOR,
|
|
9993
|
+
frozenPaneBorderColor: FROZEN_PANE_BORDER_COLOR,
|
|
9994
|
+
frozenPaneHeaderBorderColor: FROZEN_PANE_HEADER_BORDER_COLOR,
|
|
9995
|
+
singleCellSelectionBackgroundColor: "#D2E1FB44",
|
|
9996
|
+
multipleCellsSelectionBackgroundColor: "#ACC7FF44"
|
|
9997
|
+
};
|
|
9998
|
+
/** Every color defined explicitely in the dark theme is expected to be subject to color-inverter mask applied
|
|
9999
|
+
* through the css class `os-theme-dependant`. They are therefore pre-inverted for dark mode.
|
|
10000
|
+
* Note that according to `adaptForDarkMode` documentation, the resulting color will be an approximation of the pre-inverted color.
|
|
10001
|
+
*/
|
|
10002
|
+
const DARK_DISPLAYED_COLORS = {
|
|
10003
|
+
chartBackgroundColor: "#25262b",
|
|
10004
|
+
gridBorderColor: "#6B706F",
|
|
10005
|
+
gridBorderColorOnDefaultBackground: "#4F5254",
|
|
10006
|
+
headerBackgroundColor: "#262A36",
|
|
10007
|
+
headerActiveBackgroundColor: "#3A4052",
|
|
10008
|
+
headerSelectedBackgroundColor: "#4E566E",
|
|
10009
|
+
headerTextColor: "#A1A6B3",
|
|
10010
|
+
headerBorderColor: "#7A7F91",
|
|
10011
|
+
frozenPaneBorderColor: "#7A7F91",
|
|
10012
|
+
frozenPaneHeaderBorderColor: "#9FA5BD",
|
|
10013
|
+
singleCellSelectionBackgroundColor: "#696E8044",
|
|
10014
|
+
multipleCellsSelectionBackgroundColor: "#828AA044"
|
|
10015
|
+
};
|
|
9981
10016
|
const COLOR_THEMES = {
|
|
9982
10017
|
light: {
|
|
9983
10018
|
colorThemeName: "light",
|
|
9984
|
-
|
|
9985
|
-
gridBorderColor: "#CECFCF",
|
|
9986
|
-
headerBackgroundColor: BACKGROUND_HEADER_COLOR,
|
|
9987
|
-
headerActiveBackgroundColor: BACKGROUND_HEADER_ACTIVE_COLOR,
|
|
9988
|
-
headerSelectedBackgroundColor: BACKGROUND_HEADER_SELECTED_COLOR,
|
|
9989
|
-
headerTextColor: TEXT_HEADER_COLOR,
|
|
9990
|
-
headerBorderColor: HEADER_BORDER_COLOR,
|
|
9991
|
-
frozenPaneBorderColor: FROZEN_PANE_BORDER_COLOR,
|
|
9992
|
-
frozenPaneHeaderBorderColor: FROZEN_PANE_HEADER_BORDER_COLOR,
|
|
9993
|
-
singleCellSelectionBackgroundColor: "#F3F7FE",
|
|
9994
|
-
multipleCellsSelectionBackgroundColor: "#E9F0FF"
|
|
10019
|
+
...LIGHT_COLORS
|
|
9995
10020
|
},
|
|
9996
10021
|
dark: {
|
|
9997
10022
|
colorThemeName: "dark",
|
|
9998
|
-
|
|
9999
|
-
gridBorderColor: adaptForDarkMode("#6B706F"),
|
|
10000
|
-
headerBackgroundColor: adaptForDarkMode("#262A36"),
|
|
10001
|
-
headerActiveBackgroundColor: adaptForDarkMode("#3A4052"),
|
|
10002
|
-
headerSelectedBackgroundColor: adaptForDarkMode("#4E566E"),
|
|
10003
|
-
headerTextColor: adaptForDarkMode("#A1A6B3"),
|
|
10004
|
-
headerBorderColor: adaptForDarkMode("#7A7F91"),
|
|
10005
|
-
frozenPaneBorderColor: adaptForDarkMode("#7A7F91"),
|
|
10006
|
-
frozenPaneHeaderBorderColor: adaptForDarkMode("#9FA5BD"),
|
|
10007
|
-
singleCellSelectionBackgroundColor: adaptForDarkMode("#696E8044"),
|
|
10008
|
-
multipleCellsSelectionBackgroundColor: adaptForDarkMode("#828AA044")
|
|
10023
|
+
...adaptColorsForDarkMode(DARK_DISPLAYED_COLORS)
|
|
10009
10024
|
}
|
|
10010
10025
|
};
|
|
10011
10026
|
|
|
@@ -10231,7 +10246,7 @@ set(value) {
|
|
|
10231
10246
|
return axisID === "x1" || axisID === "xMovingAverage";
|
|
10232
10247
|
}
|
|
10233
10248
|
function getChartBackgroundColor({ background }, colorThemeName) {
|
|
10234
|
-
if (!background) return COLOR_THEMES[colorThemeName].
|
|
10249
|
+
if (!background) return COLOR_THEMES[colorThemeName].chartBackgroundColor;
|
|
10235
10250
|
return background;
|
|
10236
10251
|
}
|
|
10237
10252
|
|
|
@@ -14204,7 +14219,7 @@ set(value) {
|
|
|
14204
14219
|
const GAUGE_PADDING_BOTTOM = 20;
|
|
14205
14220
|
const GAUGE_LABELS_FONT_SIZE = 12;
|
|
14206
14221
|
const GAUGE_DEFAULT_VALUE_FONT_SIZE = 80;
|
|
14207
|
-
const GAUGE_BACKGROUND_COLOR = "#
|
|
14222
|
+
const GAUGE_BACKGROUND_COLOR = "#F8F8F8";
|
|
14208
14223
|
const GAUGE_INFLECTION_LABEL_BOTTOM_MARGIN = 6;
|
|
14209
14224
|
const GAUGE_TITLE_SECTION_HEIGHT = 25;
|
|
14210
14225
|
function drawGaugeChart(canvas, runtime, zoom = 1, dimensions, options) {
|
|
@@ -24539,8 +24554,8 @@ set(value) {
|
|
|
24539
24554
|
}
|
|
24540
24555
|
getBackgroundColor(cellStyle) {
|
|
24541
24556
|
const overlayColor = this.hoveredCellOverlayStore.overlayColors.get(this.props.position);
|
|
24542
|
-
if (overlayColor) return blendColors(cellStyle.fillColor
|
|
24543
|
-
return cellStyle.fillColor
|
|
24557
|
+
if (overlayColor) return cellStyle.fillColor ? blendColors(cellStyle.fillColor, overlayColor) : overlayColor;
|
|
24558
|
+
return cellStyle.fillColor;
|
|
24544
24559
|
}
|
|
24545
24560
|
};
|
|
24546
24561
|
|
|
@@ -28302,8 +28317,11 @@ set(value) {
|
|
|
28302
28317
|
drawGlobalBackground(renderingContext) {
|
|
28303
28318
|
const { ctx, viewports } = renderingContext;
|
|
28304
28319
|
const { width, height } = viewports.getSheetViewDimensionWithHeaders();
|
|
28305
|
-
|
|
28306
|
-
|
|
28320
|
+
const fillStyle = this.getBackgroundColor(renderingContext);
|
|
28321
|
+
if (fillStyle) {
|
|
28322
|
+
ctx.fillStyle = fillStyle;
|
|
28323
|
+
ctx.fillRect(0, 0, width + CANVAS_SHIFT, height + CANVAS_SHIFT);
|
|
28324
|
+
} else ctx.clearRect(0, 0, width + CANVAS_SHIFT, height + CANVAS_SHIFT);
|
|
28307
28325
|
}
|
|
28308
28326
|
drawBackground(renderingContext, boxes) {
|
|
28309
28327
|
const { ctx, thinLineWidth } = renderingContext;
|
|
@@ -28312,7 +28330,8 @@ set(value) {
|
|
|
28312
28330
|
if (areGridLinesVisible) {
|
|
28313
28331
|
const theme = this.getters.getSpreadsheetTheme();
|
|
28314
28332
|
const background = this.getBackgroundColor(renderingContext);
|
|
28315
|
-
ctx.strokeStyle = setColorAlpha(blendColors(theme.gridBorderColor + "aa", background + "50"), 1);
|
|
28333
|
+
if (background) ctx.strokeStyle = setColorAlpha(blendColors(theme.gridBorderColor + "aa", toHex(background) + "50"), 1);
|
|
28334
|
+
else ctx.strokeStyle = theme.gridBorderColorOnDefaultBackground;
|
|
28316
28335
|
ctx.lineWidth = thinLineWidth;
|
|
28317
28336
|
for (const box of boxes) {
|
|
28318
28337
|
if (box.style.hideGridLines) continue;
|
|
@@ -28322,9 +28341,11 @@ set(value) {
|
|
|
28322
28341
|
}
|
|
28323
28342
|
drawCellBackground(renderingContext, boxes) {
|
|
28324
28343
|
const { ctx } = renderingContext;
|
|
28344
|
+
const backgroundColor = this.getBackgroundColor(renderingContext);
|
|
28345
|
+
const background = backgroundColor ? toHex(backgroundColor) : void 0;
|
|
28325
28346
|
for (const box of boxes) {
|
|
28326
28347
|
const style = box.style;
|
|
28327
|
-
if (style.fillColor && toHex(style.fillColor) !==
|
|
28348
|
+
if (style.fillColor && toHex(style.fillColor) !== background) {
|
|
28328
28349
|
ctx.fillStyle = toHex(style.fillColor);
|
|
28329
28350
|
ctx.fillRect(box.x - CANVAS_SHIFT, box.y - CANVAS_SHIFT, box.width + CANVAS_SHIFT * 2, box.height + CANVAS_SHIFT * 2);
|
|
28330
28351
|
}
|
|
@@ -28338,7 +28359,8 @@ set(value) {
|
|
|
28338
28359
|
ctx.fillRect(box.x, y, width, height);
|
|
28339
28360
|
}
|
|
28340
28361
|
if (box.overlayColor) {
|
|
28341
|
-
|
|
28362
|
+
const backdrop = style.fillColor || this.getBackgroundColor(renderingContext);
|
|
28363
|
+
ctx.fillStyle = backdrop ? blendColors(backdrop, box.overlayColor) : box.overlayColor;
|
|
28342
28364
|
ctx.fillRect(box.x - CANVAS_SHIFT, box.y - CANVAS_SHIFT, box.width + CANVAS_SHIFT * 2, box.height + CANVAS_SHIFT * 2);
|
|
28343
28365
|
}
|
|
28344
28366
|
if (box?.chip) {
|
|
@@ -28366,6 +28388,7 @@ set(value) {
|
|
|
28366
28388
|
}
|
|
28367
28389
|
drawOverflowingCellBackground(renderingContext, boxes) {
|
|
28368
28390
|
const { ctx, thinLineWidth } = renderingContext;
|
|
28391
|
+
const background = this.getBackgroundColor(renderingContext);
|
|
28369
28392
|
for (const box of boxes) if (box.content && box.isOverflow) {
|
|
28370
28393
|
const align = box.content.align || "left";
|
|
28371
28394
|
let x;
|
|
@@ -28383,8 +28406,10 @@ set(value) {
|
|
|
28383
28406
|
x = (box.clipRect?.x || box.x + box.width / 2 - box.content.width / 2) + thinLineWidth / 2;
|
|
28384
28407
|
width = clipWidth - 2 * thinLineWidth;
|
|
28385
28408
|
}
|
|
28386
|
-
|
|
28387
|
-
|
|
28409
|
+
if (background) {
|
|
28410
|
+
ctx.fillStyle = background;
|
|
28411
|
+
ctx.fillRect(x, y, width, height);
|
|
28412
|
+
} else ctx.clearRect(x, y, width, height);
|
|
28388
28413
|
}
|
|
28389
28414
|
}
|
|
28390
28415
|
drawBorders(renderingContext, boxes) {
|
|
@@ -28554,7 +28579,7 @@ set(value) {
|
|
|
28554
28579
|
ctx.textBaseline = "middle";
|
|
28555
28580
|
ctx.lineWidth = thinLineWidth;
|
|
28556
28581
|
ctx.strokeStyle = theme.headerTextColor;
|
|
28557
|
-
ctx.fillStyle =
|
|
28582
|
+
ctx.fillStyle = theme.headerBackgroundColor;
|
|
28558
28583
|
ctx.fillRect(0, 0, 48, height);
|
|
28559
28584
|
ctx.fillRect(0, 0, width, 26);
|
|
28560
28585
|
for (const col of visibleCols) {
|
|
@@ -29003,7 +29028,7 @@ set(value) {
|
|
|
29003
29028
|
}
|
|
29004
29029
|
}
|
|
29005
29030
|
getBackgroundColor(renderingContext) {
|
|
29006
|
-
return this.getters.getSheet(renderingContext.sheetId).backgroundColor
|
|
29031
|
+
return this.getters.getSheet(renderingContext.sheetId).backgroundColor;
|
|
29007
29032
|
}
|
|
29008
29033
|
};
|
|
29009
29034
|
|
|
@@ -29016,7 +29041,7 @@ set(value) {
|
|
|
29016
29041
|
function drawGrid() {
|
|
29017
29042
|
const canvas = canvasRef();
|
|
29018
29043
|
if (!canvas) return;
|
|
29019
|
-
const ctx = canvas.getContext("2d", { alpha:
|
|
29044
|
+
const ctx = canvas.getContext("2d", { alpha: true });
|
|
29020
29045
|
const renderingContext = {
|
|
29021
29046
|
ctx,
|
|
29022
29047
|
thinLineWidth: .4,
|
|
@@ -29259,7 +29284,7 @@ set(value) {
|
|
|
29259
29284
|
viewports: this.viewStore.viewports,
|
|
29260
29285
|
hideGridLines: this.getters.isDashboard(),
|
|
29261
29286
|
hideFrozenPaneBorder: true,
|
|
29262
|
-
dpr: 1,
|
|
29287
|
+
dpr: window.devicePixelRatio || 1,
|
|
29263
29288
|
selectedZones: [],
|
|
29264
29289
|
activeCols: /* @__PURE__ */ new Set(),
|
|
29265
29290
|
activeRows: /* @__PURE__ */ new Set(),
|
|
@@ -29821,7 +29846,7 @@ set(value) {
|
|
|
29821
29846
|
}
|
|
29822
29847
|
get carouselStyle() {
|
|
29823
29848
|
const cssProperties = {};
|
|
29824
|
-
const backgroundColor = this.env.model.getters.getSpreadsheetTheme().
|
|
29849
|
+
const backgroundColor = this.env.model.getters.getSpreadsheetTheme().chartBackgroundColor;
|
|
29825
29850
|
if (this.selectedCarouselItem?.type === "chart") {
|
|
29826
29851
|
const chart = this.env.model.getters.getChartRuntime(this.selectedCarouselItem.chartId);
|
|
29827
29852
|
if ("background" in chart && chart.background) cssProperties["background-color"] = chart.background;
|
|
@@ -42778,7 +42803,7 @@ set(value) {
|
|
|
42778
42803
|
if (!cells.length) return {
|
|
42779
42804
|
zone,
|
|
42780
42805
|
type: "empty",
|
|
42781
|
-
|
|
42806
|
+
headerInZone: false,
|
|
42782
42807
|
rowCount: 0,
|
|
42783
42808
|
uniqueCount: 0,
|
|
42784
42809
|
uniqueRatio: 0,
|
|
@@ -42786,16 +42811,34 @@ set(value) {
|
|
|
42786
42811
|
};
|
|
42787
42812
|
const firstCell = cells[0];
|
|
42788
42813
|
const rest = cells.slice(1);
|
|
42789
|
-
|
|
42790
|
-
|
|
42814
|
+
let title;
|
|
42815
|
+
let dataCells = [];
|
|
42816
|
+
let headerInZone = false;
|
|
42817
|
+
let analyzedZone = zone;
|
|
42818
|
+
const tableHeaderPosition = getColumnTableHeaderPosition(sheetId, zone, getters);
|
|
42819
|
+
if (tableHeaderPosition) {
|
|
42820
|
+
title = getters.getCellText(tableHeaderPosition) || void 0;
|
|
42821
|
+
dataCells = cells.filter((c) => c.position && c.position.row > tableHeaderPosition.row);
|
|
42822
|
+
headerInZone = !!title && tableHeaderPosition.row >= zone.top && tableHeaderPosition.row <= zone.bottom;
|
|
42823
|
+
if (headerInZone) analyzedZone = {
|
|
42824
|
+
top: tableHeaderPosition.row,
|
|
42825
|
+
bottom: zone.bottom,
|
|
42826
|
+
left: zone.left,
|
|
42827
|
+
right: zone.right
|
|
42828
|
+
};
|
|
42829
|
+
} else if (firstCell.type === "text" && rest.some((c) => c.type !== "text")) {
|
|
42830
|
+
title = firstCell.value;
|
|
42831
|
+
dataCells = rest;
|
|
42832
|
+
headerInZone = true;
|
|
42833
|
+
} else dataCells = cells;
|
|
42791
42834
|
const numericValues = dataCells.filter((c) => c.type === "number").map((c) => c.value);
|
|
42792
42835
|
const allVals = dataCells.map((c) => String(c.value ?? ""));
|
|
42793
42836
|
const uniqueCount = new Set(allVals).size;
|
|
42794
42837
|
return {
|
|
42795
|
-
zone,
|
|
42838
|
+
zone: analyzedZone,
|
|
42796
42839
|
type: computeColumnType(dataCells),
|
|
42797
|
-
|
|
42798
|
-
|
|
42840
|
+
title,
|
|
42841
|
+
headerInZone,
|
|
42799
42842
|
rowCount: dataCells.length,
|
|
42800
42843
|
uniqueCount,
|
|
42801
42844
|
uniqueRatio: allVals.length > 0 ? uniqueCount / allVals.length : 0,
|
|
@@ -42821,6 +42864,33 @@ set(value) {
|
|
|
42821
42864
|
}
|
|
42822
42865
|
return "empty";
|
|
42823
42866
|
}
|
|
42867
|
+
function getColumnTableHeaderPosition(sheetId, zone, getters) {
|
|
42868
|
+
if (zone.left !== zone.right) return;
|
|
42869
|
+
const tables = getters.getTablesOverlappingZones(sheetId, [zone]);
|
|
42870
|
+
if (tables.length !== 1) return;
|
|
42871
|
+
const table = tables[0];
|
|
42872
|
+
const firstCell = {
|
|
42873
|
+
sheetId,
|
|
42874
|
+
col: zone.left,
|
|
42875
|
+
row: zone.top
|
|
42876
|
+
};
|
|
42877
|
+
const lastCell = {
|
|
42878
|
+
sheetId,
|
|
42879
|
+
col: zone.left,
|
|
42880
|
+
row: zone.bottom
|
|
42881
|
+
};
|
|
42882
|
+
if (firstCell.row < table.range.zone.top || lastCell.row > table.range.zone.bottom) {
|
|
42883
|
+
const cells = getters.getEvaluatedCellsInZone(sheetId, zone).filter((c) => c.type !== "empty");
|
|
42884
|
+
for (const cell of cells) if (cell.position && !isInside(cell.position.col, cell.position.row, table.range.zone)) return;
|
|
42885
|
+
}
|
|
42886
|
+
const numberOfHeaders = table.config.numberOfHeaders;
|
|
42887
|
+
if (numberOfHeaders === 0) return;
|
|
42888
|
+
return {
|
|
42889
|
+
sheetId,
|
|
42890
|
+
col: zone.left,
|
|
42891
|
+
row: table.range.zone.top + numberOfHeaders - 1
|
|
42892
|
+
};
|
|
42893
|
+
}
|
|
42824
42894
|
|
|
42825
42895
|
//#endregion
|
|
42826
42896
|
//#region src/helpers/figures/charts/charts_suggestions_constants.ts
|
|
@@ -43065,6 +43135,10 @@ set(value) {
|
|
|
43065
43135
|
description: _t("Shows the last date value."),
|
|
43066
43136
|
isApplicable: ({ rowCount }) => rowCount === 1,
|
|
43067
43137
|
build: (ctx) => scorecardChart(ctx.title, `=${ctx.lastCellXC}`)
|
|
43138
|
+
}, {
|
|
43139
|
+
description: _t("Shows occurrences for each time slot."),
|
|
43140
|
+
isApplicable: ({ rowCount }) => rowCount > 1,
|
|
43141
|
+
build: (ctx) => calendarChart(ctx.title, ctx.source)
|
|
43068
43142
|
}];
|
|
43069
43143
|
/** Pattern D — Single categorical column */
|
|
43070
43144
|
const SINGLE_CATEGORICAL_COLUMN_SUGGESTIONS = [
|
|
@@ -43375,7 +43449,7 @@ set(value) {
|
|
|
43375
43449
|
isApplicable: ({ numColsCount }) => numColsCount === 3,
|
|
43376
43450
|
build: (ctx) => {
|
|
43377
43451
|
const bubble = ctx.bubble;
|
|
43378
|
-
return bubbleChart(ctx.title, bubble.xRange, bubble.yRanges, bubble.sizeRange, bubble.labelRange, bubble.
|
|
43452
|
+
return bubbleChart(ctx.title, bubble.xRange, bubble.yRanges, bubble.sizeRange, bubble.labelRange, bubble.headerInZone);
|
|
43379
43453
|
}
|
|
43380
43454
|
}
|
|
43381
43455
|
];
|
|
@@ -43472,8 +43546,8 @@ set(value) {
|
|
|
43472
43546
|
});
|
|
43473
43547
|
}
|
|
43474
43548
|
function isPyramidLike(numCol1, numCol2) {
|
|
43475
|
-
const h1 = numCol1.
|
|
43476
|
-
const h2 = numCol2.
|
|
43549
|
+
const h1 = numCol1.title ?? "";
|
|
43550
|
+
const h2 = numCol2.title ?? "";
|
|
43477
43551
|
return PYRAMID_HEADER_KEYWORD_PATTERNS.some((re) => re.test(h1) || re.test(h2));
|
|
43478
43552
|
}
|
|
43479
43553
|
/** Returns the first and last cell XC coordinates, and the second-to-last cell XC coordinate if it exists. */
|
|
@@ -43494,25 +43568,26 @@ set(value) {
|
|
|
43494
43568
|
prevCellXC: prevCellPosition ? toXC(prevCellPosition?.col, prevCellPosition?.row) : void 0
|
|
43495
43569
|
};
|
|
43496
43570
|
}
|
|
43497
|
-
function getCategoryHeader(getters, catCol) {
|
|
43498
|
-
|
|
43499
|
-
if (
|
|
43571
|
+
function getCategoryHeader(getters, catCol, headerInZone) {
|
|
43572
|
+
if (catCol.title) return catCol.title;
|
|
43573
|
+
if (headerInZone && catCol.rowCount > 0) {
|
|
43500
43574
|
const { left, top } = catCol.zone;
|
|
43501
|
-
|
|
43575
|
+
const cellValue = getters.getEvaluatedCell({
|
|
43502
43576
|
sheetId: getters.getActiveSheetId(),
|
|
43503
43577
|
col: left,
|
|
43504
43578
|
row: top
|
|
43505
|
-
})?.value
|
|
43579
|
+
})?.value;
|
|
43580
|
+
if (cellValue) return cellValue.toString();
|
|
43506
43581
|
}
|
|
43507
|
-
return
|
|
43582
|
+
return _t("Category");
|
|
43508
43583
|
}
|
|
43509
43584
|
/** Pattern A — Single numeric column */
|
|
43510
43585
|
function buildSingleNumberContext([col], getters) {
|
|
43511
|
-
const title = col.
|
|
43586
|
+
const title = col.title ?? "";
|
|
43512
43587
|
const { firstCellXC, lastCellXC, prevCellXC } = interestingCellsXc(col);
|
|
43513
43588
|
return {
|
|
43514
43589
|
title,
|
|
43515
|
-
source: rangeSource([dataset(col.zone, getters)], col.
|
|
43590
|
+
source: rangeSource([dataset(col.zone, getters)], col.headerInZone),
|
|
43516
43591
|
rowCount: col.rowCount,
|
|
43517
43592
|
firstCellXC,
|
|
43518
43593
|
lastCellXC,
|
|
@@ -43521,10 +43596,9 @@ set(value) {
|
|
|
43521
43596
|
}
|
|
43522
43597
|
/** Pattern B — Single percentage column */
|
|
43523
43598
|
function buildSinglePercentageContext([col], getters) {
|
|
43524
|
-
const
|
|
43525
|
-
const title = col.header ?? "";
|
|
43599
|
+
const title = col.title ?? "";
|
|
43526
43600
|
const { firstCellXC, lastCellXC, prevCellXC } = interestingCellsXc(col);
|
|
43527
|
-
const source = rangeSource([dataset(col.zone, getters)],
|
|
43601
|
+
const source = rangeSource([dataset(col.zone, getters)], col.headerInZone);
|
|
43528
43602
|
const isAboveOne = (col.maxValue ?? 0) > 1;
|
|
43529
43603
|
return {
|
|
43530
43604
|
title,
|
|
@@ -43537,22 +43611,24 @@ set(value) {
|
|
|
43537
43611
|
};
|
|
43538
43612
|
}
|
|
43539
43613
|
/** Pattern C — Single date column */
|
|
43540
|
-
function buildSingleDateContext([col]) {
|
|
43614
|
+
function buildSingleDateContext([col], getters) {
|
|
43541
43615
|
const { lastCellXC } = interestingCellsXc(col);
|
|
43616
|
+
const labelRange = getUnboundRange(getters, col.zone);
|
|
43617
|
+
const source = rangeSource([dataset(col.zone, getters)], col.headerInZone, labelRange);
|
|
43542
43618
|
return {
|
|
43543
|
-
title: col.
|
|
43619
|
+
title: col.title ?? "",
|
|
43544
43620
|
lastCellXC,
|
|
43545
|
-
rowCount: col.rowCount
|
|
43621
|
+
rowCount: col.rowCount,
|
|
43622
|
+
source
|
|
43546
43623
|
};
|
|
43547
43624
|
}
|
|
43548
43625
|
/** Pattern D — Single categorical column */
|
|
43549
43626
|
function buildSingleCategoricalContext([col], getters) {
|
|
43550
|
-
const
|
|
43551
|
-
const title = col.header ?? "";
|
|
43627
|
+
const title = col.title ?? "";
|
|
43552
43628
|
const range = getUnboundRange(getters, col.zone);
|
|
43553
43629
|
return {
|
|
43554
43630
|
title,
|
|
43555
|
-
source: rangeSource([dataset(col.zone, getters)],
|
|
43631
|
+
source: rangeSource([dataset(col.zone, getters)], col.headerInZone, range),
|
|
43556
43632
|
range
|
|
43557
43633
|
};
|
|
43558
43634
|
}
|
|
@@ -43560,7 +43636,7 @@ set(value) {
|
|
|
43560
43636
|
function buildSingleLabelContext([col]) {
|
|
43561
43637
|
const { lastCellXC } = interestingCellsXc(col);
|
|
43562
43638
|
return {
|
|
43563
|
-
title: "",
|
|
43639
|
+
title: col.title ?? "",
|
|
43564
43640
|
lastCellXC,
|
|
43565
43641
|
rowCount: col.rowCount
|
|
43566
43642
|
};
|
|
@@ -43568,37 +43644,37 @@ set(value) {
|
|
|
43568
43644
|
/** Pattern F — Categorical + Number */
|
|
43569
43645
|
function buildCategoricalVsNumberContext([catCol, numCol], getters) {
|
|
43570
43646
|
const labelRange = getUnboundRange(getters, catCol.zone);
|
|
43571
|
-
const
|
|
43572
|
-
const categoryHeader =
|
|
43647
|
+
const headerInZone = numCol.headerInZone;
|
|
43648
|
+
const categoryHeader = getCategoryHeader(getters, catCol, headerInZone);
|
|
43573
43649
|
return {
|
|
43574
|
-
title: numCol.
|
|
43575
|
-
numberHeader: numCol.
|
|
43650
|
+
title: numCol.title ? _t("%(numberHeader)s by %(categoryHeader)s", {
|
|
43651
|
+
numberHeader: numCol.title,
|
|
43576
43652
|
categoryHeader
|
|
43577
43653
|
}) : "",
|
|
43578
|
-
source: rangeSource([dataset(numCol.zone, getters)],
|
|
43579
|
-
treemapSource: rangeSource([dataset(catCol.zone, getters)],
|
|
43654
|
+
source: rangeSource([dataset(numCol.zone, getters)], headerInZone, labelRange),
|
|
43655
|
+
treemapSource: rangeSource([dataset(catCol.zone, getters)], headerInZone, getUnboundRange(getters, numCol.zone))
|
|
43580
43656
|
};
|
|
43581
43657
|
}
|
|
43582
43658
|
/** Patterns G & J — Date + Number or Date + Percentage */
|
|
43583
43659
|
function buildDateVsSeriesContext([dateCol, seriesCol], getters) {
|
|
43584
43660
|
const isPercentage = seriesCol.type === "percentage";
|
|
43585
43661
|
const labelRange = getUnboundRange(getters, dateCol.zone);
|
|
43586
|
-
const
|
|
43662
|
+
const headerInZone = isDatasetTitled(getters, dateCol.zone);
|
|
43587
43663
|
return {
|
|
43588
|
-
title: seriesCol.
|
|
43589
|
-
source: rangeSource([dataset(seriesCol.zone, getters)],
|
|
43664
|
+
title: seriesCol.title ? _t("%(seriesHeader)s over time", { seriesHeader: seriesCol.title }) : "",
|
|
43665
|
+
source: rangeSource([dataset(seriesCol.zone, getters)], headerInZone, labelRange),
|
|
43590
43666
|
isPercentage
|
|
43591
43667
|
};
|
|
43592
43668
|
}
|
|
43593
43669
|
/** Pattern H — Number + Number */
|
|
43594
43670
|
function buildNumberVsNumberContext([col1, col2], getters) {
|
|
43595
|
-
const title = col1.
|
|
43596
|
-
col2Header: col2.
|
|
43597
|
-
col1Header: col1.
|
|
43671
|
+
const title = col1.title && col2.title ? _t("%(col2Header)s vs %(col1Header)s", {
|
|
43672
|
+
col2Header: col2.title,
|
|
43673
|
+
col1Header: col1.title
|
|
43598
43674
|
}) : "";
|
|
43599
|
-
const
|
|
43600
|
-
const source2 = rangeSource([dataset(col2.zone, getters)], col2.
|
|
43601
|
-
const sourceBoth = rangeSource([dataset(col1.zone, getters, "0"), dataset(col2.zone, getters, "1")],
|
|
43675
|
+
const headerInZone = col1.headerInZone || col2.headerInZone;
|
|
43676
|
+
const source2 = rangeSource([dataset(col2.zone, getters)], col2.headerInZone, getUnboundRange(getters, col1.zone));
|
|
43677
|
+
const sourceBoth = rangeSource([dataset(col1.zone, getters, "0"), dataset(col2.zone, getters, "1")], headerInZone);
|
|
43602
43678
|
const { lastCellXC } = interestingCellsXc(col2);
|
|
43603
43679
|
const { lastCellXC: prevCellXC } = interestingCellsXc(col1);
|
|
43604
43680
|
return {
|
|
@@ -43614,26 +43690,25 @@ set(value) {
|
|
|
43614
43690
|
/** Pattern I — Categorical + Percentage */
|
|
43615
43691
|
function buildCategoricalVsPercentageContext([catCol, pctCol], getters) {
|
|
43616
43692
|
const labelRange = getUnboundRange(getters, catCol.zone);
|
|
43617
|
-
const
|
|
43618
|
-
const categoryHeader =
|
|
43693
|
+
const headerInZone = pctCol.headerInZone;
|
|
43694
|
+
const categoryHeader = getCategoryHeader(getters, catCol, headerInZone);
|
|
43619
43695
|
return {
|
|
43620
|
-
title: pctCol.
|
|
43621
|
-
percentageHeader: pctCol.
|
|
43696
|
+
title: pctCol.title ? _t("%(percentageHeader)s by %(categoryHeader)s", {
|
|
43697
|
+
percentageHeader: pctCol.title,
|
|
43622
43698
|
categoryHeader
|
|
43623
43699
|
}) : "",
|
|
43624
|
-
source: rangeSource([dataset(pctCol.zone, getters)],
|
|
43700
|
+
source: rangeSource([dataset(pctCol.zone, getters)], headerInZone, labelRange),
|
|
43625
43701
|
rowCount: catCol.rowCount
|
|
43626
43702
|
};
|
|
43627
43703
|
}
|
|
43628
43704
|
/** Pattern K — Label + Number */
|
|
43629
43705
|
function buildLabelVsNumberContext([labelCol, numCol], getters) {
|
|
43630
43706
|
const labelRange = getUnboundRange(getters, labelCol.zone);
|
|
43631
|
-
const
|
|
43632
|
-
|
|
43633
|
-
|
|
43634
|
-
labelHeader: labelCol.header ?? _t("Name")
|
|
43707
|
+
const title = numCol.title ? _t("%(numberHeader)s by %(labelHeader)s", {
|
|
43708
|
+
numberHeader: numCol.title,
|
|
43709
|
+
labelHeader: labelCol.title ?? _t("Name")
|
|
43635
43710
|
}) : "";
|
|
43636
|
-
const source = rangeSource([dataset(numCol.zone, getters)],
|
|
43711
|
+
const source = rangeSource([dataset(numCol.zone, getters)], numCol.headerInZone, labelRange);
|
|
43637
43712
|
const { lastCellXC } = interestingCellsXc(numCol);
|
|
43638
43713
|
const { lastCellXC: prevCellXC } = interestingCellsXc(labelCol);
|
|
43639
43714
|
return {
|
|
@@ -43647,66 +43722,66 @@ set(value) {
|
|
|
43647
43722
|
/** Pattern M — Categorical + Multiple Numbers */
|
|
43648
43723
|
function buildCategoricalVsMultipleNumbersContext([catCol, ...numCols], getters) {
|
|
43649
43724
|
const labelRange = getUnboundRange(getters, catCol.zone);
|
|
43650
|
-
const
|
|
43651
|
-
const categoryHeader =
|
|
43725
|
+
const headerInZone = numCols.some((c) => c.headerInZone);
|
|
43726
|
+
const categoryHeader = getCategoryHeader(getters, catCol, headerInZone);
|
|
43652
43727
|
return {
|
|
43653
|
-
title:
|
|
43654
|
-
source: rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))),
|
|
43728
|
+
title: headerInZone ? _t("Multi-series By %(categoryHeader)s", { categoryHeader }) : "",
|
|
43729
|
+
source: rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), headerInZone, labelRange),
|
|
43655
43730
|
rowCount: catCol.rowCount
|
|
43656
43731
|
};
|
|
43657
43732
|
}
|
|
43658
43733
|
/** Pattern N — Date + Multiple Numbers */
|
|
43659
43734
|
function buildDateVsMultipleNumbersContext([dateCol, ...numCols], getters) {
|
|
43660
43735
|
const labelRange = getUnboundRange(getters, dateCol.zone);
|
|
43661
|
-
const
|
|
43736
|
+
const headerInZone = numCols.some((c) => c.headerInZone) || isDatasetTitled(getters, dateCol.zone);
|
|
43662
43737
|
return {
|
|
43663
|
-
title: numCols.length === 1 && numCols[0].
|
|
43664
|
-
source: rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))),
|
|
43738
|
+
title: numCols.length === 1 && numCols[0].title ? _t("%(header)s over time", { header: numCols[0].title }) : "",
|
|
43739
|
+
source: rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), headerInZone, labelRange)
|
|
43665
43740
|
};
|
|
43666
43741
|
}
|
|
43667
43742
|
/** Pattern O — Categorical + Categorical + Number */
|
|
43668
43743
|
function buildMultipleCategoricalsVsNumberContext([cat1, cat2, numCol], getters) {
|
|
43669
|
-
const title = numCol.
|
|
43670
|
-
numHeader: numCol.
|
|
43671
|
-
cat1Header: cat1.
|
|
43672
|
-
cat2Header: cat2.
|
|
43744
|
+
const title = numCol.title ? _t("%(numHeader)s by %(cat1Header)s and %(cat2Header)s", {
|
|
43745
|
+
numHeader: numCol.title,
|
|
43746
|
+
cat1Header: cat1.title ?? _t("Level 1"),
|
|
43747
|
+
cat2Header: cat2.title ?? _t("Level 2")
|
|
43673
43748
|
}) : "";
|
|
43674
|
-
const
|
|
43749
|
+
const headerInZone = numCol.headerInZone;
|
|
43675
43750
|
return {
|
|
43676
43751
|
title,
|
|
43677
|
-
hierarchySource: rangeSource([dataset(cat1.zone, getters, "0"), dataset(cat2.zone, getters, "1")],
|
|
43678
|
-
barSource: rangeSource([dataset(numCol.zone, getters)],
|
|
43752
|
+
hierarchySource: rangeSource([dataset(cat1.zone, getters, "0"), dataset(cat2.zone, getters, "1")], headerInZone, getUnboundRange(getters, numCol.zone)),
|
|
43753
|
+
barSource: rangeSource([dataset(numCol.zone, getters)], headerInZone, getUnboundRange(getters, cat1.zone))
|
|
43679
43754
|
};
|
|
43680
43755
|
}
|
|
43681
43756
|
/** Pattern P — Categorical + Date + Number */
|
|
43682
43757
|
function buildCategoricalDateNumberContext([catCol, dateCol, numCol], getters) {
|
|
43683
43758
|
const dateRange = getUnboundRange(getters, dateCol.zone);
|
|
43684
43759
|
const catRange = getUnboundRange(getters, catCol.zone);
|
|
43685
|
-
const
|
|
43686
|
-
const catHeader =
|
|
43760
|
+
const headerInZone = numCol.headerInZone;
|
|
43761
|
+
const catHeader = getCategoryHeader(getters, catCol, headerInZone);
|
|
43687
43762
|
return {
|
|
43688
|
-
title: numCol.
|
|
43689
|
-
numHeader: numCol.
|
|
43763
|
+
title: numCol.title ? _t("%(numHeader)s by %(catHeader)s over %(dateHeader)s", {
|
|
43764
|
+
numHeader: numCol.title,
|
|
43690
43765
|
catHeader,
|
|
43691
|
-
dateHeader: dateCol.
|
|
43766
|
+
dateHeader: dateCol.title ?? _t("Time")
|
|
43692
43767
|
}) : "",
|
|
43693
|
-
sourceByDate: rangeSource([dataset(numCol.zone, getters)],
|
|
43694
|
-
sourceByCat: rangeSource([dataset(numCol.zone, getters)],
|
|
43768
|
+
sourceByDate: rangeSource([dataset(numCol.zone, getters)], headerInZone, dateRange),
|
|
43769
|
+
sourceByCat: rangeSource([dataset(numCol.zone, getters)], headerInZone, catRange)
|
|
43695
43770
|
};
|
|
43696
43771
|
}
|
|
43697
43772
|
/** Pattern Q — Label + Multiple Numbers */
|
|
43698
43773
|
function buildLabelVsMultipleNumbersContext([labelCol, ...numCols], getters) {
|
|
43699
43774
|
const labelRange = getUnboundRange(getters, labelCol.zone);
|
|
43700
|
-
const
|
|
43701
|
-
const title = labelCol.
|
|
43702
|
-
const source = rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))),
|
|
43703
|
-
const scatterSource = rangeSource([dataset(numCols[1].zone, getters)], numCols[1].
|
|
43775
|
+
const headerInZone = numCols.some((c) => c.headerInZone);
|
|
43776
|
+
const title = labelCol.title ? _t("By %(title)s", { title: labelCol.title }) : "";
|
|
43777
|
+
const source = rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), headerInZone, labelRange);
|
|
43778
|
+
const scatterSource = rangeSource([dataset(numCols[1].zone, getters)], numCols[1].headerInZone, getUnboundRange(getters, numCols[0].zone));
|
|
43704
43779
|
const bubble = numCols.length === 3 ? {
|
|
43705
43780
|
xRange: getUnboundRange(getters, numCols[0].zone),
|
|
43706
43781
|
yRanges: [getUnboundRange(getters, numCols[1].zone)],
|
|
43707
43782
|
sizeRange: getUnboundRange(getters, numCols[2].zone),
|
|
43708
43783
|
labelRange,
|
|
43709
|
-
|
|
43784
|
+
headerInZone
|
|
43710
43785
|
} : void 0;
|
|
43711
43786
|
return {
|
|
43712
43787
|
title,
|
|
@@ -43720,25 +43795,25 @@ set(value) {
|
|
|
43720
43795
|
/** Pattern R — Categorical + Two Numbers (Population Pyramid or Grouped) */
|
|
43721
43796
|
function buildCategoricalTwoNumbersContext([catCol, numCol1, numCol2], getters) {
|
|
43722
43797
|
const catRange = getUnboundRange(getters, catCol.zone);
|
|
43723
|
-
const
|
|
43724
|
-
const catHeader =
|
|
43725
|
-
const title = numCol1.
|
|
43726
|
-
num1Header: numCol1.
|
|
43727
|
-
num2Header: numCol2.
|
|
43798
|
+
const headerInZone = numCol1.headerInZone || numCol2.headerInZone;
|
|
43799
|
+
const catHeader = getCategoryHeader(getters, catCol, headerInZone);
|
|
43800
|
+
const title = numCol1.title && numCol2.title ? _t("%(num1Header)s vs %(num2Header)s by %(catHeader)s", {
|
|
43801
|
+
num1Header: numCol1.title,
|
|
43802
|
+
num2Header: numCol2.title,
|
|
43728
43803
|
catHeader
|
|
43729
43804
|
}) : "";
|
|
43730
43805
|
const isPyramid = isPyramidLike(numCol1, numCol2);
|
|
43731
43806
|
return {
|
|
43732
43807
|
title,
|
|
43733
|
-
sourceBoth: rangeSource([dataset(numCol1.zone, getters, "0"), dataset(numCol2.zone, getters, "1")],
|
|
43808
|
+
sourceBoth: rangeSource([dataset(numCol1.zone, getters, "0"), dataset(numCol2.zone, getters, "1")], headerInZone, catRange),
|
|
43734
43809
|
isPyramid
|
|
43735
43810
|
};
|
|
43736
43811
|
}
|
|
43737
43812
|
/** Pattern S — Many Numbers (3+ numeric columns, no categorical/date) */
|
|
43738
43813
|
function buildManyNumbersContext(cols, getters) {
|
|
43739
|
-
const title = cols.every((c) => c.
|
|
43740
|
-
const
|
|
43741
|
-
const source = rangeSource(cols.map((c, i) => dataset(c.zone, getters, String(i))),
|
|
43814
|
+
const title = cols.every((c) => c.headerInZone) ? cols.map((c) => c.title).join(" / ") : "";
|
|
43815
|
+
const headerInZone = cols.some((c) => c.headerInZone);
|
|
43816
|
+
const source = rangeSource(cols.map((c, i) => dataset(c.zone, getters, String(i))), headerInZone);
|
|
43742
43817
|
const { lastCellXC } = interestingCellsXc(cols[2]);
|
|
43743
43818
|
const { lastCellXC: firstCellXC } = interestingCellsXc(cols[0]);
|
|
43744
43819
|
const { lastCellXC: secondCellXC } = interestingCellsXc(cols[1]);
|
|
@@ -43753,6 +43828,7 @@ set(value) {
|
|
|
43753
43828
|
};
|
|
43754
43829
|
}
|
|
43755
43830
|
const NUMBER_OR_PERCENTAGE = ["number", "percentage"];
|
|
43831
|
+
const CATEGORICAL_OR_BOOLEAN = ["categorical", "boolean"];
|
|
43756
43832
|
const EXACT_PATTERNS = [
|
|
43757
43833
|
{
|
|
43758
43834
|
pattern: { leadingTypes: ["number"] },
|
|
@@ -43770,7 +43846,7 @@ set(value) {
|
|
|
43770
43846
|
suggestions: SINGLE_DATE_COLUMN_SUGGESTIONS
|
|
43771
43847
|
},
|
|
43772
43848
|
{
|
|
43773
|
-
pattern: { leadingTypes: [
|
|
43849
|
+
pattern: { leadingTypes: [CATEGORICAL_OR_BOOLEAN] },
|
|
43774
43850
|
buildContext: buildSingleCategoricalContext,
|
|
43775
43851
|
suggestions: SINGLE_CATEGORICAL_COLUMN_SUGGESTIONS
|
|
43776
43852
|
},
|
|
@@ -43780,7 +43856,7 @@ set(value) {
|
|
|
43780
43856
|
suggestions: SINGLE_LABEL_COLUMN_SUGGESTIONS
|
|
43781
43857
|
},
|
|
43782
43858
|
{
|
|
43783
|
-
pattern: { leadingTypes: [
|
|
43859
|
+
pattern: { leadingTypes: [CATEGORICAL_OR_BOOLEAN, "number"] },
|
|
43784
43860
|
buildContext: buildCategoricalVsNumberContext,
|
|
43785
43861
|
suggestions: CATEGORICAL_VS_NUMBER_SUGGESTIONS
|
|
43786
43862
|
},
|
|
@@ -43795,7 +43871,7 @@ set(value) {
|
|
|
43795
43871
|
suggestions: NUMBER_VS_NUMBER_SUGGESTIONS
|
|
43796
43872
|
},
|
|
43797
43873
|
{
|
|
43798
|
-
pattern: { leadingTypes: [
|
|
43874
|
+
pattern: { leadingTypes: [CATEGORICAL_OR_BOOLEAN, "percentage"] },
|
|
43799
43875
|
buildContext: buildCategoricalVsPercentageContext,
|
|
43800
43876
|
suggestions: CATEGORICAL_VS_PERCENTAGE_SUGGESTIONS
|
|
43801
43877
|
},
|
|
@@ -43811,8 +43887,8 @@ set(value) {
|
|
|
43811
43887
|
},
|
|
43812
43888
|
{
|
|
43813
43889
|
pattern: { leadingTypes: [
|
|
43814
|
-
|
|
43815
|
-
|
|
43890
|
+
CATEGORICAL_OR_BOOLEAN,
|
|
43891
|
+
CATEGORICAL_OR_BOOLEAN,
|
|
43816
43892
|
"number"
|
|
43817
43893
|
] },
|
|
43818
43894
|
buildContext: buildMultipleCategoricalsVsNumberContext,
|
|
@@ -43820,7 +43896,7 @@ set(value) {
|
|
|
43820
43896
|
},
|
|
43821
43897
|
{
|
|
43822
43898
|
pattern: { leadingTypes: [
|
|
43823
|
-
|
|
43899
|
+
CATEGORICAL_OR_BOOLEAN,
|
|
43824
43900
|
"label",
|
|
43825
43901
|
"number"
|
|
43826
43902
|
] },
|
|
@@ -43829,7 +43905,7 @@ set(value) {
|
|
|
43829
43905
|
},
|
|
43830
43906
|
{
|
|
43831
43907
|
pattern: { leadingTypes: [
|
|
43832
|
-
|
|
43908
|
+
CATEGORICAL_OR_BOOLEAN,
|
|
43833
43909
|
"date",
|
|
43834
43910
|
NUMBER_OR_PERCENTAGE
|
|
43835
43911
|
] },
|
|
@@ -43838,7 +43914,7 @@ set(value) {
|
|
|
43838
43914
|
},
|
|
43839
43915
|
{
|
|
43840
43916
|
pattern: { leadingTypes: [
|
|
43841
|
-
|
|
43917
|
+
CATEGORICAL_OR_BOOLEAN,
|
|
43842
43918
|
NUMBER_OR_PERCENTAGE,
|
|
43843
43919
|
NUMBER_OR_PERCENTAGE
|
|
43844
43920
|
] },
|
|
@@ -57233,7 +57309,7 @@ set(value) {
|
|
|
57233
57309
|
return this.strictMeasureValueToNumber(comparedValue);
|
|
57234
57310
|
}
|
|
57235
57311
|
getPivotValueCells(measureId) {
|
|
57236
|
-
return this.
|
|
57312
|
+
return this.getExpandedTableStructure().getPivotCells().map((col) => col.filter((cell) => cell.type === "VALUE" && cell.measure === measureId)).filter((col) => col.length > 0);
|
|
57237
57313
|
}
|
|
57238
57314
|
measureValueToNumber(result) {
|
|
57239
57315
|
if (typeof result.value === "number") return result.value;
|
|
@@ -65929,7 +66005,7 @@ set(value) {
|
|
|
65929
66005
|
* Get the background and textColor of a chart based on the color of the first cell of the main range of the chart.
|
|
65930
66006
|
*/
|
|
65931
66007
|
getStyleOfSingleCellChart(chartBackground, mainRange, colorThemeName) {
|
|
65932
|
-
const themeBackground = COLOR_THEMES[colorThemeName].
|
|
66008
|
+
const themeBackground = COLOR_THEMES[colorThemeName].chartBackgroundColor;
|
|
65933
66009
|
if (chartBackground) return {
|
|
65934
66010
|
background: chartBackground,
|
|
65935
66011
|
fontColor: chartFontColor(chartBackground)
|
|
@@ -66983,14 +67059,12 @@ set(value) {
|
|
|
66983
67059
|
var UIPlugin = class extends BasePlugin {
|
|
66984
67060
|
static layers = [];
|
|
66985
67061
|
getters;
|
|
66986
|
-
ui;
|
|
66987
67062
|
selection;
|
|
66988
67063
|
dispatch;
|
|
66989
67064
|
canDispatch;
|
|
66990
|
-
constructor({ getters, stateObserver, dispatch, canDispatch,
|
|
67065
|
+
constructor({ getters, stateObserver, dispatch, canDispatch, selection }) {
|
|
66991
67066
|
super(stateObserver);
|
|
66992
67067
|
this.getters = getters;
|
|
66993
|
-
this.ui = uiActions;
|
|
66994
67068
|
this.selection = selection;
|
|
66995
67069
|
this.dispatch = dispatch;
|
|
66996
67070
|
this.canDispatch = canDispatch;
|
|
@@ -72459,9 +72533,7 @@ set(value) {
|
|
|
72459
72533
|
return cssPropertiesToCss({ zoom: this.zoomStore.cssZoom });
|
|
72460
72534
|
}
|
|
72461
72535
|
get backgroundStyle() {
|
|
72462
|
-
|
|
72463
|
-
const theme = this.env.model.getters.getSpreadsheetTheme();
|
|
72464
|
-
return cssPropertiesToCss({ "background-color": sheet.backgroundColor || theme.backgroundColor });
|
|
72536
|
+
return cssPropertiesToCss({ "background-color": this.env.model.getters.getActiveSheet().backgroundColor });
|
|
72465
72537
|
}
|
|
72466
72538
|
};
|
|
72467
72539
|
|
|
@@ -73067,7 +73139,7 @@ set(value) {
|
|
|
73067
73139
|
ctx.beginPath();
|
|
73068
73140
|
ctx.rect(figureRect.x, figureRect.y, figureRect.width, figureRect.height);
|
|
73069
73141
|
ctx.clip();
|
|
73070
|
-
ctx.fillStyle = chartDefinition?.background || this.getters.getSpreadsheetTheme().
|
|
73142
|
+
ctx.fillStyle = chartDefinition?.background || this.getters.getSpreadsheetTheme().chartBackgroundColor;
|
|
73071
73143
|
ctx.fillRect(figureRect.x, figureRect.y, figureRect.width, figureRect.height);
|
|
73072
73144
|
const title = {
|
|
73073
73145
|
...DEFAULT_CAROUSEL_TITLE_STYLE,
|
|
@@ -74975,14 +75047,10 @@ set(value) {
|
|
|
74975
75047
|
sticky: false
|
|
74976
75048
|
});
|
|
74977
75049
|
});
|
|
74978
|
-
this.model.on("notify-ui", this, (notification) => this.notificationStore.notifyUser(notification));
|
|
74979
|
-
this.model.on("raise-error-ui", this, ({ text }) => this.notificationStore.raiseError(text));
|
|
74980
75050
|
}
|
|
74981
75051
|
unbindModelEvents() {
|
|
74982
75052
|
this.model.off("update", this);
|
|
74983
75053
|
this.model.off("command-rejected", this);
|
|
74984
|
-
this.model.off("notify-ui", this);
|
|
74985
|
-
this.model.off("raise-error-ui", this);
|
|
74986
75054
|
}
|
|
74987
75055
|
checkViewportSize() {
|
|
74988
75056
|
const { xRatio, yRatio } = this.viewStore.viewports.getFrozenSheetViewRatio(this.viewStore.displayedSheetId);
|
|
@@ -79397,8 +79465,6 @@ set(value) {
|
|
|
79397
79465
|
client,
|
|
79398
79466
|
moveClient: () => {},
|
|
79399
79467
|
snapshotRequested: false,
|
|
79400
|
-
notifyUI: (payload) => this.trigger("notify-ui", payload),
|
|
79401
|
-
raiseBlockingErrorUI: (text) => this.trigger("raise-error-ui", { text }),
|
|
79402
79468
|
customColors: config.customColors || []
|
|
79403
79469
|
};
|
|
79404
79470
|
}
|
|
@@ -79442,7 +79508,6 @@ set(value) {
|
|
|
79442
79508
|
selection: this.selection,
|
|
79443
79509
|
moveClient: this.session.move.bind(this.session),
|
|
79444
79510
|
custom: this.config.custom,
|
|
79445
|
-
uiActions: this.config,
|
|
79446
79511
|
session: this.session,
|
|
79447
79512
|
defaultCurrency: this.config.defaultCurrency,
|
|
79448
79513
|
customColors: this.config.customColors || [],
|
|
@@ -79578,7 +79643,15 @@ set(value) {
|
|
|
79578
79643
|
dispatchFromEvaluationPlugin = (type, payload) => {
|
|
79579
79644
|
const command = createCommand(type, payload);
|
|
79580
79645
|
if (!isDispatcheableEvaluationCommand(command)) throw new Error(`An evaluation plugin cannot dispatch non-evaluation commands (${type})`);
|
|
79646
|
+
if (this.status !== 0) {
|
|
79647
|
+
this.dispatchToHandlers(this.evaluationHandlers, command);
|
|
79648
|
+
return DispatchResult.Success;
|
|
79649
|
+
}
|
|
79650
|
+
this.status = 3;
|
|
79581
79651
|
this.dispatchToHandlers(this.evaluationHandlers, command);
|
|
79652
|
+
this.finalize();
|
|
79653
|
+
this.status = 0;
|
|
79654
|
+
this.trigger("update");
|
|
79582
79655
|
return DispatchResult.Success;
|
|
79583
79656
|
};
|
|
79584
79657
|
/**
|
|
@@ -82118,7 +82191,7 @@ set(value) {
|
|
|
82118
82191
|
legend: getBubbleChartLegend(definition, chartData),
|
|
82119
82192
|
tooltip: getBubbleChartTooltip(definition, chartData),
|
|
82120
82193
|
chartShowValuesPlugin: getChartShowValues(definition, chartData),
|
|
82121
|
-
background: { color:
|
|
82194
|
+
background: { color: chartData.background }
|
|
82122
82195
|
}
|
|
82123
82196
|
}
|
|
82124
82197
|
} };
|
|
@@ -91457,8 +91530,8 @@ exports.stores = stores;
|
|
|
91457
91530
|
exports.tokenColors = tokenColors;
|
|
91458
91531
|
exports.tokenize = tokenize;
|
|
91459
91532
|
|
|
91460
|
-
__info__.version = "19.5.0-alpha.
|
|
91461
|
-
__info__.date = "2026-09-
|
|
91462
|
-
__info__.hash = "
|
|
91533
|
+
__info__.version = "19.5.0-alpha.20";
|
|
91534
|
+
__info__.date = "2026-09-16T08:02:11.430Z";
|
|
91535
|
+
__info__.hash = "4784627";
|
|
91463
91536
|
|
|
91464
91537
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|