@finebi/finebi-cli 1.4.0 → 1.6.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/README.md +35 -1
- package/package.json +5 -4
- package/skills/finebi-cli-agent/SKILL.md +8 -4
- package/skills/finebi-cli-agent/references/command-workflows.md +61 -7
- package/skills/finebi-cli-agent/references/dashboard-data-result.md +219 -0
- package/skills/finebi-cli-agent/references/dashboard-dsl-api.md +12 -1005
- package/skills/finebi-cli-agent/references/dashboard-dsl-core.md +194 -0
- package/skills/finebi-cli-agent/references/dashboard-dsl-examples.md +378 -0
- package/skills/finebi-cli-agent/references/dashboard-dsl-items.md +456 -0
- package/skills/finebi-cli-agent/references/file-to-dashboard.md +1 -1
- package/skills/finebi-cli-agent/references/handoff-contract.md +2 -0
- package/skills/finebi-cli-agent/references/mapping-rules.md +15 -15
- package/skills/finebi-cli-agent/references/scenario-workflows.md +1 -1
- package/skills/finebi-cli-agent/references/web-app.md +13 -0
- package/skills/finebi-cli-agent/references/widget-dsl-api-examples.md +21 -4
- package/skills/finebi-cli-agent/references/widget-dsl-api.md +10 -1336
- package/skills/finebi-cli-agent/references/widget-dsl-contexts.md +142 -0
- package/skills/finebi-cli-agent/references/widget-dsl-core.md +374 -0
- package/skills/finebi-cli-agent/references/widget-dsl-encodings.md +457 -0
- package/skills/finebi-cli-agent/references/widget-dsl-styles.md +413 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/package.json +1 -1
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/app.js +189 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/help.js +33 -2
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/index.js +5 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/src/schema-options.js +44 -8
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/AGENTS.md +27 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/README.md +30 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/docs/auth-and-deploy.md +17 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/docs/data-contract.md +21 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/docs/design.md +13 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/docs/filters.md +89 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/index.html +2 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/package-lock.json +2191 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/package.json +15 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/public/app-config.json +11 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/scripts/dev-proxy.mjs +56 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/App.tsx +31 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/components/Chart.tsx +31 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/components/DataTable.tsx +14 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/components/FilterBar.tsx +42 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/components/Widget.tsx +28 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/components/calendar.ts +14 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/client.ts +37 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/date.d.ts +1 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/date.js +5 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/filters.d.ts +4 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/filters.js +106 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/normalize.ts +77 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/types.ts +18 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/main.tsx +5 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/services/view-data.ts +18 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/styles.css +8 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tests/calendar.test.mjs +25 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tests/proxy.test.mjs +84 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tests/runtime.test.mjs +136 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tsconfig.json +4 -0
- package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/vite.config.ts +13 -0
- package/src/app.js +189 -0
- package/src/help.js +33 -2
- package/src/index.js +5 -0
- package/src/schema-options.js +44 -8
- package/templates/web-app/AGENTS.md +27 -0
- package/templates/web-app/README.md +30 -0
- package/templates/web-app/docs/auth-and-deploy.md +17 -0
- package/templates/web-app/docs/data-contract.md +21 -0
- package/templates/web-app/docs/design.md +13 -0
- package/templates/web-app/docs/filters.md +89 -0
- package/templates/web-app/index.html +2 -0
- package/templates/web-app/package-lock.json +2191 -0
- package/templates/web-app/package.json +15 -0
- package/templates/web-app/public/app-config.json +11 -0
- package/templates/web-app/scripts/dev-proxy.mjs +56 -0
- package/templates/web-app/src/App.tsx +31 -0
- package/templates/web-app/src/components/Chart.tsx +31 -0
- package/templates/web-app/src/components/DataTable.tsx +14 -0
- package/templates/web-app/src/components/FilterBar.tsx +42 -0
- package/templates/web-app/src/components/Widget.tsx +28 -0
- package/templates/web-app/src/components/calendar.ts +14 -0
- package/templates/web-app/src/finebi/client.ts +37 -0
- package/templates/web-app/src/finebi/date.d.ts +1 -0
- package/templates/web-app/src/finebi/date.js +5 -0
- package/templates/web-app/src/finebi/filters.d.ts +4 -0
- package/templates/web-app/src/finebi/filters.js +106 -0
- package/templates/web-app/src/finebi/normalize.ts +77 -0
- package/templates/web-app/src/finebi/types.ts +18 -0
- package/templates/web-app/src/main.tsx +5 -0
- package/templates/web-app/src/services/view-data.ts +18 -0
- package/templates/web-app/src/styles.css +8 -0
- package/templates/web-app/tests/calendar.test.mjs +25 -0
- package/templates/web-app/tests/proxy.test.mjs +84 -0
- package/templates/web-app/tests/runtime.test.mjs +136 -0
- package/templates/web-app/tsconfig.json +4 -0
- package/templates/web-app/vite.config.ts +13 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Widget DSL API:过滤、配色、数值格式与枚举
|
|
2
|
+
|
|
3
|
+
> Widget DSL API 总导航见 [widget-dsl-api.md](widget-dsl-api.md)。
|
|
4
|
+
|
|
5
|
+
## 6. 过滤上下文
|
|
6
|
+
|
|
7
|
+
过滤固定采用 `field(...)+算子` 的链式写法:
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
filter().field(from("销售表").dim("地区")).eq("华东")
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
| DSL API | 业务含义 |
|
|
14
|
+
|--------------------------------|-----------------|
|
|
15
|
+
| `.field(fieldRef)` | 指定当前过滤目标字段。 |
|
|
16
|
+
| `.eq(value)` / `.ne(value)` | 文本、数值、日期等于 / 不等于。 |
|
|
17
|
+
| `.gt(value)` / `.gte(value)` / `.lt(value)` / `.lte(value)` | 数值大于 / 大于等于 / 小于 / 小于等于。 |
|
|
18
|
+
| `.in(values)` / `.notIn(values)` | 文本枚举属于 / 不属于;日期显示文本也可按枚举匹配。 |
|
|
19
|
+
| `.contains(value)` / `.notContains(value)` | 文本或日期显示文本包含 / 不包含。 |
|
|
20
|
+
| `.startsWith(value)` / `.notStartsWith(value)` | 文本或日期显示文本前缀正 / 反匹配。 |
|
|
21
|
+
| `.endsWith(value)` / `.notEndsWith(value)` | 文本或日期显示文本后缀正 / 反匹配。 |
|
|
22
|
+
| `.between(from, to)` / `.notBetween(from, to)` | 数值或日期区间 / 区间外;数值默认包含两端。 |
|
|
23
|
+
| `.between(from, to, includeFrom, includeTo)` / `.notBetween(from, to, includeFrom, includeTo)` | 数值区间的开闭边界;两个标记均为 boolean。 |
|
|
24
|
+
| `.before(value)` / `.after(value)` | 日期早于 / 晚于。 |
|
|
25
|
+
| `.isNull()` / `.notNull()` | 文本、数值、日期为空 / 不为空。 |
|
|
26
|
+
| `.topN(value)` / `.bottomN(value)` | 文本、数值、日期最大 / 最小 N 个;N 为正整数或数值参数。日期可用 `.latest(value)` / `.earliest(value)`,导出归一为 topN/bottomN。 |
|
|
27
|
+
| `.condition(WidgetFilter.anyOf([...]))` / `.condition(WidgetFilter.allOf([...]))` | 同一字段、分组和层级内的 OR / AND 条件树,可嵌套;子条件使用 WidgetFilter 的同名算子工厂。 |
|
|
28
|
+
| `.closeRange(includeMin, includeMax)` | 数值区间端点开闭,紧跟 between 之前声明;与四参数 between 等价,重复声明的边界须一致。省略 = 全闭;回读保留开闭语义。 |
|
|
29
|
+
|
|
30
|
+
数值参数过滤:先用 `widget-parameter info --subject-id ...` 查询当前主题参数,再使用
|
|
31
|
+
`.filter().field(from("门店销售数据统计").sum("销售额")).topN(parameter("排名数量"))`。
|
|
32
|
+
等值过滤使用 `.eq(parameter("数值阈值"))`,最小 N 个使用 `.bottomN(parameter("排名数量"))`。
|
|
33
|
+
数值 eq/ne/gt/gte/lt/lte 与所有类型的 topN/bottomN 使用 number 参数;文本 in/notIn 和六种文本匹配使用 string 参数。
|
|
34
|
+
日期 eq/ne/before/after 使用 date 参数,整段日期参数通过 `.between(parameter("时间段"))` / `.notBetween(parameter("时间段"))` 传入。
|
|
35
|
+
日期显示文本匹配使用 string 参数。参数按当前主题名称解析,不用默认值替代;不接受参数与常量混合区间或参数列表。
|
|
36
|
+
仪表板数值控件通过 `bindWidgetParameter("排名数量")` 绑定同名参数,修改控件值即可动态改变过滤值。
|
|
37
|
+
参考:[数值参数参与过滤](https://help.fanruan.com/finebi/doc-view-1064.html)。
|
|
38
|
+
|
|
39
|
+
日期点与区间端点接受已有 `DynamicDate` 值;需要工作日偏移、明确粒度或时钟时使用 `FilterDate`:
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
.filter().field(from("销售表").sum("销售额")).gte(1000)
|
|
43
|
+
.filter().field(from("销售表").dim("地区"))
|
|
44
|
+
.condition(WidgetFilter.anyOf([WidgetFilter.eq("华东"), WidgetFilter.startsWith("华南")]))
|
|
45
|
+
.filter().field(from("销售表").dim("日期"))
|
|
46
|
+
.between(DynamicDate.beginOf(DynamicDate.MONTH, -1), DynamicDate.endOf(DynamicDate.MONTH, -1))
|
|
47
|
+
.filter().field(from("销售表").dim("日期"))
|
|
48
|
+
.before(FilterDate.offset(DynamicDate.today()).time("18:00:00").build())
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`FilterDate.offset(DynamicDate...)` 或 `FilterDate.workdays(-3)` 返回 Builder,可设置
|
|
52
|
+
`.group(FilterDate.YEAR/QUARTER/MONTH/WEEK/DAY/HOUR/MINUTE/SECOND/WORKDAY/AUTO)`,
|
|
53
|
+
`.currentTime()` 或 `.time("HH:mm:ss")` 后 `.build()`。工作日依赖服务器工作日日历;
|
|
54
|
+
currentTime 在查询时取当前时钟,time 为固定整秒时刻;`.time("")` 拒绝空字符串,需要当前时钟时使用 `.currentTime()`。动态区间两端可以分别使用静态或动态值。
|
|
55
|
+
|
|
56
|
+
条件树不跨字段或计算层级;多次 `.filter()` 之间仍为 AND,根 AND 导出可展开为多条条件。
|
|
57
|
+
日期文本匹配受字段日期粒度与引擎限制,保存时拒绝 Direct 引擎的包含和前后缀匹配(含参数和嵌套条件)。
|
|
58
|
+
本文组件过滤能力不扩展控件候选值过滤或动态字段值 `where` 的接口。
|
|
59
|
+
|
|
60
|
+
层级在字段与算子之间设置,例如:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
.filter().field(from("销售表").dim("地区"))
|
|
64
|
+
.level(FilterLevel.FOURTH).eq("华东")
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
| FilterLevel | 自助分析主题 | 标准分析主题 |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| AUTO(默认) | 按字段及计算自动决定 | 按字段及计算自动决定 |
|
|
70
|
+
| FIRST | 明细过滤 | 前置过滤 |
|
|
71
|
+
| SECOND | DEF 新增列过滤 | 明细过滤 |
|
|
72
|
+
| THIRD | 聚合计算过滤 | 聚合计算过滤 |
|
|
73
|
+
| FOURTH | 快速计算过滤 | 快速计算过滤 |
|
|
74
|
+
|
|
75
|
+
未声明 `.level(...)` 时按设计器面板的默认落值写入(两主题不同):
|
|
76
|
+
维度自身过滤与未聚合指标过滤在标准主题恒第二层、自助主题第一层(top/bottom N 时第二层);
|
|
77
|
+
聚合指标过滤第三层、top/bottom N 时第四层;公式过滤引用指标时第二层、否则第一层。
|
|
78
|
+
**明细表**过滤走独立编辑器,默认标准主题 22(固定明细档)、非标准主题第一层。已知差异
|
|
79
|
+
(前端有、本实现暂未镜像,可用显式 `.level(...)` 覆盖):自助主题「数值维度/维度依赖聚合指标」
|
|
80
|
+
项前端固定第二层、本实现落第一层。带快速计算的聚合指标过滤前端默认第四层、标准化路径
|
|
81
|
+
不可声明(`.filter()` 的字段不接受携带快速计算)。
|
|
82
|
+
普通维度进入分析区且依赖分组时可调整到四层;不在分析区时仅支持 FIRST/SECOND。
|
|
83
|
+
自助主题的 DEF/WINDOW/FIXED 维度进入分析区后只允许 SECOND,维度依赖指标过滤允许 SECOND/THIRD/FOURTH。
|
|
84
|
+
标准主题的聚合输出维度和分析区内依赖指标过滤仅允许 SECOND;新增列维度仅允许 FIRST/SECOND。
|
|
85
|
+
聚合指标不支持手动调整;标准主题的未聚合指标(`.measure("字段")`)可选 FIRST/SECOND。
|
|
86
|
+
明细表仅支持 FIRST/SECOND。普通算子和 `.formula(...)` 均支持层级;每条条件提交后重置为 AUTO,
|
|
87
|
+
同一字段分组的条件须使用一致层级。层级不会替字段添加聚合或快速计算。
|
|
88
|
+
|
|
89
|
+
参考:[自助分析层级](https://help.fanruan.com/finebi/doc-view-2405.html)、
|
|
90
|
+
[维度调整规则](https://help.fanruan.com/finebi/doc-view-1609.html)、
|
|
91
|
+
[标准分析层级](https://help.fanruan.com/finebi/doc-view-2777.html)。
|
|
92
|
+
|
|
93
|
+
## 7. 配色上下文
|
|
94
|
+
|
|
95
|
+
| DSL API | 业务含义 |
|
|
96
|
+
|-------------------------|---------------|
|
|
97
|
+
| `.byField(fieldRef)` | 按某个字段自动拆分颜色。 |
|
|
98
|
+
| `.palette(["#E65251", "#3478F6"])` | 按顺序设置分类色板,必须是非空 `#RRGGBB` 数组。 |
|
|
99
|
+
| `.mapping({"值":"#颜色"})` | 为具体业务值指定固定颜色。 |
|
|
100
|
+
|
|
101
|
+
先在图表上下文用 `.color(DimRef)` 绑定分类字段,再用 `.color().palette([...])` / `.mapping({...})` 配色。
|
|
102
|
+
饼图、玫瑰图使用 x 分类,多指标图也可使用自动指标名称分类。mapping 键是显示分类值或指标显示名。
|
|
103
|
+
只写 mapping 时,按映射声明顺序形成备用色板;先 palette 再 mapping 可为未列出的分类保留独立备用色板。
|
|
104
|
+
再次 palette 会清除映射,再次 mapping 替换映射并保留当前色板;`.palette("名称")` 不是有效语法。
|
|
105
|
+
|
|
106
|
+
支持柱形/折线各家族、custom、radar、box、rangeArea、pie、rose、gauge、areaMap、pointMap、lineMap。
|
|
107
|
+
每个实际图形必须有维度颜色槽;指标渐变、多系列各自不同色板不在此入口范围。
|
|
108
|
+
表格使用 tableColor;point/bubble 使用已有 colors;其他图表的适用范围按各图表节。
|
|
109
|
+
DSL 回读保留分类绑定、色板和映射,自动主题色不输出显式 palette;无法保真的配色明确报错。
|
|
110
|
+
完整例子见 [§10.12 组件配色](widget-dsl-api-examples.md#1012-组件配色)。
|
|
111
|
+
|
|
112
|
+
## 8. 数值格式工厂
|
|
113
|
+
|
|
114
|
+
```js
|
|
115
|
+
NumberFormatModel.auto()
|
|
116
|
+
NumberFormatModel.auto(2, NumberFormatModelScale.THOUSAND, null, true)
|
|
117
|
+
NumberFormatModel.number(2)
|
|
118
|
+
NumberFormatModel.number(2, NumberFormatModelScale.TEN_THOUSAND, "元", true)
|
|
119
|
+
NumberFormatModel.percentage(1, true)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
| DSL API | 业务含义 |
|
|
123
|
+
|---------------------------------------------------------------------|--------------------|
|
|
124
|
+
| `NumberFormatModel.auto()` | 使用平台自动格式。 |
|
|
125
|
+
| `NumberFormatModel.auto(decimalPlaces, scale, unit, useGrouping)` | 自动精度并保留缩放、单位和千分位配置;decimalPlaces 可为 null,保存面板值但不强制固定小数位。 |
|
|
126
|
+
| `NumberFormatModel.number(decimalPlaces)` | 普通数值格式。 |
|
|
127
|
+
| `NumberFormatModel.number(decimalPlaces, scale, unit, useGrouping)` | 带缩放、单位和千分位控制的数值格式。 |
|
|
128
|
+
| `NumberFormatModel.percentage(decimalPlaces, useGrouping)` | 百分比格式。 |
|
|
129
|
+
|
|
130
|
+
`scale` 同时决定缩放与数量级单位,`unit` 是追加的单位文本。例如 `TEN_THOUSAND` + `"元"`
|
|
131
|
+
显示“万元”;只显示“万”时使用 `null`,不要重复填写 `"万"`。`number(2, ...)` 固定两位小数;
|
|
132
|
+
带参数的 `auto(...)` 保留自动精度。只有完全默认的 `auto()` 在回读时归一为未设置。
|
|
133
|
+
|
|
134
|
+
## 9. 可用枚举
|
|
135
|
+
|
|
136
|
+
| 枚举 | 可用值 |
|
|
137
|
+
|--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
138
|
+
| `SortOrder` | `SortOrder.ASC`, `SortOrder.DESC`, `SortOrder.asc`, `SortOrder.desc` |
|
|
139
|
+
| `QuickCalculationType` | `QuickCalculationType.NONE`, `QuickCalculationType.CURRENT_TARGET_PERCENT`, `QuickCalculationType.CURRENT_TARGET_PERCENT_IN_GROUP`, `QuickCalculationType.RANK_ASC`, `QuickCalculationType.RANK_DES`, `QuickCalculationType.RANK_IN_GROUP_ASC`, `QuickCalculationType.RANK_IN_GROUP_DES`, `QuickCalculationType.SUM_OF_ABOVE`, `QuickCalculationType.SUM_OF_ABOVE_IN_GROUP`, `QuickCalculationType.SUM_OF_ALL_SUM`, `QuickCalculationType.SUM_OF_ALL_AVG`, `QuickCalculationType.SUM_OF_ALL_MAX`, `QuickCalculationType.SUM_OF_ALL_MIN`, `QuickCalculationType.SUM_OF_ALL_IN_GROUP_SUM`, `QuickCalculationType.SUM_OF_ALL_IN_GROUP_AVG`, `QuickCalculationType.SUM_OF_ALL_IN_GROUP_MAX`, `QuickCalculationType.SUM_OF_ALL_IN_GROUP_MIN`, `QuickCalculationType.YEAR_ON_YEAR_VALUE_YEAR`, `QuickCalculationType.YEAR_ON_YEAR_VALUE_QUARTER`, `QuickCalculationType.YEAR_ON_YEAR_VALUE_MONTH`, `QuickCalculationType.YEAR_ON_YEAR_VALUE_WEEK`, `QuickCalculationType.YEAR_ON_YEAR_DIFFERENCE_YEAR`, `QuickCalculationType.YEAR_ON_YEAR_DIFFERENCE_QUARTER`, `QuickCalculationType.YEAR_ON_YEAR_DIFFERENCE_MONTH`, `QuickCalculationType.YEAR_ON_YEAR_DIFFERENCE_WEEK`, `QuickCalculationType.YEAR_ON_YEAR_RATE_YEAR`, `QuickCalculationType.YEAR_ON_YEAR_RATE_QUARTER`, `QuickCalculationType.YEAR_ON_YEAR_RATE_MONTH`, `QuickCalculationType.YEAR_ON_YEAR_RATE_WEEK`, `QuickCalculationType.MONTH_ON_MONTH_VALUE`, `QuickCalculationType.MONTH_ON_MONTH_DIFFERENCE`, `QuickCalculationType.MONTH_ON_MONTH_RATE` |
|
|
140
|
+
| `NumberFormatModelStyle` | `NumberFormatModelStyle.AUTO`, `NumberFormatModelStyle.NUMBER`, `NumberFormatModelStyle.PERCENTAGE` |
|
|
141
|
+
| `NumberFormatModelScale` | `NumberFormatModelScale.NORMAL`, `NumberFormatModelScale.THOUSAND`, `NumberFormatModelScale.TEN_THOUSAND`, `NumberFormatModelScale.MILLION`, `NumberFormatModelScale.HUNDRED_MILLION`, `NumberFormatModelScale.BILLION` |
|
|
142
|
+
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
# Widget DSL API:根入口、字段工厂与组件 Builder
|
|
2
|
+
|
|
3
|
+
> Widget DSL API 总导航见 [widget-dsl-api.md](widget-dsl-api.md)。
|
|
4
|
+
|
|
5
|
+
## 1. 根入口
|
|
6
|
+
|
|
7
|
+
### 分组表、交叉表合计行列
|
|
8
|
+
|
|
9
|
+
`table()` 支持 `totalRows(config)`;`crossTable()` 还支持 `totalColumns(config)`。
|
|
10
|
+
配置以 `TableTotal.rows()` / `TableTotal.columns()` 构建:
|
|
11
|
+
|
|
12
|
+
| 方法 | 语义 |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `position(TotalPosition.TOP/BOTTOM)` | 合计行位置,总合计与组内合计共用;默认 BOTTOM |
|
|
15
|
+
| `position(TotalPosition.LEFT/RIGHT)` | 合计列位置;默认 RIGHT |
|
|
16
|
+
| `grand(boolean)` | 总合计显隐,默认 true |
|
|
17
|
+
| `subtotal(boolean)` | 组内合计显隐,默认 false,与总合计独立 |
|
|
18
|
+
| `fields([DimRef, ...])` | 需要小计的已声明维度,默认空;必须属于对应行/列轴;隐藏小计时也保留选择 |
|
|
19
|
+
| `grandStyle(TotalStyle)` / `subtotalStyle(TotalStyle)` | 总合计/组内合计的显示名称、字体、背景色 |
|
|
20
|
+
| `build()` | 生成不可变配置 |
|
|
21
|
+
|
|
22
|
+
`TotalStyle.builder().name("总合计").background("#FF0000").build()`:空名称使用平台默认标题,空背景色跟随风格。
|
|
23
|
+
字体默认自动;`autoFont()` 显式恢复自动。自定义字体使用
|
|
24
|
+
`font(TotalFont.builder().family("Arial").size(14).color("#FFFFFF").bold(true).italic(false).underline(true).build())`。
|
|
25
|
+
字号必须为正整数;未指定字体名/字号/颜色时继承平台表身或主题样式,粗体/斜体/下划线默认 false。
|
|
26
|
+
|
|
27
|
+
`totalBy(MeasureRef, TotalCalculation.X)` 仅作用于已声明的表格指标,支持
|
|
28
|
+
`AUTO`、`SUM`、`AVERAGE`、`MAX`、`MIN`、`MEDIAN`、`VARIANCE`、`STANDARD_DEVIATION`、`HIDE`。
|
|
29
|
+
`AUTO` 按指标汇总方式计算明细数据,其他计算方式对分组后的结果再次计算;`HIDE` 隐藏该指标合计。
|
|
30
|
+
合计方式独立于指标原有 `sum/avg/...` 聚合,不通过修改指标聚合表达。
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
WidgetDsl.create("地区合计").chart().table()
|
|
34
|
+
.dimension(from("销售明细").dim("省份"))
|
|
35
|
+
.dimension(from("销售明细").dim("城市"))
|
|
36
|
+
.measure(from("销售明细").sum("合同金额"))
|
|
37
|
+
.totalRows(TableTotal.rows().position(TotalPosition.TOP).subtotal(true)
|
|
38
|
+
.fields([from("销售明细").dim("省份")])
|
|
39
|
+
.grandStyle(TotalStyle.builder().name("总合计").background("#FF0000").build())
|
|
40
|
+
.subtotalStyle(TotalStyle.builder().name("省份合计").background("#FFA500").build())
|
|
41
|
+
.build())
|
|
42
|
+
.totalBy(from("销售明细").sum("合同金额"), TotalCalculation.SUM)
|
|
43
|
+
.build();
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
合计配置为完整值对象,未填写的项采用上述默认值;未声明任何合计配置时保持组件构建默认行为。
|
|
47
|
+
合计能力不适用于明细表与图表;指标名称占位不属于可选小计维度。
|
|
48
|
+
同一字段/分组在多个位置复用同一内部维度时,共享小计选择,不能表达互相冲突的选择。
|
|
49
|
+
参考:[FineBI 合计行/列样式](https://help.fanruan.com/finebi/doc-view-1697.html)。
|
|
50
|
+
|
|
51
|
+
自定义组合图模板:`finebi-cli widget template --chart-type custom --scenario basic`。
|
|
52
|
+
x/y 轴可为空,可放维度或 `bar/point/heatMap/square/area/line/pie/text/map/funnel/gauge/box/sankey(measure)` 指标系列,也可混排;无最少指标数要求,支持转置。
|
|
53
|
+
绘图轴取指标更多的一轴,数量相同时取 y 轴。非绘图轴指标用不带独立图形或堆积配置的 `bar(measure)` 表示。
|
|
54
|
+
图表级五通道由全部系列继承,系列同名通道覆盖;多指标默认自动按指标名称着色。
|
|
55
|
+
`.stacked(true)` 仅用于组合图系列,默认不堆积。值轴沿用 `valueAxis` API。
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
WidgetDsl.create("组合图")
|
|
59
|
+
.chart().custom()
|
|
60
|
+
.x(from("销售明细").dim("销售日期"))
|
|
61
|
+
.y(bar(from("销售明细").sum("毛利额")).stacked(true))
|
|
62
|
+
.y(bar(from("销售明细").sum("商品单价")).stacked(true))
|
|
63
|
+
.y(line(from("销售明细").sum("销售金额")))
|
|
64
|
+
.build();
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`area(measure)` 可与柱形或折线混合;`lineConnect(field)` 仅放在线/面积系列,
|
|
68
|
+
其字段不能与分类轴相同。自定义图表属于内置组合图,不接收 ECharts 配置或任意渲染代码。
|
|
69
|
+
|
|
70
|
+
专用通道通过系列 fluent 方法配置,随 `widget dsl` 回读保留:
|
|
71
|
+
|
|
72
|
+
| 图形 | 专用方法 |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `point(m)` | `.symbol(field)` |
|
|
75
|
+
| `heatMap(m)` | `.heatColor(measure)` |
|
|
76
|
+
| `pie(m)` | `.pieAngle(measure)` |
|
|
77
|
+
| `text(m)` | `.textField(field)`,可多次调用 |
|
|
78
|
+
| `gauge(m)` | `.gaugePointer(measure)`(可多次)、`.gaugeMax(measure)`、`.gaugeType(GaugeType.POINT_GAUGE)` |
|
|
79
|
+
| `sankey(m)` | `.sankeyStart(field).sankeyEnd(field)` |
|
|
80
|
+
|
|
81
|
+
其余图形使用公共通道。专用通道只适用于表中图形;除文本与指针外每个专用通道最多一个字段。
|
|
82
|
+
仪表盘默认 `GaugeType.SLOT_GAUGE`,还支持 `RING_GAUGE/POINT_GAUGE/SEMI_POINT_GAUGE/V_THERMOMETER_GAUGE/H_THERMOMETER_GAUGE`。
|
|
83
|
+
自定义图表中的 `box(m)` 不要求基础箱型图入口的轴布局,但不支持 `.stacked(true)`。
|
|
84
|
+
|
|
85
|
+
`widget template` 的 `basic` 支持的图表包括 `seriesLine`、`ROSE`、`MULTI_PIE`、`bubble`。`seriesLine` 使用 `dimensionField` 分类轴、指标求和折线和 `seriesField` 颜色;`ROSE` 使用 `dimensionField` 分类,数值字段 `measureField` 求和后同时绑定角度与半径;`MULTI_PIE` 使用 `dimensionField` 颜色、指标求和大小和必填 `granularityField` 粒度,不配置 x/y 或 tooltip;`bubble` 使用 `dimensionField` 颜色分组和 `measureField` 求和大小,不配置 x/y。公共变量为 `widgetName`、`tableName`、数值字段 `measureField`,变量按 JSON 字面量替换。
|
|
86
|
+
|
|
87
|
+
`LINE basic` 使用 `dateField`(DATE/DATE_TIME,默认年月日)和两个不同的数值字段 `measureField1`、`measureField2`,分别以 `sum` 绘制上下分区折线。多指标自动按指标名称着色并生成图例;颜色由转换器绑定到各指标图形,不在“全部”卡片显式绑定。`widgetName`、`tableName` 为公共变量;仍编译为 `sliceLine`,既有输入别名保持兼容。
|
|
88
|
+
|
|
89
|
+
基础箱型图使用 `.chart().box()` 和 `box(指标)`:
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
WidgetDsl.create("各省城市销量分布")
|
|
93
|
+
.chart().box()
|
|
94
|
+
.x(from("销量表").dim("省份"))
|
|
95
|
+
.y(box(from("销量表").sum("销量"))
|
|
96
|
+
.granularity(from("销量表").dim("城市"))
|
|
97
|
+
.color(from("销量表").dim("省份")))
|
|
98
|
+
.build()
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`box(measure)` 表达绘图指标,不是预计算的五个统计值。上例按城市汇总销量,再计算各省城市销量的分布。
|
|
102
|
+
支持交换 x/y 的横向布局,以及省略分类轴、只配置细粒度的整体分布。恰好一个 BOX 指标,指标轴不能混入维度;
|
|
103
|
+
分类轴或有效颜色、细粒度、提示通道至少有一个真实维度。自动指标名称不算真实维度。
|
|
104
|
+
支持图表级及 Series 级 `color`、`granularity`、`tooltipField`,Series 非空配置覆盖图表级配置;
|
|
105
|
+
复用现有字段绑定 `size`,不新增固定箱宽设置。标签、连线与混合 mark 不支持。
|
|
106
|
+
没有细粒度时不自动补字段,箱体可能退化;异常点组合图、异常点开关和统计参数不在当前支持范围内。
|
|
107
|
+
箱体及箱须由 FineBI 原生计算,箱宽和透明度采用原生默认值。字段和表名必须替换成已核实的资源。
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
WidgetDsl.create("组件名")
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
业务含义:
|
|
114
|
+
|
|
115
|
+
- 新建一个单组件 Builder。
|
|
116
|
+
- 组件名是后续保存、挂载到仪表板、联动和跳转时使用的业务名。
|
|
117
|
+
|
|
118
|
+
## 2. 字段与指标工厂
|
|
119
|
+
|
|
120
|
+
文本字段先通过 `geographic-role set` 设置国家/省份/城市/区县角色,再在组件中使用
|
|
121
|
+
`from("客户维度表").dim("省份").longitude()` 或 `.latitude()`。方向不能与其他维度分组叠加,
|
|
122
|
+
`widget dsl` 回读会保留方向。数值经纬度角色在字段级设置,组件仍用普通指标引用及显式聚合。
|
|
123
|
+
`measureID("配置ID").measure()` 表示不附聚合的计算字段,用于字段角色配置;组件展示计算指标仍用 `.sum()`。
|
|
124
|
+
完整的字段角色 DSL、匹配流程和组件引用示例见 §2.6。地理角色不包含自定义图片;字段角色设置和地图组件创建是独立操作。
|
|
125
|
+
|
|
126
|
+
物理字段使用 source-scoped 写法,模型指标集字段使用 model-scoped 写法:
|
|
127
|
+
|
|
128
|
+
```js
|
|
129
|
+
from("销售表").dim("地区")
|
|
130
|
+
from("销售表").sum("销售额")
|
|
131
|
+
from("销售表").measure("销售额")
|
|
132
|
+
from("销售表").count()
|
|
133
|
+
model("销售指标集").dataset("订单明细").dim("地区")
|
|
134
|
+
model("销售指标集").metrics().sum("销售额")
|
|
135
|
+
quickCalculation(from("销售表").sum("销售额"), QuickCalculationType.RANK_ASC)
|
|
136
|
+
|
|
137
|
+
// 标准分析主题移动计算:作用于指标聚合结果集
|
|
138
|
+
windowCalculation(
|
|
139
|
+
from("销售表").sum("销售额"),
|
|
140
|
+
WindowCalculationModel.of(0, 0, 0,
|
|
141
|
+
WindowCalculationModel.row(
|
|
142
|
+
WindowCalculationModel.preceding(1), WindowCalculationModel.following(0))))
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`windowCalculation(measure, configuration)` 是全局函数;`WindowCalculationModel` 是窗口配置命名空间。
|
|
146
|
+
仅标准分析主题可使用移动计算;自助分析主题会在保存前报错,此限制同样适用于记录数和隐藏通道。
|
|
147
|
+
组件形态需与设计器可达面一致,否则报错:组件至少要有一个维度;`calculateType` 组内要求
|
|
148
|
+
表格某一轴(行/列)或图表多于一个维度;图表方向只能是 `0`(向下,设计器仅提供「默认」);
|
|
149
|
+
表格方向按行/列区维度开放——`1` 向右需要列维度,`2`/`3` 组合方向要求行、列维度都有,
|
|
150
|
+
且至少要有一个维度。上述例子计算前一行与当前行的合计。计算作用于组件聚合后的结果行;
|
|
151
|
+
窗口顺序取决于组件排序,按日期移动时应使用日期维度并核对排序与出数。
|
|
152
|
+
原指标可另放一列,逐行核对窗口计算值。
|
|
153
|
+
|
|
154
|
+
| `WindowCalculationModel.of` 参数 | 可用值 |
|
|
155
|
+
|---|---|
|
|
156
|
+
| `function` | `0` 求和、`1` 平均、`2` 最大、`3` 最小、`4` 方差、`5` 标准差 |
|
|
157
|
+
| `calculateType` | `0` 全表、`1` 组内 |
|
|
158
|
+
| `direction` | `0` 向下、`1` 向右、`2` 先向下后向右、`3` 先向右后向下 |
|
|
159
|
+
| `frame` | `WindowCalculationModel.row(start, end)`,仅支持按行窗口 |
|
|
160
|
+
|
|
161
|
+
边界使用 `WindowCalculationModel.first()` / `.last()` / `.preceding(n)` / `.following(n)`;
|
|
162
|
+
`n` 为非负整数,`preceding(0)` 和 `following(0)` 均表示当前行,起点不能在终点之后。
|
|
163
|
+
模型字段沿用 `model("模型").dataset("表").sum("金额")`,计算字段沿用 `measureID("配置ID").sum()`,
|
|
164
|
+
记录数沿用 `from("表").count()`;包装移动计算保留字段来源和别名。
|
|
165
|
+
使用专用 `windowCalculation(...)` 传入完整配置,不能用裸 `quickCalculation(..., QuickCalculationType.WINDOW_CALCULATION)`。
|
|
166
|
+
回读 DSL 保留函数、范围、方向和边界;不支持的范围窗口会明确报错。
|
|
167
|
+
同一组件内,同一实际字段和聚合方式只能使用一套窗口配置;相同配置可重复引用,
|
|
168
|
+
不同配置会报冲突(包括记录数及隐藏通道)。需要并列不同窗口时,使用独立复制字段;
|
|
169
|
+
排序、数字格式、分析线和值轴的目标引用须携带与指标一致的完整窗口配置。
|
|
170
|
+
|
|
171
|
+
`from("名称")` 与 `model("名称")` 是不同字段身份,即使同名也不能互换。模型名和字段名必须来自
|
|
172
|
+
已确认的当前主题模型证据;模型级只提供指标,模型表字段和模型计算字段分别进入 `dataset(...)` 与 `calculated()` 子命名空间。
|
|
173
|
+
模型表字段必须写数据集限定符 `model("模型").dataset("数据集").dim/sum(...)`;模型计算字段使用 `model("模型").calculated().dim/sum(...)`。同一作用域内字段展示名重复时返回 `BLOCKED`,不能猜测来源。
|
|
174
|
+
|
|
175
|
+
### 2.1 维度字段
|
|
176
|
+
|
|
177
|
+
| DSL API | 业务含义 |
|
|
178
|
+
|---|---|
|
|
179
|
+
| `from("来源表").dim("字段名")` | 默认分组维度,用于地区、月份、产品、客户、订单号等分组或分类信息。 |
|
|
180
|
+
| `from("来源表").dim("字段名", null, "别名")` | 使用默认分组并指定展示名。 |
|
|
181
|
+
| `from("来源表").dim("字段名", grouping)` | 使用日期、文本或数值自定义分组。 |
|
|
182
|
+
| `from("来源表").dim("字段名", grouping, "别名")` | 同时指定分组和展示名。 |
|
|
183
|
+
| `measureID("配置 ID").dim()` | 已保存计算字段使用默认分组。 |
|
|
184
|
+
| `measureID("配置 ID").dim(grouping)` | 已保存计算字段使用与字段类型兼容的显式分组;不支持别名。 |
|
|
185
|
+
| `....hidden()` | 关闭展示字段:维度仍绑定进轴、保留槽位,查看态不展示(`used=false`);可叠加在上述任意维度形态之后,与分组/别名/经纬度组合。 |
|
|
186
|
+
|
|
187
|
+
分组使用以下稳定语法:
|
|
188
|
+
|
|
189
|
+
物理数值字段作维度时,主题 measure 池里必须先有该字段的**已注册副本**(`finebi-cli measure copy --subject-id <S> --field-id <F> --as dimension`,副本名为“原显示名 + 递增序号”,例如“购买的产品1”)。组件命令只复用已注册副本、不隐式注册:缺副本时 `widget add/update/data` 报 `UNSUPPORTED_FEATURE`,`nextActions` 直接给出该 copy 命令,执行后重跑组件命令即可。DSL 始终引用原字段名;导出通过副本的 `source` 还原原字段引用,并保留组件显示别名与分组。
|
|
190
|
+
|
|
191
|
+
```js
|
|
192
|
+
// 日期:默认 YEAR_MONTH_DAY 应省略 grouping;非默认粒度显式声明
|
|
193
|
+
DimensionGrouping.dateGranularity("YEAR_MONTH")
|
|
194
|
+
|
|
195
|
+
// 数值维度·相同值为一组:每个原始值自成一组(设计器数值维度菜单的「相同值为一组」)
|
|
196
|
+
DimensionGrouping.numberSameValues()
|
|
197
|
+
|
|
198
|
+
// 数值维度·区间分组:连续边界,至少两个有限数且严格递增;整数、长整数、小数都可直接写
|
|
199
|
+
DimensionGrouping.numberIntervals(0, 100, 500)
|
|
200
|
+
|
|
201
|
+
// 文本维度:值必须是非 null 字符串,同一原始值只能属于一个命名组
|
|
202
|
+
DimensionGrouping.textGroups([
|
|
203
|
+
DimensionGrouping.textGroup("华东", ["上海", "江苏"]),
|
|
204
|
+
DimensionGrouping.textGroup("华南", ["广东", "广西"])
|
|
205
|
+
], "其他")
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
`textGroups(groups)` 可省略其他组名。数值维度两种分组择一:`numberSameValues()`(相同值为一组,
|
|
209
|
+
落 `group.type=ID_GROUP`)与 `numberIntervals(...)`(区间分组,落 `group.type=NUMBER_GROUP` + 区间负载);
|
|
210
|
+
转维度副本(`TRANSFORM_FROM_NUMBER`)不写 grouping 时默认**区间分组**(与设计器默认一致),明细表的原始
|
|
211
|
+
数值列默认相同值为一组。默认日期 YMD、文本相同值分组和明细表裸数值相同值分组都不要
|
|
212
|
+
显式生成 grouping。`widget dsl` 的规范化输出会保留分组/值顺序,数值边界使用无指数十进制,
|
|
213
|
+
并把 `-0.0` 写成 `0.0`。reader 会消费的文本 CUSTOM_GROUP / 数值 NUMBER_GROUP direct holder
|
|
214
|
+
必须完整恢复,否则返回错误,不会退化成普通维度。reader 不消费的 direct holder(无匹配维度的
|
|
215
|
+
孤立载荷、默认文本 ID_GROUP / 默认日期 YMD 维度旁的 stray customGroup)会作为 warning 返回;
|
|
216
|
+
`cal[*]` 嵌套 customGroup 始终 warning。
|
|
217
|
+
|
|
218
|
+
`.hidden()` 对应设计器"展示字段"开关,回读保留(输出为维度表达式末尾的 `.hidden()` 后缀)。
|
|
219
|
+
仅视图轴绑定的维度生效:filter 字段、钻取层级、迷你图依赖、KPI 通道等非展示面引用带
|
|
220
|
+
`.hidden()` 会报错或无效果(KPI 通道维度明确拒绝)。同一字段在同一组件内多处引用须保持
|
|
221
|
+
一致 hidden 状态,否则保存报错——明细表例外:同字段多列按列独立生效,可一列隐藏一列展示;
|
|
222
|
+
分类轴(`categoryAxis`)目标引用须重复携带一致的 `.hidden()` 后缀才能命中轴上维度。
|
|
223
|
+
指标名维度(`metricNameInRow/InCol` 与自动指标名)不支持隐藏,设计器侧关闭时回读会以
|
|
224
|
+
warning 留痕。
|
|
225
|
+
|
|
226
|
+
### 2.2 聚合指标
|
|
227
|
+
|
|
228
|
+
| DSL API | 业务含义 |
|
|
229
|
+
|--------------------------------------------|---------------------------------------|
|
|
230
|
+
| `from("来源表").sum("字段名")` | 求和指标,适合销售额、利润、数量等可累计数据。 |
|
|
231
|
+
| `from("来源表").sum("字段名", "别名")` | 求和指标,并指定展示名,适合同字段多次使用时区分口径。 |
|
|
232
|
+
| `from("来源表").avg("字段名")` | 平均值指标,适合客单价、平均折扣率等场景。 |
|
|
233
|
+
| `from("来源表").avg("字段名", "别名")` | 平均值指标,并指定展示名。 |
|
|
234
|
+
| `from("来源表").max("字段名")` | 最大值指标,适合峰值展示。 |
|
|
235
|
+
| `from("来源表").max("字段名", "别名")` | 最大值指标,并指定展示名。 |
|
|
236
|
+
| `from("来源表").min("字段名")` | 最小值指标,适合谷值展示。 |
|
|
237
|
+
| `from("来源表").min("字段名", "别名")` | 最小值指标,并指定展示名。 |
|
|
238
|
+
| `from("来源表").measure("字段名")` | 原值指标,不做聚合,仅适合在非明细表过滤中表达“按字段原始值参与计算”。 |
|
|
239
|
+
| `from("来源表").measure("字段名", "聚合方式", "别名")` | 自定义聚合指标,适合平台支持但没有 sugar 方法的聚合方式。 |
|
|
240
|
+
| `from("来源表").countDistinct("字段名")` | 字段去重计数(如去重客户数)。只支持文本/日期字段,且该字段须先用 `measure transform --as measure` 转成指标形态。 |
|
|
241
|
+
| `from("来源表").countDistinct("字段名", "别名")` | 字段去重计数,并指定展示名。 |
|
|
242
|
+
| `measureID("配置 ID").countDistinct()` | 已保存计算字段按配置 ID 去重计数;形态要求同上,且公式不得引用聚合形态字段(平台会再包一层去重计数而报聚合嵌套聚合,组件命令直接拒绝)。 |
|
|
243
|
+
|
|
244
|
+
主题内已保存的计算字段作为组件指标时必须使用 `measureID("配置 ID").sum()`;作为维度时使用
|
|
245
|
+
`measureID("配置 ID").dim()`;显式数值区间可写为
|
|
246
|
+
`measureID("配置 ID").dim(DimensionGrouping.numberIntervals(0, 100, 500))`。数值计算字段生成指标转维度字段,
|
|
247
|
+
文本和日期计算字段直接绑定;grouping 与字段类型不兼容时保存失败。计算字段的配置 ID 必须属于当前主题,
|
|
248
|
+
不能用实际 `fieldId` 或名称替代;配置 ID 从 `measure search/info` 响应条目的 `measureId` 字段获取
|
|
249
|
+
(条目的 `id` 是实际字段 ID,不能填进 `measureID()`)。
|
|
250
|
+
|
|
251
|
+
### 2.3 记录数
|
|
252
|
+
|
|
253
|
+
| DSL API | 业务含义 |
|
|
254
|
+
|---------------------------------|-----------------------|
|
|
255
|
+
| `from("来源表").count()` | 当前分组范围内的记录数;存在唯一分组维度时按该维度统计,否则统计总行数。 |
|
|
256
|
+
| `from("来源表").count("别名")` | 当前分组范围内的记录数,并指定展示名。 |
|
|
257
|
+
|
|
258
|
+
模型级指标必须进入 `metrics()` 子命名空间;模型指标集不提供根级维度或记录数。按字段去重计数的
|
|
259
|
+
指标(`countDistinct`)见 §2.2,不属于记录数。
|
|
260
|
+
|
|
261
|
+
### 2.4 快速计算
|
|
262
|
+
|
|
263
|
+
| DSL API | 业务含义 |
|
|
264
|
+
|--------------------------------------------------------------------------------|---------------------------------|
|
|
265
|
+
| `quickCalculation(measureRef, QuickCalculationType.xxx)` | 基于已有指标派生快速计算指标,如排名、占比、累计、同比、环比。 |
|
|
266
|
+
| `quickCalculation(measureRef, QuickCalculationType.xxx, secondaryCalculation)` | 在快速计算基础上显式指定二次计算开关。 |
|
|
267
|
+
|
|
268
|
+
常见业务语义:
|
|
269
|
+
|
|
270
|
+
- `QuickCalculationType.RANK_ASC`、`QuickCalculationType.RANK_DES`:排名
|
|
271
|
+
- `QuickCalculationType.CURRENT_TARGET_PERCENT`:当前值占比
|
|
272
|
+
- `QuickCalculationType.SUM_OF_ABOVE`:累计值
|
|
273
|
+
- `QuickCalculationType.YEAR_ON_YEAR_*`:同比
|
|
274
|
+
- `QuickCalculationType.MONTH_ON_MONTH_*`:环比
|
|
275
|
+
|
|
276
|
+
### 2.5 主题共享钻取目录
|
|
277
|
+
|
|
278
|
+
主题共享钻取目录使用独立命令 `drill-directory update --subject-id <id> --file <directory.js>`:
|
|
279
|
+
|
|
280
|
+
```javascript
|
|
281
|
+
DrillDirectoryModel.builder("地区")
|
|
282
|
+
.levels([from("销售原表").dim("省"), from("销售原表").dim("市")])
|
|
283
|
+
.build()
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
解散用 `DrillDirectoryModel.builder("地区").dissolve().build()`,保留原字段及其他配置。`drill-directory dsl --subject-id <id> --name "地区"` 回读目录。层级至少一个,必须为同引擎维度且无分组/别名;支持物理 `from`、模型数据集 `model(...).dataset(...).dim(...)` 和已保存计算维度 `measureID(...).dim()`。同名不同层级或字段属于其他目录时拒绝写入。目录独立于组件 DSL,普通多行维度不等于创建目录。
|
|
287
|
+
|
|
288
|
+
### 2.6 地理角色字段与经纬度引用
|
|
289
|
+
|
|
290
|
+
地理角色是当前主题内已有字段的共享语义配置,不创建物理字段。先用独立的
|
|
291
|
+
`GeographicRole(...)` DSL 配置字段,再用 `WidgetDsl.create(...)` 引用;不要把 `.level()`、
|
|
292
|
+
`.within()` 或 `.role()` 接到 Widget Builder 或 `dim(...)` 后,也不要在组件保存时隐式修改共享字段。
|
|
293
|
+
|
|
294
|
+
| 字段类型 / 用途 | DSL 写法 |
|
|
295
|
+
|---|---|
|
|
296
|
+
| 文本国家、省份、城市、区县 | `GeographicRole(from("表").dim("字段")).level(NATION / PROVINCE / CITY / DISTRICT)`,四个常量择一 |
|
|
297
|
+
| 限定文本角色的上级区域 | `.within(NATION, "国家完整路径")`,更细范围可追加 `.within(PROVINCE, "省份完整路径")`、`.within(CITY, "城市完整路径")` |
|
|
298
|
+
| 自动匹配 | `.autoMatch()`;没有人工覆盖的值继续按平台规则动态匹配 |
|
|
299
|
+
| 人工修正某个原始值 | `.match("原始值", "目标区域完整路径")` |
|
|
300
|
+
| 禁止某个原始值参与匹配 | `.unmatch("原始值")`,不能写成 `.match("原始值", null)` |
|
|
301
|
+
| 数值经度 / 纬度 | `GeographicRole(from("表").measure("字段")).role(LONGITUDE / LATITUDE)`,两个常量择一 |
|
|
302
|
+
| 清除已有角色 | `GeographicRole(from("表").dim("字段")).clear().build()`;数值字段目标使用 `.measure("字段")` |
|
|
303
|
+
|
|
304
|
+
每份字段角色 DSL 以 `.build()` 结束。文本 `.level(...)`、数值 `.role(...)`、`.clear()` 三种模式互斥;
|
|
305
|
+
数值角色不能附加 `within/autoMatch/match/unmatch`。同一级 `within` 或同一原始值的人工覆盖不能重复声明。
|
|
306
|
+
`within` 必须是目标层级的祖先,多个范围必须处于同一祖先链;`match` 的目标必须符合角色层级与范围。
|
|
307
|
+
|
|
308
|
+
**文本省份示例**(保存为独立的 `province-role.dsl`):
|
|
309
|
+
|
|
310
|
+
```js
|
|
311
|
+
GeographicRole(from("客户维度表").dim("省份"))
|
|
312
|
+
.level(PROVINCE)
|
|
313
|
+
.within(NATION, "assets/map/geographic/world/中国")
|
|
314
|
+
.autoMatch()
|
|
315
|
+
.match("江苏", "assets/map/geographic/world/中国/江苏省")
|
|
316
|
+
.unmatch("未知")
|
|
317
|
+
.build();
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
表名、字段名和区域路径都必须替换为当前环境已核实的资源。先查询 `geographic-role catalog --level NATION`,
|
|
321
|
+
再用返回的国家完整路径查询 `geographic-role catalog --level PROVINCE --parent-path <国家完整路径>`;
|
|
322
|
+
城市、区县同理逐级查询。不要仅凭中文名称拼接路径。国家角色用 `.level(NATION).autoMatch()`,无需国家范围;
|
|
323
|
+
省份及更细角色省略 `within` 时,仅在平台目录含唯一国家时自动选取。城市、区县可以只限定国家,不强制填满每一级。
|
|
324
|
+
|
|
325
|
+
按以下顺序使用命令(参数编码以当前 capability 和动态 `--help` 为准):
|
|
326
|
+
|
|
327
|
+
1. 修改已有角色前,执行 `geographic-role dsl --subject-id <主题ID> --field-id <字段ID>` 读取完整配置。
|
|
328
|
+
2. 用 `geographic-role match --subject-id <主题ID> --file <角色DSL路径> --values '["上海","江苏","未知"]'` 预览匹配,不保存。
|
|
329
|
+
3. 用 `geographic-role set --subject-id <主题ID> --file <角色DSL路径>` 保存;该操作整份替换这个字段的地理配置,必须保留仍需要的人工覆盖。
|
|
330
|
+
4. 用 `geographic-role info` / `geographic-role dsl`,携带 `--subject-id` 和返回的 `fieldId` 回读核对。
|
|
331
|
+
|
|
332
|
+
`match` 只检查显式提供的 1..200 个值,`complete=true` 不表示扫描了整列。
|
|
333
|
+
人工覆盖是稀疏配置:未出现的原始值继续自动匹配,`unmatch` 禁止该值匹配;`autoMatch()` 不会把预览结果固化为人工映射。
|
|
334
|
+
取消角色也可使用 `geographic-role clear --subject-id <主题ID> --field-id <字段ID>`,保留字段;
|
|
335
|
+
仍有组件经纬度引用时会拒绝清除并返回依赖组件 ID。
|
|
336
|
+
|
|
337
|
+
**数值经纬度示例**(每行分别保存为一份角色 DSL):
|
|
338
|
+
|
|
339
|
+
```js
|
|
340
|
+
GeographicRole(from("门店表").measure("经度")).role(LONGITUDE).build();
|
|
341
|
+
GeographicRole(from("门店表").measure("纬度")).role(LATITUDE).build();
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
角色目标使用不带聚合的 `.measure(...)`;组件展示数值坐标时仍使用普通指标引用及符合业务粒度的显式聚合。
|
|
345
|
+
主题计算字段目标使用 `measureID("配置ID").dim()` 或 `.measure()`;模型字段沿用
|
|
346
|
+
`model("模型").dataset("数据集").dim()/measure()` 等已有作用域。配置只保存到当前主题,不修改业务模型源定义。
|
|
347
|
+
命令回读区分源 `fieldId` 和配置 `measureId`,计算字段引用不能把二者混用。
|
|
348
|
+
|
|
349
|
+
**组件引用示例**(字段角色已保存后,作为独立的 Widget DSL):
|
|
350
|
+
|
|
351
|
+
```js
|
|
352
|
+
WidgetDsl.create("省份坐标引用").chart().table()
|
|
353
|
+
.dimension(from("客户维度表").dim("省份").longitude())
|
|
354
|
+
.dimension(from("客户维度表").dim("省份").latitude())
|
|
355
|
+
.build();
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
同一文本地理字段通过 `.longitude()` / `.latitude()` 派生两个坐标方向;
|
|
359
|
+
裸 `.dim("省份")` 仍表示原始省份分组。方向不能与日期分组、文本自定义分组或数值区间分组叠加。
|
|
360
|
+
`widget info` 的 slot 以 `coordinate=LONGITUDE/LATITUDE` 表达方向,`widget dsl` 回读保留这两个方法。
|
|
361
|
+
地图组件也可将这两个引用分别绑定到 `.x(...)` / `.y(...)`;创建图表本身不能替代上述字段角色配置。
|
|
362
|
+
|
|
363
|
+
## 3. 组件 Builder
|
|
364
|
+
|
|
365
|
+
| DSL API | 业务含义 |
|
|
366
|
+
|---------------------------|---------------------------------|
|
|
367
|
+
| `.chart()` | 进入图表上下文,定义图表类型、编码槽位、视觉通道、排序和格式。 |
|
|
368
|
+
| `.filter()` | 进入过滤上下文,给当前组件附加查询过滤条件。 |
|
|
369
|
+
| `.color()` | 进入组件配色上下文,定义整体色板或业务值到颜色的映射。 |
|
|
370
|
+
| `.addDimension(dimRef)` | 直接把维度追加到组件的维度区,适合简单表格或快速补充分组字段。 |
|
|
371
|
+
| `.addMeasure(measureRef)` | 直接把指标追加到组件的指标区。 |
|
|
372
|
+
| `.build()` | 冻结当前定义,生成不可变 `WidgetModel`。 |
|
|
373
|
+
| `.buildWidget()` | `build()` 的兼容别名。 |
|
|
374
|
+
|