diff --git a/README.md b/README.md index 14b0f3f..2a84be4 100644 --- a/README.md +++ b/README.md @@ -376,6 +376,16 @@ field will accompany the metadata records returned by `regular-table`'s } ``` +### Rendering Options + +There are some additional values which can be configured for specialty use: + +* `column_header_merge_depth: number` configures the number of rows to include + from `colspan` merging. This defaults to `header_length - 1`. +* `row_height: number` configures the pixel height of a row for + virtual scrolling calculation. This is typically auto-detected from the DOM, + but can be overridden if needed. + ### `async` Data Models With an `async` data model, it's easy to serve `getDataSlice()` remotely from diff --git a/src/js/scroll_panel.js b/src/js/scroll_panel.js index 13c8694..5315735 100644 --- a/src/js/scroll_panel.js +++ b/src/js/scroll_panel.js @@ -388,7 +388,7 @@ export class RegularVirtualTableViewModel extends HTMLElement { async function internal_draw(options) { const __debug_start_time__ = DEBUG && performance.now(); const { invalid_viewport = true, preserve_width = false } = options; - const { num_columns, num_rows } = await this._view_cache.view(0, 0, 0, 0); + const { num_columns, num_rows, row_height } = await this._view_cache.view(0, 0, 0, 0); this._container_size = { width: this._virtual_mode === "none" || this._virtual_mode === "vertical" ? Infinity : this._table_clip.clientWidth, height: this._virtual_mode === "none" || this._virtual_mode === "horizontal" ? Infinity : this._table_clip.clientHeight, @@ -430,7 +430,7 @@ async function internal_draw(options) { this._invalidated = false; } - this.table_model.autosize_cells(autosize_cells); + this.table_model.autosize_cells(autosize_cells, row_height); this.table_model.header.reset_header_cache(); if (!preserve_width) { this._update_virtual_panel_width(this._invalid_schema || invalid_column, num_columns); diff --git a/src/js/table.js b/src/js/table.js index 954dbef..d33f7cc 100644 --- a/src/js/table.js +++ b/src/js/table.js @@ -53,11 +53,11 @@ export class RegularTableViewModel { * @param {*} {columns, column_pivots} * @memberof RegularTableViewModel */ - autosize_cells(last_cells) { + autosize_cells(last_cells, override_row_height) { while (last_cells.length > 0) { const [cell, metadata] = last_cells.pop(); const box = cell.getBoundingClientRect(); - this._column_sizes.row_height = Math.max(10, Math.min(this._column_sizes.row_height || box.height, box.height)); + this._column_sizes.row_height = override_row_height || Math.max(10, Math.min(this._column_sizes.row_height || box.height, box.height)); this._column_sizes.indices[metadata.size_key] = box.width; const is_override = this._column_sizes.override[metadata.size_key] !== undefined; if (box.width && !is_override) { @@ -73,7 +73,7 @@ export class RegularTableViewModel { async *draw(container_size, view_cache, selected_id, preserve_width, viewport, num_columns) { const { width: container_width, height: container_height } = container_size; const { view, config } = view_cache; - let { data, row_headers, column_headers, metadata: data_listener_metadata } = await view( + let { data, row_headers, column_headers, metadata: data_listener_metadata, column_header_merge_depth } = await view( Math.floor(viewport.start_col), Math.floor(viewport.start_row), Math.ceil(viewport.end_col), @@ -126,7 +126,7 @@ export class RegularTableViewModel { cont_body = this.body.draw(container_height, column_state, { ...view_state, x0: 0 }, true, undefined, undefined, size_key); const cont_heads = []; for (let i = 0; i < view_cache.config.row_pivots.length; i++) { - const header = this.header.draw(column_name, Array(view_cache.config.column_pivots.length).fill(""), 1, undefined, i, x0, i); + const header = this.header.draw(column_name, Array(view_cache.config.column_pivots.length).fill(""), 1, undefined, i, x0, i, column_header_merge_depth); if (!!header) { cont_heads.push(header); } @@ -182,6 +182,10 @@ export class RegularTableViewModel { yield undefined; const new_col = await new_col_req; + if (typeof new_col.column_header_merge_depth !== "undefined") { + column_header_merge_depth = new_col.column_header_merge_depth; + } + if (new_col.data.length === 0) { // The viewport is size 0, first the estimate, then the // first-pass render, so really actually abort now. @@ -216,7 +220,7 @@ export class RegularTableViewModel { const x = dcidx + x0; const size_key = _virtual_x + Math.floor(x0); - const cont_head = this.header.draw(undefined, column_name, undefined, x, size_key, x0, _virtual_x); + const cont_head = this.header.draw(undefined, column_name, undefined, x, size_key, x0, _virtual_x, column_header_merge_depth); cont_body = this.body.draw(container_height, column_state, view_state, false, x, x0, size_key); first_col = false; if (!preserve_width) { diff --git a/src/js/thead.js b/src/js/thead.js index db45a78..f6147a0 100644 --- a/src/js/thead.js +++ b/src/js/thead.js @@ -84,14 +84,16 @@ export class RegularHeaderViewModel extends ViewModel { return this._get_cell("TH", this.num_rows() - 1, cidx); } - draw(alias, parts, colspan, x, size_key, x0, _virtual_x) { + draw(alias, parts, colspan, x, size_key, x0, _virtual_x, column_header_merge_depth) { const header_levels = parts?.length; //config.column_pivots.length + 1; if (header_levels === 0) return; let th, metadata, column_name; + column_header_merge_depth = typeof column_header_merge_depth === "undefined" ? header_levels - 1 : column_header_merge_depth; for (let d = 0; d < header_levels; d++) { column_name = parts[d] ? parts[d] : ""; this._offset_cache[d] = this._offset_cache[d] || 0; - if (d < header_levels - 1) { + + if (d < column_header_merge_depth) { if (this._group_header_cache?.[d]?.[0]?.value === column_name) { th = this._group_header_cache[d][1]; this._group_header_cache[d][2] += 1;