How to Build a Multi‑Format Graph Drawing Engine with DSL, Layout, and Two‑Stage Rendering
This article walks through the design and implementation of a flexible graph‑drawing tool, analyzing existing solutions, defining core components such as a graph model, DSL parser, layout engine, and rendering pipeline, and detailing a step‑by‑step proof‑of‑concept built with React, Konva, and TypeScript.
Background
The project aims to provide a "graph‑as‑code" engine for architecture governance (ArchGuard) and the knowledge‑management tool Quake, supporting multiple diagram formats.
Analysis of Existing Drawing Tools
Graphviz : Uses the DOT language to generate diagrams.
Mermaid : Pure JavaScript DSL parser, builds an internal graph model and renders with graphlib, dagre‑d3 and d3.
Cytoscape : Extensible layout algorithms; nodes and edges are generic Element s rendered on an HTML5 canvas.
Excalidraw : Projection geometry keeps edges attached when nodes move; rendering is hand‑drawn style via roughjs.
MaxGraph : TypeScript implementation of mxGraph (Draw.io engine); provides an abstract canvas API ( .moveTo, .lineTo) and can output SVG or XML.
Core Elements of a Drawing Engine
Graph Model : Defines Diagram/Graph, Node, Edge, Shape, Element relationships.
Rendering Backend : SVG, Canvas, or other targets.
Layout Algorithms : Automatic positioning (e.g., Cytoscape style).
DSL Parsing : Convert textual specifications into the graph model.
Auto‑Connection : Keep edges linked when nodes move (as in Excalidraw).
Styling : Hand‑drawn effects, themes, etc.
Proof‑of‑Concept (Step 1)
Implemented three core features:
DSL parsing to produce a graph model.
Generation of the internal graph model.
Rendering of the graph using a React‑compatible canvas engine.
Demo URL (early version): https://online.feakin.com/
Technical Choices
SVG offers easy snapshot testing but hits performance limits; Canvas provides a free‑form API but is harder to test. An abstract canvas interface (inspired by MaxGraph) was adopted, and Konva was selected as the concrete engine because of its React integration.
Model Refactoring (Step 2)
Three transformation layers are unified via the Graph Intermedia Model (GIM):
export interface Graph {
nodes: Node[];
edges: Edge[];
props?: GraphProperty;
subgraphs?: Graph[];
}GIM expands into five concrete elements:
Node – position, shape, etc.
Edge – points, straight or Bézier curves.
Props – visual attributes (fillColor, strokeColor, …).
Subgraph – nested graphs (groups, clusters).
Shape hierarchy – PolygonShape, TriangleShape, DiamondShape, etc.
Two‑Stage Rendering (Step 3)
The engine separates diagram creation from editing:
Stage 1: Generate a graph from DSL or import an existing diagram.
Stage 2: Use the graphical editor to modify the generated graph.
This design enables conversion between formats (Draw.io, Excalidraw, Graphviz) while preserving both the creation process and the final visual result.
Shape Mapping Challenges
Different tools use different shape identifiers. For example, Graphviz can emit a triangle shape, but Excalidraw lacks a native triangle and requires manual line composition; Draw.io’s triangle differs from the geometric acute triangle ( mxgraph.basic.acute_triangle). Exporters must map these discrepancies accordingly.
From MVP to Production (Step 4)
Current MVP supports only basic shapes. Planned extensions:
Enrich the shape library via GIM.
Define a comprehensive property system (FillState, FontState, StrokeState, ImageState).
Improve ecosystem compatibility so that exports to Excalidraw, Draw.io, and other tools retain visual fidelity.
Implement remote multi‑user collaboration using a rope‑based state management model (inspired by JetBrains Fleet and the Xi editor).
All source code is available at https://github.com/feakin/feakin/.
phodal
A prolific open-source contributor who constantly starts new projects. Passionate about sharing software development insights to help developers improve their KPIs. Currently active in IDEs, graphics engines, and compiler technologies.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
