Skip to content

Commit

Permalink
#7338 support fixed width for image and HTML columns (#7667)
Browse files Browse the repository at this point in the history
* #7338 width parameter for HTML and Image string format - backend

* #7338 support fixed width for image and HTML columns

* #7338 fix widget resizing with fixed width columns

* #7338 fix TableDisplay resize feature
  • Loading branch information
Mariusz Jurowicz authored and LeeTZ committed Jul 12, 2018
1 parent 6930af7 commit 0065909
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 24 deletions.
29 changes: 18 additions & 11 deletions beakerx/beakerx/tabledisplay/tableitems.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,27 @@ def __init__(self, x):

class DecimalStringFormat:
type = "decimal"
minDecimals = 4
maxDecimals = 4

def __init__(self, min=4, max=4):
self.minDecimals = min
self.maxDecimals = max
def __init__(self, **kwargs):
self.minDecimals = kwargs.get('min', 4)
self.maxDecimals = kwargs.get('max', 4)


class ImageFormat:
type = "image"

def __init__(self, **kwargs):
if 'width' in kwargs:
self.width = kwargs.get('width')


class HTMLFormat:
type = "html"

def __init__(self, **kwargs):
if 'width' in kwargs:
self.width = kwargs.get('width')


class HighlightStyle(Enum):
FULL_ROW = 1
Expand All @@ -80,6 +86,7 @@ class HighlightStyle(Enum):

class HeatmapHighlighter:
type = "HeatmapHighlighter"

def __init__(self, colName, style, minVal, maxVal, minColor, maxColor):
self.colName = colName
self.style = style.name
Expand All @@ -98,16 +105,16 @@ def getDataBarsRenderer(include_text=True):
class TableDisplayStringFormat:

@staticmethod
def getDecimalFormat(min, max):
return DecimalStringFormat(min, max)
def getDecimalFormat(**kwargs):
return DecimalStringFormat(**kwargs)

@staticmethod
def getHTMLFormat():
return HTMLFormat()
def getHTMLFormat(**kwargs):
return HTMLFormat(**kwargs)

@staticmethod
def getImageFormat():
return ImageFormat()
def getImageFormat(**kwargs):
return ImageFormat(**kwargs)

class TableDisplayCellHighlighter:
FULL_ROW = HighlightStyle.FULL_ROW
Expand Down
32 changes: 26 additions & 6 deletions js/notebook/src/tableDisplay/dataGrid/DataGridResize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ import {DataGridHelpers} from "./dataGridHelpers";
import {selectColumnWidth} from "./column/selectors";
import getStringSize = DataGridHelpers.getStringSize;
import {ALL_TYPES} from "./dataTypes";
import throttle = DataGridHelpers.throttle;

const DEFAULT_RESIZE_SECTION_SIZE_IN_PX = 6;
const DEFAULT_ROW_PADDING = 4;
const SCROLLBAR_WIDTH = 16;

