mcpField
F
flint-chart-author

flint-chart-author

github.com/microsoft数据与数据库4.5k115 次安装1 周前更新
代码仓库

关于 flint-chart-author

flint-chart-author 是用于编写 Flint 图表输入规范的技能,面向基于命名数据列创建图表的 Agent。它强调语义类型、适当的数据预处理,并根据需求选择 MCP 图表工具或后端编译。

主要功能

  1. 01编写图表类型和字段映射
  2. 02为字段指定语义类型
  3. 03按需添加交互预设
  4. 04指导数据绑定与转换
  5. 05选择 MCP 图表输出流程

适用场景

  1. 01为已准备的数据集编写 Flint 规范
  2. 02准备交互式图表请求
  3. 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)
}

数据如何绑定

使用与运行环境匹配的绑定模式。不要混用。

  1. 直接通过 MCP 渲染:嵌入行数据。 调用 render_chart、 compile_chart 或 validate_chart 时,工具参数为 JSON。如果数据量较小,或已由 其他工具转换,请通过 data: { values: [...] } 传入。不要在 MCP 工具调用中传入 运行时变量名——MCP 服务无法访问你的本地变量。
  2. 直接通过 MCP 渲染:引用本地文件。 flint-chart-mcp 服务可以从本地 .json、.csv 或 .tsv 文件加载 data: { url: "..." }。默认情况下,Agent 能指定的任何本地文件都可读取(相对路径 相对于工作目录解析);安全加固的部署可能会通过 --disable-file-reference(或 FLINT_MCP_DISABLE_FILE_REFERENCE)完全拒绝本地文件 引用,这种情况下请通过 data.values 内联传入行数据。远程 URL 获取功能已禁用。如果必须先转换数据,请使用编码/数据工具写入一个经过处理的小文件, 然后引用该文件。
  3. 生成应用或笔记本代码:绑定运行时变量。 如果用户要求你在代码中添加 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 的样式微调:

  1. 编写并验证 Flint ChartAssemblyInput。
  2. 尽可能先渲染或检查 Flint 图表。
  3. 调用 compile_chart,并设置 backend: "vegalite"。
  4. 对返回的 Vega-Lite 规范进行必要的最小样式/呈现调整。
  5. 在宿主环境中使用 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风格派构图:粗黑线勾勒基本色块,采用阶梯而非斜坡,标题置于图下方。
bbcBBC 新闻图表:醒目的粗体标题,仅显示网格线,零值线加粗,页脚分隔线标注来源。
materialMaterial 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, rowgroup = 分组类别;属性 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, rowcolor = Type 列,值仅限 start / delta / end;省略此项可按符号自动着色;属性 cornerRadius、totals
"Gantt Chart"y, x, x2, color, detail, column, rowx = 开始,x2 = 结束
"Bullet Chart"y, x, goal, color, column, row必须提供 goal(目标值)
"Histogram"x, color, column, rowx = 要分箱的度量;属性 binCount
"Boxplot"x, y, color, opacity, column, row类别 + 度量;属性 whiskerMethod、showOutliers、dodge
"ECDF Plot"x, color, detail, column, rowx = 度量;累积分布(阶梯线);属性 showPoints
"Heatmap"x, y, color, column, rowcolor = 度量
"Calendar Heatmap"x, colorx = 日期;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, colorx = 度量;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, rowsize = 扇区值(→ 角度),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, rowOHLC 均为必填项
"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, detailid = 区域键(见下文 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列名将通道绑定到数据列
typequantitative、nominal、ordinal、temporal覆盖推断出的编码类型(很少需要)
aggregatecount、sum、average、mean强制对度量通道进行聚合。热力图中每个单元格有多行数据时,会自动聚合颜色值(Quantity 或 Profit 等可加类型使用 sum,其他类型使用 average),并发出警告;设置 aggregate 可选择聚合方式
sortOrderascending、descending排序方向;在 Vega-Lite 中,仅指定方向会保留或反转语义顺序
sortBy映射后的 "x"、"y"、"color";Vega-Lite 也接受数据字段或 JSON 数组字符串显式指定类别顺序;参见下文的 Vega-Lite 约定
schemeVega 配色方案名称(如 viridis、redblue),或按低端优先排列的颜色列表(["#c0392b", "#f2f2f2", "#2e75b6"])color 通道的配色方案;优先于主题的渐变色
reversetrue / 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 是一个可选的逐图表调优映射。仅当用户要求相应行为时才设置属性——默认值已经合理。这些是设计选择,而非样式覆盖(颜色、字体和刻度仍由系统推导)。值会被限制在所示范围内。

