mcpbeat

Lieflat Charts

larashero3-dotcom/lieflat-charts

一套模板驱动的单色数据可视化 skill,严格从 Lupi、Basics、Glance 与 Interactive gallery 的真实实现生成 HTML 图表;默认优先 Lupi Editorial 与 Lupi Basics,无合适模板时才使用 Glance。

1500k tokens
context cost
the whole folder, loaded on every use
30
files
ships runnable scripts
0
copies elsewhere
how many repositories repackaged it
515
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/larashero3-dotcom/lieflat-charts --skill lieflat-charts

The instruction itself

3 sections, as written by the author

Lieflat Charts — 图表品味法典

Lieflat Charts 是一套遵循 Agent Skills 格式的单色数据可视化 skill,专注于把数据图表做成有编辑感、能阅读、能组成完整页面的视觉内容。它由 moxt 与 Codex 协同制作,支持 Lupi 编辑叙事型、Glance 快速判断型、Basics 基础编辑型和 Interactive 交互大图。用户给你数据和场合,你产出一个无需构建、双击可打开的单文件 HTML,改数据只需要动顶部一个数组。纯 SVG 图可离线运行;使用 Chart.js、ECharts 或在线字体的图,在未内联依赖时需要联网。默认必须先从 Lupi Editorial 和 Lupi Basics 中选型;只有两者都没有合适模板,或用户明确要求 Glance / dashboard / 三秒快读时,才允许使用 Glance。

怎么查一张图的参考代码:catalog 查到图型 → 打开对应 gallery 文件 → 按卡内标题找到 <div class="card"> 块看结构 → 在 <script> 里搜同名 // ════ 注释块拿渲染代码。不要整页照抄——gallery 是多卡合页,交付给用户的永远是按第九节骨架组装的单图文件。

目标用户是非程序员(写作者、运营、做 PPT 的人)。他们说人话("帮我把这季度转化画一下,发公众号用"),不说图型名。你的职责是把人话翻译成正确的图,而且好看到能直接发出去。


零、模板优先硬约束

以下规则不是建议,违反任意一条都必须返工:

  • 必须从仓库模板生成。 每张成品图先在 catalog.md 锁定图型编号,再打开对应 gallery 的真实实现:Lupi 使用 templates/lupi-gallery.html,基础型使用 templates/basics-gallery.html,Glance 使用 templates/glance-gallery.html,交互大图使用 templates/big-*.html
  • 必须沿用所选模板的代码骨架。 从卡内标题对应的 <div class="card"> 和同名 // ════ 图型名 ════ 注释块出发,保留其核心 SVG / Canvas / ECharts 结构、数据编码方式、比例关系和动画节奏。允许替换数据、标题、旁注、来源与必要布局;禁止脱离模板另画一张“看起来差不多”的图,禁止拼接多个模板造混合图型,禁止退回图表库默认样式。
  • 默认选型顺序固定。 先完整比较 Lupi Editorial(L1–L15),再比较 Lupi Basics(F1–F12)。只要其中存在能诚实承载数据、容纳标签且可读的模板,就必须从这两组中选择。
  • Glance 是默认降级方案,不是并列首选。 只有 Lupi Editorial 与 Lupi Basics 都不适配,或用户明确要求 Glance、dashboard、监控、周报、三秒快读时,才使用 Glance。降级前必须写明 Lupi / Basics 不适配的具体原因。
  • 库外新造是最后手段。 Lupi、Basics、Glance 和交互模板都无法承载时,才能走第六节翻译流程;新图仍必须继承最接近 gallery 模板的视觉语法和代码结构。

一、工作流程(每次请求都走这六步)

  • 判数据形状。 别问用户要什么图,看他的数据长什么样:几个类目的比较?带时间的序列?占比?带正负?多对一归属?网络?逐条记录的分布?形状是选图的主键。
  • 先审计 Lupi 与 Basics。 按数据形状扫描所有能承接它的 Lupi Editorial(L1–L15)与 Lupi Basics(F1–F12)候选。至少比较 3 个候选;如果不足 3 个,就列出全部候选。比较语义契合、单位诚实、标签容纳、阅读速度、叙事张力和本批次是否重复。
  • 必要时才检查 Glance。 只有 Lupi 与 Basics 候选全部失败,或用户明确要求 Glance / dashboard / 监控 / 周报 / 三秒快读,才扫描 Glance(G1–G18)。选择 Glance 时记录为什么 Lupi 与 Basics 无法承载,不得只写“Glance 更直观”。
  • 锁定真实模板,再组织整页。 每张图必须记录体系、图型编号、gallery 文件和卡内标题,并以该卡的真实结构与渲染代码为骨架。禁止先想好“这一页要讲六件事”,再临时发明图型;整页叙事只能在模板锁定之后组织。
  • 按图数规则组成批次。 一张图只承担一个独立结论;去掉重复结论后,再按第 1.1 节的默认区间决定数量。模板需要全局分配:不重复、不堆同一种轮廓、不为了凑数硬加图。
  • 按模板渲染并自检(第零、二、三、八节)。逐项核对成品是否仍能对应到所选 gallery 实现;不能因为改数据而换掉模板的核心几何、编码或动效。库外图型走翻译流程(第六节)。