export class DataGridResize {
dataGrid: BeakerXDataGrid;
Expand All @@ -49,6 +51,7 @@ export class DataGridResize {
this.handleMouseMove = this.handleMouseMove.bind(this);
this.handleMouseUp = this.handleMouseUp.bind(this);
this.fillEmptySpaceResizeFn = this.fillEmptySpaceResizeFn.bind(this);
this.fitVieport = throttle<void, void>(this.fitVieport, 100, this);

this.installMessageHook();
}
Expand Down Expand Up @@ -76,24 +79,25 @@ export class DataGridResize {

updateWidgetHeight(): void {
this.dataGrid.node.style.minHeight = `${this.getWidgetHeight()}px`;
this.fitVieport();
}

updateWidgetWidth(): void {
const spacing = 2 * (DEFAULT_GRID_PADDING + DEFAULT_GRID_BORDER_WIDTH) + 1;
const hasVScroll = (
this.dataGrid.rowManager.rowsToShow !== -1 && this.dataGrid.rowManager.rowsToShow <= this.dataGrid.model.rowCount('body')
);
const vScrollWidth = hasVScroll ? this.dataGrid['_vScrollBarMinWidth'] + 1 : 0;
const vScrollWidth = hasVScroll ? SCROLLBAR_WIDTH : 0;
const width = this.dataGrid.totalWidth + spacing + vScrollWidth;

if (this.resizedHorizontally && width >= this.dataGrid.node.clientWidth) {
this.dataGrid.fit();
this.fitVieport();

return;
}

this.dataGrid.node.style.width = `${width}px`;
this.dataGrid.fit();
this.fitVieport();
}

setInitialSectionWidths(): void {
Expand All @@ -119,6 +123,8 @@ export class DataGridResize {

this.dataGrid.columnSections['_sections'].forEach(this.fillEmptySpaceResizeFn('body', value));
this.dataGrid.rowHeaderSections['_sections'].forEach(this.fillEmptySpaceResizeFn('row-header', value));

this.fitVieport();
}

updateColumnWidth(region: ColumnRegion): Function {
Expand Down Expand Up @@ -147,7 +153,6 @@ export class DataGridResize {

stopResizing() {
this.resizing = false;

this.resizeMode = null;
this.dataGrid.node.parentElement.removeEventListener('mouseup', this.handleMouseUp, true);
document.body.removeEventListener('mousemove', this.handleMouseMove, true);
Expand Down Expand Up @@ -201,6 +206,10 @@ export class DataGridResize {
column.setWidth(value);
}

fitVieport() {
this.dataGrid && this.dataGrid.fit();
}

private fillEmptySpaceResizeFn(region: ColumnRegion, value: number) {
return (section) => {
let column = this.dataGrid.columnManager.getColumnByPosition({
Expand Down Expand Up @@ -337,10 +346,21 @@ export class DataGridResize {
}

private getSectionWidth(column): number {
if(column.getDisplayType() === ALL_TYPES.image) {
return selectColumnWidth(this.dataGrid.store.state, column);
const fixedWidth = selectColumnWidth(this.dataGrid.store.state, column);
const displayType = column.getDisplayType();

if (displayType === ALL_TYPES.image) {
return fixedWidth || 1;
}

if (displayType === ALL_TYPES.html && fixedWidth) {
return fixedWidth;
}

return this.calculateSectionWidth(column);
}

private calculateSectionWidth(column: DataGridColumn) {
const position = column.getPosition();
const value = String(column.formatFn(this.dataGrid.cellManager.createCellConfig({
region: position.region,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,10 @@ export default class ImageCellRenderer extends CellRenderer {

if (selectColumnWidth(this.dataGrid.store.state, column) < width) {
column.dataGrid.dataGridResize.setSectionWidth("column", column, width);
column.dataGrid.dataGridResize.updateWidgetHeight();
column.dataGrid.dataGridResize.updateWidgetWidth();
}

column.dataGrid.dataGridResize.updateWidgetHeight();
});
}
}
2 changes: 1 addition & 1 deletion js/notebook/src/tableDisplay/dataGrid/dataGridHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export namespace DataGridHelpers {
limit: number,
context = this,
controllObject?: { timerId: any }
): (T) => U|undefined {
): (T?) => U|undefined {
let controll = controllObject || { timerId: undefined };
let lastRan;

Expand Down
34 changes: 31 additions & 3 deletions js/notebook/src/tableDisplay/dataGrid/model/selectors/column.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,19 @@ import {createSelector} from "reselect";
import {DataModel} from "@phosphor/datagrid";
import {
selectAlignmentByType,
selectAlignmentForColumn, selectAlignmentForType, selectCellHighlighters,
selectAlignmentForColumn,
selectAlignmentForType,
selectCellHighlighters,
selectColumnOrder,
selectColumnsFrozen, selectColumnsVisible, selectColumnTypes, selectHasIndex,
selectRawColumnNames, selectRendererForColumn, selectRendererForType
selectColumnsFrozen,
selectColumnsVisible,
selectColumnTypes,
selectHasIndex,
selectRawColumnNames,
selectRendererForColumn,
selectRendererForType,
selectStringFormatForColumn,
selectStringFormatForType
} from "./model";
import {getAlignmentByChar} from "../../column/columnAlignment";
import {IColumnPosition} from "../../interface/IColumn";
Expand Down Expand Up @@ -191,3 +200,22 @@ export const selectColumnHighlighters = createSelector(
highlighter => highlighter.colName === columnName && highlighter.type === highlighterType
)
);

export const selectColumnFixedWidth: (state, columnName, typeName) => number|null = createSelector([
selectStringFormatForColumn,
selectStringFormatForType,
(state, columnName) => columnName,
(state, columnName, typeName) => typeName,
],
(formatForColumns, formatForTypes, columnName, typeName) => {
if (formatForColumns[columnName] && formatForColumns[columnName].width) {
return formatForColumns[columnName].width;
}

if (formatForTypes[typeName] && formatForTypes[typeName].width) {
return formatForTypes[typeName].width;
}

return null;
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ import {
selectHasIndex,
selectInitialColumnPositions,
selectStringFormatForColumn,
selectStringFormatForType, selectFormatForTimes, DEFAULT_INDEX_COLUMN_NAME,
selectStringFormatForType,
selectFormatForTimes,
DEFAULT_INDEX_COLUMN_NAME,
selectColumnFixedWidth,
} from "../model/selectors";
import {BeakerXDataGridModel} from "../model/BeakerXDataGridModel";
import {getDisplayType, getTypeByName} from "../dataTypes";
Expand Down Expand Up @@ -69,7 +72,7 @@ export function createInitialColumnsState(initialState: IDataModelState): IColum
keepTrigger: columnType === COLUMN_TYPES.index,
position: positions[columnType][index],
dataTypeName: types[columnType][index],
width: 20,
width: selectColumnFixedWidth(state, name, types[columnType][index]),
displayType: getDisplayType(
dataType,
selectStringFormatForType(state),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,20 @@

public class HTMLStringFormat extends TableDisplayStringFormat {

private Integer width;

public HTMLStringFormat() {
}

public HTMLStringFormat(Integer width) {
this.width = width;
}

public Integer getWidth() {
return width;
}

public void setWidth(Integer width) {
this.width = width;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@

public class ImageStringFormat extends TableDisplayStringFormat {

private Integer width;

public ImageStringFormat() {
}

public ImageStringFormat(Integer width) {
this.width = width;
}

public Integer getWidth() {
return width;
}

public void setWidth(Integer width) {
this.width = width;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ public static TableDisplayStringFormat getHTMLFormat() {
return new HTMLStringFormat();
}

// Get a formatter that shows strings as formatted HTML with specified width
public static TableDisplayStringFormat getHTMLFormat(int width) {
return new HTMLStringFormat(width);
}

// Get a formatter that will show Date in a timestamp format with millisecond precision
public static TableDisplayStringFormat getTimeFormat() {
return new TimeStringFormat();
Expand All @@ -54,4 +59,9 @@ public static TableDisplayStringFormat getImageFormat() {
return new ImageStringFormat();
}

// Get a formatter that will show derived source as an image with specified width
public static TableDisplayStringFormat getImageFormat(int width) {
return new ImageStringFormat(width);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class HTMLStringFormatSerializer extends JsonSerializer<HTMLStringFormat>

public static final String TYPE = "type";
public static final String VALUE_HTML = "html";
public static final String WIDTH = "width";

@Override
public void serialize(HTMLStringFormat value,
Expand All @@ -37,6 +38,9 @@ public void serialize(HTMLStringFormat value,
synchronized (value) {
jgen.writeStartObject();
jgen.writeObjectField(TYPE, VALUE_HTML);
if (value.getWidth() != null) {
jgen.writeObjectField(WIDTH, value.getWidth());
}
jgen.writeEndObject();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class ImageStringFormatSerializer extends JsonSerializer<ImageStringForma

public static final String TYPE = "type";
public static final String VALUE_IMAGE = "image";
public static final String WIDTH = "width";

@Override
public void serialize(ImageStringFormat value,
Expand All @@ -37,6 +38,9 @@ public void serialize(ImageStringFormat value,
synchronized (value) {
jgen.writeStartObject();
jgen.writeObjectField(TYPE, VALUE_IMAGE);
if (value.getWidth() != null) {
jgen.writeObjectField(WIDTH, value.getWidth());
}
jgen.writeEndObject();
}
}
Expand Down

0 comments on commit 0065909

Please sign in to comment.