Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/functions/helper_lookup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { isZoneInside, positionToZone, zoneToXc } from "../helpers";
import { _t } from "../translation";
import { EvalContext, FunctionResultObject, Getters, Maybe, Range, UID } from "../types";
import { CircularDependencyError, EvaluationError, InvalidReferenceError } from "../types/errors";
import { PivotCoreDefinition, PivotCoreMeasure } from "../types/pivot";
import { PivotCoreMeasure } from "../types/pivot";

/**
* Get the pivot ID from the formula pivot ID.
Expand Down Expand Up @@ -37,11 +37,12 @@ export function assertDomainLength(domain: Maybe<FunctionResultObject>[]) {

export function addPivotDependencies(
evalContext: EvalContext,
coreDefinition: PivotCoreDefinition,
pivotId: UID,
forMeasures: PivotCoreMeasure[]
) {
//TODO This function can be very costly when used with PIVOT.VALUE and PIVOT.HEADER
const dependencies: Range[] = [];
const coreDefinition = evalContext.getters.getPivotCoreDefinition(pivotId);

if (coreDefinition.type === "SPREADSHEET" && coreDefinition.dataSet) {
const { sheetId, zone } = coreDefinition.dataSet;
Expand All @@ -62,8 +63,7 @@ export function addPivotDependencies(

for (const measure of forMeasures) {
if (measure.computedBy) {
const formula = evalContext.getters.getMeasureCompiledFormula(measure);
dependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
dependencies.push(...evalContext.getters.getMeasureFullDependencies(pivotId, measure));
}
}
const originPosition = evalContext.__originCellPosition;
Expand Down
7 changes: 3 additions & 4 deletions src/functions/module_lookup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ export const PIVOT_VALUE = {

addPivotDependencies(
this,
coreDefinition,
pivotId,
coreDefinition.measures.filter((m) => m.id === _measure)
);
pivot.init({ reload: pivot.needsReevaluation });
Expand Down Expand Up @@ -824,8 +824,7 @@ export const PIVOT_HEADER = {
const _pivotId = getPivotId(_pivotFormulaId, this.getters);
assertDomainLength(domainArgs);
const pivot = this.getters.getPivot(_pivotId);
const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
addPivotDependencies(this, coreDefinition, []);
addPivotDependencies(this, _pivotId, []);
pivot.init({ reload: pivot.needsReevaluation });
const error = pivot.assertIsValid({ throwOnError: false });
if (error) {
Expand Down Expand Up @@ -894,7 +893,7 @@ export const PIVOT = {
const pivotId = getPivotId(_pivotFormulaId, this.getters);
const pivot = this.getters.getPivot(pivotId);
const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
addPivotDependencies(this, coreDefinition, coreDefinition.measures);
addPivotDependencies(this, pivotId, coreDefinition.measures);
pivot.init({ reload: pivot.needsReevaluation });
const error = pivot.assertIsValid({ throwOnError: false });
if (error) {
Expand Down
7 changes: 5 additions & 2 deletions src/helpers/pivot/pivot_presentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
isMatrix,
} from "../../types";
import { CellErrorType, NotAvailableError } from "../../types/errors";
import { UID } from "../../types/misc";
import { deepEquals, removeDuplicates, transpose2dPOJO } from "../misc";
import {
NEXT_VALUE,
Expand Down Expand Up @@ -50,6 +51,7 @@ type DomainGroups<T> = { [colDomain: string]: { [rowDomain: string]: T } };
export default function (PivotClass: PivotUIConstructor) {
class PivotPresentationLayer extends PivotClass {
private getters: Getters;
private pivotId: UID;
private cache: Record<string, FunctionResultObject> = {};
private rankAsc: CacheForMeasureAndField<DomainGroups<number> | undefined> = {};
private rankDesc: CacheForMeasureAndField<DomainGroups<number> | undefined> = {};
Expand All @@ -60,9 +62,10 @@ export default function (PivotClass: PivotUIConstructor) {
DomainGroups<number | undefined> | undefined
> = {};

constructor(custom: ModelConfig["custom"], params: PivotParams) {
constructor(pivotId, custom: ModelConfig["custom"], params: PivotParams) {
super(custom, params);
this.getters = params.getters;
this.pivotId = pivotId;
}

markAsDirtyForEvaluation(): void {
Expand Down Expand Up @@ -117,7 +120,7 @@ export default function (PivotClass: PivotUIConstructor) {
return handleError(error, measure.aggregator.toUpperCase());
}
}
const formula = this.getters.getMeasureCompiledFormula(measure);
const formula = this.getters.getMeasureCompiledFormula(this.pivotId, measure);
const getSymbolValue = (symbolName: string) => {
const { columns, rows } = this.definition;
if (columns.find((col) => col.nameWithGranularity === symbolName)) {
Expand Down
43 changes: 42 additions & 1 deletion src/helpers/pivot/pivot_registry.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ModelConfig } from "../../model";
import { Registry } from "../../registries/registry";
import { CoreGetters, Getters } from "../../types";
import { ApplyRangeChange, CoreGetters, Getters, Range } from "../../types";
import { PivotCoreDefinition, PivotField, PivotFields } from "../../types/pivot";
import { Pivot } from "../../types/pivot_runtime";
import { PivotRuntimeDefinition } from "./pivot_runtime_definition";
Expand Down Expand Up @@ -32,6 +32,11 @@ export interface PivotRegistryItem {
datetimeGranularities: string[];
isMeasureCandidate: (field: PivotField) => boolean;
isGroupable: (field: PivotField) => boolean;
adaptRanges?: (
getters: CoreGetters,
definition: PivotCoreDefinition,
applyChange: ApplyRangeChange
) => PivotCoreDefinition;
}

export const pivotRegistry = new Registry<PivotRegistryItem>();
Expand All @@ -54,4 +59,40 @@ pivotRegistry.add("SPREADSHEET", {
datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
isMeasureCandidate: (field: PivotField) => !["datetime", "boolean"].includes(field.type),
isGroupable: () => true,
adaptRanges: (getters, definition, applyChange) => {
if (definition.type !== "SPREADSHEET" || !definition.dataSet) {
return definition;
}
const { sheetId, zone } = definition.dataSet;
const range = getters.getRangeFromZone(sheetId, zone);
const adaptedRange = adaptPivotRange(range, applyChange);

if (adaptedRange === range) {
return definition;
}

const dataSet = adaptedRange && {
sheetId: adaptedRange.sheetId,
zone: adaptedRange.zone,
};
return { ...definition, dataSet };
},
});

function adaptPivotRange(
range: Range | undefined,
applyChange: ApplyRangeChange
): Range | undefined {
if (!range) {
return undefined;
}
const change = applyChange(range);
switch (change.changeType) {
case "NONE":
return range;
case "REMOVE":
return undefined;
default:
return change.range;
}
}
Loading