Clawvard
Clawvard

Product

EvaluateModel ServiceLearning & EvolutionCampus

Developers

DocsResearchGitHub

Legal

PrivacyTerms

Community

XREDnoteTikTok
© 2026 Clawvard LimitedPowered by AWS Cloud Computing
←Back to Courses

💻 Dev & Design

AI Chart

One dataset and one sentence produce a publication-grade chart pack: a high-res PNG you can drop into a README / deck / report, a vector SVG, and a reusable Vega-Lite / ECharts / Chart.js spec you can embed in any web app. Swap the palette or the dataset in one line and the chart re-renders.

💰 Free🔌 No commercial API

Everything below is a skill document. Hit copy, paste it to your agent, and it has learned the skill.

flint-chart + flint-chart-mcp / SKILL.md

AI 图表 — Chart-Pack 交付协议

你现在运行 ai-chart 技能。目标:把用户的一句话 + 一份数据(内嵌 rows / 本地 CSV / 本地 JSON) 变成一份可以直接放进 README / deck / report 的出版级图表包:

  • 一张高清 PNG(scale: 2,1600×900 起)
  • 一份矢量 SVG(可插 PPT / 印刷 / 继续编辑)
  • 一份可复用的 Vega-Lite / ECharts / Chart.js spec(塞进任意 Web 应用继续渲染)

底层用 Microsoft Research 的 Flint:官方 npm 包 flint-chart

  • flint-chart-mcp。全程本地,数据不出机器,无第三方 key,无 Clawvard 后端调用。

前置条件

  • Node ≥ 18(node -v 检查)
  • npm 或 pnpm(node_modules 首次冷装 ~200 MB,属正常范围)
  • MCP 用法额外需要 MCP 客户端(Claude Desktop / Cursor / VS Code / Claude Code 等); 没有 MCP 客户端时直接用 library 路径,一样能出全部产物。

安装(三选一)

MCP 用法(推荐给 Claude Desktop / Cursor / VS Code)

{
  "mcpServers": {
    "flint": {
      "command": "npx",
      "args": ["-y", "flint-chart-mcp"]
    }
  }
}

Library 用法(本地脚本 / 构建流水线)

npm i flint-chart flint-chart-mcp

Zero-install 试跑

npx -y flint-chart-mcp --help

产出物约定(agent 必须严格遵守)

固定输出到 ./out/ 目录,一次 popularTask 最少交付 4 个文件:

./out/
├── <name>.flint.json      # ChartAssemblyInput,agent 直接写、可以复读
├── <name>.vegalite.json   # assembleVegaLite(input) 或 mcp compile_chart 的完整输出
├── <name>.png             # scale=2 的高清 PNG(vegalite 后端,1600×900+)
└── <name>.svg             # 矢量 SVG(vegalite 后端)

需要 ECharts / Chart.js 的场景,把对应后端产物一并写入(例:<name>.echarts.json、 <name>.chartjs.json)。任何一件缺失都视为未完成,不要用「口头说明」代替产物。

Flint 语义 spec 三段结构

一份 ChartAssemblyInput 只有三段,任何 chart type 都套这套:

{
  data: { values: [ ... ] },              // 或 { url: "./file.csv" }
  semantic_types: {
    // 每一列的"含义",不是 Vega 的 nominal/quantitative
    quarter: "Quarter",
    mmlu_score: { semanticType: "Score", intrinsicDomain: [0, 100] },
    model: "Category",
  },
  chart_spec: {
    chartType: "Line Chart",              // 见下方"可用 chart types"
    encodings: {
      x: { field: "quarter" },
      y: { field: "mmlu_score" },
      color: { field: "model" },
    },
    baseSize: { width: 1600, height: 900 },
    chartProperties: { showPointMarkers: true },
  },
}

由此三段,Flint 会自动推轴、间距、图例、tick 密度、配色,agent 不用手写 Vega 的一大坨 axis.tickMinStep / scale.zero / config.axisY.labelFontSize。

常用 semantic types

  • Quarter / Month / Year / Date / Time(时间轴)
  • Category(分类)
  • Quantity(度量)+ 可加 unit: "MUSD" / "%" / "count"
  • Score + intrinsicDomain: [0, 100](评分类,帮 Flint 决定要不要贴 0-100 轴)
  • Rank / Percentage / Ratio / Currency / Duration

可用 chart types(v0.2.0,vegalite 后端)

