Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#6674 viewport size and aesthetic improvements #6905

Merged
merged 1 commit into from
Feb 27, 2018
Merged
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
3 changes: 1 addition & 2 deletions js/notebook/src/TableDisplay.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ var widgets = require('./widgets');
var _ = require('underscore');
var $ = require('jquery');

var TableScope = require('./tableDisplay/tableScope');
var DataGridScope = require('./tableDisplay/dataGrid').DataGridScope;

require('datatables.net-dt/css/jquery.dataTables.css');
Expand Down Expand Up @@ -105,7 +104,7 @@ var TableDisplayView = widgets.DOMWidgetView.extend({
var tmpl = '<div id="' + this.wrapperId + '">' +
'<p class="ansired">Note: table is too big to display. ' +
'The limit is ' + rowLimit + ' rows, but this table has ' + rowLength + ' rows. ' +
'The first 1000 rows are displayed as a preview.</p></div>';
'The first 10000 rows are displayed as a preview.</p></div>';
var tmplElement = $(tmpl);
tmplElement.appendTo(this.$el);
}
Expand Down
128 changes: 72 additions & 56 deletions js/notebook/src/tableDisplay/dataGrid/BeakerxDataGrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { CellRenderer, DataGrid } from "@phosphor/datagrid";
import {CellRenderer, DataGrid, DataModel} from "@phosphor/datagrid";
import { BeakerxDataGridModel } from "./model/BeakerxDataGridModel";
import { Widget } from "@phosphor/widgets";
import { Signal } from '@phosphor/signaling';
Expand All @@ -28,13 +28,20 @@ import { DEFAULT_PAGE_LENGTH } from "../consts";
import ColumnManager from "./column/ColumnManager";
import RowManager from "./row/RowManager";
import CellSelectionManager from "./cell/CellSelectionManager";
import {SectionList} from "@phosphor/datagrid/lib/sectionlist";
import CellManager from "./cell/CellManager";
import {DataGridHelpers} from "./dataGridHelpers";
import EventManager from "./EventManager";
import EventManager from "./EventManager";import {
IMessageHandler, Message
} from '@phosphor/messaging';

import getStringWidth = DataGridHelpers.getStringWidth;
import CellFocusManager from "./cell/CellFocusManager";
import findSectionIndex = DataGridHelpers.findSectionIndex;
import {
DEFAULT_GRID_BORDER_WIDTH,
DEFAULT_GRID_PADDING,
MIN_COLUMN_WIDTH
} from "./style/dataGridStyle";

export class BeakerxDataGrid extends DataGrid {
columnSections: any;
Expand Down Expand Up @@ -72,10 +79,19 @@ export class BeakerxDataGrid extends DataGrid {
this.eventManager.handleEvent(event, super.handleEvent);
}

messageHook(handler: IMessageHandler, msg: Message): boolean {
super.messageHook(handler, msg);

if (handler === this.viewport && msg.type === 'section-resize-request') {
this.setWidgetWidth();
}

return true;
}

destroy() {
this.eventManager.destroy();
this.columnManager.destroy();
this.isAttached && this.dispose();
}

getColumn(config: CellRenderer.ICellConfig): DataGridColumn {
Expand All @@ -86,14 +102,6 @@ export class BeakerxDataGrid extends DataGrid {
return this.columnManager.getColumnByName(columnName);
}

getColumnOffset(index: number, type: COLUMN_TYPES) {
if (type === COLUMN_TYPES.index) {
return 0;
}

return this.rowHeaderSections.totalSize + this.columnSections.sectionOffset(index);
}

getCellData(clientX: number, clientY: number): ICellData|null {
if (!this.viewport) {
return null;
Expand All @@ -107,11 +115,11 @@ export class BeakerxDataGrid extends DataGrid {
// Test for a match in the corner header first.
if (x <= this.headerWidth && y <= this.headerHeight) {
if (y <= this.headerHeight) {
column = this.findSectionIndex(this.columnHeaderSections, x);
column = findSectionIndex(this.columnHeaderSections, x);
}

if (!column && x <= this.headerWidth) {
column = this.findSectionIndex(this.rowHeaderSections, y);
column = findSectionIndex(this.rowHeaderSections, y);
}

if (column) {
Expand All @@ -137,7 +145,7 @@ export class BeakerxDataGrid extends DataGrid {
}

let row: { index: number, delta: number } | null = this.findHoveredRowIndex(y);
column = this.findSectionIndex(section, pos);
column = findSectionIndex(section, pos);

if (column) {
return {
Expand All @@ -152,6 +160,14 @@ export class BeakerxDataGrid extends DataGrid {
return null;
}

getColumnOffset(index: number, type: COLUMN_TYPES) {
if (type === COLUMN_TYPES.index) {
return 0;
}

return this.rowHeaderSections.totalSize + this.columnSections.sectionOffset(index);
}

isOverHeader(event: MouseEvent) {
let rect = this.viewport.node.getBoundingClientRect();
let x = event.clientX - rect.left;
Expand All @@ -171,6 +187,10 @@ export class BeakerxDataGrid extends DataGrid {
});
}

updateModelData(state: IDataModelState) {
this.model.addProperties(state, this.columnManager, this.rowManager);
}

private init(modelState: IDataModelState) {
this.columnManager = new ColumnManager(modelState, this);
this.rowManager = new RowManager(modelState.values, modelState.hasIndex, this.columnManager);
Expand All @@ -189,8 +209,10 @@ export class BeakerxDataGrid extends DataGrid {
this.setWidgetHeight();
this.resizeSections();

this.model.reset();
this.repaint();
setTimeout(() => {
this.repaint();
this.setWidgetWidth();
});
}

private addHighlighterManager(modelState: IDataModelState) {
Expand All @@ -212,75 +234,69 @@ export class BeakerxDataGrid extends DataGrid {
}

private setWidgetHeight() {
let bodyRowCount = this.model.rowCount('body');
let rowCount = DEFAULT_PAGE_LENGTH < bodyRowCount ? DEFAULT_PAGE_LENGTH : bodyRowCount;

this.node.style.minHeight = `${ (rowCount + 2) * this.baseRowSize + this.baseColumnHeaderSize }px`;
this.node.style.minHeight = `${this.getWidgetHeight()}px`;
}

private findHoveredRowIndex(y: number) {
// Convert the position into unscrolled coordinates.
let pos = y + this.scrollY - this.headerHeight;
private setWidgetWidth() {
const scrollBarSpaceWidth = this.getWidgetHeight() >= this.totalHeight ? 0 : 20;
const spacing = 2 * (DEFAULT_GRID_PADDING + DEFAULT_GRID_BORDER_WIDTH);

return this.findSectionIndex(this.rowSections, pos);
this.node.style.width = `${this.totalWidth + scrollBarSpaceWidth + spacing}px`;
this.fit();
this['_syncViewport']();
}

private findSectionIndex(list: SectionList, cursorPosition: number): { index: number, delta: number } | null {
// Bail early if the list is empty or the position is invalid.
if (list.sectionCount === 0 || cursorPosition < 0) {
return null;
}
private getWidgetHeight() {
const bodyRowCount = this.model.rowCount('body');
const rowCount = DEFAULT_PAGE_LENGTH < bodyRowCount ? DEFAULT_PAGE_LENGTH : bodyRowCount;
const spacing = 2 * (DEFAULT_GRID_PADDING + DEFAULT_GRID_BORDER_WIDTH);

// Compute the delta from the end of the list.
let delta = cursorPosition - (list.totalSize - 1);
if (delta > 0) {
return null;
}

// Test whether the hover is just past the last section.
let index = list.sectionCount - 1;
if (delta >= -list.sectionSize(index)) {
return { index, delta };
}

index = list.sectionIndex(cursorPosition);
delta = cursorPosition - (list.sectionOffset(index) - 1);
return rowCount * this.baseRowSize + this.headerHeight + spacing;
}

if (index >= 0) {
return { index, delta };
}
private findHoveredRowIndex(y: number) {
// Convert the position into unscrolled coordinates.
let pos = y + this.scrollY - this.headerHeight;

return null;
return findSectionIndex(this.rowSections, pos);
}

private resizeColumnSection(column) {
this.columnSections.resizeSection(
this.resizeSection(
'column',
column.getResolvedIndex(),
this.getSectionWidth(column)
);
}

private getSectionWidth(column) {
let value = String(column.formatFn(this.cellManager.createCellConfig({
const value = String(column.formatFn(this.cellManager.createCellConfig({
region: 'body',
value: column.maxValue,
column: column.index,
row: 0,
})));
const nameWidth = getStringWidth(column.name, this.model.state.headerFontSize);
const valueWidth = getStringWidth(value,this.model.state.dataFontSize);
const result = nameWidth > valueWidth ? nameWidth: valueWidth;

return getStringWidth(value.length > column.name.length ? value : column.name);
return result > MIN_COLUMN_WIDTH ? result : MIN_COLUMN_WIDTH;
}

private resizeSections() {
this.columnManager.columns[COLUMN_TYPES.body].forEach(this.resizeColumnSection);
this.resizeIndexColumn();
this.setWidgetWidth();
}

private resizeIndexColumn() {
let valueCharLength = this.model.rowCount('body');
let name = this.columnManager.getColumnByIndex(COLUMN_TYPES.index, 0).name;
let value = name.length > valueCharLength ? name : String(valueCharLength);

this.rowHeaderSections.resizeSection(0, getStringWidth(value) + 10);
const valueCharLength = this.model.rowCount('body');
const name = this.columnManager.getColumnByIndex(COLUMN_TYPES.index, 0).name;
const value = name.length > valueCharLength ? name : String(valueCharLength);
const nameWidth = getStringWidth(name, this.model.state.headerFontSize);
const valueWidth = getStringWidth(value, this.model.state.dataFontSize);
const result = nameWidth > valueWidth ? nameWidth: valueWidth;

this.rowHeaderSections.resizeSection(0, result + 10);
}
}
15 changes: 15 additions & 0 deletions js/notebook/src/tableDisplay/dataGrid/DataGridScope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,19 @@ export class DataGridScope {
doDestroy() {
this.dataGrid.destroy();
}

updateModelData(newData) {
this.dataGrid.updateModelData(newData);
this.dataGrid.model.reset();
}

doResetAll() {
this.dataGrid.highlighterManager.removeHighlighters();
this.dataGrid.cellSelectionManager.clear();
this.dataGrid.rowManager.resetSorting();
this.dataGrid.columnManager.resetFilters();
this.dataGrid.columnManager.showAllColumns();
this.dataGrid.columnManager.resetColumnsAlignment();
this.dataGrid.columnManager.resetColumnsOrder();
}
}
2 changes: 1 addition & 1 deletion js/notebook/src/tableDisplay/dataGrid/EventManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ export default class EventManager {
}

private handleNumKeyDown(event: KeyboardEvent, charCode: string, column: DataGridColumn|null) {
if (event.keyCode < 48 || event.keyCode > 57) { //numbers 1..9
if (event.keyCode < 48 || event.keyCode > 57) { //not numbers 1..9
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {BeakerxDataGrid} from "../BeakerxDataGrid";
import {ICellData} from "../interface/ICell";
import {CellRenderer} from "@phosphor/datagrid";
import {COLUMN_TYPES, default as DataGridColumn} from "../column/DataGridColumn";
import {DEFAULT_CELL_BACKGROUND, FOCUSED_CELL_BACKGROUND} from "./CellRendererFactory";
import {DEFAULT_CELL_BACKGROUND, FOCUSED_CELL_BACKGROUND} from "../style/dataGridStyle";

export default class CellFocusManager {
dataGrid: BeakerxDataGrid;
Expand Down
34 changes: 28 additions & 6 deletions js/notebook/src/tableDisplay/dataGrid/cell/CellRendererFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ import { DEFAULT_ALIGNMENT } from "../column/columnAlignment";
import { CellRenderer, TextRenderer } from "@phosphor/datagrid";
import { BeakerxDataGrid } from "../BeakerxDataGrid";
import DataGridCell from "./DataGridCell";
import { darken } from "../style/dataGridStyle";

export const DEFAULT_CELL_BACKGROUND = '';
export const FOCUSED_CELL_BACKGROUND = 'rgb(200, 200, 200)';
import {
darken,
DEFAULT_CELL_BACKGROUND,
DEFAULT_DATA_FONT_COLOR,
DEFAULT_DATA_FONT_SIZE,
DEFAULT_HEADER_FONT_COLOR, formatColor
} from "../style/dataGridStyle";

export class CellRendererFactory {
private dataGrid: BeakerxDataGrid;
Expand Down Expand Up @@ -61,8 +64,27 @@ export class CellRendererFactory {

return DataGridCell.isHeaderCell(config) ? config.value : column.formatFn(config);
},
font: 'normal 13px Lato, Helvetica, sans-serif',
textColor: config => config.region === 'column-header' || config.region === "corner-header" ? '#515A5A' : '#000000',
font: ({ region }) => {
let fontSize = (region === 'column-header' || region === 'corner-header')
? this.dataGrid.model.state.headerFontSize
: this.dataGrid.model.state.dataFontSize;

return `normal ${fontSize || DEFAULT_DATA_FONT_SIZE}px Lato, Helvetica, sans-serif`
},
textColor: (config) => {
if (config.region === 'row-header') {
return DEFAULT_DATA_FONT_COLOR;
}

let colors = this.dataGrid.model.state.fontColor;
let dataFontColor = colors && colors[config.row]
? formatColor(colors[config.row][config.column])
: DEFAULT_DATA_FONT_COLOR;

return config.region === 'column-header' || config.region === "corner-header"
? DEFAULT_HEADER_FONT_COLOR
: dataFontColor;
}
});
}
}
Loading