enhancement
major
minor
defect
critical
major
minor
minor
#30187
Diagramm-Export als SVG (reactFlowToSvg, flowToSvg) ist nicht Batik- bzw. druckfähig
Problem
Das von reactFlowToSvg(...) erzeugte SVG lässt sich nicht über pdfFile rendern (Flying Saucer + Batik, eingebunden als <img src="data:image/svg+xml;base64,...">):
- Die Engine schreibt fill="transparent" bzw. stroke="transparent", u. a. in GanttLayoutOperations und GraphEdgeOperations (tl-react-flow-common). Batik kennt transparent nicht und bricht ab.
- rgba(...)-Farben werden von Batik verworfen.
- Es wird immer das Bildschirm-Stylesheet eingebettet. Es enthält var(--...), das außerhalb des Browsers nicht aufgelöst wird.
Dasselbe gilt für den Export flowToSvg(...) der klassischen Diagramme (tl-graphic-blocks-server): Farben aus dem Skript werden unverändert übernommen, und das eingebettete Stylesheet tl-flow-core.css verwendet CSS-Variablen.
Workaround in der Anwendung: Das SVG wird als Text nachbearbeitet. transparent wird zu none, rgba wird zu rgb + fill-opacity, und das Stylesheet wird entfernt. Dafür ist ein Umweg über parseCSV nötig, siehe Ticket „TL-Script: Binärwert als Text lesen“.
Erwartet
Ein exportiertes SVG ist portabel:
- none statt transparent
- fill-opacity/stroke-opacity statt rgba
- kein Stylesheet mit CSS-Variablen
Lösung
reactFlowToSvg und flowToSvg schreiben immer portables SVG, das Batik (und damit pdfFile) darstellen kann. Eine Option ist nicht nötig, die Darstellung im Browser bleibt gleich. Die Anwendung kann den Workaround entfernen.
- ColorFormat versteht zusätzlich die CSS-Notation rgb(r, g, b) / rgba(r, g, b, a) (Kanäle 0-255 oder Prozent, Alpha 0-1 oder Prozent). ColorFormat.parseColorOrNull liefert null für einen Text, der keine Farbe ist.
- Der SvgTagWriter beider Export-Linien rechnet fill/stroke über ColorFormat um: Jede Farbe wird als #RRGGBB geschrieben (auch Farbnamen, z. B. black als #000000). Eine vollständig transparente Farbe wird none, die Deckkraft einer teiltransparenten Farbe steht in fill-opacity/stroke-opacity, multipliziert mit einer am Element gesetzten Deckkraft. Werte, die keine Farbe sind (none, url(#...), currentColor), bleiben unverändert.
- Der Export bettet statt des Bildschirm-Stylesheets ein eigenes CSS2-Stylesheet ohne Variablen ein (tl-react-flow-export.css bzw. tl-flow-export.css im Klassenpfad neben der jeweiligen FlowFactory), das nur die Auswahlmarkierungen ausblendet. Die Darstellung am Bildschirm bleibt unverändert.
Test
- TestColorFormat
- TestSvgTagWriter in tl-react-flow-server und tl-graphic-blocks-server
- TestFlowSvgPortable (tl-react-flow-server) und TestFlowPdf (tl-graphic-blocks-server): exportiertes SVG ohne transparent, rgba( und var(, Darstellung über pdfFile ohne Batik-Fehler.