diff --git a/src/functions/module_lookup.ts b/src/functions/module_lookup.ts index 51cd5503e3..e1b8dd72df 100644 --- a/src/functions/module_lookup.ts +++ b/src/functions/module_lookup.ts @@ -1,4 +1,5 @@ import { getFullReference, range, splitReference, toXC, toZone } from "../helpers/index"; +import { addRowIndentToPivotHeader } from "../helpers/pivot/pivot_helpers"; import { _t } from "../translation"; import { AddFunctionDescription, FunctionResultObject, Matrix, Maybe, Zone } from "../types"; import { CellErrorType, EvaluationError, InvalidReferenceError } from "../types/errors"; @@ -829,7 +830,8 @@ export const PIVOT = { result[col].push({ value: "" }); break; case "HEADER": - result[col].push(pivot.getPivotHeaderValueAndFormat(pivotCell.domain)); + const value = pivot.getPivotHeaderValueAndFormat(pivotCell.domain); + result[col].push(addRowIndentToPivotHeader(pivot, pivotCell.domain, value)); break; case "MEASURE_HEADER": result[col].push(pivot.getPivotMeasureValue(pivotCell.measure, pivotCell.domain)); diff --git a/src/helpers/pivot/pivot_helpers.ts b/src/helpers/pivot/pivot_helpers.ts index 254bc8a8d8..4420f3ed05 100644 --- a/src/helpers/pivot/pivot_helpers.ts +++ b/src/helpers/pivot/pivot_helpers.ts @@ -4,7 +4,14 @@ import { average, countAny, max, min } from "../../functions/helper_statistical" import { inferFormat, toBoolean, toNumber, toString } from "../../functions/helpers"; import { Registry } from "../../registries/registry"; import { _t } from "../../translation"; -import { CellValue, DEFAULT_LOCALE, FunctionResultObject, Locale, Matrix } from "../../types"; +import { + CellValue, + DEFAULT_LOCALE, + FunctionResultObject, + Locale, + Matrix, + Pivot, +} from "../../types"; import { EvaluationError } from "../../types/errors"; import { Granularity, @@ -14,6 +21,7 @@ import { PivotField, PivotTableCell, } from "../../types/pivot"; +import { domainToColRowDomain } from "./pivot_domain_helpers"; import { PivotRuntimeDefinition } from "./pivot_runtime_definition"; import { pivotTimeAdapter } from "./pivot_time_adapter"; @@ -268,3 +276,22 @@ export const NEXT_VALUE = "(next)"; export function getFieldDisplayName(field: PivotDimension) { return field.displayName + (field.granularity ? ` (${ALL_PERIODS[field.granularity]})` : ""); } + +export function addRowIndentToPivotHeader( + pivot: Pivot, + domain: PivotDomain, + functionResult: FunctionResultObject +): FunctionResultObject { + const { rowDomain } = domainToColRowDomain(pivot, domain); + if (rowDomain.length === 0) { + return functionResult; + } + const indent = rowDomain.length - 1; + + const format = functionResult.format || "@"; + + return { + ...functionResult, + format: `${" ".repeat(indent)}${format}* `, + }; +} diff --git a/src/helpers/pivot/pivot_time_adapter.ts b/src/helpers/pivot/pivot_time_adapter.ts index 181e8b7cad..281d2cdd5e 100644 --- a/src/helpers/pivot/pivot_time_adapter.ts +++ b/src/helpers/pivot/pivot_time_adapter.ts @@ -159,7 +159,7 @@ const monthNumberAdapter: PivotTimeAdapterNotNull = { toValueAndFormat(normalizedValue) { return { value: MONTHS[toNumber(normalizedValue, DEFAULT_LOCALE) - 1].toString(), - format: "0", + format: "@", }; }, toFunctionValue(normalizedValue) { @@ -183,7 +183,7 @@ const quarterNumberAdapter: PivotTimeAdapterNotNull = { toValueAndFormat(normalizedValue) { return { value: _t("Q%(quarter_number)s", { quarter_number: normalizedValue }), - format: "0", + format: "@", }; }, toFunctionValue(normalizedValue) { diff --git a/tests/pivots/pivot_calculated_measure.test.ts b/tests/pivots/pivot_calculated_measure.test.ts index 8d4f555a17..ec9ac42f11 100644 --- a/tests/pivots/pivot_calculated_measure.test.ts +++ b/tests/pivots/pivot_calculated_measure.test.ts @@ -147,14 +147,14 @@ describe("Pivot calculated measure", () => { // prettier-ignore expect(getEvaluatedGrid(model, "A5:C12")).toEqual( [ - ["(#1) Pivot", "Total", "",], - ["", "calc Customer", "calc Category"], - ["Alice", "1", "2"], - ["Food", "Alice", "Food"], - ["Drink", "Alice", "Drink"], - ["Bob", "1", "1"], - ["Food", "Bob", "Food"], - ["Total", "2", "2"], + ["(#1) Pivot", "Total", "",], + ["", "calc Customer", "calc Category"], + ["Alice", "1", "2"], + [" Food", "Alice", "Food"], + [" Drink", "Alice", "Drink"], + ["Bob", "1", "1"], + [" Food", "Bob", "Food"], + ["Total", "2", "2"], ] ); }); @@ -259,12 +259,12 @@ describe("Pivot calculated measure", () => { // prettier-ignore expect(getEvaluatedGrid(model, "A5:C10")).toEqual( [ - ["(#1) Pivot", "10", "Total"], - ["", "calc Category", "calc Category"], - ["Alice", "2", "2"], - ["Food", "Food", "1"], - ["Drink", "Drink", "1"], - ["Total", "2", "2" ], + ["(#1) Pivot", "10", "Total"], + ["", "calc Category", "calc Category"], + ["Alice", "2", "2"], + [" Food", "Food", "1"], + [" Drink", "Drink", "1"], + ["Total", "2", "2" ], ] ); }); @@ -354,14 +354,14 @@ describe("Pivot calculated measure", () => { // prettier-ignore expect(getEvaluatedGrid(model, "A10:C17")).toEqual( [ - ["(#1) Pivot", "Total", ""], - ["", "Price", "Commission"], - ["Alice", "30", "3"], - ["Food", "10", "1"], - ["Drink", "20", "2"], - ["Bob", "10", "3"], - ["Food", "10", "3"], - ["Total", "40", "6" ], + ["(#1) Pivot", "Total", ""], + ["", "Price", "Commission"], + ["Alice", "30", "3"], + [" Food", "10", "1"], + [" Drink", "20", "2"], + ["Bob", "10", "3"], + [" Food", "10", "3"], + ["Total", "40", "6" ], ] ); }); @@ -550,12 +550,12 @@ describe("Pivot calculated measure", () => { }); // prettier-ignore expect(getEvaluatedGrid(model, "D1:F6")).toEqual([ - ["(#1) Pivot", "Total", ""], - ["", "Price", "calculated"], - ["Alice", "30", "50"], // 50 = 20 + 30 - ["2020", "10", "20"], // 20 = 10 + 10 - ["2021", "20", "30"], // 30 = 20 + 10 - ["Total", "30", "50"], + ["(#1) Pivot", "Total", ""], + ["", "Price", "calculated"], + ["Alice", "30", "50"], // 50 = 20 + 30 + [" 2020", "10", "20"], // 20 = 10 + 10 + [" 2021", "20", "30"], // 30 = 20 + 10 + ["Total", "30", "50"], ]); }); @@ -744,12 +744,12 @@ describe("Pivot calculated measure", () => { }); // prettier-ignore expect(getEvaluatedGrid(model, "D1:F6")).toEqual([ - ["(#1) Pivot", "Total", ""], - ["", "Price", "calculated"], - ["Alice", "1", "11"], - ["2020", "10", "20"], - ["2021", "1", "11"], - ["Total", "1", "11"], + ["(#1) Pivot", "Total", ""], + ["", "Price", "calculated"], + ["Alice", "1", "11"], + [" 2020", "10", "20"], + [" 2021", "1", "11"], + ["Total", "1", "11"], ]); }); diff --git a/tests/pivots/pivot_measure/pivot_measure_display_model.test.ts b/tests/pivots/pivot_measure/pivot_measure_display_model.test.ts index bee3b1eba0..4b1d1a4016 100644 --- a/tests/pivots/pivot_measure/pivot_measure_display_model.test.ts +++ b/tests/pivots/pivot_measure/pivot_measure_display_model.test.ts @@ -145,16 +145,16 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20: "(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "9.77%", C22: "0.00%", D22: "7.03%", - A23: "FALSE", B23: "100.00%", C23: "", D23: "100.00%", - A24: "March", B24: "54.47%", C24: "71.11%", D24: "59.15%", - A25: "FALSE", B25: "84.21%", C25: "82.81%", D25: "83.74%", - A26: "TRUE", B26: "15.79%", C26: "17.19%", D26: "16.26%", - A27: "April", B27: "35.75%", C27: "28.89%", D27: "33.82%", - A28: "FALSE", B28: "78.98%", C28: "0.00%", D28: "60.02%", - A29: "TRUE", B29: "21.02%", C29: "100.00%", D29: "39.98%", - A30: "Total", B30: "100.00%", C30: "100.00%", D30: "100.00%", + A20: "(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "9.77%", C22: "0.00%", D22: "7.03%", + A23: " FALSE", B23: "100.00%", C23: "", D23: "100.00%", + A24: "March", B24: "54.47%", C24: "71.11%", D24: "59.15%", + A25: " FALSE", B25: "84.21%", C25: "82.81%", D25: "83.74%", + A26: " TRUE", B26: "15.79%", C26: "17.19%", D26: "16.26%", + A27: "April", B27: "35.75%", C27: "28.89%", D27: "33.82%", + A28: " FALSE", B28: "78.98%", C28: "0.00%", D28: "60.02%", + A29: " TRUE", B29: "21.02%", C29: "100.00%", D29: "39.98%", + A30: "Total", B30: "100.00%", C30: "100.00%", D30: "100.00%", }); }); @@ -210,25 +210,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "100.00%", C22: "", D22: "100.00%", - A23: "FALSE", B23: "100.00%", C23: "", D23: "100.00%", - A24: "Won", B24: "100.00%", C24: "", D24: "100.00%", - A25: "March", B25: "100.00%", C25: "100.00%", D25: "100.00%", - A26: "FALSE", B26: "84.21%", C26: "82.81%", D26: "83.74%", - A27: "New", B27: "84.21%", C27: "23.44%", D27: "63.67%", - A28: "Won", B28: "0.00%", C28: "59.38%", D28: "20.06%", - A29: "TRUE", B29: "15.79%", C29: "17.19%", D29: "16.26%", - A30: "New", B30: "0.00%", C30: "17.19%", D30: "5.81%", - A31: "Won", B31: "15.79%", C31: "0.00%", D31: "10.45%", - A32: "April", B32: "100.00%", C32: "100.00%", D32: "100.00%", - A33: "FALSE", B33: "78.98%", C33: "0.00%", D33: "60.02%", - A34: "New", B34: "48.60%", C34: "0.00%", D34: "36.93%", - A35: "Won", B35: "30.38%", C35: "0.00%", D35: "23.08%", - A36: "TRUE", B36: "21.02%", C36: "100.00%", D36: "39.98%", - A37: "New", B37: "10.94%", C37: "92.31%", D37: "30.47%", - A38: "Won", B38: "10.09%", C38: "7.69%", D38: "9.51%", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "100.00%", C22: "", D22: "100.00%", + A23: " FALSE", B23: "100.00%", C23: "", D23: "100.00%", + A24: " Won", B24: "100.00%", C24: "", D24: "100.00%", + A25: "March", B25: "100.00%", C25: "100.00%", D25: "100.00%", + A26: " FALSE", B26: "84.21%", C26: "82.81%", D26: "83.74%", + A27: " New", B27: "84.21%", C27: "23.44%", D27: "63.67%", + A28: " Won", B28: "0.00%", C28: "59.38%", D28: "20.06%", + A29: " TRUE", B29: "15.79%", C29: "17.19%", D29: "16.26%", + A30: " New", B30: "0.00%", C30: "17.19%", D30: "5.81%", + A31: " Won", B31: "15.79%", C31: "0.00%", D31: "10.45%", + A32: "April", B32: "100.00%", C32: "100.00%", D32: "100.00%", + A33: " FALSE", B33: "78.98%", C33: "0.00%", D33: "60.02%", + A34: " New", B34: "48.60%", C34: "0.00%", D34: "36.93%", + A35: " Won", B35: "30.38%", C35: "0.00%", D35: "23.08%", + A36: " TRUE", B36: "21.02%", C36: "100.00%", D36: "39.98%", + A37: " New", B37: "10.94%", C37: "92.31%", D37: "30.47%", + A38: " Won", B38: "10.09%", C38: "7.69%", D38: "9.51%", + A39: "Total", B39: "", C39: "", D39: "", }); }); @@ -255,25 +255,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "100.00%", C23: "", D23: "100.00%", - A24: "Won", B24: "100.00%", C24: "", D24: "100.00%", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "100.00%", C26: "100.00%", D26: "100.00%", - A27: "New", B27: "100.00%", C27: "28.30%", D27: "76.04%", - A28: "Won", B28: "0.00%", C28: "71.70%", D28: "23.96%", - A29: "TRUE", B29: "100.00%", C29: "100.00%", D29: "100.00%", - A30: "New", B30: "0.00%", C30: "100.00%", D30: "35.71%", - A31: "Won", B31: "100.00%", C31: "0.00%", D31: "64.29%", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "100.00%", C33: "", D33: "100.00%", - A34: "New", B34: "61.54%", C34: "", D34: "61.54%", - A35: "Won", B35: "38.46%", C35: "", D35: "38.46%", - A36: "TRUE", B36: "100.00%", C36: "100.00%", D36: "100.00%", - A37: "New", B37: "52.02%", C37: "92.31%", D37: "76.21%", - A38: "Won", B38: "47.98%", C38: "7.69%", D38: "23.79%", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "100.00%", C23: "", D23: "100.00%", + A24: " Won", B24: "100.00%", C24: "", D24: "100.00%", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "100.00%", C26: "100.00%", D26: "100.00%", + A27: " New", B27: "100.00%", C27: "28.30%", D27: "76.04%", + A28: " Won", B28: "0.00%", C28: "71.70%", D28: "23.96%", + A29: " TRUE", B29: "100.00%", C29: "100.00%", D29: "100.00%", + A30: " New", B30: "0.00%", C30: "100.00%", D30: "35.71%", + A31: " Won", B31: "100.00%", C31: "0.00%", D31: "64.29%", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "100.00%", C33: "", D33: "100.00%", + A34: " New", B34: "61.54%", C34: "", D34: "61.54%", + A35: " Won", B35: "38.46%", C35: "", D35: "38.46%", + A36: " TRUE", B36: "100.00%", C36: "100.00%", D36: "100.00%", + A37: " New", B37: "52.02%", C37: "92.31%", D37: "76.21%", + A38: " Won", B38: "47.98%", C38: "7.69%", D38: "23.79%", + A39: "Total", B39: "", C39: "", D39: "", }); }); @@ -417,25 +417,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "100.00%", C23: "", D23: "100.00%", - A24: "Won", B24: "100.00%", C24: "", D24: "100.00%", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "100.00%", C26: "100.00%", D26: "100.00%", - A27: "New", B27: "100.00%", C27: "100.00%", D27: "100.00%", - A28: "Won", B28: "", C28: "100.00%", D28: "100.00%", - A29: "TRUE", B29: "18.75%", C29: "20.75%", D29: "19.42%", - A30: "New", B30: "#NULL!", C30: "73.33%", D30: "9.12%", - A31: "Won", B31: "", C31: "#NULL!", D31: "52.11%", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "100.00%", C33: "", D33: "100.00%", - A34: "New", B34: "100.00%", C34: "", D34: "100.00%", - A35: "Won", B35: "100.00%", C35: "", D35: "100.00%", - A36: "TRUE", B36: "26.62%", C36: "", D36: "66.62%", - A37: "New", B37: "22.50%", C37: "", D37: "82.50%", - A38: "Won", B38: "33.20%", C38: "", D38: "41.20%", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "100.00%", C23: "", D23: "100.00%", + A24: " Won", B24: "100.00%", C24: "", D24: "100.00%", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "100.00%", C26: "100.00%", D26: "100.00%", + A27: " New", B27: "100.00%", C27: "100.00%", D27: "100.00%", + A28: " Won", B28: "", C28: "100.00%", D28: "100.00%", + A29: " TRUE", B29: "18.75%", C29: "20.75%", D29: "19.42%", + A30: " New", B30: "#NULL!", C30: "73.33%", D30: "9.12%", + A31: " Won", B31: "", C31: "#NULL!", D31: "52.11%", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "100.00%", C33: "", D33: "100.00%", + A34: " New", B34: "100.00%", C34: "", D34: "100.00%", + A35: " Won", B35: "100.00%", C35: "", D35: "100.00%", + A36: " TRUE", B36: "26.62%", C36: "", D36: "66.62%", + A37: " New", B37: "22.50%", C37: "", D37: "82.50%", + A38: " Won", B38: "33.20%", C38: "", D38: "41.20%", + A39: "Total", B39: "", C39: "", D39: "", }); }); @@ -517,25 +517,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "100.00%", C23: "", D23: "100.00%", - A24: "Won", B24: "100.00%", C24: "", D24: "100.00%", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "100.00%", C26: "100.00%", D26: "100.00%", - A27: "New", B27: "100.00%", C27: "100.00%", D27: "100.00%", - A28: "Won", B28: "", C28: "100.00%", D28: "100.00%", - A29: "TRUE", B29: "18.75%", C29: "20.75%", D29: "19.42%", - A30: "New", B30: "#NULL!", C30: "73.33%", D30: "9.12%", - A31: "Won", B31: "", C31: "#NULL!", D31: "52.11%", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "100.00%", C33: "", D33: "100.00%", - A34: "New", B34: "100.00%", C34: "", D34: "100.00%", - A35: "Won", B35: "100.00%", C35: "", D35: "100.00%", - A36: "TRUE", B36: "26.62%", C36: "", D36: "66.62%", - A37: "New", B37: "22.50%", C37: "", D37: "82.50%", - A38: "Won", B38: "33.20%", C38: "", D38: "41.20%", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "100.00%", C23: "", D23: "100.00%", + A24: " Won", B24: "100.00%", C24: "", D24: "100.00%", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "100.00%", C26: "100.00%", D26: "100.00%", + A27: " New", B27: "100.00%", C27: "100.00%", D27: "100.00%", + A28: " Won", B28: "", C28: "100.00%", D28: "100.00%", + A29: " TRUE", B29: "18.75%", C29: "20.75%", D29: "19.42%", + A30: " New", B30: "#NULL!", C30: "73.33%", D30: "9.12%", + A31: " Won", B31: "", C31: "#NULL!", D31: "52.11%", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "100.00%", C33: "", D33: "100.00%", + A34: " New", B34: "100.00%", C34: "", D34: "100.00%", + A35: " Won", B35: "100.00%", C35: "", D35: "100.00%", + A36: " TRUE", B36: "26.62%", C36: "", D36: "66.62%", + A37: " New", B37: "22.50%", C37: "", D37: "82.50%", + A38: " Won", B38: "33.20%", C38: "", D38: "41.20%", + A39: "Total", B39: "", C39: "", D39: "", }); }); @@ -732,25 +732,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "#N/A", C23: "#N/A", D23: "#N/A", - A24: "Won", B24: "#N/A", C24: "#N/A", D24: "#N/A", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "85800", C26: "42000", D26: "127800", - A27: "New", B27: "105600", C27: "4000", D27: "109600", - A28: "Won", B28: "-19800", C28: "38000", D28: "18200", - A29: "TRUE", B29: "", C29: "", D29: "", - A30: "New", B30: "", C30: "", D30: "", - A31: "Won", B31: "", C31: "", D31: "", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "47700", C33: "-26000", D33: "21700", - A34: "New", B34: "31000", C34: "-24000", D34: "7000", - A35: "Won", B35: "16700", C35: "-2000", D35: "14700", - A36: "TRUE", B36: "", C36: "", D36: "", - A37: "New", B37: "", C37: "", D37: "", - A38: "Won", B38: "", C38: "", D38: "", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "#N/A", C23: "#N/A", D23: "#N/A", + A24: " Won", B24: "#N/A", C24: "#N/A", D24: "#N/A", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "85800", C26: "42000", D26: "127800", + A27: " New", B27: "105600", C27: "4000", D27: "109600", + A28: " Won", B28: "-19800", C28: "38000", D28: "18200", + A29: " TRUE", B29: "", C29: "", D29: "", + A30: " New", B30: "", C30: "", D30: "", + A31: " Won", B31: "", C31: "", D31: "", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "47700", C33: "-26000", D33: "21700", + A34: " New", B34: "31000", C34: "-24000", D34: "7000", + A35: " Won", B35: "16700", C35: "-2000", D35: "14700", + A36: " TRUE", B36: "", C36: "", D36: "", + A37: " New", B37: "", C37: "", D37: "", + A38: " Won", B38: "", C38: "", D38: "", + A39: "Total", B39: "", C39: "", D39: "", }); }); @@ -778,25 +778,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "", C23: "", D23: "", - A24: "Won", B24: "", C24: "", D24: "", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "", C26: "", D26: "", - A27: "New", B27: "", C27: "", D27: "", - A28: "Won", B28: "", C28: "", D28: "", - A29: "TRUE", B29: "-85800", C29: "-42000", D29: "-127800", - A30: "New", B30: "-105600", C30: "-4000", D30: "-109600", - A31: "Won", B31: "19800", C31: "-38000", D31: "-18200", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "", C33: "", D33: "", - A34: "New", B34: "", C34: "", D34: "", - A35: "Won", B35: "", C35: "", D35: "", - A36: "TRUE", B36: "-47700", C36: "26000", D36: "-21700", - A37: "New", B37: "-31000", C37: "24000", D37: "-7000", - A38: "Won", B38: "-16700", C38: "2000", D38: "-14700", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "", C23: "", D23: "", + A24: " Won", B24: "", C24: "", D24: "", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "", C26: "", D26: "", + A27: " New", B27: "", C27: "", D27: "", + A28: " Won", B28: "", C28: "", D28: "", + A29: " TRUE", B29: "-85800", C29: "-42000", D29: "-127800", + A30: " New", B30: "-105600", C30: "-4000", D30: "-109600", + A31: " Won", B31: "19800", C31: "-38000", D31: "-18200", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "", C33: "", D33: "", + A34: " New", B34: "", C34: "", D34: "", + A35: " Won", B35: "", C35: "", D35: "", + A36: " TRUE", B36: "-47700", C36: "26000", D36: "-21700", + A37: " New", B37: "-31000", C37: "24000", D37: "-7000", + A38: " Won", B38: "-16700", C38: "2000", D38: "-14700", + A39: "Total", B39: "", C39: "", D39: "", }); }); }); @@ -880,25 +880,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "#N/A", C23: "#N/A", D23: "#N/A", - A24: "Won", B24: "#N/A", C24: "#N/A", D24: "#N/A", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "433.33%", C26: "381.82%", D26: "414.94%", - A27: "New", B27: "", C27: "36.36%", D27: "996.36%", - A28: "Won", B28: "#NULL!", C28: "", D28: "91.92%", - A29: "TRUE", B29: "", C29: "", D29: "", - A30: "New", B30: "", C30: "", D30: "", - A31: "Won", B31: "", C31: "", D31: "", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "275.72%", C33: "#NULL!", D33: "50.12%", - A34: "New", B34: "344.44%", C34: "#NULL!", D34: "21.21%", - A35: "Won", B35: "201.20%", C35: "#NULL!", D35: "142.72%", - A36: "TRUE", B36: "", C36: "", D36: "", - A37: "New", B37: "", C37: "", D37: "", - A38: "Won", B38: "", C38: "", D38: "", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "#N/A", C23: "#N/A", D23: "#N/A", + A24: " Won", B24: "#N/A", C24: "#N/A", D24: "#N/A", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "433.33%", C26: "381.82%", D26: "414.94%", + A27: " New", B27: "", C27: "36.36%", D27: "996.36%", + A28: " Won", B28: "#NULL!", C28: "", D28: "91.92%", + A29: " TRUE", B29: "", C29: "", D29: "", + A30: " New", B30: "", C30: "", D30: "", + A31: " Won", B31: "", C31: "", D31: "", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "275.72%", C33: "#NULL!", D33: "50.12%", + A34: " New", B34: "344.44%", C34: "#NULL!", D34: "21.21%", + A35: " Won", B35: "201.20%", C35: "#NULL!", D35: "142.72%", + A36: " TRUE", B36: "", C36: "", D36: "", + A37: " New", B37: "", C37: "", D37: "", + A38: " Won", B38: "", C38: "", D38: "", + A39: "Total", B39: "", C39: "", D39: "", }); }); @@ -926,25 +926,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "", C23: "", D23: "", - A24: "Won", B24: "", C24: "", D24: "", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "", C26: "", D26: "", - A27: "New", B27: "", C27: "", D27: "", - A28: "Won", B28: "", C28: "", D28: "", - A29: "TRUE", B29: "-81.25%", C29: "-79.25%", D29: "-80.58%", - A30: "New", B30: "#NULL!", C30: "-26.67%", D30: "-90.88%", - A31: "Won", B31: "", C31: "#NULL!", D31: "-47.89%", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "", C33: "", D33: "", - A34: "New", B34: "", C34: "", D34: "", - A35: "Won", B35: "", C35: "", D35: "", - A36: "TRUE", B36: "-73.38%", C36: "", D36: "-33.38%", - A37: "New", B37: "-77.50%", C37: "", D37: "-17.50%", - A38: "Won", B38: "-66.80%", C38: "", D38: "-58.80%", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "", C23: "", D23: "", + A24: " Won", B24: "", C24: "", D24: "", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "", C26: "", D26: "", + A27: " New", B27: "", C27: "", D27: "", + A28: " Won", B28: "", C28: "", D28: "", + A29: " TRUE", B29: "-81.25%", C29: "-79.25%", D29: "-80.58%", + A30: " New", B30: "#NULL!", C30: "-26.67%", D30: "-90.88%", + A31: " Won", B31: "", C31: "#NULL!", D31: "-47.89%", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "", C33: "", D33: "", + A34: " New", B34: "", C34: "", D34: "", + A35: " Won", B35: "", C35: "", D35: "", + A36: " TRUE", B36: "-73.38%", C36: "", D36: "-33.38%", + A37: " New", B37: "-77.50%", C37: "", D37: "-17.50%", + A38: " Won", B38: "-66.80%", C38: "", D38: "-58.80%", + A39: "Total", B39: "", C39: "", D39: "", }); }); @@ -1014,25 +1014,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "1.390964379", C22: "0", D22: "1", - A23: "FALSE", B23: "1.390964379", C23: "0", D23: "1", - A24: "Won", B24: "1.390964379", C24: "0", D24: "1", - A25: "March", B25: "0.920944737", C25: "1.202205796", D25: "1", - A26: "FALSE", B26: "0.926140217", C26: "1.188916912", D26: "1", - A27: "New", B27: "1.217958859", C27: "0.442509674", D27: "1", - A28: "Won", B28: "0", C28: "3.557777778", D28: "1", - A29: "TRUE", B29: "0.894191386", C29: "1.270634921", D29: "1", - A30: "New", B30: "0", C30: "3.557777778", D30: "1", - A31: "Won", B31: "1.390964379", C31: "0", D31: "1", - A32: "April", B32: "1.057030179", C32: "0.854129476", D32: "1", - A33: "FALSE", B33: "1.390964379", C33: "0", D33: "1", - A34: "New", B34: "1.390964379", C34: "0", D34: "1", - A35: "Won", B35: "1.390964379", C35: "0", D35: "1", - A36: "TRUE", B36: "0.555743274", C36: "2.136309982", D36: "1", - A37: "New", B37: "0.379353921", C37: "2.587474747", D37: "1", - A38: "Won", B38: "1.120874208", C38: "0.690830636", D38: "1", - A39: "Total", B39: "1", C39: "1", D39: "1", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "1.390964379", C22: "0", D22: "1", + A23: " FALSE", B23: "1.390964379", C23: "0", D23: "1", + A24: " Won", B24: "1.390964379", C24: "0", D24: "1", + A25: "March", B25: "0.920944737", C25: "1.202205796", D25: "1", + A26: " FALSE", B26: "0.926140217", C26: "1.188916912", D26: "1", + A27: " New", B27: "1.217958859", C27: "0.442509674", D27: "1", + A28: " Won", B28: "0", C28: "3.557777778", D28: "1", + A29: " TRUE", B29: "0.894191386", C29: "1.270634921", D29: "1", + A30: " New", B30: "0", C30: "3.557777778", D30: "1", + A31: " Won", B31: "1.390964379", C31: "0", D31: "1", + A32: "April", B32: "1.057030179", C32: "0.854129476", D32: "1", + A33: " FALSE", B33: "1.390964379", C33: "0", D33: "1", + A34: " New", B34: "1.390964379", C34: "0", D34: "1", + A35: " Won", B35: "1.390964379", C35: "0", D35: "1", + A36: " TRUE", B36: "0.555743274", C36: "2.136309982", D36: "1", + A37: " New", B37: "0.379353921", C37: "2.587474747", D37: "1", + A38: " Won", B38: "1.120874208", C38: "0.690830636", D38: "1", + A39: "Total", B39: "1", C39: "1", D39: "1", }); }); }); @@ -1071,25 +1071,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "1", C22: "", D22: "1", - A23: "FALSE", B23: "1", C23: "", D23: "1", - A24: "Won", B24: "3", C24: "", D24: "3", - A25: "March", B25: "3", C25: "2", D25: "3", - A26: "FALSE", B26: "3", C26: "1", D26: "3", - A27: "New", B27: "3", C27: "2", D27: "4", - A28: "Won", B28: "", C28: "2", D28: "5", - A29: "TRUE", B29: "2", C29: "1", D29: "1", - A30: "New", B30: "", C30: "1", D30: "1", - A31: "Won", B31: "2", C31: "", D31: "2", - A32: "April", B32: "2", C32: "1", D32: "2", - A33: "FALSE", B33: "2", C33: "", D33: "2", - A34: "New", B34: "2", C34: "", D34: "3", - A35: "Won", B35: "4", C35: "", D35: "4", - A36: "TRUE", B36: "1", C36: "2", D36: "2", - A37: "New", B37: "1", C37: "3", D37: "2", - A38: "Won", B38: "1", C38: "1", D38: "1", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "1", C22: "", D22: "1", + A23: " FALSE", B23: "1", C23: "", D23: "1", + A24: " Won", B24: "3", C24: "", D24: "3", + A25: "March", B25: "3", C25: "2", D25: "3", + A26: " FALSE", B26: "3", C26: "1", D26: "3", + A27: " New", B27: "3", C27: "2", D27: "4", + A28: " Won", B28: "", C28: "2", D28: "5", + A29: " TRUE", B29: "2", C29: "1", D29: "1", + A30: " New", B30: "", C30: "1", D30: "1", + A31: " Won", B31: "2", C31: "", D31: "2", + A32: "April", B32: "2", C32: "1", D32: "2", + A33: " FALSE", B33: "2", C33: "", D33: "2", + A34: " New", B34: "2", C34: "", D34: "3", + A35: " Won", B35: "4", C35: "", D35: "4", + A36: " TRUE", B36: "1", C36: "2", D36: "2", + A37: " New", B37: "1", C37: "3", D37: "2", + A38: " Won", B38: "1", C38: "1", D38: "1", + A39: "Total", B39: "", C39: "", D39: "", }); updatePivotMeasureDisplay(model, pivotId, measureId, { @@ -1098,25 +1098,25 @@ describe("Measure display", () => { }); // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "1", C23: "", D23: "1", - A24: "Won", B24: "1", C24: "", D24: "1", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "2", C26: "2", D26: "2", - A27: "New", B27: "1", C27: "2", D27: "2", - A28: "Won", B28: "", C28: "1", D28: "2", - A29: "TRUE", B29: "1", C29: "1", D29: "1", - A30: "New", B30: "", C30: "1", D30: "1", - A31: "Won", B31: "1", C31: "", D31: "1", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "2", C33: "", D33: "2", - A34: "New", B34: "2", C34: "", D34: "2", - A35: "Won", B35: "2", C35: "", D35: "2", - A36: "TRUE", B36: "1", C36: "1", D36: "1", - A37: "New", B37: "1", C37: "1", D37: "1", - A38: "Won", B38: "1", C38: "1", D38: "1", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "1", C23: "", D23: "1", + A24: " Won", B24: "1", C24: "", D24: "1", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "2", C26: "2", D26: "2", + A27: " New", B27: "1", C27: "2", D27: "2", + A28: " Won", B28: "", C28: "1", D28: "2", + A29: " TRUE", B29: "1", C29: "1", D29: "1", + A30: " New", B30: "", C30: "1", D30: "1", + A31: " Won", B31: "1", C31: "", D31: "1", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "2", C33: "", D33: "2", + A34: " New", B34: "2", C34: "", D34: "2", + A35: " Won", B35: "2", C35: "", D35: "2", + A36: " TRUE", B36: "1", C36: "1", D36: "1", + A37: " New", B37: "1", C37: "1", D37: "1", + A38: " Won", B38: "1", C38: "1", D38: "1", + A39: "Total", B39: "", C39: "", D39: "", }); updatePivotMeasureDisplay(model, pivotId, measureId, { @@ -1125,25 +1125,25 @@ describe("Measure display", () => { }); // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "", C23: "", D23: "", - A24: "Won", B24: "1", C24: "", D24: "1", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "", C26: "", D26: "", - A27: "New", B27: "1", C27: "1", D27: "2", - A28: "Won", B28: "", C28: "2", D28: "1", - A29: "TRUE", B29: "", C29: "", D29: "", - A30: "New", B30: "", C30: "1", D30: "1", - A31: "Won", B31: "1", C31: "", D31: "2", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "", C33: "", D33: "", - A34: "New", B34: "2", C34: "", D34: "2", - A35: "Won", B35: "1", C35: "", D35: "1", - A36: "TRUE", B36: "", C36: "", D36: "", - A37: "New", B37: "2", C37: "2", D37: "2", - A38: "Won", B38: "1", C38: "1", D38: "1", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "", C23: "", D23: "", + A24: " Won", B24: "1", C24: "", D24: "1", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "", C26: "", D26: "", + A27: " New", B27: "1", C27: "1", D27: "2", + A28: " Won", B28: "", C28: "2", D28: "1", + A29: " TRUE", B29: "", C29: "", D29: "", + A30: " New", B30: "", C30: "1", D30: "1", + A31: " Won", B31: "1", C31: "", D31: "2", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "", C33: "", D33: "", + A34: " New", B34: "2", C34: "", D34: "2", + A35: " Won", B35: "1", C35: "", D35: "1", + A36: " TRUE", B36: "", C36: "", D36: "", + A37: " New", B37: "2", C37: "2", D37: "2", + A38: " Won", B38: "1", C38: "1", D38: "1", + A39: "Total", B39: "", C39: "", D39: "", }); }); @@ -1199,25 +1199,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "1", C23: "", D23: "1", - A24: "Won", B24: "1", C24: "", D24: "1", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "1", C26: "1", D26: "1", - A27: "New", B27: "1", C27: "1", D27: "1", - A28: "Won", B28: "", C28: "1", D28: "1", - A29: "TRUE", B29: "2", C29: "2", D29: "2", - A30: "New", B30: "", C30: "2", D30: "2", - A31: "Won", B31: "1", C31: "", D31: "2", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "1", C33: "", D33: "1", - A34: "New", B34: "1", C34: "", D34: "1", - A35: "Won", B35: "1", C35: "", D35: "1", - A36: "TRUE", B36: "2", C36: "1", D36: "2", - A37: "New", B37: "2", C37: "1", D37: "2", - A38: "Won", B38: "2", C38: "1", D38: "2", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "1", C23: "", D23: "1", + A24: " Won", B24: "1", C24: "", D24: "1", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "1", C26: "1", D26: "1", + A27: " New", B27: "1", C27: "1", D27: "1", + A28: " Won", B28: "", C28: "1", D28: "1", + A29: " TRUE", B29: "2", C29: "2", D29: "2", + A30: " New", B30: "", C30: "2", D30: "2", + A31: " Won", B31: "1", C31: "", D31: "2", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "1", C33: "", D33: "1", + A34: " New", B34: "1", C34: "", D34: "1", + A35: " Won", B35: "1", C35: "", D35: "1", + A36: " TRUE", B36: "2", C36: "1", D36: "2", + A37: " New", B37: "2", C37: "1", D37: "2", + A38: " Won", B38: "2", C38: "1", D38: "2", + A39: "Total", B39: "", C39: "", D39: "", }); }); @@ -1273,25 +1273,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "22500", C22: "0", D22: "22500", - A23: "FALSE", B23: "22500", C23: "0", D23: "22500", - A24: "Won", B24: "22500", C24: "0", D24: "22500", - A25: "March", B25: "147900", C25: "64000", D25: "211900", - A26: "FALSE", B26: "128100", C26: "53000", D26: "181100", - A27: "New", B27: "105600", C27: "15000", D27: "120600", - A28: "Won", B28: "22500", C28: "38000", D28: "60500", - A29: "TRUE", B29: "19800", C29: "11000", D29: "30800", - A30: "New", B30: "0", C30: "11000", D30: "11000", - A31: "Won", B31: "19800", C31: "0", D31: "19800", - A32: "April", B32: "230200", C32: "90000", D32: "320200", - A33: "FALSE", B33: "193100", C33: "53000", D33: "246100", - A34: "New", B34: "145600", C34: "15000", D34: "160600", - A35: "Won", B35: "47500", C35: "38000", D35: "85500", - A36: "TRUE", B36: "37100", C36: "37000", D36: "74100", - A37: "New", B37: "9000", C37: "35000", D37: "44000", - A38: "Won", B38: "28100", C38: "2000", D38: "30100", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "22500", C22: "0", D22: "22500", + A23: " FALSE", B23: "22500", C23: "0", D23: "22500", + A24: " Won", B24: "22500", C24: "0", D24: "22500", + A25: "March", B25: "147900", C25: "64000", D25: "211900", + A26: " FALSE", B26: "128100", C26: "53000", D26: "181100", + A27: " New", B27: "105600", C27: "15000", D27: "120600", + A28: " Won", B28: "22500", C28: "38000", D28: "60500", + A29: " TRUE", B29: "19800", C29: "11000", D29: "30800", + A30: " New", B30: "0", C30: "11000", D30: "11000", + A31: " Won", B31: "19800", C31: "0", D31: "19800", + A32: "April", B32: "230200", C32: "90000", D32: "320200", + A33: " FALSE", B33: "193100", C33: "53000", D33: "246100", + A34: " New", B34: "145600", C34: "15000", D34: "160600", + A35: " Won", B35: "47500", C35: "38000", D35: "85500", + A36: " TRUE", B36: "37100", C36: "37000", D36: "74100", + A37: " New", B37: "9000", C37: "35000", D37: "44000", + A38: " Won", B38: "28100", C38: "2000", D38: "30100", + A39: "Total", B39: "", C39: "", D39: "", }); updatePivotMeasureDisplay(model, pivotId, measureId, { @@ -1301,25 +1301,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "22500", C23: "0", D23: "22500", - A24: "Won", B24: "22500", C24: "0", D24: "22500", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "105600", C26: "53000", D26: "158600", - A27: "New", B27: "105600", C27: "15000", D27: "120600", - A28: "Won", B28: "0", C28: "38000", D28: "38000", - A29: "TRUE", B29: "125400", C29: "64000", D29: "189400", - A30: "New", B30: "105600", C30: "26000", D30: "131600", - A31: "Won", B31: "19800", C31: "38000", D31: "57800", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "65000", C33: "0", D33: "65000", - A34: "New", B34: "40000", C34: "0", D34: "40000", - A35: "Won", B35: "25000", C35: "0", D35: "25000", - A36: "TRUE", B36: "82300", C36: "26000", D36: "108300", - A37: "New", B37: "49000", C37: "24000", D37: "73000", - A38: "Won", B38: "33300", C38: "2000", D38: "35300", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "22500", C23: "0", D23: "22500", + A24: " Won", B24: "22500", C24: "0", D24: "22500", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "105600", C26: "53000", D26: "158600", + A27: " New", B27: "105600", C27: "15000", D27: "120600", + A28: " Won", B28: "0", C28: "38000", D28: "38000", + A29: " TRUE", B29: "125400", C29: "64000", D29: "189400", + A30: " New", B30: "105600", C30: "26000", D30: "131600", + A31: " Won", B31: "19800", C31: "38000", D31: "57800", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "65000", C33: "0", D33: "65000", + A34: " New", B34: "40000", C34: "0", D34: "40000", + A35: " Won", B35: "25000", C35: "0", D35: "25000", + A36: " TRUE", B36: "82300", C36: "26000", D36: "108300", + A37: " New", B37: "49000", C37: "24000", D37: "73000", + A38: " Won", B38: "33300", C38: "2000", D38: "35300", + A39: "Total", B39: "", C39: "", D39: "", }); updatePivotMeasureDisplay(model, pivotId, measureId, { @@ -1329,25 +1329,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "", C23: "", D23: "", - A24: "Won", B24: "22500", C24: "0", D24: "22500", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "", C26: "", D26: "", - A27: "New", B27: "105600", C27: "15000", D27: "120600", - A28: "Won", B28: "105600", C28: "53000", D28: "158600", - A29: "TRUE", B29: "", C29: "", D29: "", - A30: "New", B30: "0", C30: "11000", D30: "11000", - A31: "Won", B31: "19800", C31: "11000", D31: "30800", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "", C33: "", D33: "", - A34: "New", B34: "40000", C34: "0", D34: "40000", - A35: "Won", B35: "65000", C35: "0", D35: "65000", - A36: "TRUE", B36: "", C36: "", D36: "", - A37: "New", B37: "9000", C37: "24000", D37: "33000", - A38: "Won", B38: "17300", C38: "26000", D38: "43300", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "", C23: "", D23: "", + A24: " Won", B24: "22500", C24: "0", D24: "22500", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "", C26: "", D26: "", + A27: " New", B27: "105600", C27: "15000", D27: "120600", + A28: " Won", B28: "105600", C28: "53000", D28: "158600", + A29: " TRUE", B29: "", C29: "", D29: "", + A30: " New", B30: "0", C30: "11000", D30: "11000", + A31: " Won", B31: "19800", C31: "11000", D31: "30800", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "", C33: "", D33: "", + A34: " New", B34: "40000", C34: "0", D34: "40000", + A35: " Won", B35: "65000", C35: "0", D35: "65000", + A36: " TRUE", B36: "", C36: "", D36: "", + A37: " New", B37: "9000", C37: "24000", D37: "33000", + A38: " Won", B38: "17300", C38: "26000", D38: "43300", + A39: "Total", B39: "", C39: "", D39: "", }); }); @@ -1423,25 +1423,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "9.77%", C22: "0.00%", D22: "7.03%", - A23: "FALSE", B23: "11.65%", C23: "0.00%", D23: "9.14%", - A24: "Won", B24: "47.37%", C24: "0.00%", D24: "26.32%", - A25: "March", B25: "64.25%", C25: "71.11%", D25: "66.18%", - A26: "FALSE", B26: "66.34%", C26: "100.00%", D26: "73.59%", - A27: "New", B27: "72.53%", C27: "100.00%", D27: "75.09%", - A28: "Won", B28: "47.37%", C28: "100.00%", D28: "70.76%", - A29: "TRUE", B29: "53.37%", C29: "29.73%", D29: "41.57%", - A30: "New", B30: "0.00%", C30: "31.43%", D30: "25.00%", - A31: "Won", B31: "70.46%", C31: "0.00%", D31: "65.78%", - A32: "April", B32: "100.00%", C32: "100.00%", D32: "100.00%", - A33: "FALSE", B33: "100.00%", C33: "100.00%", D33: "100.00%", - A34: "New", B34: "100.00%", C34: "100.00%", D34: "100.00%", - A35: "Won", B35: "100.00%", C35: "100.00%", D35: "100.00%", - A36: "TRUE", B36: "100.00%", C36: "100.00%", D36: "100.00%", - A37: "New", B37: "100.00%", C37: "100.00%", D37: "100.00%", - A38: "Won", B38: "100.00%", C38: "100.00%", D38: "100.00%", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "9.77%", C22: "0.00%", D22: "7.03%", + A23: " FALSE", B23: "11.65%", C23: "0.00%", D23: "9.14%", + A24: " Won", B24: "47.37%", C24: "0.00%", D24: "26.32%", + A25: "March", B25: "64.25%", C25: "71.11%", D25: "66.18%", + A26: " FALSE", B26: "66.34%", C26: "100.00%", D26: "73.59%", + A27: " New", B27: "72.53%", C27: "100.00%", D27: "75.09%", + A28: " Won", B28: "47.37%", C28: "100.00%", D28: "70.76%", + A29: " TRUE", B29: "53.37%", C29: "29.73%", D29: "41.57%", + A30: " New", B30: "0.00%", C30: "31.43%", D30: "25.00%", + A31: " Won", B31: "70.46%", C31: "0.00%", D31: "65.78%", + A32: "April", B32: "100.00%", C32: "100.00%", D32: "100.00%", + A33: " FALSE", B33: "100.00%", C33: "100.00%", D33: "100.00%", + A34: " New", B34: "100.00%", C34: "100.00%", D34: "100.00%", + A35: " Won", B35: "100.00%", C35: "100.00%", D35: "100.00%", + A36: " TRUE", B36: "100.00%", C36: "100.00%", D36: "100.00%", + A37: " New", B37: "100.00%", C37: "100.00%", D37: "100.00%", + A38: " Won", B38: "100.00%", C38: "100.00%", D38: "100.00%", + A39: "Total", B39: "", C39: "", D39: "", }); updatePivotMeasureDisplay(model, pivotId, measureId, { @@ -1451,25 +1451,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "100.00%", C23: "", D23: "100.00%", - A24: "Won", B24: "100.00%", C24: "", D24: "100.00%", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "84.21%", C26: "82.81%", D26: "83.74%", - A27: "New", B27: "100.00%", C27: "57.69%", D27: "91.64%", - A28: "Won", B28: "0.00%", C28: "100.00%", D28: "65.74%", - A29: "TRUE", B29: "100.00%", C29: "100.00%", D29: "100.00%", - A30: "New", B30: "100.00%", C30: "100.00%", D30: "100.00%", - A31: "Won", B31: "100.00%", C31: "100.00%", D31: "100.00%", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "78.98%", C33: "0.00%", D33: "60.02%", - A34: "New", B34: "81.63%", C34: "0.00%", D34: "54.79%", - A35: "Won", B35: "75.08%", C35: "0.00%", D35: "70.82%", - A36: "TRUE", B36: "100.00%", C36: "100.00%", D36: "100.00%", - A37: "New", B37: "100.00%", C37: "100.00%", D37: "100.00%", - A38: "Won", B38: "100.00%", C38: "100.00%", D38: "100.00%", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "100.00%", C23: "", D23: "100.00%", + A24: " Won", B24: "100.00%", C24: "", D24: "100.00%", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "84.21%", C26: "82.81%", D26: "83.74%", + A27: " New", B27: "100.00%", C27: "57.69%", D27: "91.64%", + A28: " Won", B28: "0.00%", C28: "100.00%", D28: "65.74%", + A29: " TRUE", B29: "100.00%", C29: "100.00%", D29: "100.00%", + A30: " New", B30: "100.00%", C30: "100.00%", D30: "100.00%", + A31: " Won", B31: "100.00%", C31: "100.00%", D31: "100.00%", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "78.98%", C33: "0.00%", D33: "60.02%", + A34: " New", B34: "81.63%", C34: "0.00%", D34: "54.79%", + A35: " Won", B35: "75.08%", C35: "0.00%", D35: "70.82%", + A36: " TRUE", B36: "100.00%", C36: "100.00%", D36: "100.00%", + A37: " New", B37: "100.00%", C37: "100.00%", D37: "100.00%", + A38: " Won", B38: "100.00%", C38: "100.00%", D38: "100.00%", + A39: "Total", B39: "", C39: "", D39: "", }); updatePivotMeasureDisplay(model, pivotId, measureId, { @@ -1479,25 +1479,25 @@ describe("Measure display", () => { // prettier-ignore expect(getFormattedGrid(model)).toMatchObject({ - A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", - A22: "February", B22: "", C22: "", D22: "", - A23: "FALSE", B23: "", C23: "", D23: "", - A24: "Won", B24: "100.00%", C24: "", D24: "100.00%", - A25: "March", B25: "", C25: "", D25: "", - A26: "FALSE", B26: "", C26: "", D26: "", - A27: "New", B27: "100.00%", C27: "28.30%", D27: "76.04%", - A28: "Won", B28: "100.00%", C28: "100.00%", D28: "100.00%", - A29: "TRUE", B29: "", C29: "", D29: "", - A30: "New", B30: "0.00%", C30: "100.00%", D30: "35.71%", - A31: "Won", B31: "100.00%", C31: "100.00%", D31: "100.00%", - A32: "April", B32: "", C32: "", D32: "", - A33: "FALSE", B33: "", C33: "", D33: "", - A34: "New", B34: "61.54%", C34: "", D34: "61.54%", - A35: "Won", B35: "100.00%", C35: "", D35: "100.00%", - A36: "TRUE", B36: "", C36: "", D36: "", - A37: "New", B37: "52.02%", C37: "92.31%", D37: "76.21%", - A38: "Won", B38: "100.00%", C38: "100.00%", D38: "100.00%", - A39: "Total", B39: "", C39: "", D39: "", + A20:"(#1) Pivot", B20: "Alice", C20: "Bob", D20: "Total", + A22: "February", B22: "", C22: "", D22: "", + A23: " FALSE", B23: "", C23: "", D23: "", + A24: " Won", B24: "100.00%", C24: "", D24: "100.00%", + A25: "March", B25: "", C25: "", D25: "", + A26: " FALSE", B26: "", C26: "", D26: "", + A27: " New", B27: "100.00%", C27: "28.30%", D27: "76.04%", + A28: " Won", B28: "100.00%", C28: "100.00%", D28: "100.00%", + A29: " TRUE", B29: "", C29: "", D29: "", + A30: " New", B30: "0.00%", C30: "100.00%", D30: "35.71%", + A31: " Won", B31: "100.00%", C31: "100.00%", D31: "100.00%", + A32: "April", B32: "", C32: "", D32: "", + A33: " FALSE", B33: "", C33: "", D33: "", + A34: " New", B34: "61.54%", C34: "", D34: "61.54%", + A35: " Won", B35: "100.00%", C35: "", D35: "100.00%", + A36: " TRUE", B36: "", C36: "", D36: "", + A37: " New", B37: "52.02%", C37: "92.31%", D37: "76.21%", + A38: " Won", B38: "100.00%", C38: "100.00%", D38: "100.00%", + A39: "Total", B39: "", C39: "", D39: "", }); }); diff --git a/tests/pivots/spreadsheet_pivot/spreadsheet_pivot.test.ts b/tests/pivots/spreadsheet_pivot/spreadsheet_pivot.test.ts index e71b84d7d4..e71c0fa3bf 100644 --- a/tests/pivots/spreadsheet_pivot/spreadsheet_pivot.test.ts +++ b/tests/pivots/spreadsheet_pivot/spreadsheet_pivot.test.ts @@ -14,6 +14,7 @@ import { getCellContent, getCellError, getEvaluatedCell, + getEvaluatedCells, getEvaluatedGrid, } from "../../test_helpers/getters_helpers"; import { createModelFromGrid } from "../../test_helpers/helpers"; @@ -282,12 +283,12 @@ describe("Spreadsheet Pivot", () => { expect(getEvaluatedGrid(model, "A28:A36")).toEqual([ ["Alice"], - ["TRUE"], + [" TRUE"], ["Michel"], - ["TRUE"], + [" TRUE"], ["(Undefined)"], - ["FALSE"], - ["TRUE"], + [" FALSE"], + [" TRUE"], ["Total"], [""], ]); @@ -695,6 +696,39 @@ describe("Spreadsheet Pivot", () => { ]); }); + test("PIVOT row headers are indented relative to the groupBy depth.", () => { + // prettier-ignore + const grid = { + A1: "Date", B1: "Price", C1: "=PIVOT(1)", + A2: "2024-12-28", B2: "10", + A3: "2024-11-28", B3: "20", + A4: "1995-04-14", B4: "30", + }; + const model = createModelFromGrid(grid); + addPivot(model, "A1:B4", { + rows: [ + { fieldName: "Date", granularity: "year" }, + { fieldName: "Date", granularity: "quarter_number" }, + { fieldName: "Date", granularity: "day" }, + ], + columns: [], + measures: [{ id: "Price:sum", fieldName: "Price", aggregator: "sum" }], + }); + + expect(getEvaluatedCells(model, "C1:C10").flat()).toMatchObject([ + { value: "(#1) Pivot", format: undefined }, + { value: "", format: undefined }, + { value: 1995, format: "0* " }, + { value: "Q2", format: " @* " }, + { value: 34803, format: " m/d/yyyy* " }, + { value: 2024, format: "0* " }, + { value: "Q4", format: " @* " }, + { value: 45624, format: " m/d/yyyy* " }, + { value: 45654, format: " m/d/yyyy* " }, + { value: "Total", format: undefined }, + ]); + }); + test("PIVOT.HEADER grand total", () => { const model = createModelWithPivot("A1:I5"); updatePivot(model, "1", { @@ -1131,7 +1165,7 @@ describe("Spreadsheet Pivot", () => { }); setCellContent(model, "A27", '=PIVOT.HEADER(1, "Date:quarter_number", 4)'); expect(getEvaluatedCell(model, "A27").value).toBe("Q4"); - expect(getEvaluatedCell(model, "A27").format).toBe("0"); + expect(getEvaluatedCell(model, "A27").format).toBe("@"); // quarter as string setCellContent(model, "A28", '=PIVOT.HEADER(1, "Date:quarter_number", "4")'); diff --git a/tests/test_helpers/getters_helpers.ts b/tests/test_helpers/getters_helpers.ts index 42172adf1c..802210f2b3 100644 --- a/tests/test_helpers/getters_helpers.ts +++ b/tests/test_helpers/getters_helpers.ts @@ -95,6 +95,23 @@ export function getEvaluatedGrid( return content; } +export function getEvaluatedCells( + model: Model, + range: string, + sheetId: UID = model.getters.getActiveSheetId() +): EvaluatedCell[][] { + const zone = toZone(range); + const content: EvaluatedCell[][] = []; + for (let row = zone.top; row <= zone.bottom; row++) { + const rowContent: EvaluatedCell[] = []; + for (let col = zone.left; col <= zone.right; col++) { + rowContent.push(model.getters.getEvaluatedCell({ sheetId, col, row })); + } + content.push(rowContent); + } + return content; +} + /** * Get the string representation of the content of a cell, and always formula * for formula cells