Auto Column Sizing (#2778)

* add auto column sizing

* add break for performance

* update with new library
This commit is contained in:
Anthony Dresser
2019-01-08 13:05:53 -08:00
committed by GitHub
parent e31747d087
commit 954d0d954f
3 changed files with 82 additions and 7 deletions

View File

@@ -1,13 +1,16 @@
// Adapted from https://github.com/naresh-n/slickgrid-column-data-autosize/blob/master/src/slick.autocolumnsize.js
import { mixin, clone } from 'sql/base/common/objects';
import { isInDOM } from 'vs/base/browser/dom';
export interface IAutoColumnSizeOptions extends Slick.PluginOptions {
maxWidth?: number;
autoSizeOnRender?: boolean;
}
const defaultOptions: IAutoColumnSizeOptions = {
maxWidth: 200
maxWidth: 200,
autoSizeOnRender: false
};
export class AutoColumnSize<T> implements Slick.Plugin<T> {
@@ -15,6 +18,7 @@ export class AutoColumnSize<T> implements Slick.Plugin<T> {
private _$container: JQuery;
private _context: CanvasRenderingContext2D;
private _options: IAutoColumnSizeOptions;
private onPostEventHandler = new Slick.EventHandler();
constructor(options: IAutoColumnSizeOptions = defaultOptions) {
this._options = mixin(options, defaultOptions, false);
@@ -23,8 +27,12 @@ export class AutoColumnSize<T> implements Slick.Plugin<T> {
public init(grid: Slick.Grid<T>) {
this._grid = grid;
if (this._options.autoSizeOnRender) {
this.onPostEventHandler.subscribe(this._grid.onRendered, () => this.onPostRender());
}
this._$container = $(this._grid.getContainerNode());
this._$container.on('dblclick.autosize', '.slick-resizable-handle', e => this.reSizeColumn(e));
this._$container.on('dblclick.autosize', '.slick-resizable-handle', e => this.handleDoubleClick(e));
this._context = document.createElement('canvas').getContext('2d');
}
@@ -32,7 +40,66 @@ export class AutoColumnSize<T> implements Slick.Plugin<T> {
this._$container.off();
}
private reSizeColumn(e: JQuery.Event<HTMLElement, string>) {
private onPostRender() {
// this doesn't do anything if the grid isn't on the dom
if (!isInDOM(this._grid.getContainerNode())) {
return;
}
// since data can be async we want to only do this if we have the data to actual
// work on since we are measuring the physical length of data
let data = this._grid.getData();
let item = data.getItem(0);
if (item && Object.keys(item).length > 0) {
let hasValue = false;
for (let key in item) {
if (item.hasOwnProperty(key)) {
if (item[key]) {
hasValue = true;
break;
}
}
}
if (!hasValue) {
return;
}
} else {
return;
}
let headerColumnsQuery = $(this._grid.getContainerNode()).find('.slick-header-columns');
if (headerColumnsQuery && headerColumnsQuery.length) {
let headerColumns = headerColumnsQuery[0];
let origCols = this._grid.getColumns();
let allColumns = clone(origCols);
allColumns.forEach((col, index) => {
col.formatter = origCols[index].formatter;
col.asyncPostRender = origCols[index].asyncPostRender;
});
let change = false;
for (let i = 0; i <= headerColumns.children.length; i++) {
let headerEl = $(headerColumns.children.item(i));
let columnDef = headerEl.data('column');
if (columnDef) {
let headerWidth = this.getElementWidth(headerEl[0]);
let colIndex = this._grid.getColumnIndex(columnDef.id);
let column = allColumns[colIndex];
let autoSizeWidth = Math.max(headerWidth, this.getMaxColumnTextWidth(columnDef, colIndex)) + 1;
if (autoSizeWidth !== column.width) {
allColumns[colIndex].width = autoSizeWidth;
change = true;
}
}
}
if (change) {
this.onPostEventHandler.unsubscribeAll();
this._grid.setColumns(allColumns);
this._grid.onColumnsResized.notify();
}
}
}
private handleDoubleClick(e: JQuery.Event<HTMLElement, string>) {
let headerEl = $(e.currentTarget).closest('.slick-header-column');
let columnDef = headerEl.data('column');
@@ -43,6 +110,10 @@ export class AutoColumnSize<T> implements Slick.Plugin<T> {
e.preventDefault();
e.stopPropagation();
this.reSizeColumn(headerEl, columnDef);
}
private reSizeColumn(headerEl: JQuery, columnDef: Slick.Column<T>) {
let headerWidth = this.getElementWidth(headerEl[0]);
let colIndex = this._grid.getColumnIndex(columnDef.id);
let origCols = this._grid.getColumns();

View File

@@ -420,12 +420,12 @@ class GridTable<T> extends Disposable implements IView {
@IContextMenuService private contextMenuService: IContextMenuService,
@IInstantiationService private instantiationService: IInstantiationService,
@IEditorService private editorService: IEditorService,
@IUntitledEditorService private untitledEditorService: IUntitledEditorService
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
@IConfigurationService private configurationService: IConfigurationService
) {
super();
this.container.style.width = '100%';
this.container.style.height = '100%';
// this.container.style.marginBottom = BOTTOM_PADDING + 'px';
this.container.className = 'grid-panel';
this.columns = this.resultSet.columnInfo.map((c, i) => {
@@ -507,7 +507,7 @@ class GridTable<T> extends Disposable implements IView {
this.table = this._register(new Table(tableContainer, { dataProvider: this.dataProvider, columns: this.columns }, tableOptions));
this.table.setSelectionModel(this.selectionModel);
this.table.registerPlugin(new MouseWheelSupport());
this.table.registerPlugin(new AutoColumnSize());
this.table.registerPlugin(new AutoColumnSize({ autoSizeOnRender: this.configurationService.getValue('resultsGrid.autoSizeColumns') }));
this.table.registerPlugin(copyHandler);
this.table.registerPlugin(this.rowNumberColumn);
this.table.registerPlugin(new AdditionalKeyBindings());

View File

@@ -21,7 +21,6 @@ const resultsGridConfiguration: IConfigurationNode = {
type: 'object',
title: nls.localize('resultsGridConfigurationTitle', "Results Grid"),
overridable: true,
scope: ConfigurationScope.RESOURCE,
properties: {
'resultsGrid.fontFamily': {
type: 'string',
@@ -62,6 +61,11 @@ const resultsGridConfiguration: IConfigurationNode = {
],
default: RESULTS_GRID_DEFAULTS.cellPadding,
description: nls.localize('cellPadding', "Controls the cell padding in pixels")
},
'resultsGrid.autoSizeColumns': {
type: 'boolean',
default: false,
description: nls.localize('autoSizeColumns', "Auto size the columns width on inital results. Could have performance problems with large number of columns or large cells")
}
}
};