diff --git a/admin-lehrer/components/ocr-kombi/StepAnsicht.tsx b/admin-lehrer/components/ocr-kombi/StepAnsicht.tsx index 841a4e1..5fc1520 100644 --- a/admin-lehrer/components/ocr-kombi/StepAnsicht.tsx +++ b/admin-lehrer/components/ocr-kombi/StepAnsicht.tsx @@ -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 (
{/* 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 (
`${(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 (