skills/ppt-station-skill/reference/layout-progress-bars.md
wangyitong a65adcc2e5 Initial commit: merged, deduplicated, and vetted skill collection
Sources: extracted from two upstream archives (skill-repo, skills-main),
merged with the following policy:

- 15 broken symlinks (pointing to /Users/jameslee/.cc-switch/skills or
  ../../.agents/skills on a foreign machine) discarded
- 3 real name collisions with identical content (ai-pair, ifind-http-api,
  zhipu-websearch) kept as one copy
- Functional overlaps deduped keeping the strongest variant:
  - docx family: kept docx (official, full toolchain) + docx-cn
    (GB/T 9704 Chinese official-document constants),
    dropped docx_writer (no scripts, name collided with docx)
  - humanizer family: kept humanizer-zh (6 zh reference docs),
    dropped humanizer (en, redundant for CN workflow)
- Skills that only ran in a foreign environment removed:
  ablemind-ops, app-publish, hlb-design-system, openclaw-adj-skill,
  claude-driver
- alphapai excluded from this public repo because its SKILL.md hard-coded
  live credentials

Result: 25 skills, 572 files, ~7.5 MB.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 14:47:12 +08:00

271 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Layout: `progress_bars` — 进度条/评分页
> 幻灯片尺寸: 13.333 × 7.5 英寸 | 边距: 0.6 英寸 | 内容宽: 12.133 英寸
---
## 用途
评分展示、指标达标率、能力雷达平铺版、投资组合配置完成度、各资产类别评级。
---
## ASCII 线框图
### 变体 A单列进度条5-8 行)
```
┌─────────────────────────────────────────────────────────────┐
│ [标题] y=0.25 │
│ ▬▬ (accent 装饰线) y=0.90 │
│ │
│ 权益资产 ████████████████████░░░░░░░░░░ 80% │
│ [进度条背景(浅色)] │
│ │
│ 固定收益 █████████████░░░░░░░░░░░░░░░░░░ 52% │
│ │
│ 另类资产 ████████░░░░░░░░░░░░░░░░░░░░░░░ 32% │
│ │
│ 海外资产 ████████████████░░░░░░░░░░░░░░░ 64% │
│ │
│ 货币市场 ██████░░░░░░░░░░░░░░░░░░░░░░░░░ 24% │
│ │
└─────────────────────────────────────────────────────────────┘
```
### 变体 B带目标值的进度条显示目标线
```
│ 权益资产 ████████████████████░░░░│░░░░░ 80% / 目标 90%│
│ ↑ 目标线(垂直虚线)
```
### 变体 C双列进度条6-10 行每列3-5行
```
│ [左列标题] │ [右列标题] │
│ 指标一 ████░░░ 75% │ 指标A ████████░░ 80% │
│ 指标二 ██░░░░ 40% │ 指标B █████████░ 90% │
│ 指标三 ███████░ 70% │ 指标C ████░░░░░ 42% │
```
---
## 精确坐标标注
### 变体 A单列5-8 行)
**固定元素**
| 元素 | x | y | w | h | 字号 | 颜色 | 对齐 |
|------|---|---|---|---|------|------|------|
| 页面标题 | 0.60 | 0.25 | 12.133 | 0.60 | title_size-2 | text_dark | 左 |
| 装饰线 | 0.60 | 0.90 | 2.00 | 0.04 | — | accent | — |
**行高计算**
```
list_start_y = 1.20
available_h = 5.80 # 7.5 - 1.20 - 0.50(bottom)
row_h = available_h / N
N=5: row_h = 1.16"
N=6: row_h = 0.97"
N=7: row_h = 0.83"
N=8: row_h = 0.73"(最密,仍可读)
```
**单行结构(以 row_y 为行顶部)**
| 元素 | x | y相对 row_y | w | h | 字号 | 颜色 | 对齐 |
|------|---|----------------|---|---|------|------|------|
| 标签文字 | 0.60 | +0.15 | 2.80 | 0.40 | body_size | text_dark | 左 |
| 进度条背景(轨道) | 3.50 | +0.20 | 7.80 | 0.30 | — | secondary | — |
| 进度条填充 | 3.50 | +0.20 | 7.80 × (value/max) | 0.30 | — | primary | — |
| 数值文字 | 11.45 | +0.15 | 1.28 | 0.40 | body_size | text_dark | 右 |
> **进度条圆角**: radius=0.05"(轨道和填充均为圆角矩形)
> **填充颜色规则**:
> - 默认: `primary`
> - value/max >= 0.8(优秀): `positive`(绿)
> - value/max <= 0.3(危险): `negative`(红)
> - 可通过 `item.color` 强制指定颜色变量名
**目标线(变体 B**:
```
target_x = 3.50 + 7.80 * (target/max)
add_rect(slide, target_x-0.01, row_y+0.15, 0.02, 0.40,
fill=theme["accent"])
# 目标值文字
add_text(slide, f"目标:{target_fmt}",
x=target_x-0.40, y=row_y+0.57, w=0.80, h=0.25,
font_size=theme["caption_size"]-1, color=theme["accent"],
align="center")
```
**可选副标注**(进度条下方小字):
```
x=3.50, y=row_y+0.52, w=7.80, h=0.28
font_size=caption_size-1, color=text_muted
示例: "较上季度 +5.2 个百分点"
```
### 变体 C双列
```
col_gap = 0.60
col_w = (12.133 - col_gap) / 2 = 5.767"
左列: x_left = 0.60
右列: x_right = 0.60 + 5.767 + 0.60 = 6.967
每列标签宽: 1.80"
进度条宽: 5.767 - 1.80 - 1.00 = 2.967"
数值宽: 1.00"
```
---
## 数据接口
```python
data = {
"title": str, # 页面标题
"subtitle": str, # 可选,如 "投资组合达标情况满分100"
"variant": "single" | "target" | "double", # 布局变体,默认 "single"
"max_value": float, # 统一最大值(如 100默认 100
"unit": str, # 可选,数值单位(如 "%", "分"),显示在数值旁
"items": [
{
"label": str, # 行标签10字以内
"value": float, # 当前值
"max_value": float, # 可选,覆盖全局 max_value
"target": float, # 可选,目标值(变体 B 专用)
"value_fmt": str, # 可选,自定义数值显示文字(如 "80分"
"note": str, # 可选,进度条下方小注
"color": str, # 可选,强制指定填充颜色(主题变量名)
},
... # 最多 8 行(单列)/ 10 行(双列)
],
# 双列变体时variant="double"
"left_items": [...], # 左列数据
"right_items": [...], # 右列数据
"left_title": str, # 可选,左列分组标题
"right_title": str, # 可选,右列分组标题
}
```
---
## 实现伪代码
```python
def layout_progress_bars(slide, data, theme):
m = theme["margin"]
sw, sh = 13.333, 7.5
cw = sw - 2 * m
set_slide_bg(slide, theme["bg_light"])
add_text(slide, data["title"],
x=m, y=0.25, w=cw, h=0.60,
font_size=theme["title_size"]-2, color=theme["text_dark"],
bold=True, font_name=theme["header_font"])
add_rect(slide, m, 0.90, 2.0, 0.04, fill=theme["accent"])
items = data["items"]
N = len(items)
global_max = data.get("max_value", 100)
list_y = 1.20
row_h = max(0.73, (sh - list_y - 0.50) / N)
bar_x = 3.50
bar_total_w = 7.80
bar_h = 0.30
bar_radius = 0.05
for i, item in enumerate(items):
ry = list_y + i * row_h
max_v = item.get("max_value", global_max)
ratio = min(max(item["value"] / max_v, 0), 1)
# 颜色选择
if item.get("color"):
fill_color = theme[item["color"]]
elif ratio >= 0.8:
fill_color = theme["positive"]
elif ratio <= 0.3:
fill_color = theme["negative"]
else:
fill_color = theme["primary"]
# 标签
add_text(slide, item["label"],
x=m, y=ry+0.15, w=2.80, h=0.40,
font_size=theme["body_size"], color=theme["text_dark"],
font_name=theme["body_font"])
# 轨道背景
add_rounded_rect(slide, bar_x, ry+0.20, bar_total_w, bar_h,
fill=theme["secondary"], radius=bar_radius)
# 填充(仅当 ratio > 0
if ratio > 0:
add_rounded_rect(slide, bar_x, ry+0.20, bar_total_w*ratio, bar_h,
fill=fill_color, radius=bar_radius)
# 目标线
if item.get("target") and data.get("variant") == "target":
t_ratio = min(item["target"] / max_v, 1)
t_x = bar_x + bar_total_w * t_ratio
add_rect(slide, t_x-0.01, ry+0.12, 0.02, 0.46, fill=theme["accent"])
# 数值
val_text = item.get("value_fmt",
f"{item['value']:.0f}{data.get('unit','%')}")
add_text(slide, val_text,
x=11.45, y=ry+0.15, w=1.28, h=0.40,
font_size=theme["body_size"], color=theme["text_dark"],
bold=True, align="right", font_name=theme["body_font"])
# 小注
if item.get("note"):
add_text(slide, item["note"],
x=bar_x, y=ry+0.52, w=bar_total_w, h=0.28,
font_size=theme["caption_size"]-1, color=theme["text_muted"],
font_name=theme["body_font"])
```
---
## 设计要点
1. **进度条高度** 固定 0.30 英寸(够粗,清晰可见),不随行数缩放
2. **标签宽度** 固定 2.80 英寸,给进度条留足 7.80 英寸空间
3. **颜色自动映射**: ≥80% 绿≤30% 红,中间默认 `primary`,使进度条直观传达状态
4. **圆角** 0.05 英寸,轨道和填充同半径,视觉一致
5. **目标线**`accent` 色细竖线,明显但不抢主体
6. **最多8行**(单列时),超过时用双列变体
---
## 测试数据示例
```python
data = {
"title": "投资组合各类资产配置达标率",
"subtitle": "目标配比达成情况截至2024年12月",
"max_value": 100,
"unit": "%",
"variant": "target",
"items": [
{"label": "国内权益", "value": 82, "target": 85, "note": "较目标低 3 个百分点"},
{"label": "境外权益", "value": 45, "target": 40, "note": "较目标高 5 个百分点,需减仓"},
{"label": "利率债", "value": 78, "target": 75},
{"label": "信用债", "value": 31, "target": 40, "note": "受信用资质收紧影响", "color": "negative"},
{"label": "REITs", "value": 60, "target": 60},
{"label": "海外债券", "value": 25, "target": 30},
],
}
```