fix: Abhängigkeits-Kanten laufen hinter den Knoten (D41-Nachtrag 2)
Die Basis-Kanten lagen schon richtig; „drüber gemalt" wurde allein die Hervorhebung des ausgewählten Knotens (`svg.dep-front`, z-index 4). Eine durchgezogene Linie quer über einen fremden Knoten durchstreicht dessen Titel — und beim Tippen wechselt die Hervorhebung mit jeder Zeile. `dep-front` entfällt; hervorgehobene Kanten hängen zuletzt in derselben hinteren Ebene, liegen damit über den übrigen Kanten und unter jedem Knoten. Export und Druck waren nie betroffen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6881475193
commit
6d58164577
@@ -19,6 +19,7 @@ reverse.
|
||||
|
||||
## 2026-08-24
|
||||
|
||||
- Dependency links now run behind every node, highlighted ones included — no more lines struck through node titles
|
||||
- Fix: the line to an only child was torn where the child does not sit centred in its cell
|
||||
- An optional node (`+`) joins the cheapest path while it is being worked on — started work is the open front
|
||||
- Fix: a started alternative lost its `|`/`=` group to an untouched cheaper one, although the choice was already made
|
||||
|
||||
@@ -2805,6 +2805,61 @@ Zweiter Schritt derselben Rückmeldung: Auch die **Pfeilspitze** ist jetzt
|
||||
Dreiecks — das Dreieck stach als einziger satter Fleck aus der gepunkteten
|
||||
Linie heraus. Die Hervorhebung bekommt denselben Winkel in Tinte.
|
||||
|
||||
**Nachtrag 2 — auch die hervorgehobenen Kanten laufen hinter den Knoten
|
||||
durch.** Gemeldet: „die Abhängigkeits-Pfeile sollen im Hintergrund durch andere
|
||||
Knoten durchlaufen, derzeit werden die Pfeile drüber gemalt."
|
||||
|
||||
**Nachgemessen war es genau eine Hälfte.** Die **Basis**-Kanten lagen schon
|
||||
richtig: In einem eigens gebauten Fall — eine Kante quer über drei breite
|
||||
Knoten hinweg, zur Sichtbarkeit magenta und 6 px dick gefärbt — erschien sie
|
||||
**nur in den Lücken** zwischen den Knoten, nie über deren Fläche. Sichtbar
|
||||
„drüber" war allein die **Hervorhebung**: Steht der Cursor auf einer Zeile mit
|
||||
`:#…`, wandern deren Kanten auf `svg.dep-front` (`z-index:4`) und laufen als
|
||||
durchgezogene Tinte-Linie mitten durch die Beschriftung der Knoten dazwischen.
|
||||
|
||||
**Damit fällt die Begründung des Haupttextes** — „vorn dürfen sie den Baum
|
||||
überlagern, denn die Hervorhebung ist flüchtig und gerade angefragt". Der
|
||||
Einwand des Nutzers wiegt schwerer, und er ist derselbe, aus dem die
|
||||
Basis-Kanten von Anfang an hinten liegen: Eine Linie quer über einen fremden
|
||||
Knoten **durchstreicht dessen Titel**. Das trifft ausgerechnet die Knoten, die
|
||||
mit der Sache nichts zu tun haben — die Kante sagt etwas über ihre beiden
|
||||
Enden, nicht über das, was zufällig dazwischen steht. „Flüchtig" ist dabei kein
|
||||
Freibrief, sondern eher das Gegenteil: Beim Tippen wechselt die Hervorhebung
|
||||
mit jeder Zeile, der Schaden ist also nicht selten, sondern dauernd.
|
||||
|
||||
**Eine Ebene statt zweier.** `svg.dep-front` entfällt; hervorgehobene Kanten
|
||||
werden **zuletzt** in dieselbe hintere Ebene gehängt und liegen dadurch über
|
||||
den übrigen Kanten, aber unter jedem Knoten. Die Unterscheidung trägt weiterhin
|
||||
das Aussehen (durchgezogen in Tinte gegen gepunktet in Blassgrau), und das ist
|
||||
genug: Sie war nie an der Ebene festgemacht, sondern nur zusätzlich betont.
|
||||
|
||||
**Der Preis, benannt:** In einer dichten Reihe breiter Knoten bleibt von der
|
||||
hervorgehobenen Kante wenig mehr als ein Stück in jeder Lücke. Zu **finden**
|
||||
ist ihr Ziel trotzdem, denn die **Pfeilspitze sitzt auf der Knotenkante** und
|
||||
liegt damit außerhalb jedes Kastens. Für den Fall, dass das eines Tages nicht
|
||||
reicht, steht das Hausmittel bereit: eine **abgetönte Kopie davor**, wie sie
|
||||
der günstigste Pfad seit D18 für genau dieses Problem hat („deutet den Verlauf
|
||||
beim Durchschreiten eines Knotens nur schwach an"). Bewusst nicht vorab
|
||||
gebaut — gefragt war, dass die Kanten hinten laufen, und eine zweite Ebene
|
||||
zurückzuholen, um die erste zu erklären, ist der falsche Anfang.
|
||||
|
||||
**Was dadurch obsolet wird:** D25-Nachtrag 3 gab `.dep-front` seinen
|
||||
`z-index:4`, weil die hervorgehobenen Kanten sonst unter dem hervorgehobenen
|
||||
Knoten endeten („vorn heißt vorn"). Das war für eine vordere Ebene richtig und
|
||||
ist mit ihr weggefallen; für `.cheap-front` (`z-index:5`) gilt es unverändert
|
||||
weiter — der Stationspunkt gehört über den Knoten.
|
||||
|
||||
**Export und Druck waren nie betroffen:** `diagramToSvg()` zeichnet die
|
||||
Basis-Kanten in Schritt 1a, also vor den Knoten, und die Hervorhebung gar nicht
|
||||
(Interaktion, siehe oben). Das Bild auf dem Schirm zieht damit nach, statt dass
|
||||
etwas Neues entsteht — derselbe Befund wie bei D46-Nachtrag.
|
||||
|
||||
**Nachgemessen** nach der Änderung, an demselben Fall: `svg.dep-front` gibt es
|
||||
nicht mehr, alle Kanten hängen in `svg.dep-back` als erstem Kind von `#out`,
|
||||
die hervorgehobene als letztes Element darin. Die Tinte-Linie ist in den Lücken
|
||||
zu sehen und über den Knoten nicht mehr; die Pfeilspitze steht unverändert an
|
||||
der Kante des gebrauchten Knotens.
|
||||
|
||||
## D42 — Closure-Pfad: erschöpfend über die gekoppelten Gruppen, gierig nur benannt
|
||||
Die letzte Baustelle aus D34: Mit Abhängigkeiten zählt der günstigste Pfad
|
||||
nicht mehr den gewählten Teilbaum, sondern die **Hülle** — jeder nötige Knoten
|
||||
|
||||
+6
-2
@@ -961,9 +961,13 @@ eigenen Zeichenebene **hinter** den Knoten, mit einer kleinen **offenen
|
||||
Pfeilspitze auf das Gebrauchte** („braucht“-Richtung; ein Winkel aus zwei
|
||||
Strichen, kein gefülltes Dreieck). Der Baum trägt weiterhin die Hauptaussage.
|
||||
|
||||
- **Alle** Kanten laufen **hinter** den Knoten durch, auch die hervorgehobenen:
|
||||
sichtbar in den Lücken, verdeckt vom Knoten selbst. Der Baum bleibt damit
|
||||
lesbar — eine Kante, die quer über fremde Knoten hinwegläuft, durchstreicht
|
||||
deren Beschriftung.
|
||||
- Die Kanten des **ausgewählten** Knotens — Tastaturfokus im Diagramm, sonst
|
||||
der Knoten der Cursor-Zeile — liegen hervorgehoben in Tinte auf einer
|
||||
vorderen Ebene, ein- wie ausgehende.
|
||||
der Knoten der Cursor-Zeile — sind in Tinte hervorgehoben, ein- wie
|
||||
ausgehende; sie liegen über den übrigen Kanten, aber unter jedem Knoten.
|
||||
- Kanten zu gerade nicht sichtbaren Knoten (eingeklappt §9, verworfen
|
||||
ausgeblendet §4) entfallen; bei doppelter ID zielt die Kante auf die erste
|
||||
Vergabe (D36/D39).
|
||||
|
||||
+10
-5
@@ -426,18 +426,23 @@ function drawDepLinks(){
|
||||
cx:(r.left - outRect.left + r.width/2)/z,
|
||||
cy:(r.top - outRect.top + r.height/2)/z}; };
|
||||
const w = outRect.width/z, h = outRect.height/z;
|
||||
/* EINE Ebene, und die liegt hinter den Knoten (D41-Nachtrag 2): Die Kanten
|
||||
laufen durch fremde Knoten hindurch, statt über sie hinweg. Die
|
||||
hervorgehobenen werden zuletzt eingehängt — damit liegen sie über den
|
||||
übrigen Kanten, aber weiterhin unter jedem Knoten. */
|
||||
const back = overlaySvg('dep-overlay dep-back', w, h);
|
||||
const front = overlaySvg('dep-overlay dep-front', w, h);
|
||||
const hi = activeDepNode();
|
||||
const hoch = [];
|
||||
for(const [from, to] of edges){
|
||||
const hl = hi && (from === hi || to === hi);
|
||||
const c = depCurve(rect(from), rect(to));
|
||||
const layer = hl ? front : back;
|
||||
layer.appendChild(svgEl('path', {class:'dep-edge' + (hl ? ' hl' : ''), d:c.d}));
|
||||
layer.appendChild(svgEl('path', {class:'dep-arrow' + (hl ? ' hl' : ''), d:depArrow(c.end, c.ctrl)}));
|
||||
const kante = svgEl('path', {class:'dep-edge' + (hl ? ' hl' : ''), d:c.d});
|
||||
const spitze = svgEl('path', {class:'dep-arrow' + (hl ? ' hl' : ''), d:depArrow(c.end, c.ctrl)});
|
||||
if(hl) hoch.push(kante, spitze);
|
||||
else { back.appendChild(kante); back.appendChild(spitze); }
|
||||
}
|
||||
for(const p of hoch) back.appendChild(p);
|
||||
out.insertBefore(back, out.firstChild);
|
||||
if(front.childNodes.length) out.appendChild(front);
|
||||
}
|
||||
/* Hervorhebung folgt dem Fokus; die Basis-Kanten selbst ändern sich nicht. */
|
||||
out.addEventListener('focusin', drawDepLinks);
|
||||
|
||||
@@ -918,12 +918,12 @@
|
||||
Blättern zeigen, welche Knoten wirklich auf dem Pfad enden — durchquerte
|
||||
Fremdknoten tragen keinen Punkt. Reihenfolge im DOM steuert vorn/hinten. */
|
||||
.cheap-overlay{position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
|
||||
/* Die VORDEREN Ebenen müssen über JEDEN Knoten — auch über die, die sich
|
||||
selbst eine Stapelposition nehmen: Cursor-Zeile (`z-index:3`, D25),
|
||||
/* Die VORDERE Ebene muss über JEDEN Knoten — auch über die, die sich selbst
|
||||
eine Stapelposition nehmen: Cursor-Zeile (`z-index:3`, D25),
|
||||
Strahlenkränze (`z-index:2`, D28/D32). Ohne das deckt ausgerechnet der
|
||||
hervorgehobene Knoten seinen eigenen Stationspunkt zu, und die
|
||||
hervorgehobenen Abhängigkeits-Kanten enden unter ihm. „Vorn" heißt vorn. */
|
||||
.dep-overlay.dep-front{z-index:4}
|
||||
hervorgehobene Knoten seinen eigenen Stationspunkt zu. „Vorn" heißt vorn.
|
||||
(Die Abhängigkeits-Kanten hatten aus demselben Grund einmal `.dep-front`
|
||||
mit `z-index:4`; sie liegen jetzt vollständig hinten — D41-Nachtrag 2.) */
|
||||
.cheap-overlay.cheap-front{z-index:5}
|
||||
/* Querverbindungen der Abhängigkeiten (SPEC §9, D41): blassgrau GEPUNKTET
|
||||
und gekrümmt — Punktierung und Krümmung unterscheiden sie doppelt von den
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":"4.1.11","results":[[":frontend/tests/render.test.js",{"duration":98.47688799999997,"failed":false}],[":frontend/tests/focusmark.test.js",{"duration":35.79027499999995,"failed":false}],[":frontend/tests/fold.test.js",{"duration":41.154863999999975,"failed":false}],[":frontend/tests/optional.test.js",{"duration":35.42018200000001,"failed":false}],[":frontend/tests/parser.test.js",{"duration":33.422897999999975,"failed":false}],[":frontend/tests/xor.test.js",{"duration":52.44134100000002,"failed":false}],[":frontend/tests/desc.test.js",{"duration":31.248038000000008,"failed":false}],[":frontend/tests/deps.test.js",{"duration":31.736107000000004,"failed":false}],[":frontend/tests/closure.test.js",{"duration":24.077101999999968,"failed":false}],[":frontend/tests/effective.test.js",{"duration":27.93907200000001,"failed":false}],[":frontend/tests/ids.test.js",{"duration":25.51923499999998,"failed":false}],[":frontend/tests/remote.test.js",{"duration":20.999619999999993,"failed":false}],[":frontend/tests/warnings.test.js",{"duration":9.594386999999983,"failed":false}],[":frontend/tests/fresh.test.js",{"duration":22.15039999999999,"failed":false}]]}
|
||||
{"version":"4.1.11","results":[[":frontend/tests/render.test.js",{"duration":76.60164399999996,"failed":false}],[":frontend/tests/focusmark.test.js",{"duration":40.93189599999994,"failed":false}],[":frontend/tests/fold.test.js",{"duration":56.39246000000003,"failed":false}],[":frontend/tests/optional.test.js",{"duration":34.46531600000003,"failed":false}],[":frontend/tests/parser.test.js",{"duration":25.05400099999997,"failed":false}],[":frontend/tests/xor.test.js",{"duration":65.50341500000002,"failed":false}],[":frontend/tests/desc.test.js",{"duration":59.75648000000001,"failed":false}],[":frontend/tests/deps.test.js",{"duration":67.85368099999994,"failed":false}],[":frontend/tests/closure.test.js",{"duration":29.96200700000003,"failed":false}],[":frontend/tests/effective.test.js",{"duration":55.79072299999996,"failed":false}],[":frontend/tests/ids.test.js",{"duration":48.80462399999999,"failed":false}],[":frontend/tests/remote.test.js",{"duration":17.515127999999947,"failed":false}],[":frontend/tests/warnings.test.js",{"duration":9.082986000000005,"failed":false}],[":frontend/tests/fresh.test.js",{"duration":21.491277000000025,"failed":false}],[":frontend/tests/shortids.test.js",{"duration":40.74205600000005,"failed":false}],[":frontend/tests/snapshots.test.js",{"duration":105.82867499999998,"failed":false}],[":frontend/tests/frontier.test.js",{"duration":80.81959199999994,"failed":false}],[":frontend/tests/continuation.test.js",{"duration":36.78602599999999,"failed":false}],[":frontend/tests/news.test.js",{"duration":21.62978800000002,"failed":false}]]}
|
||||
Reference in New Issue
Block a user