StepAnsicht: dominant row height for content + proportional box rows
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 33s
CI / test-go-edu-search (push) Successful in 43s
CI / test-python-klausur (push) Failing after 2m35s
CI / test-python-agent-core (push) Successful in 34s
CI / test-nodejs-website (push) Successful in 31s
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 33s
CI / test-go-edu-search (push) Successful in 43s
CI / test-python-klausur (push) Failing after 2m35s
CI / test-python-agent-core (push) Successful in 34s
CI / test-nodejs-website (push) Successful in 31s
Content sections: use dominant (median) row height from all content rows instead of per-section average. This ensures uniform row height above and below boxes (the standard case on textbook pages). Box sections: distribute height proportionally by text line count per row. A header (1 line) gets 1/7 of box height, a bullet with 3 lines gets 3/7. Fixes Box 2 where row 3 was cut off because even distribution didn't account for multi-line cells. Removed overflow:hidden from box container to prevent clipping. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -173,6 +173,22 @@ export function StepAnsicht({ sessionId, onNext }: StepAnsichtProps) {
|
||||
const panelHeight = imgH * scale
|
||||
const contentZone = grid.zones.find((z) => z.zone_type === 'content')
|
||||
|
||||
// Dominant row height: median of row-to-row spacings (excluding box-gap jumps)
|
||||
const dominantRowH = useMemo(() => {
|
||||
const cz = grid.zones.find((z) => z.zone_type === 'content')
|
||||
if (!cz || cz.rows.length < 2) return 47
|
||||
const spacings: number[] = []
|
||||
for (let i = 0; i < cz.rows.length - 1; i++) {
|
||||
const y1 = cz.rows[i].y_min_px ?? (cz.rows[i] as any).y_min ?? 0
|
||||
const y2 = cz.rows[i + 1].y_min_px ?? (cz.rows[i + 1] as any).y_min ?? 0
|
||||
const d = y2 - y1
|
||||
if (d > 0 && d < 100) spacings.push(d)
|
||||
}
|
||||
if (spacings.length === 0) return 47
|
||||
spacings.sort((a, b) => a - b)
|
||||
return spacings[Math.floor(spacings.length / 2)]
|
||||
}, [grid])
|
||||
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
{/* Header */}
|
||||
@@ -237,7 +253,7 @@ export function StepAnsicht({ sessionId, onNext }: StepAnsichtProps) {
|
||||
rows={sec.rows}
|
||||
yStart={sec.yStart}
|
||||
scale={scale}
|
||||
avgRowH={sec.avgRowH}
|
||||
avgRowH={dominantRowH}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -375,13 +391,19 @@ function BoxSectionRenderer({ zone, scale, avgRowH }: {
|
||||
const colScale = totalColW > 0 ? width / totalColW : 1
|
||||
const numCols = zone.columns.length
|
||||
|
||||
// Evenly distribute rows within the box
|
||||
const numRows = zone.rows.length
|
||||
const evenRowH = numRows > 0 ? height / numRows : rowH
|
||||
// Distribute box height proportionally by text line count per row
|
||||
const rowLineCounts = zone.rows.map((row) => {
|
||||
const maxLines = Math.max(1, ...zone.cells
|
||||
.filter((c) => c.row_index === row.index)
|
||||
.map((c) => (c.text ?? '').split('\n').length))
|
||||
return maxLines
|
||||
})
|
||||
const totalLines = rowLineCounts.reduce((s, n) => s + n, 0)
|
||||
const lineUnitH = totalLines > 0 ? height / totalLines : height
|
||||
|
||||
return (
|
||||
<div
|
||||
className="absolute overflow-hidden"
|
||||
className="absolute"
|
||||
style={{
|
||||
left: `${left}px`,
|
||||
top: `${top}px`,
|
||||
@@ -395,14 +417,12 @@ function BoxSectionRenderer({ zone, scale, avgRowH }: {
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: colWidths.map((w) => `${(w * colScale).toFixed(1)}px`).join(' ') }}>
|
||||
{zone.rows.map((row) => {
|
||||
{zone.rows.map((row, rowIdx) => {
|
||||
const isSpanning = zone.cells.some((c) => c.row_index === row.index && c.col_type === 'spanning_header')
|
||||
|
||||
// Multi-line height
|
||||
const maxLines = Math.max(1, ...zone.cells
|
||||
.filter((c) => c.row_index === row.index)
|
||||
.map((c) => (c.text ?? '').split('\n').length))
|
||||
const cellRowH = evenRowH * (maxLines > 1 ? maxLines * 0.7 : 1)
|
||||
// Height proportional to text line count
|
||||
const rowLines = rowLineCounts[rowIdx] || 1
|
||||
const cellRowH = lineUnitH * rowLines
|
||||
|
||||
return (
|
||||
<div key={row.index} style={{ display: 'contents' }}>
|
||||
|
||||
Reference in New Issue
Block a user