将文本报告转换为可视化组件流。当用户需要将报告数据可视化或提到"可视化报告"、"用图表展示"、"图文并茂"时使用。
---
name: report-to-visualization
description: 将文本报告转换为可视化组件流。当用户需要将报告数据可视化或提到"可视化报告"、"用图表展示"、"图文并茂"时使用。
---
# 报告转可视化组件流
## 任务目标
将文本报告数据转换为可视化组件配置,输出严格的MODULE格式。
## 输入格式
用户需提供以下变量:
- `${moduleData}`: 报告数据内容
## 图表库规范
### 1. 折线图 (Chart.Line)
**使用条件**: 展示数据趋势,需至少5个连续、真实的时间点原始观测值
**数据格式**:
```json
{
"type": "Chart.Line",
"data": [{"name": "时间标签,≤6字", "value": 数值, "category": "系列名称,≤8字"}],
"config": {"xField": "name", "yField": "value", "title": "图表标题,≤12字"},
"layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto"
}
```
**约束**:
- 禁止基于平均值、最高/最低值、总计等聚合统计量推测或填充时间序列数据
- `value` 必须为 number 类型(如 `78.5`),禁止使用字符串(如 `"78.5"`)
### 2. 柱状图 (Chart.Column)
**使用条件**: 展示数据对比,一个或多个维度有不低于2个具体数值
**数据格式**:
```json
{
"type": "Chart.Column",
"data": [{"name": "分类标签,≤8字", "value": 数值, "category": "指标名称,≤8字"}],
"config": {"xField": "name", "yField": "value", "seriesField": "category", "isGroup": true, "title": "图表标题,≤12字"},
"layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto"
}
```
**约束**:
- `value` 必须为 number 类型(如 `78.5`),禁止使用字符串(如 `"78.5"`),字符串会导致图表排序和轴刻度异常
- 如果原文给出范围值(如"60%-85%"),应拆分为两个数据点(如"线下摆摊(低) 60"和"线下摆摊(高) 85"),或改用 KeyValueCard 展示
- ❌ `{"name": "线下摆摊", "value": "60-85"}` → ✅ 拆分为 `{"name": "摆摊(低)", "value": 60}` 和 `{"name": "摆摊(高)", "value": 85}`
- **禁止混合量纲**:同一个柱状图中所有数据点的 value 必须属于同一量纲(如全部是百分比,或全部是绝对数值)。禁止将绝对数值(如曝光量 9500、成交金额 7800)与百分比(如点击率 2.3%、转化率 0.8%)放在同一个图表中,否则百分比的柱子会因数量级差异完全不可见。应拆分为两个独立的 Chart.Column,或将百分比指标改用 DataCard 展示
- ❌ 曝光量(9500) + 点击率(2.3) + 成交金额(7800) 放在同一柱状图 → ✅ 拆分为"流量与销售"柱状图(绝对数值)+ "转化效率"DataCard 或柱状图(百分比)
### 3. DataCard (数据卡片)
**使用条件**: 展示核心指标值和环比数据,**不低于4个指标**
**数据格式**:
```json
{
"type": "DataCard",
"data": [{"desc": "指标名称,≤12字", "value": "指标值", "cycle": "环比变化值或null"}],
"config": {"title": "卡片标题,≤10字"},
"layoutRow": "r1", "layoutCol": "c2", "rowSize": "auto", "colSize": "auto"
}
```
**约束**:
- `cycle` 字段**仅用于**填写环比/同比的数值变化(如 `"-0.26%"`、`"+5.3%"`),或填 `null`
- 禁止在 `cycle` 中填入描述性文字(如"下降""行业第一""占比47.2%")
- 如果某指标没有环比/同比数据,`cycle` 必须为 `null`
- ❌ `{"desc": "斯凯奇份额", "value": "16.8%", "cycle": "行业第一"}` → ✅ `{"desc": "斯凯奇份额", "value": "16.8%", "cycle": null}`
### 4. 饼图 (Chart.Pie)
**使用条件**: 展示数据占比,不低于2个指标,value值求和应为100(百分比)或1(小数)
**数据格式**:
```json
{
"type": "Chart.Pie",
"data": [{"type": "类别名称,≤8字", "value": 数值}],
"config": {"angleField": "value", "colorField": "type", "innerRadius": 0.6, "statistic": {"title": false, "content": false}, "title": "图表标题,≤12字"},
"layoutRow": "r1", "layoutCol": "c2", "rowSize": "auto", "colSize": "auto"
}
```
**约束**:
- `value` 必须为 number 类型,禁止字符串
- **禁止推算补全**:如果原文只给出一个占比数据而缺少互补项(如仅提到"35-55岁占61.3%"),不得自行用 100%-61.3%=38.7% 推算出其他类别的占比。应改用 DataCard 或 KeyValueCard 展示已有数据
- ❌ `{"type": "其他年龄", "value": 38.7}` ← 原文无此数据,系推算捏造
### 5. 表格 (Chart.List)
**使用条件**: 当内容满足以下**全部**条件时,**必须**使用 Chart.List 而非 TextCard/KeyValueCard:
1. 有 **3 个以上的对比对象**(如 5 个品牌、4 款产品、6 个成本项)
2. 每个对象需要展示 **3-4 个维度**(如品牌 + 定位 + 优势 + 数据)
3. 需要**横向对比阅读**
**数据格式**:
```json
{
"type": "Chart.List",
"data": [{"list": [{"key": "列名,≤10字", "value": "列值,≤20字"}, {"key": "列名", "value": "列值"}]}],
"config": {"title": "分组标题,≤10字"},
"layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto"
}
```
**典型场景**:
- ✅ 竞争品牌格局(5 个品牌 × 4 个维度)→ Chart.List
- ✅ 成本结构明细(6 个成本项 × 3 个维度)→ Chart.List
- ❌ 品牌格局用 TextCard 描述 → 违规
**约束(总计行表达)**:
- 如果表格需要展示总计/合计行,总计行的 key-value 结构必须与明细行保持一致,**第一列的 key 不变,value 填"总计/合计"**,后续列正常填写汇总数据
- ❌ `{"list": [{"key": "成本项", "value": "约111.1元/双"}, {"key": "成本", "value": "-"}, {"key": "备注", "value": "含原材料25-40元"}]}` ← 把金额塞进第一列,第二列留空,读者无法理解
- ✅ `{"list": [{"key": "成本项", "value": "总计"}, {"key": "成本", "value": "约111.1元/双"}, {"key": "备注", "value": "含原材料25-40元"}]}` ← 第一列标明"总计",后续列正常填写数据
### 6. 文本卡片 (TextCard)
**使用条件**: 展示数据总结、趋势洞察、运营建议等定性内容,不少于2个标题
**数据格式**:
```json
{
"type": "TextCard",
"data": [{"title": "标题,≤10字", "text": "内容,尽量2行,30-45字"}],
"config": {"title": "卡片标题,≤10字"},
"layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto"
}
```
**约束(元素数量)**:
- data 数组必须包含 **至少 2 个元素**(即至少 2 个 `{"title": "...", "text": "..."}` 对象),仅 1 个元素时应从原文上下文中提取更多观点/结论来补充,若确实无法补充则考虑将内容合并到相邻的组件中
- ❌ `"data": [{"title": "可行性结论", "text": "..."}]` ← 仅 1 个元素,卡片单薄,信息密度过低
- ✅ `"data": [{"title": "可行性结论", "text": "..."}, {"title": "核心优势", "text": "..."}]` ← 至少 2 个元素,内容充实
**约束(内容聚合原则)**:
- **同一主题下的多个子观点必须放在同一个 TextCard 的 data 数组中**,禁止拆分成多个 TextCard
- 如果某个大主题下有 2-5 个紧密相关的子主题 → 使用一个 TextCard,data 数组包含多项
- ❌ 将"国家政策的 4 个方面"拆成 4 个独立的 TextCard
- ❌ 将"产品创新的 4 个趋势"拆成 2-3 个 TextCard
**约束(内容丰富度)**:
- TextCard 每项的 `text` 字段内容**尽量保持 2 行左右(30-60 字)**,避免内容过于单薄
- 如果原文信息不足以撑满 2 行,应从原文上下文中提取补充信息(如具体数据、应用场景、代表案例等)进行丰富
- ❌ `"text": "北欧极简、无性别设计"` ← 仅 1 行,信息密度过低
- ✅ `"text": "北欧极简、无性别设计成为主流趋势,通勤休闲轻运动场景无缝切换,满足全年龄段穿搭需求"` ← 约 2 行,信息丰富
### 7. 键值对卡片 (KeyValueCard)
**使用条件**: 展示不低于2个分组,每个分组不低于2个指标
**数据格式**:
```json
{
"type": "KeyValueCard",
"data": [{"title": "分组标题,≤8字", "list": [{"key": "指标名称,≤10字", "value": "格式化后的指标值,≤15字"}]}],
"config": {"title": "卡片主标题,≤10字"},
"layoutRow": "r1", "layoutCol": "c2", "rowSize": "auto", "colSize": "auto"
}
```
**约束**:
- data 数组必须包含 **至少 2 个分组**(即至少 2 个 `{"title": "...", "list": [...]}` 对象),仅 1 个分组时应改用 DataCard 或 TextCard
- 每个分组的 list 数组应包含 **至少 2 个指标**
- ❌ `"data": [{"title": "唯一分组", "list": [...]}]` ← 仅 1 个分组独占一整张卡片,信息密度过低
### 8. 阶段卡片 (PhaseCard)
**使用条件**: 展示分阶段的内容规划或执行步骤
**数据格式**:
```json
{
"type": "PhaseCard",
"data": [{"phaseNumber": "阶段序号,≤5字", "phaseName": "阶段名称,≤6字", "focusPoints": [{"label": "重点项标签,≤6字", "content": "重点项内容,≤50字"}]}],
"config": {"title": "卡片标题,≤10字", "theme": "主题色,如'blue'"},
"layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto"
}
```
**约束**:
- 阶段数控制在 **3-5 个**,避免过度拆分导致信息碎片化
- 每个阶段应包含 **2-3 个 focusPoints**,体现该阶段的多维度工作内容
- 可将相关性强的建议合并为同一阶段(如"产品定位+技术创新"合并为"产品升级"阶段)
- ❌ 将 6 条建议拆成 6 个阶段,每阶段仅 1 个 focusPoint → ✅ 合并为 3-4 个阶段,每阶段 2-3 个 focusPoints
### 9. 时间轴 (TimelineCard)
**使用条件**: 展示时间轴内容,如里程碑规划,**不低于3个时间节点**
**数据格式**:
```json
{
"type": "TimelineCard",
"data": [{"month": "月份,≤6字", "title": "里程碑标题,≤8字", "description": "详细描述,≤40字", "target": "目标值,≤12字", "status": "completed或in-progress"}],
"config": {"title": "标题,≤10字", "orientation": "horizontal或vertical"},
"layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto"
}
```
**约束**:
- data 数组必须包含 **至少 3 个时间节点**,少于 3 个节点无法体现时间线的连续感和阶段递进关系
- 仅 1-2 个时间节点时,应从原文上下文中提取更多里程碑/阶段来补充,若确实无法补充则改用 PhaseCard 或 TextCard 承载
- ❌ `"data": [{"month": "1月", ...}]` ← 仅 1 个节点,无法构成时间轴
- ❌ `"data": [{"month": "1月", ...}, {"month": "6月", ...}]` ← 仅 2 个节点,时间线过于稀疏
- ✅ `"data": [{"month": "1月", ...}, {"month": "3月", ...}, {"month": "6月", ...}]` ← 至少 3 个节点,时间线完整
### 10. 警告卡片 (AlertCard)
**使用条件**: 展示警告内容,如风险提示、注意事项,**不低于2条警告**
**数据格式**:
```json
{
"type": "AlertCard",
"data": [{"issue": "问题描述,≤25字", "consequence": "后果,≤40字", "suggestion": "建议,≤30字", "level": "warning或info或error或success"}],
"config": {"title": "卡片标题,≤10字", "showIcon": true},
"layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto"
}
```
**约束**:
- data 数组必须包含 **至少 2 条警告**,仅 1 条警告时应从原文上下文中提取更多风险/注意事项来补充,若确实无法补充则改用 TextCard 承载
- ❌ `"data": [{"issue": "唯一的风险提示", ...}]` ← 仅 1 条警告,信息密度过低,卡片单薄
- ✅ `"data": [{"issue": "风险1", ...}, {"issue": "风险2", ...}]` ← 至少 2 条,信息充实
### 11. 影响卡片 (InfluenceCard)
**使用条件**: 展示不同程度的影响内容,如关键转化杠杆、机会优先级
**数据格式**:
```json
{
"type": "InfluenceCard",
"data": [{"name": "因素名称,≤10字", "influenceLevel": 1-5, "influenceLabel": "影响力标签,≤4字", "focusPoints": [{"label": "关注点标签,≤6字", "content": "关注点内容,≤50字"}], "warnings": [{"icon": "warning或info", "label": "警告标签,≤6字", "content": "警告内容,≤40字"}], "priority": 1-3}],
"config": {"title": "主标题,≤12字"},
"layoutRow": "r1", "layoutCol": "c1", "rowSize": "auto", "colSize": "auto"
}
```
**约束**:
- 每个影响因素应包含 **2-3 个 focusPoints**,从不同维度(如技术/商业/用户/风险)展示影响
- 如果原文对某个因素只有一句话描述,应从原文上下文中提取补充信息,而非仅用 1 个 focusPoint
- ❌ 每个因素仅 1 个 focusPoint,信息密度过低 → ✅ 每个因素 2-3 个 focusPoints
## 输出格式
按报告章节分模块输出,所有模块统一组织在一个 JSON 对象的 `modules` 数组中,并使用 ` ```seller-report ` 代码块包裹。**最终输出必须严格遵循以下结构,不允许在代码块外输出任何额外内容**:
```seller-report
{
"modules": [
{
"components": [
{
"type": "Title",
"content": "<章节子标题,≤8字,禁止以\"模块一\"、\"##\"等字符开头,应体现该章节的核心主题>"
},
{
"type": "<图表组件类型,如 Chart.Column / DataCard / KeyValueCard 等>",
"data": [ ... ],
"config": { ... },
"layoutRow": "r1",
"layoutCol": "c1",
"rowSize": "auto",
"colSize": "auto"
},
{
"type": "<图表组件类型>",
"data": [ ... ],
"config": { ... },
"layoutRow": "r1",
"layoutCol": "c2",
"rowSize": "auto",
"colSize": "auto"
}
]
},
{
"components": [
{
"type": "Title",
"content": "<下一章节子标题>"
},
{
"type": "<图表组件类型>",
"data": [ ... ],
"config": { ... },
"layoutRow": "r1",
"layoutCol": "c1",
"rowSize": "auto",
"colSize": "auto"
}
]
}
]
}
```
**分模块规则**:
1. 每个原文一级标题(## 级别)对应 `modules` 数组中一个独立的模块对象(即一个 `{"components": [...]}`)
2. 每个模块的第一个组件**必须**是 `{"type": "Title", "content": "<章节子标题>"}`,用于标识该模块的核心主题(如"消费者需求""竞争格局""政策环境"),而非整个报告的标题;`Title` 组件不参与布局编号,无需 `layoutRow`/`layoutCol`/`data`/`config` 字段
3. 每个模块的 `components` 数组中,除首个 `Title` 外的其他组件仅承载该章节相关的内容
4. `layoutRow` 在每个模块内独立编号,从 r1 重新开始(`Title` 组件不占用行号)
5. 整个输出必须是**单个合法 JSON 对象**,被 ` ```seller-report ... ``` ` 包裹;JSON 中不允许出现注释、尾随逗号等非标准语法
## 布局规范(强约束)
**核心规则**: 布局只能是一行一个组件或一行两个不同组件,不允许一行放两个相同组件。
### 组件分类
**基础图表类**(可两两组合): Chart.Line、Chart.Column、Chart.Pie、DataCard、KeyValueCard
**整行展示类**(必须独占一行): Chart.List、TextCard、PhaseCard、TimelineCard、AlertCard、InfluenceCard
### 布局分配原则
1. 整行展示类组件必须独占一行
2. 基础图表类组件优先考虑两两组合(如 Column+Pie、Column+KeyValueCard、DataCard+KeyValueCard)
3. layoutRow 从 r1 开始递增,rowSize/colSize 统一用 "auto"
4. **禁止浪费**:如果某个模块内存在两个或以上的基础图表类组件各自独占一行,视为布局浪费,必须合并到同一行
5. **布局自检**(生成每个模块后必须检查):该模块内是否有基础图表类组件可以组合?layoutRow 是否从 r1 连续递增?
6. **禁止连续使用同一图表类型**:在同一个模块内(不计 `Title` 组件),相邻的两个组件不得使用相同的 `type`。如果内容需要多个同类型组件,必须在中间插入一个不同类型的组件来间隔,或将内容合并到同一个组件中
- ❌ 同一模块内第 1 个组件是 TextCard,第 2 个组件也是 TextCard → 违规,应合并为一个 TextCard 或在中间插入其他类型组件
- ❌ 同一模块内连续两个 Chart.List → 违规,应合并为一个 Chart.List 或用其他组件间隔
- ✅ TextCard → KeyValueCard → TextCard(中间有不同类型间隔)
## 完整性规则(强约束)
**报告的每一个章节都必须在可视化输出中有对应的组件体现,禁止跳过任何章节。**
1. **定性内容必须可视化**:产品定位、使用场景、竞争分析等非数字内容,应使用 TextCard、KeyValueCard 等组件承载,不得因"没有数字"而跳过
2. **章节覆盖与组件数量**:总组件数不得少于原文一级标题(## 级别)数量的 1.5 倍(如 8 个一级标题至少 12 个组件)。每个一级标题至少有一个组件与之对应
## 组件选型优先级(强约束)
当内容符合以下条件时,**必须**使用对应组件,禁止用 TextCard/KeyValueCard 替代:
| 内容特征 | 必须使用的组件 | 判断标准 |
|---------|--------------|---------|
| 有风险提示、问题警示 | AlertCard | 内容包含"问题 - 后果 - 建议"结构 |
| 有执行步骤、阶段规划 | PhaseCard | 内容包含"第一步/第二步"或"阶段 1/阶段 2" |
| 有影响力分级、优先级排序 | InfluenceCard | 内容包含"高/中/低影响"或"优先级 1/2/3" |
| 有 3+ 对象的多维度对比 | Chart.List | 内容有 3 个以上对象需要对比多个维度 |
| 有时间节点、里程碑 | TimelineCard | 内容包含具体时间点或时间序列 |
## 工作流程
1. **阅读反例约束**(强制前置步骤): 使用 read_file 工具阅读 `reference/anti-patterns.md` 文件,理解跨组件的通用反例约束。**此步骤不可跳过。**
2. **内部规划**(不输出给用户): 在内部完成以下规划步骤,**不要将规划过程输出给用户**:
- 仔细阅读 `${moduleData}`,逐一列出所有一级标题和二级标题,形成章节清单
- 识别报告核心主体,规划第一个模块的 KeyValueCard 内容
- 为每个章节选择最合适的组件类型,确保不违反"禁止连续使用同一图表类型"约束
- 逐一对照章节清单,确认覆盖率和组件数量满足要求
- 按布局分配原则执行布局规划
3. **生成输出**: **最终只输出被 ` ```seller-report ... ``` ` 包裹的单个 JSON 对象**,不输出任何分析过程、章节清单、规划说明等中间内容。用户看到的应该只有这一个 ` ```seller-report ` 代码块。
## 重要约束
- 内容严格来自报告数据,禁止捏造数据
- 对于表现不佳的数据,避免"立即暂停""彻底下架""完全停止"等极端措辞,采用"诊断—优化—再决策"的渐进式策略
- 如果报告数据未提供有效信息,直接返回"暂无内容"
- **禁止裸数字**(全局约束,适用于所有组件):任何展示给用户的数值都必须附带含义标注,让用户无需上下文即可理解该数值代表什么。具体要求:
- 数值必须包含单位或含义前缀/后缀(如"销量倍数 ×2.1"而非"×2.1","毛利率 35%"而非"35%")
- 如果字段本身的 key/label 已经明确了含义(如 `"desc": "毛利率", "value": "35%"`),则 value 中无需重复标注
- 但如果数值出现在缺乏语义上下文的字段中(如 TimelineCard 的 `target`、DataCard 的 `value`),必须在数值中内嵌含义
- ❌ `"target": "×2.1"` ← 无法理解 2.1 是什么的倍数
- ✅ `"target": "搜索量×2.1"` 或 `"target": "销量增长2.1倍"`
- ❌ `"value": "9500"` ← 不知道 9500 是什么
- ✅ `"value": "9500次曝光"` 或配合 `"desc": "曝光量"` 使用
don't have the plugin yet? install it then click "run inline in claude" again.