1.1 图数规则

图的数量由独立结论数决定,不由“有多少数据列”决定,也不固定要求 5 张或 6 张:

| 请求类型 | 默认成品数量 | 规则 |

|---|---:|---|

| 单个问题 / 单张表 / 一个指标 | 1 | 只交付最强的一张,不为了展示模板而扩展 |

| 两到三个明确结论 | 2–3 | 每张图承担一个不同结论,可共享同一数据源 |

| 一篇文章、论文或完整案例 | 4–6 | 覆盖总览、构成、比较、关系或变化等不同数据形状 |

| 用户明确要求数量 | 按用户要求 | 仍然删除重复图;不足以支撑时说明并少做 |

  • 默认单页上限为 6 张;超过 6 张就拆成多页或按章节交付。
  • 候选方案、Glance/Lupi 对照稿不计入最终图数;它们是选择过程,不是成品批次。
  • 一页多图至少保留一个总览结论,其余图必须提供新的比较维度、关系、时间变化或细节证据。
  • 如果两个图表达同一个结论,只保留阅读场合更合适、数据契约更诚实的一张。

二、Mono 语法 · 硬规则(违反即返工)

引用 mono-tokens.js(开源分发时把内容内联进 HTML)。与 token 冲突的取值一律以 token 为准。

颜色

  • 只有纸灰 #F0EFEB 和炭黑 #1C1C1A 两极,中间 7 级灰阶 ladder。没有彩色。
  • 明度即数据:最重要 = 最黑(暗卡上反转为最亮)。多系列按重要性沿 ladder 分配,不按顺序随便拿。
  • 一律实心:不透明材质、不发光、不渐变滤镜、无阴影。质感全靠明度对比和形状。唯一例外:叠加型图(Radial Patchwork)里透明度本身编码密度——那是数据,不是装饰。
  • 暗卡(.card.dark)只给两种图:必须暗底衬托的形(花瓣、发光感丝线/网络)。默认浅卡;每屏(4 卡)最多 1 张暗卡。

排版

  • Inter 全家。标题 700 / 图内数值 800 / 轴标签 600。卡片结构固定四件套:结论式标题(h2)+ 副标题(图例和时间范围写在这里,用 · 分隔)+ 图 + 来源行(全大写、加字距)。
  • 标题写结论不写图型名:"Revenue by plan" 可以,"柱状图" 不行;更好的是带判断的:"Where we gained, where we bled"。
  • SVG 最小字号:半宽卡 6.5px、通栏 5.5px。装不下的信息改 hover 出,不许缩小字号硬塞。

形状

  • 卡片圆角 24px,无边框无阴影,靠留白分卡。柱端胶囊圆角(竖柱圆上端、横柱圆外端)。
  • 柱状图不断轴。 柱的契约是长度∝数值,断轴毁契约。极端值场景的正确做法:①让极端值冲天(最诚实)②主图+放大镜小图 ③撕柱不撕轴(明说画不下)。
  • 花瓣皮(粗黑缝+圆角扇瓣)只适用等分或近似等分的径向图。宽窄悬殊的扇区会相互遮蔽,降低可读性。

动画

  • 入场动画默认开,quarticOut 快进快停,不弹跳(波浪入场可用 elasticOut)。点阵 stagger 8–15ms/个,条形 80–130ms/根。
  • 统一 reveal 机制:滚入视野才播 + 点击重播(用 token 里的 obsReveal,带 timer 清理)。
  • 必须带 prefers-reduced-motion 降级(token 的 CSS 已含)。
  • 动画不可优于结构:一个效果如果需要发明新布局才能安放,不配存在(effectScatter 教训)。

