Skip to content

Commit c5c0e04

Browse files
use inferred table schema fields for the tabulator table column descriptors (#15)
1 parent 4cbf318 commit c5c0e04

File tree

3 files changed

+114
-50
lines changed

3 files changed

+114
-50
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "tabular-data-viewer",
33
"displayName": "Tabular Data Viewer 中",
44
"description": "Tabular Data Viewer provides fast DSV data loading and custom Table View 🀄 display for large .csv, .tsv and .tab data files via Tabulator table and Papa Parse CSV parser.",
5-
"version": "1.3.0",
5+
"version": "1.4.0",
66
"engines": {
77
"vscode": "^1.63.0"
88
},

src/views/tableView.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ export class TableView {
316316
command: 'refresh',
317317
fileName: this._fileInfo.fileName,
318318
documentUrl: this._fileInfo.fileUri.toString(),
319-
tableShema: this._tableSchema,
319+
tableSchema: this._tableSchema,
320320
totalRows: this._totalRows,
321321
tableData: initialDataRows
322322
});

web/scripts/tableView.js

Lines changed: 112 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ let loadedDataPage = 0;
2222
// table view settings
2323
const toolbarHeight = 40; // table view toolbar height offset
2424
const autoResize = true;
25-
const autoColumns = true;
25+
let autoColumns = true;
2626
const enableClipboard = true; // enable clipboard copy and paste
2727
const clipboardPasteAction = 'replace';
2828
const movableColumns = true;
@@ -103,7 +103,7 @@ window.addEventListener('message', event => {
103103
tableSchema = event.data.tableSchema;
104104
tableData = event.data.tableData;
105105
totalRows = event.data.totalRows;
106-
loadData(tableData, fileName);
106+
loadData(tableData, tableSchema);
107107
break;
108108
case 'addData':
109109
totalRows = event.data.totalRows;
@@ -164,13 +164,14 @@ function reloadData() {
164164
* Loads and displays table data.
165165
*
166166
* @param {*} tableData Data array to display in tabulator table.
167+
* @param {*} tableSchema Data table schema with inferred column fields info.
167168
*/
168-
function loadData(tableData) {
169+
function loadData(tableData, tableSchema) {
169170
console.log('tableView.loadData(): loading table data ...');
170171
logTableData(tableData);
171172
if (table === undefined) {
172173
// create table and load initial set of data rows
173-
createTable(tableData);
174+
createTable(tableData, tableSchema);
174175
}
175176
else {
176177
// add new data rows to existing tabulator table
@@ -183,49 +184,20 @@ function loadData(tableData) {
183184
* Creates new Tabulator table with initial set of data to display.
184185
*
185186
* @param {*} tableData Data array to display in tabulator table.
187+
* @param {*} tableSchema Data table schema with inferred column fields info.
186188
*/
187-
function createTable(tableData) {
189+
function createTable(tableData, tableSchema) {
188190
if (table === undefined) {
189-
table = new Tabulator('#table-container', {
190-
height: window.innerHeight - toolbarHeight,
191-
maxHeight: '100%',
192-
autoResize: autoResize,
193-
autoColumns: autoColumns,
194-
columnDefaults: {
195-
headerMenu: columnHeaderMenu
196-
},
197-
clipboard: enableClipboard, // enable clipboard copy and paste
198-
clipboardPasteAction: clipboardPasteAction,
199-
layout: 'fitDataStretch', // 'fitColumns',
200-
layoutColumnsOnNewData: true,
201-
movableColumns: movableColumns,
202-
movableRows: movableRows,
203-
selectable: selectableRows,
204-
reactiveData: reactiveData,
205-
data: tableData,
206-
pagination: pagination,
207-
paginationSize: paginationSize,
208-
paginationSizeSelector: pageSizes,
209-
rowContextMenu: rowContextMenu,
210-
renderVerticalBuffer: renderVerticalBuffer,
211-
debugInvalidOptions: debugInvalidOptions, // log invalid tabulator config warnings
212-
debugEventsExternal: debugEventsExternal,
213-
debugEventsInternal: debugEventsInternal,
214-
persistenceMode: 'local',
215-
persistenceID: fileName,
216-
// persistentLayout: true,
217-
persistence: {
218-
sort: true,
219-
filter: true,
220-
group: true,
221-
columns: true,
222-
},
223-
// add table setting save/restore handlers
224-
persistenceWriterFunc: (id, type, data) => saveTableSetting(id, type, data),
225-
persistenceReaderFunc: (id, type) => restoreTableSetting(id, type),
226-
// add table data download handler
227-
downloadReady: (fileContents, blob) => downloadData(fileContents, blob)
228-
});
191+
// create table columns array from table schema fields
192+
tableColumns = createTableColumns(tableSchema);
193+
if (tableColumns.length > 0) {
194+
// don't auto generate columns
195+
autoColumns = false;
196+
}
197+
198+
// create tabulator table instance for tabular data display
199+
const tableConfig = createTableConfig(tableColumns);
200+
table = new Tabulator('#table-container', tableConfig);
229201

230202
// update table settings after initial data rows load
231203
table.on('tableBuilt', onTableBuilt);
@@ -237,6 +209,98 @@ function createTable(tableData) {
237209
}
238210
}
239211

212+
/**
213+
* Creates table column descriptors from frictionless data table schema config.
214+
*
215+
* @see https://specs.frictionlessdata.io/table-schema/#descriptor
216+
*
217+
* @param {*} tableSchema Frictionless data table schema config.
218+
*/
219+
function createTableColumns(tableSchema) {
220+
const tableColumns = [];
221+
// Note: sometimes table rows are not parsed correctly
222+
// by the frictionless table schema infer() and returns only 1 field
223+
if (tableSchema && tableSchema.fields && tableSchema.fields.length > 1) {
224+
console.log('tableView.createTableColumns():tableSchema:', tableSchema.fields);
225+
tableSchema.fields.forEach(field => {
226+
// determine field sorter type
227+
let sorter = 'string';
228+
switch (field.type) {
229+
case 'integer':
230+
case 'number':
231+
sorter = 'number';
232+
break;
233+
// TODO: add more sorter types for dates, etc.
234+
}
235+
236+
// add new table column descriptor
237+
tableColumns.push({
238+
field: field.name,
239+
title: field.name,
240+
resizable: true,
241+
headerSort: true,
242+
sorter: sorter
243+
});
244+
});
245+
console.log('tableView.createTableColumns():columns:', tableColumns);
246+
return tableColumns;
247+
}
248+
}
249+
250+
/**
251+
* Creates Tabulator table config.
252+
*
253+
* @param {*} tableColumns Optional table column descriptors array.
254+
*/
255+
function createTableConfig(tableColumns) {
256+
let tableConfig = {
257+
height: window.innerHeight - toolbarHeight,
258+
maxHeight: '100%',
259+
autoResize: autoResize,
260+
autoColumns: autoColumns,
261+
columnDefaults: {
262+
headerMenu: columnHeaderMenu
263+
},
264+
clipboard: enableClipboard, // enable clipboard copy and paste
265+
clipboardPasteAction: clipboardPasteAction,
266+
layout: 'fitDataStretch', // 'fitColumns',
267+
layoutColumnsOnNewData: true,
268+
movableColumns: movableColumns,
269+
movableRows: movableRows,
270+
selectable: selectableRows,
271+
reactiveData: reactiveData,
272+
data: tableData,
273+
pagination: pagination,
274+
paginationSize: paginationSize,
275+
paginationSizeSelector: pageSizes,
276+
rowContextMenu: rowContextMenu,
277+
renderVerticalBuffer: renderVerticalBuffer,
278+
debugInvalidOptions: debugInvalidOptions, // log invalid tabulator config warnings
279+
debugEventsExternal: debugEventsExternal,
280+
debugEventsInternal: debugEventsInternal,
281+
persistenceMode: 'local',
282+
persistenceID: fileName,
283+
// persistentLayout: true,
284+
persistence: {
285+
sort: true,
286+
filter: true,
287+
group: true,
288+
columns: true,
289+
},
290+
// add table setting save/restore handlers
291+
persistenceWriterFunc: (id, type, data) => saveTableSetting(id, type, data),
292+
persistenceReaderFunc: (id, type) => restoreTableSetting(id, type),
293+
// add table data download handler
294+
downloadReady: (fileContents, blob) => downloadData(fileContents, blob)
295+
};
296+
297+
if (tableColumns && tableColumns.length > 0) {
298+
tableConfig.autoColumns = false;
299+
tableConfig.columns = tableColumns;
300+
}
301+
return tableConfig;
302+
}
303+
240304
/**
241305
* Updates Tabulator table after initial set of data rows is loaded.
242306
*/
@@ -246,7 +310,7 @@ function onTableBuilt () {
246310

247311
// get table columns for debug
248312
const columns = table.getColumns();
249-
// console.log('tableView.columns:', columns);
313+
console.log('tableView.onTableBuilt():columns:', columns);
250314

251315
// add row selection column
252316
// TODO: make this optional via tabular data viewer config setting
@@ -360,7 +424,7 @@ function clearTable(table) {
360424
function saveTableSetting(id, type, data) {
361425
// create table setting key
362426
const tableSettingKey = `${id}-${type}`;
363-
// console.log(`tableSetting:${tableSettingKey}:`, data);
427+
console.log(`tableView.saveTableSetting(): ${tableSettingKey}=`, data);
364428

365429
// save table settings in local storage for now
366430
localStorage.setItem(tableSettingKey, JSON.stringify(data));
@@ -380,7 +444,7 @@ function restoreTableSetting(id, type) {
380444
// try to get requested table setting from local storage
381445
const tableSetting = localStorage.getItem(tableSettingKey);
382446
if (tableSetting) {
383-
// console.log(`tableSetting:${tableSettingKey}:`, tableSetting);
447+
console.log(`tableView.restoreTableSetting(): ${tableSettingKey}=`, tableSetting);
384448
}
385449
return tableSetting ? JSON.parse(tableSetting) : false;
386450
}

0 commit comments

Comments
 (0)