@imanect/yui 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +49 -16
  2. package/dist/react/index.d.ts +46 -0
  3. package/dist/react/index.d.ts.map +1 -0
  4. package/dist/react/index.js +119 -0
  5. package/dist/react/index.js.map +1 -0
  6. package/dist/render/chart.d.ts +10 -0
  7. package/dist/render/chart.d.ts.map +1 -0
  8. package/dist/render/chart.js +239 -0
  9. package/dist/render/chart.js.map +1 -0
  10. package/dist/render/flow.d.ts +12 -0
  11. package/dist/render/flow.d.ts.map +1 -0
  12. package/dist/render/flow.js +284 -0
  13. package/dist/render/flow.js.map +1 -0
  14. package/dist/render/frame.d.ts +44 -0
  15. package/dist/render/frame.d.ts.map +1 -0
  16. package/dist/render/frame.js +79 -0
  17. package/dist/render/frame.js.map +1 -0
  18. package/dist/render/layout.d.ts +7 -0
  19. package/dist/render/layout.d.ts.map +1 -0
  20. package/dist/render/layout.js +29 -0
  21. package/dist/render/layout.js.map +1 -0
  22. package/dist/render/measure.d.ts +16 -0
  23. package/dist/render/measure.d.ts.map +1 -0
  24. package/dist/render/measure.js +86 -0
  25. package/dist/render/measure.js.map +1 -0
  26. package/dist/render/scene.d.ts +60 -0
  27. package/dist/render/scene.d.ts.map +1 -0
  28. package/dist/render/scene.js +20 -0
  29. package/dist/render/scene.js.map +1 -0
  30. package/dist/render/stack.d.ts +11 -0
  31. package/dist/render/stack.d.ts.map +1 -0
  32. package/dist/render/stack.js +112 -0
  33. package/dist/render/stack.js.map +1 -0
  34. package/dist/render/stat.d.ts +5 -0
  35. package/dist/render/stat.d.ts.map +1 -0
  36. package/dist/render/stat.js +36 -0
  37. package/dist/render/stat.js.map +1 -0
  38. package/dist/render/svg.d.ts +19 -0
  39. package/dist/render/svg.d.ts.map +1 -0
  40. package/dist/render/svg.js +88 -0
  41. package/dist/render/svg.js.map +1 -0
  42. package/dist/render/theme.d.ts +25 -0
  43. package/dist/render/theme.d.ts.map +1 -0
  44. package/dist/render/theme.js +93 -0
  45. package/dist/render/theme.js.map +1 -0
  46. package/dist/svg.d.ts +8 -0
  47. package/dist/svg.d.ts.map +1 -0
  48. package/dist/svg.js +7 -0
  49. package/dist/svg.js.map +1 -0
  50. package/package.json +36 -4
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @imanect/yui
2
2
 
3
- **Yui (結)** — a tiny, LLM-friendly notation for drawing figures inside Markdown, and the parser for it.
3
+ **Yui (結)** — a tiny, LLM-friendly notation for drawing figures inside Markdown, with a parser, an SVG renderer and React components.
4
4
 
5
5
  Models write a few lines of data in a ` ```ui ` block; the renderer decides layout, colors and axes.
6
6
  It is designed to be written correctly by small models with a short prompt, rendered while streaming, and safe for any input (no HTML, URLs or scripts).
@@ -15,40 +15,73 @@ Feb | 150 | -10
15
15
  ```
16
16
  ````
17
17
 
18
- Five figure kinds in v0.1: `bar`, `line`, `stat`, `flow` and `stack` (layered architecture diagrams).
18
+ Five figure kinds: `bar`, `line`, `stat` (KPI cards), `flow` (flowcharts with branches and loops) and `stack` (layered architecture diagrams).
19
19
  The parser is lenient with what models naturally write (GFM tables, Mermaid-style arrows, Japanese number formats such as `1億2,000万円` or `△120`) and reports per-line diagnostics instead of failing the whole block.
20
20
 
21
- > Status: **0.1 — parser only.** Renderers (`@imanect/yui/svg`, `@imanect/yui/react`) and a Markdown plugin are planned.
22
-
23
21
  ## Install
24
22
 
25
23
  ```sh
26
24
  npm install @imanect/yui
27
25
  ```
28
26
 
