Skip to content
Draft
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
26 changes: 15 additions & 11 deletions web-common/src/features/dashboards/pivot/pivot-data-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import {
getTimeGrainFromDimension,
getTotalColumnCount,
isTimeDimension,
sortNumericDimensionAxes,
splitPivotChips,
} from "./pivot-utils";
import {
Expand Down Expand Up @@ -271,6 +272,9 @@ export function createPivotDataStore(
if (columnDimensionAxes?.error && columnDimensionAxes?.error.length) {
return columnSet(getErrorState(columnDimensionAxes.error));
}
const columnDimensionAxesData = sortNumericDimensionAxes(
columnDimensionAxes?.data,
);
const anchorDimension = rowDimensionNames[0];

const rowPage = config.pivot.rowPage;
Expand All @@ -293,7 +297,7 @@ export function createPivotDataStore(
} = getSortForAccessor(
anchorDimension,
config,
columnDimensionAxes?.data,
columnDimensionAxesData,
);

const { sortFilteredMeasureBody, isMeasureSortAccessor, sortAccessor } =
Expand Down Expand Up @@ -369,7 +373,7 @@ export function createPivotDataStore(
totalsRowQuery = getTotalsRowQuery(
ctx,
config,
columnDimensionAxes?.data,
columnDimensionAxesData,
);
}

Expand All @@ -390,7 +394,7 @@ export function createPivotDataStore(
) {
const skeletonTotalsRowData = getTotalsRowSkeleton(
config,
columnDimensionAxes?.data,
columnDimensionAxesData,
);
return axesSet({
isFetching: true,
Expand Down Expand Up @@ -437,7 +441,7 @@ export function createPivotDataStore(

const totalsRowData = getTotalsRow(
config,
columnDimensionAxes?.data,
columnDimensionAxesData,
totalsRowResponse?.data?.data,
globalTotalsResponse?.data?.data,
);
Expand Down Expand Up @@ -495,7 +499,7 @@ export function createPivotDataStore(
) {
const slicedAxesDataForDef = sliceColumnAxesDataForDef(
config,
columnDimensionAxes?.data,
columnDimensionAxesData,
totalsRowData,
);

Expand All @@ -508,7 +512,7 @@ export function createPivotDataStore(
tableCellQuery = createTableCellQuery(
ctx,
config,
columnDimensionAxes?.data,
columnDimensionAxesData,
totalsRowData,
rowDimensionValues,
isFlat ? NUM_ROWS_PER_PAGE.toString() : "5000",
Expand All @@ -517,7 +521,7 @@ export function createPivotDataStore(
} else {
columnDef = getColumnDefForPivot(
config,
columnDimensionAxes?.data,
columnDimensionAxesData,
totalsRowData,
);
}
Expand Down Expand Up @@ -602,7 +606,7 @@ export function createPivotDataStore(
config,
anchorDimension,
rowDimensionValues || [],
columnDimensionAxes?.data || {},
columnDimensionAxesData,
pivotSkeleton as PivotDataRow[],
cellData,
);
Expand All @@ -614,7 +618,7 @@ export function createPivotDataStore(
ctx,
config,
pivotData,
columnDimensionAxes?.data,
columnDimensionAxesData,
totalsRowData,
);

Expand All @@ -636,7 +640,7 @@ export function createPivotDataStore(
config,
pivotData,
rowDimensionNames,
columnDimensionAxes?.data || {},
columnDimensionAxesData,
expandedRowMeasureValues,
);

Expand Down Expand Up @@ -668,7 +672,7 @@ export function createPivotDataStore(
config,
activeCell.rowId,
activeCell.columnId,
columnDimensionAxes?.data,
columnDimensionAxesData,
tableDataExpanded,
);
}
Expand Down
43 changes: 43 additions & 0 deletions web-common/src/features/dashboards/pivot/pivot-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,49 @@ export function createIndexMap<T>(arr: T[]): Map<T, number> {
return indexMap;
}

function isNumericAxisValue(value: unknown): boolean {
if (value === null || value === undefined) return false;
if (typeof value === "string" && value.trim() === "") return false;

const numericValue = Number(value);
return Number.isFinite(numericValue);
}

/**
* Sort axis values when all non-null values are numeric-like.
* This keeps dimensions such as month offsets in natural numeric order.
*/
export function sortNumericDimensionAxisValues<T>(values: T[]): T[] {
const definedValues = values.filter(
(value): value is T => value !== null && value !== undefined,
);

if (!definedValues.length) return values;
if (!definedValues.every((value) => isNumericAxisValue(value))) return values;

return [...values].sort((a, b) => {
const aIsNumeric = isNumericAxisValue(a);
const bIsNumeric = isNumericAxisValue(b);

if (!aIsNumeric && !bIsNumeric) return 0;
if (!aIsNumeric) return 1;
if (!bIsNumeric) return -1;

return Number(a) - Number(b);
});
}

export function sortNumericDimensionAxes(
axes: Record<string, string[]> = {},
): Record<string, string[]> {
return Object.fromEntries(
Object.entries(axes).map(([dimension, values]) => [
dimension,
sortNumericDimensionAxisValues(values),
]),
);
}

/**
* Returns total number of columns for the table
* excluding row and group totals columns
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { sortAcessors } from "@rilldata/web-common/features/dashboards/pivot/pivot-utils";
import {
sortAcessors,
sortNumericDimensionAxisValues,
} from "@rilldata/web-common/features/dashboards/pivot/pivot-utils";
import { describe, expect, it } from "vitest";

describe("sortAcessors function", () => {
Expand Down Expand Up @@ -26,3 +29,22 @@ describe("sortAcessors function", () => {
expect(sortAcessors(input)).toEqual(expected);
});
});

describe("sortNumericDimensionAxisValues", () => {
it("sorts numeric dimension values in ascending order", () => {
const input = ["5", "6", "0", "2"];
const expected = ["0", "2", "5", "6"];
expect(sortNumericDimensionAxisValues(input)).toEqual(expected);
});

it("sorts signed and decimal numeric values", () => {
const input = ["3.5", "-1", "0", "2"];
const expected = ["-1", "0", "2", "3.5"];
expect(sortNumericDimensionAxisValues(input)).toEqual(expected);
});

it("does not reorder non-numeric dimensions", () => {
const input = ["north", "south", "east"];
expect(sortNumericDimensionAxisValues(input)).toEqual(input);
});
});
Loading