@guandata/guanvis 0.1.23 → 0.1.25

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## @guandata/guanvis 0.1.25 - 2026-06-11
4
+
5
+ - 补充资源 ID 命名指引,建议 Card/Page/布局等资源 ID 使用字母开头,降低平台 ID 解析兼容风险。
6
+
7
+ ## @guandata/guanvis 0.1.24 - 2026-06-09
8
+
9
+ - 新增 area title 和 card group 布局能力,支持在页面中组织分区标题和卡片分组。
10
+ - `gen-layout-id` 支持生成 area title 相关布局 ID,便于构建复杂页面布局。
11
+ - 增强布局 DSL、打包导出和页面布局校验,补充大量布局场景测试。
12
+
3
13
  ## @guandata/guanvis 0.1.23 - 2026-06-04
4
14
 
5
15
  - 新增指标卡片构建能力,支持基于指标配置生成图表卡片,并补充 `metric init` 和指标图表参考文档。
package/README.md CHANGED
@@ -18,6 +18,8 @@ guanvis genid 5
18
18
  # 生成布局组件 ID
19
19
  guanvis gen-layout-id tab
20
20
  guanvis gen-layout-id panel 3 --length 8
21
+ guanvis gen-layout-id areaTitle
22
+ guanvis gen-layout-id cardGroup
21
23
 
22
24
  # 初始化:从 BI 获取数据集结构
23
25
  guanvis init <dsId> -d ./my_dashboard/
@@ -49,6 +51,16 @@ guanvis publish ./my_dashboard/ --allow-overwrite
49
51
 
50
52
  ## 版本更新
51
53
 
54
+ ### @guandata/guanvis 0.1.25
55
+
56
+ - 补充资源 ID 命名指引,建议 Card/Page/布局等资源 ID 使用字母开头,降低平台 ID 解析兼容风险。
57
+
58
+ ### @guandata/guanvis 0.1.24
59
+
60
+ - 新增 area title 和 card group 布局能力,支持在页面中组织分区标题和卡片分组。
61
+ - `gen-layout-id` 支持生成 area title 相关布局 ID,便于构建复杂页面布局。
62
+ - 增强布局 DSL、打包导出和页面布局校验,补充大量布局场景测试。
63
+
52
64
  ### @guandata/guanvis 0.1.23
53
65
 
54
66
  - 新增指标卡片构建能力,支持基于指标配置生成图表卡片,并补充 `metric init` 和指标图表参考文档。
@@ -83,7 +95,7 @@ guanvis publish ./my_dashboard/ --allow-overwrite
83
95
  ### 0.1.18
84
96
 
85
97
  - 新增 Tab 布局能力,支持通过 `createTab()` / `addPanel()` 组织同页多组可切换内容。
86
- - 新增 `gen-layout-id` 命令,用于生成 tab/panel 等布局组件 ID。
98
+ - 新增 `gen-layout-id` 命令,用于生成布局组件 ID。
87
99
  - 增加 Tab 布局示例工程和文档说明,便于快速复用。
88
100
  - 增强筛选器默认值校验,提前发现不匹配的筛选值配置。
