@odoo/o-spreadsheet 18.1.0-alpha.6 → 18.1.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/o-spreadsheet.cjs.js +299 -247
- package/dist/o-spreadsheet.d.ts +226 -210
- package/dist/o-spreadsheet.esm.js +299 -247
- package/dist/o-spreadsheet.iife.js +299 -247
- package/dist/o-spreadsheet.iife.min.js +454 -454
- package/dist/o_spreadsheet.xml +28 -19
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.1.0-alpha.
|
|
6
|
-
* @date 2024-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.1.0-alpha.7
|
|
6
|
+
* @date 2024-12-05T10:40:26.512Z
|
|
7
|
+
* @hash 7b1c39b
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -172,10 +172,13 @@ const ALERT_INFO_BG = "#CDEDF1";
|
|
|
172
172
|
const ALERT_INFO_BORDER = "#98DBE2";
|
|
173
173
|
const ALERT_INFO_TEXT_COLOR = "#09414A";
|
|
174
174
|
const BADGE_SELECTED_COLOR = "#E6F2F3";
|
|
175
|
-
const
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
const
|
|
175
|
+
const CHART_PADDING$1 = 20;
|
|
176
|
+
const CHART_PADDING_BOTTOM = 10;
|
|
177
|
+
const CHART_PADDING_TOP = 15;
|
|
178
|
+
const CHART_TITLE_FONT_SIZE = 16;
|
|
179
|
+
const CHART_AXIS_TITLE_FONT_SIZE = 12;
|
|
180
|
+
const SCORECARD_CHART_TITLE_FONT_SIZE = 14;
|
|
181
|
+
const PIVOT_TOKEN_COLOR = "#F28C28";
|
|
179
182
|
// Color picker defaults as upper case HEX to match `toHex`helper
|
|
180
183
|
const COLOR_PICKER_DEFAULTS = [
|
|
181
184
|
"#000000",
|
|
@@ -335,8 +338,8 @@ const DEFAULT_WINDOW_SIZE = 2;
|
|
|
335
338
|
const DEBOUNCE_TIME = 200;
|
|
336
339
|
const MESSAGE_VERSION = 1;
|
|
337
340
|
// Sheets
|
|
338
|
-
const
|
|
339
|
-
const
|
|
341
|
+
const FORBIDDEN_SHEETNAME_CHARS = ["'", "*", "?", "/", "\\", "[", "]"];
|
|
342
|
+
const FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX = /'|\*|\?|\/|\\|\[|\]/;
|
|
340
343
|
// Cells
|
|
341
344
|
const FORMULA_REF_IDENTIFIER = "|";
|
|
342
345
|
// Components
|
|
@@ -389,6 +392,7 @@ const DEFAULT_CURRENCY = {
|
|
|
389
392
|
//------------------------------------------------------------------------------
|
|
390
393
|
// Miscellaneous
|
|
391
394
|
//------------------------------------------------------------------------------
|
|
395
|
+
const sanitizeSheetNameRegex = new RegExp(FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX, "g");
|
|
392
396
|
/**
|
|
393
397
|
* Remove quotes from a quoted string
|
|
394
398
|
* ```js
|
|
@@ -484,6 +488,10 @@ function getCanonicalSymbolName(symbolName) {
|
|
|
484
488
|
}
|
|
485
489
|
return symbolName;
|
|
486
490
|
}
|
|
491
|
+
/** Replace the excel-excluded characters of a sheetName */
|
|
492
|
+
function sanitizeSheetName(sheetName, replacementChar = " ") {
|
|
493
|
+
return sheetName.replace(sanitizeSheetNameRegex, replacementChar);
|
|
494
|
+
}
|
|
487
495
|
function clip(val, min, max) {
|
|
488
496
|
return val < min ? min : val > max ? max : val;
|
|
489
497
|
}
|
|
@@ -9516,6 +9524,12 @@ function chartFontColor(backgroundColor) {
|
|
|
9516
9524
|
}
|
|
9517
9525
|
return relativeLuminance(backgroundColor) < 0.3 ? "#FFFFFF" : "#000000";
|
|
9518
9526
|
}
|
|
9527
|
+
function chartMutedFontColor(backgroundColor) {
|
|
9528
|
+
if (!backgroundColor) {
|
|
9529
|
+
return "#666666";
|
|
9530
|
+
}
|
|
9531
|
+
return relativeLuminance(backgroundColor) < 0.3 ? "#C8C8C8" : "#666666";
|
|
9532
|
+
}
|
|
9519
9533
|
function checkDataset(definition) {
|
|
9520
9534
|
if (definition.dataSets) {
|
|
9521
9535
|
const invalidRanges = definition.dataSets.find((range) => !rangeReference.test(range.dataRange)) !== undefined;
|
|
@@ -9651,8 +9665,8 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
|
|
|
9651
9665
|
const yMin = chart.chartArea.top;
|
|
9652
9666
|
const textsPositions = {};
|
|
9653
9667
|
for (const dataset of chart._metasets) {
|
|
9654
|
-
if (dataset.xAxisID === TREND_LINE_XAXIS_ID) {
|
|
9655
|
-
|
|
9668
|
+
if (dataset.xAxisID === TREND_LINE_XAXIS_ID || dataset.hidden) {
|
|
9669
|
+
continue;
|
|
9656
9670
|
}
|
|
9657
9671
|
for (let i = 0; i < dataset._parsed.length; i++) {
|
|
9658
9672
|
const parsedValue = dataset._parsed[i];
|
|
@@ -10099,7 +10113,7 @@ let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
|
|
|
10099
10113
|
function drawScoreChart(structure, canvas) {
|
|
10100
10114
|
const ctx = canvas.getContext("2d");
|
|
10101
10115
|
canvas.width = structure.canvas.width;
|
|
10102
|
-
const availableWidth = canvas.width -
|
|
10116
|
+
const availableWidth = canvas.width - CHART_PADDING$1 * 2;
|
|
10103
10117
|
canvas.height = structure.canvas.height;
|
|
10104
10118
|
ctx.fillStyle = structure.canvas.backgroundColor;
|
|
10105
10119
|
ctx.fillRect(0, 0, structure.canvas.width, structure.canvas.height);
|
|
@@ -10234,10 +10248,9 @@ function createScorecardChartRuntime(chart, getters) {
|
|
|
10234
10248
|
}
|
|
10235
10249
|
|
|
10236
10250
|
/* Padding at the border of the chart */
|
|
10237
|
-
const CHART_PADDING =
|
|
10251
|
+
const CHART_PADDING = 10;
|
|
10238
10252
|
const BOTTOM_PADDING_RATIO = 0.05;
|
|
10239
10253
|
/* Maximum font sizes of each element */
|
|
10240
|
-
const CHART_TITLE_FONT_SIZE = SCORECARD_GAUGE_CHART_FONT_SIZE;
|
|
10241
10254
|
const KEY_VALUE_FONT_SIZE = 32;
|
|
10242
10255
|
const BASELINE_MAX_FONT_SIZE = 16;
|
|
10243
10256
|
function formatBaselineDescr(baselineDescr, baseline) {
|
|
@@ -10309,7 +10322,7 @@ class ScorecardChartConfigBuilder {
|
|
|
10309
10322
|
: this.height - (this.height - titleHeight - baselineHeight) / 2 - CHART_PADDING,
|
|
10310
10323
|
},
|
|
10311
10324
|
};
|
|
10312
|
-
const minimalBaselinePosition = baselineArrowSize +
|
|
10325
|
+
const minimalBaselinePosition = baselineArrowSize + CHART_PADDING * 2;
|
|
10313
10326
|
if (structure.baseline.position.x < minimalBaselinePosition) {
|
|
10314
10327
|
structure.baseline.position.x = minimalBaselinePosition;
|
|
10315
10328
|
}
|
|
@@ -10389,7 +10402,7 @@ class ScorecardChartConfigBuilder {
|
|
|
10389
10402
|
return this.runtime.background;
|
|
10390
10403
|
}
|
|
10391
10404
|
get secondaryFontColor() {
|
|
10392
|
-
return
|
|
10405
|
+
return chartMutedFontColor(this.backgroundColor);
|
|
10393
10406
|
}
|
|
10394
10407
|
getTextDimensions(text, font) {
|
|
10395
10408
|
this.context.font = font;
|
|
@@ -10415,7 +10428,7 @@ class ScorecardChartConfigBuilder {
|
|
|
10415
10428
|
}
|
|
10416
10429
|
return {
|
|
10417
10430
|
title: {
|
|
10418
|
-
font: getDefaultContextFont(
|
|
10431
|
+
font: getDefaultContextFont(this.runtime.title.fontSize ?? SCORECARD_CHART_TITLE_FONT_SIZE, this.runtime.title.bold, this.runtime.title.italic),
|
|
10419
10432
|
color: this.runtime.title.color ?? this.secondaryFontColor,
|
|
10420
10433
|
},
|
|
10421
10434
|
keyValue: {
|
|
@@ -21236,7 +21249,7 @@ function getFunctionsFromAST(ast, functionNames) {
|
|
|
21236
21249
|
|
|
21237
21250
|
const PIVOT_FUNCTIONS = ["PIVOT.VALUE", "PIVOT.HEADER", "PIVOT"];
|
|
21238
21251
|
/**
|
|
21239
|
-
* Create a proposal entry for the
|
|
21252
|
+
* Create a proposal entry for the composer autocomplete
|
|
21240
21253
|
* to insert a field name string in a formula.
|
|
21241
21254
|
*/
|
|
21242
21255
|
function makeFieldProposal(field, granularity) {
|
|
@@ -22019,14 +22032,8 @@ const GAUGE_PADDING_BOTTOM = 20;
|
|
|
22019
22032
|
const GAUGE_LABELS_FONT_SIZE = 12;
|
|
22020
22033
|
const GAUGE_DEFAULT_VALUE_FONT_SIZE = 80;
|
|
22021
22034
|
const GAUGE_BACKGROUND_COLOR = "#F3F2F1";
|
|
22022
|
-
const GAUGE_TEXT_COLOR = "#666666";
|
|
22023
|
-
const GAUGE_TEXT_COLOR_HIGH_CONTRAST = "#C8C8C8";
|
|
22024
|
-
const GAUGE_INFLECTION_MARKER_COLOR = "#666666aa";
|
|
22025
22035
|
const GAUGE_INFLECTION_LABEL_BOTTOM_MARGIN = 6;
|
|
22026
22036
|
const GAUGE_TITLE_SECTION_HEIGHT = 25;
|
|
22027
|
-
const GAUGE_TITLE_FONT_SIZE = SCORECARD_GAUGE_CHART_FONT_SIZE;
|
|
22028
|
-
const GAUGE_TITLE_PADDING_LEFT = SCORECARD_GAUGE_CHART_PADDING;
|
|
22029
|
-
const GAUGE_TITLE_PADDING_TOP = SCORECARD_GAUGE_CHART_PADDING;
|
|
22030
22037
|
function drawGaugeChart(canvas, runtime) {
|
|
22031
22038
|
const canvasBoundingRect = canvas.getBoundingClientRect();
|
|
22032
22039
|
canvas.width = canvasBoundingRect.width;
|
|
@@ -22085,7 +22092,7 @@ function drawInflectionValues(ctx, config) {
|
|
|
22085
22092
|
ctx.translate(rectX + width / 2 - 0.5, rectY + height - 0.5); // -0.5 for sharper lines. see RendererPlugin.drawBorders comment
|
|
22086
22093
|
ctx.rotate(Math.PI / 2 - inflectionValue.rotation);
|
|
22087
22094
|
ctx.lineWidth = 2;
|
|
22088
|
-
ctx.strokeStyle =
|
|
22095
|
+
ctx.strokeStyle = chartMutedFontColor(config.backgroundColor) + "aa";
|
|
22089
22096
|
ctx.beginPath();
|
|
22090
22097
|
ctx.moveTo(0, -(height - config.gauge.arcWidth));
|
|
22091
22098
|
ctx.lineTo(0, -height - 3);
|
|
@@ -22139,22 +22146,22 @@ function getGaugeRenderingConfig(boundingRect, runtime, ctx) {
|
|
|
22139
22146
|
x: gaugeRect.x + gaugeRect.width - gaugeArcWidth / 2,
|
|
22140
22147
|
y: gaugeRect.y + gaugeRect.height + GAUGE_LABELS_FONT_SIZE,
|
|
22141
22148
|
};
|
|
22142
|
-
const textColor =
|
|
22149
|
+
const textColor = chartMutedFontColor(runtime.background);
|
|
22143
22150
|
const inflectionValues = getInflectionValues(runtime, gaugeRect, textColor, ctx);
|
|
22144
22151
|
let x = 0, titleWidth = 0, titleHeight = 0;
|
|
22145
22152
|
if (runtime.title.text) {
|
|
22146
|
-
({ width: titleWidth, height: titleHeight } = computeTextDimension(ctx, runtime.title.text, { ...runtime.title
|
|
22153
|
+
({ width: titleWidth, height: titleHeight } = computeTextDimension(ctx, runtime.title.text, { fontSize: CHART_TITLE_FONT_SIZE, ...runtime.title }, "px"));
|
|
22147
22154
|
}
|
|
22148
22155
|
switch (runtime.title.align) {
|
|
22149
22156
|
case "right":
|
|
22150
|
-
x = boundingRect.width - titleWidth -
|
|
22157
|
+
x = boundingRect.width - titleWidth - CHART_PADDING$1;
|
|
22151
22158
|
break;
|
|
22152
22159
|
case "center":
|
|
22153
22160
|
x = (boundingRect.width - titleWidth) / 2;
|
|
22154
22161
|
break;
|
|
22155
22162
|
case "left":
|
|
22156
22163
|
default:
|
|
22157
|
-
x =
|
|
22164
|
+
x = CHART_PADDING$1;
|
|
22158
22165
|
break;
|
|
22159
22166
|
}
|
|
22160
22167
|
return {
|
|
@@ -22162,10 +22169,10 @@ function getGaugeRenderingConfig(boundingRect, runtime, ctx) {
|
|
|
22162
22169
|
height: boundingRect.height,
|
|
22163
22170
|
title: {
|
|
22164
22171
|
label: runtime.title.text ?? "",
|
|
22165
|
-
fontSize:
|
|
22172
|
+
fontSize: runtime.title.fontSize ?? CHART_TITLE_FONT_SIZE,
|
|
22166
22173
|
textPosition: {
|
|
22167
22174
|
x,
|
|
22168
|
-
y:
|
|
22175
|
+
y: CHART_PADDING_TOP + titleHeight / 2,
|
|
22169
22176
|
},
|
|
22170
22177
|
color: runtime.title.color ?? textColor,
|
|
22171
22178
|
bold: runtime.title.bold,
|
|
@@ -22282,11 +22289,6 @@ function getGaugeColor(runtime) {
|
|
|
22282
22289
|
}
|
|
22283
22290
|
return runtime.colors.at(-1);
|
|
22284
22291
|
}
|
|
22285
|
-
function getContrastedTextColor(backgroundColor) {
|
|
22286
|
-
return relativeLuminance(backgroundColor) > 0.3
|
|
22287
|
-
? GAUGE_TEXT_COLOR
|
|
22288
|
-
: GAUGE_TEXT_COLOR_HIGH_CONTRAST;
|
|
22289
|
-
}
|
|
22290
22292
|
function getSegmentsOfRectangle(rectangle) {
|
|
22291
22293
|
return [
|
|
22292
22294
|
{ start: rectangle.topLeft, end: rectangle.topRight },
|
|
@@ -27000,13 +27002,12 @@ migrationStepRegistry
|
|
|
27000
27002
|
versionFrom: "7",
|
|
27001
27003
|
migrate(data) {
|
|
27002
27004
|
const namesTaken = [];
|
|
27003
|
-
const globalForbiddenInExcel = new RegExp(FORBIDDEN_IN_EXCEL_REGEX, "g");
|
|
27004
27005
|
for (let sheet of data.sheets || []) {
|
|
27005
27006
|
if (!sheet.name) {
|
|
27006
27007
|
continue;
|
|
27007
27008
|
}
|
|
27008
27009
|
const oldName = sheet.name;
|
|
27009
|
-
const escapedName = oldName
|
|
27010
|
+
const escapedName = sanitizeSheetName(oldName, "_");
|
|
27010
27011
|
let i = 1;
|
|
27011
27012
|
let newName = escapedName;
|
|
27012
27013
|
while (namesTaken.includes(newName)) {
|
|
@@ -28242,37 +28243,45 @@ function interpolateData(config, values, labels, newLabels) {
|
|
|
28242
28243
|
const labelRange = labelMax - labelMin;
|
|
28243
28244
|
const normalizedLabels = labels.map((v) => (v - labelMin) / labelRange);
|
|
28244
28245
|
const normalizedNewLabels = newLabels.map((v) => (v - labelMin) / labelRange);
|
|
28245
|
-
|
|
28246
|
-
|
|
28247
|
-
|
|
28248
|
-
|
|
28249
|
-
|
|
28250
|
-
|
|
28251
|
-
|
|
28252
|
-
|
|
28253
|
-
|
|
28254
|
-
|
|
28255
|
-
|
|
28256
|
-
|
|
28257
|
-
|
|
28258
|
-
|
|
28259
|
-
|
|
28260
|
-
|
|
28246
|
+
try {
|
|
28247
|
+
switch (config.type) {
|
|
28248
|
+
case "polynomial": {
|
|
28249
|
+
const order = config.order;
|
|
28250
|
+
if (!order) {
|
|
28251
|
+
return Array.from({ length: newLabels.length }, () => NaN);
|
|
28252
|
+
}
|
|
28253
|
+
if (order === 1) {
|
|
28254
|
+
return predictLinearValues([values], [normalizedLabels], [normalizedNewLabels], true)[0];
|
|
28255
|
+
}
|
|
28256
|
+
const coeffs = polynomialRegression(values, normalizedLabels, order, true).flat();
|
|
28257
|
+
return normalizedNewLabels.map((v) => evaluatePolynomial(coeffs, v, order));
|
|
28258
|
+
}
|
|
28259
|
+
case "exponential": {
|
|
28260
|
+
const positiveLogValues = [];
|
|
28261
|
+
const filteredLabels = [];
|
|
28262
|
+
for (let i = 0; i < values.length; i++) {
|
|
28263
|
+
if (values[i] > 0) {
|
|
28264
|
+
positiveLogValues.push(Math.log(values[i]));
|
|
28265
|
+
filteredLabels.push(normalizedLabels[i]);
|
|
28266
|
+
}
|
|
28261
28267
|
}
|
|
28268
|
+
if (!filteredLabels.length) {
|
|
28269
|
+
return Array.from({ length: newLabels.length }, () => NaN);
|
|
28270
|
+
}
|
|
28271
|
+
return expM(predictLinearValues([positiveLogValues], [filteredLabels], [normalizedNewLabels], true))[0];
|
|
28262
28272
|
}
|
|
28263
|
-
|
|
28264
|
-
return [];
|
|
28273
|
+
case "logarithmic": {
|
|
28274
|
+
return predictLinearValues([values], logM([normalizedLabels]), logM([normalizedNewLabels]), true)[0];
|
|
28265
28275
|
}
|
|
28266
|
-
|
|
28267
|
-
|
|
28268
|
-
|
|
28269
|
-
|
|
28270
|
-
|
|
28271
|
-
case "trailingMovingAverage": {
|
|
28272
|
-
return getMovingAverageValues(values, config.window);
|
|
28276
|
+
case "trailingMovingAverage": {
|
|
28277
|
+
return getMovingAverageValues(values, config.window);
|
|
28278
|
+
}
|
|
28279
|
+
default:
|
|
28280
|
+
return Array.from({ length: newLabels.length }, () => NaN);
|
|
28273
28281
|
}
|
|
28274
|
-
|
|
28275
|
-
|
|
28282
|
+
}
|
|
28283
|
+
catch (e) {
|
|
28284
|
+
return Array.from({ length: newLabels.length }, () => NaN);
|
|
28276
28285
|
}
|
|
28277
28286
|
}
|
|
28278
28287
|
function getChartAxisType(chart, labelRange, getters) {
|
|
@@ -28743,54 +28752,16 @@ function getChartColorsGenerator(definition, dataSetsSize) {
|
|
|
28743
28752
|
return new ColorGenerator(dataSetsSize, definition.dataSets?.map((ds) => ds.backgroundColor) || []);
|
|
28744
28753
|
}
|
|
28745
28754
|
|
|
28746
|
-
function
|
|
28747
|
-
// TODO FIXME: this is unused ATM. All the charts should probably use this instead oh whatever padding they are using now
|
|
28748
|
-
// also look into how DEFAULT_CHART_PADDING is used in scorecards, it look strange
|
|
28755
|
+
function getChartLayout(definition) {
|
|
28749
28756
|
return {
|
|
28750
28757
|
padding: {
|
|
28751
|
-
left:
|
|
28752
|
-
right:
|
|
28753
|
-
top:
|
|
28754
|
-
bottom:
|
|
28758
|
+
left: CHART_PADDING$1,
|
|
28759
|
+
right: CHART_PADDING$1,
|
|
28760
|
+
top: CHART_PADDING_TOP,
|
|
28761
|
+
bottom: CHART_PADDING_BOTTOM,
|
|
28755
28762
|
},
|
|
28756
28763
|
};
|
|
28757
28764
|
}
|
|
28758
|
-
function getBarChartLayout(definition) {
|
|
28759
|
-
return {
|
|
28760
|
-
padding: computeChartPadding({
|
|
28761
|
-
displayTitle: !!definition.title?.text,
|
|
28762
|
-
displayLegend: definition.legendPosition === "top",
|
|
28763
|
-
}),
|
|
28764
|
-
};
|
|
28765
|
-
}
|
|
28766
|
-
function getLineChartLayout(definition) {
|
|
28767
|
-
return {
|
|
28768
|
-
padding: computeChartPadding({
|
|
28769
|
-
displayTitle: !!definition.title?.text,
|
|
28770
|
-
displayLegend: definition.legendPosition === "top",
|
|
28771
|
-
}),
|
|
28772
|
-
};
|
|
28773
|
-
}
|
|
28774
|
-
function getPieChartLayout(definition) {
|
|
28775
|
-
return {
|
|
28776
|
-
padding: { left: 20, right: 20, top: definition.title ? 10 : 25, bottom: 10 },
|
|
28777
|
-
};
|
|
28778
|
-
}
|
|
28779
|
-
function getWaterfallChartLayout(definition) {
|
|
28780
|
-
return {
|
|
28781
|
-
padding: { left: 20, right: 20, top: definition.title ? 10 : 25, bottom: 10 },
|
|
28782
|
-
};
|
|
28783
|
-
}
|
|
28784
|
-
function computeChartPadding({ displayTitle, displayLegend, }) {
|
|
28785
|
-
let top = 25;
|
|
28786
|
-
if (displayTitle) {
|
|
28787
|
-
top = 0;
|
|
28788
|
-
}
|
|
28789
|
-
else if (displayLegend) {
|
|
28790
|
-
top = 10;
|
|
28791
|
-
}
|
|
28792
|
-
return { left: 20, right: 20, top, bottom: 10 };
|
|
28793
|
-
}
|
|
28794
28765
|
|
|
28795
28766
|
function getLegendDisplayOptions(definition, args) {
|
|
28796
28767
|
return {
|
|
@@ -28848,11 +28819,12 @@ function getScatterChartLegend(definition, args) {
|
|
|
28848
28819
|
return {
|
|
28849
28820
|
...INTERACTIVE_LEGEND_CONFIG,
|
|
28850
28821
|
...getLegendDisplayOptions(definition),
|
|
28851
|
-
|
|
28852
|
-
|
|
28853
|
-
|
|
28854
|
-
|
|
28855
|
-
|
|
28822
|
+
...getCustomLegendLabels(chartFontColor(definition.background), {
|
|
28823
|
+
pointStyle: "circle",
|
|
28824
|
+
// the stroke is the border around the circle, so increasing its size with the chart's color reduce the size of the circle
|
|
28825
|
+
strokeStyle: definition.background || "#ffffff",
|
|
28826
|
+
lineWidth: 8,
|
|
28827
|
+
}),
|
|
28856
28828
|
};
|
|
28857
28829
|
}
|
|
28858
28830
|
function getComboChartLegend(definition, args) {
|
|
@@ -28941,10 +28913,10 @@ const INTERACTIVE_LEGEND_CONFIG = {
|
|
|
28941
28913
|
target.style.cursor = "default";
|
|
28942
28914
|
},
|
|
28943
28915
|
onClick: (event, legendItem, legend) => {
|
|
28944
|
-
|
|
28916
|
+
const index = legendItem.datasetIndex;
|
|
28917
|
+
if (!legend.legendItems || index === undefined) {
|
|
28945
28918
|
return;
|
|
28946
28919
|
}
|
|
28947
|
-
const index = legend.legendItems.indexOf(legendItem);
|
|
28948
28920
|
if (legend.chart.isDatasetVisible(index)) {
|
|
28949
28921
|
legend.chart.hide(index);
|
|
28950
28922
|
}
|
|
@@ -28960,15 +28932,29 @@ function getCustomLegendLabels(fontColor, legendLabelConfig) {
|
|
|
28960
28932
|
labels: {
|
|
28961
28933
|
color: fontColor,
|
|
28962
28934
|
usePointStyle: true,
|
|
28963
|
-
generateLabels: (chart) => chart.data.datasets.map((dataset, index) =>
|
|
28964
|
-
|
|
28965
|
-
|
|
28966
|
-
|
|
28967
|
-
|
|
28968
|
-
|
|
28969
|
-
|
|
28970
|
-
|
|
28971
|
-
|
|
28935
|
+
generateLabels: (chart) => chart.data.datasets.map((dataset, index) => {
|
|
28936
|
+
if (dataset["xAxisID"] === TREND_LINE_XAXIS_ID) {
|
|
28937
|
+
return {
|
|
28938
|
+
text: dataset.label ?? "",
|
|
28939
|
+
fontColor,
|
|
28940
|
+
strokeStyle: dataset.borderColor,
|
|
28941
|
+
hidden: !chart.isDatasetVisible(index),
|
|
28942
|
+
pointStyle: "line",
|
|
28943
|
+
datasetIndex: index,
|
|
28944
|
+
lineWidth: 3,
|
|
28945
|
+
};
|
|
28946
|
+
}
|
|
28947
|
+
return {
|
|
28948
|
+
text: dataset.label ?? "",
|
|
28949
|
+
fontColor,
|
|
28950
|
+
strokeStyle: dataset.borderColor,
|
|
28951
|
+
fillStyle: dataset.backgroundColor,
|
|
28952
|
+
hidden: !chart.isDatasetVisible(index),
|
|
28953
|
+
pointStyle: dataset.type === "line" ? "line" : "rect",
|
|
28954
|
+
datasetIndex: index,
|
|
28955
|
+
...legendLabelConfig,
|
|
28956
|
+
};
|
|
28957
|
+
}),
|
|
28972
28958
|
},
|
|
28973
28959
|
};
|
|
28974
28960
|
}
|
|
@@ -29116,6 +29102,7 @@ function getChartAxisTitleRuntime(design) {
|
|
|
29116
29102
|
font: {
|
|
29117
29103
|
style: italic ? "italic" : "normal",
|
|
29118
29104
|
weight: bold ? "bold" : "normal",
|
|
29105
|
+
size: design.title.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE,
|
|
29119
29106
|
},
|
|
29120
29107
|
align: align === "left" ? "start" : align === "right" ? "end" : "center",
|
|
29121
29108
|
};
|
|
@@ -29181,17 +29168,22 @@ function getChartShowValues(definition, args) {
|
|
|
29181
29168
|
|
|
29182
29169
|
function getChartTitle(definition) {
|
|
29183
29170
|
const chartTitle = definition.title;
|
|
29184
|
-
const fontColor =
|
|
29171
|
+
const fontColor = chartMutedFontColor(definition.background);
|
|
29185
29172
|
return {
|
|
29186
29173
|
display: !!chartTitle.text,
|
|
29187
29174
|
text: _t(chartTitle.text),
|
|
29188
29175
|
color: chartTitle?.color ?? fontColor,
|
|
29189
29176
|
align: chartTitle.align === "center" ? "center" : chartTitle.align === "right" ? "end" : "start",
|
|
29190
29177
|
font: {
|
|
29191
|
-
size:
|
|
29178
|
+
size: definition.title.fontSize ?? CHART_TITLE_FONT_SIZE,
|
|
29192
29179
|
weight: chartTitle.bold ? "bold" : "normal",
|
|
29193
29180
|
style: chartTitle.italic ? "italic" : "normal",
|
|
29194
29181
|
},
|
|
29182
|
+
padding: {
|
|
29183
|
+
// Disable title top/left/right padding to use the chart padding instead.
|
|
29184
|
+
// The legend already has a top padding, so bottom padding is useless for the title there.
|
|
29185
|
+
bottom: definition.legendPosition === "top" ? 0 : CHART_PADDING$1,
|
|
29186
|
+
},
|
|
29195
29187
|
};
|
|
29196
29188
|
}
|
|
29197
29189
|
|
|
@@ -29338,26 +29330,23 @@ var CHART_RUNTIME_HELPERS = /*#__PURE__*/Object.freeze({
|
|
|
29338
29330
|
canChartParseLabels: canChartParseLabels,
|
|
29339
29331
|
getBarChartData: getBarChartData,
|
|
29340
29332
|
getBarChartDatasets: getBarChartDatasets,
|
|
29341
|
-
getBarChartLayout: getBarChartLayout,
|
|
29342
29333
|
getBarChartLegend: getBarChartLegend,
|
|
29343
29334
|
getBarChartScales: getBarChartScales,
|
|
29344
29335
|
getBarChartTooltip: getBarChartTooltip,
|
|
29345
29336
|
getChartLabelFormat: getChartLabelFormat,
|
|
29337
|
+
getChartLayout: getChartLayout,
|
|
29346
29338
|
getChartShowValues: getChartShowValues,
|
|
29347
29339
|
getChartTitle: getChartTitle,
|
|
29348
29340
|
getComboChartDatasets: getComboChartDatasets,
|
|
29349
29341
|
getComboChartLegend: getComboChartLegend,
|
|
29350
|
-
getCommonChartLayout: getCommonChartLayout,
|
|
29351
29342
|
getData: getData,
|
|
29352
29343
|
getLineChartData: getLineChartData,
|
|
29353
29344
|
getLineChartDatasets: getLineChartDatasets,
|
|
29354
|
-
getLineChartLayout: getLineChartLayout,
|
|
29355
29345
|
getLineChartLegend: getLineChartLegend,
|
|
29356
29346
|
getLineChartScales: getLineChartScales,
|
|
29357
29347
|
getLineChartTooltip: getLineChartTooltip,
|
|
29358
29348
|
getPieChartData: getPieChartData,
|
|
29359
29349
|
getPieChartDatasets: getPieChartDatasets,
|
|
29360
|
-
getPieChartLayout: getPieChartLayout,
|
|
29361
29350
|
getPieChartLegend: getPieChartLegend,
|
|
29362
29351
|
getPieChartTooltip: getPieChartTooltip,
|
|
29363
29352
|
getPyramidChartData: getPyramidChartData,
|
|
@@ -29373,7 +29362,6 @@ var CHART_RUNTIME_HELPERS = /*#__PURE__*/Object.freeze({
|
|
|
29373
29362
|
getScatterChartScales: getScatterChartScales,
|
|
29374
29363
|
getTrendDatasetForBarChart: getTrendDatasetForBarChart,
|
|
29375
29364
|
getTrendDatasetForLineChart: getTrendDatasetForLineChart,
|
|
29376
|
-
getWaterfallChartLayout: getWaterfallChartLayout,
|
|
29377
29365
|
getWaterfallChartLegend: getWaterfallChartLegend,
|
|
29378
29366
|
getWaterfallChartScales: getWaterfallChartScales,
|
|
29379
29367
|
getWaterfallChartTooltip: getWaterfallChartTooltip,
|
|
@@ -29521,7 +29509,7 @@ function createBarChartRuntime(chart, getters) {
|
|
|
29521
29509
|
options: {
|
|
29522
29510
|
...CHART_COMMON_OPTIONS,
|
|
29523
29511
|
indexAxis: chart.horizontal ? "y" : "x",
|
|
29524
|
-
layout:
|
|
29512
|
+
layout: getChartLayout(),
|
|
29525
29513
|
scales: getBarChartScales(definition, chartData),
|
|
29526
29514
|
plugins: {
|
|
29527
29515
|
title: getChartTitle(definition),
|
|
@@ -29673,7 +29661,7 @@ function createComboChartRuntime(chart, getters) {
|
|
|
29673
29661
|
},
|
|
29674
29662
|
options: {
|
|
29675
29663
|
...CHART_COMMON_OPTIONS,
|
|
29676
|
-
layout:
|
|
29664
|
+
layout: getChartLayout(),
|
|
29677
29665
|
scales: getBarChartScales(definition, chartData),
|
|
29678
29666
|
plugins: {
|
|
29679
29667
|
title: getChartTitle(definition),
|
|
@@ -30074,7 +30062,7 @@ function createLineChartRuntime(chart, getters) {
|
|
|
30074
30062
|
},
|
|
30075
30063
|
options: {
|
|
30076
30064
|
...CHART_COMMON_OPTIONS,
|
|
30077
|
-
layout:
|
|
30065
|
+
layout: getChartLayout(),
|
|
30078
30066
|
scales: getLineChartScales(definition, chartData),
|
|
30079
30067
|
plugins: {
|
|
30080
30068
|
title: getChartTitle(definition),
|
|
@@ -30209,7 +30197,7 @@ function createPieChartRuntime(chart, getters) {
|
|
|
30209
30197
|
},
|
|
30210
30198
|
options: {
|
|
30211
30199
|
...CHART_COMMON_OPTIONS,
|
|
30212
|
-
layout:
|
|
30200
|
+
layout: getChartLayout(),
|
|
30213
30201
|
plugins: {
|
|
30214
30202
|
title: getChartTitle(definition),
|
|
30215
30203
|
legend: getPieChartLegend(definition, chartData),
|
|
@@ -30346,7 +30334,7 @@ function createPyramidChartRuntime(chart, getters) {
|
|
|
30346
30334
|
options: {
|
|
30347
30335
|
...CHART_COMMON_OPTIONS,
|
|
30348
30336
|
indexAxis: "y",
|
|
30349
|
-
layout:
|
|
30337
|
+
layout: getChartLayout(),
|
|
30350
30338
|
scales: getPyramidChartScales(definition, chartData),
|
|
30351
30339
|
plugins: {
|
|
30352
30340
|
title: getChartTitle(definition),
|
|
@@ -30495,7 +30483,7 @@ function createRadarChartRuntime(chart, getters) {
|
|
|
30495
30483
|
},
|
|
30496
30484
|
options: {
|
|
30497
30485
|
...CHART_COMMON_OPTIONS,
|
|
30498
|
-
layout:
|
|
30486
|
+
layout: getChartLayout(),
|
|
30499
30487
|
scales: getRadarChartScales(definition, chartData),
|
|
30500
30488
|
plugins: {
|
|
30501
30489
|
title: getChartTitle(definition),
|
|
@@ -30648,7 +30636,7 @@ function createScatterChartRuntime(chart, getters) {
|
|
|
30648
30636
|
},
|
|
30649
30637
|
options: {
|
|
30650
30638
|
...CHART_COMMON_OPTIONS,
|
|
30651
|
-
layout:
|
|
30639
|
+
layout: getChartLayout(),
|
|
30652
30640
|
scales: getScatterChartScales(definition, chartData),
|
|
30653
30641
|
plugins: {
|
|
30654
30642
|
title: getChartTitle(definition),
|
|
@@ -30809,7 +30797,7 @@ function createWaterfallChartRuntime(chart, getters) {
|
|
|
30809
30797
|
},
|
|
30810
30798
|
options: {
|
|
30811
30799
|
...CHART_COMMON_OPTIONS,
|
|
30812
|
-
layout:
|
|
30800
|
+
layout: getChartLayout(),
|
|
30813
30801
|
scales: getWaterfallChartScales(definition, chartData),
|
|
30814
30802
|
plugins: {
|
|
30815
30803
|
title: getChartTitle(definition),
|
|
@@ -33119,6 +33107,7 @@ var CHART_HELPERS = /*#__PURE__*/Object.freeze({
|
|
|
33119
33107
|
adaptChartRange: adaptChartRange,
|
|
33120
33108
|
chartFactory: chartFactory,
|
|
33121
33109
|
chartFontColor: chartFontColor,
|
|
33110
|
+
chartMutedFontColor: chartMutedFontColor,
|
|
33122
33111
|
chartRuntimeFactory: chartRuntimeFactory,
|
|
33123
33112
|
chartToImage: chartToImage,
|
|
33124
33113
|
checkDataset: checkDataset,
|
|
@@ -37411,6 +37400,95 @@ class ColorPickerWidget extends owl.Component {
|
|
|
37411
37400
|
}
|
|
37412
37401
|
}
|
|
37413
37402
|
|
|
37403
|
+
css /* scss */ `
|
|
37404
|
+
.o-font-size-editor {
|
|
37405
|
+
height: calc(100% - 4px);
|
|
37406
|
+
input.o-font-size {
|
|
37407
|
+
outline-color: ${SELECTION_BORDER_COLOR};
|
|
37408
|
+
height: 20px;
|
|
37409
|
+
width: 23px;
|
|
37410
|
+
}
|
|
37411
|
+
}
|
|
37412
|
+
.o-text-options > div {
|
|
37413
|
+
cursor: pointer;
|
|
37414
|
+
line-height: 26px;
|
|
37415
|
+
padding: 3px 12px;
|
|
37416
|
+
&:hover {
|
|
37417
|
+
background-color: rgba(0, 0, 0, 0.08);
|
|
37418
|
+
}
|
|
37419
|
+
}
|
|
37420
|
+
`;
|
|
37421
|
+
class FontSizeEditor extends owl.Component {
|
|
37422
|
+
static template = "o-spreadsheet-FontSizeEditor";
|
|
37423
|
+
static props = {
|
|
37424
|
+
currentFontSize: Number,
|
|
37425
|
+
onFontSizeChanged: Function,
|
|
37426
|
+
onToggle: { type: Function, optional: true },
|
|
37427
|
+
class: String,
|
|
37428
|
+
};
|
|
37429
|
+
static components = { Popover };
|
|
37430
|
+
fontSizes = FONT_SIZES;
|
|
37431
|
+
dropdown = owl.useState({ isOpen: false });
|
|
37432
|
+
inputRef = owl.useRef("inputFontSize");
|
|
37433
|
+
rootEditorRef = owl.useRef("FontSizeEditor");
|
|
37434
|
+
fontSizeListRef = owl.useRef("fontSizeList");
|
|
37435
|
+
setup() {
|
|
37436
|
+
owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
37437
|
+
}
|
|
37438
|
+
get popoverProps() {
|
|
37439
|
+
const { x, y, width, height } = this.rootEditorRef.el.getBoundingClientRect();
|
|
37440
|
+
return {
|
|
37441
|
+
anchorRect: { x, y, width, height },
|
|
37442
|
+
positioning: "BottomLeft",
|
|
37443
|
+
verticalOffset: 0,
|
|
37444
|
+
};
|
|
37445
|
+
}
|
|
37446
|
+
onExternalClick(ev) {
|
|
37447
|
+
if (!isChildEvent(this.fontSizeListRef.el, ev) && !isChildEvent(this.rootEditorRef.el, ev)) {
|
|
37448
|
+
this.closeFontList();
|
|
37449
|
+
}
|
|
37450
|
+
}
|
|
37451
|
+
toggleFontList() {
|
|
37452
|
+
const isOpen = this.dropdown.isOpen;
|
|
37453
|
+
if (!isOpen) {
|
|
37454
|
+
this.props.onToggle?.();
|
|
37455
|
+
this.inputRef.el.focus();
|
|
37456
|
+
}
|
|
37457
|
+
else {
|
|
37458
|
+
this.closeFontList();
|
|
37459
|
+
}
|
|
37460
|
+
}
|
|
37461
|
+
closeFontList() {
|
|
37462
|
+
this.dropdown.isOpen = false;
|
|
37463
|
+
}
|
|
37464
|
+
setSize(fontSizeStr) {
|
|
37465
|
+
const fontSize = clip(Math.floor(parseFloat(fontSizeStr)), 1, 400);
|
|
37466
|
+
this.props.onFontSizeChanged(fontSize);
|
|
37467
|
+
this.closeFontList();
|
|
37468
|
+
}
|
|
37469
|
+
setSizeFromInput(ev) {
|
|
37470
|
+
this.setSize(ev.target.value);
|
|
37471
|
+
}
|
|
37472
|
+
setSizeFromList(fontSizeStr) {
|
|
37473
|
+
this.setSize(fontSizeStr);
|
|
37474
|
+
}
|
|
37475
|
+
onInputFocused(ev) {
|
|
37476
|
+
this.dropdown.isOpen = true;
|
|
37477
|
+
ev.target.select();
|
|
37478
|
+
}
|
|
37479
|
+
onInputKeydown(ev) {
|
|
37480
|
+
if (ev.key === "Enter" || ev.key === "Escape") {
|
|
37481
|
+
this.closeFontList();
|
|
37482
|
+
const target = ev.target;
|
|
37483
|
+
// In the case of a ESCAPE key, we get the previous font size back
|
|
37484
|
+
if (ev.key === "Escape") {
|
|
37485
|
+
target.value = `${this.props.currentFontSize}`;
|
|
37486
|
+
}
|
|
37487
|
+
this.props.onToggle?.();
|
|
37488
|
+
}
|
|
37489
|
+
}
|
|
37490
|
+
}
|
|
37491
|
+
|
|
37414
37492
|
css /* scss */ `
|
|
37415
37493
|
.o-chart-title-designer {
|
|
37416
37494
|
> span {
|
|
@@ -37445,7 +37523,7 @@ css /* scss */ `
|
|
|
37445
37523
|
`;
|
|
37446
37524
|
class ChartTitle extends owl.Component {
|
|
37447
37525
|
static template = "o-spreadsheet.ChartTitle";
|
|
37448
|
-
static components = { Section, ColorPickerWidget };
|
|
37526
|
+
static components = { Section, ColorPickerWidget, FontSizeEditor };
|
|
37449
37527
|
static props = {
|
|
37450
37528
|
title: { type: String, optional: true },
|
|
37451
37529
|
updateTitle: Function,
|
|
@@ -37454,7 +37532,8 @@ class ChartTitle extends owl.Component {
|
|
|
37454
37532
|
toggleBold: { type: Function, optional: true },
|
|
37455
37533
|
updateAlignment: { type: Function, optional: true },
|
|
37456
37534
|
updateColor: { type: Function, optional: true },
|
|
37457
|
-
style:
|
|
37535
|
+
style: Object,
|
|
37536
|
+
onFontSizeChanged: Function,
|
|
37458
37537
|
};
|
|
37459
37538
|
static defaultProps = {
|
|
37460
37539
|
title: "",
|
|
@@ -37469,6 +37548,9 @@ class ChartTitle extends owl.Component {
|
|
|
37469
37548
|
updateTitle(ev) {
|
|
37470
37549
|
this.props.updateTitle(ev.target.value);
|
|
37471
37550
|
}
|
|
37551
|
+
updateFontSize(fontSize) {
|
|
37552
|
+
this.props.onFontSizeChanged(fontSize);
|
|
37553
|
+
}
|
|
37472
37554
|
toggleDropdownTool(tool, ev) {
|
|
37473
37555
|
const isOpen = this.state.activeTool === tool;
|
|
37474
37556
|
this.closeMenus();
|
|
@@ -37511,6 +37593,7 @@ class AxisDesignEditor extends owl.Component {
|
|
|
37511
37593
|
return {
|
|
37512
37594
|
color: "",
|
|
37513
37595
|
align: "center",
|
|
37596
|
+
fontSize: CHART_AXIS_TITLE_FONT_SIZE,
|
|
37514
37597
|
...axisDesign.title,
|
|
37515
37598
|
};
|
|
37516
37599
|
}
|
|
@@ -37528,6 +37611,17 @@ class AxisDesignEditor extends owl.Component {
|
|
|
37528
37611
|
};
|
|
37529
37612
|
this.props.updateChart(this.props.figureId, { axesDesign });
|
|
37530
37613
|
}
|
|
37614
|
+
updateAxisTitleFontSize(fontSize) {
|
|
37615
|
+
const axesDesign = this.props.definition.axesDesign ?? {};
|
|
37616
|
+
axesDesign[this.state.currentAxis] = {
|
|
37617
|
+
...axesDesign[this.state.currentAxis],
|
|
37618
|
+
title: {
|
|
37619
|
+
...(axesDesign[this.state.currentAxis]?.title ?? {}),
|
|
37620
|
+
fontSize,
|
|
37621
|
+
},
|
|
37622
|
+
};
|
|
37623
|
+
this.props.updateChart(this.props.figureId, { axesDesign });
|
|
37624
|
+
}
|
|
37531
37625
|
toggleBoldAxisTitle() {
|
|
37532
37626
|
const axesDesign = this.props.definition.axesDesign ?? {};
|
|
37533
37627
|
const title = axesDesign[this.state.currentAxis]?.title ?? {};
|
|
@@ -37647,8 +37741,12 @@ class GeneralDesignEditor extends owl.Component {
|
|
|
37647
37741
|
figureId: String,
|
|
37648
37742
|
definition: Object,
|
|
37649
37743
|
updateChart: Function,
|
|
37744
|
+
defaultChartTitleFontSize: { type: Number, optional: true },
|
|
37650
37745
|
slots: { type: Object, optional: true },
|
|
37651
37746
|
};
|
|
37747
|
+
static defaultProps = {
|
|
37748
|
+
defaultChartTitleFontSize: CHART_TITLE_FONT_SIZE,
|
|
37749
|
+
};
|
|
37652
37750
|
state;
|
|
37653
37751
|
setup() {
|
|
37654
37752
|
this.state = owl.useState({
|
|
@@ -37674,6 +37772,7 @@ class GeneralDesignEditor extends owl.Component {
|
|
|
37674
37772
|
get titleStyle() {
|
|
37675
37773
|
return {
|
|
37676
37774
|
align: "left",
|
|
37775
|
+
fontSize: this.props.defaultChartTitleFontSize,
|
|
37677
37776
|
...this.title,
|
|
37678
37777
|
};
|
|
37679
37778
|
}
|
|
@@ -37682,6 +37781,10 @@ class GeneralDesignEditor extends owl.Component {
|
|
|
37682
37781
|
this.props.updateChart(this.props.figureId, { title });
|
|
37683
37782
|
this.state.activeTool = "";
|
|
37684
37783
|
}
|
|
37784
|
+
updateChartTitleFontSize(fontSize) {
|
|
37785
|
+
const title = { ...this.title, fontSize };
|
|
37786
|
+
this.props.updateChart(this.props.figureId, { title });
|
|
37787
|
+
}
|
|
37685
37788
|
toggleBoldChartTitle() {
|
|
37686
37789
|
let title = this.title;
|
|
37687
37790
|
title = { ...title, bold: !title.bold };
|
|
@@ -37889,7 +37992,7 @@ class SeriesWithAxisDesignEditor extends owl.Component {
|
|
|
37889
37992
|
case "polynomial":
|
|
37890
37993
|
config = {
|
|
37891
37994
|
type: "polynomial",
|
|
37892
|
-
order: type === "linear" ? 1 :
|
|
37995
|
+
order: type === "linear" ? 1 : this.getMaxPolynomialDegree(index),
|
|
37893
37996
|
};
|
|
37894
37997
|
break;
|
|
37895
37998
|
case "exponential":
|
|
@@ -38349,6 +38452,9 @@ class ScorecardChartDesignPanel extends owl.Component {
|
|
|
38349
38452
|
get humanizeNumbersLabel() {
|
|
38350
38453
|
return _t("Humanize numbers");
|
|
38351
38454
|
}
|
|
38455
|
+
get defaultScorecardTitleFontSize() {
|
|
38456
|
+
return SCORECARD_CHART_TITLE_FONT_SIZE;
|
|
38457
|
+
}
|
|
38352
38458
|
updateHumanizeNumbers(humanize) {
|
|
38353
38459
|
this.props.updateChart(this.props.figureId, { humanize });
|
|
38354
38460
|
}
|
|
@@ -39812,6 +39918,15 @@ class StandaloneComposerStore extends AbstractComposerStore {
|
|
|
39812
39918
|
confirmEdition(content) {
|
|
39813
39919
|
this.args().onConfirm(content);
|
|
39814
39920
|
}
|
|
39921
|
+
getTokenColor(token) {
|
|
39922
|
+
if (token.type === "SYMBOL") {
|
|
39923
|
+
const matchedColor = this.args().getContextualColoredSymbolToken?.(token);
|
|
39924
|
+
if (matchedColor) {
|
|
39925
|
+
return matchedColor;
|
|
39926
|
+
}
|
|
39927
|
+
}
|
|
39928
|
+
return super.getTokenColor(token);
|
|
39929
|
+
}
|
|
39815
39930
|
}
|
|
39816
39931
|
|
|
39817
39932
|
css /* scss */ `
|
|
@@ -39849,6 +39964,7 @@ class StandaloneComposer extends owl.Component {
|
|
|
39849
39964
|
placeholder: { type: String, optional: true },
|
|
39850
39965
|
class: { type: String, optional: true },
|
|
39851
39966
|
invalid: { type: Boolean, optional: true },
|
|
39967
|
+
getContextualColoredSymbolToken: { type: Function, optional: true },
|
|
39852
39968
|
};
|
|
39853
39969
|
static components = { Composer };
|
|
39854
39970
|
static defaultProps = {
|
|
@@ -39865,6 +39981,7 @@ class StandaloneComposer extends owl.Component {
|
|
|
39865
39981
|
content: this.props.composerContent,
|
|
39866
39982
|
contextualAutocomplete: this.props.contextualAutocomplete,
|
|
39867
39983
|
defaultRangeSheetId: this.props.defaultRangeSheetId,
|
|
39984
|
+
getContextualColoredSymbolToken: this.props.getContextualColoredSymbolToken,
|
|
39868
39985
|
}));
|
|
39869
39986
|
this.standaloneComposerStore = standaloneComposerStore;
|
|
39870
39987
|
this.composerInterface = {
|
|
@@ -43425,7 +43542,7 @@ function createMeasureAutoComplete(pivot, forComputedMeasure) {
|
|
|
43425
43542
|
return {
|
|
43426
43543
|
text: text,
|
|
43427
43544
|
description: measure.displayName,
|
|
43428
|
-
htmlContent: [{ value: text, color:
|
|
43545
|
+
htmlContent: [{ value: text, color: PIVOT_TOKEN_COLOR }],
|
|
43429
43546
|
fuzzySearchKey: measure.displayName + text + measure.fieldName,
|
|
43430
43547
|
};
|
|
43431
43548
|
});
|
|
@@ -43434,7 +43551,7 @@ function createMeasureAutoComplete(pivot, forComputedMeasure) {
|
|
|
43434
43551
|
return {
|
|
43435
43552
|
text: text,
|
|
43436
43553
|
description: dimension.displayName,
|
|
43437
|
-
htmlContent: [{ value: text, color:
|
|
43554
|
+
htmlContent: [{ value: text, color: PIVOT_TOKEN_COLOR }],
|
|
43438
43555
|
fuzzySearchKey: dimension.displayName + text + dimension.fieldName,
|
|
43439
43556
|
};
|
|
43440
43557
|
});
|
|
@@ -43514,6 +43631,18 @@ class PivotMeasureEditor extends owl.Component {
|
|
|
43514
43631
|
measure: this.props.measure,
|
|
43515
43632
|
});
|
|
43516
43633
|
}
|
|
43634
|
+
getColoredSymbolToken(token) {
|
|
43635
|
+
if (token.type !== "SYMBOL") {
|
|
43636
|
+
return undefined;
|
|
43637
|
+
}
|
|
43638
|
+
const tokenValue = unquote(token.value, "'");
|
|
43639
|
+
if (this.props.definition.columns.some((col) => col.nameWithGranularity === tokenValue) ||
|
|
43640
|
+
this.props.definition.rows.some((row) => row.nameWithGranularity === tokenValue) ||
|
|
43641
|
+
this.props.definition.measures.some((measure) => measure.id === tokenValue && measure.id !== this.props.measure.id)) {
|
|
43642
|
+
return PIVOT_TOKEN_COLOR;
|
|
43643
|
+
}
|
|
43644
|
+
return undefined;
|
|
43645
|
+
}
|
|
43517
43646
|
}
|
|
43518
43647
|
|
|
43519
43648
|
css /* scss */ `
|
|
@@ -51888,7 +52017,7 @@ class CellPlugin extends CorePlugin {
|
|
|
51888
52017
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
51889
52018
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
51890
52019
|
const cell = this.getters.getCell({ sheetId, col, row });
|
|
51891
|
-
if (cell) {
|
|
52020
|
+
if (cell?.isFormula || cell?.content) {
|
|
51892
52021
|
this.dispatch("UPDATE_CELL", {
|
|
51893
52022
|
sheetId: sheetId,
|
|
51894
52023
|
content: "",
|
|
@@ -51924,7 +52053,6 @@ class CellPlugin extends CorePlugin {
|
|
|
51924
52053
|
for (let zone of recomputeZones(zones)) {
|
|
51925
52054
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
51926
52055
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
51927
|
-
// commandHelpers.updateCell(sheetId, col, row, { style: undefined});
|
|
51928
52056
|
this.dispatch("UPDATE_CELL", {
|
|
51929
52057
|
sheetId,
|
|
51930
52058
|
col,
|
|
@@ -55343,7 +55471,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
55343
55471
|
if (orderedSheetIds.find((id) => sheets[id]?.name.toLowerCase() === name && id !== cmd.sheetId)) {
|
|
55344
55472
|
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
55345
55473
|
}
|
|
55346
|
-
if (
|
|
55474
|
+
if (FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX.test(name)) {
|
|
55347
55475
|
return "ForbiddenCharactersInSheetName" /* CommandResult.ForbiddenCharactersInSheetName */;
|
|
55348
55476
|
}
|
|
55349
55477
|
return "Success" /* CommandResult.Success */;
|
|
@@ -60751,11 +60879,13 @@ class PivotUIPlugin extends UIPlugin {
|
|
|
60751
60879
|
return EMPTY_PIVOT_CELL;
|
|
60752
60880
|
}
|
|
60753
60881
|
if (functionName === "PIVOT") {
|
|
60754
|
-
const includeTotal = args[2]
|
|
60755
|
-
const
|
|
60882
|
+
const includeTotal = toScalar(args[2]);
|
|
60883
|
+
const shouldIncludeTotal = includeTotal === undefined ? true : toBoolean(includeTotal);
|
|
60884
|
+
const includeColumnHeaders = toScalar(args[3]);
|
|
60885
|
+
const shouldIncludeColumnHeaders = includeColumnHeaders === undefined ? true : toBoolean(includeColumnHeaders);
|
|
60756
60886
|
const pivotCells = pivot
|
|
60757
60887
|
.getTableStructure()
|
|
60758
|
-
.getPivotCells(
|
|
60888
|
+
.getPivotCells(shouldIncludeTotal, shouldIncludeColumnHeaders);
|
|
60759
60889
|
const pivotCol = position.col - mainPosition.col;
|
|
60760
60890
|
const pivotRow = position.row - mainPosition.row;
|
|
60761
60891
|
return pivotCells[pivotCol][pivotRow];
|
|
@@ -62909,7 +63039,7 @@ class InsertPivotPlugin extends UIPlugin {
|
|
|
62909
63039
|
getPivotDuplicateSheetName(pivotName) {
|
|
62910
63040
|
let i = 1;
|
|
62911
63041
|
const names = this.getters.getSheetIds().map((id) => this.getters.getSheetName(id));
|
|
62912
|
-
const sanitizedName = pivotName
|
|
63042
|
+
const sanitizedName = sanitizeSheetName(pivotName);
|
|
62913
63043
|
let name = sanitizedName;
|
|
62914
63044
|
while (names.includes(name)) {
|
|
62915
63045
|
name = `${sanitizedName} (${i})`;
|
|
@@ -66985,7 +67115,7 @@ function interactiveRenameSheet(env, sheetId, name, errorCallback) {
|
|
|
66985
67115
|
env.raiseError(_t("A sheet with the name %s already exists. Please select another name.", name), errorCallback);
|
|
66986
67116
|
}
|
|
66987
67117
|
else if (result.reasons.includes("ForbiddenCharactersInSheetName" /* CommandResult.ForbiddenCharactersInSheetName */)) {
|
|
66988
|
-
env.raiseError(_t("Some used characters are not allowed in a sheet name (Forbidden characters are %s).",
|
|
67118
|
+
env.raiseError(_t("Some used characters are not allowed in a sheet name (Forbidden characters are %s).", FORBIDDEN_SHEETNAME_CHARS.join(" ")), errorCallback);
|
|
66989
67119
|
}
|
|
66990
67120
|
}
|
|
66991
67121
|
|
|
@@ -68215,7 +68345,7 @@ class ActionButton extends owl.Component {
|
|
|
68215
68345
|
setup() {
|
|
68216
68346
|
owl.onWillUpdateProps((nextProps) => {
|
|
68217
68347
|
if (nextProps.action !== this.props.action) {
|
|
68218
|
-
this.actionButton = createAction(
|
|
68348
|
+
this.actionButton = createAction(nextProps.action);
|
|
68219
68349
|
}
|
|
68220
68350
|
});
|
|
68221
68351
|
}
|
|
@@ -68551,88 +68681,6 @@ class TopBarComposer extends owl.Component {
|
|
|
68551
68681
|
}
|
|
68552
68682
|
}
|
|
68553
68683
|
|
|
68554
|
-
css /* scss */ `
|
|
68555
|
-
.o-font-size-editor {
|
|
68556
|
-
height: calc(100% - 4px);
|
|
68557
|
-
input.o-font-size {
|
|
68558
|
-
outline-color: ${SELECTION_BORDER_COLOR};
|
|
68559
|
-
height: 20px;
|
|
68560
|
-
width: 23px;
|
|
68561
|
-
}
|
|
68562
|
-
}
|
|
68563
|
-
.o-text-options > div {
|
|
68564
|
-
cursor: pointer;
|
|
68565
|
-
line-height: 26px;
|
|
68566
|
-
padding: 3px 12px;
|
|
68567
|
-
&:hover {
|
|
68568
|
-
background-color: rgba(0, 0, 0, 0.08);
|
|
68569
|
-
}
|
|
68570
|
-
}
|
|
68571
|
-
`;
|
|
68572
|
-
class FontSizeEditor extends owl.Component {
|
|
68573
|
-
static template = "o-spreadsheet-FontSizeEditor";
|
|
68574
|
-
static props = {
|
|
68575
|
-
onToggle: Function,
|
|
68576
|
-
dropdownStyle: String,
|
|
68577
|
-
class: String,
|
|
68578
|
-
};
|
|
68579
|
-
static components = {};
|
|
68580
|
-
fontSizes = FONT_SIZES;
|
|
68581
|
-
dropdown = owl.useState({ isOpen: false });
|
|
68582
|
-
inputRef = owl.useRef("inputFontSize");
|
|
68583
|
-
rootEditorRef = owl.useRef("FontSizeEditor");
|
|
68584
|
-
setup() {
|
|
68585
|
-
owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
68586
|
-
}
|
|
68587
|
-
onExternalClick(ev) {
|
|
68588
|
-
if (!isChildEvent(this.rootEditorRef.el, ev)) {
|
|
68589
|
-
this.closeFontList();
|
|
68590
|
-
}
|
|
68591
|
-
}
|
|
68592
|
-
get currentFontSize() {
|
|
68593
|
-
return this.env.model.getters.getCurrentStyle().fontSize || DEFAULT_FONT_SIZE;
|
|
68594
|
-
}
|
|
68595
|
-
toggleFontList() {
|
|
68596
|
-
const isOpen = this.dropdown.isOpen;
|
|
68597
|
-
if (!isOpen) {
|
|
68598
|
-
this.props.onToggle();
|
|
68599
|
-
this.inputRef.el.focus();
|
|
68600
|
-
}
|
|
68601
|
-
else {
|
|
68602
|
-
this.closeFontList();
|
|
68603
|
-
}
|
|
68604
|
-
}
|
|
68605
|
-
closeFontList() {
|
|
68606
|
-
this.dropdown.isOpen = false;
|
|
68607
|
-
}
|
|
68608
|
-
setSize(fontSizeStr) {
|
|
68609
|
-
const fontSize = clip(Math.floor(parseFloat(fontSizeStr)), 1, 400);
|
|
68610
|
-
setStyle(this.env, { fontSize });
|
|
68611
|
-
this.closeFontList();
|
|
68612
|
-
}
|
|
68613
|
-
setSizeFromInput(ev) {
|
|
68614
|
-
this.setSize(ev.target.value);
|
|
68615
|
-
}
|
|
68616
|
-
setSizeFromList(fontSizeStr) {
|
|
68617
|
-
this.setSize(fontSizeStr);
|
|
68618
|
-
}
|
|
68619
|
-
onInputFocused(ev) {
|
|
68620
|
-
this.dropdown.isOpen = true;
|
|
68621
|
-
ev.target.select();
|
|
68622
|
-
}
|
|
68623
|
-
onInputKeydown(ev) {
|
|
68624
|
-
if (ev.key === "Enter" || ev.key === "Escape") {
|
|
68625
|
-
this.closeFontList();
|
|
68626
|
-
const target = ev.target;
|
|
68627
|
-
// In the case of a ESCAPE key, we get the previous font size back
|
|
68628
|
-
if (ev.key === "Escape") {
|
|
68629
|
-
target.value = `${this.currentFontSize}`;
|
|
68630
|
-
}
|
|
68631
|
-
this.props.onToggle();
|
|
68632
|
-
}
|
|
68633
|
-
}
|
|
68634
|
-
}
|
|
68635
|
-
|
|
68636
68684
|
class TableDropdownButton extends owl.Component {
|
|
68637
68685
|
static template = "o-spreadsheet-TableDropdownButton";
|
|
68638
68686
|
static components = { TableStylesPopover, ActionButton };
|
|
@@ -68801,9 +68849,6 @@ class TopBar extends owl.Component {
|
|
|
68801
68849
|
onClick: Function,
|
|
68802
68850
|
dropdownMaxHeight: Number,
|
|
68803
68851
|
};
|
|
68804
|
-
get dropdownStyle() {
|
|
68805
|
-
return `max-height:${this.props.dropdownMaxHeight}px`;
|
|
68806
|
-
}
|
|
68807
68852
|
static components = {
|
|
68808
68853
|
ColorPickerWidget,
|
|
68809
68854
|
ColorPicker,
|
|
@@ -68841,6 +68886,9 @@ class TopBar extends owl.Component {
|
|
|
68841
68886
|
.getAllOrdered()
|
|
68842
68887
|
.filter((item) => !item.isVisible || item.isVisible(this.env));
|
|
68843
68888
|
}
|
|
68889
|
+
get currentFontSize() {
|
|
68890
|
+
return this.env.model.getters.getCurrentStyle().fontSize || DEFAULT_FONT_SIZE;
|
|
68891
|
+
}
|
|
68844
68892
|
onExternalClick(ev) {
|
|
68845
68893
|
// TODO : manage click events better. We need this piece of code
|
|
68846
68894
|
// otherwise the event opening the menu would close it on the same frame.
|
|
@@ -68919,6 +68967,9 @@ class TopBar extends owl.Component {
|
|
|
68919
68967
|
setStyle(this.env, { [target]: color });
|
|
68920
68968
|
this.onClick();
|
|
68921
68969
|
}
|
|
68970
|
+
setFontSize(fontSize) {
|
|
68971
|
+
setStyle(this.env, { fontSize });
|
|
68972
|
+
}
|
|
68922
68973
|
}
|
|
68923
68974
|
|
|
68924
68975
|
function instantiateClipboard() {
|
|
@@ -70919,12 +70970,11 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
70919
70970
|
// <manualLayout/> to manually position the chart in the figure container
|
|
70920
70971
|
let title = escapeXml ``;
|
|
70921
70972
|
if (chart.data.title?.text) {
|
|
70922
|
-
const
|
|
70923
|
-
|
|
70924
|
-
: chart.data.fontColor;
|
|
70973
|
+
const titleColor = toXlsxHexColor(chartMutedFontColor(chart.data.backgroundColor));
|
|
70974
|
+
const fontSize = chart.data.title.fontSize ?? CHART_TITLE_FONT_SIZE;
|
|
70925
70975
|
title = escapeXml /*xml*/ `
|
|
70926
70976
|
<c:title>
|
|
70927
|
-
${insertText(chart.data.title.text,
|
|
70977
|
+
${insertText(chart.data.title.text, titleColor, fontSize, chart.data.title)}
|
|
70928
70978
|
<c:overlay val="0" />
|
|
70929
70979
|
</c:title>
|
|
70930
70980
|
`;
|
|
@@ -71014,7 +71064,7 @@ function lineAttributes(params) {
|
|
|
71014
71064
|
</a:ln>
|
|
71015
71065
|
`;
|
|
71016
71066
|
}
|
|
71017
|
-
function insertText(text, fontColor = "000000", fontsize =
|
|
71067
|
+
function insertText(text, fontColor = "000000", fontsize = CHART_TITLE_FONT_SIZE, style = {}) {
|
|
71018
71068
|
return escapeXml /*xml*/ `
|
|
71019
71069
|
<c:tx>
|
|
71020
71070
|
<c:rich>
|
|
@@ -71515,6 +71565,7 @@ function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, del
|
|
|
71515
71565
|
// Each Axis present inside a graph needs to be identified by an unsigned integer in order to be referenced by its crossAxis.
|
|
71516
71566
|
// I.e. x-axis, will reference y-axis and vice-versa.
|
|
71517
71567
|
const color = title?.color ? toXlsxHexColor(title.color) : defaultFontColor;
|
|
71568
|
+
const fontSize = title?.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE;
|
|
71518
71569
|
return escapeXml /*xml*/ `
|
|
71519
71570
|
<${axisName}>
|
|
71520
71571
|
<c:axId val="${axId}"/>
|
|
@@ -71530,7 +71581,7 @@ function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, del
|
|
|
71530
71581
|
<c:minorTickMark val="none" />
|
|
71531
71582
|
<c:numFmt formatCode="General" sourceLinked="1" />
|
|
71532
71583
|
<c:title>
|
|
71533
|
-
${insertText(title?.text ?? "", color,
|
|
71584
|
+
${insertText(title?.text ?? "", color, fontSize, title)}
|
|
71534
71585
|
</c:title>
|
|
71535
71586
|
${insertTextProperties(10, defaultFontColor)}
|
|
71536
71587
|
</${axisName}>
|
|
@@ -73641,6 +73692,7 @@ const helpers = {
|
|
|
73641
73692
|
createPivotFormula,
|
|
73642
73693
|
areDomainArgsFieldsValid,
|
|
73643
73694
|
splitReference,
|
|
73695
|
+
sanitizeSheetName,
|
|
73644
73696
|
};
|
|
73645
73697
|
const links = {
|
|
73646
73698
|
isMarkdownLink,
|
|
@@ -73779,6 +73831,6 @@ exports.tokenColors = tokenColors;
|
|
|
73779
73831
|
exports.tokenize = tokenize;
|
|
73780
73832
|
|
|
73781
73833
|
|
|
73782
|
-
__info__.version = "18.1.0-alpha.
|
|
73783
|
-
__info__.date = "2024-
|
|
73784
|
-
__info__.hash = "
|
|
73834
|
+
__info__.version = "18.1.0-alpha.7";
|
|
73835
|
+
__info__.date = "2024-12-05T10:40:26.512Z";
|
|
73836
|
+
__info__.hash = "7b1c39b";
|