mirror of
http://172.20.10.11:3000/gitadmin/INSIGHT-MVP.git
synced 2026-06-25 00:16:41 +02:00
fix: Timeline-Linie am Anfang der nächsten Iteration zeichnen (Deferred-Draw)
Vorherige Ansätze berechneten die Ziel-Header-Höhe am Ende des Eintrags neu (fehleranfällig durch doppelte Font-State-Operationen). Neuer Ansatz: Linie für Entry i wird am ANFANG von Entry i+1 gezeichnet, BEVOR der Seitenumbruch-Check läuft — mit demselben headerH der bereits berechnet wurde. Eine einzige Bedingung entscheidet konsistent ob Linie gezeichnet wird UND ob ein Seitenumbruch folgt, ohne Redundanz oder State-Probleme. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fb57f5a4dc
commit
a7cf59ae20
1 changed files with 22 additions and 19 deletions
|
|
@ -491,6 +491,11 @@ export class ProfileExportService {
|
||||||
const contentX = rightColX + 18;
|
const contentX = rightColX + 18;
|
||||||
const contentWidth = rightColWidth - 18;
|
const contentWidth = rightColWidth - 18;
|
||||||
|
|
||||||
|
// Vorgemerkter Linien-Start vom vorherigen Eintrag
|
||||||
|
// (wird am Anfang der nächsten Iteration gezeichnet, wenn kein Seitenumbruch nötig ist)
|
||||||
|
let pendingLineStartY: number | null = null;
|
||||||
|
let pendingLineEndY: number | null = null;
|
||||||
|
|
||||||
for (let i = 0; i < profile.projects.length; i++) {
|
for (let i = 0; i < profile.projects.length; i++) {
|
||||||
const proj = profile.projects[i];
|
const proj = profile.projects[i];
|
||||||
|
|
||||||
|
|
@ -507,6 +512,19 @@ export class ProfileExportService {
|
||||||
const companyH = companyLine ? doc.heightOfString(companyLine, { width: contentWidth }) + 2 : 0;
|
const companyH = companyLine ? doc.heightOfString(companyLine, { width: contentWidth }) + 2 : 0;
|
||||||
const headerH = 14 + roleH + 2 + companyH + 8; // Datum + Rolle + Firma + Puffer
|
const headerH = 14 + roleH + 2 + companyH + 8; // Datum + Rolle + Firma + Puffer
|
||||||
|
|
||||||
|
// Linie des vorherigen Eintrags zeichnen — JETZT, bevor der Seitenumbruch-Check läuft.
|
||||||
|
// Nur wenn dieser Eintrag auf derselben Seite bleibt (kein Seitenumbruch nötig),
|
||||||
|
// sind Quell-Dot und Ziel-Dot auf derselben Seite → Linie korrekt.
|
||||||
|
if (pendingLineStartY !== null && pendingLineEndY !== null) {
|
||||||
|
if (yRight + headerH <= pageBottom) {
|
||||||
|
doc.moveTo(timelineX, pendingLineStartY + 8)
|
||||||
|
.lineTo(timelineX, pendingLineEndY)
|
||||||
|
.strokeColor(accentColor).lineWidth(1).stroke();
|
||||||
|
}
|
||||||
|
pendingLineStartY = null;
|
||||||
|
pendingLineEndY = null;
|
||||||
|
}
|
||||||
|
|
||||||
// Seitenumbruch wenn Header nicht mehr passt
|
// Seitenumbruch wenn Header nicht mehr passt
|
||||||
if (yRight + headerH > pageBottom) {
|
if (yRight + headerH > pageBottom) {
|
||||||
doc.addPage();
|
doc.addPage();
|
||||||
|
|
@ -567,25 +585,10 @@ export class ProfileExportService {
|
||||||
|
|
||||||
yRight += 12;
|
yRight += 12;
|
||||||
|
|
||||||
// Timeline-Linie: nur zeichnen wenn kein Seitenumbruch im Eintrag
|
// Linie für nächste Iteration vormerken — nur wenn kein Seitenumbruch innerhalb des Eintrags
|
||||||
// UND der nächste Eintrag noch auf dieser Seite passt (exakte Header-Höhe prüfen)
|
if (!pageBreakOccurred) {
|
||||||
if (i < profile.projects.length - 1 && !pageBreakOccurred) {
|
pendingLineStartY = entryStartY;
|
||||||
const nextProj = profile.projects[i + 1];
|
pendingLineEndY = yRight - 4;
|
||||||
const nextRoleText = this.sanitizePdfText(nextProj.role);
|
|
||||||
const nextCompanyLine = nextProj.company
|
|
||||||
? this.sanitizePdfText([nextProj.company, nextProj.industry].filter(Boolean).join(' \u00b7 '))
|
|
||||||
: '';
|
|
||||||
doc.font('Helvetica-Bold').fontSize(10);
|
|
||||||
const nextRoleH = doc.heightOfString(nextRoleText, { width: contentWidth });
|
|
||||||
doc.fontSize(9);
|
|
||||||
const nextCompanyH = nextCompanyLine
|
|
||||||
? doc.heightOfString(nextCompanyLine, { width: contentWidth }) + 2
|
|
||||||
: 0;
|
|
||||||
const nextHeaderH = 14 + nextRoleH + 2 + nextCompanyH + 8;
|
|
||||||
if (yRight + nextHeaderH <= pageBottom) {
|
|
||||||
doc.moveTo(timelineX, entryStartY + 8).lineTo(timelineX, yRight - 4)
|
|
||||||
.strokeColor(accentColor).lineWidth(1).stroke();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue