@wubaoqi/guancopilot 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +17 -0
- package/README.md +146 -2
- package/assets/coreutils.wasm +0 -0
- package/assets/find.wasm +0 -0
- package/assets/guanbi.wasm +4 -0
- package/assets/guancli.wasm +0 -0
- package/assets/guanhelm.wasm +0 -0
- package/assets/jq.wasm +0 -0
- package/assets/openskills.wasm +0 -0
- package/assets/rg.wasm +0 -0
- package/assets/sed.wasm +0 -0
- package/bin/guancopilot +0 -0
- package/bin/guanvm +0 -0
- package/bin/platforms.cjs +6 -0
- package/bin/run.cjs +39 -0
- package/bin/runtime.cjs +44 -0
- package/licenses/Go-LICENSE +27 -0
- package/licenses/browser-_speed-highlight_core-LICENSE +121 -0
- package/licenses/browser-_speed-highlight_core-package.json +14 -0
- package/licenses/browser-dompurify-LICENSE +202 -0
- package/licenses/browser-dompurify-LICENSE-MPL +373 -0
- package/licenses/browser-dompurify-package.json +10 -0
- package/licenses/browser-marked-LICENSE +44 -0
- package/licenses/browser-marked-package.json +10 -0
- package/licenses/coreutils-LICENSE +18 -0
- package/licenses/findutils-LICENSE +18 -0
- package/licenses/github.com_BurntSushi_toml_v1.6.0-COPYING +21 -0
- package/licenses/github.com_dustin_go-humanize_v1.0.1-LICENSE +21 -0
- package/licenses/github.com_google_jsonschema-go_v0.4.3-LICENSE +21 -0
- package/licenses/github.com_google_uuid_v1.6.0-LICENSE +27 -0
- package/licenses/github.com_jackc_pgpassfile_v1.0.0-LICENSE +22 -0
- package/licenses/github.com_jackc_pgservicefile_v0.0.0-20240606120523-5a60cdf6a761-LICENSE +22 -0
- package/licenses/github.com_jackc_pgx_v5_v5.11.0-LICENSE +22 -0
- package/licenses/github.com_jackc_puddle_v2_v2.2.2-LICENSE +22 -0
- package/licenses/github.com_mattn_go-isatty_v0.0.20-LICENSE +9 -0
- package/licenses/github.com_modelcontextprotocol_go-sdk_v1.8.0-LICENSE +216 -0
- package/licenses/github.com_ncruces_go-strftime_v1.0.0-LICENSE +21 -0
- package/licenses/github.com_remyoudompheng_bigfft_v0.0.0-20230129092748-24d4a6f8daec-LICENSE +27 -0
- package/licenses/github.com_santhosh-tekuri_jsonschema_v6_v6.0.3-LICENSE +175 -0
- package/licenses/github.com_segmentio_asm_v1.1.3-LICENSE +21 -0
- package/licenses/github.com_segmentio_encoding_v0.5.4-LICENSE +21 -0
- package/licenses/github.com_tetratelabs_wazero_v1.12.0-LICENSE +201 -0
- package/licenses/github.com_tetratelabs_wazero_v1.12.0-NOTICE +2 -0
- package/licenses/github.com_yosida95_uritemplate_v3_v3.0.2-LICENSE +25 -0
- package/licenses/golang.org_x_image_v0.44.0-LICENSE +27 -0
- package/licenses/golang.org_x_net_v0.58.0-LICENSE +27 -0
- package/licenses/golang.org_x_oauth2_v0.36.0-LICENSE +27 -0
- package/licenses/golang.org_x_sync_v0.22.0-LICENSE +27 -0
- package/licenses/golang.org_x_sys_v0.47.0-LICENSE +27 -0
- package/licenses/golang.org_x_text_v0.41.0-LICENSE +27 -0
- package/licenses/golang.org_x_time_v0.15.0-LICENSE +27 -0
- package/licenses/guanbi-skills-LICENSE +133 -0
- package/licenses/guanbi-skills-LICENSE.README.md +28 -0
- package/licenses/guanbi-skills-LICENSE.zh-CN +82 -0
- package/licenses/jq-COPYING +176 -0
- package/licenses/modernc.org_libc_v1.73.4-LICENSE +27 -0
- package/licenses/modernc.org_libc_v1.73.4-LICENSE-3RD-PARTY.md +305 -0
- package/licenses/modernc.org_mathutil_v1.7.1-LICENSE +27 -0
- package/licenses/modernc.org_memory_v1.11.0-LICENSE +27 -0
- package/licenses/modernc.org_memory_v1.11.0-LICENSE-GO +27 -0
- package/licenses/modernc.org_memory_v1.11.0-LICENSE-LOGO +1 -0
- package/licenses/modernc.org_memory_v1.11.0-LICENSE-MMAP-GO +25 -0
- package/licenses/modernc.org_sqlite_v1.53.0-LICENSE +26 -0
- package/licenses/mvdan.cc_sh_v3_v3.13.1-LICENSE +27 -0
- package/licenses/ripgrep-COPYING +3 -0
- package/licenses/ripgrep-LICENSE-MIT +21 -0
- package/licenses/sed-LICENSE +21 -0
- package/manifest.json +972 -0
- package/package.json +30 -4
- package/plugin/guancopilot.js +193 -0
- package/skills-bundle/.guanvm-skills-bundle +0 -0
- package/skills-bundle/_recipes/dashboard/gates/page_check.js +16 -0
- package/skills-bundle/_recipes/dashboard/gates/report_check.js +4 -0
- package/skills-bundle/_recipes/dashboard/knowledge/01.md +1 -0
- package/skills-bundle/_recipes/dashboard/knowledge/02.md +1 -0
- package/skills-bundle/_recipes/dashboard/knowledge/03.md +1 -0
- package/skills-bundle/_recipes/dashboard/knowledge/04.md +1 -0
- package/skills-bundle/_recipes/dashboard/knowledge/05.md +1 -0
- package/skills-bundle/_recipes/dashboard/knowledge/06.md +1 -0
- package/skills-bundle/_recipes/dashboard/template.json +41 -0
- package/skills-bundle/_recipes/etl/gates/etl_live_check.js +10 -0
- package/skills-bundle/_recipes/etl/gates/etl_report_check.js +3 -0
- package/skills-bundle/_recipes/etl/knowledge/01.md +1 -0
- package/skills-bundle/_recipes/etl/knowledge/02.md +9 -0
- package/skills-bundle/_recipes/etl/knowledge/03.md +1 -0
- package/skills-bundle/_recipes/etl/knowledge/04.md +1 -0
- package/skills-bundle/_recipes/etl/knowledge/05.md +1 -0
- package/skills-bundle/_recipes/etl/template.json +39 -0
- package/skills-bundle/_recipes/hints.json +46 -0
- package/skills-bundle/guancli/.commandface.json +155 -0
- package/skills-bundle/guancli/SKILL.md +342 -0
- package/skills-bundle/guancli/evals/evals.json +156 -0
- package/skills-bundle/guancli/evals/fixtures/metric-candidate-empty-search.json +13 -0
- package/skills-bundle/guancli/evals/fixtures/metric-candidate-prior-request.json +13 -0
- package/skills-bundle/guancli/evals/fixtures/metric-consumption-columns.json +46 -0
- package/skills-bundle/guancli/evals/fixtures/metric-consumption-metadata.json +36 -0
- package/skills-bundle/guancli/evals/fixtures/metric-consumption-query.json +18 -0
- package/skills-bundle/guancli/references/analysis-primitives.md +95 -0
- package/skills-bundle/guancli/references/auth-and-config.md +131 -0
- package/skills-bundle/guancli/references/examples/metric-date-in.json +7 -0
- package/skills-bundle/guancli/references/examples/metric-query-rows.py +83 -0
- package/skills-bundle/guancli/references/examples/metric-query.sh +6 -0
- package/skills-bundle/guancli/references/form-chatbi.md +199 -0
- package/skills-bundle/guancli/references/gateway.md +148 -0
- package/skills-bundle/guancli/references/metric-batch-query.md +82 -0
- package/skills-bundle/guancli/references/metric-commands.md +562 -0
- package/skills-bundle/guancli/references/metric-generic-query.md +215 -0
- package/skills-bundle/guancli/references/metric-json-migration.md +18 -0
- package/skills-bundle/guancli/references/metric-query-recipes.md +358 -0
- package/skills-bundle/guancli/references/preview-and-output.md +192 -0
- package/skills-bundle/guancli/references/resource-query.md +101 -0
- package/skills-bundle/guands/SKILL.md +281 -0
- package/skills-bundle/guands/references/calc-fields-boundaries-and-pitfalls.md +160 -0
- package/skills-bundle/guands/references/command-reference.md +267 -0
- package/skills-bundle/guands/references/incremental-and-schedule.md +157 -0
- package/skills-bundle/guands/references/workflows.md +256 -0
- package/skills-bundle/guanetl/SKILL.md +391 -0
- package/skills-bundle/guanetl/evals/evals.json +41 -0
- package/skills-bundle/guanetl/references/ETL_AI_DEVELOP.md +456 -0
- package/skills-bundle/guanmetric/SKILL.md +144 -0
- package/skills-bundle/guanmetric/evals/evals.json +117 -0
- package/skills-bundle/guanmetric/evals/fixtures/atomic-detail-read-model.json +18 -0
- package/skills-bundle/guanmetric/evals/fixtures/confirmed-template-summary.json +12 -0
- package/skills-bundle/guanmetric/evals/fixtures/create-result-unknown-state.json +13 -0
- package/skills-bundle/guanmetric/evals/forward-eval-2026-09-21.json +62 -0
- package/skills-bundle/guanmetric/references/metric-api-contract-examples.json +690 -0
- package/skills-bundle/guanmetric/references/metric-api-contract.schema.json +349 -0
- package/skills-bundle/guanmetric/references/metric-api-contracts.md +436 -0
- package/skills-bundle/guanmetric/references/metric-atomic-mutation.md +238 -0
- package/skills-bundle/guanmetric/references/metric-batch-status.md +71 -0
- package/skills-bundle/guanmetric/references/metric-business-dictionary-api-contract-examples.json +53 -0
- package/skills-bundle/guanmetric/references/metric-business-dictionary-api-contract.schema.json +26 -0
- package/skills-bundle/guanmetric/references/metric-business-dictionary.md +76 -0
- package/skills-bundle/guanmetric/references/metric-common-fields.md +246 -0
- package/skills-bundle/guanmetric/references/metric-composite-mutation.md +165 -0
- package/skills-bundle/guanmetric/references/metric-delete-mutation.md +70 -0
- package/skills-bundle/guanmetric/references/metric-derived-mutation.md +453 -0
- package/skills-bundle/guanmetric/references/metric-excel-template.md +365 -0
- package/skills-bundle/guanmetric/references/metric-expression-rules.md +146 -0
- package/skills-bundle/guanmetric/references/metric-flow-generate-example.json +79 -0
- package/skills-bundle/guanmetric/references/metric-flow-generate.schema.json +93 -0
- package/skills-bundle/guanmetric/references/metric-flow.md +218 -0
- package/skills-bundle/guanmetric/references/metric-hierarchy-api-contract-examples.json +171 -0
- package/skills-bundle/guanmetric/references/metric-hierarchy-api-contract.schema.json +167 -0
- package/skills-bundle/guanmetric/references/metric-hierarchy-api-contracts.md +193 -0
- package/skills-bundle/guanmetric/references/metric-mutation.md +155 -0
- package/skills-bundle/guanmetric/references/metric-public-dimension-api-contract-examples.json +62 -0
- package/skills-bundle/guanmetric/references/metric-public-dimension-api-contract.schema.json +47 -0
- package/skills-bundle/guanmetric/references/metric-public-dimension.md +155 -0
- package/skills-bundle/guanmetric/references/metric-tree-api-contract-examples.json +277 -0
- package/skills-bundle/guanmetric/references/metric-tree-api-contract.schema.json +263 -0
- package/skills-bundle/guanmetric/references/metric-tree-api-contracts.md +53 -0
- package/skills-bundle/guanmetric/references/metric-tree-mutation.md +500 -0
- package/skills-bundle/guanmetric/references/metric-validation-ownership.md +74 -0
- package/skills-bundle/guanvis/SKILL.md +333 -0
- package/skills-bundle/guanvis/evals/china_map/card_01_basic_map.js +13 -0
- package/skills-bundle/guanvis/evals/china_map/card_02_world_map.js +10 -0
- package/skills-bundle/guanvis/evals/china_map/card_03_point_map.js +12 -0
- package/skills-bundle/guanvis/evals/china_map/page.js +10 -0
- package/skills-bundle/guanvis/evals/china_map/schema.js +10 -0
- package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/README.md +30 -0
- package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/card_01_comparative_mvp.js +72 -0
- package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/page.js +6 -0
- package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/schema.js +22 -0
- package/skills-bundle/guanvis/evals/comparative_mvp_roundtrip/verify_default_roundtrip.sh +92 -0
- package/skills-bundle/guanvis/evals/complex_report_pro/card_01_monthly.js +63 -0
- package/skills-bundle/guanvis/evals/complex_report_pro/page.js +6 -0
- package/skills-bundle/guanvis/evals/complex_report_pro/schema.js +6 -0
- package/skills-bundle/guanvis/evals/custom_chart_echarts/card_01_bar.js +13 -0
- package/skills-bundle/guanvis/evals/custom_chart_echarts/card_02_pie.js +13 -0
- package/skills-bundle/guanvis/evals/custom_chart_echarts/charts/bar.js +11 -0
- package/skills-bundle/guanvis/evals/custom_chart_echarts/charts/pie.js +15 -0
- package/skills-bundle/guanvis/evals/custom_chart_echarts/page.js +5 -0
- package/skills-bundle/guanvis/evals/custom_chart_echarts/schema.js +9 -0
- package/skills-bundle/guanvis/evals/custom_chart_sdk/card_01_level_nodes.js +19 -0
- package/skills-bundle/guanvis/evals/custom_chart_sdk/charts/level_nodes.css +51 -0
- package/skills-bundle/guanvis/evals/custom_chart_sdk/charts/level_nodes.html +1 -0
- package/skills-bundle/guanvis/evals/custom_chart_sdk/charts/level_nodes.js +28 -0
- package/skills-bundle/guanvis/evals/custom_chart_sdk/page.js +5 -0
- package/skills-bundle/guanvis/evals/custom_chart_sdk/schema.js +7 -0
- package/skills-bundle/guanvis/evals/dynamic_fields/card_01_dynamic_dataset.js +20 -0
- package/skills-bundle/guanvis/evals/dynamic_fields/card_02_dynamic_metric_chart.js +16 -0
- package/skills-bundle/guanvis/evals/dynamic_fields/metrics.js +19 -0
- package/skills-bundle/guanvis/evals/dynamic_fields/page.js +9 -0
- package/skills-bundle/guanvis/evals/dynamic_fields/schema.js +7 -0
- package/skills-bundle/guanvis/evals/dynamic_fields/verify_default_roundtrip.sh +137 -0
- package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/README.md +26 -0
- package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/card_01_percentage_advcalc.js +44 -0
- package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/card_02_scroll_percentage.js +12 -0
- package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/page.js +6 -0
- package/skills-bundle/guanvis/evals/percentage_advcalc_roundtrip/schema.js +22 -0
- package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/README.md +28 -0
- package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/card_01_rank_advcalc.js +59 -0
- package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/page.js +6 -0
- package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/schema.js +22 -0
- package/skills-bundle/guanvis/evals/rank_advcalc_roundtrip/verify_default_roundtrip.sh +135 -0
- package/skills-bundle/guanvis/evals/running_total_advcalc_roundtrip/README.md +15 -0
- package/skills-bundle/guanvis/evals/running_total_advcalc_roundtrip/card_01_running_total_advcalc.js +74 -0
- package/skills-bundle/guanvis/evals/running_total_advcalc_roundtrip/page.js +6 -0
- package/skills-bundle/guanvis/evals/running_total_advcalc_roundtrip/schema.js +22 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/card_01_revenue_column.js +10 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/card_02_trend_line.js +9 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/card_03_kpi.js +6 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/card_04_pie.js +9 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/card_05_calc_field_test.js +12 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/page.js +11 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/schema.js +14 -0
- package/skills-bundle/guanvis/evals/sales_dashboard/selector_01_region.js +10 -0
- package/skills-bundle/guanvis/evals/split_charts/card_01_column_split.js +10 -0
- package/skills-bundle/guanvis/evals/split_charts/card_02_line_split.js +10 -0
- package/skills-bundle/guanvis/evals/split_charts/card_03_combo_split.js +11 -0
- package/skills-bundle/guanvis/evals/split_charts/page.js +10 -0
- package/skills-bundle/guanvis/evals/split_charts/schema.js +14 -0
- package/skills-bundle/guanvis/evals/tab_layout/card_00_total_revenue.js +6 -0
- package/skills-bundle/guanvis/evals/tab_layout/card_01_revenue.js +10 -0
- package/skills-bundle/guanvis/evals/tab_layout/card_02_trend.js +9 -0
- package/skills-bundle/guanvis/evals/tab_layout/card_03_story.js +11 -0
- package/skills-bundle/guanvis/evals/tab_layout/page.js +23 -0
- package/skills-bundle/guanvis/evals/tab_layout/schema.js +11 -0
- package/skills-bundle/guanvis/evals/tab_layout/selector_01_region.js +8 -0
- package/skills-bundle/guanvis/references/api-reference.md +476 -0
- package/skills-bundle/guanvis/references/builder-reference.md +1676 -0
- package/skills-bundle/guanvis/references/chart-properties.md +2101 -0
- package/skills-bundle/guanvis/references/checkout-editing.md +53 -0
- package/skills-bundle/guanvis/references/complex-report-pro-patterns.md +398 -0
- package/skills-bundle/guanvis/references/dir-and-page-management.md +48 -0
- package/skills-bundle/guanvis/references/metric-chart-reference.md +258 -0
- package/skills-bundle/guanvis/references/publish-and-constraints.md +60 -0
- package/skills-bundle/guanvis/references/selector-reference.md +431 -0
- package/skills-bundle/guanvis/references/tableau-migration.md +73 -0
- package/skills-bundle/guanvis/references/theme.md +123 -0
- package/skills-bundle/guanvis/references/troubleshooting.md +25 -0
- package/skills-bundle/guanvis/references/validation-and-chart-patterns.md +205 -0
- package/skills-bundle/guanwf/SKILL.md +543 -0
- package/skills-bundle/guanwf/references/ETL_AI_DEVELOP.md +456 -0
- package/skills-bundle/guanwf/references/TASK_NODE_CONTRACTS.md +64 -0
- package/skills-bundle/guanwf/references/WORKFLOW_DSL.md +536 -0
- package/skills-bundle/guanwf/references/WORKFLOW_NODES.md +166 -0
- package/skills-bundle/js/SKILL.md +145 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: guanvis
|
|
3
|
+
description: 当用户要新建、修改、组装观远 BI / Guandata 的 Card(图表/报表卡片)、复杂报表 Pro(COMPLEX_REPORT_PRO)、用指标平台指标创建的指标卡片、文本卡片、图片卡片、筛选器(selector,含日历/时间宏/区间/离散值)或仪表板(Page),或给出 Card ID、数据集 ID、指标 ID、card.js/page.js、图表类型关键词(柱状/折线/饼/KPI/表格/漏斗/地图/散点等 30+ 种)时,优先使用这个 skill。即使用户只说"做个销售仪表板""创建一个复杂报表 Pro""用这个指标做张卡片""加个 KPI 卡片""新建一个区域筛选器联动所有图""帮我改一下这个图的图例""把这几个 card 拼成一个 page""加一个本月/近 7 天的快捷日期筛选",也要主动使用。它通过 AI 编写简洁的 JS 脚本(card_*.js / selector_*.js / page.js)定义卡片、筛选器和页面布局,再 pack/publish 上传到目标 BI。认证复用 guancli 共享配置。页面目录(PAGE 目录树)的创建/改名/移动/删除也在这个 skill(`guanvis dir`),用户说"给看板建个目录""把这个页面目录改个名"时触发。页面本身的删除/改名/移动同样在这个 skill(`guanvis page delete/rename/move`),用户说"删掉这个页面""把这个页面挪到 XX 目录""给这个看板改个名"时触发。只想查现有 Card/Page 内容或目录树走 guancli。旧版复杂报表不支持创建或编辑。
|
|
4
|
+
compatibility: "Requires Node.js 14+. Install via npm link --foreground-scripts (local) or npm install -g --foreground-scripts @guandata/guanvis (from internal Nexus registry) so the AI skill refresh result is visible. CLI command: guanvis."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# guanvis
|
|
8
|
+
|
|
9
|
+
执行型 skill:通过 AI 编写的 JS 脚本创建/修改 BI Card 和 Page 资源。
|
|
10
|
+
|
|
11
|
+
AI 生成 `card_*.js` 定义 Card、`page.js` 组装仪表板(`schema.js`/`metrics.js` 是生成的事实快照,见下);框架在 preview/pack/publish 时内置验证(字段数量、zone 兼容性、必填字段等),认证复用 `guancli` 共享配置。
|
|
12
|
+
|
|
13
|
+
## Harness 化工作法
|
|
14
|
+
|
|
15
|
+
把可视化生成当作源文件驱动的构建流程:本地 JS DSL 是可编辑事实源,payload、ZIP、线上 Card/Page 都是从源文件生成的派生产物。
|
|
16
|
+
|
|
17
|
+
- `schema.js` 是由 `init` / `checkout` 生成的数据集事实快照,不手改;数据集字段变化时重新运行对应命令。`metrics.js` 是由 `metric-init` 生成的指标事实快照,不手改;指标口径、适用维度或格式变化时重新运行 `metric-init`。
|
|
18
|
+
- `theme-colors.js` 是项目级图表主题色事实快照,不手改。准备在脚本中使用 `setThemeColor()` 前,先检查项目根目录;不存在时先运行 `guanvis theme-color sync -d <project>`。调用 `setThemeColor()` 切换主题时必须从快照选择真实 `tcId`,不得猜测或编造。已有文件直接复用,主题色列表变化或切换 BI 环境时用 `theme-color sync` 刷新;快照会记录实际选中的 profile、服务地址和 domain,通过环境变量或默认 profile 切换环境后,构建都会拒绝复用旧快照。`preview`/`diff`/`pack`/`publish` 对缺失快照的自动生成只作兜底。
|
|
19
|
+
- 全局参数先用 `guanvis parameter` 创建或复用,再通过 `dynamic-parameters.js` 按 `dpId` 引用;`pack`/`publish` 不会隐式写入参数。创建前必须按名称查询;发现同名有效参数时立即停止,让用户明确选择"更新已有参数"或"换名创建",不得自动复用或修改。
|
|
20
|
+
- `card_*.js`、`selector_*.js`、`page.js` 是可编辑源文件;`*_package.zip`、`.preview.json`(preview 落盘的全量 payload)、publish 后线上资源都是派生产物,不要手工编辑。
|
|
21
|
+
- **Page 归属红线**:包含 Card/Selector 的资源包必须同时包含 Page,且每个 Card/Selector 都必须被至少一个 Page 引用;否则后端会产生 `pg_id` 为空、无法访问且可能阻塞后续发布的孤儿卡片。校验失败时在 `page.js` 中放置对应资源后同包发布。页面"卡片池"里的卡(checkout 回写为 `page.addSpareCard(cardId)`)归属本页但默认不展示,编辑时原样保留,不要删掉或改成放置。
|
|
22
|
+
- 已有线上仪表板用 `guanvis checkout <pgId> -d <dir>` 拉成可编辑工程(attachCard 基线、自定义图表 `charts/` 反编译、Pro 模板 `templates/`、Page 布局脚本)。checkout 工程只用于修改指定 Page,不用于复制新 Page;只支持普通仪表板(pgType=PAGE),DSL 不能安全表达的结构会直接失败而不是清结构。**checkout 工程动手前先读 `references/checkout-editing.md`**。
|
|
23
|
+
- **Checkout 账号红线**:checkout 读到的是"当前账号视角",publish 整体回写。必须用对涉及数据集有**完整列权限、无脱敏限制**的账号(推荐 owner 或管理员)执行 checkout/publish,否则被裁剪的字段会在回写后从线上卡片永久丢失;多语言租户操作账号语言须与卡片原始语言一致。
|
|
24
|
+
- **Checkout JSON 红线**:`.guanvis/raw/**`、`.guanvis/base/**`、`.guanvis/manifest.json` 是只读快照。Agent 不得修改这些 JSON,也不得复制 checkout JSON 改副本创建新资源;现有卡片修改必须通过 `attachCard(...)` 的 DSL 操作表达(优先 `update*/patch*/add*/remove*/move*`,整 zone 重建的 `set*/clear*` 会触发 warning),新增卡片必须用 `createCard()` / `createSelector()` 工厂函数;操作清单见 `references/checkout-editing.md` §3。
|
|
25
|
+
- Card/Page 描述也是 JS 源文件的一部分:新建资源未设置非空业务描述时,payload 描述使用 `[guanvis:created]` 标记创建来源,Page 不会因此打开描述展示;调用 `.setDescription(...)` 设置非空业务描述后只保留业务描述,不追加标记。attach/checkout 已有资源不补标记。新建看板或改版时,在 `card_*.js` / `page.js` 中写 `.setDescription(...)`,再通过 `preview`/`pack`/`publish` 从 JS 源文件生成并发布资源。
|
|
26
|
+
- 写脚本前先形成 dashboard contract:目标用户、业务问题、使用的数据集、核心指标、维度拆解、筛选器、页面结构和验证方式。
|
|
27
|
+
- 每次生成都针对明确目录或明确子目录;不要把 unrelated 示例、旧包或临时 ZIP 混入同一个发布目标。
|
|
28
|
+
- Card/Page/Selector 的 `.setId(...)` 必须用 `guanvis genid` 生成(保证字母开头);数字开头 ID 会触发 BI 前端 CSS selector 语法错误,新建资源校验直接报 error 拦截(checkout/attach 的已有资源保留原 ID 不受限)。
|
|
29
|
+
- 先 `preview` 做本地结构验证,再 `publish`(publish 自带构建打包上传,**发布前不需要单独 `pack`**;`pack` 只用于生成离线 ZIP 走 `upload`)。仅修复描述用 `card/page set-description` 并同步 JS 中的 `.setDescription(...)`;改看板内容按「线上仪表板更新红线」处理。
|
|
30
|
+
- **编辑红线(编辑 ≠ 删除重建)**:修改/改名已发布 Page 或 Card 必须保留原 pgId/cdId 原地覆盖发布。本地源工程还在且线上未被网页端改动 → 直接改本地 JS 同 ID 重新 publish;否则 → `checkout` 后编辑,且**不得**把 `attachCard` 改写成 `createCard()`(绕过 base JSON 会丢线上配置)。**禁止**用"新建 + 删除旧的"模拟编辑——资源 ID 变化会让收藏、分享、订阅、门户引用和页面权限全部失效且无法迁移;"保留旧页面出新版本"用 `guanvis page save-as`。全局参数同理只能 `parameter update <dpId>` 原地更新,禁止 delete 后重建同名参数(dpId 断链)。**页面壳与页面目录**的改名/换位置已有原地命令(`guanvis page rename/move`、`guanvis dir rename/move`,保留原 ID、可逆、不需要 `--yes`),一律用它们,**禁止**"删掉重发页面 / 新建目录搬内容删旧目录"模拟改名挪位。各资源的原地更新入口见下方「编辑红线速查」。分流决策见 `references/checkout-editing.md` §4。
|
|
31
|
+
- **资源包安全红线**:Agent 只编辑 DSL 源文件;资源包 ZIP 是 `guanvis pack/publish` 的派生产物,不手工生成、解包修改或重打包。`guanvis upload` 只允许上传 `guanvis pack` 原样生成的 ZIP。若用户要求批量重绑资源、迁移已有页面或复用线上页面结构,先停下来说明风险并确认方案,不要直接改 ZIP。
|
|
32
|
+
- 发布后优先用 `guancli page get/card get` 回读结构与配置;`guanvis screenshot` 仅在明确需要视觉质量判断且模型支持图像理解时使用(额外消耗 token),不作默认闭环步骤。**例外**:自定义图表的视觉验收按速查第 24 条执行。
|
|
33
|
+
|
|
34
|
+
### 编辑红线速查
|
|
35
|
+
|
|
36
|
+
| 资源 | 编辑用什么 | 删除重建会丢什么 |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| 页面 Page | 内容改本地 JS 后同 pgId 重新 `publish`(线上被网页端改过则先 `checkout`);只改描述用 `guanvis page set-description`;要保留旧版另出新版用 `guanvis page save-as`;页面本身的改名/换目录/删除用 `guanvis page rename/move/delete` | pgId 变化,收藏、分享、订阅、门户与 SuperApp 引用、页面权限全部断链且无法迁移 |
|
|
39
|
+
| 卡片 Card | `checkout` 后 `attachCard(cdId, jsonPath)` 链式操作(不得改写成 `createCard()`);只改描述用 `guanvis card set-description` | cdId 变化,`/page/<pgId>?anchor=<cdId>` 锚点链接、卡片级订阅与下游引用断链;网页端做过的线上配置丢失 |
|
|
40
|
+
| 全局参数 Dynamic Parameter | `guanvis parameter update <dpId>` 原地更新 | dpId 变化,引用该参数的卡片与筛选器断链 |
|
|
41
|
+
| 页面目录 Dir | 改名用 `guanvis dir rename <dirId> --name`;换位置用 `guanvis dir move <dirId> --parent <新父目录 dirId>` | 目录 ID 变化,需逐个把页面和子目录搬到新目录,目录权限配置丢失;且目录删除是**物理删除、不进回收站**,删错无从恢复 |
|
|
42
|
+
|
|
43
|
+
## AI Quick Reference(速查,详细说明见按需参考资料)
|
|
44
|
+
|
|
45
|
+
**Checkout/attachCard 速记**:`attachCard(cardId, jsonPath)` 是"base JSON + 链式 DSL 操作 = 目标 JSON",不修改 base JSON,重复执行产出相同 payload。zone 修改优先 `update*/patch*/add*/remove*/move*`(整 zone 重建的 `set*/clear*` 会触发 warning);已有且在能力矩阵中标记为可编辑的 selector 用 `.setSelectorSetting()` 修改配置,树状筛选器用专属 `.setTreeSetting()` 修改层级字段配置,层级树状筛选器用 `.setLayerTreeSetting()` 修改多选、清空与默认路径,组合条件筛选器用 `.setCombinationSetting()` 修改清空、展示和默认条件(不重新绑定候选字段),`cdType=SELECTOR` 的筛选器用 `.addLink()/.removeLink()/.clearLinks()` 修改联动,禁止借配置入口改变 selector 类型或重新绑定字段;已有 `PARAMETER` selector 例外,允许用 `.bindParameter()` 原地更新参数配置。自定义筛选器等未提供专用 DSL 的类型只能保留已有专属配置。自定义图表内容编辑仅限 SDK/ECHARTS_LITE(编辑 `charts/` 下反编译源文件),COMPLEX_REPORT/PLUGIN/PLUGIN_LITE/REPORT_FORM 调内容编辑 API 直接报错。发布前用 `guanvis diff <dir>` 或 preview 的 `changeSummary` 查看影响面;没有 DSL 操作覆盖的需求应报告暂不支持,不改 `.guanvis` JSON。完整操作语义(zone/筛选区/筛选栏画布互移等)见 `references/checkout-editing.md` §3。
|
|
46
|
+
|
|
47
|
+
**字段显示名与 Card 标题**:`createCard()` 第二参数是 Card 标题,与字段显示名独立。图例/轴标题/表头/Tooltip/指标标签都用字段显示名,需要与物理字段名或 calcField 内部名分开时设置 `alias`(如 `f("营收", { alias: "本月营收" })`);`SINGLE_VALUE`/`KPI_CARD`/`KPI_TREND` 和仪表盘/进度类尤其明显。
|
|
48
|
+
|
|
49
|
+
**图表属性配置**:设置图表属性时,先读 `references/chart-properties.md`,按其中的方法和参数配置。
|
|
50
|
+
|
|
51
|
+
1. **工厂函数**:数据集图表 `createCard()`;复杂报表 Pro `createComplexReportPro()` + `createReportWorkbook()`;已有线上普通卡片 `attachCard(cardId, jsonPath)`;指标卡片 `createMetricChart()`;筛选器/文本/图片/杜邦/Tab/页面用对应工厂函数,不要 `new XxxBuilder()`。旧版复杂报表拒绝,Pro 父卡不能用泛化 `attachCard()`
|
|
52
|
+
2. **注册函数**:`registerCard` / `registerComplexReportPro` / `registerMetricChart` / `registerSelector` / `registerTextCard` / `registerImageCard` / `registerCustomChart` / `registerDuPontChart` / `registerPage`,入参一律 `xxx.build()`;注册函数与工厂函数必须配对(如 `createCustomChart` 只能 `registerCustomChart`),错配会在 preview 时直接报错并提示正确函数
|
|
53
|
+
3. **字段引用**:单数据集用 `f("字段名")`,多数据集用 `field(DS, "字段名")`
|
|
54
|
+
4. **zone maxCount**:`BASIC_COLUMN/BAR/LINE` metric=1;`GROUPED_*/STACKED_*` metric=∞;`KPI_CARD` metric=1;组合图 `*_WITH_LINE` row=1
|
|
55
|
+
5. **column vs colorBy**:column 放维度(按类别分组着色),colorBy 放度量(按值渐变着色)
|
|
56
|
+
6. **原生聚合优先**:单字段聚合用 `f("字段", { aggrType: AggrType.XXX })`(SUM/AVG/COUNT/COUNT_DISTINCT/MIN/MAX),不要用 `calcField()` 手写 SQL 聚合函数(如 `COUNT_DISTINCT([字段])`)
|
|
57
|
+
7. **calcField 命名**:不能与数据集物理字段同名,否则 BI 默认取数据集字段
|
|
58
|
+
8. **calcField 类型**:`aggregation`(默认)公式必须含聚合函数;纯算术用 `{ calculationType: "normal" }`;窗口函数用 `{ calculationType: "window" }`
|
|
59
|
+
9. **明细/滚动表 calcField**:`DETAIL_TABLE`/`SCROLL_TABLE` 只逐行展示,行级计算必须 `{ calculationType: "normal" }` 且禁用聚合/窗口函数;汇总需求改用非明细图表或 ETL 预计算
|
|
60
|
+
10. **筛选器/联动/下钻**:新建筛选器和能力矩阵中标记可编辑的已有 selector 优先用 `.setSelectorSetting()` 配置;新建筛选器联动图表必须 `.linkToAll()` 或 `.linkTo(cardIndex)`,已有 `cdType=SELECTOR` 筛选器用 `attachCard(...).addLink()/.removeLink()/.clearLinks()` 修改联动;筛选器级联用 `.linkToSelector(selectorId, targetFieldName?)`;完整能力边界和配置规则见 `references/selector-reference.md`。卡片联动卡片用 `card.linkTo(layoutCardIndex, { fields: [{ source, target }] })`;固定路径下钻用 `registerDrillPath(parentCardIndex, [child.build()], { position: DrillPathPosition.BOTTOM })`
|
|
61
|
+
11. **selector 类型**:离散值 → `DS_ELEMENTS`(默认);文本条件 → `TEXT_MATCH`(默认操作符 `CONTAINS`);连续数值 → `SelectorType.DS_INTERVAL`;日期 → `CALENDAR`;快捷日期区间(本月/近7天等)→ `.setSelectorSetting({ type: SelectorType.TIME_MACRO, timeMacro: { options, defaultName } })`(旧 `.setTimeMacroOptions()` 仅保留兼容);树状筛选器 → `SelectorType.TREE` + `.bindTreeFields(...)` + `.setTreeSetting(...)`;层级树状筛选器 → `SelectorType.LAYER_TREE` + `.bindLayerTreeField(...)` + `.setLayerTreeSetting(...)`(字段必须有 `layerTreeId`);组合条件 → `SelectorType.COMBINATION` + `.bindCombinationFields(...)` + `.setCombinationSetting(...)`;全局参数 → `.bindParameter(...)`(自动设置为 `PARAMETER`)
|
|
62
|
+
12. **同环比默认**:未指定输出值时默认增长率;未指定模式时默认 `ComparativeMode.FILTER_BASED`(普通模式需显式 `NORMAL`)。日期字段已是预聚合周期字段(如 `月开始日期`)时必须声明 `{ granularity: Granularity.NONE }`,避免按 DAY 筛选窗口计算为空
|
|
63
|
+
13. **placeCard 入参**:优先用 card/selector ID 字符串(checkout 工程与子目录工程必须用),如 `placeCard("cardId", x, y, w, h)`。数字 index 仅限新建工程,按可布局资源(registerCard/MetricChart/TextCard/ImageCard/CustomChart/DuPontChart)的注册顺序累加,文件按文件名排序加载;**registerSelector 不参与 card index 计数**——selector 进画布/布局组件一律用其 ID 字符串。
|
|
64
|
+
14. **publish 认证**:由底层 CLI 负责——普通 guancli profile 用 `GUANCLI_PROFILE=<profile> guancli auth status` 验证,发布时继续使用同一 `GUANCLI_PROFILE`,仅用户明确要求切换机器级默认环境时才用 `auth use`;上游托管 OIDC Token 时在当前进程同时设置 `GUANCLI_OIDC_BASE_URL`/`GUANCLI_OIDC_ACCESS_TOKEN`,无需本地 profile;guancli-lite 使用 `GUANCLI_BASE_URL`/`GUANCLI_TOKEN`
|
|
65
|
+
15. **更新线上仪表板**:checkout 工程 = 修改指定线上 Page,保留原资源 ID;同 ID 覆盖必须先经用户确认才可加 `--allow-overwrite`,"保留原页面出新版本"用 `guanvis page save-as <pgId> --suffix _guanvis`;完整红线见下文「线上仪表板更新红线」与 `references/checkout-editing.md` §5
|
|
66
|
+
16. **描述维护**:仅修复已发布资源描述时保留原 ID,用 `guanvis card/page set-description`;本地有 JS 工程时同步更新 `.setDescription(...)`
|
|
67
|
+
17. **主题切换**:用户描述风格 → 工程目录里 `guanvis theme preference --keywords "..." --sync`;不要选租户默认"浅色"/"深色",没有合适主题就保持/清空偏好用内置"简约"兜底;改版未提风格时普通工程由 `.applied.json` 继承上次主题,checkout 工程按 Page base 保留线上主题。多子目录工程主题按子目录独立配置和执行;详见 `references/theme.md`
|
|
68
|
+
18. **设计规则**:preview/pack/publish 自动应用内置设计规则;自定义时在工程目录新建 `design-rule.json`,不手改 `themes/<themeId>.json`;详见 `references/theme.md`
|
|
69
|
+
19. **"指标卡片"语义分流**:数据集字段做单值/KPI → `SINGLE_VALUE` / `KPI_CARD`;用指标平台已有指标建卡 → 先 `guanvis metric-init <metricId>` 再 `createMetricChart()` + `metric()`/`metricDim()`;复杂指标卡片参数先读 `references/metric-chart-reference.md`
|
|
70
|
+
20. **杜邦分析图**:用 `createDuPontChart()` 创建 `LAYOUT` 卡片(非普通 ChartType),节点放 `KPI_CARD` 子卡并用 `.setRoot()`/`.addChild()` 组织树;页面只放杜邦父卡片,筛选器 `linkToAll()` 会覆盖杜邦子卡片
|
|
71
|
+
21. **布局组件**:AreaTitle/CardGroup/SelGroup/Tab 只支持放画布根布局、不支持嵌套组合;SelGroup 内只能放 selector;详见 `references/builder-reference.md`
|
|
72
|
+
22. **资源包/checkout JSON 禁止手改**:只改 DSL 源文件,不改 ZIP 内部文件与 `.guanvis/**` JSON;批量重绑、迁移页面等需求先讨论方案,必要时扩展 DSL,不手工改生成物。
|
|
73
|
+
23. **动态字段**:用户明确需要字段切换时用 `.addDynamicRow()` / `.addDynamicMetric()` 等(普通卡动态维度/数值,指标卡动态维度/指标);细节见 `references/builder-reference.md`。
|
|
74
|
+
24. **自定义图表(HTML/CSS/JS 自绘)**:内置图表满足不了的可视化才走 `createCustomChart()`。子类型选型:纯 ECharts 配置能画 → `CustomChartSubType.ECHARTS_LITE`(脚本给 `option` 赋值,禁用 `GDPlugin`);需要自定义 DOM/CSS 布局或第三方库(节点图、进度轴、Vega 等)→ `CustomChartSubType.SDK`(`charts/<name>.{html,css,js}` 三件套 + `loadContent("charts/<name>")`,js 里实现 `renderChart(data, clickFunc, config)` 并 `new GDPlugin().init(renderChart)`)。数据用 `.addDataView(createCard(ChartType.DATA_GRID, ...))` 传入;`DATA_GRID` 只承载数据,不应用页面主题,pack/publish 会删除其 `settings` 中的 `bgSettings`、`backgroundColor`、`showTitle`、`style`、`titleSetting`,checkout 工程回写时也会清理既有值。最小可运行工程直接抄 `evals/custom_chart_sdk/`(SDK)或 `evals/custom_chart_echarts/`(ECHARTS_LITE)。**布局写法**:对齐/等比类要求用结构性保证而非数值手调——固定尺寸容器 + flex 居中让几何天然成立,关键坐标(如贯穿线端点)在渲染 JS 里 `getBoundingClientRect()` 实测反写并挂 resize 重算;手调 top/margin 意味着每发布一次才能验一次。**视觉验收**:preview 只校验结构不渲染 HTML/CSS,本地 file:// 打开也不可靠——正确闭环是发布(可先发到测试目录)后 `guanvis screenshot <pgId>` 读图确认(这是总则"screenshot 不作默认闭环"的例外:自定义图表视觉由手写 HTML/CSS 决定,结构回读覆盖不到);读图判断即可,不要解析 PNG 像素做几何量化,也不要为验收安装图像处理依赖;模型不支持图像理解时,改为把 publish 成功后输出的 `Page URL` 交给用户人工确认。不要浪费时间做本地渲染验证。完整 API 见 `references/builder-reference.md` 的 CustomChartBuilder 章节。
|
|
75
|
+
25. **复杂报表 Pro**:非默认功能,需单独授权——只有用户明确点名"复杂报表 / 复杂报表 Pro"或被修改卡片已是 Pro 才选 Pro;用户只说"表格/报表/透视表"一律用原生卡片(DATA_GRID/PIVOT_TABLE 等),版式做不到时告知"Pro 可实现但需授权"由用户决定。动手前必读 `references/complex-report-pro-patterns.md`(§0 选型、§2 配方、§3 数据视图规则、§4 报错修复、§5 编辑闭环、§6 验证闭环),全部结构红线与修复表以该文件为准;工作流程见下文「复杂报表 Pro 工作方式」
|
|
76
|
+
|
|
77
|
+
## 何时使用
|
|
78
|
+
|
|
79
|
+
- 新建观远 BI Card(柱形/折线/饼/表格/KPI/散点/漏斗/地图等 30+ 种)、文本卡片、图片卡片。
|
|
80
|
+
- 基于指标平台已有指标创建指标卡片(MetricChart,后端 `cdType=13`)。
|
|
81
|
+
- 创建或 checkout/edit 复杂报表 Pro——**仅当用户明确点名"复杂报表 / 复杂报表 Pro"或被修改卡片已是 Pro**(需单独授权;泛化"做个表格/报表"用原生卡片);旧版复杂报表明确拒绝并建议外部迁移后新建 Pro。
|
|
82
|
+
- 创建筛选器并配置联动;组装 Card 和筛选器为仪表板/Page(grid layout + 筛选器面板)。
|
|
83
|
+
- 页面目录(`guanvis dir`)与页面壳(`guanvis page rename/move/delete`)的创建、改名、移动、删除;红线见下方「页面目录与页面壳管理」。
|
|
84
|
+
- 用户提到 `card.js`、`page.js`、CardPayload、图表类型、zone spec、筛选器联动。
|
|
85
|
+
|
|
86
|
+
## 固定工作方式
|
|
87
|
+
|
|
88
|
+
### 1. 确认前置条件
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
guancli auth status
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
- 如果用户指定的资源(数据集、仪表板等)搜索不到,先用 `guancli auth list` 列出所有可用环境,提示用户确认是否需要切换 profile,而不要在当前 profile 上反复重试。
|
|
95
|
+
|
|
96
|
+
### 2. 生成 schema.js(只做一次或数据集变更时重新生成)
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
guancli ds search <关键词> # 查找数据集 ID
|
|
100
|
+
guancli ds preview <dsId> # 先看几行真实数据再动笔:确认量纲与格式(如"比例"是 0~1 小数还是百分数)
|
|
101
|
+
guanvis init <dsId1> <dsId2> -d ./my_dashboard/ # 生成 schema.js(多数据集加 --alias 命名全局变量)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
用户给的是业务目录名时,先 `guancli ds tree` 定位目录再按真实数据集名搜索,不要把目录名当数据集名反复 `ds search`。生成的 `schema.js` 是 `defineDataset(dsId, [{ fdId, name, fdType, metaType }...])` 形态的事实快照,不可编辑。
|
|
105
|
+
|
|
106
|
+
### 2b. 生成 metrics.js(创建指标平台指标卡片时)
|
|
107
|
+
|
|
108
|
+
用户给的是指标平台 metric ID/指标名时走这条链路,不要把指标当数据集字段:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
guancli metric search '<关键词>' # 用户只给名称时先查 ID
|
|
112
|
+
guanvis metric-init <metricId1> <metricId2> -d ./my_dashboard/
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
```javascript
|
|
116
|
+
var card = createMetricChart(ChartType.PIVOT_TABLE, "销售指标分析")
|
|
117
|
+
.setId("cardId24chars")
|
|
118
|
+
.addRow(metricDim("销售额", "区域"))
|
|
119
|
+
.addMetric(metric("销售额"));
|
|
120
|
+
registerMetricChart(card.build());
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
目录模式自动按「文件结构约定」的顺序加载:`metrics.js` 等快照文件先于 `card_*.js` 执行。
|
|
124
|
+
|
|
125
|
+
### 3. 设置仪表板主题(按需)
|
|
126
|
+
|
|
127
|
+
如果用户**明确提到了视觉风格**("深色科技风"、"蓝色简约"、"科技蓝T004" 或具体 themeId 等),在编写 card/page 之前把意图落到 `.preference.json`:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
cd ./my_dashboard
|
|
131
|
+
guanvis theme preference --keywords "深色 科技" --sync # (a) 用户描述了风格关键词
|
|
132
|
+
guanvis theme preference --theme-id custom_blue --sync # (b) 用户给出明确 themeId
|
|
133
|
+
guanvis theme sync && guanvis theme list # (c) 先看候选名字再决定
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
何时跳过:改版已有看板(`.applied.json` 自动继承上次主题)、新看板但用户没描述风格(自动落到内置 `simple.json`)、候选只剩默认"浅色"/"深色"或都不贴合(不要随便选,清空/不写偏好用内置"简约"兜底)。多子目录工程的主题各子目录独立配置和执行。完整决策规则、`themes/` 目录文件说明、离线 vs 联网约定、排错见 `references/theme.md`。
|
|
137
|
+
|
|
138
|
+
### 4. 编写 card 脚本
|
|
139
|
+
|
|
140
|
+
card 脚本用 `field(DS, "字段")` 或单数据集简写 `f("字段")` 从 schema 引用字段(无需记忆 fdId):
|
|
141
|
+
|
|
142
|
+
```javascript
|
|
143
|
+
// card_01_revenue.js
|
|
144
|
+
var card = createCard(ChartType.GROUPED_COLUMN, "营收分析")
|
|
145
|
+
.bindDataset(DS)
|
|
146
|
+
.setDescription("业务故事:回答各区域营收规模与产品结构差异,面向经营管理层。营收按 SUM 聚合。")
|
|
147
|
+
.addRow(f("区域"))
|
|
148
|
+
.addColumn(f("产品"))
|
|
149
|
+
.addMetric(f("营收", { aggrType: AggrType.SUM, numberFormat: NumberFormat.currency("¥", 0) }))
|
|
150
|
+
.addSort(f("营收", { aggrType: AggrType.SUM, sortType: SortOrder.DESC }))
|
|
151
|
+
.setShowLegend(true, "right")
|
|
152
|
+
.setDataLabel({ show: true, showNumber: true });
|
|
153
|
+
|
|
154
|
+
registerCard(card.build());
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### 5. 编写 page.js(发布 Card/Selector 时必需)
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
var page = createPage("销售仪表板")
|
|
161
|
+
.setId("wb52d11444d6f1b4063d8cf8")
|
|
162
|
+
.setDescription("综合销售分析")
|
|
163
|
+
.setBackgroundColor("#f5f5f5")
|
|
164
|
+
.setCardMargin(8)
|
|
165
|
+
.addRow([{ card: 0, w: 4 }, { card: 1, w: 8 }], 4)
|
|
166
|
+
.addFullWidthCard(2, 6)
|
|
167
|
+
.addHalfWidthCards(3, 4, 6);
|
|
168
|
+
|
|
169
|
+
registerPage(page.build());
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**仪表板主题**:新建工程没配 `themes/` 时 `preview`/`pack`/`publish` 自动使用内置简约主题(不依赖租户线上主题列表);`checkout` 工程未明确切换主题时保留线上主题或“无主题”状态。**JS DSL 不提供主题接口**——`setDashboardTheme(...)` / `page.setTheme(...)` 会因函数未定义而报错,主题一律走 `guanvis theme preference`(见 `references/theme.md`)。
|
|
173
|
+
|
|
174
|
+
**单张图表主题色**:用 `.setThemeColor(tcId, colors?, options?)` 切换主题色、修改颜色覆盖或选择分类/顺序色板(`options.useSequentialPalette` 显式选色板模式;只改当前主题时 `tcId` 传 `null`)。`tcId` 必须取自 `theme-colors.js` 快照(快照约束见「Harness 化工作法」),完整语义见 `references/chart-properties.md`。
|
|
175
|
+
|
|
176
|
+
**多页面支持**:同一项目可多次 `registerPage`。两种组织方式:
|
|
177
|
+
|
|
178
|
+
1. **单目录**:所有 card 和 page 在同一目录,page 通过 card index(注册顺序)引用
|
|
179
|
+
2. **子目录**(推荐):每个子目录是独立看板工程,有自己的 `schema.js`、`card_*.js`、`page.js`、`themes/`、`charts/`;page 布局必须用 card ID 字符串而非 index,如 `addFullWidthCard("cardId24chars", 8)`
|
|
180
|
+
|
|
181
|
+
子目录模式下 preview/pack/publish/`theme *` 必须 `cd` 进对应子目录单独执行;**根目录直接运行时,若任一子目录有 `themes/`,命令会直接报错并提示 cd**(避免子目录主题被静默忽略)。整个工程都没配 `themes/` 时根目录一次性 `pack` 照常工作。
|
|
182
|
+
|
|
183
|
+
### 6. 执行命令
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# 生成资源 ID(用于 .setId();genid 保证字母开头,手写数字开头 ID 会被新建校验报错拦截)
|
|
187
|
+
guanvis genid 5
|
|
188
|
+
guanvis gen-layout-id <tab|panel|areaTitle|cardGroup|selGroup> [数量] [--length N] # 布局组件 ID,如 tab_AbCdEf
|
|
189
|
+
|
|
190
|
+
# 拉取已有线上仪表板为可编辑工程(只读 BI;细节与红线见 references/checkout-editing.md)
|
|
191
|
+
guanvis checkout <pageId> -d ./existing_dashboard
|
|
192
|
+
# 已有 schema.js 时不加 --force 会保留原文件、向 stderr 输出 WARNING 并成功退出,后续步骤可继续;需要重刷或补字段时显式覆盖
|
|
193
|
+
guanvis init <dsId> -d ./existing_dashboard --force
|
|
194
|
+
# checkout --overwrite 会清理输出目录下所有根级 .js 和旧 .guanvis,避免残留混入运行
|
|
195
|
+
|
|
196
|
+
# 预览(默认摘要 JSON:卡片/页面清单 + changeSummary + 验证状态;全量 payload 落盘 .preview.json,--full 全量输出)
|
|
197
|
+
guanvis preview ./my_dashboard/
|
|
198
|
+
guanvis diff ./existing_dashboard/ # checkout/attach 工程的路径级变更摘要
|
|
199
|
+
|
|
200
|
+
# 发布(publish 自带构建打包上传;pack 只用于生成离线 ZIP 走 upload)
|
|
201
|
+
guanvis publish ./my_dashboard/ --dry-run # 先看"页面落位计划"(目录路径 + dirId),交给用户确认
|
|
202
|
+
guanvis publish ./my_dashboard/ [--page-parent-dir <dir_id>]
|
|
203
|
+
# 每个 Page 都必须有存储目录:page.js 里 .setParentDir("<dirId>") 或 --page-parent-dir;
|
|
204
|
+
# 两者皆无且线上没有同 pgId 页面可沿用时 publish/pack 直接拒绝(不会落根目录,也不会自动建目录)。
|
|
205
|
+
# 目标目录还不存在时先 guanvis dir create --name <名称> --parent <父目录 dirId> 建出来,
|
|
206
|
+
# 用它输出的 dirId 再 publish;查已有目录 ID 用 guancli page tree --type dir
|
|
207
|
+
# 拉不到页面目录树时 publish 会阻断(路径来自目录树,读不到就无法确认落位),先检查账号的页面目录权限
|
|
208
|
+
guanvis pack [-o output.zip] ./my_dashboard/
|
|
209
|
+
guanvis upload output.zip # 只允许上传 guanvis pack 原样生成的 ZIP
|
|
210
|
+
|
|
211
|
+
# 页面目录与页面壳(只动壳,改页面内容仍走 checkout+publish;红线见「页面目录与页面壳管理」)
|
|
212
|
+
guanvis dir create --name <名称> --parent <父目录 dirId>
|
|
213
|
+
guanvis dir rename <dirId> --name <新名称>
|
|
214
|
+
guanvis dir move <dirId> --parent <新父目录 dirId>
|
|
215
|
+
guanvis dir delete <dirId> --yes # 只删空目录;物理删除不进回收站
|
|
216
|
+
guanvis page rename <pgId> --name <新名称> # rename/move 保留 pgId、可逆、不需 --yes
|
|
217
|
+
guanvis page move <pgId> --parent-dir <dirId>
|
|
218
|
+
guanvis page delete <pgId> --yes [--force] # 软删进回收站但 CLI 无恢复命令;有卡片需 --force
|
|
219
|
+
|
|
220
|
+
# 修复已发布资源描述(保留原 ID;本地有 JS 工程时同步更新 .setDescription(...))
|
|
221
|
+
guanvis card set-description <cd_id> --description "..." # 或 --file ./story.md
|
|
222
|
+
guanvis page set-description <pg_id> --description "..." # 支持 --visible=false
|
|
223
|
+
|
|
224
|
+
# 页面视觉验证(可选 PNG,服务端截图不依赖浏览器;仅在需要视觉判断且模型支持图像理解时用,消耗额外 token)
|
|
225
|
+
guanvis screenshot <pageId> [-o out.png] [--orientation horizontal]
|
|
226
|
+
|
|
227
|
+
# 数据集/指标切换后的检查(仅梳理):check-dataset-usage / check-dataset-switch / check-metric-switch
|
|
228
|
+
guanvis check-dataset-switch . --from <oldDs> --to <newDs> --mode full # 详见 --help;--mode linked 查一跳关联
|
|
229
|
+
|
|
230
|
+
# 仪表板主题(详见 references/theme.md)
|
|
231
|
+
guanvis theme preference --keywords "..." --sync # 另有 --theme-id / --clear;theme list/show/sync
|
|
232
|
+
|
|
233
|
+
# 获取当前环境中可用的图表主题色
|
|
234
|
+
guanvis theme-color list
|
|
235
|
+
guanvis theme-color sync -d ./my_dashboard
|
|
236
|
+
|
|
237
|
+
# 获取当前 BI 环境可用的图标
|
|
238
|
+
guanvis icon list
|
|
239
|
+
guanvis icon list --group default_line -f json
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**发布机制**:`publish`/`upload` 走 BI transfer API,`needIdMapping=false` 同 ID 覆盖、发布前强制校验 Page 归属(Card-only 与孤儿 Card/Selector 包直接拒绝)、覆盖检查只探测 Page ID;接口/认证/header 细节见 `references/publish-and-constraints.md`。
|
|
243
|
+
|
|
244
|
+
**线上仪表板更新红线**:checkout 工程发布 = 覆盖式修改指定 Page。CLI 检测到同 ID Page 时,**Agent 禁止未经用户确认自行加 `--allow-overwrite`**——必须先说明将覆盖的 Page ID/名称与影响,用户明确确认后才可重跑加该参数(CLI 会先做覆盖备份,备份失败则中止;`--dry-run` 可预查覆盖对象)。要"保留原页面出新版本"用 `guanvis page save-as`,不要复制 JSON 改 ID。备份/回滚/save-as 细节见 `references/checkout-editing.md` §5。
|
|
245
|
+
|
|
246
|
+
## 页面目录与页面壳管理(guanvis dir / guanvis page)
|
|
247
|
+
|
|
248
|
+
命令清单见上方「执行命令」。红线:删除都有 `--yes` 闸门(不加只打印并取消);**目录删除是物理删除不可恢复且只删空目录,页面删除是软删进回收站但 CLI 无恢复命令**;rename/move 保留原 ID、可逆、不需要 `--yes`。`--parent`/`--parent-dir` 必填(根目录也有真实 `dirId`,用 `guancli page tree --type dir` 查)。完整硬约束(`--force` 语义、服务端硬阻断、预检/回读规则、成环拦截等)动手前读 `references/dir-and-page-management.md`。
|
|
249
|
+
|
|
250
|
+
## 复杂报表 Pro 工作方式
|
|
251
|
+
|
|
252
|
+
**进入前提**:用户明确点名"复杂报表 / 复杂报表 Pro",或 checkout 的目标卡片已是 Pro(未点名的表格/报表需求回「固定工作方式」用原生卡片)。只支持 `COMPLEX_REPORT_PRO`,旧版复杂报表拒绝并建议外部迁移后新建 Pro。
|
|
253
|
+
|
|
254
|
+
与「固定工作方式」同体系(auth → init → 写脚本 → preview/pack → publish),差异只在脚本形态和验证闭环,**动手前先读 `references/complex-report-pro-patterns.md`**(新建走 §0 选型 → §2 骨架与配方 → §3 数据视图规则;编辑已有 Pro 统一 `.setWorkbook()` 见 §5;报错对照 §4 修复表)。两条硬红线:Pro 卡必须与引用它的 Page 同包发布;`pack`/`preview` 只验证结构,发布后必须 `guancli card preview <proCardId> -o result.xlsx` 检查无 `{{...}}` 残留(§6)。
|
|
255
|
+
|
|
256
|
+
## 文件结构约定
|
|
257
|
+
|
|
258
|
+
目录模式下文件加载顺序:
|
|
259
|
+
1. `schema.js` — 数据集定义(init/checkout 生成,不可修改)
|
|
260
|
+
2. `metrics.js` — 指标定义(仅指标卡片需要,自动生成,不可修改)
|
|
261
|
+
3. `dynamic-parameters.js` — 项目全局参数快照(按需,由 parameter 命令或 checkout 生成)
|
|
262
|
+
4. `theme-colors.js` — 项目级图表主题色快照(配置主题色前由 `theme-color sync` 生成或刷新,不可修改;多页面/多子目录共用;构建阶段缺失时会兜底生成)
|
|
263
|
+
5. `card_01_xxx.js` ~ `card_NN_xxx.js` — Card 定义(按文件名排序)
|
|
264
|
+
6. `selector_01_xxx.js` ~ `selector_NN_xxx.js` — 筛选器定义(在 card 之后执行,因为联动需要引用 card 索引)
|
|
265
|
+
7. `page.js` — Page/仪表板组装
|
|
266
|
+
|
|
267
|
+
自定义图表内容文件(如 ECharts 脚本)放子目录(如 `charts/`),避免被当作 card 脚本执行;`themes/` 由 `theme *` 命令维护、全部文件不手改(见 `references/theme.md`)。
|
|
268
|
+
|
|
269
|
+
## 参考示例
|
|
270
|
+
|
|
271
|
+
| 示例 | 路径 | 说明 |
|
|
272
|
+
|------|------|------|
|
|
273
|
+
| 基础仪表板 | `evals/sales_dashboard/` | 普通卡片 + 筛选器 + 页面布局 |
|
|
274
|
+
| 拆分图 | `evals/split_charts/` | 图表按字段拆分 |
|
|
275
|
+
| 自定义图表(ECharts Lite) | `evals/custom_chart_echarts/` | 纯 ECharts `option`,`loadContent()` 文件模式 |
|
|
276
|
+
| 自定义图表(SDK/自定义 DOM) | `evals/custom_chart_sdk/` | HTML/CSS 节点进度图,`GDPlugin` + 连接线对齐布局范式 |
|
|
277
|
+
| 复杂报表 Pro | `evals/complex_report_pro/` | 最小 Workbook DSL 工程(结构配方以 patterns.md §2 为准) |
|
|
278
|
+
| Tab 布局 | `evals/tab_layout/` | 根布局指标卡 + panel 内卡片 + 筛选器 |
|
|
279
|
+
|
|
280
|
+
生成脚本前先查阅对应示例中的文件结构和写法。
|
|
281
|
+
|
|
282
|
+
## 按需参考资料
|
|
283
|
+
|
|
284
|
+
| 场景 | 路径 | 读取时机 |
|
|
285
|
+
|------|------|----------|
|
|
286
|
+
| 字段、计算字段、NumberFormat、高级计算、卡片筛选器 API | `references/api-reference.md` | 写字段/指标/公式/筛选条件时 |
|
|
287
|
+
| 各类 Builder API 与枚举(含 ComplexReportProBuilder 权威定义) | `references/builder-reference.md` | 写或改 JS DSL builder 调用时 |
|
|
288
|
+
| 页面筛选器:类型、配置、默认值、联动、级联、参数和 checkout 编辑 | `references/selector-reference.md` | 创建或修改 selector 前必读 |
|
|
289
|
+
| 图表属性配置 | `references/chart-properties.md` | 创建或修改图表属性时 |
|
|
290
|
+
| checkout 编辑闭环:生成物、attachCard 操作语义、覆盖发布与备份 | `references/checkout-editing.md` | checkout 工程动手前、改线上仪表板时 |
|
|
291
|
+
| 页面目录与页面壳管理完整硬约束 | `references/dir-and-page-management.md` | `guanvis dir` / `page rename/move/delete` 动手前 |
|
|
292
|
+
| 复杂报表 Pro 选型/骨架/配方/报错/编辑/验证 | `references/complex-report-pro-patterns.md` | 创建或修改 Pro 前必读 |
|
|
293
|
+
| zone 校验、图表选型、地图/拆分图、字段对象细节 | `references/validation-and-chart-patterns.md` | pack 报错、选型不确定时 |
|
|
294
|
+
| 仪表板主题机制与 theme 排错 | `references/theme.md` | 指定视觉风格、主题异常时 |
|
|
295
|
+
| 在线同步、认证、ID 管理和硬约束 | `references/publish-and-constraints.md` | publish/upload、确认生成边界时 |
|
|
296
|
+
| Tableau 迁移清单 | `references/tableau-migration.md` | Tableau 工作簿迁移时 |
|
|
297
|
+
| 常见错误与修复 | `references/troubleshooting.md` | 命令失败或校验报错时 |
|
|
298
|
+
|
|
299
|
+
## 最后怎么向用户汇报
|
|
300
|
+
|
|
301
|
+
至少说明:
|
|
302
|
+
|
|
303
|
+
- 创建了多少个 Card、什么图表类型。
|
|
304
|
+
- 是否有筛选器,联动了哪些卡片。
|
|
305
|
+
- 是否有 Page,布局方式如何。
|
|
306
|
+
- 是否有验证错误及修复建议。
|
|
307
|
+
- `pack`/`publish`/`upload` 哪些步骤已成功。
|
|
308
|
+
- 每个已发布 Page 的访问链接和存储路径,直接取 `publish` 成功后"页面落位(发布后回读)"段里的 `链接:`(`<BI 地址>/page/<pgId>`)和 `路径:`(页面目录名称链)。回读失败或提示"实际目录与计划目录不一致"时如实转述,不要编造路径。
|
|
309
|
+
|
|
310
|
+
## 发布前必须确认页面存储目录
|
|
311
|
+
|
|
312
|
+
创建/发布仪表板前先明确页面放在哪个文件夹并由用户确认(招行等客户的目录管理规范):先用 `guancli page tree --type dir` 找到目录的路径和 dirId,把"页面 <名称> 将保存到 <路径>"交给用户;目录不存在时用 `guanvis dir create` 显式创建,**不要**让发布流程自动建目录。确认后在 `page.js` 写 `.setParentDir("<dirId>")`(或发布时 `--page-parent-dir`),`publish --dry-run` 会打印"页面落位计划"(目录路径 + dirId + 新建/覆盖),确认无误再真实发布。修改已发布页面(checkout 工程或线上已有同 pgId)时不指定目录会沿用当前目录,落位计划里会标注"沿用"。任何 Page 都不允许没有目录:`publish`/`pack` 会拒绝,不会把页面放到根目录。
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## VM 环境差异(观远 BI 工作站)
|
|
318
|
+
|
|
319
|
+
本技能在 MCP 虚拟工作站中运行,与本地 CLI 有以下差异:
|
|
320
|
+
|
|
321
|
+
- 命令名直接可用:在工作站里直接执行 `guancli` / `guanetl` / `guanvis` / `guands` / `guanmetric` / `guanwf`(无需安装)。
|
|
322
|
+
- 认证:BI 凭证由网关注入,**不要**执行 `auth login` 或设置 token,直接运行业务命令即可。
|
|
323
|
+
- 文件路径一律用以 `/` 开头的绝对路径(`/` 即工作区根,跨会话持久)。
|
|
324
|
+
- 本技能的参考文档在 `/skills/<技能名>/references/` 下、示例工程在 `/skills/<技能名>/evals/` 下(均只读),用 read_file 工具或 `cat` 按需阅读;正文引用 `references/xxx` / `evals/xxx` 时按此路径解析。
|
|
325
|
+
- 图片文件(png/jpg/gif/webp)用 read_file 工具读取,**不要**用 `cat`/`head` 读图片。默认部署下图片以图像内容返回、模型可直接查看;若 read_file 返回"当前部署已关闭图像内容返回"的提示(部署方接入的模型不支持图像理解),则只有文本元信息,此时不要做任何依赖看图的验证,改用数据类命令核对。
|
|
326
|
+
- 不支持 `cd`、`$VAR` 展开、命令替换 `$(...)`、glob 展开;需要组合时把中间结果写入文件。
|
|
327
|
+
- 文本搜索用 `rg`(工作站内无独立 grep 二进制,`grep`/`egrep`/`fgrep` 会自动转成 `rg` 执行,无需绕路)。
|
|
328
|
+
- `install-skill` / profile 切换 / npm 相关步骤在工作站内不适用,忽略即可。
|
|
329
|
+
|
|
330
|
+
### guanvis 在工作站内的差异(必读)
|
|
331
|
+
|
|
332
|
+
- `guanvis screenshot <pageId> -o /shot.png` 生成 PNG 后,用 read_file 工具读取 `/shot.png` 查看截图(默认以图像内容返回)。超高的纵向长页会自动以「整页概览图 + 多张自上而下的可读分块」一次性返回,无需自行裁剪;只想确认布局/发布成功时用 read_file 的 image_mode=overview 只取一张缩略图省 token。截图前确认当前模型支持图像理解;图像会额外消耗 token。
|
|
333
|
+
- 若 read_file 返回"当前部署已关闭图像内容返回"提示(GUANVM_IMAGE_CONTENT=off 部署),screenshot 的视觉验证闭环不可用:不要反复截图重试,改用 `guancli page get` / `guancli card preview` 等数据类命令核对发布结果。
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// BASIC_MAP: 中国省级行政地图(内置 Highmaps)
|
|
2
|
+
// row zone 放地理维度(省/自治区名),colorBy zone 放渐变着色指标
|
|
3
|
+
// 后端验证:rowSize == 1 && (colorBySize == 1 | metricSize == 1)
|
|
4
|
+
|
|
5
|
+
var card = createCard(ChartType.BASIC_MAP, "各省利润率")
|
|
6
|
+
.setId("b11111111111111111111110")
|
|
7
|
+
.bindDataset(DS)
|
|
8
|
+
.addRow(f("省/自治区"))
|
|
9
|
+
.addColorBy(calcField("利润率", "SUM([利润])/SUM([销售额])", {
|
|
10
|
+
numberFormat: NumberFormat.percentage(1)
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
registerCard(card.build());
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// WORLD_MAP: 世界国家级地图(内置 Highmaps)
|
|
2
|
+
// row zone 放国家名维度,colorBy zone 放渐变着色指标
|
|
3
|
+
|
|
4
|
+
var card = createCard(ChartType.WORLD_MAP, "全球销售分布")
|
|
5
|
+
.setId("b22222222222222222222220")
|
|
6
|
+
.bindDataset(DS)
|
|
7
|
+
.addRow(f("省/自治区"))
|
|
8
|
+
.addColorBy(f("销售额", { aggrType: AggrType.SUM }));
|
|
9
|
+
|
|
10
|
+
registerCard(card.build());
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// POINT_MAP: 标记地图(内置 Highmaps)
|
|
2
|
+
// row zone 放地名维度(1个),metric zone 放数值指标(可多个)
|
|
3
|
+
// 后端验证:rowSize == 1 && metricSize >= 1
|
|
4
|
+
|
|
5
|
+
var card = createCard(ChartType.POINT_MAP, "各省订单与销售额")
|
|
6
|
+
.setId("b33333333333333333333330")
|
|
7
|
+
.bindDataset(DS)
|
|
8
|
+
.addRow(f("省/自治区"))
|
|
9
|
+
.addMetric(f("订单数", { aggrType: AggrType.SUM }))
|
|
10
|
+
.addMetric(f("销售额", { aggrType: AggrType.SUM }));
|
|
11
|
+
|
|
12
|
+
registerCard(card.build());
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
var page = createPage("中国地图示例")
|
|
2
|
+
.setId("c11111111111111111111110")
|
|
3
|
+
.setDescription("BASIC_MAP / WORLD_MAP / POINT_MAP 内置地图示例")
|
|
4
|
+
.setBackgroundColor("#f5f5f5")
|
|
5
|
+
.setCardMargin(8)
|
|
6
|
+
.addFullWidthCard(0, 8)
|
|
7
|
+
.addFullWidthCard(1, 8)
|
|
8
|
+
.addFullWidthCard(2, 8);
|
|
9
|
+
|
|
10
|
+
registerPage(page.build());
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Auto-generated by guanvis schema command
|
|
2
|
+
// This file defines dataset schemas for field() references in card scripts.
|
|
3
|
+
|
|
4
|
+
// Dataset: 各省销售数据 (example, 4 fields)
|
|
5
|
+
defineDataset("s1234567890abcdef12345678", [
|
|
6
|
+
{ fdId: "a1111111111111111111111", name: "省/自治区", fdType: "STRING", metaType: "DIM" },
|
|
7
|
+
{ fdId: "a2222222222222222222222", name: "销售额", fdType: "DOUBLE", metaType: "METRIC" },
|
|
8
|
+
{ fdId: "a3333333333333333333333", name: "利润率", fdType: "DOUBLE", metaType: "METRIC" },
|
|
9
|
+
{ fdId: "a4444444444444444444444", name: "订单数", fdType: "INT", metaType: "METRIC" }
|
|
10
|
+
], { displayType: "CSV" });
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Comparative MVP Round-Trip
|
|
2
|
+
|
|
3
|
+
This eval verifies the L3 native BI `COMPARATIVE` advanced calculation MVP against a real `default` BI environment.
|
|
4
|
+
|
|
5
|
+
It intentionally uses BI menu-facing cases:
|
|
6
|
+
|
|
7
|
+
- 日环比: 增长值
|
|
8
|
+
- 周同比: 增长率
|
|
9
|
+
- 月同比: 对比值
|
|
10
|
+
- 季同比: 增长值
|
|
11
|
+
- 年同比: 默认增长率 + 默认日期筛选模式
|
|
12
|
+
- 年同比(按周): 对比值
|
|
13
|
+
- 期末值: 上月末增长率、上季度末增长值、上年末对比值
|
|
14
|
+
- 自定义: 后移 1 个月增长率
|
|
15
|
+
- 普通模式兼容性由 exporter 单测覆盖;round-trip eval 使用日期筛选上下文保证线上 preview 有可验证结果
|
|
16
|
+
|
|
17
|
+
Run from `guanvis/`:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
./evals/comparative_mvp_roundtrip/verify_default_roundtrip.sh
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The script publishes fixed resource IDs to `default`, then verifies:
|
|
24
|
+
|
|
25
|
+
- `advCalc` is preserved in `zoneData.metric[*].advCalc`.
|
|
26
|
+
- No metric silently degrades to a formula.
|
|
27
|
+
- `card preview` succeeds.
|
|
28
|
+
- Each target metric has at least one non-empty preview value.
|
|
29
|
+
|
|
30
|
+
Runtime outputs are written to `.roundtrip/` and ignored by git.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
var dateField = f("订单日期");
|
|
2
|
+
|
|
3
|
+
var normalCard = createCard(ChartType.PIVOT_TABLE, "L3 同环比 MVP 默认日期筛选模式")
|
|
4
|
+
.setId("p3bc51ab664e095ab2dff402")
|
|
5
|
+
.bindDataset(DS)
|
|
6
|
+
.addFilter(filterField(DS, "订单日期", FilterType.BT, ["2024-01-01", "2025-12-31"]))
|
|
7
|
+
.addFilter(filterField(DS, "订单日期", FilterType.BT, ["2025-01-01", "2025-12-31"]))
|
|
8
|
+
.addMetric(f("销售额", {
|
|
9
|
+
alias: "月同比对比值",
|
|
10
|
+
aggrType: AggrType.SUM,
|
|
11
|
+
advCalc: comparative.monthOverMonth(dateField, ComparativeOutput.COMPARE_VALUE)
|
|
12
|
+
}))
|
|
13
|
+
.addMetric(f("销售额", {
|
|
14
|
+
alias: "季同比增长值",
|
|
15
|
+
aggrType: AggrType.SUM,
|
|
16
|
+
advCalc: comparative.quarterOverQuarter(dateField, ComparativeOutput.GROWTH_VALUE, { replenishDimData: true })
|
|
17
|
+
}))
|
|
18
|
+
.addMetric(f("销售额", {
|
|
19
|
+
alias: "年同比增长率",
|
|
20
|
+
aggrType: AggrType.SUM,
|
|
21
|
+
advCalc: comparative.yearOverYear(dateField, { replenishDimData: true })
|
|
22
|
+
}))
|
|
23
|
+
.addMetric(f("销售额", {
|
|
24
|
+
alias: "上月末增长率",
|
|
25
|
+
aggrType: AggrType.SUM,
|
|
26
|
+
advCalc: comparative.periodEnd(dateField, ComparativePeriodEnd.MONTH_END, ComparativeOutput.GROWTH_RATE)
|
|
27
|
+
}))
|
|
28
|
+
.addMetric(f("销售额", {
|
|
29
|
+
alias: "上季度末增长值",
|
|
30
|
+
aggrType: AggrType.SUM,
|
|
31
|
+
advCalc: comparative.periodEnd(dateField, ComparativePeriodEnd.QUARTER_END, ComparativeOutput.GROWTH_VALUE)
|
|
32
|
+
}))
|
|
33
|
+
.addMetric(f("销售额", {
|
|
34
|
+
alias: "上年末对比值",
|
|
35
|
+
aggrType: AggrType.SUM,
|
|
36
|
+
advCalc: comparative.periodEnd(dateField, ComparativePeriodEnd.YEAR_END, ComparativeOutput.COMPARE_VALUE)
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
registerCard(normalCard.build());
|
|
40
|
+
|
|
41
|
+
var filterBasedCard = createCard(ChartType.PIVOT_TABLE, "L3 同环比 MVP 日期筛选模式")
|
|
42
|
+
.setId("o360e50afb73bcc998353c13")
|
|
43
|
+
.bindDataset(DS)
|
|
44
|
+
.addFilter(filterField(DS, "订单日期", FilterType.BT, ["2024-01-01", "2025-12-31"]))
|
|
45
|
+
.addFilter(filterField(DS, "订单日期", FilterType.BT, ["2025-01-01", "2025-12-31"]))
|
|
46
|
+
.addMetric(f("销售额", {
|
|
47
|
+
alias: "日环比增长值",
|
|
48
|
+
aggrType: AggrType.SUM,
|
|
49
|
+
advCalc: comparative.dayOverDay(dateField, ComparativeOutput.GROWTH_VALUE, { mode: ComparativeMode.FILTER_BASED })
|
|
50
|
+
}))
|
|
51
|
+
.addMetric(f("销售额", {
|
|
52
|
+
alias: "周同比增长率",
|
|
53
|
+
aggrType: AggrType.SUM,
|
|
54
|
+
advCalc: comparative.weekOverWeek(dateField, ComparativeOutput.GROWTH_RATE, { mode: ComparativeMode.FILTER_BASED })
|
|
55
|
+
}))
|
|
56
|
+
.addMetric(f("销售额", {
|
|
57
|
+
alias: "默认年同比增长率",
|
|
58
|
+
aggrType: AggrType.SUM,
|
|
59
|
+
advCalc: comparative.yearOverYear(dateField)
|
|
60
|
+
}))
|
|
61
|
+
.addMetric(f("销售额", {
|
|
62
|
+
alias: "年同比按周对比值",
|
|
63
|
+
aggrType: AggrType.SUM,
|
|
64
|
+
advCalc: comparative.yearOverYearByWeek(dateField, ComparativeOutput.COMPARE_VALUE, { mode: ComparativeMode.FILTER_BASED })
|
|
65
|
+
}))
|
|
66
|
+
.addMetric(f("销售额", {
|
|
67
|
+
alias: "自定义后移增长率",
|
|
68
|
+
aggrType: AggrType.SUM,
|
|
69
|
+
advCalc: comparative.customMonthShift(dateField, -1, ComparativeOutput.GROWTH_RATE)
|
|
70
|
+
}));
|
|
71
|
+
|
|
72
|
+
registerCard(filterBasedCard.build());
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Dataset: 订单表 (default)
|
|
2
|
+
defineDataset("a184fe1b1c27941a9ac977bc", [
|
|
3
|
+
{ fdId: "o0f29e706bf1041d9ab0da11", name: "订单 ID", fdType: "STRING", metaType: "DIM" },
|
|
4
|
+
{ fdId: "r739b62cd3dab49ff9bb7134", name: "订单日期", fdType: "DATE", metaType: "DIM" },
|
|
5
|
+
{ fdId: "o82eaae89ecd046a4b531ce4", name: "发货日期", fdType: "DATE", metaType: "DIM" },
|
|
6
|
+
{ fdId: "k673939fff12744b786d8d44", name: "邮寄方式", fdType: "STRING", metaType: "DIM" },
|
|
7
|
+
{ fdId: "me4783b3bf8984906a32e5ce", name: "客户 ID", fdType: "STRING", metaType: "DIM" },
|
|
8
|
+
{ fdId: "v2a8590c1236e4e58882ee9c", name: "客户名称", fdType: "STRING", metaType: "DIM" },
|
|
9
|
+
{ fdId: "j81f7f09ab6c84168924f9aa", name: "细分", fdType: "STRING", metaType: "DIM" },
|
|
10
|
+
{ fdId: "s99bcae4ac5a045ebae87762", name: "城市", fdType: "STRING", metaType: "DIM" },
|
|
11
|
+
{ fdId: "ufe7632b5afa44dd7a79194e", name: "省/自治区", fdType: "STRING", metaType: "DIM" },
|
|
12
|
+
{ fdId: "e2a051c6ebda04917a10cc14", name: "国家", fdType: "STRING", metaType: "DIM" },
|
|
13
|
+
{ fdId: "xe01f39825ccc428eaf67911", name: "地区", fdType: "STRING", metaType: "DIM" },
|
|
14
|
+
{ fdId: "cd9b3a6c556ef4c53a08df16", name: "产品 ID", fdType: "STRING", metaType: "DIM" },
|
|
15
|
+
{ fdId: "cece9879e99f545449909a82", name: "类别", fdType: "STRING", metaType: "DIM" },
|
|
16
|
+
{ fdId: "k15359167149d4d02bbede2b", name: "子类别", fdType: "STRING", metaType: "DIM" },
|
|
17
|
+
{ fdId: "f247afa584af241dba64821d", name: "产品名称", fdType: "STRING", metaType: "DIM" },
|
|
18
|
+
{ fdId: "g4a34bd7bcb78425aa5485d1", name: "销售额", fdType: "DOUBLE", metaType: "METRIC" },
|
|
19
|
+
{ fdId: "xd21ba1d7fd19433ebc728b6", name: "数量", fdType: "LONG", metaType: "METRIC" },
|
|
20
|
+
{ fdId: "l0dbffcc612e047c9a6dae7b", name: "折扣", fdType: "DOUBLE", metaType: "METRIC" },
|
|
21
|
+
{ fdId: "s1c05aa5e4bdd4a54a60e811", name: "利润", fdType: "DOUBLE", metaType: "METRIC" }
|
|
22
|
+
], { displayType: "DATAFLOW" });
|