数据

  • 演示数据用 token 的 rnd(i,k) 确定性伪随机,禁用 Math.random()——刷新必须长一样。
  • 数值和视觉严格成正比。面积编码用 Math.sqrt(v) 换算半径,不许拿数值直接当半径。

三、两个风格系的分工

同一份 mono 色板下有两种世界观,选哪个看场合读者愿意花几秒

| | Glance 系(18 张) | Lupi 系(细读,15 张) |

|---|---|---|

| 基本单元 | 形状(粗柱、大弧、色块) | 记录(一个点 = 一条数据) |

| 线条 | 2px+,理直气壮 | 0.5–0.7px 发丝 |

| 聚合 | 提前聚合好,给结论 | 拒绝聚合,摊开原材料 |

| 读法 | 扫一眼(<10s) | 凑近读(30s+) |

| 场合 | 周报、dashboard、随手贴 | 年报、对外故事页、海报 |

| 引擎 | Chart.js / ECharts | 手写 SVG |

默认策略:Lupi Editorial → Lupi Basics → Glance。 没有明确场合时,禁止默认 Glance。放年报、公众号长文、海报、开源 README、作品集时先选 Lupi Editorial;数据较少或适合熟悉图型时再选 Lupi Basics。只有前两组都没有合适模板,或用户明确要 dashboard、监控、周报、三秒快读时,才进入 Glance 候选池。

全量候选审计不是“把所有图都做一遍”。 先用数据形状筛出能编码同一本体的候选,再把候选分成:

  • 语义合适:每个点、线、面、串珠背后都有真实单位或明确聚合口径。
  • 视觉合适:标签装得下,密度足够,读者能按预期时间读完。
  • 叙事合适:图形本身能承载这批数据要讲的判断,而不只是把数字摆出来。

最终选择是三项的交集,不是“哪个模板文件最容易复制”。默认审计先在 Lupi Editorial 与 Lupi Basics 内完成;只有两组都失败才扩展到 Glance。若同一批要做多张图,再对候选做一次全局分配:模板不重复,形状轮换,最多一张暗卡,避免整页变成六张相似的环或横条。

数据少(只有几个百分比)不等于只能 Glance。 Lupi 化的正道是单位分解:把聚合数摊回可数单位(1 点 = 1 人 / 1 百分点),密度来自单位而不是记录数。单位含义写进副标题,只摊诚实单位(占比加总 100 → 100 个点),不编造不存在的个体记录。取整时如果加总不足 100(如 49.0+27.4+13.9+5.0+3.2 → 98),在底注写明「另外 N 人被四舍五入吃掉了」,不凑假单位。

小数据走 Lupi 的路径优先级(经多轮案例验证)

  • 先全量扫描,再选代码骨架——基础型组 F1–F12(templates/basics-gallery.html)是稀疏数据的 Lupi 词汇:柱/折线/面积/环形/横条/分组/堆叠/散点/瀑布/热力/进度/哑铃;编辑型 L1–L15 则提供逐记录、单位分解、关系与旁注语法。不要因为 basics-gallery.html 里有现成代码就直接选 F 图。
  • 用最接近本体的模板起步——多选题百分比优先比较 L15、F5、L2;100% 构成优先比较 L14、L5、F4、G4;漏斗优先比较 L13、F1/F5 的降级表达。选择依据是数据编码方式,不是文件顺序。
  • 库里真没有对应形状才新造,且新造必须从 gallery 现有语法延伸(发丝 tick、确定性 rnd 抖动、paint-order 光晕、全大写注记),不引入库外参照——“Lupi 风”指 gallery 那批图的视觉语法,不是 Giorgia Lupi 本人的手绘风。
  • 新造的小数据图要配满环境结构层:gallery 好看有一半靠无数据的家具(账本纸横线、虚线导轨、rim 刻度、每 10 单位的立柱网格、旁注引线)。数据层诚实稀疏,密度预算花在家具上。只画数据 + 一根底线的小数据图必然寒酸。

同一批产出(一页多图)里模板不重复。 15 张 Lupi 系够轮换;同一数据能被多个模板承接时,选这一批里还没用过的。

四、图型决策树(数据形状 → 候选)

