npx skills add https://github.com/matsonj/mviz --skill mvizmviz v1.6.4
从简洁的 JSON 规范或 Markdown 生成清晰、以数据为中心的图表和仪表板。最大化数据墨水比,减少不必要的图表装饰、网格线和装饰性元素。使用 16 列网格布局系统。
无需安装。使用 npx -y -q mviz 会自动从 npm 下载。-q 标志可减少 npm 输出,同时仍显示 lint 错误。
如需更快的重复使用,请全局安装:npm install -g mviz
使用 ECharts 将最简化的 JSON 规范转换为独立的 HTML 可视化。无需编写 50-100 行图表代码,只需编写一个简洁的规范,即可扩展为具有专业样式的完整 HTML 成品。
#f8f8f8 浅色) / 深色 (#231f20 深色)广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
echo '<json_spec>' | npx -y -q mviz -o chart.html
npx -y -q mviz dashboard.md -o dashboard.html
npx -y -q mviz my-dashboard/ -o dashboard.html
组件使用 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"}
```
高度指南:
| 行单位 | 近似高度 | 适用于 |
|---|---|---|
| 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 | 轻量级内联标题 (微妙,较小文本) |
--- | 视觉分隔线 |
=== | 用于打印的换页符 |
=== | 显式换页符:在 PDF 中强制新页面 |
empty_space | 不可见的网格单元格间隔 (默认 4 列 × 2 行) |
标题指南:
# H1 表示在打印时需要单独页面的主要文档分区## H2 表示页面内的内容分区 (最常见)### H3 表示不中断流程的轻量级子标题continuous: true 模式下,H1 的换页符会被抑制分区符与换页符:
--- 在视觉上分隔逻辑分区。内容在需要时会自然地流到下一页。===。===。仅在用户明确要求时才添加换页符。| 组件 | 默认尺寸 | 备注 |
|---|---|---|
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] |
```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 (前后比较)
注释通过 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 用于排名 (越低越好)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}
]
}
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 用于持久标签:
{
"type": "bubble",
"title": "Market Analysis",
"x": "growth",
"y": "profit",
"size": "revenue",
"series": "region",
"label": "company",
"data": [
{"growth": 5, "profit": 20, "revenue": 100, "region": "US", "company": "Acme"},
{"growth": 10, "profit": 15, "revenue": 200, "region": "EU", "company": "Beta"}
]
}
sankey - 显示关系的流程图:
{
"type": "sankey",
"title": "Traffic Sources",
"data": [
{"source": "Organic", "target": "Landing", "value": 500},
{"source": "Paid", "target": "Landing", "value": 300},
{"source": "Landing", "target": "Signup", "value": 400}
]
}
mermaid - 来自 Mermaid 语法的图表 (流程图、序列图、状态图、类图、ER 图)。使用数组表示多行代码:
{
"type": "mermaid",
"title": "User Flow",
"code": [
"graph TD",
" A[Start] --> B{Decision}",
" B -->|Yes| C[Action]",
" B -->|No| D[End]"
]
}
mermaid (ASCII) - ASCII/Unicode 文本图表 (设置 ascii: true):
{
"type": "mermaid",
"title": "Process Flow",
"code": ["graph LR", " A[Input] --> B[Process] --> C[Output]"],
"ascii": true
}
Mermaid lint 规则 (会导致验证失败的错误):
<br/> 标签 (渲染为字面文本,而非换行符)A["text"] (引号会出现在输出中)| 格式 | 示例 | 用于 |
|---|---|---|
auto | 1.000m, 10.00k | 智能自动格式化 (推荐) |
currency_auto | $1.000m, $10.00k | 带 $ 前缀的智能自动格式化 |
currency0m | $1.2m | 百万 |
currency0b | $1.2b | 十亿 |
currency0k | $125k | 千 |
currency | $1,250,000 | 详细金额 |
num0m | 1.2m | 百万 |
num0b | 1.2b | 十亿 |
num0k | 125k | 千 |
num0 | 1,250,000 | 详细计数 |
pct | 15.0% | 带小数的百分比 |
pct0 | 15% | 整数百分比 |
pct1 | 15.0% | 带 1 位小数的百分比 |
重要提示: 百分比格式期望十进制值 (0.25 = 25%),而不是整数。
推荐使用智能格式化 (auto/currency_auto)。 format 选项同时应用于条形图的轴标签和数据标签。它会根据数值大小自动选择正确的后缀 (k, m, b),并始终显示 4 位有效数字。负值用括号括起:(1.000m)。
当未指定格式时,默认使用智能格式化。
图表轴会根据字段名称自动检测适当的格式:
| 字段模式 | 自动格式 | 示例 |
|---|---|---|
| revenue, sales, price, cost, profit, amount | currency_auto | $1.250m |
| pct, percent, rate, ratio | pct | 15.0% |
| 所有其他数字字段 | auto | 1.250m |
可以在图表规范中使用显式的 format 字段进行覆盖。
图表生成器会自动检测列式查询结果。无需手动将 columns/rows 转换为 data,直接传递结果即可:
{
"type": "bar",
"title": "Sales by Region",
"x": "region",
"y": "sales",
"columns": ["region", "sales"],
"rows": [["North", 45000], ["South", 32000], ["East", 28000]]
}
这会在内部自动转换。无需手动重建 JSON。
对于折线图、面积图、条形图和组合图,可以使用 yMin 和 yMax 控制 y 轴范围:
{
"type": "line",
"title": "Elo Rating Trend",
"x": "date",
"y": "elo",
"yMin": 1400,
"data": [{"date": "Oct", "elo": 1511}, {"date": "Jan", "elo": 1636}]
}
使用 yMin 的情况:
使用 yMax 的情况:
CLI 使用内置的 lint 规则自动验证规范。使用 --lint 标志进行仅验证模式:
npx -y -q mviz --lint dashboard.md # 验证而不生成 HTML
| 规则 | 严重性 | 触发条件 |
|---|---|---|
required-fields | 警告 | 缺少必需字段,如 x, y, 或 data |
unknown-field | 警告 | 图表类型不支持的字段 |
time-series-sorted | 错误 | 时间序列数据未按时间顺序排列 |
sankey-wrong-keys | 错误 | 使用 from/to 而不是 source/target |
big-value-string | 错误 | 传递 "62.5%" 字符串而不是 0.625 数字 |
duplicate-x-values | 警告 | x 轴上有重复值 |
mermaid-no-br-tags | 错误 | mermaid 代码中有 <br/> 标签 (渲染为字面文本) |
mermaid-no-quoted-labels | 错误 | 流程图中出现带引号的标签,如 A["text"] |
错误 会以代码 1 退出。警告 会记录到 stderr 但不会失败。
时间序列错误: 在将数据传递给图表之前,按日期对数据进行排序。
Sankey 键错误: 在数据中使用 source, target, value:
{"source": "A", "target": "B", "value": 100}
big_value 字符串错误: 传递带格式选项的数值:
{"type": "big_value", "value": 0.625, "format": "pct0", "label": "Rate"}
当检测到问题时,生成器会向 stderr 输出有用的警告:
| 警告 | 原因 | 解决方案 |
|---|---|---|
Invalid JSON in 'bar' block | JSON 语法错误 | 检查 JSON 语法,确保引号正确 |
Unknown component type 'bars' | 图表类型拼写错误 | 使用建议的类型 (例如,bar 而不是 bars) |
Cannot resolve 'file=...' | 文件引用没有基础目录 | 使用文件路径参数或内联 JSON |
Row exceeds 16 columns | 一行中组件太多 | 减少组件宽度或拆分成多行 |
警告包括上下文,如内容预览、类似类型建议以及分区/行信息。
如果条形图、折线图或面积图上的数据标签在顶部被截断:
yMax 设置为比该值高约 10-15%示例: 如果最大值为 200,设置 "yMax": 220
{
"type": "bar",
"title": "Sales",
"x": "month",
"y": "sales",
"yMax": 250,
"data": [{"month": "Jan", "sales": 180}, {"month": "Feb", "sales": 220}]
}
这为条形上方的标签文本提供了空间。
使用 SQL 生成数据文件,而不是手动编写 JSON。这可以减少错误并确保数据准确性:
-- 生成图表数据文件
COPY (
SELECT month, SUM(sales) as sales, SUM(revenue) as revenue
FROM orders
GROUP BY month
ORDER BY month
) TO 'data/monthly-sales.json' (FORMAT JSON, ARRAY true);
然后引用生成的文件:
```bar file=data/monthly-sales.json
{"title": "Monthly Sales", "x": "month", "y": "sales"}
```
这种方法:
引用外部数据文件以节省 token 并实现数据与可视化分离:
```bar size=[8,6] file=data/sales.json
```
CSV 文件非常适合与 DuckDB 进行数据探索:
# 将查询结果导出到 CSV
duckdb -csv -c "SELECT quarter, revenue FROM sales" > data/quarterly.csv
```bar file=data/quarterly.csv
{"title": "Quarterly Revenue", "x": "quarter", "y": "revenue"}
```
| 方法 | 最适合 |
|---|---|
| 内联 JSON | 小型、静态规范 |
| JSON 文件 | 可重用的图表配置 |
| CSV 文件 | DuckDB 工作流,频繁更新的数据 |
---
theme: light
title: My Dashboard
---
# Page Title
## Section Name
```big_value size=[4,2]
{"value": 125000, "label": "Revenue", "format": "currency0k"}
```
```bar size=[12,6] file=data/sales.json
```
规则:
# Title 设置页面标题 (仅首次出现)## Section 创建一个带有分隔符的新分区 (边框,间距)### Header 在当前分区内创建一个软标题 (无分隔符)--- 创建一个分区符 (无标题,仅视觉分隔线)=== 创建一个换页符 (打印到 PDF 时强制新页面)size=[cols,rows] 控制布局 (16 列网格)size=auto 根据数据自动计算尺寸file=path 引用外部 JSON仪表板包含一个主题切换按钮 (右上角),可在浅色和深色模式之间切换。所有图表在主题更改时都会动态更新。
在前置元数据中设置默认主题:
---
title: My Dashboard
theme: dark
orientation: landscape
print: true
---
| 选项 | 描述 |
|---|---|
title | 显示在顶部的仪表板标题 |
theme | light (默认) 或 dark |
orientation | portrait (默认) 或 landscape 用于打印布局 |
print | 当为 true 时,要求所有组件都显式指定 size=[cols,rows] |
continuous | 当为 true 时,移除 # 标题之间的分区符以实现流式布局 |
页面容量: 纵向可容纳 30 行单位,横向可容纳 22 行单位 (Letter 纸张,0.5 英寸边距)。
主题切换会影响所有图表全局 - 单个图表的 theme 设置会被忽略,以支持全局切换。
从 YAML 文件加载自定义品牌颜色和字体:
npx -y -q mviz --theme my_theme.yaml dashboard.md -o dashboard.html
示例主题文件:
name: brand-colors
extends: light
colors:
primary: "#1a73e8"
secondary: "#ea4335"
palette:
- "#1a73e8"
- "#ea4335"
- "#fbbc04"
fonts:
family: "'Roboto', sans-serif"
import: "https://fonts.googleapis.com/css2?family=Roboto&display=swap"
自定义主题会与默认主题合并 - 只需指定您想要覆盖的部分。
图表针对打印到 PDF 进行了优化:
将仪表板打印到 PDF 时,所有内容都会保持完整,不会在图表中间被截断。
当数据可能需要编辑时,使用格式化 (多行) JSON。 这可以实现更小、更精确的编辑:
```bar size=[8,5]
{
"title": "Monthly Sales",
"x": "month",
"y": "sales",
"data": [
{"month": "Jan", "sales": 120},
{"month": "Feb", "sales": 150},
{"month": "Mar", "sales": 180}
]
}
```
好处:
何时使用紧凑 JSON:
{"value": 1250000, "label": "Revenue"}mviz 规范可以使用以下 JSON 模式进行验证:
https://raw.githubusercontent.com/matsonj/mviz/main/schema/mviz.schema.json
添加 $schema 以启用编辑器自动补全和验证:
{
"$schema": "https://raw.githubusercontent.com/matsonj/mviz/main/schema/mviz.schema.json",
"type": "bar",
"title": "Sales",
...
}
| 颜色 | 十六进制 | 用途 |
|---|---|---|
| 主蓝色 | #0777b3 | 主系列 |
| 辅助橙色 | #bd4e35 | 辅助系列,强调色 |
| 信息蓝 | #638CAD | 第三级,信息性 |
| 积极绿 | #2d7a00 | 成功,正值 |
| 警告琥珀 | #e18727 | 警告 |
| 错误红 | #bc1200 | 错误,负面强调 |
完整文档请参阅 reference/chart-types.md。
您是一位分析助手,正在帮助一个具有您所缺乏的决策背景的人类。您的工作是清晰地呈现数据并指出值得调查的模式——而不是得出结论或提出建议。
关键原则:
有关创建有效数据可视化的更多指导——包括受 Tufte 启发的原则、应避免的反模式以及布局示例——请参阅 Best_practices.md。
使用 mviz 时遇到问题?请让 Claude 创建一个记录问题的摩擦日志,然后在 https://github.com/matsonj/mviz/issues 上将其作为 issue 提交。
每周安装量
162
代码仓库
GitHub 星标数
206
首次出现
Jan 20, 2026
安全审计
安装于
opencode132
codex125
claude-code124
gemini-cli121
cursor121
github-copilot115
mviz v1.6.4
Generate clean, data-focused charts and dashboards from compact JSON specs or markdown. Maximizes data-ink ratio with minimal chartjunk, gridlines, and decorative elements. Uses a 16-column grid layout system.
No installation required. Use npx -y -q mviz which auto-downloads from npm. The -q flag reduces npm output while still showing lint errors.
For faster repeated use, install globally: npm install -g mviz
Converts minimal JSON specifications into standalone HTML visualizations using ECharts. Instead of writing 50-100 lines of chart code, write a compact spec that gets expanded into a full HTML artifact with professional styling.
#f8f8f8 light) / Dark (#231f20 dark)echo '<json_spec>' | npx -y -q mviz -o chart.html
npx -y -q mviz dashboard.md -o dashboard.html
npx -y -q mviz my-dashboard/ -o dashboard.html
Components are sized using size=[cols,rows] syntax:
```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"}
```
Height Guidelines:
| Row Units | Approximate Height | Good For |
|---|---|---|
| 2 | ~64px | KPIs, single-line notes |
| 4 | ~128px | Small tables, text blocks |
| 5-6 | ~160-192px | Standard charts |
| 8+ | ~256px+ | Dense tables, detailed charts |
For charts with many categories (10+ bars, 10+ rows in dumbbell), increase row units to prevent compression.
Critical: To place components side-by-side, their code blocks must have NO blank lines between them:
```bar size=[8,5]
{"title": "Chart A", ...}
```
```line size=[8,5]
{"title": "Chart B", ...}
```
This renders Chart A and Chart B on the same row. Adding a blank line between them would put them on separate rows.
| Syntax | Effect |
|---|---|
# H1 | Major section title |
## H2 | Section title |
### H3 | Light inline header (subtle, smaller text) |
--- | Visual divider line |
=== | Page break for printing |
=== | Explicit page break: forces new page in PDF |
Heading Guidelines:
# H1 for major document sections that warrant their own page when printed## H2 for content sections within a page (most common)### H3 for lightweight subheadings that don't interrupt flowcontinuous: true mode, H1 page breaks are suppressedSection vs Page Breaks:
--- to separate logical sections visually. Content flows naturally to the next page when needed.=== only when you explicitly want to force a new page (e.g., separating chapters or major report sections for PDF output).=== by default. Only add page breaks when the user specifically requests them.| Component | Default Size | Notes |
|---|---|---|
big_value | [4, 2] | Fits 4 per row |
delta | [4, 2] | Fits 4 per row |
sparkline | [4, 2] | Compact inline chart |
bar, line, area | [8, 5] | Half width |
| Layout Goal | Components | Sizes |
|---|---|---|
| 4 KPIs in a row | 4× big_value | [4,2] each |
| 5 KPIs in a row | 4× big_value + 1 wider | [3,2] + [4,2] |
| KPI + context | big_value + textarea | [3,2] + [13,2] |
| KPI + chart | big_value + bar | [4,2] + [12,5] |
```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"}
```
This creates a row with 5 KPIs (3+3+3+3+4 = 16 columns).
```bar size=[8,6] file=data/region-sales.json
```
```line size=[8,6] file=data/monthly-trend.json
```
Charts: bar, line, area, pie, scatter, bubble, boxplot, histogram, waterfall, xmr, sankey, funnel, heatmap, calendar, sparkline, combo, dumbbell, mermaid
UI Components: big_value, delta, alert, note, text, textarea, empty_space, table
Tables support column-level and cell-level formatting:
Column options: bold, italic, type ("sparkline" or "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]}
]
}
Cell-level overrides: Use {"value": "text", "bold": true} to override column defaults.
Heatmap: Applies color gradient from low to high values. Text auto-switches to white on dark backgrounds.
Sparkline types: line, bar, area, pct_bar (progress bar), dumbbell (before/after comparison)
Notes support three severity levels via noteType:
| Type | Border Color | Use For |
|---|---|---|
default | Red | Important notices (default) |
warning | Yellow | Cautions, preliminary data |
tip | Green | Best practices, pro tips |
Notes also support an optional label for bold prefix text:
{"type": "note", "label": "Pro Tip:", "content": "Use keyboard shortcuts for faster navigation.", "noteType": "tip"}
big_value - Hero metrics with large display:
{"type": "big_value", "value": 1250000, "label": "Revenue", "format": "currency0m"}
comparison object: {"value": 10300, "format": "currency", "label": "vs last month"} shows change with arrowdumbbell - Before/after comparisons with directional coloring:
{
"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 for rankings (lower = better)delta - Change metrics with directional coloring:
{"type": "delta", "value": 0.15, "label": "MoM Growth", "format": "pct0"}
comparison object: {"value": 0.05, "label": "vs Target"}area - Filled line chart for cumulative/volume data:
{
"type": "area",
"title": "Daily Active Users",
"x": "date",
"y": "users",
"data": [{"date": "Mon", "users": 1200}, {"date": "Tue", "users": 1450}]
}
combo - Bar + line with dual Y-axis:
{
"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}
]
}
heatmap - 2D matrix visualization:
{
"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 option applies to cell labels (e.g., num0k, currency0k, pct)funnel - Conversion or elimination flows:
{
"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 option applies to labels/tooltips (e.g., currency_auto, pct, num0)waterfall - Cumulative change visualization:
{
"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 - Scatter with size dimension. Supports series for color grouping and showLabels for persistent labels:
{
"type": "bubble",
"title": "Market Analysis",
"x": "growth",
"y": "profit",
"size": "revenue",
"series": "region",
"label": "company",
"data": [
{"growth": 5, "profit": 20, "revenue": 100, "region": "US", "company": "Acme"},
{"growth": 10, "profit": 15, "revenue": 200, "region": "EU", "company": "Beta"}
]
}
sankey - Flow diagrams showing relationships:
{
"type": "sankey",
"title": "Traffic Sources",
"data": [
{"source": "Organic", "target": "Landing", "value": 500},
{"source": "Paid", "target": "Landing", "value": 300},
{"source": "Landing", "target": "Signup", "value": 400}
]
}
mermaid - Diagrams from Mermaid syntax (flowcharts, sequence, state, class, ER). Use array for multi-line code:
{
"type": "mermaid",
"title": "User Flow",
"code": [
"graph TD",
" A[Start] --> B{Decision}",
" B -->|Yes| C[Action]",
" B -->|No| D[End]"
]
}
mermaid (ASCII) - ASCII/Unicode text-based diagrams (set ascii: true):
{
"type": "mermaid",
"title": "Process Flow",
"code": ["graph LR", " A[Input] --> B[Process] --> C[Output]"],
"ascii": true
}
Mermaid lint rules (errors that will fail validation):
<br/> tags in labels (render as literal text, not line breaks)A["text"] in flowcharts (quotes appear in output)| Format | Example | Use For |
|---|---|---|
auto | 1.000m, 10.00k | Smart auto-format (recommended) |
currency_auto | $1.000m, $10.00k | Smart auto-format with $ prefix |
currency0m | $1.2m | Millions |
currency0b | $1.2b | Billions |
currency0k | $125k |
Important: Percentage formats expect decimal values (0.25 = 25%), not whole numbers.
Smart formatting (auto/currency_auto) is recommended. The format option applies to both axis labels and data labels on bar charts. It automatically picks the right suffix (k, m, b) based on magnitude and always shows 4 significant digits. Negative values are wrapped in parentheses: (1.000m).
When no format is specified, smart formatting is used by default.
Chart axes automatically detect the appropriate format based on field names:
| Field Pattern | Auto Format | Example |
|---|---|---|
| revenue, sales, price, cost, profit, amount | currency_auto | $1.250m |
| pct, percent, rate, ratio | pct | 15.0% |
| All other numeric fields | auto | 1.250m |
Override with an explicit format field in the chart spec.
The chart generator auto-detects columnar query results. Instead of manually converting columns/rows to data, pass the result directly:
{
"type": "bar",
"title": "Sales by Region",
"x": "region",
"y": "sales",
"columns": ["region", "sales"],
"rows": [["North", 45000], ["South", 32000], ["East", 28000]]
}
This is automatically converted internally. No manual JSON reconstruction needed.
For line, area, bar, and combo charts, control y-axis range with yMin and yMax:
{
"type": "line",
"title": "Elo Rating Trend",
"x": "date",
"y": "elo",
"yMin": 1400,
"data": [{"date": "Oct", "elo": 1511}, {"date": "Jan", "elo": 1636}]
}
Use yMin when:
Use yMax when:
The CLI validates specs automatically using built-in lint rules. Use --lint flag for validation-only mode:
npx -y -q mviz --lint dashboard.md # Validate without generating HTML
| Rule | Severity | Trigger |
|---|---|---|
required-fields | warning | Missing required fields like x, y, or data |
unknown-field | warning | Field not recognized for the chart type |
time-series-sorted | error | Time series data not in chronological order |
sankey-wrong-keys |
Errors exit with code 1. Warnings log to stderr but don't fail.
Time series error: Sort your data by date before passing to the chart.
Sankey wrong keys: Use source, target, value in your data:
{"source": "A", "target": "B", "value": 100}
big_value string: Pass numeric value with format option:
{"type": "big_value", "value": 0.625, "format": "pct0", "label": "Rate"}
The generator outputs helpful warnings to stderr when issues are detected:
| Warning | Cause | Solution |
|---|---|---|
Invalid JSON in 'bar' block | Malformed JSON syntax | Check JSON syntax, ensure proper quoting |
Unknown component type 'bars' | Typo in chart type | Use suggested type (e.g., bar not bars) |
Cannot resolve 'file=...' | File reference without base directory | Use file path argument or inline JSON |
Row exceeds 16 columns |
Warnings include context like content previews, similar type suggestions, and section/row info.
If data labels on bar, line, or area charts are being cut off at the top:
yMax to ~10-15% higher than that valueExample: If max value is 200, set "yMax": 220
{
"type": "bar",
"title": "Sales",
"x": "month",
"y": "sales",
"yMax": 250,
"data": [{"month": "Jan", "sales": 180}, {"month": "Feb", "sales": 220}]
}
This provides headroom for the label text above the bars.
Use SQL to generate data files instead of manually authoring JSON. This reduces errors and ensures data accuracy:
-- Generate chart data file
COPY (
SELECT month, SUM(sales) as sales, SUM(revenue) as revenue
FROM orders
GROUP BY month
ORDER BY month
) TO 'data/monthly-sales.json' (FORMAT JSON, ARRAY true);
Then reference the generated file:
```bar file=data/monthly-sales.json
{"title": "Monthly Sales", "x": "month", "y": "sales"}
```
This approach:
Reference external data files to save tokens and enable data/visualization separation:
```bar size=[8,6] file=data/sales.json
```
CSV files work great with DuckDB for data exploration:
# Export query results to CSV
duckdb -csv -c "SELECT quarter, revenue FROM sales" > data/quarterly.csv
```bar file=data/quarterly.csv
{"title": "Quarterly Revenue", "x": "quarter", "y": "revenue"}
```
| Approach | Best For |
|---|---|
| Inline JSON | Small, static specs |
| JSON files | Reusable chart configs |
| CSV files | DuckDB workflows, frequently updated data |
---
theme: light
title: My Dashboard
---
# Page Title
## Section Name
```big_value size=[4,2]
{"value": 125000, "label": "Revenue", "format": "currency0k"}
```
```bar size=[12,6] file=data/sales.json
```
Rules:
# Title sets the page title (first occurrence only)## Section creates a new section with divider (border, spacing)### Header creates a soft header within the current section (no divider)--- creates a section break (untitled, visual divider only)=== creates a page break (forces new page when printing to PDF)size=[cols,rows] controls layout (16-column grid)size=auto auto-calculates size from datafile=path references external JSONDashboards include a theme toggle button (top right) that switches between light and dark modes. All charts dynamically update when the theme changes.
Set the default theme in frontmatter:
---
title: My Dashboard
theme: dark
orientation: landscape
print: true
---
| Option | Description |
|---|---|
title | Dashboard title displayed at top |
theme | light (default) or dark |
orientation | portrait (default) or landscape for print layout |
print |
Page capacity: Portrait fits 30 row units, landscape fits 22 row units (Letter paper, 0.5" margins).
The theme toggle affects all charts globally - individual chart theme settings are ignored in favor of the global toggle.
Load custom brand colors and fonts from a YAML file:
npx -y -q mviz --theme my_theme.yaml dashboard.md -o dashboard.html
Example theme file:
name: brand-colors
extends: light
colors:
primary: "#1a73e8"
secondary: "#ea4335"
palette:
- "#1a73e8"
- "#ea4335"
- "#fbbc04"
fonts:
family: "'Roboto', sans-serif"
import: "https://fonts.googleapis.com/css2?family=Roboto&display=swap"
Custom themes merge with defaults - only specify what you want to override.
Charts are optimized for printing to PDF:
When printing dashboards to PDF, all content stays intact without being cut off mid-chart.
Use formatted (multi-line) JSON when data may need editing. This enables smaller, more precise edits:
```bar size=[8,5]
{
"title": "Monthly Sales",
"x": "month",
"y": "sales",
"data": [
{"month": "Jan", "sales": 120},
{"month": "Feb", "sales": 150},
{"month": "Mar", "sales": 180}
]
}
```
Benefits:
When to use compact JSON:
{"value": 1250000, "label": "Revenue"}mviz specs can be validated using the JSON Schema at:
https://raw.githubusercontent.com/matsonj/mviz/main/schema/mviz.schema.json
Add $schema to enable editor autocomplete and validation:
{
"$schema": "https://raw.githubusercontent.com/matsonj/mviz/main/schema/mviz.schema.json",
"type": "bar",
"title": "Sales",
...
}
| Color | Hex | Use |
|---|---|---|
| Primary Blue | #0777b3 | Primary series |
| Secondary Orange | #bd4e35 | Secondary series, accent |
| Info Blue | #638CAD | Tertiary, informational |
| Positive Green | #2d7a00 | Success, positive values |
| Warning Amber | #e18727 | Warnings |
See reference/chart-types.md for complete documentation.
You are an analytics assistant helping a human who has decision-making context that you lack. Your job is to present data clearly and surface patterns worth investigating—not to draw conclusions or make recommendations.
Key principles:
For additional guidance on creating effective data visualizations—including Tufte-inspired principles, anti-patterns to avoid, and layout examples—see Best_practices.md.
Having issues with mviz? Ask Claude to create a friction log documenting the problem, then open it as an issue at https://github.com/matsonj/mviz/issues
Weekly Installs
162
Repository
GitHub Stars
206
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
opencode132
codex125
claude-code124
gemini-cli121
cursor121
github-copilot115
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
152,900 周安装
Listennotes自动化:通过Rube MCP和Composio工具包实现播客API自动化操作
1 周安装
Lexoffice自动化工具包:通过Rube MCP实现德国会计软件自动化操作
1 周安装
Labs64 Netlicensing自动化工具包:通过Rube MCP实现许可证管理自动化
1 周安装
Keap自动化集成指南:通过Rube MCP和Composio实现Keap操作自动化
1 周安装
insighto-ai-automation:AI自动化技能,集成Claude与GitHub工作流
1 周安装
Identitycheck自动化:通过Rube MCP和Composio实现身份验证流程自动化
1 周安装
empty_space| Invisible grid cell spacer (default 4 cols × 2 rows) |
pie, scatter, bubble |
| [8, 5] |
| Half width |
funnel, sankey, heatmap | [8, 5] | Half width |
histogram, boxplot, waterfall | [8, 5] | Half width |
combo | [8, 5] | Half width |
dumbbell | [12, 6] | 3/4 width |
table | [16, 4] | Full width |
textarea | [16, 4] | Full width |
calendar | [16, 3] | Full width |
xmr | [16, 6] | Full width, tall |
mermaid | [8, 5] | Half width (use ascii: true for text art) |
alert, note, text | [16, 1] | Full width, single row |
empty_space | [4, 2] | Invisible spacer |
| Thousands |
currency | $1,250,000 | Detailed amounts |
num0m | 1.2m | Millions |
num0b | 1.2b | Billions |
num0k | 125k | Thousands |
num0 | 1,250,000 | Detailed counts |
pct | 15.0% | Percentage with decimal |
pct0 | 15% | Percentage integer |
pct1 | 15.0% | Percentage with 1 decimal |
| error |
Using from/to instead of source/target |
big-value-string | error | Passing "62.5%" string instead of 0.625 number |
duplicate-x-values | warning | Duplicate values on x-axis |
mermaid-no-br-tags | error | <br/> tags in mermaid code (render as literal text) |
mermaid-no-quoted-labels | error | Quoted labels like A["text"] in flowcharts |
| Too many components in one row |
| Reduce component widths or split into rows |
When true, requires explicit size=[cols,rows] on all components |
continuous | When true, removes section breaks between # headers for flowing layout |
| Error Red | #bc1200 | Errors, negative emphasis |