关于 flint-chart-author
flint-chart-author 是用于编写 Flint 图表输入规范的技能,面向基于命名数据列创建图表的 Agent。它强调语义类型、适当的数据预处理,并根据需求选择 MCP 图表工具或后端编译。
主要功能
- 01编写图表类型和字段映射
- 02为字段指定语义类型
- 03按需添加交互预设
- 04指导数据绑定与转换
- 05选择 MCP 图表输出流程
适用场景
- 01为已准备的数据集编写 Flint 规范
- 02准备交互式图表请求
- 03选择图表渲染或后端 JSON
MCP 相关
该技能介绍使用 Flint MCP 工具,包括 `validate_chart`、`show`、`render_chart` 和 `compile_chart`。也说明 MCP 客户端可通过 `npx -y flint-chart-mcp` 启动服务。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ microsoft/ flint-chart --skill flint-chart-author安装后在 Claude Code 中输入/flint-chart-author确认已加载。
详细介绍
flint-chart:编写和使用图表规范
你需要生成的内容(以及不需要生成的内容)
你的输出是规范:ChartAssemblyInput 的 chart_spec 和 semantic_types。你按名称引用数据列。宿主会将生成的输入传递给 assembleVegaLite、assembleECharts 或 assembleChartjs,以获取后端规范。
你编写的是输入规范,而不是输出规范。 重要的是:
- 务必输出
chart_spec(图表类型、通道→字段映射、属性)和semantic_types(字段 → 语义类型)。 - 务必在用户要求交互行为(高亮、图例切换、平移和缩放、画刷)、要求交互式图表,或会话目标是探索数据时,添加
interaction_spec。按名称列出预设;请参阅“交互”,对于意图、未指定具体交互的交互式图表或交互组合,请加载flint-interaction-author技能。 - 按名称引用列。
data本身的绑定方式取决于具体情况——可能是 URL、宿主端变量或内嵌行(请参阅“数据绑定方式”)。对于小型表格,内嵌数据完全可行;但不要手动重新序列化大型数据集,因为这可能导致截断和无提示的数据损坏,还会浪费 token。 - 在 Flint 之前转换数据。 如果请求的图表需要聚合、筛选、连接、透视、派生列,或超出 Flint 内置静态序列折叠功能的长宽格式转换,请先使用编码、笔记本、SQL 或数据工具。然后基于转换后的表编写 Flint 规范。
- 仅在必要时于 Flint 之后设置样式。 使用 Flint 编写结构。对于 Flint 无法表达的展示调整(参考线、注释或阴影带),请使用 Vega-Lite 变通方案——请参阅“Flint 后的样式自定义”。切勿将编辑后的 Vega-Lite JSON 传回
render_chart。
当用户想要的不只是规范
首先判断用户请求的是哪种工作流:
- **仅编写规范:**返回
ChartAssemblyInput,或其semantic_types+chart_spec部分。除非用户要求,否则不要安装软件包或编写 渲染器代码。 - **MCP 图表输出:**如果 Flint MCP 工具可用,用户要求查看图表时,默认先调用
validate_chart,再调用show。validate_chart会检查规范并返回报告,但不会绘图;按照报告要求修正规范后,再调用一次show({ "chart": … }),传入完整规范。这会打开一张交互式实时渲染卡片,其中带有自定义面板。 服务不会在调用之间保留任何内容:对话中的规范就是图表。只有当宿主不支持 App UI,或用户明确要求静态图片时,才改用render_chart(PNG/SVG)。用户需要后端原生 JSON 时,使用compile_chart;需要查看支持的图表目录时,使用list_chart_types。 - 务必在用户要求图表以某种状态打开时,将
updates与输入一并传给validate_chart和show:例如突出显示某些行、为某个标记添加注释,或框选某个范围。它是一个 ChartUpdate 图层列表,表示状态而非行为;具体结构见flint://interaction-skill中的“Update the chart”。若要在后续轮次修改图表,请修改其规范或updates,然后再次调用show:新卡片会展示修改后的图表,之前的卡片保持不变。读者在卡片面板中的编辑仅作用于该卡片;其上下文会提供保留这些编辑的chart_spec,因此请传入该规范,除非用户另有要求。 - 务必在用户想查看图表数值时,将
view: "table"传给show:卡片会默认显示图表所用行的数据表,读者可以切换到图表视图。当用户只想查看记录列表、不需要图表时,改用chartType: "Table"。 - **仅在用户要求提供代码时进行项目集成:**将 Flint 添加到应用、笔记本、脚本或 Agent 产品中,安装/导入库,并在代码中调用组装器。保持相同的
ChartAssemblyInput契约,然后让宿主渲染后端结果。
对于 MCP 客户端,可以使用 npx 运行服务:
npx -y flint-chart-mcp
对于 JavaScript 或 TypeScript 项目,请先安装 Flint,并仅添加所用后端渲染所需的渲染器对等依赖:
npm install flint-chart
npm install vega vega-lite vega-embed # browser Vega-Lite rendering
npm install echarts # ECharts rendering
npm install chart.js # Chart.js rendering
然后使用所需后端进行编译:
import { assembleChartjs, assembleECharts, assembleVegaLite } from 'flint-chart';
const vegaLiteSpec = assembleVegaLite(input);
const echartsOption = assembleECharts(input);
const chartjsConfig = assembleChartjs(input);
Python 支持计划在后续版本中推出。在 PyPI 软件包发布之前,已发布工作流请使用 npm 软件包或 MCP 服务。
interface ChartAssemblyInput {
// Bound by the HOST or by you, depending on the situation (see below).
data: { values: any[] } | { url: string };
semantic_types?: Record<string, string | SemanticAnnotation>; // field → type ( ← you write this)
chart_spec: { // ← you write this
chartType: string; // e.g. "Scatter Plot"
title?: string; // the headline — write one
subtitle?: string; // what is measured, of whom, when, in what units
encodings: Record<string, EncodingValue>; // channel → { field, ... } (or array)
baseSize?: { width: number; height: number }; // target layout size, default 400×320
canvasSize?: { width: number; height: number }; // optional hard ceiling on stretch
chartProperties?: Record<string, any>; // per-chart tuning (optional)
};
options?: Record<string, any>; // global layout options (rarely needed)
field_display_names?: Record<string, string>; // field → readable axis/legend title
theme_spec?: string | { extends: string; [key: string]: any }; // preset or preset override (Vega-Lite only)
}
数据如何绑定
使用与运行环境匹配的绑定模式。不要混用。
- 直接通过 MCP 渲染:嵌入行数据。 调用
render_chart、compile_chart或validate_chart时,工具参数为 JSON。如果数据量较小,或已由 其他工具转换,请通过data: { values: [...] }传入。不要在 MCP 工具调用中传入 运行时变量名——MCP 服务无法访问你的本地变量。 - 直接通过 MCP 渲染:引用本地文件。
flint-chart-mcp服务可以从本地.json、.csv或.tsv文件加载data: { url: "..." }。默认情况下,Agent 能指定的任何本地文件都可读取(相对路径 相对于工作目录解析);安全加固的部署可能会通过--disable-file-reference(或FLINT_MCP_DISABLE_FILE_REFERENCE)完全拒绝本地文件 引用,这种情况下请通过data.values内联传入行数据。远程 URL 获取功能已禁用。如果必须先转换数据,请使用编码/数据工具写入一个经过处理的小文件, 然后引用该文件。 - 生成应用或笔记本代码:绑定运行时变量。 如果用户要求你在代码中添加 Flint,请先
编写常规的数据加载代码,再将真实的运行时值(例如
data: { values: rows })传给assembleVegaLite、assembleECharts或assembleChartjs。这种变量写法适用于生成的 代码,不适用于 MCP 工具调用。
- 使用真正的解析器(
d3.csvParse、Papa Parse、pandas)解析 CSV,绝不要用line.split(','):带引号的值(如"Korea, Rep.")会导致后续所有列错位,而错位的 度量值会悄然改变图表(产生错误的域或意外的对数刻度)。 - 保留数据原有的值,并让
semantic_types读取这些值:数值列year若类型为Year,以及值为202501、"202501"或"2025-01"的YearMonth列,都会被标记为 年和月;不要先将它们转换为日期字符串。
对于仅包含规范的回答,请返回 semantic_types 和 chart_spec 部分,并说明宿主应如何
绑定数据。以下示例中,data 显示为 { values: [] },表示“由宿主绑定此数据”——重点关注
chart_spec 和 semantic_types。
绘图前的数据转换
Flint 是图表编译器,而非数据处理层。如果图表需要分组汇总、时间分桶、筛选、联接、透视、 衍生比率或长格式表,请先使用宿主工具转换数据,再绑定处理后的表(参见“数据如何绑定”)。 针对转换后仍存在的列选择语义类型和通道,不要针对已不存在的列进行选择。
先检查数据值,切勿盲目绘图。 使用数据工具检查实际数据(每个分类列的不同值、每个度量值的 最小值/最大值),不要只看列名,并留意以下情况:
- 包含汇总值。 分类列可能同时包含汇总层级及其组成部分(例如
all与cage-free/caged并存,或包含Total区域)。将汇总值与组成部分一起绘图会导致重复计数, 并压平各组成部分——在堆叠/分组/着色通道中只保留其中一方,不要两者兼用。 - 单位。
Percentage可接受比例值(0–1)或百分比值(0–100): Flint 会根据数值判断,并将两者都格式化为%。不要为了 Flint 缩放列,也不要重复缩放。 - 唯一的实际实体。 如果细分列只有一个不同值,按组绘制的图表会收缩为一个标记——预期的 细分列很可能是另一列。
Flint 之后的样式自定义
结构层面(数据、图表类型、通道、变换、尺寸、属性)保持在 Flint 层级——Flint 规范可移植,也能安全地重新生成。只有在有效的 Flint 图表已存在后,才使用后端 JSON,而且仅用于 Flint 未提供的细微呈现调整(精确的坐标轴/图例/标记样式、标题、注释、参考线、布局润色)。绝不要用它来更改数据、图表类型、字段映射或变换——应在上游修正。
针对 Vega-Lite 的样式微调:
- 编写并验证 Flint
ChartAssemblyInput。 - 尽可能先渲染或检查 Flint 图表。
- 调用
compile_chart,并设置backend: "vegalite"。 - 对返回的 Vega-Lite 规范进行必要的最小样式/呈现调整。
- 在宿主环境中使用 Vega-Lite 渲染器渲染修改后的规范。
修改后的 Vega-Lite 规范不再是可移植的 Flint 规范。不要将其发送给 render_chart;render_chart 仅用于 Flint ChartAssemblyInput。
撰写标题
将 chart_spec.title 设为一句话,说明发现;将 chart_spec.subtitle 设为对发现的解读——测量对象、对象是谁、时间以及单位:
title: "A pyramid that is no longer a pyramid"
subtitle: "United States population by age and sex, 2020, millions"
仅当图表处于编号序列中或隶属于某个章节名称时,才添加 chart_spec.label:label: "Figure 2"。它会以主题的眉题样式绘制在主标题上方。
chart_spec.source 是可选项。仅当用户指定来源或要求添加来源行,或者数据本身说明了来源时才添加:source: "UN World Population Prospects 2024"(或使用 { text, href } 添加链接)。绝不要编造或猜测来源。主题决定其呈现方式(“来源:”、位置、分隔线、署名);不添加来源时,图表不会绘制页脚。
chart_spec.chrome 是主题围绕图表绘制的装饰:页眉分隔线、标签、字标、徽标、页脚分隔线和主题署名。它不是图表自身的标题、标签或来源。默认由主题绘制;除非用户要求去掉,否则不要设置 chrome:chrome: false 会去掉全部装饰;chrome: { logos: false }(或 header、footer: false)会去掉其中一部分。即使不显示徽标,署名文字仍会保留。
Jan、Cairo、Chrome 表示各自的类别;26、5,300、0.42 则不会,标题应在其中说明它们的含义。仅当图表不会脱离上下文单独阅读时才省略标题——例如单元格中的迷你图,或带有自身说明文字的图块。不会因此出错:没有标题可供参考时,编译器会保留坐标轴标题。
视觉主题(theme_spec)
使用以下两种形式之一。除非用户要求调整特定品牌样式,否则优先使用预设主题。
1. 使用预设
调用 list_themes 选择一个 ID,然后将其放在 chart_spec 旁边:
{ "chart_spec": { ... }, "theme_spec": "economist" }
| ID | 用途 |
|---|---|
nyt | 新闻编辑部图表:标题直接说明发现,数值标注在图形上,系列名称标在末端。 |
economist | 周刊印刷版:简洁、平直的标题置于副标题上方,刻度线上重复标注单位。 |
swiss | 国际主义平面设计风格:鲜明的网格结构、黑色字体和醒目的红色点缀。 |
nature | 期刊图表:小面板、带单位的坐标轴标题、拟合线旁标注统计数据。 |
mckinsey | 咨询演示文稿:宽色带、标出所有数值,标题直接说明要点。 |
datawrapper | 嵌入式网页图表:窄列、简洁的标题和副标题,页脚下方有分隔线。 |
powerbi | 仪表板磁贴:紧凑布局,图例置于右侧,突出显示最新数据点。 |
powerbi-light | 浅色仪表板磁贴:白色画布、精细网格线和鲜亮的分类颜色。 |
cartoon | 活泼的插画风格:暖色纸张、圆润字体、粗描边和鲜亮色彩。 |
apple | 应用界面图表:浅色标签、末端数值轴,颜色旁配有符号。 |
de-stijl | 风格派构图:粗黑线勾勒基本色块,采用阶梯而非斜坡,标题置于图下方。 |
bbc | BBC 新闻图表:醒目的粗体标题,仅显示网格线,零值线加粗,页脚分隔线标注来源。 |
material | Material Design 3 产品图表:以紫色为主的色调、Roboto 字体、浅色网格线和圆角柱。 |
2. 覆盖预设
覆盖范围应尽量小,只说明用户希望更改的内容:
{
"theme_spec": {
"extends": "economist",
"id": "our-brand",
"ink": {
"series": {
"single": "#6b3fa0"
}
}
}
}
常见的简单覆盖项包括 ink.surface.canvas、ink.series.single、
ink.series.categorical、type.headline.family 和 layout.density
("compact"、"normal" 或 "airy")。如果替换
ink.series.categorical,还要替换 categoricalExtended,确保包含多个
系列的图表仍使用用户指定的品牌调色板。
不要复制整个预设,也不要臆造主题键。主题控制呈现方式;字段、聚合、筛选和排序仍由图表输入控制。ThemeSpec 适用于 Vega-Lite 和 Plotly;ECharts、Chart.js 和 Excel 会忽略它。
完整参考: https://microsoft.github.io/flint-chart/#/documentation/theme-spec
交互(interaction_spec)
用户要求实现交互行为,或会话目标是探索或分析数据时,将
interaction_spec 放在 chart_spec 旁边。静态图像不需要它。
{
"chart_spec": { "chartType": "Line Chart", "encodings": { "x": "date", "y": "value", "color": "series" } },
"interaction_spec": { "interactions": [ { "type": "brush-x" } ] }
}
每个条目的格式为 { "type": <preset>, "options": { ... } },每种行为对应一个条目。
使用 list_interaction_presets 和 chartType 获取该图表类型的预设及其选项;不要自行臆造。选项嵌套在
options 中;id 位于条目上。
哪些预设适用于某项请求、它们如何组合,以及警告的含义,都由
flint-interaction-author 技能(MCP 服务上的 flint://interaction-skill)说明。对于超出单个指定手势的需求,请加载该技能:包括某种意图(探索、比较、分析、找出异常值)、未指定具体行为的“让它具有交互性”、组合使用多个预设、为现有图表添加行为,或更新屏幕上已有的图表。
完整参考: https://microsoft.github.io/flint-chart/#/documentation/interaction-spec
步骤 1 — 选择 chartType
必须严格使用已注册的名称之一。Vega-Lite 是默认且覆盖范围最广的后端;下表列出了每种 Vega-Lite 图表类型、其接受的通道及其可调属性(见“图表级属性”)。必需通道会特别标注。
| 图表类型 | 通道 | 说明 / 必填项 |
|---|---|---|
"Scatter Plot" | x, y, color, size, shape, detail, opacity, column, row | 必须提供 x + y;detail 在每个点上携带一个字段(例如 country),但不映射到视觉通道,可用于工具提示和联动 |
"Regression" | x, y, size, color, column, row | 散点图 + 拟合线;属性 regressionMethod、polyOrder |
"Connected Scatter Plot" | x, y, order, color, detail, column, row | 必须提供 x + y;order = 连接顺序(时间 / 索引),因此线条会描绘轨迹,并且可能自相交 |
"Ranged Dot Plot" | x, y, color | 每个类别的两个 x 值构成哑铃图 |
"Strip Plot" | x, y, color, size, column, row | 带抖动的点;属性 stepWidth、pointSize、opacity |
"Bar Chart" | x, y, color, opacity, column, row | 一个离散变量 + 一个度量;属性 cornerRadius |
"Grouped Bar Chart" | x, y, group, column, row | group = 分组类别;属性 dodge |
"Stacked Bar Chart" | x, y, color, column, row | 属性 stackMode |
"Pyramid Chart" | x, y, color | 发散式水平条形图 |
"Lollipop Chart" | x, y, color, column, row | 属性 dotSize |
"Waterfall Chart" | x, y, color, column, row | color = Type 列,值仅限 start / delta / end;省略此项可按符号自动着色;属性 cornerRadius、totals |
"Gantt Chart" | y, x, x2, color, detail, column, row | x = 开始,x2 = 结束 |
"Bullet Chart" | y, x, goal, color, column, row | 必须提供 goal(目标值) |
"Histogram" | x, color, column, row | x = 要分箱的度量;属性 binCount |
"Boxplot" | x, y, color, opacity, column, row | 类别 + 度量;属性 whiskerMethod、showOutliers、dodge |
"ECDF Plot" | x, color, detail, column, row | x = 度量;累积分布(阶梯线);属性 showPoints |
"Heatmap" | x, y, color, column, row | color = 度量 |
"Calendar Heatmap" | x, color | x = 日期;color = 每日值(按日求和);GitHub 风格的周 × 星期网格 |
"Line Chart" | x, y, color, strokeDash, detail, opacity, column, row | 属性 interpolate、showPoints |
"Sparkline" | x, y, color, detail, row, column | 必须提供 x + y;小倍数迷你趋势线,每个系列一条(系列来自 color 或 detail);属性 interpolate、baseline、trendWidth |
"Bump Chart" | x, y, color, detail, column, row | 随时间变化的排名线 |
"Slope Chart" | x, y, color, detail, column, row | 两个时期之间的数值变化;直线线段 + 端点,每个类别一条线 |
"Area Chart" | x, y, color, opacity, column, row | 属性 interpolate、opacity、stackMode |
"Range Area Chart" | x, y, y2, color, column, row | 必须提供 x + y + y2;从 y(下限)到 y2(上限)的半透明带,数值轴适配该带(不从零开始) |
"Violin Plot" | x, y, color, row | 必须提供 x(类别)+ y(度量);每个类别对应一个镜像 KDE 密度图;属性 bandwidth;仅限 Vega-Lite;真正的 color 子组可拆分为两组,或将 3 组及以上绘制为网格 |
"Streamgraph" | x, y, color, column, row | 居中堆叠面积图 |
"Density Plot" | x, color, column, row | 属性 bandwidth、stackMode(系列堆叠;layered 会让它们重叠)、opacity |
"Ridgeline Plot" | x, y, color | x = 度量;color(或离散型 y)命名山脊,每条山脊都是 x 的 KDE,并以自身基线绘制;度量型 y 则绘制每个系列自身的曲线;属性 overlap、order、tailCut、colorBy、perspective(根据山脊数量规划未设置的 skew、tilt、overlap,使深度约占绘图区的 40%)、skew、tilt、valueMax、markAt(true 会标记 x 刻度,也可传入 x 值列表;每条山脊上的值会用点标出并标注,并跨山脊连接)、opacity、interpolate、bandwidth;命名山脊共用一种颜色,除非 colorBy 指定其他方式;数值型 color 会保留渐变图例;仅限 Vega-Lite |
"Marginal Plot" | x, y, color, size, shape, opacity | 图表类型由轴类型决定(度量 × 度量 = 散点图,类别 × 度量 = 条带图,类别 × 类别 = 计数热图),并在每个轴旁显示其分布(度量轴上显示密度图、直方图或箱线图,类别轴上显示计数条形图,按 color 拆分;默认情况下,边缘密度图会分层绘制);属性 marginal、stackMode、bandwidth、binCount、whiskerMethod、showOutliers;仅限 Vega-Lite |
"Pie Chart" | size, color, column, row | size = 扇区值(→ 角度),color = 类别;属性 innerRadius、sortSlices |
"Rose Chart" | x, y, color, column, row | 极坐标条形图;属性 alignment、padAngle、sortSlices |
"Radar Chart" | x, y, color, column, row | 属性 filled、fillOpacity、strokeWidth |
"Candlestick Chart" | x, open, high, low, close, column, row | OHLC 均为必填项 |
"Bar Table" | y, x, color, column, row | 紧凑条形图 + 数值标签 |
"KPI Card" | metric, value, goal | 大数字卡片;属性 behindThreshold |
"Table" | 无(encodings: {}) | 按给定顺序显示行,每个字段对应一列;将 data.values 整理为行,将字段整理为列表,并使用 field_display_names 命名列;数字和日期按 semantic_types 格式打印;接收链接和 updates,不发送选择 |
"Map" | longitude, latitude, color, size, opacity | 气泡地图;属性 region、projection |
"Choropleth" | id, color, detail | id = 区域键(见下文 Maps);属性 region("world" / "us")、level(美国:"state" / "county" / "auto")、projection(世界地图) |
地图:id 接受的值。 Flint 会将键与自身的底图匹配;你无需提供几何数据或查找表。世界地图接受国家名称("India"、“DR Congo”、“United Kingdom”)、ISO 3166 alpha-2 / alpha-3 代码("IN"、"IND")或 ISO 数字代码(356),且都放在同一列中。美国地图接受州名、USPS 代码("CA")或 FIPS 代码(6),以及在 level: "county" 时使用的县 FIPS 代码(6037)。如果代码可能产生歧义,例如 "CA"、“IN”、“Georgia”或较小的数字,请在 semantic_types 中声明键为 Country 或 State(或设置 chartProperties.region)。与任何地区都不匹配的键不会绘制出来。地图标记仅包含 id、color 和 detail:若要将地图与按名称列作为键的图表关联,请将该列编码为 id(名称也能解析),或将其放在 detail 上(例如 id: "map_id", detail: "country");这样也会在工具提示中显示该名称。 |
**环形图:**使用 "Pie Chart",并将 chartProperties.innerRadius 设为大于 0 的值。
选择柱状图(最常见的混淆)。这三种图表都在 x(或 y)上使用一个离散类别和一个度量。它们的区别在于如何显示第二个类别,而且每种图表从不同的通道读取该类别:
"Bar Chart"— 用于单个系列。多行共享一个x时,color上的第二个类别会生成堆叠分段。若要并排显示柱形,请使用"Grouped Bar Chart",并将第二个类别放在group上。"Stacked Bar Chart"— 将第二个类别放在color上,在每个柱形中绘制为堆叠分段(总量很重要)。使用stackMode(stacked/normalize/layered)调整。"Grouped Bar Chart"— 将第二个类别放在**group通道上,在每个x簇中绘制为并排(错开)**柱形(便于直接比较数值)。将用于分组的类别放在group上,而不是color。
经验法则:比较部分与整体 → Stacked;并排比较数值 → Grouped(使用 group);单个系列 → Bar。
瀑布图颜色使用特殊的 "Type" 列,而非任意类别。对于 "Waterfall Chart",color 通道保留给一种类型字段,其值必须是字面上的 start、delta 和 end——它决定哪些柱形以零为基准,而非用于任意分组。不要将 color 绑定到 Increase/Decrease(或 up/down、gain/loss)类别:up/down 方向已根据 y 值的正负号推导,并自动着色(向上为绿色 / 向下为红色)。对于常见用法,完全省略 color,让 Flint 推断 start/delta/end,并按每个柱形的正负号着色。若要指定哪些柱形是锚定总计,请使用 totals 属性(first/last/both),而非颜色字段。仅当你确实有 start/delta/end 类型列时,才绑定 color。
**后端支持范围。**Vega-Lite 支持以上所有图表。其他后端仅支持其中一部分(若目标后端不是 VL,请先确认):
- ECharts 还支持:
"Gauge"、"Funnel"、"Treemap"、"Sunburst"、"Sankey"、"Parallel Coordinates"、"Graph"、"Tree"。 - Chart.js 支持:Scatter、Bubble、Bar、Grouped Bar、Stacked Bar、 Lollipop、Bump、Combo、Line、Area、Range Area、Pie、Doughnut、Histogram、 Radar、Rose、Slope、Connected Scatter。
编写输入时无需调用库或检查其源代码——从此表中选择即可。
步骤 2 — 将字段映射到通道
每个通道都映射到一个编码对象 { field, ... }(或简写为裸字符串,展开后为 { field: "<string>" }):
"encodings": {
"x": { "field": "weight" },
"y": "mpg",
"color": { "field": "origin" }
}
编码对象字段(除 field 外均为可选):
| 字段 | 值 | 用途 |
|---|---|---|
field | 列名 | 将通道绑定到数据列 |
type | quantitative、nominal、ordinal、temporal | 覆盖推断出的编码类型(很少需要) |
aggregate | count、sum、average、mean | 强制对度量通道进行聚合。热力图中每个单元格有多行数据时,会自动聚合颜色值(Quantity 或 Profit 等可加类型使用 sum,其他类型使用 average),并发出警告;设置 aggregate 可选择聚合方式 |
sortOrder | ascending、descending | 排序方向;在 Vega-Lite 中,仅指定方向会保留或反转语义顺序 |
sortBy | 映射后的 "x"、"y"、"color";Vega-Lite 也接受数据字段或 JSON 数组字符串 | 显式指定类别顺序;参见下文的 Vega-Lite 约定 |
scheme | Vega 配色方案名称(如 viridis、redblue),或按低端优先排列的颜色列表(["#c0392b", "#f2f2f2", "#2e75b6"]) | color 通道的配色方案;优先于主题的渐变色 |
reverse | true / false | 仅适用于 color:反转颜色比例尺 |
mid | 数字 | 仅适用于 color:此图表中发散色阶的中心点(字段的 divergingMidpoint) |
domain | [low, high] | 仅适用于 color:色阶覆盖的度量范围,替代数据范围 |
bins | 整数 ≥ 2,或 0 | 仅适用于 color:将连续度量量化为指定步数;0 表示保持连续渐变 |
colors | { value: color } | 仅适用于 color:此图表中与类别值绑定的颜色(字段的 colors) |
title | 字符串,或 null | 通道的坐标轴或图例显示的名称,用于替代字段名称;null 表示不显示名称 |
通常不需要设置 type、aggregate 或 sortOrder——它们会根据语义类型推断。仅在有特定需求时才设置。
Vega-Lite 排序。 对于标准的月份/星期/季度顺序,请省略排序设置。
仅设置 sortOrder 会遵循语义顺序(descending 会反转顺序),
而不是按月份名称的字母顺序排序。没有语义顺序时,仅指定方向
会使用字段的原生值顺序。
sortBy: "month_number"按现有数据字段排序,默认升序。同一类别有多行时,使用排序字段的最小值。sortBy: "y"按映射后的通道排序;跨通道排序默认降序,自身通道排序默认升序。x、y和color是保留的通道名称,必须进行映射。sortBy: "[\"Mar\",\"Jan\",\"Feb\"]"提供显式的类别顺序;sortOrder: "descending"会将其反转。请使用 JSON 数组字符串,而非数组或 Vega-Lite 排序对象。成员必须是字符串、数字或布尔值。- 若要显式按月份标签的字典顺序排序,请按类别字段本身排序:
{ "field": "month", "sortBy": "month", "sortOrder": "ascending" }。
未知字段、未映射的通道、无效的排序方向和格式错误的排序数组都会报错,不会回退到其他排序方式。Vega-Lite 后端目前支持按原始字段名称排序;对于其他后端,请使用其支持的通道排序控件。请根据所选后端验证输入。
多系列(宽格式 → 长格式)。 若要将多个度量列绘制为系列,
请在 x 或 y 上传入数组(仅限这两个通道)。该库会将其
折叠成长格式,并合成一个系列/图例字段:
"encodings": { "x": { "field": "month" }, "y": ["sales", "profit"] }
所有数组字段都必须是定量字段,且使用数组形式时不能同时绑定
color(折叠操作会管理颜色/图例)。这是唯一内置的重塑方式——没有
transforms/fold 属性。对于其他任何形状转换(长格式↔宽格式、编码无法表达的聚合、派生列、透视、联接),请先使用宿主工具重塑数据——pandas/polars、
Arquero/Array.map/SQL,或数据/MCP 工具——再将结果作为 data.values 传入。如果无法转换数据,请向开发者说明这一限制,不要虚构不存在的转换属性。
步骤 3 — 使用语义类型标注
这是最重要的一步。 语义类型决定所有下游行为——格式、零基线、配色方案、刻度方向等。为每个字段选择最具体的类型。完整的注册类型集:
| 系列 | 语义类型 |
|---|---|
| 时间(时点) | DateTime、Date、Time、Timestamp |
| 时间(粒度) | Year、Quarter、Month、Week、Day、Hour、YearMonth、YearQuarter、YearWeek、Decade |
| 时间(跨度) | Duration |
| 度量(金额) | Amount、Price、Quantity、Count、Number |
| 度量(比例) | Percentage |
| 度量(有符号/发散) | Profit、PercentageChange、Sentiment、Correlation |
| 度量(物理量) | Temperature |
| 离散/排名 | Rank、Score、ID |
| 地理(坐标) | Latitude、Longitude |
| 地理(地点) | Country、State、City、Region、Address、ZipCode |
| 分类 | Category、Name、Status、Boolean、Direction、Range |
| 回退 | Unknown |
时间类型还会告诉 Flint 如何读取值:YearMonth 可接受 202501、2025-01、2025/1、01/2025、2025M01、Jan 2025、2025-Jul、July-2025 或 Jul '25;Date 可接受 20250115、2025/01/15、Jan 15, 2025 或 15-Jan-2025。按原样传入值;未标注类型的字段绝不会被重新解释。
选择合适类型可自动获得以下效果:
Price/Amount→ 货币格式、零基线、顺序色Temperature→ 发散配色方案,不强制使用零基线Correlation→ 固定为[-1, 1]的发散域Rank→ 反向坐标轴(1 在顶部)、离散色Date/DateTime→ 时间坐标轴,自动设置粒度格式Percentage→ 百分比格式,识别 0–100 的值域
如果不确定,数字使用 Quantity,字符串使用 Category,日期形式的值使用 Date / DateTime。不要自行创造类型名称。
比只写类型名称更具体
当仅用类型不足以表达你掌握的信息时,字段条目可以是对象,而不是字符串:
"semantic_types": {
"anomaly": { "semanticType": "Quantity", "unit": "°C", "divergingMidpoint": 0 },
"rating": { "semanticType": "Score", "intrinsicDomain": [1, 5] }
}
unit— 可选的声明,用于授权 Flint 显示单位。仅当数据或上下文明确了度量单位,且显示单位会实质性地改变读者对数值的理解时才添加。仅凭Duration这类类型、life_expectancy这类字段名称,或看起来合理的值,不足以作为依据。- 优先使用规范代码:
"USD"、"°C"、"kg"、"km/h"、"min"。 - 常见的紧凑单位会被规范化,并可能显示在数值旁边(
USD→$,hours→hr)。 "years"这类词汇形式的单位只在字段名称旁标注一次,格式为field (years),不在每个值后重复。- 不要在
unit中填写解释性短语。将"per working-age resident"或"constant 2024 prices"这类限定条件放入副标题。 - 如果单位的含义、量级或分母不确定,则省略
unit。Flint 不会根据语义类型或字段名称推断并显示单位。
- 优先使用规范代码:
intrinsicDomain— 仅适用于有界尺度的字段自身范围:五星评分用[1, 5],百分制分数用[0, 100]。不适用于无上限的度量。divergingMidpoint— 发散色阶中间颜色所对应的位置。如果能判断读者要与什么进行比较,就设置此项;否则省略。sortOrder— 数据中的类别顺序并非你想要的顺序,且也不是字母顺序时,设置类别的显示顺序:["Low", "Medium", "High"]。仅适用于少量类别,不适用于长列表。colors— 当数据遵循读者预期的惯例时,为特定值指定对应颜色:{ "DFL": "#0793AB", "Republican": "#A1000F" }。根据值进行匹配(不区分大小写);未列出的值使用调色板,且该调色板会跳过这些颜色。仅适用于真实惯例(政党、品牌、资产类别),不要用它来改变图表风格——调色板由主题决定。polarity—"higher-is-better"或"lower-is-better":指定发散色彩中哪一端表示警示。带正负号的度量(Profit、PercentageChange)默认按越高越好解读;对于成本、错误、流失或延迟,应设置"lower-is-better",这样无论使用什么主题,较高值而非较低值都会采用暖色。
第 4 步 — 编写规范
将这三个步骤整合到一个 ChartAssemblyInput 中,并按照“数据的绑定方式”绑定数据,再按照“编写标题”添加标题:
{
"data": { "url": "sales.csv" },
"semantic_types": { "month": "YearMonth", "revenue": "Amount", "region": "Region" },
"chart_spec": {
"chartType": "Line Chart",
"title": "Europe climbed every month after the April dip",
"subtitle": "Revenue by region, $m",
"encodings": { "x": { "field": "month" }, "y": { "field": "revenue" }, "color": { "field": "region" } }
},
"theme_spec": "economist"
}
仅当请求需要时,才添加 theme_spec、chartProperties、interaction_spec 或 updates。使用 MCP 工具时,通过 validate_chart 检查规范,并根据报告修正规范,然后将完整规范作为 chart 传给 show。不使用这些工具时,请执行“验证清单”。
图表级属性(chartProperties)
chartProperties 是一个可选的逐图表调优映射。仅当用户要求相应行为时才设置属性——默认值已经合理。这些是设计选择,而非样式覆盖(颜色、字体和刻度仍由系统推导)。值会被限制在所示范围内。
| 图表类型 | 属性 | 类型 / 范围(默认值) | 效果 |
|---|---|---|---|
| 柱状图 | cornerRadius | 0–15(0) | 圆角柱形(px) |
| 面积图 / 堆叠柱状图 | stackMode | stacked | normalize | center | layered(未设置) | 堆叠方式;normalize = 100%,center = 河流图 |
| 密度图 | stackMode | normalize | layered(未设置 = 堆叠) | layered 会以半透明方式重叠各系列 |
| 密度图 | opacity | 0.1–1(0.7) | 分层系列的不透明度 |
| 边际图 | stackMode | stacked(未设置 = 分层) | 堆叠密度边际,而不是将其分层 |
| 分组柱状图 / 箱线图 | dodge | auto | local | global(auto) | local 会按类别紧凑排列稀疏分组;global 会保留对齐的分组通道;除非用户指定,否则保持 auto |
| 折线图 / 面积图 / 迷你折线图 | interpolate | linear | monotone | step | step-before | step-after | basis | cardinal | catmull-rom(linear) | 曲线形状 |
| 折线图 / ECDF 图 | showPoints | 布尔值(false) | 在线上绘制数据点标记 |
| 迷你折线图 | baseline | mean | zero | median | none(mean) | 每行迷你图的参考线 |
| 迷你折线图 | trendWidth | 80–600(240) | 迷你折线图宽度(px) |
| 箱线图 | whiskerMethod | iqr | minmax(iqr) | 须线规则(Tukey 1.5×IQR 或最小值–最大值) |
| 箱线图 | showOutliers | 布尔值(true) | 显示离群点(仅限 Tukey 方法) |
| 面积图 | opacity | 0.1–1(0.7) | 填充不透明度 |
| 散点图 | opacity | 0.1–1(1) | 数据点不透明度 |
| 条带图 | stepWidth | 10–100(20) | 抖动幅度 |
| 条带图 | pointSize | 0–150(0=自动) | 数据点大小 |
| 条带图 | opacity | 0–1(0=自动) | 数据点不透明度 |
| 直方图 | binCount | 5–50(10) | 分箱数量 |
| 密度图 / 山峦图 / 边际图 | bandwidth | 0.05–2(0=自动) | 核带宽 |
| 山峦图 | overlap | 0.5–4(1.8) | 最高山峦高出基线的倍数 |
| 山峦图 | order | mean、reverse(未设置 = 按给定顺序;定量系列中最低的排在最前) | 均值最高的排在顶部,或反转顺序 |
| 山峦图 | tailCut | 0–0.2(0) | 将每座山峦裁剪到密度至少达到其峰值这一比例的位置 |
| 山峦图 | colorBy | series、x(未设置 = 单一颜色) | 命名山峦默认使用同一种颜色;series 为每座山峦着色,x 则沿 x 轴为每座山峦填充渐变色 |
| 山峦图 | perspective | 布尔值(false) | 将山峦立在一个透视地面上:skew、tilt、overlap 未设置时,会按计划将深度控制在图表宽度的约 40%,并随着山峦增加而占据更多高度;深度名称、边缘刻度和数值刻度会在相互碰触前依次让位(先沿轴方向,再按层级,最后每隔 n 个显示) |
| 山峦图 | skew | 0–0.4(0) | 透视:将后方山峦向左移动 x 轴范围的这一比例 |
| 山峦图 | tilt | 0–6(0) | 透视:x 轴在其范围内上升这么多个基线高度,标签沿轴边缘排列 |
| 山峦图 | opacity | 0.1–1(0.5) | 山峦不透明度,与范围面积图相同;透视模式下默认为不透明,除非另行设置 |
| 山峦图 | valueMax | 数值(0 = 最高峰) | 透视:完整山峦高度所代表的数值,沿左后方的数值轴读取 |
| 山峦图 | markAt | 布尔值 | number[] | 在范围内的 x 轴刻度处标记并标注每座山峦的数值(true),或在这些 x 值处标记;一条虚线会连接同一 x 值处各座山峦上的标记 |
| 边际图 | marginal | density | histogram | boxplot(density) | 每个边际沿度量轴绘制的内容;类别轴则显示计数柱 |
| 饼图 | innerRadius | 0–100(0) | 环形孔洞大小(>0 → 环形图) |
| 饼图 / 玫瑰图 | sortSlices | none | descending | ascending(none) | 按扇区数值对扇区及其图例排序 |
| 玫瑰图 | alignment | left | center(left) | 扇区对齐方式 |
| 玫瑰图 | padAngle | 0–0.1(0) | 扇区之间的间隙 |
| 棒棒糖图 | dotSize | 20–300(80) | 圆点大小(px) |
| 瀑布图 | cornerRadius | 0–8(0) | 圆角柱形 |
| 瀑布图 | totals | auto | none | first | last | both(auto) | 哪些柱作为总计锚定到零值(仅在没有 Type 列时) |
| 瀑布图 | showTextLabels | 布尔值(false) | showValueLabels 的旧拼写形式;仍然接受 |
| 柱状图 / 分组柱状图 / 堆叠柱状图 / 棒棒糖图 / 金字塔图 / 饼图 / 环形图 / 热力图 / 瀑布图 | showValueLabels | 布尔值 | 在标记上打印数值。无论是否使用主题均有效:未设置时,会依照当前图表风格在这种密度下的惯例处理(未指定图表风格时则默认关闭),因此编译器报告的默认值始终如实反映实际情况。将其设为其他值即可覆盖该图表的默认行为。如果标记过于密集,无法清晰显示数值,或模板已经包含文本,则会报告为不适用并忽略,因此它不会成为一个不起作用的控制项。在堆叠柱状图上,每个分段会在自身中间显示其数值(若放在边缘,则会显示累计总计);无法容纳一行文字的细分段不会显示标签,而归一化堆叠图显示的是各分段的占比,而非原始值,因为长度表示的正是占比。打印的数值会四舍五入到约 3 位有效数字——数值较大时会使用 k/M 后缀,同时保留足够的小数位,让系列中的最小值仍有意义——因此,原始值 3.14159265 会显示为 3.14,而数值范围从 0.001 到 5000 的系列在两端都能清晰显示。四舍五入的精度不会低到让大小不同的两个标记显示相同数值,也不会让非零值显示为 0;如果图表风格要求的精度更粗糙,则会增加位数,直到标签与标记相符。 |
| 回归 | regressionMethod | linear | log | exp | pow | quad | poly(linear) | 拟合方法 |
| 回归 | polyOrder | 1–5(3) | 多项式阶数(使用 poly 时) |
| 雷达图 | filled | 布尔值(true) | 填充多边形 |
| 雷达图 | fillOpacity | 0–0.5(0.15) | 多边形填充不透明度 |
| 雷达图 | strokeWidth | 0.5–4(1.5) | 线宽 |
| KPI 卡片 | behindThreshold | 0–1(0.5) | 用于颜色判断的数值/目标比值阈值 |
| 地图 | region | us | world | auto(auto) | 地理范围 |
| 地图 | projection | mercator | equalEarth | orthographic | stereographic | conic | mollweide | 地图投影 |
| 跨类型属性(在相关情况下适用于位置图/分面图;仅在需要强制采用非默认行为时设置): |
independentYAxis(布尔值)——分面图:为每个面板设置独立的 y 轴刻度。logScale_x/logScale_y(布尔值)——强制使用对数轴。includeZero_x/includeZero_y(布尔值)——强制坐标轴包含 0。xAxisType/yAxisType(temporal|nominal)——强制将时间字段渲染为离散区间(或反之)。labelOverflow(步骤列表)——指定路径 x 轴类别名称无法放入其区间时的处理方式。省略此项时,名称会换行,然后竖排(必要时截断),并打印每个名称;对于一串时间、日期、年份或排名,名称会换行,然后仅平铺显示整值(16:45、17:00)。仅在用户提出要求时设置,例如使用["wrap", "rotate90"]标注每一年,或使用["wrap", "rotate45", "rotate90"]显示 45° 标签。步骤:wrap、skip(仅序列)、rotate45、rotate90。
参数覆盖——何时使用
虽然可以覆盖参数,但应优先让语义类型决定行为。仅当用户意图确实与默认行为冲突时,才使用覆盖:
- 强制聚合:
encodings.y = { field: "sales", aggregate: "sum" }。 - 按度量对类别轴排序:
encodings.x = { field: "name", sortBy: "y", sortOrder: "descending" }。 - 选择配色方案:
encodings.color = { field: "region", scheme: "tableau10" }。 - 按用户要求控制颜色渐变:
encodings.color = { field: "net", scheme: ["#c0392b", "#f2f2f2", "#2e75b6"], mid: 0, bins: 5 };添加reverse: true可反转渐变,添加domain: [-50000, 50000]可固定其范围。这些设置优先于主题。 - 覆盖推断出的类型:
encodings.x = { field: "year", type: "ordinal" }(例如,将年份视为离散区间)。 - 使用易读的字段标题:
field_display_names = { percentageOfCountries: "Percentage of countries" }。 将编码绑定到实际列名;Flint 会使用显示名称作为坐标轴标题和图例标题。 - 调整图表大小: Flint 根据两个数值调整大小——
baseSize(它努力达到的目标,默认值为 400×320)和canvasSize(它绝不会超过的上限)。数据密集时,图表会从基础大小向上限扩展。- 需要舒适的大小,并允许图表在数据密集时增大 → 设置
chart_spec.baseSize = { width, height }。 - 需要适配的固定区域 → 仅设置
chart_spec.canvasSize = { width, height };图表会填满该区域并缩小以适应,绝不溢出。要求的尺寸就是实际得到的尺寸。 - 两者都设置 → 以
baseSize为目标,向canvasSize扩展,绝不超出。
- 需要舒适的大小,并允许图表在数据密集时增大 → 设置
- 强制使用对数轴/零基线: 使用上文的
logScale_*/includeZero_*图表属性。
全局布局调整位于顶层 options 对象中(例如 addTooltips、区间内边距、分面尺寸)。编写图表时很少需要调整这些选项——除非用户要求,否则省略。
示例
每个示例中的 data 都是占位符——宿主会绑定真实数据行或 URL。你只需编写 chart_spec 和 semantic_types。
散点图
用户:“绘制汽车重量与燃油经济性的关系图,并按产地着色。”
{
"data": { "values": [] },
"semantic_types": {
"weight": "Quantity",
"mpg": "Quantity",
"origin": "Country"
},
"chart_spec": {
"chartType": "Scatter Plot",
"encodings": {
"x": { "field": "weight" },
"y": { "field": "mpg" },
"color": { "field": "origin" }
},
"baseSize": { "width": 400, "height": 300 }
}
}
按数值排序的分面收入柱状图
用户:“按产品线展示收入,从高到低排序,每个地区一个面板。”
{
"data": { "values": [] },
"semantic_types": {
"product_line": "Category",
"revenue": "Amount",
"region": "Region"
},
"chart_spec": {
"chartType": "Bar Chart",
"encodings": {
"x": { "field": "product_line", "sortBy": "y", "sortOrder": "descending" },
"y": { "field": "revenue" },
"column": { "field": "region" }
}
}
}
时间序列,多条序列(通过数组从宽表转换成长表)
用户:“绘制月销售额和利润折线图。”
{
"data": { "values": [] },
"semantic_types": {
"month": "YearMonth",
"sales": "Amount",
"profit": "Profit"
},
"chart_spec": {
"chartType": "Line Chart",
"encodings": {
"x": { "field": "month" },
"y": ["sales", "profit"]
},
"chartProperties": { "interpolate": "monotone", "showPoints": true }
}
}
环形图(Pie + innerRadius),数值映射到 size
用户:“以环形图展示各供应商的市场份额。”
Pie/环形图将切片数值映射到 size(渲染为角度),并将类别映射到 color。数据已经是长表(每个供应商一行)。
{
"data": { "values": [] },
"semantic_types": {
"vendor": "Category",
"share": "Percentage"
},
"chart_spec": {
"chartType": "Pie Chart",
"encodings": {
"size": { "field": "share" },
"color": { "field": "vendor" }
},
"chartProperties": { "innerRadius": 60 }
}
}
子弹图(KPI 与目标对比)
用户:“展示每位销售代表的销售额与其配额的对比。”
{
"data": { "values": [] },
"semantic_types": {
"rep": "Name",
"sales": "Amount",
"quota": "Amount"
},
"chart_spec": {
"chartType": "Bullet Chart",
"encodings": {
"y": { "field": "rep" },
"x": { "field": "sales" },
"goal": { "field": "quota" }
}
}
}
不应执行的操作
- 不要重新输出数据。 按名称引用列;让宿主绑定
data(URL、变量或少量字面量)。切勿粘贴大型数据集。 - 不要直接编写后端规范——先编写
ChartAssemblyInput,再调用组装器。这正是整个流程的意义。 - 不要臆造转换。 内置的唯一重塑方式是
x/y上的数组形式。如果数据形状不适用于图表,请说明这一点,并请宿主重塑数据。 - 不要臆造字段名。 只引用实际存在的列,且拼写必须完全一致。如果数据形状不适用于图表,请在上游重塑数据,而不是猜测不存在的列名。
- 除非意图与默认值冲突,否则不要设置
type/aggregate/sortOrder。 - 不要传入颜色、字号、坐标轴刻度数——编译器会推导这些值。用户可以微调输出规范。例外情况是用户要求的颜色映射(品牌色阶、固定分箱、透视):使用
color编码的scheme、reverse、mid、domain、bins和colors。 - 不要臆造语义类型名称。 如果没有合适的类型,就使用类别默认值(
Quantity、Category、Date)。 - 不要调用库来查询通道/类型——本文档就是编写参考。
验证清单
返回前,请确认:
chartType是目标后端支持的准确注册名称。encodings中引用的每个field都是真实列名。- 每个编码字段在
semantic_types中都有对应条目(具体类型)。 - 图表类型所需的通道均已提供(例如 Bullet→
goal、Candlestick→open/high/low/close、Pie→size+color)。 - 任何
chartProperties键对该图表类型都有效,且值在允许范围内。 - 你没有内嵌大型数据,也没有手动微调推导出的样式。
- 数据中没有嵌入总计/小计层级(例如
all/total行),并与其组成部分混在堆叠、分组或着色通道中。