编号对应 catalog.md。这些只是候选召回表,箭头和书写顺序不代表优先级。实际选择必须遵守:先检查全部 Lupi Editorial 与 Lupi Basics 候选,确认无合适模板后,才允许采用 Glance 候选。

  • 少类目比较(≤8) → G3 Chunky Bars ⇄ 竖排 F1 Rung Bars / 横排 F5 Tick Rows ⇄ L2 Dot Cascade(⚠️ cascade 类目名竖排,仅当名称 ≤4 字或短缩写时可用;中文长类目换 F5/L5/L12)
  • 多选题百分比(各项独立 0–100,加总可超 100) → G3 Chunky Bars ⇄ L15 Ballot Tally
  • 多类目分布(30–60 根) → G12 Stagger Wave
  • 带正负的分类数值 → G10 Diverging Bar
  • 占比 / 100% 构成 → G4 Dot Waffle ⇄ L14 Hundred Field ⇄ F4 Tick Donut(饼图的默认替代);近似等分且要门面 → G2 Petal Rose;占比×强度双编码 → G13 Big Slice;按类堆叠 → F7 Stacked Rungs
  • 两时点对比(前后 / 今昔) → 类目级(≤6 类)→ F12 Dumbbell Queue(横向,串珠 = 真单位)⇄ F6 Paired Rungs(并肩双梯);只有 2–4 条序列要画趋势线 → Glance chunky slope(粗线、大数、结论进标题)。交叉过多的斜率图会显著降低可读性,不要为了 Lupi 化增加装饰结构。
  • 日序列(≤30 天,带区间) → G1 Range Capsules ⇄ 逐日读数 F2 Hairline Line ⇄(90 天级、要肌理)L3 Barcode Lollipop;30–60 天看形态 → F3 Hairline Area
  • 累计增长 → G18 Draw-in + Counter
  • 双序列因果(投入 vs 产出) → G8 Rainfall
  • 实时数据 → G17 Dynamic Stream
  • 排名随时间变 → G16 Bar Race
  • 星期×小时×量 → G14 Single Axis ⇄ F10 Dot Heat
  • 瀑布 / 增减分解(≤6 级) → F9 Rung Waterfall
  • 单值进度(0–100%) → F11 Tick Gauge ⇄ G18 Draw-in + Counter
  • 二维散点(≤20 点) → F8 Plumb Scatter;几百点分布 → G15 Jitter Strip
  • 分组分布、逐条记录 → G15 Jitter Strip
  • 分类×分类+量(矩阵) → 轻(≤100 格)L4 Arc Matrix ⇄ 重(大跨度、要旁注)L9 Bubble Almanac
  • 多对一归属 → 造型强 L5 Radial Convergence ⇄ 带名单 L12 Type Colonnade
  • 漏斗 / 分阶段递减 → L13 Hourglass Stream
  • 层级结构 → G7 Tree LR
  • 事件序列生命史 → L11 Trend Lineage
  • 多实体出生时间+现状 → L1 Launch Fan
  • 逐事件时刻分布(一天内) → L10 Radial Patchwork
  • 双极量表(两端都合法) → L7 Brand Spectrum。注意和单极打分(雷达)区分:单极用 ECharts 原生雷达
  • 网络 → ≤15 节点 G6/G11 小图;>15 或要查数 → B1 环形 / B2 力导向;多段路径流向 → B3 Threads
  • 多组×网格(要装饰感) → L8 Dotty Matrix;要读数 → 摊平用 G14
  • 同一实体集多维度轮播(演示) → G9 Scatter Morph

五、交互三问(决定静态还是可交互)

按顺序问:

  • 这根线/点背后有没有一条真实记录? 没有(纯肌理装饰,如 Cluster Field 的辐条、Hourglass 的淌线)→ 禁止加交互,给没有内容的元素加 hover 是欺骗。
  • 有记录 → 不点能不能读出来? 元素 <50 且两端有标注(如 Colonnade)→ 静态够用,hover 是锦上添花。
  • 元素 >50 根或多段路径(如 Threads)→ 必须 hover/pin,否则只是氛围图。交互实现参考 templates/big-threads.html:可见线下垫 9px 透明孪生线当热区,hover 单线亮整条路径、hover 标签拉整束、点击钉住。

六、库外图型 · 翻译流程

用户要的图不在 48 张里(或发来一张参考图)时,不是做不了,是现场造句。流程四步,第一步不许跳:

  • 先回答本体:这个图型编码了什么?每个视觉通道(位置/长度/角度/面积/明度/密度)分别对应哪个数据维度?答不出来就问用户拿数据结构。抄形不抄魂 = 白做(pictorial bar 曾把"符号计数"错做成"树长高",返工)。
  • 找最近的亲戚:在 catalog 里找数据形状最像的一张当起点,继承它的布局骨架和动画节奏。
  • 用 token 造句:色板、字体、圆角、动画参数全部从 mono-tokens.js 拿,不许发明新颜色新字号。产出必须和库里的图"一眼一家人"。
  • 过第二节硬规则和第八节自检,和库内图同一标准。

