
Self-hosted SDK parsing, laying out, and rendering Mermaid, PlantUML, and DOT diagrams with streaming incremental updates, viewport-aware rendering, cached measurements, and SVG/bitmap export hooks.
A Kotlin Multiplatform diagram rendering SDK with self-hosted parsing, layout, and rendering for Mermaid, PlantUML, and Graphviz DOT. The project targets Android, iOS, Desktop (JVM), and Web (JS/Wasm), with streaming incremental rendering as a first-class use case.
Diagram.session() supports append-only incremental parsing, layout, and draw updates for LLM and live-preview scenarios.DiagramView(source = ...) is the app-facing Composable and owns language detection, snapshots, and incremental updates internally.DrawCommandIndex.Detailed compatibility notes live in Mermaid, PlantUML, and DOT.
:diagram-core: shared IR, geometry, theme, diagnostics, draw commands, and export-facing primitives.:diagram-layout: self-hosted layout algorithms such as Sugiyama, tree, timeline, chart, and structural layouts.:diagram-parser: Mermaid, PlantUML, and DOT parsers plus lowering into the shared IR.:diagram-render: Compose rendering facade, streaming session API, viewport-aware canvas, and top-level user-facing entry points.:composeApp: cross-platform demo gallery with built-in samples.:androidApp: Android host app for local verification.Add diagram-render if you want the full parsing, layout, and Compose rendering stack.
[versions]
diagram = "1.0.4"
[libraries]
diagram-render = { module = "io.github.huarangmeng:diagram-render", version.ref = "diagram" }dependencies {
implementation(libs.diagram.render)
}Use lower-level modules directly only when you need a subset of the stack.
dependencies {
implementation("io.github.huarangmeng:diagram-core:1.0.4")
implementation("io.github.huarangmeng:diagram-layout:1.0.4")
implementation("io.github.huarangmeng:diagram-parser:1.0.4")
}Markdown renderers can ask the SDK whether a code fence or streaming block should become a diagram before creating Compose UI.
import com.hrm.diagram.render.Diagram
val detection = Diagram.detectSource(fenceBody, hint = fenceInfo)
if (detection.shouldRouteToDiagram) {
// Render with DiagramView(source = fenceBody)
}The primary public workflow is a streaming session. Feed source chunks incrementally and finish when the stream ends.
import com.hrm.diagram.core.ir.SourceLanguage
import com.hrm.diagram.render.Diagram
val session = Diagram.session(SourceLanguage.MERMAID)
session.append("""
flowchart LR
A[Start] --> B{Decide}
""".trimIndent())
session.append("\n B -->|yes| C[Ship]\n B -->|no| D[Stop]\n")
val snapshot = session.finish()
println(snapshot.diagnostics)DiagramView(...) accepts source text plus an optional DiagramTheme at the app boundary. It wires Compose text measurement into the layout pipeline, detects Mermaid / PlantUML / DOT, and maintains the incremental snapshot internally.
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.hrm.diagram.core.theme.DiagramTheme
import com.hrm.diagram.render.compose.DiagramView
import com.hrm.diagram.render.theme.material3
@Composable
fun MermaidPreview(source: String) {
val theme = DiagramTheme.material3()
DiagramView(
source = source,
theme = theme,
modifier = Modifier.fillMaxSize(),
zoomEnabled = true,
)
}./gradlew :androidApp:assembleDebug
./gradlew :composeApp:run
./gradlew :composeApp:wasmJsBrowserDevelopmentRun
./gradlew :composeApp:jsBrowserDevelopmentRun
iosApp/ in Xcode./gradlew allTestsA Kotlin Multiplatform diagram rendering SDK with self-hosted parsing, layout, and rendering for Mermaid, PlantUML, and Graphviz DOT. The project targets Android, iOS, Desktop (JVM), and Web (JS/Wasm), with streaming incremental rendering as a first-class use case.
Diagram.session() supports append-only incremental parsing, layout, and draw updates for LLM and live-preview scenarios.DiagramView(source = ...) is the app-facing Composable and owns language detection, snapshots, and incremental updates internally.DrawCommandIndex.Detailed compatibility notes live in Mermaid, PlantUML, and DOT.
:diagram-core: shared IR, geometry, theme, diagnostics, draw commands, and export-facing primitives.:diagram-layout: self-hosted layout algorithms such as Sugiyama, tree, timeline, chart, and structural layouts.:diagram-parser: Mermaid, PlantUML, and DOT parsers plus lowering into the shared IR.:diagram-render: Compose rendering facade, streaming session API, viewport-aware canvas, and top-level user-facing entry points.:composeApp: cross-platform demo gallery with built-in samples.:androidApp: Android host app for local verification.Add diagram-render if you want the full parsing, layout, and Compose rendering stack.
[versions]
diagram = "1.0.4"
[libraries]
diagram-render = { module = "io.github.huarangmeng:diagram-render", version.ref = "diagram" }dependencies {
implementation(libs.diagram.render)
}Use lower-level modules directly only when you need a subset of the stack.
dependencies {
implementation("io.github.huarangmeng:diagram-core:1.0.4")
implementation("io.github.huarangmeng:diagram-layout:1.0.4")
implementation("io.github.huarangmeng:diagram-parser:1.0.4")
}Markdown renderers can ask the SDK whether a code fence or streaming block should become a diagram before creating Compose UI.
import com.hrm.diagram.render.Diagram
val detection = Diagram.detectSource(fenceBody, hint = fenceInfo)
if (detection.shouldRouteToDiagram) {
// Render with DiagramView(source = fenceBody)
}The primary public workflow is a streaming session. Feed source chunks incrementally and finish when the stream ends.
import com.hrm.diagram.core.ir.SourceLanguage
import com.hrm.diagram.render.Diagram
val session = Diagram.session(SourceLanguage.MERMAID)
session.append("""
flowchart LR
A[Start] --> B{Decide}
""".trimIndent())
session.append("\n B -->|yes| C[Ship]\n B -->|no| D[Stop]\n")
val snapshot = session.finish()
println(snapshot.diagnostics)DiagramView(...) accepts source text plus an optional DiagramTheme at the app boundary. It wires Compose text measurement into the layout pipeline, detects Mermaid / PlantUML / DOT, and maintains the incremental snapshot internally.
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.hrm.diagram.core.theme.DiagramTheme
import com.hrm.diagram.render.compose.DiagramView
import com.hrm.diagram.render.theme.material3
@Composable
fun MermaidPreview(source: String) {
val theme = DiagramTheme.material3()
DiagramView(
source = source,
theme = theme,
modifier = Modifier.fillMaxSize(),
zoomEnabled = true,
)
}./gradlew :androidApp:assembleDebug
./gradlew :composeApp:run
./gradlew :composeApp:wasmJsBrowserDevelopmentRun
./gradlew :composeApp:jsBrowserDevelopmentRun
iosApp/ in Xcode./gradlew allTests