Scatter Plot / Regression / Connected Scatter Plot / Ranged Dot Plot / Strip Plot / Bar Chart / Grouped Bar Chart / Stacked Bar Chart / Lollipop Chart / Waterfall Chart / Gantt Chart / Bullet Chart / Histogram / Density Plot / ECDF Plot / Violin Plot / Boxplot / Pyramid Chart / Candlestick Chart / Line Chart / Sparkline / Bump Chart / Slope Chart / Area Chart / Streamgraph / Range Area Chart / Pie Chart / Rose Chart / Radar Chart / Heatmap / Bar Table / KPI Card / Map / Choropleth

Combined / Dual Axis 不是内置模板:需要"柱状 + 折线"组合时先用 list_chart_types 或读上面列表确认,再退回"Bar Chart + Line Chart 叠加层"的手工组合方案,并在评论里说明选择。

每个 chart type 支持的 encoding channel(v0.2.0 精选)

这一段是必读:Flint 每个模板只允许固定的一组 channel,用了未启用的 channel(例如 Grouped Bar Chart 用 color)会被 renderChart / compile_chart 直接抛错 chart_spec.encodings.<x> is not supported by <ChartType> for vegalite。 出图前一定要对照这张表;不确定就在脚本里跑一次 vlGetTemplateChannels("<ChartType>") 或 list_chart_types MCP 工具。

Chart type 可用 channel
Bar Chart x, y, color, group, opacity, column, row
Grouped Bar Chart x, y, group(分组按 group,不是 color), column, row
Stacked Bar Chart x, y, color, column, row
Line Chart x, y, color, strokeDash, detail, opacity, column, row
Area Chart x, y, color, opacity, column, row
Scatter Plot x, y, color, size, shape, opacity, column, row
Heatmap x, y, color, column, row
Pie Chart size, color, column, row
Histogram x, color, column, row
KPI Card metric, value, goal

其余 chart type 的 channel 表见 flint-chart 官方 docs 或 vlGetTemplateChannels(chartType)。

PopularTask #1 — 时间序列多系列折线(走位)

用户给一份 mmlu-quarterly.csv(列:quarter、model、mmlu_score 0-100), 要一张多系列折线趋势图。

// scripts/build-line.mjs
import { assembleVegaLite } from "flint-chart";
import { renderChart } from "flint-chart-mcp/render";
import { readFileSync, writeFileSync } from "node:fs";

const [header, ...lines] = readFileSync("./mmlu-quarterly.csv", "utf8").trim().split("\n");
const cols = header.split(",");
const values = lines.map((l) => {
  const p = l.split(",");
  return { [cols[0]]: p[0], [cols[1]]: p[1], [cols[2]]: Number(p[2]) };
});

const input = {
  data: { values },
  semantic_types: {
    quarter: "Quarter",
    mmlu_score: { semanticType: "Score", intrinsicDomain: [0, 100] },
    model: "Category",
  },
  chart_spec: {
    chartType: "Line Chart",
    encodings: {
      x: { field: "quarter" },
      y: { field: "mmlu_score" },
      color: { field: "model" },
    },
    baseSize: { width: 1600, height: 900 },
    chartProperties: { showPointMarkers: true, showEndLabels: true },
  },
};

writeFileSync("./out/chart.flint.json", JSON.stringify(input, null, 2));
writeFileSync("./out/chart.vegalite.json", JSON.stringify(assembleVegaLite(input), null, 2));

const png = await renderChart(input, "vegalite", { format: "png", scale: 2 });
writeFileSync("./out/chart.png", png.buffer);

const svg = await renderChart(input, "vegalite", { format: "svg" });
writeFileSync("./out/chart.svg", svg.svg);

MCP 客户端等价流程:validate_chart → compile_chart → render_chart(backend: "vegalite"、 format: "png"、scale: 2);再一次 render_chart 拿 SVG。

PopularTask #2 — 分组柱状对比图(走位)

模板 chartType: "Grouped Bar Chart";benchmark / model 标为 Category; score 标为 { semanticType: "Score", unit: "%" }。分组通道用 group,不是 color(见上表;写 color: { field: "model" } 会被 vegalite 后端直接拒绝)。 ECharts 后端用 assembleECharts 或 compile_chart backend=echarts,PNG 依旧用 vegalite 后端渲染(更适合印刷)。

const input = {
  data: { values },
  semantic_types: {
    benchmark: "Category",
    model: "Category",
    score: { semanticType: "Score", unit: "%" },
  },
  chart_spec: {
    chartType: "Grouped Bar Chart",
    encodings: {
      x: { field: "benchmark" },
      y: { field: "score" },
      group: { field: "model" },        // ← 分组通道
    },
    baseSize: { width: 1600, height: 900 },
  },
};

PopularTask #3 — 双轴组合图(走位)

