feat: Querverbindungen folgen der Faltung + Schalter; Falt-Knopf mit vier Voreinstellungen (D75)
- Abhängigkeits-Kanten enden am nächsten sichtbaren Vorfahren, für Quelle wie Ziel; zusammengefallene Kanten entfallen bzw. werden dedupliziert (data-sub-ids/data-sub-deps am eingeklappten Vertreter, SPEC §9) - Umschalter für die Querverbindungen neben dem Günstigster-Pfad-Knopf, Voreinstellung an, persistiert; Export und Druck folgen ihm - Der Falt-Knopf schaltet durch: M und kleiner zu → alles abseits des Pfads zu → alles zu → alles offen; Icon/Tooltip zeigen den nächsten Schritt, Handfaltung setzt die Position zurück (presetFoldSet, model.js) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
69c9be7a6d
commit
33443016ce
@@ -19,6 +19,9 @@ reverse.
|
||||
|
||||
## 2026-08-25
|
||||
|
||||
- The fold button cycles through four presets now: size M and smaller, everything off the cheapest path, everything, all open
|
||||
- A button next to the cheapest-path toggle switches the dependency cross links on and off
|
||||
- Dependency links follow the folding: an edge to a hidden node now ends at its first visible ancestor, for source and target alike
|
||||
- In Brave, the file notice names the flag that enables the File System Access API by hand
|
||||
- Fix: the file notice and the legend blamed "Chromium", but Brave is Chromium without the File System Access API — they now name the feature and example browsers
|
||||
- Browsers without the File System Access API (Firefox, Safari) explain themselves once: files open as copies and saving downloads a new file
|
||||
|
||||
@@ -5660,3 +5660,87 @@ in den Übersetzungen — eine Stelle statt neun, an denen sie vertippt sein
|
||||
kann. **Nachgemessen** im Dev-Server (Stufe-1-Pfad erzwungen, Brave per
|
||||
`navigator.brave`-Stub zur Laufzeit): mit Stub trägt das Banner die zweite
|
||||
Zeile samt Mono-Code der Adresse, ohne Stub fehlt beides.
|
||||
|
||||
## D75 — Querverbindungen folgen der Faltung und bekommen einen Schalter; der Falt-Knopf schaltet vier Voreinstellungen durch
|
||||
Drei zusammenhängende Nutzerwünsche an derselben Stelle des Diagramms, in
|
||||
einem Zug gebaut.
|
||||
|
||||
**1. Abhängigkeits-Kanten enden am nächsten sichtbaren Vorfahren.** D41 ließ
|
||||
Kanten zu eingeklappten Knoten schlicht entfallen — gerade in einem dicht
|
||||
gefalteten Plan verschwand damit die Aussage „dieser Zweig braucht jenen"
|
||||
genau dann, wenn man sie am nötigsten hat. Die Regel gab es längst: **Der
|
||||
eingeklappte Knoten vertritt seinen Teilbaum** — für die Pfad-Station, den
|
||||
„▸ n"-Zähler und die Cursor-Zeile (D38-Nachträge). Jetzt gilt sie auch für
|
||||
die Querverbindungen, für **Quelle wie Ziel** (Nutzer-Vorgabe). Fallen beide
|
||||
Endpunkte in denselben sichtbaren Knoten, entfällt die Kante (sie sagte
|
||||
nichts mehr); mehrere so zusammengefallene Kanten desselben Paars werden
|
||||
**eine**. Kanten zu ausgeblendeten **verworfenen** Knoten entfallen
|
||||
weiterhin — dieselbe Grenze wie bei der Cursor-Zeile (D38-Nachtrag 4):
|
||||
Faltung ist Ansicht, der Verworfen-Filter ist eine Aussage über den Plan.
|
||||
|
||||
**Umgesetzt im Renderer, nicht in einer App-Nebenrechnung:** `walkFolded()`
|
||||
läuft ohnehin durch jeden verborgenen Teilbaum (Warnungen, „▸ n") und sammelt
|
||||
jetzt dessen IDs und Abhängigkeiten mit; der eingeklappte Knoten trägt sie
|
||||
als `data-sub-ids`/`data-sub-deps` — getrennt von den eigenen Attributen,
|
||||
damit die Bedeutung ablesbar bleibt, und headless testbar (Hausregel
|
||||
D54-Nachtrag 3). `depEdges()` in app.js löst dann nur noch auf: Die
|
||||
Sub-IDs stehen in DFS- und damit Dokumentreihenfolge, „erste Vergabe
|
||||
gewinnt" (D36) gilt so auch über die Faltgrenze hinweg. Der Grafikexport
|
||||
nutzt dasselbe `depEdges()` und folgt ohne Zusatzcode.
|
||||
|
||||
**2. Ein Umschalter für die Querverbindungen**, neben dem
|
||||
Günstigster-Pfad-Knopf (Nutzer-Vorgabe): Voreinstellung an, persistiert in
|
||||
`werkbaum-ui` wie die Nachbarn (D22). Export und Druck folgen ihm wie den
|
||||
übrigen Ansichts-Filtern (die D38/D44/D56-Linie: das Bild zeigt, was
|
||||
sichtbar ist). Der Klick zeichnet nur die Overlays neu statt zu rendern —
|
||||
am Baum ändert sich nichts.
|
||||
|
||||
**3. Der Falt-Knopf wird ein Durchschalter mit vier Voreinstellungen**
|
||||
(Nutzer-Vorgabe, Reihenfolge wie gewünscht): **(1)** ab Größe M abwärts zu
|
||||
(die D44-Regel, unverändert), **(2)** alles zu, durch dessen Teilbaum der
|
||||
günstigste Pfad nicht läuft — weder der Knoten selbst noch ein Unterknoten
|
||||
liegt darauf; sichtbar bleibt genau der Pfad, alles Übrige steht als je ein
|
||||
eingeklappter Knoten da —, **(3)** alles zu, **(4)** alles offen, dann
|
||||
wieder von vorn. Jede Stufe beschreibt einen **vollständigen** Faltzustand
|
||||
(die D44-Eigenschaft bleibt: zweimal Drücken derselben Stufe ergäbe
|
||||
dasselbe), geschrieben wird über denselben Weg wie bisher — ein
|
||||
Undo-Schritt je Stufe, beim Pad trägt die Sitzungs-Überlagerung.
|
||||
|
||||
- **Der Knopf zeigt den NÄCHSTEN Schritt** (Icon per `data-next`, Tooltip
|
||||
aus vier neuen i18n-Schlüsseln × 9 Sprachen; `foldSmallTooltip` entfällt).
|
||||
Das ist die D17-Logik des Bereichs-Umschalters: Ein Knopf, der den
|
||||
Zustand zeigt, den man vor sich hat, sagt nichts — einer, der das Ziel
|
||||
zeigt, sagt, was passiert. Mit vier Stufen ist er zudem kein Umschalter
|
||||
mehr, `aria-pressed` entfällt.
|
||||
- **Die Reihum-Position wird nicht gemerkt, sondern geprüft** — die
|
||||
D44-Fortschreibung für vier Stufen: `render()` rechnet nach, ob der Baum
|
||||
noch die zuletzt hergestellte Stufe beschreibt (`presetFoldSet` in
|
||||
model.js, headless getestet); wenn nicht — Handfaltung, Textänderung,
|
||||
Dokumentwechsel —, beginnt der nächste Druck wieder bei 1. Ein reines
|
||||
Ablesen ohne Position (D44) trägt bei vier Stufen nicht mehr: Ein voll
|
||||
offener Baum kann zugleich Stufe 4 und einer leeren Stufe 1 entsprechen —
|
||||
die Mehrdeutigkeit ist den Stufen inhärent, die geprüfte Position löst
|
||||
sie deterministisch.
|
||||
- **Stufe 2 rechnet den Pfad auch bei ausgeschaltetem Pfad-Umschalter** —
|
||||
die Voreinstellung fragt nach dem Pfad, nicht nach seiner Anzeige; die
|
||||
Rechnung ist dieselbe, die bei eingeschaltetem Pfad ohnehin je Tastendruck
|
||||
läuft (D42).
|
||||
|
||||
**Preis in der Kopfzeile, benannt:** Der Querverbindungs-Knopf ist das elfte
|
||||
Element. Auf dem Telefon (375 px) bricht die Zeile damit regulär in zwei
|
||||
Reihen à 78 px — genau der Umbruch, den D50/D56 unterhalb von 440 px
|
||||
vorsehen; am Schreibtisch bleibt sie einreihig (gemessen 44 px bei 800 px).
|
||||
|
||||
**Nachgemessen** im Browser an einem Wegwerf-Dokument (10 Knoten, 3 Kanten,
|
||||
über die echte UI angelegt und gelöscht): Mittel eingeklappt → Kante endet
|
||||
am Vertreter (`data-sub-deps="z1"`), Ziel-Seite ebenso; beide Quellen unter
|
||||
einem Vorfahren eingeklappt → **eine** Kante statt zwei (3 → 2); Wurzel zu →
|
||||
0 Kanten. Durchschalter: small → path → closed → open → wieder small, je mit
|
||||
korrekter Faltmenge und Tooltip; Handfaltung danach setzt auf small zurück;
|
||||
`path` faltet bei ausgeschaltetem Pfad-Umschalter identisch; Undo nimmt eine
|
||||
Stufe in einem Zug zurück (4 Marken → 1 → 4). Umschalter: aus → 0 Overlays
|
||||
und 0 Kanten im exportierten SVG, an → 3/3; `depLinks` überlebt den Reload.
|
||||
480 → 487 Tests, davon 7 neue in `tests/fold.test.js` (presetFoldSet-Modi
|
||||
inkl. des per `:#…` gezogenen Ziels unter einer Zugabe; `data-sub-*` in
|
||||
Dokumentreihenfolge, dedupliziert, nie an offenen Knoten, nie für
|
||||
ausgeblendete verworfene).
|
||||
|
||||
+41
-18
@@ -1083,19 +1083,32 @@ fokussierten Knoten (WAI-ARIA-Baum-Idiom).
|
||||
weil eine Fokusmarke `!!!` ihren Knoten immer wieder hervorholt): Dann wird
|
||||
lieber nichts geschrieben, als einen Text zu hinterlassen, der etwas anderes
|
||||
sagt als das Bild.
|
||||
- **Für den ganzen Baum** gibt es im Diagramm-Kopf einen **Umschalter**:
|
||||
gedrückt ist alles **ab Größe M abwärts** zugeklappt, nicht gedrückt ist der
|
||||
ganze Baum **offen**. Betroffen ist jeder Knoten mit Kindern, dessen
|
||||
**angegebene** Größe (§5) `M` oder kleiner ist — offen bleiben `L`, `XL`,
|
||||
`XXL`. Ein Knoten **ohne** Größenangabe wird nicht zugeklappt: Der günstigste
|
||||
Pfad rechnet fehlende Größen zwar als `M` (unten), das ist aber eine
|
||||
Kostenannahme und keine Aussage des Autors.
|
||||
- Beide Stellungen beschreiben einen **vollständigen** Faltzustand — was der
|
||||
Umschalter nicht zuklappt, ist danach offen. Sein Zustand wird **nicht
|
||||
gemerkt, sondern am Baum abgelesen**: Wer danach einen Knoten von Hand
|
||||
umklappt, sieht ihn von selbst herausspringen. Geschrieben wird wie beim
|
||||
einzelnen Umklappen — ein einziger Rückgängig-Schritt für den ganzen
|
||||
Vorgang. Siehe D44.
|
||||
- **Für den ganzen Baum** gibt es im Diagramm-Kopf einen **Durchschalter**:
|
||||
Jeder Druck stellt die **nächste** von vier Voreinstellungen her, reihum —
|
||||
1. **ab Größe M abwärts zugeklappt**: jeder Knoten mit Kindern, dessen
|
||||
**angegebene** Größe (§5) `M` oder kleiner ist — offen bleiben `L`,
|
||||
`XL`, `XXL`. Ein Knoten **ohne** Größenangabe wird nicht zugeklappt:
|
||||
Der günstigste Pfad schätzt fehlende Größen zwar (unten), das ist aber
|
||||
eine Kostenannahme und keine Aussage des Autors.
|
||||
2. **alles abseits des günstigsten Pfads zugeklappt**: jeder Knoten, durch
|
||||
dessen Teilbaum der günstigste Pfad (§9) **nicht** läuft — weder er
|
||||
selbst noch ein Unterknoten liegt auf ihm. Der Pfad bleibt vollständig
|
||||
sichtbar, alles Übrige steht als je ein eingeklappter Knoten da.
|
||||
Gerechnet wird dafür auch bei **ausgeschaltetem** Pfad-Umschalter — die
|
||||
Voreinstellung fragt nach dem Pfad, nicht nach seiner Anzeige.
|
||||
3. **alles zugeklappt**: jeder Knoten mit Kindern.
|
||||
4. **alles offen**.
|
||||
|
||||
Der Knopf zeigt als Icon und Tooltip den **nächsten** Schritt — also was
|
||||
Drücken tun wird, nicht was gerade gilt: Den Zustand hat man ohnehin vor
|
||||
sich (dieselbe Logik wie beim Bereichs-Umschalter auf kleinem Bildschirm).
|
||||
- Jede Voreinstellung beschreibt einen **vollständigen** Faltzustand — was
|
||||
sie nicht zuklappt, ist danach offen. Die Reihum-Position wird **nicht
|
||||
gemerkt, sondern am Baum geprüft**: Beschreibt der Baum nicht mehr den
|
||||
zuletzt hergestellten Schritt (jemand hat von Hand umgeklappt oder den
|
||||
Text geändert), beginnt der nächste Druck wieder bei 1. Geschrieben wird
|
||||
wie beim einzelnen Umklappen — ein einziger Rückgängig-Schritt je
|
||||
Voreinstellung. Siehe D44, D75.
|
||||
- Faltung ist **reine Ansicht**: Warnungen aus eingeklappten Teilbäumen werden
|
||||
weiter gemeldet (sie gelten dem Text), und der günstigste Pfad rechnet
|
||||
unverändert über den ganzen Baum.
|
||||
@@ -1139,11 +1152,21 @@ Strichen, kein gefülltes Dreieck). Der Baum trägt weiterhin die Hauptaussage.
|
||||
- Die Kanten des **ausgewählten** Knotens — Tastaturfokus im Diagramm, sonst
|
||||
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).
|
||||
- Die Basis-Kanten erscheinen auch im **Grafikexport** und im **Druck**; die
|
||||
Hervorhebung ist Interaktion und erscheint nicht. Siehe D41.
|
||||
- **Eingeklappte Knoten vertreten ihre Teilbäume auch hier** (§9, Falten):
|
||||
Liegt ein Endpunkt — Quelle wie Ziel — in einem eingeklappten Teilbaum,
|
||||
endet die Kante am nächsten **sichtbaren Vorfahren**. Fallen beide
|
||||
Endpunkte in denselben sichtbaren Knoten zusammen, entfällt die Kante (sie
|
||||
sagte nichts mehr); mehrere so zusammengefallene Kanten desselben Paars
|
||||
werden zu **einer**. Kanten zu **ausgeblendeten verworfenen** Knoten (§4)
|
||||
entfallen weiterhin — der Verworfen-Filter ist eine Aussage über den Plan,
|
||||
keine Ansicht. Bei doppelter ID zielt die Kante auf die erste Vergabe
|
||||
(D36/D39).
|
||||
- **Ein Umschalter im Diagramm-Kopf** (neben dem günstigsten Pfad) blendet
|
||||
die Querverbindungen ein und aus; Voreinstellung **an**, Zustand gemerkt.
|
||||
- Die Basis-Kanten erscheinen auch im **Grafikexport** und im **Druck**,
|
||||
sofern der Umschalter an ist (beide folgen ihm wie den übrigen
|
||||
Ansichts-Filtern); die Hervorhebung ist Interaktion und erscheint nicht.
|
||||
Siehe D41, D75.
|
||||
|
||||
### Grafikexport des Diagramms
|
||||
Das Diagramm wird aus der Live-Geometrie in ein eigenständiges SVG (nur Formen
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
- [^] #ed.deplink: Cross links for dependencies (M)
|
||||
- [^] #ed.deplink.calm: Visually secondary — the tree carries the message (S)
|
||||
- [^] #ed.deplink.focus: Highlight what a selected node needs and feeds (S)
|
||||
- [x] #ed.deplink.fold: A hidden endpoint falls to its visible ancestor (S) %% source and target alike, see D75
|
||||
- [x] #ed.deplink.toggle: A switch hides the cross links (XS)
|
||||
- [^] #ed.path: Cheapest path (XL)
|
||||
- [^] #ed.path.cost: Cost model, a size prices its subtree (S)
|
||||
- [^] #ed.path.est: Missing size estimated from the sub-packages (S) %% see D66
|
||||
@@ -83,7 +85,7 @@
|
||||
- [^] #ed.fold.marks: Initial state from the text: > collapses, < re-opens (S)
|
||||
- [^] #ed.fold.click: Fold and unfold in the diagram (S)
|
||||
- [^] #ed.fold.write: Folding writes the mark back into the text (S) %% one undo step
|
||||
- [^] #ed.fold.preset: One switch folds everything from size M downward (S) %% see D44
|
||||
- [x] #ed.fold.preset: The fold button cycles through four presets (S) %% M-and-smaller, off-path, all, none — see D44/D75
|
||||
- [^] #ed.snaps: Earlier states of a document, every ten minutes (S) %% only when something changed
|
||||
- [^] #ed.snaps.manual: Save a state by hand, before a larger change (XS) %% ten minutes is the wrong beat for that moment
|
||||
- [^] #ed.files: Open and save .werkbaum files (S)
|
||||
@@ -397,6 +399,16 @@
|
||||
The selected node — keyboard focus in the diagram, otherwise the node of the
|
||||
caret line — pulls its incoming and outgoing edges forward in ink.
|
||||
|
||||
#ed.deplink.fold
|
||||
When an endpoint sits in a folded subtree, the edge ends at the nearest
|
||||
visible ancestor instead of vanishing — the collapsed node stands in for
|
||||
its subtree here too, for source and target alike. Edges whose two ends
|
||||
fall into the same visible node disappear, duplicates merge into one.
|
||||
|
||||
#ed.deplink.toggle
|
||||
A toggle next to the cheapest-path button hides the cross links entirely;
|
||||
export and print follow it like the other view filters.
|
||||
|
||||
#ed.path
|
||||
Highlight the cheapest way through the tree: with and, everything; with or,
|
||||
the cheapest alternative. This is the feature the whole notation exists for.
|
||||
@@ -590,9 +602,11 @@
|
||||
restores exactly what you were looking at.
|
||||
|
||||
#ed.fold.preset
|
||||
One switch puts the whole tree at working height: everything of size M and
|
||||
smaller closed, L and above open. Size rather than depth — depth only says
|
||||
how finely somebody happened to write it down.
|
||||
One button cycles the whole tree through four complete fold states: size M
|
||||
and smaller closed, everything off the cheapest path closed, everything
|
||||
closed, everything open. Icon and tooltip show the next step; a manual fold
|
||||
restarts the cycle. Size rather than depth — depth only says how finely
|
||||
somebody happened to write it down.
|
||||
|
||||
#ed.snaps
|
||||
A safety net against mishaps: the text is put aside every ten minutes, but
|
||||
|
||||
Reference in New Issue
Block a user