Skip to content

Commit

Permalink
Datagrid: Add a public API to get the current viewport (#695)
Browse files Browse the repository at this point in the history
* Datagrid: Add a public API to get the current viewport

* Review

* Add docstring

* Generate API

* Add spec

* Add model

* Proper test

* Fix typo

Co-authored-by: Michał Krassowski <5832902+krassowski@users.noreply.github.com>

---------

Co-authored-by: Michał Krassowski <5832902+krassowski@users.noreply.github.com>
  • Loading branch information
martinRenou and krassowski committed Apr 16, 2024
1 parent f9b76e2 commit f85aad4
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 4 deletions.
70 changes: 70 additions & 0 deletions packages/datagrid/src/datagrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2012,6 +2012,51 @@ export class DataGrid extends Widget {
}
}

/**
* Get the current viewport.
*
* @returns The current viewport as row/column coordinates.
* Returns undefined if the grid is not visible.
*/
get currentViewport(): DataGrid.IBodyRegion | undefined {
let width = this.viewport.node.offsetWidth;
let height = this.viewport.node.offsetHeight;

width = Math.round(width);
height = Math.round(height);

if (width <= 0 || height <= 0) {
return;
}

const contentW = this._columnSections.length - this.scrollX;
const contentH = this._rowSections.length - this.scrollY;

const contentX = this.headerWidth;
const contentY = this.headerHeight;

const x1 = contentX;
const y1 = contentY;
const x2 = Math.min(width - 1, contentX + contentW - 1);
const y2 = Math.min(height - 1, contentY + contentH - 1);

const firstRow = this._rowSections.indexOf(y1 - contentY + this.scrollY);
const firstColumn = this._columnSections.indexOf(
x1 - contentX + this.scrollX
);
const lastRow = this._rowSections.indexOf(y2 - contentY + this.scrollY);
const lastColumn = this._columnSections.indexOf(
x2 - contentX + this.scrollX
);

return {
firstRow,
firstColumn,
lastRow,
lastColumn
};
}

/**
* A message handler invoked on an `'activate-request'` message.
*/
Expand Down Expand Up @@ -6721,6 +6766,31 @@ export namespace DataGrid {
headers: 'none',
warningThreshold: 1e6
};

/**
* A body region defined by the cells' boundaries using row/column coordinates.
*/
export interface IBodyRegion {
/**
* First row of the region
*/
firstRow: number;

/**
* Last row of the region
*/
lastRow: number;

/**
* First column of the region
*/
firstColumn: number;

/**
* Last column of the region
*/
lastColumn: number;
}
}

/**
Expand Down
59 changes: 59 additions & 0 deletions packages/datagrid/tests/src/datagrid.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
import { expect } from 'chai';

import { DataGrid, DataModel } from '@lumino/datagrid';

class LargeDataModel extends DataModel {
rowCount(region: DataModel.RowRegion): number {
return region === 'body' ? 1_000_000_000_000 : 2;
}

columnCount(region: DataModel.ColumnRegion): number {
return region === 'body' ? 1_000_000_000_000 : 3;
}

data(region: DataModel.CellRegion, row: number, column: number): any {
if (region === 'row-header') {
return `R: ${row}, ${column}`;
}
if (region === 'column-header') {
return `C: ${row}, ${column}`;
}
if (region === 'corner-header') {
return `N: ${row}, ${column}`;
}
return `(${row}, ${column})`;
}
}

describe('@lumino/datagrid', () => {
let datagrid: DataGrid;
let model: LargeDataModel;

beforeEach(() => {
datagrid = new DataGrid();
model = new LargeDataModel();
datagrid.dataModel = model;
datagrid.viewport.node.style.height = '500px';
datagrid.viewport.node.style.width = '500px';
document.children[0].appendChild(datagrid.node);
});

describe('DataGrid', () => {
describe('currentViewport()', () => {
it('should return the viewport', () => {
const viewport = datagrid.currentViewport;

if (viewport === undefined) {
throw new Error('viewport is undefined');
}

expect(viewport.firstRow).to.be.eq(0);
expect(viewport.firstColumn).to.be.eq(0);
expect(viewport.lastRow).to.be.eq(22);
expect(viewport.lastColumn).to.be.eq(4);
});
});
});
});
1 change: 1 addition & 0 deletions packages/datagrid/tests/src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@

import './textrenderer.spec';
import './imagerenderer.spec';
import './datagrid.spec';
15 changes: 11 additions & 4 deletions review/api/datagrid.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ export class DataGrid extends Widget {
get copyConfig(): DataGrid.CopyConfig;
set copyConfig(value: DataGrid.CopyConfig);
copyToClipboard(): void;
get currentViewport(): DataGrid.IBodyRegion | undefined;
get dataModel(): DataModel | null;
set dataModel(value: DataModel | null);
get defaultSizes(): DataGrid.DefaultSizes;
Expand Down Expand Up @@ -332,6 +333,12 @@ export namespace DataGrid {
readonly width: number;
readonly height: number;
};
export interface IBodyRegion {
firstColumn: number;
firstRow: number;
lastColumn: number;
lastRow: number;
}
export interface IKeyHandler extends IDisposable {
onKeyDown(grid: DataGrid, event: KeyboardEvent): void;
}
Expand Down Expand Up @@ -363,6 +370,10 @@ export namespace DataGrid {
readonly rowHeaderWidth: number;
readonly columnHeaderHeight: number;
};
const defaultStyle: Style;
const defaultSizes: DefaultSizes;
const minimumSizes: MinimumSizes;
const defaultCopyConfig: CopyConfig;
export type Style = {
readonly voidColor?: string;
readonly backgroundColor?: string;
Expand All @@ -388,10 +399,6 @@ export namespace DataGrid {
readonly color3: string;
};
};
const defaultStyle: Style;
const defaultSizes: DefaultSizes;
const minimumSizes: MinimumSizes;
const defaultCopyConfig: CopyConfig;
}

// @public
Expand Down

0 comments on commit f85aad4

Please sign in to comment.