Skip to content

Commit

Permalink
Sort dim table by dim value (#3173)
Browse files Browse the repository at this point in the history
* switching dimension table to use sorted query API

* wip changes to show Speros

* type to search fixed

* cleanups

* add sort by context actions

* remove unused functions

* cleanup

* fixing arrows on dim table headers

* lint cleanups

* fix interminable bug

* cleanups

* lint fix

* set context col when changing context col sort in dimension table, other cleanups

* starting to put column click actions in place, need sort query

* moving actions and selectors to state-managers

* add comments

* fix highlighting and context columns when sorting by dimension values

* remove some layers of prop drilling and dispatch bubbling

* fix import

* fix import

* adding nice types to factories for selectors and actions

* clean ups on actions and selectors

* cleanup

* simplify args to prepareVirtualizedDimTableColumns

* changing line to block comments for better intellisense hints

* cleanup

* fix accidentally commited go files

* fix accidentally committed go file take 2

* cleanup

* split types out to separate files

* improve arrow alignment
  • Loading branch information
bcolloran authored Oct 17, 2023
1 parent dab97a0 commit 9a0411d
Show file tree
Hide file tree
Showing 18 changed files with 559 additions and 127 deletions.
25 changes: 19 additions & 6 deletions web-common/src/features/dashboards/dashboard-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type {
} from "@rilldata/web-common/runtime-client";
import type { TimeControlState } from "./time-controls/time-control-store";
import { getQuerySortType } from "./leaderboard/leaderboard-utils";
import type { DashboardState_LeaderboardSortType } from "@rilldata/web-common/proto/gen/rill/ui/v1/dashboard_pb";
import { SortType } from "./proto-state/derived-types";

export function isSummableMeasure(measure: MetricsViewSpecMeasureV2): boolean {
return (
Expand All @@ -31,10 +31,26 @@ export function prepareSortedQueryBody(
measureNames: string[],
timeControls: TimeControlState,
sortMeasureName: string,
sortType: DashboardState_LeaderboardSortType,
sortType: SortType,
sortAscending: boolean,
filterForDimension: V1MetricsViewFilter
): QueryServiceMetricsViewComparisonToplistBody {
let comparisonTimeRange = {
start: timeControls.comparisonTimeStart,
end: timeControls.comparisonTimeEnd,
};

// FIXME: As a temporary way of enabling sorting by dimension values,
// Benjamin and Egor put in a patch that will allow us to use the
// dimension name as the measure name. This will need to be updated
// once they have stabilized the API.
if (sortType === SortType.DIMENSION) {
sortMeasureName = dimensionName;
// note also that we need to remove the comparison time range
// when sorting by dimension values, or the query errors
comparisonTimeRange = undefined;
}

const querySortType = getQuerySortType(sortType);

return {
Expand All @@ -44,10 +60,7 @@ export function prepareSortedQueryBody(
start: timeControls.timeStart,
end: timeControls.timeEnd,
},
comparisonTimeRange: {
start: timeControls.comparisonTimeStart,
end: timeControls.comparisonTimeEnd,
},
comparisonTimeRange,
sort: [
{
ascending: sortAscending,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,6 @@
} from "@rilldata/web-common/runtime-client";
import { useQueryClient } from "@tanstack/svelte-query";
import { runtime } from "../../../runtime-client/runtime-store";
import { SortDirection, SortType } from "../proto-state/derived-types";
import {
metricsExplorerStore,
useDashboardStore,
} from "web-common/src/features/dashboards/stores/dashboard-stores";
import {
getDimensionFilterWithSearch,
prepareDimensionTableRows,
Expand All @@ -40,7 +33,7 @@
isSummableMeasure,
prepareSortedQueryBody,
} from "../dashboard-utils";
import { LeaderboardContextColumn } from "../leaderboard-context-column";
import { metricsExplorerStore } from "../stores/dashboard-stores";
export let metricViewName: string;
export let dimensionName: string;
Expand All @@ -62,10 +55,15 @@
let dimension: MetricsViewDimension;
$: dimension = $dimensionQuery?.data;
$: dimensionColumn = getDimensionColumn(dimension);
const stateManagers = getStateManagers();
const timeControlsStore = useTimeControlStore(stateManagers);
$: dashboardStore = useDashboardStore(metricViewName);
const timeControlsStore = useTimeControlStore(getStateManagers());
const {
dashboardStore,
selectors: {
sorting: { sortedAscending },
},
} = stateManagers;
$: leaderboardMeasureName = $dashboardStore?.leaderboardMeasureName;
$: isBeingCompared =
Expand Down Expand Up @@ -101,8 +99,6 @@
$dashboardStore?.visibleMeasureKeys.has(m.name)
);
$: sortAscending = $dashboardStore.sortDirection === SortDirection.ASCENDING;
$: totalsQuery = createQueryServiceMetricsViewTotals(
instanceId,
metricViewName,
Expand Down Expand Up @@ -130,15 +126,12 @@
}
$: columns = prepareVirtualizedDimTableColumns(
$dashboardStore,
allMeasures,
leaderboardMeasureName,
referenceValues,
dimension,
[...$dashboardStore.visibleMeasureKeys],
$timeControlsStore.showComparison,
validPercentOfTotal,
$dashboardStore.dashboardSortType,
$dashboardStore.sortDirection
validPercentOfTotal
);
$: sortedQueryBody = prepareSortedQueryBody(
Expand All @@ -147,7 +140,7 @@
$timeControlsStore,
leaderboardMeasureName,
$dashboardStore.dashboardSortType,
sortAscending,
$sortedAscending,
filterSet
);
Expand Down Expand Up @@ -178,39 +171,6 @@
metricsExplorerStore.toggleFilter(metricViewName, dimensionName, label);
}
function onSortByColumn(event) {
const columnName = event.detail;
if (columnName === leaderboardMeasureName + "_delta") {
metricsExplorerStore.toggleSort(metricViewName, SortType.DELTA_ABSOLUTE);
metricsExplorerStore.setContextColumn(
metricViewName,
LeaderboardContextColumn.DELTA_ABSOLUTE
);
} else if (columnName === leaderboardMeasureName + "_delta_perc") {
metricsExplorerStore.toggleSort(metricViewName, SortType.DELTA_PERCENT);
metricsExplorerStore.setContextColumn(
metricViewName,
LeaderboardContextColumn.DELTA_PERCENT
);
} else if (columnName === leaderboardMeasureName + "_percent_of_total") {
metricsExplorerStore.toggleSort(metricViewName, SortType.PERCENT);
metricsExplorerStore.setContextColumn(
metricViewName,
LeaderboardContextColumn.PERCENT
);
} else if (columnName === leaderboardMeasureName) {
metricsExplorerStore.toggleSort(metricViewName, SortType.VALUE);
} else {
metricsExplorerStore.setLeaderboardMeasureName(
metricViewName,
columnName
);
metricsExplorerStore.toggleSort(metricViewName, SortType.VALUE);
metricsExplorerStore.setSortDescending(metricViewName);
}
}
function toggleComparisonDimension(dimensionName, isBeingCompared) {
metricsExplorerStore.setComparisonDimension(
metricViewName,
Expand All @@ -237,15 +197,14 @@
<div class="grow" style="overflow-y: hidden;">
<DimensionTable
on:select-item={(event) => onSelectItem(event)}
on:sort={(event) => onSortByColumn(event)}
on:toggle-dimension-comparison={() =>
toggleComparisonDimension(dimensionName, isBeingCompared)}
isFetching={$sortedQuery?.isFetching}
dimensionName={dimensionColumn}
{isBeingCompared}
{columns}
{selectedValues}
rows={tableRows}
sortByColumn={leaderboardMeasureName}
{excludeMode}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,24 @@
import Spinner from "../../entity-management/Spinner.svelte";
import { metricsExplorerStore } from "web-common/src/features/dashboards/stores/dashboard-stores";
import ExportDimensionTableDataButton from "./ExportDimensionTableDataButton.svelte";
import { getStateManagers } from "../state-managers/state-managers";
import { SortType } from "../proto-state/derived-types";
export let metricViewName: string;
export let dimensionName: string;
export let isFetching: boolean;
export let excludeMode = false;
const stateManagers = getStateManagers();
const {
selectors: {
sorting: { sortedByDimensionValue },
},
actions: {
sorting: { toggleSort },
},
} = stateManagers;
const queryClient = useQueryClient();
$: filterKey = excludeMode ? "exclude" : "include";
Expand All @@ -46,6 +58,9 @@
const goBackToLeaderboard = () => {
metricsExplorerStore.setMetricDimensionName(metricViewName, null);
if ($sortedByDimensionValue) {
toggleSort(SortType.VALUE);
}
};
function toggleFilterMode() {
cancelDashboardQueries(queryClient, metricViewName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,25 @@ TableCells – the cell contents.
} from "./dimension-table-utils";
import type { DimensionTableRow } from "./dimension-table-types";
import { getStateManagers } from "../state-managers/state-managers";
const dispatch = createEventDispatcher();
export let rows: DimensionTableRow[];
export let columns: VirtualizedTableColumns[];
export let selectedValues: Array<unknown> = [];
export let sortByColumn: string;
export let dimensionName: string;
export let excludeMode = false;
export let isBeingCompared = false;
export let isFetching: boolean;
const {
actions: { dimTable },
selectors: {
sorting: { sortMeasure },
},
} = getStateManagers();
/** the overscan values tell us how much to render off-screen. These may be set by the consumer
* in certain circumstances. The tradeoff: the higher the overscan amount, the more DOM elements we have
Expand Down Expand Up @@ -169,7 +178,8 @@ TableCells – the cell contents.
async function handleColumnHeaderClick(event) {
colScrollOffset = $columnVirtualizer.scrollOffset;
dispatch("sort", event.detail);
const columnName = event.detail;
dimTable.handleMeasureColumnHeaderClick(columnName);
}
async function handleResizeDimensionColumn(event) {
Expand Down Expand Up @@ -216,7 +226,7 @@ TableCells – the cell contents.
<ColumnHeaders
virtualColumnItems={virtualColumns}
noPin={true}
selectedColumn={sortByColumn}
selectedColumn={$sortMeasure}
columns={measureColumns}
on:click-column={handleColumnHeaderClick}
/>
Expand Down Expand Up @@ -245,6 +255,7 @@ TableCells – the cell contents.
{excludeMode}
{scrolling}
{horizontalScrolling}
on:dimension-sort
on:select-item={(event) => onSelectItem(event)}
on:inspect={setActiveIndex}
/>
Expand All @@ -264,6 +275,10 @@ TableCells – the cell contents.
on:inspect={setActiveIndex}
cellLabel="Filter dimension value"
/>
{:else if isFetching}
<div class="flex text-gray-500 justify-center mt-[30vh]">
Loading...
</div>
{:else}
<div class="flex text-gray-500 justify-center mt-[30vh]">
No results to show
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import { createEventDispatcher, getContext } from "svelte";
import Cell from "../../../components/virtualized-table/core/Cell.svelte";
import type { VirtualizedTableConfig } from "../../../components/virtualized-table/types";
import ArrowDown from "@rilldata/web-common/components/icons/ArrowDown.svelte";
import { fly } from "svelte/transition";
import { getStateManagers } from "../state-managers/state-managers";
import type { ResizeEvent } from "@rilldata/web-common/components/virtualized-table/drag-table-cell";
const config: VirtualizedTableConfig = getContext("config");
Expand All @@ -21,6 +24,14 @@
export let activeIndex;
export let excludeMode = false;
const {
actions: {
sorting: { sortByDimensionValue },
},
selectors: {
sorting: { sortedByDimensionValue, sortedAscending },
},
} = getStateManagers();
const dispatch = createEventDispatcher();
$: atLeastOneSelected = !!selectedIndex?.length;
Expand Down Expand Up @@ -54,10 +65,29 @@
enableResize={true}
position="top-left"
borderRight={horizontalScrolling}
bgClass="bg-white"
bgClass={$sortedByDimensionValue ? `bg-gray-50` : "bg-white"}
on:click={sortByDimensionValue}
on:keydown={sortByDimensionValue}
on:resize={handleResize}
>
<span class="px-1">{column?.label || column?.name}</span>
<div class="flex items-center">
<span class={"px-1 " + $sortedByDimensionValue ? "font-bold" : ""}
>{column?.label || column?.name}</span
>
{#if $sortedByDimensionValue}
<div class="ui-copy-icon">
{#if $sortedAscending}
<div in:fly={{ duration: 200, y: -8 }} style:opacity={1}>
<ArrowDown size="12px" />
</div>
{:else}
<div in:fly={{ duration: 200, y: 8 }} style:opacity={1}>
<ArrowDown transform="scale(1 -1)" size="12px" />
</div>
{/if}
</div>
{/if}
</div>
</StickyHeader>
{#each virtualRowItems as row (`row-${row.key}`)}
{@const rowActive = activeIndex === row?.index}
Expand All @@ -66,7 +96,7 @@
position="left"
header={{ size: width, start: row.start }}
borderRight={horizontalScrolling}
bgClass="bg-white"
bgClass={$sortedByDimensionValue ? `bg-gray-50` : "bg-white"}
>
<Cell
positionStatic
Expand All @@ -76,6 +106,7 @@
{excludeMode}
{rowActive}
{...getCellProps(row)}
colSelected={$sortedByDimensionValue}
on:inspect
on:select-item
label="Filter dimension value"
Expand Down
Loading

1 comment on commit 9a0411d

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.