关于 card-creation
这是一份通过 community-domo-cli 程序化创建、读取和更新 Domo KPI 卡片的参考技能,面向构建卡片管理流程的用户。内容涵盖卡片结构、列映射、公式和图表类型。
主要功能
- 01卡片创建、读取与更新指南
- 02完整的卡片请求结构
- 03列映射与聚合方式
- 04Beast Mode 公式参考
- 05图表类型与覆盖设置指南
适用场景
- 01根据数据集创建 KPI 卡片
- 02保留现有字段并更新卡片
- 03选择图表列与聚合方式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ stahura/ domo-ai-vibe-rules --skill card-creation安装后在 Claude Code 中输入/card-creation确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdreferences/area.mdbar.mdbarline.mddata-science.mdexamples.mdgauge.mdline.mdmap.mdperiod-over-period.mdpie.mdselector.mdsmall-charts.mdspecialty.mdstatistical.mdtable.md详细介绍
Domo 卡片 CRUD 参考
CLI 与原始 API:所有卡片操作都使用
community-domo-cli。无需原始 curl/fetch。CLI 封装了 Domo Product API 端点并自动处理认证。
以编程方式管理 KPI 卡片的完整参考。记录了 207 种图表类型及其覆盖数据。206/207 已确认可用(仅 badge_line 失败)。
1. CRUD 操作
创建卡片
community-domo-cli --output json -y cards create \
--body-file card.json --page-id $PAGE_ID > card_response.json
CARD_ID=$(python3 -c "import json; print(json.load(open('card_response.json'))['id'])")
创建时 --page-id 是必填项。
读取卡片定义
community-domo-cli --output json cards definition $CARD_ID > card_def.json
返回 definition、dataSourceWrite、drillpath、columns。读写格式不匹配问题请参阅注意事项。
更新卡片
community-domo-cli --output json -y cards update $CARD_ID \
--body-file card_updated.json
完整替换全部内容——需包含所有字段,而不仅仅是更改的字段。始终先读取、修改,再写回。
复制卡片(原始 API——无 CLI 命令)
curl -X POST "https://$INSTANCE/api/content/v1/cards/$CARD_ID/copy" \
-H "x-domo-developer-token: $TOKEN" -H "Content-Type: application/json" -d '{}'
删除卡片(原始 API——无 CLI 命令)
curl -X DELETE "https://$INSTANCE/api/content/v1/cards/$CARD_ID" \
-H "x-domo-developer-token: $TOKEN"
永久删除,无法撤销。
辅助操作
# Discover dataset columns before creating cards
community-domo-cli --output json datasets schema $DATASET_ID > schema.json
# List cards on a page
community-domo-cli --output json pages list-cards $PAGE_ID
# Add an existing card to another page (goes to appendix)
community-domo-cli -y pages add-card $PAGE_ID $CARD_ID
# Create a beast mode / variable
community-domo-cli --output json -y beast-modes create --body-file beastmode.json
2. 完整 Body Schema
这是 CREATE 和 UPDATE 操作所需的精确结构。
{
"definition": {
"subscriptions": {
"big_number": {
"name": "big_number",
"columns": [
{
"column": "Revenue",
"aggregation": "SUM",
"alias": "Revenue",
"format": {"type": "abbreviated", "format": "#A"}
}
],
"filters": []
},
"main": {
"name": "main",
"columns": [
{"column": "Team", "mapping": "ITEM"},
{"column": "Revenue", "mapping": "VALUE", "aggregation": "SUM"}
],
"filters": [],
"orderBy": [],
"groupBy": [{"column": "Team"}],
"fiscal": false,
"projection": false,
"distinct": false
}
},
"formulas": {
"dsUpdated": [],
"dsDeleted": [],
"card": []
},
"annotations": {
"new": [],
"modified": [],
"deleted": []
},
"conditionalFormats": {
"card": [],
"datasource": []
},
"controls": [],
"segments": {
"active": [],
"create": [],
"update": [],
"delete": []
},
"charts": {
"main": {
"component": "main",
"chartType": "badge_vert_bar",
"overrides": {},
"goal": null
}
},
"dynamicTitle": {
"text": [{"text": "My Card Title", "type": "TEXT"}]
},
"dynamicDescription": {
"text": [{"text": "Card description here", "type": "TEXT"}],
"displayOnCardDetails": true
},
"chartVersion": "12",
"inputTable": false,
"noDateRange": false,
"title": "My Card Title",
"description": "Card description here"
},
"dataProvider": {
"dataSourceId": "DATASET_UUID_HERE"
},
"variables": true,
"columns": false
}
逐字段参考
根层级
| 字段 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
definition | object | 是 | 包含所有卡片配置 |
dataProvider.dataSourceId | string | 是 | 数据集 UUID。必须使用 dataSourceId,而不是 dsId! |
variables | boolean | 是 | 必须为 true。 |
columns | boolean | 是 | 必须为 false。 |
definition.subscriptions.big_number
控制卡片顶部的摘要数字。始终必填,但对于 badge_singlevalue,columns 应为空(卡片本身会显示该数字)。
| 字段 | 类型 | 描述 |
|---|---|---|
name | string | 始终为 "big_number" |
columns | array | 对于 badge_singlevalue 为空 []。所有其他类型为第一个 VALUE 列。 |
columns[].column | string | 列名(用于数据集列) |
columns[].formulaId | string | Beast mode ID(用于计算字段) |
columns[].aggregation | string | SUM、AVG、COUNT、MIN、MAX |
columns[].alias | string | 显示名称 |
columns[].format | object | {"type": "abbreviated", "format": "#A"} |
filters | array | big_number 始终为 [] |
definition.subscriptions.main
| 字段 | 类型 | 描述 |
|---|---|---|
name | string | 始终为 "main" |
columns | array | 所有列定义及其映射(见第 3 节) |
filters | array | 筛选器对象 |
orderBy | array | 排序定义 |
groupBy | array | 根据 ITEM 和 SERIES 列自动构建:[{"column": "Name"}] |
fiscal | boolean | 默认为 false |
projection | boolean | 默认为 false |
distinct | boolean | 默认为 false |
筛选器对象结构:
{
"column": "Type",
"values": ["New Business"],
"filterType": "LEGACY",
"operand": "IN"
}
definition.formulas
| 字段 | 类型 | 描述 |
|---|---|---|
dsUpdated | array | 更新数据集级公式 |
dsDeleted | array | 删除数据集级公式 |
card | array | 卡片级 beast modes(见第 4 节) |
definition.charts.main
| 字段 | 类型 | 描述 |
|---|---|---|
component | string | 始终为 "main" |
chartType | string | 207 种类型之一(见第 5 节) |
overrides | object | 图表样式覆盖(所有值均为字符串) |
goal | null/object | 目标线配置 |
definition.conditionalFormats——必须是 object
{"card": [], "datasource": []}
definition.segments——必须是 object
{"active": [], "create": [], "update": [], "delete": []}
definition.dynamicTitle / dynamicDescription
{
"text": [{"text": "Title goes here", "type": "TEXT"}]
}
dynamicDescription 还具有 "displayOnCardDetails": true。
其他定义字段
| 字段 | 类型 | 默认值 | 描述 |
|---|---|---|---|
chartVersion | string | "12" | 图表渲染版本 |
inputTable | boolean | false | 卡片是否为输入表格 |
noDateRange | boolean | false | 禁用日期范围筛选 |
title | string | -- | 纯文本标题(同时设置 dynamicTitle) |
description | string | -- | 纯文本描述 |
3. 列映射
映射类型
| 映射 | 视觉角色 | 是否必需 | 描述 |
|---|---|---|---|
ITEM | X 轴 / 类别 | 是(大多数图表) | 维度/类别轴 |
VALUE | Y 轴 / 度量 | 是 | 被度量的数值 |
SERIES | 颜色 / 图例 | 否 | 将数据分组为彩色系列 |
列对象结构
对于数据集列:
{
"column": "Team",
"mapping": "ITEM",
"aggregation": "SUM",
"alias": "Team Name",
"format": {"type": "number", "format": "###,##0"}
}
对于 beast mode 列:
{
"formulaId": "calculation_123456",
"mapping": "VALUE",
"aggregation": "SUM",
"alias": "Win Rate %"
}
字段参考
| 字段 | 是否必需 | 描述 |
|---|---|---|
column | 是* | 数据集中的列名 |
formulaId | 是* | Beast mode 旧版 ID(用于计算字段,替代 column) |
mapping | 是 | ITEM、VALUE 或 SERIES |
aggregation | 否 | SUM、AVG、COUNT、MIN、MAX、UNIQUE |
alias | 否 | 显示名称覆盖 |
format | 否 | 数字/日期格式化对象 |
*column 或 formulaId 必须提供其一。
按图表类型的示例
条形图(类别 + 度量):
[
{"column": "Region", "mapping": "ITEM"},
{"column": "Revenue", "mapping": "VALUE", "aggregation": "SUM"}
]
堆叠条形图(类别 + 度量 + 系列):
[
{"column": "Region", "mapping": "ITEM"},
{"column": "Revenue", "mapping": "VALUE", "aggregation": "SUM"},
{"column": "Product Line", "mapping": "SERIES"}
]
单值(仅度量):
[
{"column": "Revenue", "mapping": "VALUE", "aggregation": "SUM", "alias": "Total Revenue"}
]
表格(多个项目):
[
{"column": "Name", "mapping": "ITEM"},
{"column": "Department", "mapping": "ITEM"},
{"column": "Revenue", "mapping": "VALUE", "aggregation": "SUM"},
{"column": "Deals", "mapping": "VALUE", "aggregation": "COUNT"}
]
groupBy 自动生成
从所有 ITEM 和 SERIES 列构建 groupBy:
group_by = []
for c in columns:
if c.get("mapping") in ("ITEM", "SERIES") and "column" in c:
group_by.append({"column": c["column"]})
4. Beast Modes
卡片级 vs 数据集级
| 作用域 | 存储 | 可见性 | 如何引用 |
|---|---|---|---|
| 卡片级 | definition.formulas.card[] | 仅在此卡片上 | 内联包含在卡片主体中 |
| 数据集级 | 通过 API 创建 | 使用该数据集的所有卡片 | 通过 formulaId 引用 |
创建 Beast Mode(数据集级)
community-domo-cli --output json -y beast-modes create \
--body-file beastmode.json > bm_response.json
请求体:
{
"name": "Revenue per Deal",
"owner": 705231757,
"locked": false,
"global": false,
"expression": "SUM(`Distinct Closed Won ACV`) / COUNT(`Opportunity ID`)",
"links": [
{
"resource": {"type": "DATA_SOURCE", "id": "DATASET_UUID"},
"visible": true,
"active": false,
"valid": "VALID"
}
],
"aggregated": true,
"analytic": false,
"nonAggregatedColumns": [],
"dataType": "DECIMAL",
"status": "VALID",
"cacheWindow": "non_dynamic",
"columnPositions": [],
"functions": [],
"functionTemplateDependencies": [],
"archived": false,
"hidden": false,
"variable": false
}
响应包含 id(UUID)和 legacyId —— 使用 legacyId 作为卡片列中的 formulaId。
dataType 选项
| 值 | 用于 |
|---|---|
DECIMAL | 货币、百分比、比率(默认) |
LONG | 整数、计数 |
DOUBLE | 高精度小数 |
STRING | 文本/类别结果 |
DATE | 日期计算 |
5. 图表类型索引
207 种图表类型,分为 22 个组。从下方索引中选择一个 badge_* 类型字符串,然后阅读相应的参考文件以了解覆盖详情。
badge_line是唯一在创建时返回 HTTP 400 的类型。请改用badge_two_trendline或badge_spark_line。 | Group | Count | Types | Reference | |-------|-------|-------|-----------| | Bar | 24 |badge_vert_bar,badge_horiz_bar,badge_vert_stackedbar,badge_horiz_stackedbar,badge_vert_multibar,badge_horiz_multibar,badge_vert_nestedbar,badge_horiz_nestedbar,badge_vert_percentbar,badge_horiz_percentbar,badge_vert_100pct,badge_horiz_100pct,badge_vert_dual_stackedbar,badge_horiz_dual_stackedbar,badge_vert_rtbar,badge_horiz_rtbar,badge_vert_rtmultibar,badge_horiz_rtmultibar,badge_vert_rtstackedbar,badge_horiz_rtstackedbar,badge_vert_bar_overlay,badge_horiz_bar_overlay,badge_vert_symbol,badge_spark_bar| references/bar.md | | Line | 16 |badge_trendline,badge_two_trendline,badge_curvedline,badge_stepline,badge_symbolline,badge_rttrendline,badge_stackedtrend,badge_variance_line,badge_spark_line,badge_curved_symbolline,badge_horiz_trendline,badge_horiz_curvedline,badge_horiz_stepline,badge_horiz_symbolline,badge_horiz_curved_symbolline,badge_horiz_stackedtrend| references/line.md | | Combo | 18 |badge_line_bar,badge_line_stackedbar,badge_line_clusterbar,badge_vert_bar_line,badge_horiz_bar_line,badge_curved_line_bar,badge_curved_line_stackedbar,badge_horiz_line_bar,badge_horiz_line_clusterbar,badge_horiz_line_stackedbar,badge_vert_100pct_linebar,badge_horiz_100pct_linebar,badge_vert_nested_linebar,badge_horiz_nested_linebar,badge_symbol_bar,badge_symbol_stackedbar,badge_horiz_symbol_bar,badge_horiz_symbol_stackedbar| references/barline.md | | Area + Dot Plot | 26 |badge_vert_area_overlay,badge_horiz_area_overlay,badge_vert_100pct_area,badge_horiz_100pct_area,badge_vert_curved_area_overlay,badge_horiz_curved_area_overlay,badge_vert_curved_stacked_area,badge_horiz_curved_stacked_area,badge_vert_curved_100pct_area,badge_horiz_curved_100pct_area,badge_vert_step_area_overlay,badge_horiz_step_area_overlay,badge_vert_step_stacked_area,badge_horiz_step_stacked_area,badge_vert_step_100pct_area,badge_horiz_step_100pct_area,badge_vert_dotplot_overlay,badge_horiz_dotplot_overlay,badge_vert_multi_dotplot,badge_horiz_multi_dotplot,badge_vert_stacked_dotplot,badge_horiz_stacked_dotplot,badge_vert_line_multi_dotplot,badge_horiz_line_multi_dotplot,badge_vert_line_stacked_dotplot,badge_horiz_line_stacked_dotplot| references/area.md | | Pie / Donut / Rose | 5 |badge_pie,badge_donut,badge_nautilus,badge_nautilus_donut,badge_nightingale_rose| references/pie.md | | Tables | 5 |badge_basic_table,badge_pivot_table,badge_flex_table,badge_table,badge_heatmap_table| references/table.md | | Gauges + Multi-Value | 16 |badge_singlevalue,badge_filledgauge,badge_gauge,badge_facegauge,badge_shapegauge,badge_compgauge,badge_compfillgauge_basic,badge_compfillgauge_adv,badge_progressbar,badge_radial_progress,badge_multi_radial_progress,badge_in_range_gauge,badge_imagegauge,badge_bullet,badge_multi_value,badge_multi_value_cols| references/gauge.md | | Maps | 42 |badge_world_map,badge_map,badge_map_us_state,badge_map_us_county,badge_map_latlong,badge_map_latlong_route, + 36 country maps | references/map.md | | Specialty | 16 |badge_treemap,badge_funnel,badge_funnel_bars,badge_funnel_swing,badge_waffle,badge_word_cloud,badge_stream,badge_stream_funnel,badge_slope,badge_bump,badge_pareto,badge_heatmap,badge_gantt,badge_gantt_dep,badge_gantt_percent,badge_calendar| references/specialty.md | | Data Science | 6 |badge_ds_forecasting,badge_ds_outliers,badge_ds_pred_modeling,badge_ds_spc,badge_correlation_matrix,badge_confusion_matrix| references/data-science.md | | Period over Period | 13 |badge_pop_trendline,badge_pop_trendline_var,badge_pop_rttrendline,badge_pop_bar_line,badge_pop_bar_line_var,badge_pop_line_bar,badge_pop_line_bar_var,badge_pop_vert_multibar,badge_pop_filledgauge,badge_pop_shapegauge,badge_pop_multi_value,badge_pop_progressbar,badge_pop_flex_table| references/period-over-period.md | | Statistical | 8 |badge_vert_histogram,badge_horiz_histogram,badge_vert_boxplot,badge_horiz_boxplot,badge_vert_waterfall,badge_horiz_waterfall,badge_xy_line,badge_xybubble| references/statistical.md | | Selectors | 6 |badge_checkbox_selector,badge_date_selector,badge_dropdown_selector,badge_radio_selector,badge_range_selector,badge_slicer| references/selector.md | | Text + Small Charts | 6 |badge_textbox,badge_dynamic_textbox,badge_vert_marimekko,badge_horiz_marimekko,badge_vert_facetedbar,badge_horiz_facetedbar| references/small-charts.md |
常见覆盖类别
大多数图表类型共享以下标准覆盖类别:
| 类别 | 用途 | 主要覆盖项 |
|---|---|---|
| general | 字体、排序、限制 | default_font_family、font_size(Smaller/Larger/Largest)、total_sort、display_limit、hide_interactivity、disable_animation |
| legend | 图例位置与样式 | lrg_legend_position(Top/Bottom/Hide)、details_legend_position、legend_font_family |
| bar_settings | 条形宽度/高度 | width_percentage、fixed_bar_width、allow_wide_bars |
| grid_lines | 网格线、零线、计算线 | hide_value_gridlines、grid_line_color、zero_line_color、calculated_line(Median/Average) |
| data_label_settings | 图表上的数值标签 | show_data_label(Always/Always - Rotated)、datalabel_position、datalabel_fnt_clr、decimal_places_dl |
| value_scale_y | Y 轴格式 | title_y、label_format_y(Number/Currency/Percentage)、divide_value_scale_by_y、value_scale_min、value_scale_max、log_scale_y |
| category_scale_x | X 轴格式 | title_x、cat_scale_show_labels、cat_scale_manual_rotate、max_label_length、never_use_time_scale |
| hover_text_settings | Tooltip 格式 | hover_text、hover_format、decimal_places_hvr |
| number_format | 货币/小数配置 | currency_symbol、currency_sym_position、decimal_separator、thousands_separator |
| gradient_colors | 颜色渐变 | use_gradient_colors、gradient_start_fill_color、gradient_end_fill_color、gradient_by_value |
| scale_marker | 参考线/范围 | sm_type(Line/Range/Quantiles)、sm_val_type、sm_value、sm_line_color |
| colors | 系列颜色 | series_1_color(十六进制字符串) |
覆盖值类型
| 类型 | 格式 | 示例 |
|---|---|---|
boolean | "true" 或 "false"(以字符串形式) | "use_gradient_colors": "true" |
string | 自由文本或十六进制颜色 | "gradient_start_fill_color": "#99CCEEFF" |
float | 以字符串形式表示的数字 | "display_limit": "10" |
select_list | 预定义值之一 | "font_size": "Largest" |
所有覆盖值都是字符串,即使是布尔值和数字。
6. 条件格式
结构必须是对象,而不是数组。
"conditionalFormats": {
"card": [
{
"type": "COLOR",
"column": "Revenue",
"rules": [
{"min": 0, "max": 50000, "color": "#FF0000", "label": "Below Target"},
{"min": 50000, "max": 100000, "color": "#FFAA00", "label": "Near Target"},
{"min": 100000, "color": "#00AA00", "label": "Above Target"}
]
}
],
"datasource": []
}
将 conditionalFormats 作为数组 [] 传入,而不是 {card:[], datasource:[]},会导致 HTTP 400。Domo UI 在读取时会将其作为数组返回——写入前请转换为对象。
7. 注意事项
关键——将导致失败
| 注意事项 | 详情 |
|---|---|
dataProvider.dataSourceId 而非 dsId | 字段名是 dataSourceId。使用 dsId 会静默失败。 |
根级必须包含 variables: true | 必须存在于根级别。 |
根级必须包含 columns: false | 必须存在于根级别。 |
| 两个订阅均为必需 | 必须同时包含 big_number 和 main。缺少任一都会导致 HTTP 400。 |
conditionalFormats 必须是对象 | {"card":[], "datasource":[]}。传入 [] 会导致 HTTP 400。 |
segments 必须是对象 | {"active":[], "create":[], "update":[], "delete":[]}。传入 [] 会导致 HTTP 400。 |
badge_line 会失败 | 始终返回 HTTP 400。请使用 badge_two_trendline 或 badge_spark_line。 |
CREATE 需要 --page-id | cards create --page-id $PAGE_ID — 必需。 |
| UPDATE 不使用 page-id | cards update $CARD_ID — 仅需 card ID。 |
重要 — 影响行为
| 注意事项 | 详情 |
|---|---|
| 覆盖值必须是字符串 | 即使是布尔值("true")和数字("10")也必须是字符串。 |
| UPDATE 会替换整个定义 | 完全替换。先读取,再修改,最后写回。 |
| READ→WRITE 格式不匹配 | 更新前先修复:formulas(read=[],write={"dsUpdated":[],"dsDeleted":[],"card":[]})、conditionalFormats(read=[],write={"card":[],"datasource":[]})、annotations(read=[],write={"new":[],"modified":[],"deleted":[]})、segments(read={"active":[],"definitions":[]},write={"active":[],"create":[],"update":[],"delete":[]})。如果缺失,还要添加 title、description、noDateRange;移除 modified、allowTableDrill。 |
groupBy 自动生成 | 从所有 ITEM 和 SERIES 列构建。缺少此项 = 不分组 = 所有值聚合为一个。 |
singlevalue 使用 big_number | badge_singlevalue 需要在 big_number 中设置 columns: []。所有其他类型:第一个 VALUE 列。 |
PoP 卡片需要 dateRangeFilter | 除非满足以下条件,否则 badge_pop_* 卡片会显示 "0" 对比:主项中日期列的 mapping:"ITEM"、aggregation:"MAX";带有 dateTimeRange 和 periods 的 dateRangeFilter;time_period 订阅。在添加 periods 之前移除 dateGrain(两者冲突)。 |
| 选择器卡片需要 big_number 列 | 空的 big_number.columns 会导致 400 {"message":"big_number subscription missing select columns"}。下拉菜单对筛选列使用 COUNT,日期选择器使用 MAX。 |
快速参考
CREATE: cards create --body-file card.json --page-id PAGE_ID
READ: cards definition CARD_ID
UPDATE: cards update CARD_ID --body-file card.json
COPY: POST /content/v1/cards/CARD_ID/copy (raw API)
DELETE: DELETE /content/v1/cards/CARD_ID (raw API)
Required root: variables=true, columns=false
Required data: dataProvider.dataSourceId (NOT dsId)
Required subs: big_number AND main
conditionalFormats: {card:[], datasource:[]} (OBJECT)
segments: {active:[], create:[], update:[], delete:[]} (OBJECT)
Line charts: badge_two_trendline (NOT badge_line)
Total types: 207 (206 work, badge_line fails)