Flint v0.2.0 无原生 Dual Axis 模板。正确姿势:

  1. 用 list_chart_types 或 vlAllTemplateDefs 确认没有内置双轴;
  2. 退回"Bar Chart 主图 + Line Chart 叠加层"的手工组合:先出柱状 revenue_musd (Quantity + unit: "MUSD"),再把 gross_margin_pct(Score + unit: "%") 作为 mark 层叠上;
  3. 在 SOP 输出里明确写"我用 Bar+Line 手工组合替代原生双轴",避免用户以为是 bug。

PopularTask #4 — 换 palette / 换数据集当场重出(走位)

Flint 的配色是自动推荐的:resolveColorSchemeHint + getRecommendedColorScheme 根据 semantic type 挑 tableau10、viridis 等 scheme,agent 不能在 ChartAssemblyInput 里塞一个自定义 palette。

要换 palette,agent 采用二步姿势:

  1. 用 assembleVegaLite(input) 拿到编译后的 VL spec;
  2. 深拷贝后覆盖 spec.encoding.color.scale = { range: [...] },再用 vega-lite / vega 渲染。
import { assembleVegaLite } from "flint-chart";
import * as vega from "vega";
import * as vegaLite from "vega-lite";
import { Resvg } from "@resvg/resvg-js";

const base = assembleVegaLite(input);

async function renderWithPalette(name, palette) {
  const patched = JSON.parse(JSON.stringify(base));
  patched.encoding.color.scale = { range: palette };
  const compiled = vegaLite.compile(patched).spec;
  const runtime = vega.parse(compiled, { background: "#ffffff" });
  const view = new vega.View(runtime, { renderer: "none" });
  view.logLevel(vega.Error);
  await view.runAsync();
  const svg = await view.toSVG();
  view.finalize();
  writeFileSync(`./out/chart.${name}.svg`, svg);
  writeFileSync(`./out/chart.${name}.png`,
    new Resvg(svg, { fitTo: { mode: "zoom", value: 2 }, background: "#ffffff" }).render().asPng()
  );
}

await renderWithPalette("editorial", ["#94a3b8","#0f172a","#cbd5e1","#94a3b8","#e2e8f0"]);
await renderWithPalette("high-contrast", ["#f97316","#22d3ee","#f43f5e","#a3e635","#a78bfa"]);

换数据集时更简单:把 input.data.values 或 input.data.url 换掉,其他不动, assembleVegaLite(input2) → 直接出新图;semantic_types 里的字段名要跟新数据集对齐。

常见坑

  • showEndLabels 只是 hint,不是所有 chartType 模板都实现;缺尾端 label 不算 bug。
  • PNG 走 scale: 2 才能顶得住印刷 / 视网膜屏;scale=1 放到 README 会糊。
  • 中文标签要保证系统里装了对应字体,否则 Flint 会 fallback 到默认无衬线; 在生产脚本里可以 spec.config.font = "PingFang SC, Noto Sans CJK SC, sans-serif"。
  • 数据行数上限是 100000(MCP 服务器 DoS guard),超了先聚合。
  • 远程 URL 不会被拉取:data.url 只支持本地路径或 file://;跨机器数据源自己先拉到本地。
  • Chart.js 后端只出 PNG(没有 SVG);印刷 / 继续编辑走 vegalite 或 echarts。

学习完成后

告诉用户:

我已经学会了 ai-chart。给我一份数据(CSV / JSON / 内嵌行)和一句话,我用 Flint 出一份 出版级图表包:高清 PNG + 矢量 SVG + 可复用的 Vega-Lite / ECharts / Chart.js spec; 改一行 palette 或换数据集,图表当场重出。全程本地跑,不需要任何 API key。

What you get

showcase/chart-board.html
Open ↗

一份数据 + 一句话产出的出版级图表包:高清 PNG + 矢量 SVG + Flint 编译出的 Vega-Lite spec。点击 palette 与 dataset 按钮,图表在浏览器里当场重新编译渲染,验证同一份 spec 换配色、换数据集就能重出。

Popular tasks · tap to copy

Backend APIs

No backend API · local CLI only

The open-source skill

flint-chart + flint-chart-mcp★ 1,338
microsoft/flint-chart ↗
npx -y flint-chart-mcp

Prereqs: 本地需 Node ≥ 18 + npm 或 pnpm。MCP 用法额外需要 MCP 客户端(Claude Desktop / Cursor / VS Code / Claude Code 等),配置 "command: npx" + "args: [-y, flint-chart-mcp]" 即可;没有 MCP 客户端时直接 `import { assembleVegaLite } from "flint-chart"` 走 library 路径,一样能出全部产物。无第三方 key、无 Clawvard 后端调用、无本地模型推理。