# Visualise

> 在对话中直接渲染内联交互式可视化——SVG 图、HTML 组件、图表、讲解图。当用户要求画图、做图、画流程图、架构图、数据可视化、UI mockup，或说'画个图''show me''draw''map out''visualize''diagram'时触发；即使没明说，只要主题有空间/顺序/系统性关系、用图比文字更清楚，也应主动使用。

- Skill: `shyxin/visualise` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add shyxin/visualise`
- Raw SKILL.md: https://api.skillmd.com/api/skills/shyxin/visualise/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: shyxin (https://skillmd.com/u/shyxin)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/shyxin/visualise

---


# Inline Visualizer（内联可视化器）

在对话里直接渲染富可视化内容——SVG 图、HTML 交互组件、图表。输出以 token 流方式逐字注入一个沙箱化 iframe，观感像对话的自然延伸，而不是一个附件。

## 工作原理

你生成原始 HTML 或 SVG 片段。客户端把它们渲染进一个沙箱化 iframe，并注入设计系统的 CSS 变量。不要写 `<html>`、`<head>`、`<body>` 标签——只写内容片段。

**两种输出模式：**

- **SVG 模式**：输出以 `<svg>` 开头。客户端自动包进卡片。最适合静态图。
- **HTML 模式**：原始 HTML 片段。最适合交互内容（滑块、标签页、图表、控件）。你可以在 HTML 模式里内嵌 `<svg>` 元素。

客户端根据输出是否以 `<svg` 开头来判断模式。

## 生成任何可视化之前

先读设计系统参考，再开始画第一个图：

1. **永远先读**：`references/design-system.md` — CSS 变量、色阶、排版、核心规则
2. **再读相关模块**：
   - 图（流程图、结构图、示意解释图）：`references/diagrams.md`
   - 交互讲解、对比、数据记录：`references/components.md`
   - 图表（Chart.js、数据可视化）：`references/charts.md`

每次对话读一次设计系统文件。每种图按需读对应模块文件。

## 流式约束

输出以 token 流注入 DOM。这决定了结构顺序：

1. 先 `<style>`（控制在 15 行内——优先用内联样式）
2. 再放可见的 HTML/SVG 内容（用户能看到它逐步生成）
3. 最后 `<script>`（流结束后才执行）

**因为流式：**
- 不要渐变、投影、模糊、发光——它们在 DOM diff 时会闪。用平涂填充。
- 不要 `display:none` 或隐藏内容——会以不可见方式流出。
- 不要 `<!-- 注释 -->` 或 `/* 注释 */`——浪费 token、破坏流式。
- 优先用内联 `style="..."` 而非 `<style>` 块，让元素在流式中途就正确显示。
- 不要起始隐藏的标签页或轮播——流式期间所有内容纵向堆叠展示。流式结束后的 JS 再加交互。

## Iframe 沙箱规则

可视化渲染在沙箱化 iframe 里。这些是硬性约束：

- **不要 localStorage / sessionStorage** — 所有状态必须在内存里
- **不要 position: fixed** — iframe 按内容高度自动撑高；fixed 元素会让它塌掉
- **不要外部请求** — CSP 会拦截 widget 内的 API 调用
- **仅允许 CDN 白名单**：`cdnjs.cloudflare.com`、`esm.sh`、`cdn.jsdelivr.net`、`unpkg.com`
- **不要 DOCTYPE、`<html>`、`<head>`、`<body>`** — 只写内容片段
- 背景透明——容器/卡片样式由宿主提供
- 通过 `<script src="https://cdnjs.cloudflare.com/ajax/libs/...">` 加载库（UMD 全局变量）

## sendPrompt 桥接

iframe 内可用全局函数 `sendPrompt(text)`。它把一条消息发到聊天，就像用户自己输入的一样。用它让可视化变得可对话——点击图里的节点可以触发后续讲解。

当用户下一步需要模型思考时才用 `sendPrompt`；筛选、排序、切换、计算放在本地 JS 里处理。

## 选对可视化类型

按"动词"而非"名词"路由。同一个主题，按被问的方式得到不同处理：

| 用户说 | 类型 | 该画什么 |
|--------|------|----------|
| "X 是怎么工作的" | 示意解释图 | 展示机制的立体隐喻 |
| "X 由哪些部分组成" | 结构图 | 带标签的盒子表示包含关系 |
| "带我走一遍步骤" | 流程图 | 顺序盒子加箭头 |
| "对比 X 和 Y" | 对比布局 | 左右并排的卡片带指标 |
| "把数据给我看" | 图表 | Chart.js 或内联数据可视化 |
| "解释 X"（空间概念） | 交互讲解 | 滑块、控件、实时状态 |

"X 是怎么工作的"默认画示意解释图——这是更进阶的选择。不要因为流程图更"安全"就退而求其次。

## 一次回复里放多个可视化

在一次回复里生成多个可视化，与文字交错：

1. 文字块（引入/讲解）
2. 可视化
3. 文字块（过渡）
4. 可视化（如需）

两个可视化之间绝不能没有文字直接堆叠。

## 输出包裹

把可视化输出包在语言标签为 `visualizer` 的代码围栏里，让客户端识别并路由到 iframe 渲染器：

````
```visualizer
<svg width="100%" viewBox="0 0 680 400">
  ...
</svg>
```
````

客户端剥离围栏，把内容注入 iframe，并在前面加上主题变量。

## 速查表

| 规则 | 值 |
|------|-----|
| SVG viewBox 宽度 | 固定 680px |
| 字号 | 标签 14px，副标题 12px |
| 描边宽度 | 边框与连线 0.5px |
| 单图最多色数 | 2-3 个色阶 |
| 盒子副标题长度 | ≤5 个词 |
| 圆角（SVG） | rx="4" 默认，强调用 rx="8" |
| 圆角（HTML） | `var(--border-radius-md)` 或 `-lg` |
| 最小字号 | 11px |
| 字重 | 仅 400 常规、500 加粗 |
| 标题字号 | h1=22px，h2=18px，h3=16px |

