关于 bklit-ui-migrate
用于指导将 Recharts 和 TanStack Charts 迁移到 Bklit UI 图表组件的技能。它要求先盘点并分类图表,再逐项转换,同时保留不适合迁移的图表。
主要功能
- 01图表盘点与分类
- 02组件和属性映射参考
- 03Bklit 注册表安装指引
- 04逐文件转换流程
- 05保留不支持的图表
适用场景
- 01评估项目的图表迁移范围
- 02转换兼容的 Recharts 组件
- 03将微型图表迁移为 Bklit 火花线
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ bklit/ bklit-ui --skill bklit-ui-migrate安装后在 Claude Code 中输入/bklit-ui-migrate确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsonevals/files/bar-layout-vertical/package.jsonevals/files/bar-layout-vertical/components/browser-share.tsxevals/files/donut-pie-center/package.jsonevals/files/donut-pie-center/components/plan-mix.tsxevals/files/line-multi-series/package.jsonevals/files/line-multi-series/components/traffic-chart.tsxevals/files/radar-normalize/package.jsonevals/files/radar-normalize/components/skills-radar.tsxevals/files/recharts-tiny/package.jsonevals/files/recharts-tiny/components/kpi-sparklines.tsxevals/files/scatter-numeric-x/package.jsonevals/files/scatter-numeric-x/components/height-weight.tsxevals/files/shadcn-area-interactive/package.jsonevals/files/shadcn-area-interactive/components/chart-area-interactive.tsxevals/files/shadcn-area-interactive/components/ui/chart.tsxevals/files/shadcn-stacked-bar/package.jsonevals/files/shadcn-stacked-bar/components/chart-bar-stacked.tsxevals/files/shadcn-stacked-bar/components/ui/chart.tsxevals/files/tanstack-sparkline/package.jsonevals/files/tanstack-sparkline/components/revenue-kpi.tsxevals/files/treemap-keep/package.jsonevals/files/treemap-keep/components/monthly-bars.tsxstorage-treemap.tsxreferences/component-map.mdexamples.mdprop-map.mdshadcn-chart.mdtanstack-charts.mdrules/gaps.md详细介绍
Recharts / TanStack Charts → Bklit UI 迁移
Bklit 图表是 shadcn 注册表组件:运行 npx shadcn@latest add @bklit/<slug> 会将源代码复制到用户的项目中,代码再通过用户自己的别名导入,例如 @/components/charts/line-chart。绝不要从 @bklitui/ui/charts 导入——这是 bklit 私有的单体仓库包。
请按顺序完成各步骤。在向用户展示清单(步骤 1)和分类结果(步骤 2)之前,不要开始重写。
参考资料
| 文件 | 用途 |
|---|---|
| references/component-map.md | Recharts 组件 → bklit 导出项、注册表 slug、导入路径 |
| references/prop-map.md | 逐项属性映射、单位、默认值 |
| references/shadcn-chart.md | ChartContainer / ChartConfig / ChartTooltipContent / ChartLegendContent、var(--color-*)、完整的迁移前后示例 |
| references/examples.md | 迁移前后示例:多折线、堆叠柱状图、横向柱状图、环形图、雷达图、渐变面积图、微型折线图/面积图/柱状图 → 迷你图、TanStack KPI 迷你图 |
| references/tanstack-charts.md | TanStack Charts(@tanstack/charts):图形标记 → 迷你图(覆盖充分)和完整图表(仅提供高层说明) |
| rules/gaps.md | bklit 没有对应属性的功能——变通方案或保留 Recharts(错误/正确示例) |
| scripts/detect-recharts.mjs | 零依赖的清单生成与分类(Recharts、shadcn 封装、TanStack Charts、微型图表 → 迷你图) |
各图表的文档:https://bklit.com/docs/components/<slug>。
基本规则
- 绝不臆造属性。 如果 Recharts 属性在
prop-map.md中没有对应项,那就是缺口——请阅读rules/gaps.md。bklit 的XAxis没有tickFormatter,YAxis没有domain,也没有stackId、layout、connectNulls或syncId。 - Line / Area / Composed / Scatter 都是时间序列图表。 x 值必须是
Date(或 ISO 字符串 / epoch 毫秒)。分类 x 轴应使用BarChart或变通方案。 微型图表是迷你图。 只有一个系列、没有坐标轴 / 网格 / 图例,且以小尺寸呈现 → 使用@bklit/sparkline中的LineSparkline/AreaSparkline/BarSparkline(x 轴按行顺序排列,因此不需要日期)。不要用带隐藏装饰元素的LineChart重建它们。 - 保留数据、颜色和标签。 系列相同、颜色相同(根据
ChartConfig确定),工具提示和图例中的可读标签也相同。 - 一次处理一个文件,每处理完一个文件就进行类型检查。
- 进行任何“需要变通方案”的转换前,先征求同意——这会改变图表的外观或解读方式。
- 保留 Recharts 的图表不要改动。 部分迁移也是有效的结果。
步骤 1 — 检测并盘点
从项目根目录运行检测器(Node ≥ 18,无需安装):
node <skill-dir>/scripts/detect-recharts.mjs . --format=table # human table
node <skill-dir>/scripts/detect-recharts.mjs . # full JSON
它会遍历源文件(跳过 node_modules、.next、dist、build 和点目录),查找 recharts 导入(命名导入或 import * as RechartsPrimitive)、shadcn 封装导入和 @tanstack/charts 导入(每个 defineChart(...) 都算一个图表,且 "library": "@tanstack/charts"),并按文件报告:使用的组件、每个图表根节点及其行号、值得注意的属性(stackId、layout="vertical"、syncId、XAxis type="number"、Treemap、LabelList、ErrorBar、自定义 shape/content、Brush 等)、建议的 bklit 目标、要安装的 slug,以及分类。它会将识别为迷你图的图表标记为 "sparkline": true,目标设为 @bklit/sparkline;对于大小未知且没有坐标轴的图表,会添加建议使用它的说明。shadcnWrappers[].importedBy 会列出仍在导入 components/ui/chart.tsx 的文件。它绝不会抛出异常;无法读取的路径会列在 errors 中。
此脚本使用启发式方法(无法读取数据值或在辅助函数中构建的坐标轴)。请打开列出的每个文件并确认后再展示。向用户展示一张表:
| 文件 | Recharts / shadcn 组件 | 图表类型 | bklit 目标 | 分类 |
|---|---|---|---|---|
components/chart-area-interactive.tsx:51 | AreaChart, Area, CartesianGrid, XAxis, ChartContainer, ChartTooltip(Content), ChartLegend(Content) | 面积图(堆叠) | AreaChart | 需要变通处理 |
components/storage-treemap.tsx:25 | Treemap, Tooltip, ResponsiveContainer | 矩形式树状图 | — | 保留 Recharts |
还要检查 components.json:确认存在 @bklit 注册表("registries": { "@bklit": "https://ui.bklit.com/r/{name}.json" }),并记录 aliases.components——它决定导入前缀(默认为 @/components → 文件会放在 components/charts/)。
步骤 2 — 分类并确认
对于每个图表,注明以下一种分类:
- 可直接转换 — 每个组件和属性都有对应映射(参见
component-map.md、prop-map.md)。数据仍可能需要重塑(饼图、雷达图、径向图、环形图)。 - 需要变通处理 — 可以转换,但需要折中处理。常见情况:时间序列图表中的分类或数值型 x 轴、
Area stackId、多个柱形堆叠组、固定的YAxis domain、负值柱形、x 轴tickFormatter/倾斜刻度、LabelList、syncId、Brush(bklit 未在任何注册表项目中提供画刷)、ReferenceLine/ReferenceDot、空值间隙、嵌套饼图。 - 保留 Recharts —
Treemap、ErrorBar、Customized、自定义shape/节点渲染器、ZAxis气泡图、非柱形图中的layout="vertical"。 - 保留 TanStack Charts(
keep-tanstack)— 使用 bklit 没有映射的标记的图表定义(dot、cell、rect、text、ruleY、hexagon、facet等)。完整的lineY/areaY/barY图表属于需要变通处理(仅提供高层映射);迷你图定义则可直接转换。参见tanstack-charts.md。 - 迷你图 — 微型图表上的
Tooltip(或 TanStacktooltip)属于需要变通处理:迷你图不提供工具提示,因此值会通过useSparklineHover移到图表旁边。
说明每个无法直接转换的图表的原因(引用对应属性),并给出 rules/gaps.md 中建议的变通方案。询问用户要转换哪些需要变通处理的图表,以及采用哪种方式(例如重叠面积还是累积面积)。除非用户要求逐个审核,否则无需进一步询问,直接转换可直接转换的图表。
第 3 步 — 安装 bklit 项
仅使用项目的包运行器,安装已确认的图表所需的内容:
npx shadcn@latest add @bklit/line-chart @bklit/bar-chart @bklit/y-axis @bklit/legend
# pnpm dlx shadcn@latest add … | bunx --bun shadcn@latest add …
| 用途 | Slug |
|---|---|
微型 LineChart / AreaChart / BarChart、TanStack lineY / areaY / barY 迷你图 | sparkline(LineSparkline、AreaSparkline、BarSparkline、useSparklineHover;不会引入网格/坐标轴/工具提示) |
LineChart / AreaChart / BarChart / ComposedChart / ScatterChart | line-chart / area-chart / bar-chart / composed-chart / scatter-chart(每种都会引入 grid、chart-tooltip;时间图表会引入 x-axis;条形图会引入 BarXAxis/BarYAxis) |
PieChart / RadarChart / 环形图(RadialBarChart)/ 单值仪表盘 | pie-chart / radar-chart / ring-chart / gauge-chart |
FunnelChart / Sankey / SunburstChart | funnel-chart / sankey-chart / sunburst-chart |
任意可见值 YAxis | y-axis(不会随折线图/面积图/条形图一同打包) |
Legend | legend |
ReferenceArea | reference-area |
ReferenceDot / 事件标记 | markers |
shadcn 会将 bklit 的 CSS 变量(--chart-line-primary、--chart-grid、--chart-crosshair、工具提示颜色等)添加到全局样式表中,但不会覆盖已有变量,因此用户的 --chart-1 … --chart-5 会保持不变。编写导入语句前,请确认文件已放置在 aliases.components 指定的位置。
步骤 4 — 每次转换一个文件
对于每个图表:
- 调整数据结构。
- 时间图表:将
row[xDataKey]转换为Date。裸字符串"2024-04-01"会解析为 UTC 午夜(在 UTC 以西的地区会显示为前一天)→new Date(\${d}T00:00:00`)。按 x 排序。键不是"date"时,设置xDataKey(柱状图默认值为"name"`)。 - 系列级
data(<Scatter data>、<Line data>)→ 合并到根级data。 - 饼图:
{ label, value, color? }[]。雷达图:metrics {key,label}[]+data {label, color?, values}[],归一化到 0–100。环形图:{ label, value, maxValue, color? }[]。漏斗图:{ label, value, color? }[]。Sankey:保持不变。
- 时间图表:将
- 使用
component-map.md和prop-map.md映射组件和属性。以下容易出错的映射请特别注意:ResponsiveContainer→ 删除;使用aspectRatio(默认值为"2 / 1")或className="h-[300px]"设置尺寸。layout="vertical"→BarChart orientation="horizontal"(命名方向相反)+BarYAxis。- 所有柱子共用一个
stackId→ 根级stacked。 type="monotone"→ 从@visx/curve导入curve={curveMonotoneX}。Recharts 的默认曲线为线性;bklit 的Line默认使用curveNatural,Area默认使用curveMonotoneX。dot→showMarkers/markers;activeDot→ChartTooltip showDots/dotSize。isAnimationActive={false}→ 在系列上设置animate={false}(根级animationDuration默认值为 1100 ms)。Bar radius→lineCap(默认值为"round";Recharts 方角柱子使用"butt";也可以使用表示像素值的数字)。paddingAngle(度)→padAngle(弧度);饼图角度:rad = (90 − deg) · π / 180。YAxis tickFormatter→formatValue;domain→ 无对应项。Tooltip→ChartTooltip,使用rows={(point) => [...]}设置标签/格式(行顺序与系列子项顺序一致),使用content={({ point, index }) => …}完全自定义内容;cursor={false}→showCrosshair={false}。Legend→ 从@/components/charts/legend导入<Legend items>,并在图表根元素外部渲染。margin:形状相同,但 bklit 的默认值是四边各 40,因为坐标轴标签位于边距区域。- 迷你图(
prop-map.md→“迷你图”):stroke/fill→color,type="monotone"→curve="monotone"(字符串),margin→padding,radius→barRadius,isAnimationActive={false}→animate={false},ResponsiveContainer→ 不传width,Tooltip→useSparklineHover+ 自行提供数值。从@/components/charts/sparkline导入。 - TanStack Charts:替换
defineChart(...)和<Chart definition>元素;将标记通道转换为属性(y→dataKey,stroke→color,curve→curve,y 轴比例尺范围 →yDomain,margin→padding,ariaLabel→aria-label,svgAnimation/motion()→animate)。详情见tanstack-charts.md。
- 保留
ChartConfig(shadcn)中的颜色和标签。每个var(--color-<key>)都必须替换为配置中的颜色(例如var(--chart-1))——这些变量仅在ChartContainer内存在。将标签传入rows和Legend items。详情见shadcn-chart.md。 - 保留组件的公开 API(名称、属性、导出),以免调用方需要修改。
- 如果文件传递了函数(
rows、content、formatValue)且尚未是客户端组件,则添加"use client"。
步骤 5 — 重写导入(注意命名冲突)
从注册表安装的文件中导入每个部分:
import { Line, LineChart } from "@/components/charts/line-chart";
import { Grid } from "@/components/charts/grid";
import { XAxis } from "@/components/charts/x-axis";
import { YAxis } from "@/components/charts/y-axis";
import { ChartTooltip } from "@/components/charts/tooltip";
import { Legend, LegendItem, LegendLabel, LegendMarker } from "@/components/charts/legend";
import { AreaSparkline, BarSparkline, LineSparkline, useSparklineHover } from "@/components/charts/sparkline";
当文件中不再使用 recharts 和 @/components/ui/chart 时,移除对应导入。不同库中的名称可能冲突——ChartTooltip、ChartLegend(shadcn 包装器),以及 LineChart、Line、Area、Bar、XAxis、YAxis、Legend、ReferenceArea、PieChart 等(Recharts)。如果文件仍在渲染保留的 Recharts 图表,请为其中一方设置别名:
import { Treemap, Tooltip as RechartsTooltip } from "recharts";
import { ChartTooltip as BklitChartTooltip } from "@/components/charts/tooltip";
注册表导出的图例项名称为 LegendItem(文档中的 LegendItemComponent 别名仅存在于 bklit 的 monorepo 导出入口中)。
第 6 步 — 仅在未使用时移除旧代码
- 仅当没有文件导入
components/ui/chart.tsx时,才删除它:重新运行检测器(shadcnWrappers[].importedBy为空),并且搜索代码库(rg "ui/chart"),包括故事、测试和文档。 - 仅当检测器报告不再有
recharts导入(没有保留的图表),且rg "from ['\"]recharts"无结果时,才移除recharts依赖。使用项目的包管理器(npm uninstall recharts、pnpm remove recharts等)。 - 仅当检测器报告不再有
@tanstack/charts导入,且rg "@tanstack/charts"无结果时,才移除@tanstack/charts。 - 如果有任何图表继续使用 Recharts 或 TanStack Charts,请保留相应依赖并在摘要中说明。
第 7 步 — 验证
- 每处理完一个文件后,都要运行类型检查和 lint,然后构建:
npx tsc --noEmit(或项目的typecheck脚本)、项目的 lint 脚本,然后运行build。 - 视觉对比:运行开发服务器,将每个转换后的图表与原图对比(转换前后的截图、浅色和深色模式)。检查:系列数量和颜色、工具提示和图例中的标签、x 轴标签/日期(UTC 偏移)、y 轴范围、堆叠、尺寸、悬停效果、空状态。
- 需要说明的预期且可接受的差异:bklit 的进入动画、虚线/边缘淡化网格、十字准线 + 日期胶囊工具提示、固定的
"MMM d"x 轴标签、默认圆角柱。 - 重新运行检测器,并说明剩余的 Recharts 图表及原因。
完成
向用户总结:已转换的图表(文件 → bklit 图表)、采用的变通方案、保留 Recharts 的图表及原因、安装的项、移除的文件/依赖,以及验证结果。
如需调整迁移后图表的样式(调色板、设计令牌、字体排印、动效),请交由 bklit-ui-design 技能处理;如有一般的 bklit 组合问题,请使用 bklit-ui 技能。