Skip to content

快速开始 ​

画一张图要走五步:校验文档 → 解析主题 → 算几何 → 生成场景 → 输出。 每一步都能单独用,也能串起来一次做完(见五段管线)。

先看一眼它长什么样(这张图是当前代码实时渲染的):

Live一份文档,一张图契约里只有「谁连谁」
订单服务 库存服务

零警告:整条管线没有产生任何诊断

更多图例在 示例。 想先了解扩展点,可以从节点注册开始。

bash
bun add @ggn/draw

① 全自动:handle 接线 ​

ts
import { parseDocument, createDrawHandle } from "@ggn/draw";
import { createDomHost } from "@ggn/draw/dom";

const parsed = parseDocument(json);
if (!parsed.ok) throw new Error(parsed.diagnostics.map((d) => `${d.code}: ${d.message}`).join("\n"));

const host = createDomHost(document.querySelector("svg")!);
const handle = createDrawHandle({ document: parsed.value, host });

// 第二帧起只产 patch;失败时保留上一帧
const diagnostics = handle.update(nextDocument);

② 半自动:显式管线 ​

每段的输出直接就是下一段的输入,中间结果全部可断言:

ts
import {
  parseDocument, resolveTheme, createRegistry, builtinRegistry,
  layoutDocument, buildScene, renderToSvg,
} from "@ggn/draw";

const doc = parseDocument(json);
if (!doc.ok) throw new Error(String(doc.diagnostics.length));

const theme = resolveTheme({ tokens: { accent: "#0f766e" } });
if (!theme.ok) throw new Error("theme");

const registry = createRegistry({ base: builtinRegistry }).registerShape("actor", actorShape);
const layout = layoutDocument(doc.value, { typography: theme.value.typography, metrics: registry.metrics() });
if (!layout.ok) throw new Error("layout");

const scene = buildScene(doc.value, layout.value, { registry, theme: theme.value });
if (!scene.ok) throw new Error("build");

const svg = renderToSvg(scene.value, { idPrefix: "uc" });

③ 全手工:只换一段 ​

任何一段都是注入点,其余不动:

想换什么传什么类型
布局算法layoutDocument(doc, { engine })LayoutEngine
连线路由layoutDocument(doc, { router })Router
文本度量layoutDocument / buildScene 的 measurerTextMeasurer
图元画法createRegistry({ base }).registerShape(...)ShapeSpec
介质自己实现 DrawHost,或只消费 SceneScene

两条入口 ​

入口用来做什么约束
@ggn/drawmodel / theme / registry / layout / scene / build / renderToSvg / createDrawHandle不出现 DOM API,直接 import 也不会碰浏览器
@ggn/draw/domcreateDomHost(root)唯一接触 DOM 的地方

失败与回落 ​

  • ok: false 只表示「产不出可用值」(结构非法、缺几何、入参不自洽),调用方必须处理。
  • 其余问题一律 ok: true + 诊断:未知类型回落、未知 token 回落、props 非法用默认值。
  • 每条诊断的 code 是稳定契约,message 只是给人看的。
ts
const scene = buildScene(doc, layout, { registry, theme });
if (scene.ok) {
  const warnings = scene.diagnostics.filter((d) => d.severity === "warning");
}

MIT License