mviz v1.7.0
mviz 是做什么的?
生成整洁、数据聚焦的图表和仪表盘,基于紧凑的JSON规范或Markdown。最大化数据-墨水平比,最小化图表垃圾、网格线和装饰元素。采用16列网格布局系统。
设置
无需安装。使用 npx -y -q mviz 自动从npm下载。-q 标志减少npm输出,同时仍显示lint错误。
如需更快速地重复使用,可全局安装:npm install -g mviz
此技能的作用
mviz 包含两部分:
- 规范语言 — 使用围栏代码块描述组件(图表、KPI、表格、注释等)的Markdown。一个Markdown文件(或单个JSON规范)描述整个可视化。
- 一组渲染器 — 将规范转换为适用于不同显示上下文的HTML。目前有两种:
visualize:show_widget(内联)— 当你在 claude.ai 且可视化工具可用时,将mviz规范渲染为widget_codeHTML片段,使用 claude.ai 的设计系统(Chart.js、var(--color-*)令牌)。该小组件内联显示在对话中。- mviz CLI(独立)—
mviz dashboard.md -o report.html生成一个完整的HTML文档,使用mviz自己的设计系统(mdsinabox主题,ECharts)。适用于下载、iframe图块、打印/PDF。
mviz Markdown规范是规范性的;渲染器根据可视化的展示位置选择。同一规范,两种渲染。第三方可以构建不同的渲染器(基于Chart.js的CLI、Slack主题渲染器等),而无需更改规范。
选择渲染器
始终先编写mviz Markdown规范,即使是在内联渲染时也是如此。规范是规范性的产物——在响应中将其放在围栏代码块中,以便用户稍后复制/重用/管道到CLI。然后使用适合需求的渲染器进行渲染。
在渲染之前,确定哪个渲染器更合适——并陈述你的推断,以便用户可以纠正你。一些信号:
内联(visualize:show_widget):
- "展示X" / "X是什么" / "X如何变化" / "渲染"
- 一个小型可视化(通常1-4个组件),与周围文本自然衔接
- 用户正在探索数据,而非准备分享的内容
visualize:show_widget在此对话中可用
独立(mviz CLI):
- "制作一份报告" / "把文件发给我" / "导出为PDF" / "保存"
- 多节组合视图(5个以上组件,分隔线,分页符,全宽表格)
- 用户想要保存、分享、打印或嵌入到外部宿主(iframe图块、仪表盘单元格)的内容
visualize:show_widget不可用(无内联渲染表面)
当有歧义时,默认使用内联。明确陈述推断:
"我将内联渲染,因为你要求在聊天中查看。如果你想要一个可下载的文件,我可以在同一规范上运行mviz CLI——只需说一声。"
如果用户在内联渲染后要求文件版本,规范已在对话中——直接通过 mviz ... -o out.html 管道输出,无需重新编写。
视觉风格(mdsinabox主题 — 用于CLI渲染器)
- 字体:Helvetica Neue, Arial(简洁无衬线)
- 标志:仪表盘顶部橙色强调线
- 调色板:蓝色主色,橙色辅助色,语义色(绿色=正面,琥珀色=警告,红色=错误)
- 背景:浅色纸色(
#f8f8f8)/ 深色(#231f20) - 原则:高数据-墨水平比,无图表垃圾,最小化网格线,数据自我表达
渲染器:mviz CLI(独立HTML)
CLI渲染器生成一个完整的HTML文档,样式采用上述mdsinabox主题。输出适用于直接浏览器查看、PDF导出、iframe嵌入或作为文件共享。
单个图表(JSON)
echo '<json_spec>' | npx -y -q mviz -o chart.html
从Markdown创建仪表盘
npx -y -q mviz dashboard.md -o dashboard.html
从文件夹创建仪表盘
npx -y -q mviz my-dashboard/ -o dashboard.html
Iframe嵌入输出(--embed)
当渲染后的HTML将放置在另一个产品的iframe中(mdw-turbo Prism图块、仪表盘单元格等)时,传递 --embed 以去除页面外壳(红色强调条、标题行、主题切换),并应用一系列后处理来精简主体:CSS修剪、透明背景以使宿主的卡片外壳透出、当无图表时删除ECharts脚本、当无 marked.parse(...) 调用时删除marked、JS压缩等。
npx -y -q mviz dashboard.md --embed -o tile.html
嵌入模式生成一个完整的HTML文档(DOCTYPE + html + head + body 完整保留)。它不适用于 visualize:show_widget —— 对于该场景,请使用另一个渲染器(见下文)。
16列网格系统
组件使用 size=[cols,rows] 语法调整大小:
```big_value size=[4,2]
{"value": 1250000, "label": "Revenue", "format": "currency0m"}
```
```bar size=[8,6]
{"title": "Sales", "x": "month", "y": "sales", "file": "data/sales.json"}
```
- 总计16列(纵向和横向均适用)
- 行高:每行单位约32px(近似值——图表有内边距)
- 页面容量:纵向 [16c × 30r],横向 [16c × 22r]
- 同一行的组件共享该行
- 空行 = 新行
高度指南:
| 行单位 | 近似高度 | 适用场景 |
|---|---|---|
| 2 | ~64px | KPI,单行注释 |
| 4 | ~128px | 小型表格,文本块 |
| 5-6 | ~160-192px | 标准图表 |
| 8+ | ~256px+ | 密集表格,详细图表 |
对于包含多个类别(10+条形,10+哑铃行)的图表,增加行单位以防止压缩。
并排布局
关键: 要将组件并排放置,它们的代码块之间不能有空白行:
```bar size=[8,5]
{"title": "Chart A", ...}
```
```line size=[8,5]
{"title": "Chart B", ...}
```
这样渲染时,图表A和图表B位于同一行。在它们之间添加空白行会导致它们位于不同行。
标题和分节符
| 语法 | 效果 |
|---|---|
# H1 | 页面标题 |
## H2 | 节标题 |
### H3 | 轻量级内联标题(微妙,较小文字) |
--- | 视觉分隔线 |
=== | 打印分页符 |
empty_space | 不可见网格单元格占位符(默认4列 × 2行) |
标题指南:
- 使用 frontmatter
title:或 开头的# H1设置页面标题,不要同时使用。 - 在页面内使用
## H2作为节标题(最常见)。 - 使用
### H3作为不影响流程的轻量级副标题。
分节符与分页符:
- 使用
---在视觉上分隔逻辑部分。内容在需要时会自然流动到下一页。 - 仅在明确需要强制新页面时使用
===(例如,为PDF输出分隔章节或主要报告部分)。 - 默认情况下绝不使用
===。仅在用户特别要求时才添加分页符。
默认尺寸
| 组件 | 默认尺寸 | 备注 |
|---|---|---|
big_value | [4, 2] | 每行4个 |
delta | [4, 2] | 每行4个 |
sparkline | [4, 2] | 紧凑内联图表 |
bar, line, area | [8, 5] | 半宽 |
pie, scatter, bubble | [8, 5] | 半宽 |
funnel, sankey, heatmap | [8, 5] | 半宽 |
histogram, boxplot, waterfall | [8, 5] | 半宽 |
combo | [8, 5] | 半宽 |
dumbbell | [12, 6] | 3/4宽 |
table | [16, 4] | 全宽 |
textarea | [16, 4] | 全宽 |
calendar | [16, 3] | 全宽 |
xmr | [16, 6] | 全宽,较高 |
mermaid | [8, 5] | 半宽(使用 ascii: true 表示文本图形) |
alert, note, text | [16, 1] | 全宽,单行 |
empty_space | [4, 2] | 不可见占位符 |
推荐尺寸搭配
| 布局目标 | 组件 | 尺寸 |
|---|---|---|
| 一行4个KPI | 4× big_value | 每个 [4,2] |
| 一行5个KPI | 4× big_value + 1个更宽 | [3,2] + [4,2] |
| KPI + 上下文 | big_value + textarea | [3,2] + [13,2] |
| KPI + 图表 | big_value + bar | [4,2] + [12,5] |
示例:密集KPI行
```big_value size=[3,2]
{"value": 1250000, "label": "Revenue", "format": "currency0m"}
```
```big_value size=[3,2]
{"value": 8450, "label": "Orders", "format": "num0k"}
```
```big_value size=[3,2]
{"value": 2400000000, "label": "Queries", "format": "num0b"}
```
```delta size=[3,2]
{"value": 0.15, "label": "MoM", "format": "pct0"}
```
```delta size=[4,2]
{"value": 0.08, "label": "vs Target", "format": "pct0"}
```
这将创建一行包含5个KPI(3+3+3+3+4 = 16列)。
示例:两个图表并排
```bar size=[8,6] file=data/region-sales.json
```
```line size=[8,6] file=data/monthly-trend.json
```
支持的类型
图表: bar, line, area, pie, scatter, bubble, boxplot, histogram, waterfall, xmr, sankey, funnel, heatmap, calendar, sparkline, combo, dumbbell, mermaid
UI组件: big_value, delta, alert, note, text, textarea, empty_space, table
表格格式化
表格支持列级别和单元格级别的格式化:
列选项: bold, italic, type("sparkline" 或 "heatmap")
{
"type": "table",
"columns": [
{"id": "product", "title": "Product", "bold": true},
{"id": "category", "title": "Category", "italic": true},
{"id": "sales", "title": "Sales", "fmt": "currency"},
{"id": "margin", "title": "Margin", "type": "heatmap", "fmt": "pct"},
{"id": "trend", "title": "Trend", "type": "sparkline", "sparkType": "line"}
],
"data": [
{"product": "Widget", "category": "Electronics", "sales": 125000, "margin": 0.85, "trend": [85, 92, 88, 95, 102, 125]}
]
}
单元格级别覆盖: 使用 {"value": "text", "bold": true} 覆盖列默认值。
热力图: 从低到高值应用颜色渐变。深色背景上文字自动切换到白色。
迷你图类型: line, bar, area, pct_bar(进度条), dumbbell(前后对比)
排序与过滤:
| 字段 | 值 | 默认值 | 效果 |
|---|---|---|---|
sortable | true / false | true | 点击列标题进行排序。循环切换 升序 → 降序 → 关闭。数值列按原始值排序。 |
filter | true / false | false | 为 true 时,在表格上方渲染一个“按任意值过滤…”搜索输入框。行根据所有单元格的不区分大小写的包含匹配进行实时过滤。 |
示例:{"type": "table", "filter": true, "columns": [...], "data": [...]}
注释类型
注释通过 noteType 支持三种严重级别:
| 类型 | 边框颜色 | 用途 |
|---|---|---|
default | 红色 | 重要通知(默认) |
warning | 黄色 | 警告,初步数据 |
tip | 绿色 | 最佳实践,专业提示 |
注释还支持可选的 label 作为粗体前缀文本:
{"type": "note", "label": "Pro Tip:", "content": "Use keyboard shortcuts for faster navigation.", "noteType": "tip"}
专门图表示例
big_value - 主指标大数字显示:
{"type": "big_value", "value": 1250000, "label": "Revenue", "format": "currency0m"}
- 可选的
comparison对象:{"value": 10300, "format": "currency", "label": "vs last month"}显示变化方向箭头
dumbbell - 前后对比,带方向着色:
{
"type": "dumbbell",
"title": "ELO Changes",
"category": "team",
"start": "before",
"end": "after",
"startLabel": "Week 1",
"endLabel": "Week 2",
"higherIsBetter": true,
"data": [
{"team": "Chiefs", "before": 1650, "after": 1720},
{"team": "Bills", "before": 1600, "after": 1550}
]
}
- 绿色 = 改善,红色 = 下降,灰色 = 无变化
higherIsBetter: false用于排名(越低越好)- 标签自动缩写大数字(7450 → "7k")
delta - 变化指标,带方向着色:
{"type": "delta", "value": 0.15, "label": "MoM Growth", "format": "pct0"}
- 正值显示绿色带 ▲,负值显示红色带 ▼
- 可选的
comparison对象:{"value": 0.05, "label": "vs Target"}
area - 填充折线图,用于累积/体积数据:
{
"type": "area",
"title": "Daily Active Users",
"x": "date",
"y": "users",
"data": [{"date": "Mon", "users": 1200}, {"date": "Tue", "users": 1450}]
}
combo - 条形图+折线图,带双Y轴:
{
"type": "combo",
"title": "Revenue vs Growth Rate",
"x": "quarter",
"y": ["revenue", "growth_rate"],
"data": [
{"quarter": "Q1", "revenue": 1000000, "growth_rate": 0.15},
{"quarter": "Q2", "revenue": 1200000, "growth_rate": 0.20}
]
}
- 第一个y字段渲染为条形,第二个为折线
- 双Y轴,独立刻度
heatmap - 二维矩阵可视化:
{
"type": "heatmap",
"title": "Activity by Hour",
"xCategories": ["Mon", "Tue", "Wed", "Thu", "Fri"],
"yCategories": ["9am", "12pm", "3pm", "6pm"],
"format": "num0",
"data": [[0, 0, 85], [1, 0, 90], [2, 0, 72]]
}
format选项应用于单元格标签(例如num0k,currency0k,pct)
funnel - 转化或淘汰流程:
{
"type": "funnel",
"title": "Sales Pipeline",
"format": "num0",
"data": [
{"stage": "Leads", "value": 1000},
{"stage": "Qualified", "value": 600},
{"stage": "Proposal", "value": 300},
{"stage": "Closed", "value": 100}
]
}
format选项应用于标签/工具提示(例如currency_auto,pct,num0)
waterfall - 累积变化可视化:
{
"type": "waterfall",
"title": "Revenue Bridge",
"x": "item",
"y": "value",
"data": [
{"item": "Start", "value": 1000, "isTotal": true},
{"item": "Growth", "value": 200},
{"item": "Churn", "value": -50},
{"item": "End", "value": 1150, "isTotal": true}
]
}
bubble - 带尺寸维度的散点图。支持 series 进行颜色分组和 showLabels