29
- ## Usage
27
+ `react` (>= 18) is an optional peer dependency, needed only for `@imanect/yui/react`.
28
+
29
+ ## React
30
+
31
+ ```tsx
32
+ import { YuiBlock, isYuiLanguage } from "@imanect/yui/react";
33
+
34
+ // e.g. with react-markdown
35
+ <Markdown
36
+ components={{
37
+ code({ className, children }) {
38
+ return isYuiLanguage(className)
39
+ ? <YuiBlock source={String(children)} streaming={isStreaming} />
40
+ : <code className={className}>{children}</code>;
41
+ },
42
+ }}
43
+ >
44
+ {text}
45
+ </Markdown>
46
+ ```
47
+
48
+ `YuiBlock` re-lays out to its container width, follows the page's light/dark theme, and while `streaming` draws only completed lines — a figure grows and never shows a half-written value.
49
+
50
+ ## SVG (browser or server)
51
+
52
+ ```ts
53
+ import { parseBlock } from "@imanect/yui";
54
+ import { renderSVG } from "@imanect/yui/svg";
55
+
56
+ const { figure } = parseBlock(source, { final: true });
57
+ renderSVG(figure!); // for screens: CSS variables, fluid width
58
+ renderSVG(figure!, { theme: "light", width: 720 }); // for export: colors and size baked in
59
+ ```
60
+
61
+ The same layout drives both outputs, so what you export is what you saw. Every SVG carries a `<desc>` with a plain-text table of the data for screen readers.
62
+
63
+ ## Theming
64
+
65
+ Colors are CSS custom properties: `--yui-s1` … `--yui-s8` (series), `--yui-ink`, `--yui-ink2`, `--yui-muted`, `--yui-grid`, `--yui-axis`, `--yui-surface`, `--yui-surface2`, `--yui-border`, `--yui-accentWash`, `--yui-accentLine`.
66
+ Set them on any ancestor to match your design system; `--yui-font` sets the typeface. The defaults are muted, seasonal hues on cool neutrals, validated for color-vision deficiencies with separate light and dark steps.
67
+
68
+ In `auto` mode Yui follows the page first — `<html class="dark">` (Tailwind, next-themes) or `<html data-theme="dark">`, and `light` likewise — and falls back to `prefers-color-scheme`.
69
+
70
+ ## Parser only
30
71
 
31
72
  ```ts
32
73
  import { parseMarkdown, toText } from "@imanect/yui";
33
74
 
34
- // Works on partial (streaming) text: unfinished last lines are held back,
35
- // so a figure only ever grows and never shows a half-written value.
36
75
  for (const seg of parseMarkdown(streamingText)) {
37
- if (seg.type === "ui" && seg.result.figure) {
38
- render(seg.result.figure, seg.result.diagnostics);
39
- }
76
+ if (seg.type === "ui" && seg.result.figure) draw(seg.result.figure);
40
77
  }
41
-
42
- // Plain-Markdown fallback (tables / lists) for places that don't support Yui.
43
- toText(figure);
78
+ toText(figure); // plain-Markdown fallback (tables / lists)
44
79
  ```
45
80
 
46
- Other exports: `parseBlock` (one block), `splitMarkdown`, `toSource` (canonical source), `transformMarkdown`, `parseNumber`.
47
-
48
81
  ## Docs
49
82
 
