Interactive
Hybrid HTML + SVG diagrams from mermoid-ascent: real HTML nodes (click, hover, tooltips), SVG edges/splines
that re-layout when the viewport changes. Run sbt docs/specularPreview and work through every section below.
libraryDependencies += "rocks.earlyeffect" %% "mermoid-ascent" % "<version>" // JVM
libraryDependencies += "rocks.earlyeffect" %%% "mermoid-ascent" % "<version>" // Scala.js
import mermoid.ascent.MermoidAscent
import mermoid.{Mermaid, RenderConfig, Viewport}
val source = Mermaid("flowchart LR\n A[Start] --> B[Done]")
MermoidAscent.diagram(source, viewport = Some(Viewport(640)))
MermoidAscent.diagramInteractive(source, initialWidth = 720)
Existing guide pages still embed inert SVG via MermoidAscent.svgDiagram so structure docs stay byte-stable.
Hybrid flowchart
HTML nodes + SVG edges (not an inert SvgNode → UI map). Inspect the DOM: nodes are <button class="mermoid-node">.
MermoidAscent.diagram(hybridFlow, chalkboard, Some(Viewport(640)))Hybrid state + notes
States and note cards are HTML; connectors stay in the SVG layer. Click a state or its note.
MermoidAscent.diagramInteractive(stateNotes, chalkboard, initialWidth = 560)Hover + selection
Click a node: it gets is-selected and incident edges get is-incident. Click again to clear.
MermoidAscent.diagramInteractive(hybridFlow, chalkboard, initialWidth = 640)Tooltips
Mermaid click … "tooltip" becomes an ascent hover card (and SVG <title> on the SVG painter). Hover a node.
MermoidAscent.diagramInteractive(tooltips, chalkboard, initialWidth = 640)Links from click
click C href "…" "…" _blank wraps the node as a link. The Paint node opens earlyeffect.rocks in a new tab.
MermoidAscent.diagram(tooltips, chalkboard, Some(Viewport(640)))Reactive reflow
Use Narrow / Medium / Wide (or shrink the browser). This example opts into flipDirectionBelow = Some(640):
below 640px the layout prefers TB, and at or above 640px it prefers LR. The default config does not flip. Spacing
compresses to the viewport. Edges are recomputed, not stretched.
See Responsive layout for direction, spacing compression, and container fit.
MermoidAscent.diagramInteractive(
reflowWide,
chalkboard.copy(responsive = ResponsiveConfig(flipDirectionBelow = Some(640))),
initialWidth = 720,
)Scale-to-fit safety
A dense hub still overflows after minimum spacing. Container fit scales the HTML nodes and the SVG edges together, down to the scale floor (default 0.5), then the root scrolls horizontally.
MermoidAscent.diagram(denseFit, chalkboard, Some(Viewport(320)))Selection across reflow
Select a node, then hit Narrow/Wide: the selected id is preserved while geometry updates.
MermoidAscent.diagramInteractive(reflowWide, chalkboard, initialWidth = 720)Theme / chalkboard
Interactive diagram under docs chalkboard colors (Dark base + Early Effect palette).
MermoidAscent.diagramInteractive(hybridFlow, chalkboard, initialWidth = 600)Side-by-side contrast
Same source: inert SVG embed vs hybrid interactive.
SVG (svgDiagram):
MermoidAscent.svgDiagram(hybridFlow, chalkboard)Hybrid (diagramInteractive):
MermoidAscent.diagramInteractive(hybridFlow, chalkboard, initialWidth = 560)