Skip to content

Commit 9d4516d

Browse files
authored
Merge pull request #3136 from perspective-dev/fix-datagrid-sort-jump
Fix datagrid scroll position shift when sorting
2 parents a435e2f + 50a53e6 commit 9d4516d

5 files changed

Lines changed: 52 additions & 16 deletions

File tree

packages/viewer-datagrid/src/ts/data_listener/index.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import type {
2424
Schema,
2525
} from "../types.js";
2626
import type { CellScalar, DataResponse } from "regular-table/dist/esm/types.js";
27-
import { ViewWindow } from "@perspective-dev/client";
27+
import { ViewConfig, ViewWindow } from "@perspective-dev/client";
2828

2929
interface ColumnData {
3030
__ROW_PATH__?: unknown[][];
@@ -192,8 +192,10 @@ export function createDataListener(
192192
column_paths.push(path);
193193
}
194194

195+
const is_dim_call = x1 - x0 > 0 && y1 - y0 > 0;
196+
195197
// Only update the last state if this is not a "phantom" call.
196-
if (x1 - x0 > 0 && y1 - y0 > 0) {
198+
if (is_dim_call) {
197199
this.last_column_paths = last_column_paths;
198200
this.last_meta = last_meta;
199201
this.last_ids = last_ids;
@@ -223,7 +225,9 @@ export function createDataListener(
223225
),
224226
) as (string | HTMLElement)[][];
225227

226-
const num_row_headers = row_headers[0]?.length;
228+
const num_row_headers = !is_dim_call
229+
? row_header_depth(this._config)
230+
: row_headers[0]?.length;
227231

228232
const result: DataResponse = {
229233
num_column_headers:
@@ -244,3 +248,15 @@ export function createDataListener(
244248
return result;
245249
};
246250
}
251+
252+
function row_header_depth(config: ViewConfig) {
253+
if (config.group_rollup_mode === "flat") {
254+
return config.group_by.length;
255+
} else if (config.group_rollup_mode === "total") {
256+
return 0;
257+
} else if (config.group_by.length === 0) {
258+
return 0;
259+
} else {
260+
return config.group_by.length + 1;
261+
}
262+
}

packages/viewer-datagrid/src/ts/event_handlers/sort.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ const ROW_SORT_ORDER: SortRotationOrder = {
2828

2929
const ROW_COL_SORT_ORDER: SortRotationOrder = {
3030
desc: "asc",
31-
asc: "col desc",
31+
asc: undefined,
3232
"desc abs": "asc abs",
33-
"asc abs": "col desc abs",
34-
"col desc": "col asc",
35-
"col asc": undefined,
36-
"col desc abs": "col asc abs",
37-
"col asc abs": undefined,
33+
"asc abs": undefined,
34+
// "col desc": "col asc",
35+
// "col asc": undefined,
36+
// "col desc abs": "col asc abs",
37+
// "col asc abs": undefined,
3838
};
3939

4040
export async function sortHandler(
@@ -49,7 +49,7 @@ export async function sortHandler(
4949
const column_name = meta.column_header[this._config.split_by.length];
5050
const sort_method =
5151
event.ctrlKey ||
52-
(event as MouseEvent & { metaKet?: boolean }).metaKet ||
52+
(event as MouseEvent & { metaKey?: boolean }).metaKey ||
5353
event.altKey
5454
? append_sort
5555
: override_sort;
@@ -97,6 +97,7 @@ export function override_sort(
9797
return sort ? [sort] : [];
9898
}
9999
}
100+
100101
return [[column_name, abs ? "desc abs" : "desc"]];
101102
}
102103

@@ -111,8 +112,10 @@ export function create_sort(
111112
const inc_sort_dir: SortDir | undefined = sort_dir
112113
? order[sort_dir]
113114
: "desc";
115+
114116
if (inc_sort_dir) {
115117
return [column_name, inc_sort_dir];
116118
}
119+
117120
return undefined;
118121
}

packages/viewer-datagrid/src/ts/model/create.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,21 +87,21 @@ export async function createModel(
8787
}
8888

8989
let split_by_changed = old.split_by.length !== config.split_by.length;
90-
if (split_by_changed) {
90+
if (!split_by_changed) {
9191
for (const lvl in old.split_by) {
9292
split_by_changed ||= config.split_by[lvl] !== old.split_by[lvl];
9393
}
9494
}
9595

9696
let columns_changed = old.columns.length !== config.columns.length;
97-
if (columns_changed) {
97+
if (!columns_changed) {
9898
for (const lvl in old.columns) {
9999
columns_changed ||= config.columns[lvl] !== old.columns[lvl];
100100
}
101101
}
102102

103103
let filter_changed = old.filter.length !== config.filter.length;
104-
if (filter_changed) {
104+
if (!filter_changed) {
105105
for (const lvl in old.filter) {
106106
for (const i in config.filter[lvl]) {
107107
filter_changed ||=
@@ -112,7 +112,7 @@ export async function createModel(
112112
}
113113

114114
let sort_changed = old.sort.length !== config.sort.length;
115-
if (sort_changed) {
115+
if (!sort_changed) {
116116
for (const lvl in old.sort) {
117117
for (const i in config.sort[lvl]) {
118118
sort_changed ||=

rust/perspective-js/test/js/group_rollup_mode.spec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,23 @@ const data = {
585585
table.delete();
586586
});
587587

588+
test("with split_by schema", async function () {
589+
const table = await perspective.table(data);
590+
const view = await table.view({
591+
split_by: ["z"],
592+
group_rollup_mode: "total",
593+
});
594+
const schema = await view.schema();
595+
expect(schema).toStrictEqual({
596+
w: "float",
597+
x: "integer",
598+
y: "integer",
599+
z: "integer",
600+
});
601+
view.delete();
602+
table.delete();
603+
});
604+
588605
test("updates after table.update()", async function () {
589606
const table = await perspective.table(data);
590607
const view = await table.view({

rust/perspective-server/cpp/perspective/src/cpp/view.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ View<CTX_T>::schema() const {
461461
std::string type_string = dtype_to_str(types[agg_name]);
462462
new_schema[agg_name] = type_string;
463463

464-
if ((!m_row_pivots.empty() || m_view_config->is_total_only()) && !is_column_only()) {
464+
if ((!m_row_pivots.empty() || m_view_config->is_total_only()) && (!is_column_only() || m_view_config->is_total_only())) {
465465
new_schema[agg_name] =
466466
_map_aggregate_types(agg_name, new_schema[agg_name]);
467467
}
@@ -540,7 +540,7 @@ View<CTX_T>::expression_schema() const {
540540
const std::string& expression_alias = expr->get_expression_alias();
541541
new_schema[expression_alias] = dtype_to_str(expr->get_dtype());
542542

543-
if ((!m_row_pivots.empty() || m_view_config->is_total_only()) && !is_column_only()) {
543+
if ((!m_row_pivots.empty() || m_view_config->is_total_only()) && (!is_column_only() || m_view_config->is_total_only())) {
544544
new_schema[expression_alias] = _map_aggregate_types(
545545
expression_alias, new_schema[expression_alias]
546546
);

0 commit comments

Comments
 (0)