50
83
  - Notation spec (Japanese): [docs/spec.md](https://github.com/imanect-labs/y-ui/blob/main/docs/spec.md)
51
- - Export / copy design (Japanese): [docs/export.md](https://github.com/imanect-labs/y-ui/blob/main/docs/export.md)
84
+ - Evaluation with small models (Japanese): [docs/eval-results-2026-10-12-gemma.md](https://github.com/imanect-labs/y-ui/blob/main/docs/eval-results-2026-10-12-gemma.md)
52
85
 
53
86
  ## License
54
87
 
@@ -0,0 +1,46 @@
1
+ /**
2
+ * `@imanect/yui/react`: React で図を描く。
3
+ *
4
+ * - YuiFigure: 中間表現を描く(親の幅に合わせて描き直す)
5
+ * - YuiBlock: ` ```ui ` の中身(ソース)を解析して描く。ストリーミング中でもよい
6
+ * - isYuiLanguage: Markdown レンダラーのコードブロックの言語名が Yui か
7
+ *
8
+ * SVG はシーンから React 要素として組み立てる(HTML 文字列を差し込まない)。
9
+ */
10
+ import { type ReactElement } from "react";
11
+ import type { Diagnostic, Figure, Kind } from "../ir.js";
12
+ import { type LayoutOptions } from "../render/layout.js";
13
+ import type { Scene } from "../render/scene.js";
14
+ import { type ThemeMode } from "../render/theme.js";
15
+ export interface YuiFigureProps extends Omit<LayoutOptions, "width"> {
16
+ figure: Figure;
17
+ /** 既定は auto(CSS 変数・ページの明暗に追従)。 */
18
+ theme?: ThemeMode;
19
+ /** 幅を固定する場合(指定しなければ親の幅に合わせる)。 */
20
+ width?: number;
21
+ className?: string;
22
+ }
23
+ /** シーンを SVG の React 要素にする。 */
24
+ export declare function SceneSvg(props: {
25
+ scene: Scene;
26
+ theme?: ThemeMode;
27
+ fluid?: boolean;
28
+ }): ReactElement;
29
+ /** 図を描く。幅を指定しなければ親の幅に合わせて描き直す。 */
30
+ export declare function YuiFigure(props: YuiFigureProps): ReactElement;
31
+ export interface YuiBlockProps extends Omit<YuiFigureProps, "figure"> {
32
+ /** ` ```ui ` の中身。 */
33
+ source: string;
34
+ /** ストリーミング中か(true なら改行で終わっていない最終行を読まない)。 */
35
+ streaming?: boolean;
36
+ /** フェンスの情報文字列で種類が指定されている場合。 */
37
+ kind?: Kind;
38
+ /** 図にできないときの表示(既定はソースをそのまま表示)。 */
39
+ fallback?: (source: string, diagnostics: Diagnostic[]) => ReactElement | null;
40
+ }
41
+ /** 除外した行などの診断を、図の下に一言で示す。 */
42
+ export declare function diagnosticsSummary(diags: Diagnostic[]): string | null;
43
+ export declare function YuiBlock(props: YuiBlockProps): ReactElement | null;
44
+ /** Markdown レンダラーのコードブロックの className(`language-ui` など)が Yui か。 */
45
+ export declare function isYuiLanguage(className: string | undefined): boolean;
46
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAuF,KAAK,YAAY,EAAkB,MAAM,OAAO,CAAC;AAC/I,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEzD,OAAO,EAAU,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAQ,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAyB,KAAK,SAAS,EAAc,MAAM,oBAAoB,CAAC;AAEvF,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAqED,8BAA8B;AAC9B,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,YAAY,CA8BlG;AAED,kCAAkC;AAClC,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,CAK7D;AAED,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC;IACnE,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+BAA+B;IAC/B,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,kCAAkC;IAClC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,YAAY,GAAG,IAAI,CAAC;CAC/E;AAED,6BAA6B;AAC7B,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,GAAG,IAAI,CAGrE;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,YAAY,GAAG,IAAI,CAclE;AAED,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEpE"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * `@imanect/yui/react`: React で図を描く。
3
+ *
4
+ * - YuiFigure: 中間表現を描く(親の幅に合わせて描き直す)
5
+ * - YuiBlock: ` ```ui ` の中身(ソース)を解析して描く。ストリーミング中でもよい
6
+ * - isYuiLanguage: Markdown レンダラーのコードブロックの言語名が Yui か
7
+ *
8
+ * SVG はシーンから React 要素として組み立てる(HTML 文字列を差し込まない)。
9
+ */
10
+ import { createElement as h, useEffect, useId, useMemo, useRef, useState } from "react";
11
+ import { parseBlock } from "../parse.js";
12
+ import { layout } from "../render/layout.js";
13
+ import { FONT, paint, themeCss } from "../render/theme.js";
14
+ /** 親要素の幅を測る(SSR では fallback)。 */
15
+ function useContainerWidth(fixed, fallback = 640) {
16
+ const ref = useRef(null);
17
+ const [width, setWidth] = useState(fixed ?? fallback);
18
+ useEffect(() => {
19
+ if (fixed !== undefined || !ref.current || typeof ResizeObserver === "undefined")
20
+ return;
21
+ const el = ref.current;
22
+ const update = () => {
23
+ const w = Math.round(el.getBoundingClientRect().width);
24
+ if (w > 0)
25
+ setWidth((prev) => (Math.abs(prev - w) >= 4 ? w : prev));
26
+ };
27
+ update();
28
+ const ro = new ResizeObserver(update);
29
+ ro.observe(el);
30
+ return () => ro.disconnect();
31
+ }, [fixed]);
32
+ return [ref, fixed ?? width];
33
+ }
34
+ function colors(mode, fill, stroke) {
35
+ const s = {};
36
+ if (fill)
37
+ s.fill = fill === "none" ? "none" : paint(fill, mode);
38
+ if (stroke)
39
+ s.stroke = paint(stroke, mode);
40
+ return s;
41
+ }
42
+ function renderItem(it, i, mode, arrowId) {
43
+ const title = it.hint ? h("title", null, it.hint) : null;
44
+ const common = { key: i, opacity: it.opacity };
45
+ switch (it.t) {
46
+ case "rect":
47
+ return h("rect", { ...common, x: it.x, y: it.y, width: Math.max(0, it.w), height: Math.max(0, it.h), rx: it.r, style: colors(mode, it.fill, it.stroke), strokeWidth: it.stroke ? (it.strokeWidth ?? 1) : undefined }, title);
48
+ case "circle":
49
+ return h("circle", { ...common, cx: it.cx, cy: it.cy, r: it.r, style: colors(mode, it.fill, it.stroke), strokeWidth: it.stroke ? (it.strokeWidth ?? 1) : undefined }, title);
50
+ case "path":
51
+ return h("path", {
52
+ ...common,
53
+ d: it.d,
54
+ style: colors(mode, it.fill ?? "none", it.stroke),
55
+ strokeWidth: it.stroke ? (it.strokeWidth ?? 1) : undefined,
56
+ strokeLinecap: it.stroke ? "round" : undefined,
57
+ strokeLinejoin: it.stroke ? "round" : undefined,
58
+ strokeDasharray: it.dash,
59
+ markerEnd: it.arrow ? `url(#${arrowId})` : undefined,
60
+ }, title);
61
+ case "text":
62
+ return h("text", {
63
+ ...common,
64
+ x: it.x,
65
+ y: it.y,
66
+ fontSize: it.size,
67
+ fontWeight: it.weight,
68
+ textAnchor: it.anchor && it.anchor !== "start" ? it.anchor : undefined,
69
+ style: { ...colors(mode, it.fill), ...(it.tabular ? { fontVariantNumeric: "tabular-nums" } : {}) },
70
+ }, it.text, title);
71
+ }
72
+ }
73
+ /** シーンを SVG の React 要素にする。 */
74
+ export function SceneSvg(props) {
75
+ const mode = props.theme ?? "auto";
76
+ const { scene } = props;
77
+ const id = `yui${useId().replace(/[^A-Za-z0-9_-]/g, "")}`;
78
+ const arrowId = `${id}-arrow`;
79
+ const fluid = props.fluid ?? mode === "auto";
80
+ return h("svg", {
81
+ xmlns: "http://www.w3.org/2000/svg",
82
+ className: id,
83
+ viewBox: `0 0 ${scene.width} ${scene.height}`,
84
+ width: fluid ? "100%" : scene.width,
85
+ height: fluid ? undefined : scene.height,
86
+ style: fluid ? { maxWidth: scene.width, height: "auto", display: "block" } : undefined,
87
+ role: "img",
88
+ "aria-labelledby": `${id}-t ${id}-d`,
89
+ fontFamily: FONT,
90
+ }, h("title", { id: `${id}-t` }, scene.title), h("desc", { id: `${id}-d` }, scene.desc), mode === "auto" ? h("style", null, themeCss(`.${id}`)) : null, h("defs", null, h("marker", { id: arrowId, viewBox: "0 0 10 10", refX: 9, refY: 5, markerWidth: 7, markerHeight: 7, orient: "auto-start-reverse" }, h("path", { d: "M1,1L9,5L1,9Z", style: colors(mode, "muted") }))), mode === "auto" ? null : h("rect", { width: "100%", height: "100%", style: colors(mode, "surface") }), ...scene.items.map((it, i) => renderItem(it, i, mode, arrowId)));
91
+ }
92
+ /** 図を描く。幅を指定しなければ親の幅に合わせて描き直す。 */
93
+ export function YuiFigure(props) {
94
+ const { figure, theme, width, className, ...layoutOpts } = props;
95
+ const [ref, w] = useContainerWidth(width);
96
+ const scene = useMemo(() => layout(figure, { ...layoutOpts, width: w }), [figure, w, layoutOpts.locale, layoutOpts.measure, layoutOpts.labels]);
97
+ return h("div", { ref, className, "data-yui": figure.kind }, h(SceneSvg, { scene, theme: theme ?? "auto" }));
98
+ }
99
+ /** 除外した行などの診断を、図の下に一言で示す。 */
100
+ export function diagnosticsSummary(diags) {
101
+ const dropped = diags.filter((d) => d.severity === "warning").length;
102
+ return dropped > 0 ? `${dropped} 件の行を表示できませんでした` : null;
103
+ }
104
+ export function YuiBlock(props) {
105
+ const { source, streaming, kind, fallback, ...rest } = props;
106
+ const result = useMemo(() => parseBlock(source, kind ? { final: !streaming, kind } : { final: !streaming }), [source, streaming, kind]);
107
+ if (!result.figure) {
108
+ if (streaming)
109
+ return null;
110
+ return fallback ? fallback(source, result.diagnostics) : h("pre", { "data-yui-error": "" }, h("code", null, source));
111
+ }
112
+ const note = streaming ? null : diagnosticsSummary(result.diagnostics);
113
+ return h("figure", { style: { margin: 0 }, "data-yui-source": source }, h(YuiFigure, { ...rest, figure: result.figure }), note ? h("figcaption", { style: { fontSize: 12, opacity: 0.7, marginTop: 4 } }, note) : null);
114
+ }
115
+ /** Markdown レンダラーのコードブロックの className(`language-ui` など)が Yui か。 */
116
+ export function isYuiLanguage(className) {
117
+ return /(?:^|\s)language-(?:ui|yui)(?:$|[\s:])/.test(className ?? "");
118
+ }
119
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * bar / line のレイアウト。
3
+ *
4
+ * マークの仕様は dataviz の指針に従う: 棒は 24px 以下・データ側の端だけ 4px の角丸・基線から伸ばす、
5
+ * 線は 2px、点は半径 4 に 2px の背景色の縁、目盛り線は 1px の実線で控えめに、値の数字は控えめに一部だけ。
6
+ */
7
+ import type { ChartFigure } from "../ir.js";
8
+ import { type Ctx } from "./frame.js";
9
+ export declare function layoutChart(ctx: Ctx, f: ChartFigure, y0: number): number;
10
+ //# sourceMappingURL=chart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../../src/render/chart.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAa,KAAK,GAAG,EAA8D,MAAM,YAAY,CAAC;AAuC7G,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAaxE"}
@@ -0,0 +1,239 @@
1
+ /**
2
+ * bar / line のレイアウト。
3
+ *
4
+ * マークの仕様は dataviz の指針に従う: 棒は 24px 以下・データ側の端だけ 4px の角丸・基線から伸ばす、
5
+ * 線は 2px、点は半径 4 に 2px の背景色の縁、目盛り線は 1px の実線で控えめに、値の数字は控えめに一部だけ。
6
+ */
7
+ import { BODY_SIZE, drawLegend, formatTick, formatValue, niceTicks, SMALL_SIZE } from "./frame.js";
8
+ import { fit } from "./measure.js";
9
+ import { barPath } from "./scene.js";
10
+ import { SERIES } from "./theme.js";
11
+ const PLOT_HEIGHT = 220;
12
+ const MAX_BAR = 24;
13
+ const GAP = 2;
14
+ /** 目盛り線は細かい破線にして、データより目立たせない(基線は実線)。 */
15
+ const GRID_DASH = "2 4";
16
+ function seriesNames(f) {
17
+ return f.columns.slice(1);
18
+ }
19
+ function hint(f, label, s, v, ctx) {
20
+ const names = seriesNames(f);
21
+ const name = names.length > 1 ? ` ${names[s]}` : "";
22
+ return `${label}${name}: ${formatValue(v, ctx.locale)}${f.unit ?? ""}`;
23
+ }
24
+ /** 値の範囲(積み上げなら行ごとの合計)。 */
25
+ function extent(f) {
26
+ let lo = 0;
27
+ let hi = 0;
28
+ for (const r of f.rows) {
29
+ if (f.stacked && f.kind === "bar") {
30
+ let pos = 0;
31
+ let neg = 0;
32
+ for (const v of r.values)
33
+ if (v !== null)
34
+ (v >= 0 ? (pos += v) : (neg += v));
35
+ lo = Math.min(lo, neg);
36
+ hi = Math.max(hi, pos);
37
+ }
38
+ else {
39
+ for (const v of r.values)
40
+ if (v !== null)
41
+ ((lo = Math.min(lo, v)), (hi = Math.max(hi, v)));
42
+ }
43
+ }
44
+ return [lo, hi];
45
+ }
46
+ export function layoutChart(ctx, f, y0) {
47
+ const names = seriesNames(f);
48
+ let y = drawLegend(ctx, names, y0, f.kind === "bar" ? "box" : "line");
49
+ if (f.unit) {
50
+ ctx.items.push({ t: "text", x: ctx.pad, y: y + 12, text: ctx.labels.unit(f.unit), size: SMALL_SIZE, fill: "muted" });
51
+ y += 18;
52
+ }
53
+ if (f.rows.length === 0)
54
+ return y;
55
+ const maxLabel = Math.max(...f.rows.map((r) => ctx.measure(r.label, SMALL_SIZE)));
56
+ const plotWidth = ctx.width - ctx.pad * 2 - 48;
57
+ const horizontal = f.kind === "bar" && (f.horizontal === true || f.rows.length > 14 || (f.rows.length > 6 && maxLabel > (plotWidth / f.rows.length) * 1.6));
58
+ return horizontal ? horizontalBars(ctx, f, y) : vertical(ctx, f, y);
59
+ }
60
+ // ---------------------------------------------------------------- 縦向き(棒・折れ線)
61
+ function vertical(ctx, f, top) {
62
+ const S = Math.max(1, f.columns.length - 1);
63
+ const R = f.rows.length;
64
+ const [lo, hi] = extent(f);
65
+ const ticks = niceTicks(lo, hi);
66
+ const tMin = ticks[0];
67
+ const tMax = ticks[ticks.length - 1];
68
+ const tickLabels = ticks.map((t) => formatTick(t, ctx.locale));
69
+ const left = ctx.pad + Math.max(...tickLabels.map((l) => ctx.measure(l, SMALL_SIZE))) + 8;
70
+ const right = ctx.width - ctx.pad;
71
+ const plotTop = top + 6;
72
+ const plotBottom = plotTop + PLOT_HEIGHT;
73
+ const yOf = (v) => plotBottom - ((v - tMin) / (tMax - tMin)) * PLOT_HEIGHT;
74
+ const band = (right - left) / R;
75
+ // 目盛り線と基線
76
+ ticks.forEach((t, i) => {
77
+ const yy = Math.round(yOf(t)) + 0.5;
78
+ ctx.items.push({ t: "path", d: `M${left},${yy}H${right}`, stroke: t === 0 ? "axis" : "grid", strokeWidth: 1, ...(t === 0 ? {} : { dash: GRID_DASH }) });
79
+ ctx.items.push({ t: "text", x: left - 8, y: yy + 4, text: tickLabels[i], size: SMALL_SIZE, fill: "muted", anchor: "end", tabular: true });
80
+ });
81
+ // 横軸のラベル(重なるなら間引く)
82
+ const maxLabel = Math.max(...f.rows.map((r) => ctx.measure(r.label, SMALL_SIZE)));
83
+ const every = Math.max(1, Math.ceil((maxLabel + 6) / band));
84
+ f.rows.forEach((r, i) => {
85
+ if (i % every !== 0)
86
+ return;
87
+ ctx.items.push({ t: "text", x: left + band * (i + 0.5), y: plotBottom + 16, text: fit(r.label, band * every - 4, SMALL_SIZE, ctx.measure), size: SMALL_SIZE, fill: "muted", anchor: "middle" });
88
+ });
89
+ if (f.kind === "bar")
90
+ verticalBars(ctx, f, { left, band, yOf, S });
91
+ else
92
+ lines(ctx, f, { left, band, yOf, S });
93
+ return plotBottom + 24;
94
+ }
95
+ function verticalBars(ctx, f, g) {
96
+ const { left, band, yOf, S } = g;
97
+ const zero = yOf(0);
98
+ const stacked = f.stacked === true && S > 1;
99
+ const bw = stacked ? Math.min(MAX_BAR, band * 0.6) : Math.min(MAX_BAR, (band * 0.72 - GAP * (S - 1)) / S);
100
+ const groupW = stacked ? bw : bw * S + GAP * (S - 1);
101
+ const showValues = S === 1 && f.rows.length <= 12;
102
+ f.rows.forEach((r, i) => {
103
+ const gx = left + band * i + (band - groupW) / 2;
104
+ if (stacked) {
105
+ let pos = 0;
106
+ let neg = 0;
107
+ const lastPos = r.values.reduce((k, v, s) => (v !== null && v > 0 ? s : k), -1);
108
+ const lastNeg = r.values.reduce((k, v, s) => (v !== null && v < 0 ? s : k), -1);
109
+ r.values.forEach((v, s) => {
110
+ if (v === null || v === 0)
111
+ return;
112
+ const from = v > 0 ? pos : neg;
113
+ const to = from + v;
114
+ if (v > 0)
115
+ pos = to;
116
+ else
117
+ neg = to;
118
+ const y1 = Math.min(yOf(from), yOf(to));
119
+ const y2 = Math.max(yOf(from), yOf(to));
120
+ const isEnd = v > 0 ? s === lastPos : s === lastNeg;
121
+ // 積み重ねの切れ目に 2px の背景色の隙間
122
+ const h = Math.max(0.5, y2 - y1 - (isEnd ? 0 : GAP));
123
+ const yy = v > 0 ? y2 - h : y1;
124
+ ctx.items.push({ t: "path", d: isEnd ? barPath(gx, yy, bw, h, 4, v > 0 ? "top" : "bottom") : `M${gx},${yy}h${bw}v${h}h${-bw}Z`, fill: SERIES[s % 8], hint: hint(f, r.label, s, v, ctx) });
125
+ });
126
+ return;
127
+ }
128
+ r.values.forEach((v, s) => {
129
+ if (v === null)
130
+ return;
131
+ const x = gx + s * (bw + GAP);
132
+ const yv = yOf(v);
133
+ const h = Math.max(1, Math.abs(zero - yv));
134
+ ctx.items.push({ t: "path", d: barPath(x, Math.min(zero, yv), bw, h, 4, v >= 0 ? "top" : "bottom"), fill: SERIES[s % 8], hint: hint(f, r.label, s, v, ctx) });
135
+ if (showValues) {
136
+ const text = formatValue(v, ctx.locale);
137
+ if (ctx.measure(text, SMALL_SIZE) <= band - 2) {
138
+ ctx.items.push({ t: "text", x: x + bw / 2, y: v >= 0 ? yv - 5 : yv + 13, text, size: SMALL_SIZE, fill: "ink2", anchor: "middle", tabular: true });
139
+ }
140
+ }
141
+ });
142
+ });
143
+ }
144
+ function lines(ctx, f, g) {
145
+ const { left, band, yOf, S } = g;
146
+ const dots = f.rows.length <= 16;
147
+ for (let s = 0; s < S; s++) {
148
+ const token = SERIES[s % 8];
149
+ let d = "";
150
+ let pen = false;
151
+ const pts = [];
152
+ f.rows.forEach((r, i) => {
153
+ const v = r.values[s];
154
+ if (v === null || v === undefined) {
155
+ pen = false;
156
+ return;
157
+ }
158
+ const x = +(left + band * (i + 0.5)).toFixed(2);
159
+ const yy = +yOf(v).toFixed(2);
160
+ d += `${pen ? "L" : "M"}${x},${yy}`;
161
+ pen = true;
162
+ pts.push([x, yy, v, r.label]);
163
+ });
164
+ if (d)
165
+ ctx.items.push({ t: "path", d, stroke: token, strokeWidth: 2 });
166
+ const marked = dots ? pts : pts.slice(-1);
167
+ for (const [x, yy, v, label] of marked) {
168
+ ctx.items.push({ t: "circle", cx: x, cy: yy, r: 4, fill: token, stroke: "surface", strokeWidth: 2, hint: hint(f, label, s, v, ctx) });
169
+ }
170
+ }
171
+ // 1 系列なら終点の値だけ添える
172
+ if (S === 1) {
173
+ const lastRow = [...f.rows].reverse().find((r) => r.values[0] !== null && r.values[0] !== undefined);
174
+ if (lastRow) {
175
+ const i = f.rows.indexOf(lastRow);
176
+ const v = lastRow.values[0];
177
+ ctx.items.push({ t: "text", x: left + band * (i + 0.5), y: yOf(v) - 10, text: formatValue(v, ctx.locale), size: SMALL_SIZE, fill: "ink2", anchor: "middle", tabular: true });
178
+ }
179
+ }
180
+ }
181
+ // ---------------------------------------------------------------- 横向きの棒(行が多い・ラベルが長い)
182
+ function horizontalBars(ctx, f, top) {
183
+ const S = Math.max(1, f.columns.length - 1);
184
+ const stacked = f.stacked === true && S > 1;
185
+ const thick = stacked || S === 1 ? 14 : Math.max(6, Math.min(12, 30 / S));
186
+ const rowH = stacked || S === 1 ? 24 : S * (thick + GAP) + 10;
187
+ const [lo, hi] = extent(f);
188
+ const ticks = niceTicks(lo, hi, 4);
189
+ const tMin = ticks[0];
190
+ const tMax = ticks[ticks.length - 1];
191
+ const labelW = Math.min(Math.max(...f.rows.map((r) => ctx.measure(r.label, BODY_SIZE))), ctx.width * 0.32);
192
+ const left = ctx.pad + labelW + 8;
193
+ const right = ctx.width - ctx.pad - (S === 1 ? 52 : 8);
194
+ const xOf = (v) => left + ((v - tMin) / (tMax - tMin)) * (right - left);
195
+ const zero = xOf(0);
196
+ const plotTop = top + 4;
197
+ const plotBottom = plotTop + rowH * f.rows.length;
198
+ ticks.forEach((t) => {
199
+ const xx = Math.round(xOf(t)) + 0.5;
200
+ ctx.items.push({ t: "path", d: `M${xx},${plotTop}V${plotBottom}`, stroke: t === 0 ? "axis" : "grid", strokeWidth: 1, ...(t === 0 ? {} : { dash: GRID_DASH }) });
201
+ ctx.items.push({ t: "text", x: xx, y: plotBottom + 14, text: formatTick(t, ctx.locale), size: SMALL_SIZE, fill: "muted", anchor: "middle", tabular: true });
202
+ });
203
+ f.rows.forEach((r, i) => {
204
+ const cy = plotTop + rowH * i + rowH / 2;
205
+ ctx.items.push({ t: "text", x: left - 8, y: cy + 4, text: fit(r.label, labelW, BODY_SIZE, ctx.measure), size: BODY_SIZE, fill: "ink2", anchor: "end" });
206
+ if (stacked) {
207
+ let pos = 0;
208
+ let neg = 0;
209
+ r.values.forEach((v, s) => {
210
+ if (v === null || v === 0)
211
+ return;
212
+ const from = v > 0 ? pos : neg;
213
+ const to = from + v;
214
+ if (v > 0)
215
+ pos = to;
216
+ else
217
+ neg = to;
218
+ const x1 = Math.min(xOf(from), xOf(to));
219
+ const w = Math.max(0.5, Math.abs(xOf(to) - xOf(from)) - GAP);
220
+ ctx.items.push({ t: "rect", x: v > 0 ? x1 : x1 + GAP, y: cy - thick / 2, w, h: thick, fill: SERIES[s % 8], hint: hint(f, r.label, s, v, ctx) });
221
+ });
222
+ return;
223
+ }
224
+ const groupH = S * thick + (S - 1) * GAP;
225
+ r.values.forEach((v, s) => {
226
+ if (v === null)
227
+ return;
228
+ const yy = cy - groupH / 2 + s * (thick + GAP);
229
+ const xv = xOf(v);
230
+ const w = Math.max(1, Math.abs(xv - zero));
231
+ ctx.items.push({ t: "path", d: barPath(Math.min(zero, xv), yy, w, thick, 4, v >= 0 ? "right" : "left"), fill: SERIES[s % 8], hint: hint(f, r.label, s, v, ctx) });
232
+ if (S === 1) {
233
+ ctx.items.push({ t: "text", x: v >= 0 ? xv + 6 : xv - 6, y: cy + 4, text: formatValue(v, ctx.locale), size: SMALL_SIZE, fill: "ink2", anchor: v >= 0 ? "start" : "end", tabular: true });
234
+ }
235
+ });
236
+ });
237
+ return plotBottom + 24;
238
+ }
239
+ //# sourceMappingURL=chart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart.js","sourceRoot":"","sources":["../../src/render/chart.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * flow: 流れ図のレイアウト(Sugiyama 法の簡易版)。
3
+ *
4
+ * 1. 逆向きの辺(ループ)を見つけて外す 2. 最長経路で段を決める 3. 段をまたぐ辺に中継点を入れる
5
+ * 4. 重心法で段の中の並びを決める 5. 座標を決める 6. 辺を直角に曲げて引く(ループは脇を回す)
6
+ *
7
+ * 分岐(出る辺が 2 本以上)のノードはひし形にする。形はモデルに決めさせない。
8
+ */
9
+ import type { FlowFigure } from "../ir.js";
10
+ import { type Ctx } from "./frame.js";
11
+ export declare function layoutFlow(ctx: Ctx, f: FlowFigure, top: number): number;
12
+ //# sourceMappingURL=flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../src/render/flow.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,UAAU,CAAC;AACrD,OAAO,EAAE,KAAK,GAAG,EAAc,MAAM,YAAY,CAAC;AA+ClD,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAWvE"}