# Layout: `comparison_cards` — 对比卡片(A vs B) > 幻灯片尺寸: 13.333 × 7.5 英寸 | 边距: 0.6 英寸 | 内容宽: 12.133 英寸 --- ## 用途 两家公司对比、方案A vs 方案B、Before/After、两只基金横向比较。 --- ## ASCII 线框图 ``` ┌─────────────────────────────────────────────────────────────┐ │ [标题] y=0.25 │ │ ▬▬ (accent 装饰线) y=0.90 │ │ │ │ ┌──────────────────────────┐VS┌──────────────────────────┐ │ │ │ [left_color 顶部色带] │ │ [right_color 顶部色带] │ │ │ │ │ │ │ │ │ │ [Left Title] │ │ [Right Title] │ │ │ │ [Left Subtitle] │ │ [Right Subtitle] │ │ │ │ ─────────────────────── │ │ ─────────────────────── │ │ │ │ 指标A 3,521点 │ │ 指标A 3,089点 │ │ │ │ 指标B +12.3% │ │ 指标B +8.7% │ │ │ │ 指标C 0.85 │ │ 指标C 0.62 │ │ │ │ 指标D 2.15% │ │ 指标D 3.40% │ │ │ │ 指标E AA │ │ 指标E A │ │ │ └──────────────────────────┘ └──────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 精确坐标标注 ### 固定元素 | 元素 | 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 | — | ### "VS" 中间分隔 | 元素 | x | y | w | h | 字号 | 颜色 | 对齐 | |------|---|---|---|---|------|------|------| | "VS" 文字 | 6.167 | 3.50 | 1.00 | 0.60 | subtitle_size+4 | text_muted | 中 | | 中央竖线(可选) | 6.617 | 1.10 | 0.01 | 5.80 | — | border | — | > VS 文字居中于两卡片之间间隙 (x≈6.167,间隙约1.0英寸) ### 卡片尺寸 ``` vs_gap = 1.00 # VS 区域宽度 card_w = (12.133 - vs_gap) / 2 = 5.567" left_x = 0.60 right_x = 0.60 + 5.567 + 1.00 = 7.167 card_y = 1.10 card_h = 5.80 (到 y=6.90) ``` ### 左/右卡片内部结构(以左卡片 x=0.60 为例) | 元素 | x(相对 card_x) | y | w | h | 字号 | 颜色 | 对齐 | |------|-----------------|---|---|---|------|------|------| | 卡片背景(圆角矩形) | +0 | 1.10 | 5.567 | 5.80 | — | card_bg | — | | 顶部色带 | +0 | 1.10 | 5.567 | 0.08 | — | left_color / right_color | — | | 卡片标题 | +0.20 | 1.28 | 5.167 | 0.55 | subtitle_size+2 | text_dark | 左 | | 卡片副标题 | +0.20 | 1.88 | 5.167 | 0.40 | body_size | text_muted | 左 | | 分隔线 | +0.20 | 2.35 | 5.167 | 0.02 | — | border | — | | 指标区域(起始 y) | +0.20 | 2.50 | 5.167 | — | — | — | — | **指标行(每行)**: ``` row_start_y = 2.50 row_h = 0.55 # 每行高度 max_rows = floor((6.90 - 2.50) / 0.55) = 8行(最多) 建议 5-7 行 ``` | 元素 | x(相对 card_x) | y(相对 row_y) | w | h | 字号 | 颜色 | 对齐 | |------|-----------------|----------------|---|---|------|------|------| | 指标名称 | +0.20 | +0 | 2.80 | 0.40 | body_size | text_muted | 左 | | 指标数值 | +3.00 | +0 | 2.37 | 0.40 | body_size | text_dark | 右 | | 行间细线 | +0.20 | +0.47 | 5.167 | 0.01 | — | border | — | **胜出方高亮规则**(当某指标某卡片更优时): - 数值颜色改为 `positive`(绿),`bold=True` - 或在数值前加 ▲ 符号 - 或行背景加极浅的 `positive` 色(透明度 10%) ### 底部注释(可选) | 元素 | x | y | w | h | 字号 | 颜色 | |------|---|---|---|---|------|------| | 来源说明 | 0.60 | 7.10 | 12.133 | 0.30 | caption_size | text_muted | --- ## 颜色约定 | 元素 | 默认值 | 说明 | |------|--------|------| | left_color | primary | 左卡片顶部色带 | | right_color | secondary | 右卡片顶部色带(可自定义) | | 胜出数值 | positive | 某指标上较优的一方 | | 劣势数值 | negative | 某指标上较差的一方(可选显示) | | "VS" 文字 | text_muted | 居中,降调处理 | --- ## 数据接口 ```python data = { "title": str, # 页面标题 "subtitle": str, # 可选,如 "截至2024年12月31日" "left": { "title": str, # 左卡片主标题(如公司名/方案名) "subtitle": str, # 可选,左卡片副标题 "color": str, # 可选,顶部色带颜色(主题变量名,默认 "primary") "items": [ { "label": str, # 指标名(如 "近一年收益") "value": str, # 指标值(如 "+12.3%") "better": bool, # 可选,是否为该指标的优胜方(高亮显示) }, ... ], }, "right": { # 同上 }, "source": str, # 可选,数据来源 } ``` --- ## 实现伪代码 ```python def layout_comparison_cards(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"]) # "VS" add_text(slide, "VS", x=6.167, y=3.50, w=1.00, h=0.60, font_size=theme["subtitle_size"]+4, color=theme["text_muted"], bold=True, align="center", font_name=theme["header_font"]) vs_gap = 1.00 card_w = (cw - vs_gap) / 2 # 5.567" card_y = 1.10 card_h = 5.80 for side, card_x in [("left", m), ("right", m + card_w + vs_gap)]: card_data = data[side] top_color = theme.get(card_data.get("color", "primary" if side=="left" else "secondary")) # 卡片背景 add_rounded_rect(slide, card_x, card_y, card_w, card_h, fill=theme["card_bg"], border=theme["border"], radius=0.10) # 顶部色带 add_rect(slide, card_x, card_y, card_w, 0.08, fill=top_color) # 标题 add_text(slide, card_data["title"], x=card_x+0.20, y=1.28, w=card_w-0.40, h=0.55, font_size=theme["subtitle_size"]+2, color=theme["text_dark"], bold=True, font_name=theme["header_font"]) if card_data.get("subtitle"): add_text(slide, card_data["subtitle"], x=card_x+0.20, y=1.88, w=card_w-0.40, h=0.40, font_size=theme["body_size"], color=theme["text_muted"], font_name=theme["body_font"]) # 分隔线 add_rect(slide, card_x+0.20, 2.35, card_w-0.40, 0.02, fill=theme["border"]) # 指标行 row_y = 2.50 row_h = 0.55 for item in card_data["items"]: val_color = theme["positive"] if item.get("better") else theme["text_dark"] add_text(slide, item["label"], x=card_x+0.20, y=row_y, w=3.00, h=0.40, font_size=theme["body_size"], color=theme["text_muted"], font_name=theme["body_font"]) add_text(slide, item["value"], x=card_x+0.20, y=row_y, w=card_w-0.40, h=0.40, font_size=theme["body_size"], color=val_color, bold=item.get("better", False), align="right", font_name=theme["body_font"]) add_rect(slide, card_x+0.20, row_y+0.47, card_w-0.40, 0.01, fill=theme["border"]) row_y += row_h if data.get("source"): add_text(slide, f"数据来源:{data['source']}", x=m, y=7.10, w=cw, h=0.30, font_size=theme["caption_size"], color=theme["text_muted"], font_name=theme["body_font"]) ``` --- ## 设计要点 1. **"VS" 居中** 在两卡片之间间隙正中,字号略大,用 `text_muted` 降调,不抢主体 2. **顶部色带** 区分左右卡片身份,通常左用 `primary`,右用 `secondary` 或 `accent` 3. **胜出指标高亮** 用 `positive` 绿色+粗体,对比一目了然 4. **指标行数** 最多 7 行(含卡片标题区后剩余 4.4 英寸 / 0.55 = 8 行,预留间距后7行) 5. **指标名长度** 建议 8 字以内;数值最长 10 个字符(含符号) --- ## 测试数据示例 ```python data = { "title": "基金产品横向对比", "subtitle": "截至2024年12月31日", "left": { "title": "国投养老稳健型 A", "subtitle": "成立日期:2015年3月", "items": [ {"label": "近一年收益", "value": "+12.3%", "better": True}, {"label": "近三年年化", "value": "+8.7%", "better": True}, {"label": "最大回撤", "value": "-5.2%", "better": True}, {"label": "夏普比率", "value": "1.85", "better": True}, {"label": "管理费率", "value": "0.80%", "better": False}, {"label": "规模(亿元)", "value": "380"}, {"label": "评级", "value": "★★★★★"}, ], }, "right": { "title": "同类产品均值", "subtitle": "(Wind 同类基金平均)", "items": [ {"label": "近一年收益", "value": "+8.9%"}, {"label": "近三年年化", "value": "+6.2%"}, {"label": "最大回撤", "value": "-8.1%"}, {"label": "夏普比率", "value": "1.12"}, {"label": "管理费率", "value": "0.65%", "better": True}, {"label": "规模(亿元)", "value": "85"}, {"label": "评级", "value": "★★★"}, ], }, "source": "Wind 资讯,国投养老基金管理有限公司", } ```