图表类型属性类型 / 范围(默认值)效果
柱状图cornerRadius0–15(0)圆角柱形(px)
面积图 / 堆叠柱状图stackModestacked | normalize | center | layered(未设置)堆叠方式;normalize = 100%,center = 河流图
密度图stackModenormalize | layered(未设置 = 堆叠)layered 会以半透明方式重叠各系列
密度图opacity0.1–1(0.7)分层系列的不透明度
边际图stackModestacked(未设置 = 分层)堆叠密度边际,而不是将其分层
分组柱状图 / 箱线图dodgeauto | local | global(auto)local 会按类别紧凑排列稀疏分组;global 会保留对齐的分组通道;除非用户指定,否则保持 auto
折线图 / 面积图 / 迷你折线图interpolatelinear | monotone | step | step-before | step-after | basis | cardinal | catmull-rom(linear)曲线形状
折线图 / ECDF 图showPoints布尔值(false)在线上绘制数据点标记
迷你折线图baselinemean | zero | median | none(mean)每行迷你图的参考线
迷你折线图trendWidth80–600(240)迷你折线图宽度(px)
箱线图whiskerMethodiqr | minmax(iqr)须线规则(Tukey 1.5×IQR 或最小值–最大值)
箱线图showOutliers布尔值(true)显示离群点(仅限 Tukey 方法)
面积图opacity0.1–1(0.7)填充不透明度
散点图opacity0.1–1(1)数据点不透明度
条带图stepWidth10–100(20)抖动幅度
条带图pointSize0–150(0=自动)数据点大小
条带图opacity0–1(0=自动)数据点不透明度
直方图binCount5–50(10)分箱数量
密度图 / 山峦图 / 边际图bandwidth0.05–2(0=自动)核带宽
山峦图overlap0.5–4(1.8)最高山峦高出基线的倍数
山峦图ordermean、reverse(未设置 = 按给定顺序;定量系列中最低的排在最前)均值最高的排在顶部,或反转顺序
山峦图tailCut0–0.2(0)将每座山峦裁剪到密度至少达到其峰值这一比例的位置
山峦图colorByseries、x(未设置 = 单一颜色)命名山峦默认使用同一种颜色;series 为每座山峦着色,x 则沿 x 轴为每座山峦填充渐变色
山峦图perspective布尔值(false)将山峦立在一个透视地面上:skew、tilt、overlap 未设置时,会按计划将深度控制在图表宽度的约 40%,并随着山峦增加而占据更多高度;深度名称、边缘刻度和数值刻度会在相互碰触前依次让位(先沿轴方向,再按层级,最后每隔 n 个显示)
山峦图skew0–0.4(0)透视:将后方山峦向左移动 x 轴范围的这一比例
山峦图tilt0–6(0)透视:x 轴在其范围内上升这么多个基线高度,标签沿轴边缘排列
山峦图opacity0.1–1(0.5)山峦不透明度,与范围面积图相同;透视模式下默认为不透明,除非另行设置
山峦图valueMax数值(0 = 最高峰)透视:完整山峦高度所代表的数值,沿左后方的数值轴读取
山峦图markAt布尔值 | number[]在范围内的 x 轴刻度处标记并标注每座山峦的数值(true),或在这些 x 值处标记;一条虚线会连接同一 x 值处各座山峦上的标记
边际图marginaldensity | histogram | boxplot(density)每个边际沿度量轴绘制的内容;类别轴则显示计数柱
饼图innerRadius0–100(0)环形孔洞大小(>0 → 环形图)
饼图 / 玫瑰图sortSlicesnone | descending | ascending(none)按扇区数值对扇区及其图例排序
玫瑰图alignmentleft | center(left)扇区对齐方式
玫瑰图padAngle0–0.1(0)扇区之间的间隙
棒棒糖图dotSize20–300(80)圆点大小(px)
瀑布图cornerRadius0–8(0)圆角柱形
瀑布图totalsauto | none | first | last | both(auto)哪些柱作为总计锚定到零值(仅在没有 Type 列时)
瀑布图showTextLabels布尔值(false)showValueLabels 的旧拼写形式;仍然接受
柱状图 / 分组柱状图 / 堆叠柱状图 / 棒棒糖图 / 金字塔图 / 饼图 / 环形图 / 热力图 / 瀑布图showValueLabels布尔值在标记上打印数值。无论是否使用主题均有效:未设置时,会依照当前图表风格在这种密度下的惯例处理(未指定图表风格时则默认关闭),因此编译器报告的默认值始终如实反映实际情况。将其设为其他值即可覆盖该图表的默认行为。如果标记过于密集,无法清晰显示数值,或模板已经包含文本,则会报告为不适用并忽略,因此它不会成为一个不起作用的控制项。在堆叠柱状图上,每个分段会在自身中间显示其数值(若放在边缘,则会显示累计总计);无法容纳一行文字的细分段不会显示标签,而归一化堆叠图显示的是各分段的占比,而非原始值,因为长度表示的正是占比。打印的数值会四舍五入到约 3 位有效数字——数值较大时会使用 k/M 后缀,同时保留足够的小数位,让系列中的最小值仍有意义——因此,原始值 3.14159265 会显示为 3.14,而数值范围从 0.001 到 5000 的系列在两端都能清晰显示。四舍五入的精度不会低到让大小不同的两个标记显示相同数值,也不会让非零值显示为 0;如果图表风格要求的精度更粗糙,则会增加位数,直到标签与标记相符。
回归regressionMethodlinear | log | exp | pow | quad | poly(linear)拟合方法
回归polyOrder1–5(3)多项式阶数(使用 poly 时)
雷达图filled布尔值(true)填充多边形
雷达图fillOpacity0–0.5(0.15)多边形填充不透明度
雷达图strokeWidth0.5–4(1.5)线宽
KPI 卡片behindThreshold0–1(0.5)用于颜色判断的数值/目标比值阈值
地图regionus | world | auto(auto)地理范围
地图projectionmercator | 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)。
  • 不要调用库来查询通道/类型——本文档就是编写参考。

验证清单

返回前,请确认:

  1. chartType 是目标后端支持的准确注册名称。
  2. encodings 中引用的每个 field 都是真实列名。
  3. 每个编码字段在 semantic_types 中都有对应条目(具体类型)。
  4. 图表类型所需的通道均已提供(例如 Bullet→goal、Candlestick→open/high/low/close、Pie→size+color)。
  5. 任何 chartProperties 键对该图表类型都有效,且值在允许范围内。
  6. 你没有内嵌大型数据,也没有手动微调推导出的样式。
  7. 数据中没有嵌入总计/小计层级(例如 all / total 行),并与其组成部分混在堆叠、分组或着色通道中。

评论

支持 Markdown