@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
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -170,10 +170,13 @@ const ALERT_INFO_BG = "#CDEDF1";
|
|
|
170
170
|
const ALERT_INFO_BORDER = "#98DBE2";
|
|
171
171
|
const ALERT_INFO_TEXT_COLOR = "#09414A";
|
|
172
172
|
const BADGE_SELECTED_COLOR = "#E6F2F3";
|
|
173
|
-
const
|
|
174
|
-
const
|
|
175
|
-
const
|
|
176
|
-
const
|
|
173
|
+
const CHART_PADDING$1 = 20;
|
|
174
|
+
const CHART_PADDING_BOTTOM = 10;
|
|
175
|
+
const CHART_PADDING_TOP = 15;
|
|
176
|
+
const CHART_TITLE_FONT_SIZE = 16;
|
|
177
|
+
const CHART_AXIS_TITLE_FONT_SIZE = 12;
|
|
178
|
+
const SCORECARD_CHART_TITLE_FONT_SIZE = 14;
|
|
179
|
+
const PIVOT_TOKEN_COLOR = "#F28C28";
|
|
177
180
|
// Color picker defaults as upper case HEX to match `toHex`helper
|
|
178
181
|
const COLOR_PICKER_DEFAULTS = [
|
|
179
182
|
"#000000",
|
|
@@ -333,8 +336,8 @@ const DEFAULT_WINDOW_SIZE = 2;
|
|
|
333
336
|
const DEBOUNCE_TIME = 200;
|
|
334
337
|
const MESSAGE_VERSION = 1;
|
|
335
338
|
// Sheets
|
|
336
|
-
const
|
|
337
|
-
const
|
|
339
|
+
const FORBIDDEN_SHEETNAME_CHARS = ["'", "*", "?", "/", "\\", "[", "]"];
|
|
340
|
+
const FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX = /'|\*|\?|\/|\\|\[|\]/;
|
|
338
341
|
// Cells
|
|
339
342
|
const FORMULA_REF_IDENTIFIER = "|";
|
|
340
343
|
// Components
|
|
@@ -387,6 +390,7 @@ const DEFAULT_CURRENCY = {
|
|
|
387
390
|
//------------------------------------------------------------------------------
|
|
388
391
|
// Miscellaneous
|
|
389
392
|
//------------------------------------------------------------------------------
|
|
393
|
+
const sanitizeSheetNameRegex = new RegExp(FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX, "g");
|
|
390
394
|
/**
|
|
391
395
|
* Remove quotes from a quoted string
|
|
392
396
|
* ```js
|
|
@@ -482,6 +486,10 @@ function getCanonicalSymbolName(symbolName) {
|
|
|
482
486
|
}
|
|
483
487
|
return symbolName;
|
|
484
488
|
}
|
|
489
|
+
/** Replace the excel-excluded characters of a sheetName */
|
|
490
|
+
function sanitizeSheetName(sheetName, replacementChar = " ") {
|
|
491
|
+
return sheetName.replace(sanitizeSheetNameRegex, replacementChar);
|
|
492
|
+
}
|
|
485
493
|
function clip(val, min, max) {
|
|
486
494
|
return val < min ? min : val > max ? max : val;
|
|
487
495
|
}
|
|
@@ -9514,6 +9522,12 @@ function chartFontColor(backgroundColor) {
|
|
|
9514
9522
|
}
|
|
9515
9523
|
return relativeLuminance(backgroundColor) < 0.3 ? "#FFFFFF" : "#000000";
|
|
9516
9524
|
}
|
|
9525
|
+
function chartMutedFontColor(backgroundColor) {
|
|
9526
|
+
if (!backgroundColor) {
|
|
9527
|
+
return "#666666";
|
|
9528
|
+
}
|
|
9529
|
+
return relativeLuminance(backgroundColor) < 0.3 ? "#C8C8C8" : "#666666";
|
|
9530
|
+
}
|
|
9517
9531
|
function checkDataset(definition) {
|
|
9518
9532
|
if (definition.dataSets) {
|
|
9519
9533
|
const invalidRanges = definition.dataSets.find((range) => !rangeReference.test(range.dataRange)) !== undefined;
|
|
@@ -9649,8 +9663,8 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
|
|
|
9649
9663
|
const yMin = chart.chartArea.top;
|
|
9650
9664
|
const textsPositions = {};
|
|
9651
9665
|
for (const dataset of chart._metasets) {
|
|
9652
|
-
if (dataset.xAxisID === TREND_LINE_XAXIS_ID) {
|
|
9653
|
-
|
|
9666
|
+
if (dataset.xAxisID === TREND_LINE_XAXIS_ID || dataset.hidden) {
|
|
9667
|
+
continue;
|
|
9654
9668
|
}
|
|
9655
9669
|
for (let i = 0; i < dataset._parsed.length; i++) {
|
|
9656
9670
|
const parsedValue = dataset._parsed[i];
|
|
@@ -10097,7 +10111,7 @@ let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
|
|
|
10097
10111
|
function drawScoreChart(structure, canvas) {
|
|
10098
10112
|
const ctx = canvas.getContext("2d");
|
|
10099
10113
|
canvas.width = structure.canvas.width;
|
|
10100
|
-
const availableWidth = canvas.width -
|
|
10114
|
+
const availableWidth = canvas.width - CHART_PADDING$1 * 2;
|
|
10101
10115
|
canvas.height = structure.canvas.height;
|
|
10102
10116
|
ctx.fillStyle = structure.canvas.backgroundColor;
|
|
10103
10117
|
ctx.fillRect(0, 0, structure.canvas.width, structure.canvas.height);
|
|
@@ -10232,10 +10246,9 @@ function createScorecardChartRuntime(chart, getters) {
|
|
|
10232
10246
|
}
|
|
10233
10247
|
|
|
10234
10248
|
/* Padding at the border of the chart */
|
|
10235
|
-
const CHART_PADDING =
|
|
10249
|
+
const CHART_PADDING = 10;
|
|
10236
10250
|
const BOTTOM_PADDING_RATIO = 0.05;
|
|
10237
10251
|
/* Maximum font sizes of each element */
|
|
10238
|
-
const CHART_TITLE_FONT_SIZE = SCORECARD_GAUGE_CHART_FONT_SIZE;
|
|
10239
10252
|
const KEY_VALUE_FONT_SIZE = 32;
|
|
10240
10253
|
const BASELINE_MAX_FONT_SIZE = 16;
|
|
10241
10254
|
function formatBaselineDescr(baselineDescr, baseline) {
|
|
@@ -10307,7 +10320,7 @@ class ScorecardChartConfigBuilder {
|
|
|
10307
10320
|
: this.height - (this.height - titleHeight - baselineHeight) / 2 - CHART_PADDING,
|
|
10308
10321
|
},
|
|
10309
10322
|
};
|
|
10310
|
-
const minimalBaselinePosition = baselineArrowSize +
|
|
10323
|
+
const minimalBaselinePosition = baselineArrowSize + CHART_PADDING * 2;
|
|
10311
10324
|
if (structure.baseline.position.x < minimalBaselinePosition) {
|
|
10312
10325
|
structure.baseline.position.x = minimalBaselinePosition;
|
|
10313
10326
|
}
|
|
@@ -10387,7 +10400,7 @@ class ScorecardChartConfigBuilder {
|
|
|
10387
10400
|
return this.runtime.background;
|
|
10388
10401
|
}
|
|
10389
10402
|
get secondaryFontColor() {
|
|
10390
|
-
return
|
|
10403
|
+
return chartMutedFontColor(this.backgroundColor);
|
|
10391
10404
|
}
|
|
10392
10405
|
getTextDimensions(text, font) {
|
|
10393
10406
|
this.context.font = font;
|
|
@@ -10413,7 +10426,7 @@ class ScorecardChartConfigBuilder {
|
|
|
10413
10426
|
}
|
|
10414
10427
|
return {
|
|
10415
10428
|
title: {
|
|
10416
|
-
font: getDefaultContextFont(
|
|
10429
|
+
font: getDefaultContextFont(this.runtime.title.fontSize ?? SCORECARD_CHART_TITLE_FONT_SIZE, this.runtime.title.bold, this.runtime.title.italic),
|
|
10417
10430
|
color: this.runtime.title.color ?? this.secondaryFontColor,
|
|
10418
10431
|
},
|
|
10419
10432
|
keyValue: {
|
|
@@ -21234,7 +21247,7 @@ function getFunctionsFromAST(ast, functionNames) {
|
|
|
21234
21247
|
|
|
21235
21248
|
const PIVOT_FUNCTIONS = ["PIVOT.VALUE", "PIVOT.HEADER", "PIVOT"];
|
|
21236
21249
|
/**
|
|
21237
|
-
* Create a proposal entry for the
|
|
21250
|
+
* Create a proposal entry for the composer autocomplete
|
|
21238
21251
|
* to insert a field name string in a formula.
|
|
21239
21252
|
*/
|
|
21240
21253
|
function makeFieldProposal(field, granularity) {
|
|
@@ -22017,14 +22030,8 @@ const GAUGE_PADDING_BOTTOM = 20;
|
|
|
22017
22030
|
const GAUGE_LABELS_FONT_SIZE = 12;
|
|
22018
22031
|
const GAUGE_DEFAULT_VALUE_FONT_SIZE = 80;
|
|
22019
22032
|
const GAUGE_BACKGROUND_COLOR = "#F3F2F1";
|
|
22020
|
-
const GAUGE_TEXT_COLOR = "#666666";
|
|
22021
|
-
const GAUGE_TEXT_COLOR_HIGH_CONTRAST = "#C8C8C8";
|
|
22022
|
-
const GAUGE_INFLECTION_MARKER_COLOR = "#666666aa";
|
|
22023
22033
|
const GAUGE_INFLECTION_LABEL_BOTTOM_MARGIN = 6;
|
|
22024
22034
|
const GAUGE_TITLE_SECTION_HEIGHT = 25;
|
|
22025
|
-
const GAUGE_TITLE_FONT_SIZE = SCORECARD_GAUGE_CHART_FONT_SIZE;
|
|
22026
|
-
const GAUGE_TITLE_PADDING_LEFT = SCORECARD_GAUGE_CHART_PADDING;
|
|
22027
|
-
const GAUGE_TITLE_PADDING_TOP = SCORECARD_GAUGE_CHART_PADDING;
|
|
22028
22035
|
function drawGaugeChart(canvas, runtime) {
|
|
22029
22036
|
const canvasBoundingRect = canvas.getBoundingClientRect();
|
|
22030
22037
|
canvas.width = canvasBoundingRect.width;
|
|
@@ -22083,7 +22090,7 @@ function drawInflectionValues(ctx, config) {
|
|
|
22083
22090
|
ctx.translate(rectX + width / 2 - 0.5, rectY + height - 0.5); // -0.5 for sharper lines. see RendererPlugin.drawBorders comment
|
|
22084
22091
|
ctx.rotate(Math.PI / 2 - inflectionValue.rotation);
|
|
22085
22092
|
ctx.lineWidth = 2;
|
|
22086
|
-
ctx.strokeStyle =
|
|
22093
|
+
ctx.strokeStyle = chartMutedFontColor(config.backgroundColor) + "aa";
|
|
22087
22094
|
ctx.beginPath();
|
|
22088
22095
|
ctx.moveTo(0, -(height - config.gauge.arcWidth));
|
|
22089
22096
|
ctx.lineTo(0, -height - 3);
|
|
@@ -22137,22 +22144,22 @@ function getGaugeRenderingConfig(boundingRect, runtime, ctx) {
|
|
|
22137
22144
|
x: gaugeRect.x + gaugeRect.width - gaugeArcWidth / 2,
|
|
22138
22145
|
y: gaugeRect.y + gaugeRect.height + GAUGE_LABELS_FONT_SIZE,
|
|
22139
22146
|
};
|
|
22140
|
-
const textColor =
|
|
22147
|
+
const textColor = chartMutedFontColor(runtime.background);
|
|
22141
22148
|
const inflectionValues = getInflectionValues(runtime, gaugeRect, textColor, ctx);
|
|
22142
22149
|
let x = 0, titleWidth = 0, titleHeight = 0;
|
|
22143
22150
|
if (runtime.title.text) {
|
|
22144
|
-
({ width: titleWidth, height: titleHeight } = computeTextDimension(ctx, runtime.title.text, { ...runtime.title
|
|
22151
|
+
({ width: titleWidth, height: titleHeight } = computeTextDimension(ctx, runtime.title.text, { fontSize: CHART_TITLE_FONT_SIZE, ...runtime.title }, "px"));
|
|
22145
22152
|
}
|
|
22146
22153
|
switch (runtime.title.align) {
|
|
22147
22154
|
case "right":
|
|
22148
|
-
x = boundingRect.width - titleWidth -
|
|
22155
|
+
x = boundingRect.width - titleWidth - CHART_PADDING$1;
|
|
22149
22156
|
break;
|
|
22150
22157
|
case "center":
|
|
22151
22158
|
x = (boundingRect.width - titleWidth) / 2;
|
|
22152
22159
|
break;
|
|
22153
22160
|
case "left":
|
|
22154
22161
|
default:
|
|
22155
|
-
x =
|
|
22162
|
+
x = CHART_PADDING$1;
|
|
22156
22163
|
break;
|
|
22157
22164
|
}
|
|
22158
22165
|
return {
|
|
@@ -22160,10 +22167,10 @@ function getGaugeRenderingConfig(boundingRect, runtime, ctx) {
|
|
|
22160
22167
|
height: boundingRect.height,
|
|
22161
22168
|
title: {
|
|
22162
22169
|
label: runtime.title.text ?? "",
|
|
22163
|
-
fontSize:
|
|
22170
|
+
fontSize: runtime.title.fontSize ?? CHART_TITLE_FONT_SIZE,
|
|
22164
22171
|
textPosition: {
|
|
22165
22172
|
x,
|
|
22166
|
-
y:
|
|
22173
|
+
y: CHART_PADDING_TOP + titleHeight / 2,
|
|
22167
22174
|
},
|
|
22168
22175
|
color: runtime.title.color ?? textColor,
|
|
22169
22176
|
bold: runtime.title.bold,
|
|
@@ -22280,11 +22287,6 @@ function getGaugeColor(runtime) {
|
|
|
22280
22287
|
}
|
|
22281
22288
|
return runtime.colors.at(-1);
|
|
22282
22289
|
}
|
|
22283
|
-
function getContrastedTextColor(backgroundColor) {
|
|
22284
|
-
return relativeLuminance(backgroundColor) > 0.3
|
|
22285
|
-
? GAUGE_TEXT_COLOR
|
|
22286
|
-
: GAUGE_TEXT_COLOR_HIGH_CONTRAST;
|
|
22287
|
-
}
|
|
22288
22290
|
function getSegmentsOfRectangle(rectangle) {
|
|
22289
22291
|
return [
|
|
22290
22292
|
{ start: rectangle.topLeft, end: rectangle.topRight },
|
|
@@ -26998,13 +27000,12 @@ migrationStepRegistry
|
|
|
26998
27000
|
versionFrom: "7",
|
|
26999
27001
|
migrate(data) {
|
|
27000
27002
|
const namesTaken = [];
|
|
27001
|
-
const globalForbiddenInExcel = new RegExp(FORBIDDEN_IN_EXCEL_REGEX, "g");
|
|
27002
27003
|
for (let sheet of data.sheets || []) {
|
|
27003
27004
|
if (!sheet.name) {
|
|
27004
27005
|
continue;
|
|
27005
27006
|
}
|
|
27006
27007
|
const oldName = sheet.name;
|
|
27007
|
-
const escapedName = oldName
|
|
27008
|
+
const escapedName = sanitizeSheetName(oldName, "_");
|
|
27008
27009
|
let i = 1;
|
|
27009
27010
|
let newName = escapedName;
|
|
27010
27011
|
while (namesTaken.includes(newName)) {
|
|
@@ -28240,37 +28241,45 @@ function interpolateData(config, values, labels, newLabels) {
|
|
|
28240
28241
|
const labelRange = labelMax - labelMin;
|
|
28241
28242
|
const normalizedLabels = labels.map((v) => (v - labelMin) / labelRange);
|
|
28242
28243
|
const normalizedNewLabels = newLabels.map((v) => (v - labelMin) / labelRange);
|
|
28243
|
-
|
|
28244
|
-
|
|
28245
|
-
|
|
28246
|
-
|
|
28247
|
-
|
|
28248
|
-
|
|
28249
|
-
|
|
28250
|
-
|
|
28251
|
-
|
|
28252
|
-
|
|
28253
|
-
|
|
28254
|
-
|
|
28255
|
-
|
|
28256
|
-
|
|
28257
|
-
|
|
28258
|
-
|
|
28244
|
+
try {
|
|
28245
|
+
switch (config.type) {
|
|
28246
|
+
case "polynomial": {
|
|
28247
|
+
const order = config.order;
|
|
28248
|
+
if (!order) {
|
|
28249
|
+
return Array.from({ length: newLabels.length }, () => NaN);
|
|
28250
|
+
}
|
|
28251
|
+
if (order === 1) {
|
|
28252
|
+
return predictLinearValues([values], [normalizedLabels], [normalizedNewLabels], true)[0];
|
|
28253
|
+
}
|
|
28254
|
+
const coeffs = polynomialRegression(values, normalizedLabels, order, true).flat();
|
|
28255
|
+
return normalizedNewLabels.map((v) => evaluatePolynomial(coeffs, v, order));
|
|
28256
|
+
}
|
|
28257
|
+
case "exponential": {
|
|
28258
|
+
const positiveLogValues = [];
|
|
28259
|
+
const filteredLabels = [];
|
|
28260
|
+
for (let i = 0; i < values.length; i++) {
|
|
28261
|
+
if (values[i] > 0) {
|
|
28262
|
+
positiveLogValues.push(Math.log(values[i]));
|
|
28263
|
+
filteredLabels.push(normalizedLabels[i]);
|
|
28264
|
+
}
|
|
28259
28265
|
}
|
|
28266
|
+
if (!filteredLabels.length) {
|
|
28267
|
+
return Array.from({ length: newLabels.length }, () => NaN);
|
|
28268
|
+
}
|
|
28269
|
+
return expM(predictLinearValues([positiveLogValues], [filteredLabels], [normalizedNewLabels], true))[0];
|
|
28260
28270
|
}
|
|
28261
|
-
|
|
28262
|
-
return [];
|
|
28271
|
+
case "logarithmic": {
|
|
28272
|
+
return predictLinearValues([values], logM([normalizedLabels]), logM([normalizedNewLabels]), true)[0];
|
|
28263
28273
|
}
|
|
28264
|
-
|
|
28265
|
-
|
|
28266
|
-
|
|
28267
|
-
|
|
28268
|
-
|
|
28269
|
-
case "trailingMovingAverage": {
|
|
28270
|
-
return getMovingAverageValues(values, config.window);
|
|
28274
|
+
case "trailingMovingAverage": {
|
|
28275
|
+
return getMovingAverageValues(values, config.window);
|
|
28276
|
+
}
|
|
28277
|
+
default:
|
|
28278
|
+
return Array.from({ length: newLabels.length }, () => NaN);
|
|
28271
28279
|
}
|
|
28272
|
-
|
|
28273
|
-
|
|
28280
|
+
}
|
|
28281
|
+
catch (e) {
|
|
28282
|
+
return Array.from({ length: newLabels.length }, () => NaN);
|
|
28274
28283
|
}
|
|
28275
28284
|
}
|
|
28276
28285
|
function getChartAxisType(chart, labelRange, getters) {
|
|
@@ -28741,54 +28750,16 @@ function getChartColorsGenerator(definition, dataSetsSize) {
|
|
|
28741
28750
|
return new ColorGenerator(dataSetsSize, definition.dataSets?.map((ds) => ds.backgroundColor) || []);
|
|
28742
28751
|
}
|
|
28743
28752
|
|
|
28744
|
-
function
|
|
28745
|
-
// TODO FIXME: this is unused ATM. All the charts should probably use this instead oh whatever padding they are using now
|
|
28746
|
-
// also look into how DEFAULT_CHART_PADDING is used in scorecards, it look strange
|
|
28753
|
+
function getChartLayout(definition) {
|
|
28747
28754
|
return {
|
|
28748
28755
|
padding: {
|
|
28749
|
-
left:
|
|
28750
|
-
right:
|
|
28751
|
-
top:
|
|
28752
|
-
bottom:
|
|
28756
|
+
left: CHART_PADDING$1,
|
|
28757
|
+
right: CHART_PADDING$1,
|
|
28758
|
+
top: CHART_PADDING_TOP,
|
|
28759
|
+
bottom: CHART_PADDING_BOTTOM,
|
|
28753
28760
|
},
|
|
28754
28761
|
};
|
|
28755
28762
|
}
|
|
28756
|
-
function getBarChartLayout(definition) {
|
|
28757
|
-
return {
|
|
28758
|
-
padding: computeChartPadding({
|
|
28759
|
-
displayTitle: !!definition.title?.text,
|
|
28760
|
-
displayLegend: definition.legendPosition === "top",
|
|
28761
|
-
}),
|
|
28762
|
-
};
|
|
28763
|
-
}
|
|
28764
|
-
function getLineChartLayout(definition) {
|
|
28765
|
-
return {
|
|
28766
|
-
padding: computeChartPadding({
|
|
28767
|
-
displayTitle: !!definition.title?.text,
|
|
28768
|
-
displayLegend: definition.legendPosition === "top",
|
|
28769
|
-
}),
|
|
28770
|
-
};
|
|
28771
|
-
}
|
|
28772
|
-
function getPieChartLayout(definition) {
|
|
28773
|
-
return {
|
|
28774
|
-
padding: { left: 20, right: 20, top: definition.title ? 10 : 25, bottom: 10 },
|
|
28775
|
-
};
|
|
28776
|
-
}
|
|
28777
|
-
function getWaterfallChartLayout(definition) {
|
|
28778
|
-
return {
|
|
28779
|
-
padding: { left: 20, right: 20, top: definition.title ? 10 : 25, bottom: 10 },
|
|
28780
|
-
};
|
|
28781
|
-
}
|
|
28782
|
-
function computeChartPadding({ displayTitle, displayLegend, }) {
|
|
28783
|
-
let top = 25;
|
|
28784
|
-
if (displayTitle) {
|
|
28785
|
-
top = 0;
|
|
28786
|
-
}
|
|
28787
|
-
else if (displayLegend) {
|
|
28788
|
-
top = 10;
|
|
28789
|
-
}
|
|
28790
|
-
return { left: 20, right: 20, top, bottom: 10 };
|
|
28791
|
-
}
|
|
28792
28763
|
|
|
28793
28764
|
function getLegendDisplayOptions(definition, args) {
|
|
28794
28765
|
return {
|
|
@@ -28846,11 +28817,12 @@ function getScatterChartLegend(definition, args) {
|
|
|
28846
28817
|
return {
|
|
28847
28818
|
...INTERACTIVE_LEGEND_CONFIG,
|
|
28848
28819
|
...getLegendDisplayOptions(definition),
|
|
28849
|
-
|
|
28850
|
-
|
|
28851
|
-
|
|
28852
|
-
|
|
28853
|
-
|
|
28820
|
+
...getCustomLegendLabels(chartFontColor(definition.background), {
|
|
28821
|
+
pointStyle: "circle",
|
|
28822
|
+
// the stroke is the border around the circle, so increasing its size with the chart's color reduce the size of the circle
|
|
28823
|
+
strokeStyle: definition.background || "#ffffff",
|
|
28824
|
+
lineWidth: 8,
|
|
28825
|
+
}),
|
|
28854
28826
|
};
|
|
28855
28827
|
}
|
|
28856
28828
|
function getComboChartLegend(definition, args) {
|
|
@@ -28939,10 +28911,10 @@ const INTERACTIVE_LEGEND_CONFIG = {
|
|
|
28939
28911
|
target.style.cursor = "default";
|
|
28940
28912
|
},
|
|
28941
28913
|
onClick: (event, legendItem, legend) => {
|
|
28942
|
-
|
|
28914
|
+
const index = legendItem.datasetIndex;
|
|
28915
|
+
if (!legend.legendItems || index === undefined) {
|
|
28943
28916
|
return;
|
|
28944
28917
|
}
|
|
28945
|
-
const index = legend.legendItems.indexOf(legendItem);
|
|
28946
28918
|
if (legend.chart.isDatasetVisible(index)) {
|
|
28947
28919
|
legend.chart.hide(index);
|
|
28948
28920
|
}
|
|
@@ -28958,15 +28930,29 @@ function getCustomLegendLabels(fontColor, legendLabelConfig) {
|
|
|
28958
28930
|
labels: {
|
|
28959
28931
|
color: fontColor,
|
|
28960
28932
|
usePointStyle: true,
|
|
28961
|
-
generateLabels: (chart) => chart.data.datasets.map((dataset, index) =>
|
|
28962
|
-
|
|
28963
|
-
|
|
28964
|
-
|
|
28965
|
-
|
|
28966
|
-
|
|
28967
|
-
|
|
28968
|
-
|
|
28969
|
-
|
|
28933
|
+
generateLabels: (chart) => chart.data.datasets.map((dataset, index) => {
|
|
28934
|
+
if (dataset["xAxisID"] === TREND_LINE_XAXIS_ID) {
|
|
28935
|
+
return {
|
|
28936
|
+
text: dataset.label ?? "",
|
|
28937
|
+
fontColor,
|
|
28938
|
+
strokeStyle: dataset.borderColor,
|
|
28939
|
+
hidden: !chart.isDatasetVisible(index),
|
|
28940
|
+
pointStyle: "line",
|
|
28941
|
+
datasetIndex: index,
|
|
28942
|
+
lineWidth: 3,
|
|
28943
|
+
};
|
|
28944
|
+
}
|
|
28945
|
+
return {
|
|
28946
|
+
text: dataset.label ?? "",
|
|
28947
|
+
fontColor,
|
|
28948
|
+
strokeStyle: dataset.borderColor,
|
|
28949
|
+
fillStyle: dataset.backgroundColor,
|
|
28950
|
+
hidden: !chart.isDatasetVisible(index),
|
|
28951
|
+
pointStyle: dataset.type === "line" ? "line" : "rect",
|
|
28952
|
+
datasetIndex: index,
|
|
28953
|
+
...legendLabelConfig,
|
|
28954
|
+
};
|
|
28955
|
+
}),
|
|
28970
28956
|
},
|
|
28971
28957
|
};
|
|
28972
28958
|
}
|
|
@@ -29114,6 +29100,7 @@ function getChartAxisTitleRuntime(design) {
|
|
|
29114
29100
|
font: {
|
|
29115
29101
|
style: italic ? "italic" : "normal",
|
|
29116
29102
|
weight: bold ? "bold" : "normal",
|
|
29103
|
+
size: design.title.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE,
|
|
29117
29104
|
},
|
|
29118
29105
|
align: align === "left" ? "start" : align === "right" ? "end" : "center",
|
|
29119
29106
|
};
|
|
@@ -29179,17 +29166,22 @@ function getChartShowValues(definition, args) {
|
|
|
29179
29166
|
|
|
29180
29167
|
function getChartTitle(definition) {
|
|
29181
29168
|
const chartTitle = definition.title;
|
|
29182
|
-
const fontColor =
|
|
29169
|
+
const fontColor = chartMutedFontColor(definition.background);
|
|
29183
29170
|
return {
|
|
29184
29171
|
display: !!chartTitle.text,
|
|
29185
29172
|
text: _t(chartTitle.text),
|
|
29186
29173
|
color: chartTitle?.color ?? fontColor,
|
|
29187
29174
|
align: chartTitle.align === "center" ? "center" : chartTitle.align === "right" ? "end" : "start",
|
|
29188
29175
|
font: {
|
|
29189
|
-
size:
|
|
29176
|
+
size: definition.title.fontSize ?? CHART_TITLE_FONT_SIZE,
|
|
29190
29177
|
weight: chartTitle.bold ? "bold" : "normal",
|
|
29191
29178
|
style: chartTitle.italic ? "italic" : "normal",
|
|
29192
29179
|
},
|
|
29180
|
+
padding: {
|
|
29181
|
+
// Disable title top/left/right padding to use the chart padding instead.
|
|
29182
|
+
// The legend already has a top padding, so bottom padding is useless for the title there.
|
|
29183
|
+
bottom: definition.legendPosition === "top" ? 0 : CHART_PADDING$1,
|
|
29184
|
+
},
|
|
29193
29185
|
};
|
|
29194
29186
|
}
|
|
29195
29187
|
|
|
@@ -29336,26 +29328,23 @@ var CHART_RUNTIME_HELPERS = /*#__PURE__*/Object.freeze({
|
|
|
29336
29328
|
canChartParseLabels: canChartParseLabels,
|
|
29337
29329
|
getBarChartData: getBarChartData,
|
|
29338
29330
|
getBarChartDatasets: getBarChartDatasets,
|
|
29339
|
-
getBarChartLayout: getBarChartLayout,
|
|
29340
29331
|
getBarChartLegend: getBarChartLegend,
|
|
29341
29332
|
getBarChartScales: getBarChartScales,
|
|
29342
29333
|
getBarChartTooltip: getBarChartTooltip,
|
|
29343
29334
|
getChartLabelFormat: getChartLabelFormat,
|
|
29335
|
+
getChartLayout: getChartLayout,
|
|
29344
29336
|
getChartShowValues: getChartShowValues,
|
|
29345
29337
|
getChartTitle: getChartTitle,
|
|
29346
29338
|
getComboChartDatasets: getComboChartDatasets,
|
|
29347
29339
|
getComboChartLegend: getComboChartLegend,
|
|
29348
|
-
getCommonChartLayout: getCommonChartLayout,
|
|
29349
29340
|
getData: getData,
|
|
29350
29341
|
getLineChartData: getLineChartData,
|
|
29351
29342
|
getLineChartDatasets: getLineChartDatasets,
|
|
29352
|
-
getLineChartLayout: getLineChartLayout,
|
|
29353
29343
|
getLineChartLegend: getLineChartLegend,
|
|
29354
29344
|
getLineChartScales: getLineChartScales,
|
|
29355
29345
|
getLineChartTooltip: getLineChartTooltip,
|
|
29356
29346
|
getPieChartData: getPieChartData,
|
|
29357
29347
|
getPieChartDatasets: getPieChartDatasets,
|
|
29358
|
-
getPieChartLayout: getPieChartLayout,
|
|
29359
29348
|
getPieChartLegend: getPieChartLegend,
|
|
29360
29349
|
getPieChartTooltip: getPieChartTooltip,
|
|
29361
29350
|
getPyramidChartData: getPyramidChartData,
|
|
@@ -29371,7 +29360,6 @@ var CHART_RUNTIME_HELPERS = /*#__PURE__*/Object.freeze({
|
|
|
29371
29360
|
getScatterChartScales: getScatterChartScales,
|
|
29372
29361
|
getTrendDatasetForBarChart: getTrendDatasetForBarChart,
|
|
29373
29362
|
getTrendDatasetForLineChart: getTrendDatasetForLineChart,
|
|
29374
|
-
getWaterfallChartLayout: getWaterfallChartLayout,
|
|
29375
29363
|
getWaterfallChartLegend: getWaterfallChartLegend,
|
|
29376
29364
|
getWaterfallChartScales: getWaterfallChartScales,
|
|
29377
29365
|
getWaterfallChartTooltip: getWaterfallChartTooltip,
|
|
@@ -29519,7 +29507,7 @@ function createBarChartRuntime(chart, getters) {
|
|
|
29519
29507
|
options: {
|
|
29520
29508
|
...CHART_COMMON_OPTIONS,
|
|
29521
29509
|
indexAxis: chart.horizontal ? "y" : "x",
|
|
29522
|
-
layout:
|
|
29510
|
+
layout: getChartLayout(),
|
|
29523
29511
|
scales: getBarChartScales(definition, chartData),
|
|
29524
29512
|
plugins: {
|
|
29525
29513
|
title: getChartTitle(definition),
|
|
@@ -29671,7 +29659,7 @@ function createComboChartRuntime(chart, getters) {
|
|
|
29671
29659
|
},
|
|
29672
29660
|
options: {
|
|
29673
29661
|
...CHART_COMMON_OPTIONS,
|
|
29674
|
-
layout:
|
|
29662
|
+
layout: getChartLayout(),
|
|
29675
29663
|
scales: getBarChartScales(definition, chartData),
|
|
29676
29664
|
plugins: {
|
|
29677
29665
|
title: getChartTitle(definition),
|
|
@@ -30072,7 +30060,7 @@ function createLineChartRuntime(chart, getters) {
|
|
|
30072
30060
|
},
|
|
30073
30061
|
options: {
|
|
30074
30062
|
...CHART_COMMON_OPTIONS,
|
|
30075
|
-
layout:
|
|
30063
|
+
layout: getChartLayout(),
|
|
30076
30064
|
scales: getLineChartScales(definition, chartData),
|
|
30077
30065
|
plugins: {
|
|
30078
30066
|
title: getChartTitle(definition),
|
|
@@ -30207,7 +30195,7 @@ function createPieChartRuntime(chart, getters) {
|
|
|
30207
30195
|
},
|
|
30208
30196
|
options: {
|
|
30209
30197
|
...CHART_COMMON_OPTIONS,
|
|
30210
|
-
layout:
|
|
30198
|
+
layout: getChartLayout(),
|
|
30211
30199
|
plugins: {
|
|
30212
30200
|
title: getChartTitle(definition),
|
|
30213
30201
|
legend: getPieChartLegend(definition, chartData),
|
|
@@ -30344,7 +30332,7 @@ function createPyramidChartRuntime(chart, getters) {
|
|
|
30344
30332
|
options: {
|
|
30345
30333
|
...CHART_COMMON_OPTIONS,
|
|
30346
30334
|
indexAxis: "y",
|
|
30347
|
-
layout:
|
|
30335
|
+
layout: getChartLayout(),
|
|
30348
30336
|
scales: getPyramidChartScales(definition, chartData),
|
|
30349
30337
|
plugins: {
|
|
30350
30338
|
title: getChartTitle(definition),
|
|
@@ -30493,7 +30481,7 @@ function createRadarChartRuntime(chart, getters) {
|
|
|
30493
30481
|
},
|
|
30494
30482
|
options: {
|
|
30495
30483
|
...CHART_COMMON_OPTIONS,
|
|
30496
|
-
layout:
|
|
30484
|
+
layout: getChartLayout(),
|
|
30497
30485
|
scales: getRadarChartScales(definition, chartData),
|
|
30498
30486
|
plugins: {
|
|
30499
30487
|
title: getChartTitle(definition),
|
|
@@ -30646,7 +30634,7 @@ function createScatterChartRuntime(chart, getters) {
|
|
|
30646
30634
|
},
|
|
30647
30635
|
options: {
|
|
30648
30636
|
...CHART_COMMON_OPTIONS,
|
|
30649
|
-
layout:
|
|
30637
|
+
layout: getChartLayout(),
|
|
30650
30638
|
scales: getScatterChartScales(definition, chartData),
|
|
30651
30639
|
plugins: {
|
|
30652
30640
|
title: getChartTitle(definition),
|
|
@@ -30807,7 +30795,7 @@ function createWaterfallChartRuntime(chart, getters) {
|
|
|
30807
30795
|
},
|
|
30808
30796
|
options: {
|
|
30809
30797
|
...CHART_COMMON_OPTIONS,
|
|
30810
|
-
layout:
|
|
30798
|
+
layout: getChartLayout(),
|
|
30811
30799
|
scales: getWaterfallChartScales(definition, chartData),
|
|
30812
30800
|
plugins: {
|
|
30813
30801
|
title: getChartTitle(definition),
|
|
@@ -33117,6 +33105,7 @@ var CHART_HELPERS = /*#__PURE__*/Object.freeze({
|
|
|
33117
33105
|
adaptChartRange: adaptChartRange,
|
|
33118
33106
|
chartFactory: chartFactory,
|
|
33119
33107
|
chartFontColor: chartFontColor,
|
|
33108
|
+
chartMutedFontColor: chartMutedFontColor,
|
|
33120
33109
|
chartRuntimeFactory: chartRuntimeFactory,
|
|
33121
33110
|
chartToImage: chartToImage,
|
|
33122
33111
|
checkDataset: checkDataset,
|
|
@@ -37409,6 +37398,95 @@ class ColorPickerWidget extends Component {
|
|
|
37409
37398
|
}
|
|
37410
37399
|
}
|
|
37411
37400
|
|
|
37401
|
+
css /* scss */ `
|
|
37402
|
+
.o-font-size-editor {
|
|
37403
|
+
height: calc(100% - 4px);
|
|
37404
|
+
input.o-font-size {
|
|
37405
|
+
outline-color: ${SELECTION_BORDER_COLOR};
|
|
37406
|
+
height: 20px;
|
|
37407
|
+
width: 23px;
|
|
37408
|
+
}
|
|
37409
|
+
}
|
|
37410
|
+
.o-text-options > div {
|
|
37411
|
+
cursor: pointer;
|
|
37412
|
+
line-height: 26px;
|
|
37413
|
+
padding: 3px 12px;
|
|
37414
|
+
&:hover {
|
|
37415
|
+
background-color: rgba(0, 0, 0, 0.08);
|
|
37416
|
+
}
|
|
37417
|
+
}
|
|
37418
|
+
`;
|
|
37419
|
+
class FontSizeEditor extends Component {
|
|
37420
|
+
static template = "o-spreadsheet-FontSizeEditor";
|
|
37421
|
+
static props = {
|
|
37422
|
+
currentFontSize: Number,
|
|
37423
|
+
onFontSizeChanged: Function,
|
|
37424
|
+
onToggle: { type: Function, optional: true },
|
|
37425
|
+
class: String,
|
|
37426
|
+
};
|
|
37427
|
+
static components = { Popover };
|
|
37428
|
+
fontSizes = FONT_SIZES;
|
|
37429
|
+
dropdown = useState({ isOpen: false });
|
|
37430
|
+
inputRef = useRef("inputFontSize");
|
|
37431
|
+
rootEditorRef = useRef("FontSizeEditor");
|
|
37432
|
+
fontSizeListRef = useRef("fontSizeList");
|
|
37433
|
+
setup() {
|
|
37434
|
+
useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
37435
|
+
}
|
|
37436
|
+
get popoverProps() {
|
|
37437
|
+
const { x, y, width, height } = this.rootEditorRef.el.getBoundingClientRect();
|
|
37438
|
+
return {
|
|
37439
|
+
anchorRect: { x, y, width, height },
|
|
37440
|
+
positioning: "BottomLeft",
|
|
37441
|
+
verticalOffset: 0,
|
|
37442
|
+
};
|
|
37443
|
+
}
|
|
37444
|
+
onExternalClick(ev) {
|
|
37445
|
+
if (!isChildEvent(this.fontSizeListRef.el, ev) && !isChildEvent(this.rootEditorRef.el, ev)) {
|
|
37446
|
+
this.closeFontList();
|
|
37447
|
+
}
|
|
37448
|
+
}
|
|
37449
|
+
toggleFontList() {
|
|
37450
|
+
const isOpen = this.dropdown.isOpen;
|
|
37451
|
+
if (!isOpen) {
|
|
37452
|
+
this.props.onToggle?.();
|
|
37453
|
+
this.inputRef.el.focus();
|
|
37454
|
+
}
|
|
37455
|
+
else {
|
|
37456
|
+
this.closeFontList();
|
|
37457
|
+
}
|
|
37458
|
+
}
|
|
37459
|
+
closeFontList() {
|
|
37460
|
+
this.dropdown.isOpen = false;
|
|
37461
|
+
}
|
|
37462
|
+
setSize(fontSizeStr) {
|
|
37463
|
+
const fontSize = clip(Math.floor(parseFloat(fontSizeStr)), 1, 400);
|
|
37464
|
+
this.props.onFontSizeChanged(fontSize);
|
|
37465
|
+
this.closeFontList();
|
|
37466
|
+
}
|
|
37467
|
+
setSizeFromInput(ev) {
|
|
37468
|
+
this.setSize(ev.target.value);
|
|
37469
|
+
}
|
|
37470
|
+
setSizeFromList(fontSizeStr) {
|
|
37471
|
+
this.setSize(fontSizeStr);
|
|
37472
|
+
}
|
|
37473
|
+
onInputFocused(ev) {
|
|
37474
|
+
this.dropdown.isOpen = true;
|
|
37475
|
+
ev.target.select();
|
|
37476
|
+
}
|
|
37477
|
+
onInputKeydown(ev) {
|
|
37478
|
+
if (ev.key === "Enter" || ev.key === "Escape") {
|
|
37479
|
+
this.closeFontList();
|
|
37480
|
+
const target = ev.target;
|
|
37481
|
+
// In the case of a ESCAPE key, we get the previous font size back
|
|
37482
|
+
if (ev.key === "Escape") {
|
|
37483
|
+
target.value = `${this.props.currentFontSize}`;
|
|
37484
|
+
}
|
|
37485
|
+
this.props.onToggle?.();
|
|
37486
|
+
}
|
|
37487
|
+
}
|
|
37488
|
+
}
|
|
37489
|
+
|
|
37412
37490
|
css /* scss */ `
|
|
37413
37491
|
.o-chart-title-designer {
|
|
37414
37492
|
> span {
|
|
@@ -37443,7 +37521,7 @@ css /* scss */ `
|
|
|
37443
37521
|
`;
|
|
37444
37522
|
class ChartTitle extends Component {
|
|
37445
37523
|
static template = "o-spreadsheet.ChartTitle";
|
|
37446
|
-
static components = { Section, ColorPickerWidget };
|
|
37524
|
+
static components = { Section, ColorPickerWidget, FontSizeEditor };
|
|
37447
37525
|
static props = {
|
|
37448
37526
|
title: { type: String, optional: true },
|
|
37449
37527
|
updateTitle: Function,
|
|
@@ -37452,7 +37530,8 @@ class ChartTitle extends Component {
|
|
|
37452
37530
|
toggleBold: { type: Function, optional: true },
|
|
37453
37531
|
updateAlignment: { type: Function, optional: true },
|
|
37454
37532
|
updateColor: { type: Function, optional: true },
|
|
37455
|
-
style:
|
|
37533
|
+
style: Object,
|
|
37534
|
+
onFontSizeChanged: Function,
|
|
37456
37535
|
};
|
|
37457
37536
|
static defaultProps = {
|
|
37458
37537
|
title: "",
|
|
@@ -37467,6 +37546,9 @@ class ChartTitle extends Component {
|
|
|
37467
37546
|
updateTitle(ev) {
|
|
37468
37547
|
this.props.updateTitle(ev.target.value);
|
|
37469
37548
|
}
|
|
37549
|
+
updateFontSize(fontSize) {
|
|
37550
|
+
this.props.onFontSizeChanged(fontSize);
|
|
37551
|
+
}
|
|
37470
37552
|
toggleDropdownTool(tool, ev) {
|
|
37471
37553
|
const isOpen = this.state.activeTool === tool;
|
|
37472
37554
|
this.closeMenus();
|
|
@@ -37509,6 +37591,7 @@ class AxisDesignEditor extends Component {
|
|
|
37509
37591
|
return {
|
|
37510
37592
|
color: "",
|
|
37511
37593
|
align: "center",
|
|
37594
|
+
fontSize: CHART_AXIS_TITLE_FONT_SIZE,
|
|
37512
37595
|
...axisDesign.title,
|
|
37513
37596
|
};
|
|
37514
37597
|
}
|
|
@@ -37526,6 +37609,17 @@ class AxisDesignEditor extends Component {
|
|
|
37526
37609
|
};
|
|
37527
37610
|
this.props.updateChart(this.props.figureId, { axesDesign });
|
|
37528
37611
|
}
|
|
37612
|
+
updateAxisTitleFontSize(fontSize) {
|
|
37613
|
+
const axesDesign = this.props.definition.axesDesign ?? {};
|
|
37614
|
+
axesDesign[this.state.currentAxis] = {
|
|
37615
|
+
...axesDesign[this.state.currentAxis],
|
|
37616
|
+
title: {
|
|
37617
|
+
...(axesDesign[this.state.currentAxis]?.title ?? {}),
|
|
37618
|
+
fontSize,
|
|
37619
|
+
},
|
|
37620
|
+
};
|
|
37621
|
+
this.props.updateChart(this.props.figureId, { axesDesign });
|
|
37622
|
+
}
|
|
37529
37623
|
toggleBoldAxisTitle() {
|
|
37530
37624
|
const axesDesign = this.props.definition.axesDesign ?? {};
|
|
37531
37625
|
const title = axesDesign[this.state.currentAxis]?.title ?? {};
|
|
@@ -37645,8 +37739,12 @@ class GeneralDesignEditor extends Component {
|
|
|
37645
37739
|
figureId: String,
|
|
37646
37740
|
definition: Object,
|
|
37647
37741
|
updateChart: Function,
|
|
37742
|
+
defaultChartTitleFontSize: { type: Number, optional: true },
|
|
37648
37743
|
slots: { type: Object, optional: true },
|
|
37649
37744
|
};
|
|
37745
|
+
static defaultProps = {
|
|
37746
|
+
defaultChartTitleFontSize: CHART_TITLE_FONT_SIZE,
|
|
37747
|
+
};
|
|
37650
37748
|
state;
|
|
37651
37749
|
setup() {
|
|
37652
37750
|
this.state = useState({
|
|
@@ -37672,6 +37770,7 @@ class GeneralDesignEditor extends Component {
|
|
|
37672
37770
|
get titleStyle() {
|
|
37673
37771
|
return {
|
|
37674
37772
|
align: "left",
|
|
37773
|
+
fontSize: this.props.defaultChartTitleFontSize,
|
|
37675
37774
|
...this.title,
|
|
37676
37775
|
};
|
|
37677
37776
|
}
|
|
@@ -37680,6 +37779,10 @@ class GeneralDesignEditor extends Component {
|
|
|
37680
37779
|
this.props.updateChart(this.props.figureId, { title });
|
|
37681
37780
|
this.state.activeTool = "";
|
|
37682
37781
|
}
|
|
37782
|
+
updateChartTitleFontSize(fontSize) {
|
|
37783
|
+
const title = { ...this.title, fontSize };
|
|
37784
|
+
this.props.updateChart(this.props.figureId, { title });
|
|
37785
|
+
}
|
|
37683
37786
|
toggleBoldChartTitle() {
|
|
37684
37787
|
let title = this.title;
|
|
37685
37788
|
title = { ...title, bold: !title.bold };
|
|
@@ -37887,7 +37990,7 @@ class SeriesWithAxisDesignEditor extends Component {
|
|
|
37887
37990
|
case "polynomial":
|
|
37888
37991
|
config = {
|
|
37889
37992
|
type: "polynomial",
|
|
37890
|
-
order: type === "linear" ? 1 :
|
|
37993
|
+
order: type === "linear" ? 1 : this.getMaxPolynomialDegree(index),
|
|
37891
37994
|
};
|
|
37892
37995
|
break;
|
|
37893
37996
|
case "exponential":
|
|
@@ -38347,6 +38450,9 @@ class ScorecardChartDesignPanel extends Component {
|
|
|
38347
38450
|
get humanizeNumbersLabel() {
|
|
38348
38451
|
return _t("Humanize numbers");
|
|
38349
38452
|
}
|
|
38453
|
+
get defaultScorecardTitleFontSize() {
|
|
38454
|
+
return SCORECARD_CHART_TITLE_FONT_SIZE;
|
|
38455
|
+
}
|
|
38350
38456
|
updateHumanizeNumbers(humanize) {
|
|
38351
38457
|
this.props.updateChart(this.props.figureId, { humanize });
|
|
38352
38458
|
}
|
|
@@ -39810,6 +39916,15 @@ class StandaloneComposerStore extends AbstractComposerStore {
|
|
|
39810
39916
|
confirmEdition(content) {
|
|
39811
39917
|
this.args().onConfirm(content);
|
|
39812
39918
|
}
|
|
39919
|
+
getTokenColor(token) {
|
|
39920
|
+
if (token.type === "SYMBOL") {
|
|
39921
|
+
const matchedColor = this.args().getContextualColoredSymbolToken?.(token);
|
|
39922
|
+
if (matchedColor) {
|
|
39923
|
+
return matchedColor;
|
|
39924
|
+
}
|
|
39925
|
+
}
|
|
39926
|
+
return super.getTokenColor(token);
|
|
39927
|
+
}
|
|
39813
39928
|
}
|
|
39814
39929
|
|
|
39815
39930
|
css /* scss */ `
|
|
@@ -39847,6 +39962,7 @@ class StandaloneComposer extends Component {
|
|
|
39847
39962
|
placeholder: { type: String, optional: true },
|
|
39848
39963
|
class: { type: String, optional: true },
|
|
39849
39964
|
invalid: { type: Boolean, optional: true },
|
|
39965
|
+
getContextualColoredSymbolToken: { type: Function, optional: true },
|
|
39850
39966
|
};
|
|
39851
39967
|
static components = { Composer };
|
|
39852
39968
|
static defaultProps = {
|
|
@@ -39863,6 +39979,7 @@ class StandaloneComposer extends Component {
|
|
|
39863
39979
|
content: this.props.composerContent,
|
|
39864
39980
|
contextualAutocomplete: this.props.contextualAutocomplete,
|
|
39865
39981
|
defaultRangeSheetId: this.props.defaultRangeSheetId,
|
|
39982
|
+
getContextualColoredSymbolToken: this.props.getContextualColoredSymbolToken,
|
|
39866
39983
|
}));
|
|
39867
39984
|
this.standaloneComposerStore = standaloneComposerStore;
|
|
39868
39985
|
this.composerInterface = {
|
|
@@ -43423,7 +43540,7 @@ function createMeasureAutoComplete(pivot, forComputedMeasure) {
|
|
|
43423
43540
|
return {
|
|
43424
43541
|
text: text,
|
|
43425
43542
|
description: measure.displayName,
|
|
43426
|
-
htmlContent: [{ value: text, color:
|
|
43543
|
+
htmlContent: [{ value: text, color: PIVOT_TOKEN_COLOR }],
|
|
43427
43544
|
fuzzySearchKey: measure.displayName + text + measure.fieldName,
|
|
43428
43545
|
};
|
|
43429
43546
|
});
|
|
@@ -43432,7 +43549,7 @@ function createMeasureAutoComplete(pivot, forComputedMeasure) {
|
|
|
43432
43549
|
return {
|
|
43433
43550
|
text: text,
|
|
43434
43551
|
description: dimension.displayName,
|
|
43435
|
-
htmlContent: [{ value: text, color:
|
|
43552
|
+
htmlContent: [{ value: text, color: PIVOT_TOKEN_COLOR }],
|
|
43436
43553
|
fuzzySearchKey: dimension.displayName + text + dimension.fieldName,
|
|
43437
43554
|
};
|
|
43438
43555
|
});
|
|
@@ -43512,6 +43629,18 @@ class PivotMeasureEditor extends Component {
|
|
|
43512
43629
|
measure: this.props.measure,
|
|
43513
43630
|
});
|
|
43514
43631
|
}
|
|
43632
|
+
getColoredSymbolToken(token) {
|
|
43633
|
+
if (token.type !== "SYMBOL") {
|
|
43634
|
+
return undefined;
|
|
43635
|
+
}
|
|
43636
|
+
const tokenValue = unquote(token.value, "'");
|
|
43637
|
+
if (this.props.definition.columns.some((col) => col.nameWithGranularity === tokenValue) ||
|
|
43638
|
+
this.props.definition.rows.some((row) => row.nameWithGranularity === tokenValue) ||
|
|
43639
|
+
this.props.definition.measures.some((measure) => measure.id === tokenValue && measure.id !== this.props.measure.id)) {
|
|
43640
|
+
return PIVOT_TOKEN_COLOR;
|
|
43641
|
+
}
|
|
43642
|
+
return undefined;
|
|
43643
|
+
}
|
|
43515
43644
|
}
|
|
43516
43645
|
|
|
43517
43646
|
css /* scss */ `
|
|
@@ -51886,7 +52015,7 @@ class CellPlugin extends CorePlugin {
|
|
|
51886
52015
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
51887
52016
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
51888
52017
|
const cell = this.getters.getCell({ sheetId, col, row });
|
|
51889
|
-
if (cell) {
|
|
52018
|
+
if (cell?.isFormula || cell?.content) {
|
|
51890
52019
|
this.dispatch("UPDATE_CELL", {
|
|
51891
52020
|
sheetId: sheetId,
|
|
51892
52021
|
content: "",
|
|
@@ -51922,7 +52051,6 @@ class CellPlugin extends CorePlugin {
|
|
|
51922
52051
|
for (let zone of recomputeZones(zones)) {
|
|
51923
52052
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
51924
52053
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
51925
|
-
// commandHelpers.updateCell(sheetId, col, row, { style: undefined});
|
|
51926
52054
|
this.dispatch("UPDATE_CELL", {
|
|
51927
52055
|
sheetId,
|
|
51928
52056
|
col,
|
|
@@ -55341,7 +55469,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
55341
55469
|
if (orderedSheetIds.find((id) => sheets[id]?.name.toLowerCase() === name && id !== cmd.sheetId)) {
|
|
55342
55470
|
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
55343
55471
|
}
|
|
55344
|
-
if (
|
|
55472
|
+
if (FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX.test(name)) {
|
|
55345
55473
|
return "ForbiddenCharactersInSheetName" /* CommandResult.ForbiddenCharactersInSheetName */;
|
|
55346
55474
|
}
|
|
55347
55475
|
return "Success" /* CommandResult.Success */;
|
|
@@ -60749,11 +60877,13 @@ class PivotUIPlugin extends UIPlugin {
|
|
|
60749
60877
|
return EMPTY_PIVOT_CELL;
|
|
60750
60878
|
}
|
|
60751
60879
|
if (functionName === "PIVOT") {
|
|
60752
|
-
const includeTotal = args[2]
|
|
60753
|
-
const
|
|
60880
|
+
const includeTotal = toScalar(args[2]);
|
|
60881
|
+
const shouldIncludeTotal = includeTotal === undefined ? true : toBoolean(includeTotal);
|
|
60882
|
+
const includeColumnHeaders = toScalar(args[3]);
|
|
60883
|
+
const shouldIncludeColumnHeaders = includeColumnHeaders === undefined ? true : toBoolean(includeColumnHeaders);
|
|
60754
60884
|
const pivotCells = pivot
|
|
60755
60885
|
.getTableStructure()
|
|
60756
|
-
.getPivotCells(
|
|
60886
|
+
.getPivotCells(shouldIncludeTotal, shouldIncludeColumnHeaders);
|
|
60757
60887
|
const pivotCol = position.col - mainPosition.col;
|
|
60758
60888
|
const pivotRow = position.row - mainPosition.row;
|
|
60759
60889
|
return pivotCells[pivotCol][pivotRow];
|
|
@@ -62907,7 +63037,7 @@ class InsertPivotPlugin extends UIPlugin {
|
|
|
62907
63037
|
getPivotDuplicateSheetName(pivotName) {
|
|
62908
63038
|
let i = 1;
|
|
62909
63039
|
const names = this.getters.getSheetIds().map((id) => this.getters.getSheetName(id));
|
|
62910
|
-
const sanitizedName = pivotName
|
|
63040
|
+
const sanitizedName = sanitizeSheetName(pivotName);
|
|
62911
63041
|
let name = sanitizedName;
|
|
62912
63042
|
while (names.includes(name)) {
|
|
62913
63043
|
name = `${sanitizedName} (${i})`;
|
|
@@ -66983,7 +67113,7 @@ function interactiveRenameSheet(env, sheetId, name, errorCallback) {
|
|
|
66983
67113
|
env.raiseError(_t("A sheet with the name %s already exists. Please select another name.", name), errorCallback);
|
|
66984
67114
|
}
|
|
66985
67115
|
else if (result.reasons.includes("ForbiddenCharactersInSheetName" /* CommandResult.ForbiddenCharactersInSheetName */)) {
|
|
66986
|
-
env.raiseError(_t("Some used characters are not allowed in a sheet name (Forbidden characters are %s).",
|
|
67116
|
+
env.raiseError(_t("Some used characters are not allowed in a sheet name (Forbidden characters are %s).", FORBIDDEN_SHEETNAME_CHARS.join(" ")), errorCallback);
|
|
66987
67117
|
}
|
|
66988
67118
|
}
|
|
66989
67119
|
|
|
@@ -68213,7 +68343,7 @@ class ActionButton extends Component {
|
|
|
68213
68343
|
setup() {
|
|
68214
68344
|
onWillUpdateProps((nextProps) => {
|
|
68215
68345
|
if (nextProps.action !== this.props.action) {
|
|
68216
|
-
this.actionButton = createAction(
|
|
68346
|
+
this.actionButton = createAction(nextProps.action);
|
|
68217
68347
|
}
|
|
68218
68348
|
});
|
|
68219
68349
|
}
|
|
@@ -68549,88 +68679,6 @@ class TopBarComposer extends Component {
|
|
|
68549
68679
|
}
|
|
68550
68680
|
}
|
|
68551
68681
|
|
|
68552
|
-
css /* scss */ `
|
|
68553
|
-
.o-font-size-editor {
|
|
68554
|
-
height: calc(100% - 4px);
|
|
68555
|
-
input.o-font-size {
|
|
68556
|
-
outline-color: ${SELECTION_BORDER_COLOR};
|
|
68557
|
-
height: 20px;
|
|
68558
|
-
width: 23px;
|
|
68559
|
-
}
|
|
68560
|
-
}
|
|
68561
|
-
.o-text-options > div {
|
|
68562
|
-
cursor: pointer;
|
|
68563
|
-
line-height: 26px;
|
|
68564
|
-
padding: 3px 12px;
|
|
68565
|
-
&:hover {
|
|
68566
|
-
background-color: rgba(0, 0, 0, 0.08);
|
|
68567
|
-
}
|
|
68568
|
-
}
|
|
68569
|
-
`;
|
|
68570
|
-
class FontSizeEditor extends Component {
|
|
68571
|
-
static template = "o-spreadsheet-FontSizeEditor";
|
|
68572
|
-
static props = {
|
|
68573
|
-
onToggle: Function,
|
|
68574
|
-
dropdownStyle: String,
|
|
68575
|
-
class: String,
|
|
68576
|
-
};
|
|
68577
|
-
static components = {};
|
|
68578
|
-
fontSizes = FONT_SIZES;
|
|
68579
|
-
dropdown = useState({ isOpen: false });
|
|
68580
|
-
inputRef = useRef("inputFontSize");
|
|
68581
|
-
rootEditorRef = useRef("FontSizeEditor");
|
|
68582
|
-
setup() {
|
|
68583
|
-
useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
68584
|
-
}
|
|
68585
|
-
onExternalClick(ev) {
|
|
68586
|
-
if (!isChildEvent(this.rootEditorRef.el, ev)) {
|
|
68587
|
-
this.closeFontList();
|
|
68588
|
-
}
|
|
68589
|
-
}
|
|
68590
|
-
get currentFontSize() {
|
|
68591
|
-
return this.env.model.getters.getCurrentStyle().fontSize || DEFAULT_FONT_SIZE;
|
|
68592
|
-
}
|
|
68593
|
-
toggleFontList() {
|
|
68594
|
-
const isOpen = this.dropdown.isOpen;
|
|
68595
|
-
if (!isOpen) {
|
|
68596
|
-
this.props.onToggle();
|
|
68597
|
-
this.inputRef.el.focus();
|
|
68598
|
-
}
|
|
68599
|
-
else {
|
|
68600
|
-
this.closeFontList();
|
|
68601
|
-
}
|
|
68602
|
-
}
|
|
68603
|
-
closeFontList() {
|
|
68604
|
-
this.dropdown.isOpen = false;
|
|
68605
|
-
}
|
|
68606
|
-
setSize(fontSizeStr) {
|
|
68607
|
-
const fontSize = clip(Math.floor(parseFloat(fontSizeStr)), 1, 400);
|
|
68608
|
-
setStyle(this.env, { fontSize });
|
|
68609
|
-
this.closeFontList();
|
|
68610
|
-
}
|
|
68611
|
-
setSizeFromInput(ev) {
|
|
68612
|
-
this.setSize(ev.target.value);
|
|
68613
|
-
}
|
|
68614
|
-
setSizeFromList(fontSizeStr) {
|
|
68615
|
-
this.setSize(fontSizeStr);
|
|
68616
|
-
}
|
|
68617
|
-
onInputFocused(ev) {
|
|
68618
|
-
this.dropdown.isOpen = true;
|
|
68619
|
-
ev.target.select();
|
|
68620
|
-
}
|
|
68621
|
-
onInputKeydown(ev) {
|
|
68622
|
-
if (ev.key === "Enter" || ev.key === "Escape") {
|
|
68623
|
-
this.closeFontList();
|
|
68624
|
-
const target = ev.target;
|
|
68625
|
-
// In the case of a ESCAPE key, we get the previous font size back
|
|
68626
|
-
if (ev.key === "Escape") {
|
|
68627
|
-
target.value = `${this.currentFontSize}`;
|
|
68628
|
-
}
|
|
68629
|
-
this.props.onToggle();
|
|
68630
|
-
}
|
|
68631
|
-
}
|
|
68632
|
-
}
|
|
68633
|
-
|
|
68634
68682
|
class TableDropdownButton extends Component {
|
|
68635
68683
|
static template = "o-spreadsheet-TableDropdownButton";
|
|
68636
68684
|
static components = { TableStylesPopover, ActionButton };
|
|
@@ -68799,9 +68847,6 @@ class TopBar extends Component {
|
|
|
68799
68847
|
onClick: Function,
|
|
68800
68848
|
dropdownMaxHeight: Number,
|
|
68801
68849
|
};
|
|
68802
|
-
get dropdownStyle() {
|
|
68803
|
-
return `max-height:${this.props.dropdownMaxHeight}px`;
|
|
68804
|
-
}
|
|
68805
68850
|
static components = {
|
|
68806
68851
|
ColorPickerWidget,
|
|
68807
68852
|
ColorPicker,
|
|
@@ -68839,6 +68884,9 @@ class TopBar extends Component {
|
|
|
68839
68884
|
.getAllOrdered()
|
|
68840
68885
|
.filter((item) => !item.isVisible || item.isVisible(this.env));
|
|
68841
68886
|
}
|
|
68887
|
+
get currentFontSize() {
|
|
68888
|
+
return this.env.model.getters.getCurrentStyle().fontSize || DEFAULT_FONT_SIZE;
|
|
68889
|
+
}
|
|
68842
68890
|
onExternalClick(ev) {
|
|
68843
68891
|
// TODO : manage click events better. We need this piece of code
|
|
68844
68892
|
// otherwise the event opening the menu would close it on the same frame.
|
|
@@ -68917,6 +68965,9 @@ class TopBar extends Component {
|
|
|
68917
68965
|
setStyle(this.env, { [target]: color });
|
|
68918
68966
|
this.onClick();
|
|
68919
68967
|
}
|
|
68968
|
+
setFontSize(fontSize) {
|
|
68969
|
+
setStyle(this.env, { fontSize });
|
|
68970
|
+
}
|
|
68920
68971
|
}
|
|
68921
68972
|
|
|
68922
68973
|
function instantiateClipboard() {
|
|
@@ -70917,12 +70968,11 @@ function createChart(chart, chartSheetIndex, data) {
|
|
|
70917
70968
|
// <manualLayout/> to manually position the chart in the figure container
|
|
70918
70969
|
let title = escapeXml ``;
|
|
70919
70970
|
if (chart.data.title?.text) {
|
|
70920
|
-
const
|
|
70921
|
-
|
|
70922
|
-
: chart.data.fontColor;
|
|
70971
|
+
const titleColor = toXlsxHexColor(chartMutedFontColor(chart.data.backgroundColor));
|
|
70972
|
+
const fontSize = chart.data.title.fontSize ?? CHART_TITLE_FONT_SIZE;
|
|
70923
70973
|
title = escapeXml /*xml*/ `
|
|
70924
70974
|
<c:title>
|
|
70925
|
-
${insertText(chart.data.title.text,
|
|
70975
|
+
${insertText(chart.data.title.text, titleColor, fontSize, chart.data.title)}
|
|
70926
70976
|
<c:overlay val="0" />
|
|
70927
70977
|
</c:title>
|
|
70928
70978
|
`;
|
|
@@ -71012,7 +71062,7 @@ function lineAttributes(params) {
|
|
|
71012
71062
|
</a:ln>
|
|
71013
71063
|
`;
|
|
71014
71064
|
}
|
|
71015
|
-
function insertText(text, fontColor = "000000", fontsize =
|
|
71065
|
+
function insertText(text, fontColor = "000000", fontsize = CHART_TITLE_FONT_SIZE, style = {}) {
|
|
71016
71066
|
return escapeXml /*xml*/ `
|
|
71017
71067
|
<c:tx>
|
|
71018
71068
|
<c:rich>
|
|
@@ -71513,6 +71563,7 @@ function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, del
|
|
|
71513
71563
|
// Each Axis present inside a graph needs to be identified by an unsigned integer in order to be referenced by its crossAxis.
|
|
71514
71564
|
// I.e. x-axis, will reference y-axis and vice-versa.
|
|
71515
71565
|
const color = title?.color ? toXlsxHexColor(title.color) : defaultFontColor;
|
|
71566
|
+
const fontSize = title?.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE;
|
|
71516
71567
|
return escapeXml /*xml*/ `
|
|
71517
71568
|
<${axisName}>
|
|
71518
71569
|
<c:axId val="${axId}"/>
|
|
@@ -71528,7 +71579,7 @@ function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, del
|
|
|
71528
71579
|
<c:minorTickMark val="none" />
|
|
71529
71580
|
<c:numFmt formatCode="General" sourceLinked="1" />
|
|
71530
71581
|
<c:title>
|
|
71531
|
-
${insertText(title?.text ?? "", color,
|
|
71582
|
+
${insertText(title?.text ?? "", color, fontSize, title)}
|
|
71532
71583
|
</c:title>
|
|
71533
71584
|
${insertTextProperties(10, defaultFontColor)}
|
|
71534
71585
|
</${axisName}>
|
|
@@ -73639,6 +73690,7 @@ const helpers = {
|
|
|
73639
73690
|
createPivotFormula,
|
|
73640
73691
|
areDomainArgsFieldsValid,
|
|
73641
73692
|
splitReference,
|
|
73693
|
+
sanitizeSheetName,
|
|
73642
73694
|
};
|
|
73643
73695
|
const links = {
|
|
73644
73696
|
isMarkdownLink,
|
|
@@ -73733,6 +73785,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
73733
73785
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
73734
73786
|
|
|
73735
73787
|
|
|
73736
|
-
__info__.version = "18.1.0-alpha.
|
|
73737
|
-
__info__.date = "2024-
|
|
73738
|
-
__info__.hash = "
|
|
73788
|
+
__info__.version = "18.1.0-alpha.7";
|
|
73789
|
+
__info__.date = "2024-12-05T10:40:26.512Z";
|
|
73790
|
+
__info__.hash = "7b1c39b";
|