参考图翻译的附加规则:识别参考图属于哪个流派(Glance or 编辑部),编辑部风格的密度、旁注、手绘感(blob)是本体的一部分,别做收敛了——almanac 曾因"不敢挤"返工。

七、什么时候说不

敢拒绝比什么都接更可信。以下情况不做,并给替代:

  • 断轴柱状图 → 拒绝,给三个诚实方案(冲天 / 放大镜 / 撕柱不撕轴)。
  • 彩色 / 发光 / 玻璃拟态 / 3D → 不属于 Mono。用户坚持要彩色,说明他要的不是这个 skill,直说。
  • 地图类(choropleth、轨迹图)→ 库里没有地理管线,老实说做不了,别硬画走样的。
  • 给纯装饰元素加交互(第五节第 1 问)→ 拒绝并解释。
  • 雷达图重构 → 不重构,用 ECharts 原生雷达 + Mono token 换肤(实测过:展示场景里"认得出的图型"有价值)。
  • 数据太少撑不起所选图型(如 3 个节点要力导向)→ 降级到更简单的图并说明。

八、交付前自检清单

  • 数值和视觉成正比?(面积用了 sqrt?柱没断轴?)
  • 色板全部来自 token?数一遍,出现任何非 ladder 颜色即返工。
  • 标签会不会重叠?(barcode 教训:邻近峰值标签要强制最小间距)
  • 最小字号踩线没有?(半宽 6.5 / 通栏 5.5)
  • 演示数据是 rnd 确定性的?刷新两次长得一样?
  • reveal 正常?(滚入播、点击重播、timer 不叠加、reduced-motion 降级在)
  • node --check 过语法(把 <script> 内容抽出来查)。
  • 卡片四件套齐全?标题是结论不是图型名?
  • 副标题把图例说清了?(读者不看代码只看这一行)

10. 是否完成全量候选审计?至少写下 3 个候选和淘汰理由,而不是只记录“采用了哪个模板”。

11. 如果是一页多图,模板是否全局分配过?有没有相似轮廓重复、暗卡过量、所有图都变成同一种径向图?

12. 每张图是否记录了图型编号、gallery 文件和卡内标题?成品的核心结构是否确实来自该模板,而不是重新发明?

13. 如果使用 Glance,是否写明 Lupi Editorial 与 Lupi Basics 为什么都不适配?如果没有,返工回到 Lupi / Basics。

14. 最后一问:这张图放回所选 gallery 的对应卡片旁边,是不是同一个模板家族,而不只是“风格有点像”?

九、单文件模板骨架

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Mono — {图名}</title>
<!-- 需要 ECharts 时: -->
<script src="https://cdn.jsdelivr.net/npm/echarts@6/dist/echarts.min.js"></script>
<!-- 需要 Chart.js 时(G1 / G3): -->
<!-- <script src="https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js"></script> -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="{MONO.FONT.link}" rel="stylesheet">
<style>/* 内联 MONO.CARD_CSS */</style>
</head>
<body>
<div class="grid2">
  <div class="card"><!-- 或 card dark / card wide -->
    <h2>{结论式标题}</h2>
    <div class="sub">{说明} · {图例} · {时间范围}</div>
    <!-- 图容器按引擎三选一: -->
    <div class="ch" id="ch"></div><!-- ECharts -->
    <!-- 手写 SVG: <svg id="ch" viewBox="0 0 400 320"></svg> -->
    <!-- Chart.js(G1/G3): <div class="wrap"><canvas id="ch"></canvas></div>,配 .wrap{position:relative;height:320px} -->
    <!-- ⚠️ Chart.js 必须挂 <canvas>,套 <div class="ch"> 会报 can't acquire context -->
    <div class="src">{图型名} · {系列} · {数据来源}</div>
  </div>
</div>
<script>
// 内联 mono-tokens.js 全文
// ── 数据(用户只需要改这里)──
const DATA = [ /* ... */ ];
// ── 渲染 ──
MONO.obsReveal('ch', el => { /* ... */ });
</script>
</body>
</html>

How to use it

Copy the folder

Take larashero3-dotcom/lieflat-charts from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.