89
101
 
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guandata/guanvis",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "description": "观远 BI Card/Page 生成工具 - 通过 JS DSL 创建图表和仪表板",
5
5
  "bin": {
6
6
  "guanvis": "bin/run.js"
@@ -22,13 +22,14 @@ compatibility: "Requires Node.js 14+. Install via npm link (local) or npm instal
22
22
  - Card/Page 描述也是 JS 源文件的一部分:新建看板或改版时,在 `card_*.js` / `page.js` 中写 `.setDescription(...)`,再通过 `preview`/`pack`/`publish` 从 JS 源文件生成并发布资源。
23
23
  - 写脚本前先形成 dashboard contract:目标用户、业务问题、使用的数据集、核心指标、维度拆解、筛选器、页面结构和验证方式。
24
24
  - 每次生成都针对明确目录或明确子目录;不要把 unrelated 示例、旧包或临时 ZIP 混入同一个发布目标。
25
+ - Card/Page/Selector 的 `.setId(...)` 建议使用 `guanvis genid` 生成;如果生成或填写的 24 位 ID 以数字开头,重新生成一组,避免 BI 前端把 ID 拼成 CSS selector(如 `#5bef...`)时触发 `querySelector` 语法错误。
25
26
  - 先 `preview/pack` 做本地结构验证,再 `publish/upload`;修改已发布资源前先判断变更类型:仅修复 Card/Page 描述时应保留原资源 ID,使用 `card/page set-description` 并同步维护 JS 中的 `.setDescription(...)`;调整图表、布局、筛选器、字段等看板内容时,按线上仪表板更新策略处理。
26
27
  - **资源包安全红线**:Agent 只编辑 DSL 源文件;资源包 ZIP 是 `guanvis pack/publish` 的派生产物,不手工生成、解包修改或重打包。`guanvis upload` 只允许上传 `guanvis pack` 原样生成的 ZIP。若用户要求批量重绑资源、迁移已有页面或复用线上页面结构,先停下来说明风险并确认方案,不要直接改 ZIP。
27
28
  - 发布后优先用 `guancli page get/card get` 回读结构与配置。只有在明确需要视觉质量判断、且当前大模型支持图像理解时,才使用 `guanvis screenshot <pageId>` 生成 PNG 并交给模型分析;不要把截图作为默认闭环步骤,因为图像理解会额外消耗 token/费用。
28
29
 
29
30
  ## AI Quick Reference(速查,详细说明见按需参考资料)
30
31
 
31
- 1. **工厂函数**:数据集图表用 `createCard()`;指标平台指标卡片用 `createMetricChart()`;筛选器/文本/图片/杜邦/Tab/页面用 `createSelector()` / `createTextCard()` / `createImageCard()` / `createDuPontChart()` / `createTab()` / `createPage()`,不要 `new XxxBuilder()`
32
+ 1. **工厂函数**:数据集图表用 `createCard()`;指标平台指标卡片用 `createMetricChart()`;筛选器/文本/图片/杜邦/Tab/页面用 `createSelector()` / `createTextCard()` / `createImageCard()` / `createDuPontChart()` / `createAreaTitle()` / `createCardGroup()` / `createTab()` / `createPage()`,不要 `new XxxBuilder()`
32
33
  2. **注册函数**:`registerCard(card.build())` / `registerMetricChart(card.build())` / `registerSelector(sel.build())` / `registerTextCard(text.build())` / `registerImageCard(image.build())` / `registerDuPontChart(dupont.build())` / `registerPage(page.build())`
33
34
  3. **字段引用**:单数据集用 `f("字段名")`,多数据集用 `field(DS, "字段名")`
34
35
  4. **zone maxCount**:`BASIC_COLUMN/BAR/LINE` metric=1;`GROUPED_*/STACKED_*` metric=∞;`KPI_CARD` metric=1;组合图 `*_WITH_LINE` row=1
@@ -48,7 +49,7 @@ compatibility: "Requires Node.js 14+. Install via npm link (local) or npm instal
48
49
  18. **设计规则**:`preview`/`pack`/`publish` 会自动应用内置设计规则;需要自定义静态卡片默认规则或主题已开放配置时,在工程目录新建 `design-rule.json`,不要手改 `themes/<themeId>.json`;详见 `references/theme.md`
49
50
  19. **图表选型**:用户说“指标卡片”时先区分语义:如果是数据集字段做单值/KPI,用 `SINGLE_VALUE` / `KPI_CARD`;如果是“用指标平台已有指标创建卡片”,必须先 `guanvis metric-init <metricId>`,再用 `createMetricChart()` + `metric()` / `metricDim()`,生成后端 `CARD_TYPE.METRIC_CHART`。复杂指标卡片参数先读 `references/metric-chart-reference.md`
50
51
  20. **杜邦分析图**:杜邦不是普通 `ChartType`,用 `createDuPontChart()` 创建 `LAYOUT` 卡片;节点通常放 `KPI_CARD` 子卡片,并通过 `.setRoot()` / `.addChild()` 组织树。页面布局只放杜邦父卡片,不单独放子卡片;筛选器 `linkToAll()` 会覆盖杜邦子卡片。
51
- 21. **tab 布局**:同一主题有多组互斥分析内容时可用 tab;少量卡片或需同时对照时优先平铺。用法见 `references/builder-reference.md`,示例见 `evals/tab_layout/`
52
+ 21. **布局组件**:支持了布局组件 `小标题(AreaTitle)`/ `卡片组(CardGroup)`/ `标签页(Tab)`, 目前布局组件只支持放在画布的根布局,不支持嵌套组合使用,用法见 `references/builder-reference.md`。
52
53
  22. **资源包禁止手改**:只改 DSL,不改 ZIP 内部文件;`upload` 只用于上传 `guanvis pack` 原样生成的包。批量重绑、迁移页面等需求先讨论方案。
53
54
 
54
55
  ## 何时使用
@@ -262,10 +263,13 @@ registerPage(p.build());
262
263
  # 生成资源 ID(用于 .setId() 调用)
263
264
  guanvis genid # 生成 1 个
264
265
  guanvis genid 5 # 生成 5 个
266
+ # 如果生成或填写的 ID 以数字开头,重新生成一组,避免 BI 前端 querySelector("#<id>") 报非法 selector
265
267
 
266
268
  # 生成布局组件 ID
267
269
  guanvis gen-layout-id tab # 生成 1 个 tab_ + 默认 6 位字母
268
270
  guanvis gen-layout-id panel 3 --length 8 # 生成 3 个 panel_ + 8 位字母;length 只计算下划线后的随机字母,超出 6~10 时自动收敛
271
+ guanvis gen-layout-id areaTitle # 生成 1 个 areaTitle_ + 默认 6 位字母
272
+ guanvis gen-layout-id cardGroup # 生成 1 个 cardGroup_ + 默认 6 位字母
269
273
 
270
274
  # 预览生成结果(JSON 输出到 stdout,含 payload 验证,用于调试)
271
275
  guanvis preview ./my_dashboard/
@@ -5,7 +5,7 @@
5
5
  | 方法 | 说明 |
6
6
  |------|------|
7
7
  | `createCard(chartType, name)` | 创建 Card(chartType 必须使用 `ChartType.XXX` 枚举) |
8
- | `.setId(cardId)` | **必填**。设置资源 ID(严格 24 位字母数字,格式与后端 RandUtil.uuid 一致),支持多次上传覆盖更新。通过 `guanvis genid` 生成 |
8
+ | `.setId(cardId)` | **必填**。设置资源 ID(严格 24 位字母数字,格式与后端 RandUtil.uuid 一致),支持多次上传覆盖更新。通过 `guanvis genid` 生成;如果生成或填写的 ID 以数字开头,建议重新生成一组,避免 BI 前端 `querySelector("#<id>")` 报错 |
9
9
  | `.bindDataset(dsId)` | 绑定数据集(必填,dsId 必须在 defineDataset 中注册) |
10
10
  | `.addRow(field)` | 添加行维度(X 轴) |
11
11
  | `.addColumn(field)` | 添加列维度(按维度分组着色,如按地区/类别分色)。仅 `STACKED_COLUMN`、`GROUPED_COLUMN`、`GROUPED_BAR` 等多指标图表支持 |
@@ -289,8 +289,10 @@ overview.linkTo("bbbbbbbbbbbbbbbbbbbbbbbb", {
289
289
 
290
290
  **布局单位**:
291
291
  1. 默认横向使用 12 列栅格;开启精细模式后使用 60 列栅格。
292
- 2. 推荐通过 `.setFineMode(true)` 设置为精细模式,且必须在任何 `addRow()` / `placeCard()` / `addTab()` 等布局方法之前调用。
292
+ 2. 推荐通过 `.setFineMode(true)` 设置为精细模式,且必须在任何 `addRow()` / `placeCard()` / `addTab()` / `addAreaTitle()` / `addCardGroup()` 等布局方法之前调用。
293
293
  3. `addRow()` 及其快捷方法的 `height` 省略或为 0 时使用默认行高(普通 6,精细 18)。
294
+ 4. 区域小标题用 `createAreaTitle(...).setId(...).build()` 定义,并通过 `page.addAreaTitle(title)` 放在 Page 根布局;不要放进 tab panel。
295
+ 5. 卡片组用 `createCardGroup(...).setId(...)` 定义,并通过 `page.addCardGroup(group)` 放在 Page 根布局。
294
296
 
295
297
  | 方法 | 说明 |
296
298
  |------|------|
@@ -304,6 +306,8 @@ overview.linkTo("bbbbbbbbbbbbbbbbbbbbbbbb", {
304
306
  | `.addQuarterWidthCards(ci1, ci2, ci3, ci4, height?)` | 四等分 |
305
307
  | `.placeCard(cardIndex, x, y, w, h)` | 精确放置 Card,`w/h` 必须大于 0, `x/y/w/h` 必须显式填写 |
306
308
  | `.addTab(tab, height?)` | 添加一个满宽 tab 容器;不传 height 时按第一个 panel 内容自动推导 |
309
+ | `.addAreaTitle(areaTitle, height?)` | 添加一个满宽区域小标题|
310
+ | `.addCardGroup(group, height?)` | 添加一个满宽卡片组;不传 height 时按标题和组内布局自动推导 |
307
311
  | `.setBackgroundColor(color)` | 页面背景色 |
308
312
  | `.setCardMargin(margin)` | 卡片间距 |
309
313
  | `.setFineMode(enabled)` | 开启/关闭精细模式 |
@@ -311,6 +315,66 @@ overview.linkTo("bbbbbbbbbbbbbbbbbbbbbbbb", {
311
315
  | `.setLayoutSetting(config)` | 原始 layout 配置 |
312
316
  | `.build()` | 构建 |
313
317
 
318
+ ### AreaTitleBuilder
319
+
320
+ `areaTitle` 是 Page 根布局里的区域小标题,不是 Card,不绑定数据集,也不会生成 page-card relation。ID 必须以 `areaTitle_` 开头,建议用 `guanvis gen-layout-id areaTitle` 生成。
321
+
322
+ | 方法 | 说明 |
323
+ |------|------|
324
+ | `createAreaTitle(name)` | 创建区域小标题,`name` 即为标题的内容,会被写入该组件的 style 中,必须要传 name |
325
+ | `.setId(areaTitleId)` | **必填**。设置区域小标题 ID,必须以 `areaTitle_` 开头 |
326
+ | `.setShowTitle(boolean)` | 是否显示标题 |
327
+ | `.setFontSize(number)` | 字号 |
328
+ | `.setColor(color)` | 字体颜色 |
329
+ | `.setBold(boolean)` | 是否加粗 |
330
+ | `.setTextAlign(alignment)` | 对齐方式, 支持 `left`, `center`, `right` |
331
+ | `.setBackgroundColor(color)` | 背景色 |
332
+ | `.setShowBgImage(boolean)` | 是否显示背景图 |
333
+ | `.setShowIcon(boolean)` | 是否显示图标 |
334
+ | `.build()` | 构建 areaTitle result |
335
+
336
+ ```javascript
337
+ var salesTitle = createAreaTitle("销售概览")
338
+ .setId("areaTitle_AbCdEf")
339
+ .setFontSize(20)
340
+ .setBold(true)
341
+ .setTextAlign("left")
342
+ .build();
343
+
344
+ var page = createPage("销售仪表板")
345
+ .setId("p184352b7a76776db5f534df")
346
+ .addAreaTitle(salesTitle)
347
+ .addFullWidthCard(0, 6);
348
+
349
+ registerPage(page.build());
350
+ ```
351
+
352
+ ### CardGroupBuilder
353
+
354
+ `cardGroup` 是一个布局容器,不是 Card,不绑定数据集,也不会生成独立 page-card relation。ID 必须以 `cardGroup_` 开头,建议用 `guanvis gen-layout-id cardGroup` 生成。卡片组目前只能放入根布局,暂不支持放入 tab panel、另一个卡片组或嵌套区域小标题。
355
+
356
+ | 方法 | 说明 |
357
+ |------|------|
358
+ | `createCardGroup(name)` | 创建卡片组,`name` 写入分组标题 |
359
+ | `.setId(cardGroupId)` | **必填**。设置卡片组 ID,必须以 `cardGroup_` 开头 |
360
+ | `.setShowTitle(boolean)` | 是否显示标题,默认 `true` |
361
+ | `.addRow(specs, height?)` | 在组内按行放置卡片,写法同 `PageBuilder.addRow()` |
362
+ | `.addFullWidthCard(cardIndex, height?)` | 在组内放一张满宽卡片 |
363
+ | `.placeCard(cardIndex, x, y, w, h)` | 在组内精确放置卡片 |
364
+
365
+ ```javascript
366
+ var salesGroup = createCardGroup("销售概览")
367
+ .setId("cardGroup_AbCdEf")
368
+ .addRow([{ card: 0 }, { card: 1 }])
369
+ .addFullWidthCard(2);
370
+
371
+ var page = createPage("销售仪表板")
372
+ .setId("p184352b7a76776db5f534df")
373
+ .addCardGroup(salesGroup);
374
+
375
+ registerPage(page.build());
376
+ ```
377
+
314
378
  #### 页面密度尺寸建议
315
379
 
316
380
  以下尺寸建议以非精细模式的 12 列布局单位为基准,用于生成页面时选择页面卡片间距和常见卡片高度。精细模式目前只定义横向 60 列栅格与显式 `x/y/w/h` 放置规则,暂不提供独立的密度尺寸换算规则。
@@ -329,9 +393,9 @@ overview.linkTo("bbbbbbbbbbbbbbbbbbbbbbbb", {
329
393
 
330
394
  注意:这里的高度建议是非精细模式下的页面生成建议,不覆盖 `addRow()` 在精细模式下省略高度时使用默认行高 `18` 的 API 行为。
331
395
 
332
- ### Tab 布局
396
+ ### Tab Builder
333
397
 
334
- tab 用于把页面中的卡片分到多个 panel。适合同一主题下多组互斥查看的分析内容;若卡片较少或需要同时对照,优先直接平铺。关键总览指标通常放在 tab 外,tab 内按实际分析主题组织 panel。支持通过 `page.addTab(tab)` 添加满宽 tab,暂不支持半宽 tab 或 tab 嵌套。
398
+ tab 用于把页面中的卡片分到多个 panel。适合同一主题下多组互斥查看的分析内容;若卡片较少或需要同时对照,优先直接平铺。关键总览指标通常放在 tab 外,tab 内按实际分析主题组织 panel。支持通过 `page.addTab(tab)` 添加满宽 tab,暂不支持半宽 tab 或 tab 嵌套。 示例可以参考 `evals/tab_layout/`。
335
399
 
336
400
  | 方法 | 说明 |
337
401
  |------|------|
@@ -46,7 +46,7 @@
46
46
 
47
47
  所有 Card、Selector 和 Page **必须**调用 `.setId(id)` 设置显式 ID。未设置 ID 会在 JS 校验和 Go 校验两层报错,阻止生成。
48
48
 
49
- - `.setId(id)` 的 ID **必须**为严格 24 位字母数字字符串(正则:`^[a-zA-Z0-9]{24}$`),与后端 `RandUtil.uuid` 格式一致。
49
+ - `.setId(id)` 的 ID **必须**为严格 24 位字母数字字符串(正则:`^[a-zA-Z0-9]{24}$`),与后端 `RandUtil.uuid` 格式一致。若生成或手填的 ID 以数字开头,建议重新生成一组,避免 BI 前端某些路径把 ID 拼成 CSS selector(如 `#5bef...`)时触发 `querySelector` 语法错误。
50
50
  - **生成 ID**:先运行 `guanvis genid <数量>` 生成足够的 ID,在编写脚本时直接填入每个 card/selector/page 的 `.setId()` 调用中。
51
51
  - **线上更新默认策略**:已发布过或线上正在使用的仪表板,后续修改默认生成新的 Page/Card/Selector ID,并给 Page 名称追加版本号后发布,保留旧版本不覆盖。
52
52
  - **覆盖前检查**:发布前可先运行 `guanvis publish <dir> --dry-run` 或 `guanvis upload <zip> --dry-run`,只构建/解析资源并列出将被覆盖的线上 Card/Page,不提交 transfer 任务。