Put a floor under the row-label columns
Loading a saved layout brought them back a few pixels wide, needing to be dragged open by hand. Restoring resets the widths, and the row-header columns are then sized from their header — which for row headers is a blank corner cell — so they measure as empty. A minimum rather than a fit. Fitting to content is the other extreme: each group_by level is its own column, so the first widens to its longest label and shoves the second rightwards, which is the spacing that read worse than the default. 130px leaves a reasonable default alone and only intervenes where a column came back unusable; anything already wider, whether dragged or recorded in a layout, is untouched. Applied after the initial load and after a layout restore — the two places that reset widths. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a9062c398c
commit
4045d336c4
@ -811,6 +811,7 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
|
|||||||
// column list.
|
// column list.
|
||||||
try {
|
try {
|
||||||
await syncOrderExpressions()
|
await syncOrderExpressions()
|
||||||
|
await ensureRowLabelWidth()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Its own try covers only restore(); save() and the builders sit outside
|
// Its own try covers only restore(); save() and the builders sit outside
|
||||||
// it, and a throw there would abort the rest of initViewer silently.
|
// it, and a throw there would abort the rest of initViewer silently.
|
||||||
@ -1085,6 +1086,40 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A floor under the row-label columns, not a fit.
|
||||||
|
//
|
||||||
|
// Restoring a layout resets the widths, and the row-header columns are then
|
||||||
|
// sized from their *header* — which for row headers is a blank corner cell —
|
||||||
|
// so they come back a few pixels wide and have to be dragged open by hand.
|
||||||
|
// Fitting them to content is the other extreme: each group_by level is its own
|
||||||
|
// column, so the first widens to its longest label and shoves the second
|
||||||
|
// rightwards.
|
||||||
|
//
|
||||||
|
// A minimum leaves the default spacing alone where it is already reasonable and
|
||||||
|
// only intervenes where a column came back unusably narrow. Anything already
|
||||||
|
// wider — set by dragging, or recorded in a layout — is untouched.
|
||||||
|
const MIN_ROW_LABEL_W = 130
|
||||||
|
|
||||||
|
async function ensureRowLabelWidth() {
|
||||||
|
const grid = (await viewerRef.current?.getPlugin())?.regular_table
|
||||||
|
if (!grid?.saveColumnSizes) return
|
||||||
|
const idxs = new Set()
|
||||||
|
for (const cell of grid.querySelectorAll('tbody th')) {
|
||||||
|
const m = [...cell.classList].map(c => /^rt-col-(\d+)$/.exec(c)).find(Boolean)
|
||||||
|
if (m) idxs.add(Number(m[1]))
|
||||||
|
}
|
||||||
|
if (idxs.size === 0) return
|
||||||
|
|
||||||
|
const sizes = { ...grid.saveColumnSizes() }
|
||||||
|
let changed = false
|
||||||
|
for (const idx of idxs) {
|
||||||
|
if ((sizes[idx] ?? 0) < MIN_ROW_LABEL_W) { sizes[idx] = MIN_ROW_LABEL_W; changed = true }
|
||||||
|
}
|
||||||
|
if (!changed) return
|
||||||
|
grid.restoreColumnSizes(sizes)
|
||||||
|
await grid.draw({ invalid_columns: true })
|
||||||
|
}
|
||||||
|
|
||||||
// Pin the row-label columns wide enough for the labels they show.
|
// Pin the row-label columns wide enough for the labels they show.
|
||||||
//
|
//
|
||||||
// Measured with a canvas rather than the DOM: the cell is clipped, so reading
|
// Measured with a canvas rather than the DOM: the cell is clipped, so reading
|
||||||
@ -1336,6 +1371,7 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
|
|||||||
// back. Re-applied after every restore that comes from a saved config, which
|
// back. Re-applied after every restore that comes from a saved config, which
|
||||||
// is the general form of the fix initViewer already needed.
|
// is the general form of the fix initViewer already needed.
|
||||||
await syncOrderExpressions()
|
await syncOrderExpressions()
|
||||||
|
await ensureRowLabelWidth()
|
||||||
|
|
||||||
setActiveLayoutId(layout.id)
|
setActiveLayoutId(layout.id)
|
||||||
// After the sync, so the persisted copy carries the expressions too.
|
// After the sync, so the persisted copy carries the expressions too.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user