@odoo/o-spreadsheet 17.4.9 → 17.4.11
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 +150 -82
- package/dist/o-spreadsheet.d.ts +3 -0
- package/dist/o-spreadsheet.esm.js +150 -82
- package/dist/o-spreadsheet.iife.js +150 -82
- package/dist/o-spreadsheet.iife.min.js +345 -345
- package/dist/o_spreadsheet.xml +4 -4
- 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 17.4.
|
|
6
|
-
* @date 2024-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.4.11
|
|
6
|
+
* @date 2024-11-08T12:15:26.239Z
|
|
7
|
+
* @hash 2eb3f1c
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -7626,7 +7626,10 @@
|
|
|
7626
7626
|
case "STRING":
|
|
7627
7627
|
return { type: "STRING", value: removeStringQuotes(current.value) };
|
|
7628
7628
|
case "INVALID_REFERENCE":
|
|
7629
|
-
|
|
7629
|
+
return {
|
|
7630
|
+
type: "REFERENCE",
|
|
7631
|
+
value: CellErrorType.InvalidReference,
|
|
7632
|
+
};
|
|
7630
7633
|
case "REFERENCE":
|
|
7631
7634
|
if (tokens[0]?.value === ":" && tokens[1]?.type === "REFERENCE") {
|
|
7632
7635
|
tokens.shift();
|
|
@@ -8430,6 +8433,7 @@
|
|
|
8430
8433
|
StackedBarChart: _t("Stacked bar chart"),
|
|
8431
8434
|
StackedLineChart: _t("Stacked line chart"),
|
|
8432
8435
|
StackedAreaChart: _t("Stacked area chart"),
|
|
8436
|
+
StackedColumnChart: _t("Stacked column chart"),
|
|
8433
8437
|
CumulativeData: _t("Cumulative data"),
|
|
8434
8438
|
TreatLabelsAsText: _t("Treat labels as text"),
|
|
8435
8439
|
AggregatedChart: _t("Aggregate"),
|
|
@@ -10624,67 +10628,112 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
10624
10628
|
ctx.save();
|
|
10625
10629
|
ctx.textAlign = "center";
|
|
10626
10630
|
ctx.textBaseline = "middle";
|
|
10627
|
-
ctx.
|
|
10628
|
-
|
|
10629
|
-
|
|
10630
|
-
|
|
10631
|
-
|
|
10632
|
-
|
|
10633
|
-
|
|
10634
|
-
|
|
10635
|
-
|
|
10636
|
-
|
|
10637
|
-
|
|
10638
|
-
|
|
10639
|
-
|
|
10640
|
-
ctx.fillStyle = chartFontColor(bar.options.backgroundColor);
|
|
10641
|
-
ctx.strokeStyle = chartFontColor(ctx.fillStyle);
|
|
10642
|
-
const value = options.callback(dataset._parsed[i]);
|
|
10643
|
-
ctx.strokeText(value, x, y);
|
|
10644
|
-
ctx.fillText(value, x, y);
|
|
10645
|
-
}
|
|
10646
|
-
break;
|
|
10647
|
-
}
|
|
10648
|
-
case "bar":
|
|
10649
|
-
case "line": {
|
|
10650
|
-
const yOffset = dataset.type === "bar" && !options.horizontal ? 0 : 3;
|
|
10651
|
-
for (let i = 0; i < dataset._parsed.length; i++) {
|
|
10652
|
-
const point = dataset.data[i];
|
|
10653
|
-
const value = options.horizontal ? dataset._parsed[i].x : dataset._parsed[i].y;
|
|
10654
|
-
const displayedValue = options.callback(value - 0);
|
|
10655
|
-
let xPosition = 0, yPosition = 0;
|
|
10656
|
-
if (options.horizontal) {
|
|
10657
|
-
yPosition = point.y;
|
|
10658
|
-
if (value < 0) {
|
|
10659
|
-
ctx.textAlign = "right";
|
|
10660
|
-
xPosition = point.x - yOffset;
|
|
10661
|
-
}
|
|
10662
|
-
else {
|
|
10663
|
-
ctx.textAlign = "left";
|
|
10664
|
-
xPosition = point.x + yOffset;
|
|
10665
|
-
}
|
|
10666
|
-
}
|
|
10667
|
-
else {
|
|
10668
|
-
xPosition = point.x;
|
|
10669
|
-
if (value < 0) {
|
|
10670
|
-
ctx.textBaseline = "top";
|
|
10671
|
-
yPosition = point.y + yOffset;
|
|
10672
|
-
}
|
|
10673
|
-
else {
|
|
10674
|
-
ctx.textBaseline = "bottom";
|
|
10675
|
-
yPosition = point.y - yOffset;
|
|
10676
|
-
}
|
|
10677
|
-
}
|
|
10678
|
-
ctx.strokeText(displayedValue, xPosition, yPosition);
|
|
10679
|
-
ctx.fillText(displayedValue, xPosition, yPosition);
|
|
10680
|
-
}
|
|
10681
|
-
break;
|
|
10682
|
-
}
|
|
10683
|
-
}
|
|
10684
|
-
});
|
|
10631
|
+
ctx.miterLimit = 1; // Avoid sharp artifacts on strokeText
|
|
10632
|
+
switch (chart.config.type) {
|
|
10633
|
+
case "pie":
|
|
10634
|
+
case "doughnut":
|
|
10635
|
+
drawPieChartValues(chart, options, ctx);
|
|
10636
|
+
break;
|
|
10637
|
+
case "bar":
|
|
10638
|
+
case "line":
|
|
10639
|
+
options.horizontal
|
|
10640
|
+
? drawHorizontalBarChartValues(chart, options, ctx)
|
|
10641
|
+
: drawLineOrBarChartValues(chart, options, ctx);
|
|
10642
|
+
break;
|
|
10643
|
+
}
|
|
10685
10644
|
ctx.restore();
|
|
10686
10645
|
},
|
|
10687
10646
|
};
|
|
10647
|
+
function drawTextWithBackground(text, x, y, ctx) {
|
|
10648
|
+
ctx.lineWidth = 3; // Stroke the text with a big lineWidth width to have some kind of background
|
|
10649
|
+
ctx.strokeText(text, x, y);
|
|
10650
|
+
ctx.lineWidth = 1;
|
|
10651
|
+
ctx.fillText(text, x, y);
|
|
10652
|
+
}
|
|
10653
|
+
function drawLineOrBarChartValues(chart, options, ctx) {
|
|
10654
|
+
const yMax = chart.chartArea.bottom;
|
|
10655
|
+
const yMin = chart.chartArea.top;
|
|
10656
|
+
const textsPositions = {};
|
|
10657
|
+
for (const dataset of chart._metasets) {
|
|
10658
|
+
for (let i = 0; i < dataset._parsed.length; i++) {
|
|
10659
|
+
const value = dataset._parsed[i].y;
|
|
10660
|
+
const point = dataset.data[i];
|
|
10661
|
+
const xPosition = point.x;
|
|
10662
|
+
let yPosition = 0;
|
|
10663
|
+
if (chart.config.type === "line") {
|
|
10664
|
+
yPosition = point.y - 10;
|
|
10665
|
+
}
|
|
10666
|
+
else {
|
|
10667
|
+
yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
|
|
10668
|
+
}
|
|
10669
|
+
yPosition = Math.min(yPosition, yMax);
|
|
10670
|
+
yPosition = Math.max(yPosition, yMin);
|
|
10671
|
+
// Avoid overlapping texts with same X
|
|
10672
|
+
if (!textsPositions[xPosition]) {
|
|
10673
|
+
textsPositions[xPosition] = [];
|
|
10674
|
+
}
|
|
10675
|
+
for (const otherPosition of textsPositions[xPosition] || []) {
|
|
10676
|
+
if (Math.abs(otherPosition - yPosition) < 13) {
|
|
10677
|
+
yPosition = otherPosition - 13;
|
|
10678
|
+
}
|
|
10679
|
+
}
|
|
10680
|
+
textsPositions[xPosition].push(yPosition);
|
|
10681
|
+
ctx.fillStyle = point.options.backgroundColor;
|
|
10682
|
+
ctx.strokeStyle = options.background || "#ffffff";
|
|
10683
|
+
drawTextWithBackground(options.callback(value - 0), xPosition, yPosition, ctx);
|
|
10684
|
+
}
|
|
10685
|
+
}
|
|
10686
|
+
}
|
|
10687
|
+
function drawHorizontalBarChartValues(chart, options, ctx) {
|
|
10688
|
+
const xMax = chart.chartArea.right;
|
|
10689
|
+
const xMin = chart.chartArea.left;
|
|
10690
|
+
const textsPositions = {};
|
|
10691
|
+
for (const dataset of chart._metasets) {
|
|
10692
|
+
for (let i = 0; i < dataset._parsed.length; i++) {
|
|
10693
|
+
const value = dataset._parsed[i].x;
|
|
10694
|
+
const displayValue = options.callback(value - 0);
|
|
10695
|
+
const point = dataset.data[i];
|
|
10696
|
+
const yPosition = point.y;
|
|
10697
|
+
let xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
|
|
10698
|
+
xPosition = Math.min(xPosition, xMax);
|
|
10699
|
+
xPosition = Math.max(xPosition, xMin);
|
|
10700
|
+
// Avoid overlapping texts with same Y
|
|
10701
|
+
if (!textsPositions[yPosition]) {
|
|
10702
|
+
textsPositions[yPosition] = [];
|
|
10703
|
+
}
|
|
10704
|
+
const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
|
|
10705
|
+
for (const otherPosition of textsPositions[yPosition]) {
|
|
10706
|
+
if (Math.abs(otherPosition - xPosition) < textWidth) {
|
|
10707
|
+
xPosition = otherPosition + textWidth + 3;
|
|
10708
|
+
}
|
|
10709
|
+
}
|
|
10710
|
+
textsPositions[yPosition].push(xPosition);
|
|
10711
|
+
ctx.fillStyle = point.options.backgroundColor;
|
|
10712
|
+
ctx.strokeStyle = options.background || "#ffffff";
|
|
10713
|
+
drawTextWithBackground(displayValue, xPosition, yPosition, ctx);
|
|
10714
|
+
}
|
|
10715
|
+
}
|
|
10716
|
+
}
|
|
10717
|
+
function drawPieChartValues(chart, options, ctx) {
|
|
10718
|
+
for (const dataset of chart._metasets) {
|
|
10719
|
+
for (let i = 0; i < dataset._parsed.length; i++) {
|
|
10720
|
+
const value = Number(dataset._parsed[i]);
|
|
10721
|
+
if (isNaN(value) || value === 0) {
|
|
10722
|
+
continue;
|
|
10723
|
+
}
|
|
10724
|
+
const bar = dataset.data[i];
|
|
10725
|
+
const { startAngle, endAngle, innerRadius, outerRadius } = bar;
|
|
10726
|
+
const midAngle = (startAngle + endAngle) / 2;
|
|
10727
|
+
const midRadius = (innerRadius + outerRadius) / 2;
|
|
10728
|
+
const x = bar.x + midRadius * Math.cos(midAngle);
|
|
10729
|
+
const y = bar.y + midRadius * Math.sin(midAngle) + 7;
|
|
10730
|
+
ctx.fillStyle = chartFontColor(options.background);
|
|
10731
|
+
ctx.strokeStyle = options.background || "#ffffff";
|
|
10732
|
+
const displayValue = options.callback(value);
|
|
10733
|
+
drawTextWithBackground(displayValue, x, y, ctx);
|
|
10734
|
+
}
|
|
10735
|
+
}
|
|
10736
|
+
}
|
|
10688
10737
|
|
|
10689
10738
|
/** This is a chartJS plugin that will draw connector lines between the bars of a Waterfall chart */
|
|
10690
10739
|
const waterfallLinesPlugin = {
|
|
@@ -23414,7 +23463,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
23414
23463
|
const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
|
|
23415
23464
|
// tooltipItem.parsed can be an object or a number for pie charts
|
|
23416
23465
|
let yLabel = horizontalChart ? tooltipItem.parsed.x : tooltipItem.parsed.y;
|
|
23417
|
-
if (
|
|
23466
|
+
if (yLabel === undefined || yLabel === null) {
|
|
23418
23467
|
yLabel = tooltipItem.parsed;
|
|
23419
23468
|
}
|
|
23420
23469
|
const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
|
|
@@ -31585,6 +31634,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
31585
31634
|
|
|
31586
31635
|
class BarConfigPanel extends GenericChartConfigPanel {
|
|
31587
31636
|
static template = "o-spreadsheet-BarConfigPanel";
|
|
31637
|
+
get stackedLabel() {
|
|
31638
|
+
const definition = this.props.definition;
|
|
31639
|
+
return definition.horizontal
|
|
31640
|
+
? this.chartTerms.StackedBarChart
|
|
31641
|
+
: this.chartTerms.StackedColumnChart;
|
|
31642
|
+
}
|
|
31588
31643
|
onUpdateStacked(stacked) {
|
|
31589
31644
|
this.props.updateChart(this.props.figureId, {
|
|
31590
31645
|
stacked,
|
|
@@ -32753,7 +32808,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32753
32808
|
}
|
|
32754
32809
|
get stackedLabel() {
|
|
32755
32810
|
const definition = this.props.definition;
|
|
32756
|
-
return definition.fillArea
|
|
32811
|
+
return definition.fillArea
|
|
32812
|
+
? this.chartTerms.StackedAreaChart
|
|
32813
|
+
: this.chartTerms.StackedLineChart;
|
|
32757
32814
|
}
|
|
32758
32815
|
getLabelRangeOptions() {
|
|
32759
32816
|
const options = super.getLabelRangeOptions();
|
|
@@ -46531,7 +46588,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
46531
46588
|
if (!data) {
|
|
46532
46589
|
return createEmptyWorkbookData();
|
|
46533
46590
|
}
|
|
46534
|
-
console.
|
|
46591
|
+
console.debug("### Loading data ###");
|
|
46535
46592
|
const start = performance.now();
|
|
46536
46593
|
if (data["[Content_Types].xml"]) {
|
|
46537
46594
|
const reader = new XlsxReader(data);
|
|
@@ -46545,13 +46602,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
46545
46602
|
// apply migrations, if needed
|
|
46546
46603
|
if ("version" in data) {
|
|
46547
46604
|
if (data.version < CURRENT_VERSION) {
|
|
46548
|
-
console.
|
|
46605
|
+
console.debug("Migrating data from version", data.version);
|
|
46549
46606
|
data = migrate(data);
|
|
46550
46607
|
}
|
|
46551
46608
|
}
|
|
46552
46609
|
data = repairData(data);
|
|
46553
|
-
console.
|
|
46554
|
-
console.
|
|
46610
|
+
console.debug("Data loaded in", performance.now() - start, "ms");
|
|
46611
|
+
console.debug("###");
|
|
46555
46612
|
return data;
|
|
46556
46613
|
}
|
|
46557
46614
|
function migrate(data) {
|
|
@@ -46560,7 +46617,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
46560
46617
|
for (let i = index; i < MIGRATIONS.length; i++) {
|
|
46561
46618
|
data = MIGRATIONS[i].applyMigration(data);
|
|
46562
46619
|
}
|
|
46563
|
-
console.
|
|
46620
|
+
console.debug("Data migrated in", performance.now() - start, "ms");
|
|
46564
46621
|
return data;
|
|
46565
46622
|
}
|
|
46566
46623
|
const MIGRATIONS = [
|
|
@@ -54120,7 +54177,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54120
54177
|
cellsToCompute.addMany(arrayFormulasPositions);
|
|
54121
54178
|
cellsToCompute.addMany(this.getCellsDependingOn(arrayFormulasPositions));
|
|
54122
54179
|
this.evaluate(cellsToCompute);
|
|
54123
|
-
console.
|
|
54180
|
+
console.debug("evaluate Cells", performance.now() - start, "ms");
|
|
54124
54181
|
}
|
|
54125
54182
|
getArrayFormulasImpactedByChangesOf(positions) {
|
|
54126
54183
|
const impactedPositions = this.createEmptyPositionSet();
|
|
@@ -54159,7 +54216,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54159
54216
|
const start = performance.now();
|
|
54160
54217
|
this.evaluatedCells = new PositionMap();
|
|
54161
54218
|
this.evaluate(this.getAllCells());
|
|
54162
|
-
console.
|
|
54219
|
+
console.debug("evaluate all cells", performance.now() - start, "ms");
|
|
54163
54220
|
}
|
|
54164
54221
|
evaluateFormulaResult(sheetId, formulaString) {
|
|
54165
54222
|
try {
|
|
@@ -55981,6 +56038,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
55981
56038
|
if (!pivot.isValid()) {
|
|
55982
56039
|
return EMPTY_PIVOT_CELL;
|
|
55983
56040
|
}
|
|
56041
|
+
if (functionName === "PIVOT" &&
|
|
56042
|
+
!cell.content.replaceAll(" ", "").toUpperCase().startsWith("=PIVOT")) {
|
|
56043
|
+
return EMPTY_PIVOT_CELL;
|
|
56044
|
+
}
|
|
55984
56045
|
if (functionName === "PIVOT") {
|
|
55985
56046
|
const includeTotal = args[2] === false ? false : undefined;
|
|
55986
56047
|
const includeColumnHeaders = args[3] === false ? false : undefined;
|
|
@@ -57309,7 +57370,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57309
57370
|
this.onMessageReceived(message);
|
|
57310
57371
|
}
|
|
57311
57372
|
this.isReplayingInitialRevisions = false;
|
|
57312
|
-
console.
|
|
57373
|
+
console.debug("Replayed", numberOfCommands, "commands in", performance.now() - start, "ms");
|
|
57313
57374
|
}
|
|
57314
57375
|
/**
|
|
57315
57376
|
* Notify the server that the user client left the collaborative session
|
|
@@ -66572,7 +66633,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66572
66633
|
}
|
|
66573
66634
|
const attrs = [["t", type]];
|
|
66574
66635
|
const XlsxFormula = adaptFormulaToExcel(formula);
|
|
66575
|
-
const
|
|
66636
|
+
const exportedValue = adaptFormulaValueToExcel(cell.value);
|
|
66637
|
+
const node = escapeXml /*xml*/ `<f>${XlsxFormula}</f><v>${exportedValue}</v>`;
|
|
66576
66638
|
return { attrs, node };
|
|
66577
66639
|
}
|
|
66578
66640
|
function addContent(content, sharedStrings, forceString = false) {
|
|
@@ -66607,8 +66669,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66607
66669
|
ast = addMissingRequiredArgs(ast);
|
|
66608
66670
|
return ast;
|
|
66609
66671
|
});
|
|
66672
|
+
ast = convertAstNodes(ast, "REFERENCE", (ast) => {
|
|
66673
|
+
return ast.value === CellErrorType.InvalidReference ? { ...ast, value: "#REF!" } : ast;
|
|
66674
|
+
});
|
|
66610
66675
|
return ast ? astToFormula(ast) : formulaText;
|
|
66611
66676
|
}
|
|
66677
|
+
function adaptFormulaValueToExcel(formulaValue) {
|
|
66678
|
+
return formulaValue === CellErrorType.InvalidReference ? "#REF!" : formulaValue;
|
|
66679
|
+
}
|
|
66612
66680
|
/**
|
|
66613
66681
|
* Some Excel function need required args that might not be mandatory in o-spreadsheet.
|
|
66614
66682
|
* This adds those missing args.
|
|
@@ -67919,7 +67987,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67919
67987
|
coreHandlers = [];
|
|
67920
67988
|
constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = true) {
|
|
67921
67989
|
const start = performance.now();
|
|
67922
|
-
console.
|
|
67990
|
+
console.debug("##### Model creation #####");
|
|
67923
67991
|
super();
|
|
67924
67992
|
setDefaultTranslationMethod();
|
|
67925
67993
|
stateUpdateMessages = repairInitialMessages(data, stateUpdateMessages);
|
|
@@ -67991,16 +68059,16 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67991
68059
|
this.joinSession();
|
|
67992
68060
|
if (config.snapshotRequested) {
|
|
67993
68061
|
const startSnapshot = performance.now();
|
|
67994
|
-
console.
|
|
68062
|
+
console.debug("Snapshot requested");
|
|
67995
68063
|
this.session.snapshot(this.exportData());
|
|
67996
68064
|
this.garbageCollectExternalResources();
|
|
67997
|
-
console.
|
|
68065
|
+
console.debug("Snapshot taken in", performance.now() - startSnapshot, "ms");
|
|
67998
68066
|
}
|
|
67999
68067
|
// mark all models as "raw", so they will not be turned into reactive objects
|
|
68000
68068
|
// by owl, since we do not rely on reactivity
|
|
68001
68069
|
owl.markRaw(this);
|
|
68002
|
-
console.
|
|
68003
|
-
console.
|
|
68070
|
+
console.debug("Model created in", performance.now() - start, "ms");
|
|
68071
|
+
console.debug("######");
|
|
68004
68072
|
}
|
|
68005
68073
|
joinSession() {
|
|
68006
68074
|
this.session.join(this.config.client);
|
|
@@ -68223,7 +68291,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68223
68291
|
this.finalize();
|
|
68224
68292
|
const time = performance.now() - start;
|
|
68225
68293
|
if (time > 5) {
|
|
68226
|
-
console.
|
|
68294
|
+
console.debug(type, time, "ms");
|
|
68227
68295
|
}
|
|
68228
68296
|
});
|
|
68229
68297
|
this.session.save(command, commands, changes);
|
|
@@ -68609,9 +68677,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68609
68677
|
exports.tokenize = tokenize;
|
|
68610
68678
|
|
|
68611
68679
|
|
|
68612
|
-
__info__.version = "17.4.
|
|
68613
|
-
__info__.date = "2024-
|
|
68614
|
-
__info__.hash = "
|
|
68680
|
+
__info__.version = "17.4.11";
|
|
68681
|
+
__info__.date = "2024-11-08T12:15:26.239Z";
|
|
68682
|
+
__info__.hash = "2eb3f1c";
|
|
68615
68683
|
|
|
68616
68684
|
|
|
68617
68685
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|