@finebi/finebi-cli 1.5.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.
Files changed (98) hide show
  1. package/README.md +10 -0
  2. package/package.json +4 -3
  3. package/skills/finebi-cli-agent/SKILL.md +8 -4
  4. package/skills/finebi-cli-agent/references/command-workflows.md +7 -3
  5. package/skills/finebi-cli-agent/references/dashboard-data-result.md +191 -191
  6. package/skills/finebi-cli-agent/references/dashboard-dsl-api.md +8 -1018
  7. package/skills/finebi-cli-agent/references/dashboard-dsl-core.md +194 -0
  8. package/skills/finebi-cli-agent/references/dashboard-dsl-examples.md +378 -0
  9. package/skills/finebi-cli-agent/references/dashboard-dsl-items.md +456 -0
  10. package/skills/finebi-cli-agent/references/mapping-rules.md +14 -14
  11. package/skills/finebi-cli-agent/references/scenario-workflows.md +1 -1
  12. package/skills/finebi-cli-agent/references/web-app.md +13 -0
  13. package/skills/finebi-cli-agent/references/widget-dsl-api-examples.md +3 -4
  14. package/skills/finebi-cli-agent/references/widget-dsl-api.md +10 -1374
  15. package/skills/finebi-cli-agent/references/widget-dsl-contexts.md +142 -0
  16. package/skills/finebi-cli-agent/references/widget-dsl-core.md +374 -0
  17. package/skills/finebi-cli-agent/references/widget-dsl-encodings.md +457 -0
  18. package/skills/finebi-cli-agent/references/widget-dsl-styles.md +413 -0
  19. package/skills/finebi-cli-agent/scripts/finebi-cli/package.json +1 -1
  20. package/skills/finebi-cli-agent/scripts/finebi-cli/src/app.js +189 -0
  21. package/skills/finebi-cli-agent/scripts/finebi-cli/src/config.js +27 -27
  22. package/skills/finebi-cli-agent/scripts/finebi-cli/src/help.js +78 -55
  23. package/skills/finebi-cli-agent/scripts/finebi-cli/src/index.js +5 -0
  24. package/skills/finebi-cli-agent/scripts/finebi-cli/src/install-skill.js +89 -89
  25. package/skills/finebi-cli-agent/scripts/finebi-cli/src/profiles.js +158 -158
  26. package/skills/finebi-cli-agent/scripts/finebi-cli/src/skill-files.js +94 -94
  27. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/AGENTS.md +27 -0
  28. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/README.md +30 -0
  29. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/docs/auth-and-deploy.md +17 -0
  30. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/docs/data-contract.md +21 -0
  31. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/docs/design.md +13 -0
  32. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/docs/filters.md +89 -0
  33. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/index.html +2 -0
  34. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/package-lock.json +2191 -0
  35. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/package.json +15 -0
  36. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/public/app-config.json +11 -0
  37. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/scripts/dev-proxy.mjs +56 -0
  38. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/App.tsx +31 -0
  39. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/components/Chart.tsx +31 -0
  40. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/components/DataTable.tsx +14 -0
  41. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/components/FilterBar.tsx +42 -0
  42. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/components/Widget.tsx +28 -0
  43. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/components/calendar.ts +14 -0
  44. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/client.ts +37 -0
  45. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/date.d.ts +1 -0
  46. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/date.js +5 -0
  47. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/filters.d.ts +4 -0
  48. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/filters.js +106 -0
  49. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/normalize.ts +77 -0
  50. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/finebi/types.ts +18 -0
  51. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/main.tsx +5 -0
  52. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/services/view-data.ts +18 -0
  53. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/src/styles.css +8 -0
  54. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tests/calendar.test.mjs +25 -0
  55. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tests/proxy.test.mjs +84 -0
  56. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tests/runtime.test.mjs +136 -0
  57. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/tsconfig.json +4 -0
  58. package/skills/finebi-cli-agent/scripts/finebi-cli/templates/web-app/vite.config.ts +13 -0
  59. package/skills/finebi-cli-agent/scripts/finebi-cli-runner.mjs +4 -4
  60. package/src/app.js +189 -0
  61. package/src/config.js +27 -27
  62. package/src/help.js +78 -55
  63. package/src/index.js +5 -0
  64. package/src/install-skill.js +89 -89
  65. package/src/profiles.js +158 -158
  66. package/src/skill-files.js +94 -94
  67. package/templates/web-app/AGENTS.md +27 -0
  68. package/templates/web-app/README.md +30 -0
  69. package/templates/web-app/docs/auth-and-deploy.md +17 -0
  70. package/templates/web-app/docs/data-contract.md +21 -0
  71. package/templates/web-app/docs/design.md +13 -0
  72. package/templates/web-app/docs/filters.md +89 -0
  73. package/templates/web-app/index.html +2 -0
  74. package/templates/web-app/package-lock.json +2191 -0
  75. package/templates/web-app/package.json +15 -0
  76. package/templates/web-app/public/app-config.json +11 -0
  77. package/templates/web-app/scripts/dev-proxy.mjs +56 -0
  78. package/templates/web-app/src/App.tsx +31 -0
  79. package/templates/web-app/src/components/Chart.tsx +31 -0
  80. package/templates/web-app/src/components/DataTable.tsx +14 -0
  81. package/templates/web-app/src/components/FilterBar.tsx +42 -0
  82. package/templates/web-app/src/components/Widget.tsx +28 -0
  83. package/templates/web-app/src/components/calendar.ts +14 -0
  84. package/templates/web-app/src/finebi/client.ts +37 -0
  85. package/templates/web-app/src/finebi/date.d.ts +1 -0
  86. package/templates/web-app/src/finebi/date.js +5 -0
  87. package/templates/web-app/src/finebi/filters.d.ts +4 -0
  88. package/templates/web-app/src/finebi/filters.js +106 -0
  89. package/templates/web-app/src/finebi/normalize.ts +77 -0
  90. package/templates/web-app/src/finebi/types.ts +18 -0
  91. package/templates/web-app/src/main.tsx +5 -0
  92. package/templates/web-app/src/services/view-data.ts +18 -0
  93. package/templates/web-app/src/styles.css +8 -0
  94. package/templates/web-app/tests/calendar.test.mjs +25 -0
  95. package/templates/web-app/tests/proxy.test.mjs +84 -0
  96. package/templates/web-app/tests/runtime.test.mjs +136 -0
  97. package/templates/web-app/tsconfig.json +4 -0
  98. package/templates/web-app/vite.config.ts +13 -0
@@ -0,0 +1,194 @@
1
+ # Dashboard DSL API:根入口、布局与移动端
2
+
3
+ > Dashboard DSL API 总导航见 [dashboard-dsl-api.md](dashboard-dsl-api.md)。
4
+
5
+ ## 1. 根入口
6
+
7
+ 嵌入的数据图表沿用 [Widget DSL API §4.7.2](widget-dsl-styles.md#472-值轴与双-y-轴) 的
8
+ `.valueAxis(measureRef, ValueAxis.builder()...build())`,无需 Dashboard 专属双轴开关。
9
+ `dashboard dsl` 可回读支持的值轴设置;替换更新应保留导出的完整组件 DSL,
10
+ 遇到不能表达的有效轴公式或样式时先处理明确报错,不删除设置后强行更新。
11
+
12
+ ```js
13
+ DashboardDsl.create("仪表板名")
14
+ ```
15
+
16
+ 业务含义:
17
+
18
+ - 新建一个仪表板 Builder。
19
+ - 仪表板负责组织组件、控件、文本、布局、样式和移动端配置。
20
+
21
+ ## 2. 顶层 Builder
22
+
23
+ | DSL API | 业务含义 |
24
+ |-------------------|-----------------------------|
25
+ | `.content()` | 进入内容域,定义仪表板上有哪些条目。 |
26
+ | `.presentation()` | 进入布局与样式域,定义条目如何摆放、整板采用什么风格。 |
27
+ | `.mobile()` | 进入移动端域,定义移动端展示顺序。 |
28
+ | `.build()` | 结束编排,生成 `ReportModel`。 |
29
+
30
+ ## 3. 内容域
31
+
32
+ ### 3.1 条目挂载
33
+
34
+ | DSL API | 业务含义 |
35
+ |---------------------------|-----------------------|
36
+ | `.reference("已有组件名")` | 引用已有数据组件,不在当前脚本内重新定义。 |
37
+ | `.control(controlItem)` | 挂载一个筛选控件。 |
38
+ | `.text(textItem)` | 挂载一个文本组件。 |
39
+ | `.image(imageItem)` | 挂载一个图片组件。 |
40
+ | `.web(webItem)` | 挂载一个 Web 组件(内嵌 iframe 打开外部地址)。 |
41
+ | `.generalQuery(generalQueryItem)` | 挂载一个复合过滤组件:用 `.where(...)` / `.orGroup(...)` 声明初始过滤条件(省略 = 空骨架,查看者在查看态自行增删条件、且或组合并触发查询)(见 [§6.13](dashboard-dsl-items.md#613-generalqueryitem复合过滤组件))。 |
42
+ | `.aiDiagnosis(aiDiagnosisItem)` | 挂载一个 AI 诊断组件:对选中组件做 AI 诊断/产出分析(见 [§6.14](dashboard-dsl-items.md#614-aidiagnosisitemai-诊断组件))。 |
43
+ | `.combine(combineItem)` | 挂载一个组件组合(区块容器):成员为已声明的非容器条目名(至少 2 个),成员布局移入组合内容区(见 [§6.10](dashboard-dsl-items.md#610-combineitem组件组合))。 |
44
+ | `.tab(tabItem)` | 挂载一个 Tab 组件:多页签切换展示,每页持成员(见 [§6.11](dashboard-dsl-items.md#611-tabitemtab-组件))。 |
45
+ | `.freeze(freezeItem)` | 挂载一个过滤组件冻结栏:成员为控件与复合过滤组件,查看态钉在页面上方(见 [§6.12](dashboard-dsl-items.md#612-freezeitem过滤组件冻结栏))。 |
46
+ | `.title("组件名", "标题")` | 给已声明的数据组件设置显示标题;第二参数也可传 `RichText.of()...build()`(富文本标题,含动态字段值,见 [§8.3](dashboard-dsl-examples.md#83-数据组件标题))。 |
47
+ | `.showTitle("组件名", true)` | 设置已声明的数据组件是否显示标题。 |
48
+
49
+ 容器公共口径(三件套同构):
50
+
51
+ - 成员是**同板已声明的条目名**,可在容器声明之后才声明;一个条目至多加入一个容器;成员不得再 `position` 到顶层(其布局在容器内局部 72×36 网格)。
52
+ - 容器自身占一个画布位:不 `position` 时默认尺寸 组合 72×24 / Tab 72×16 / 冻结栏 72×8,与其他条目一起自动排;组合与 Tab 可悬浮(`float` 作用于容器名),**冻结栏自身不可悬浮**(设计器工具栏无该入口)。
53
+ - **组合容器浮 = 成员全浮**:`float(组合名)` 时**全部成员都须 `float`**(否则 fail-loud)。设计器按「成员全悬浮 → 容器悬浮」派生(帮助文档 §4),因此容器不浮而部分成员悬浮是合法的(对应设计器的「部分悬浮组合」形态)。
54
+ - 组合/Tab 页成员可悬浮(`float(成员名)`,须显式 `place`);冻结栏成员不可悬浮。组合不可嵌任何容器;Tab 页可含组合与冻结栏(冻结栏每页至多 1 个);Tab 不可嵌 Tab。
55
+
56
+ ### 3.2 联动与跳转
57
+
58
+ | DSL API | 业务含义 |
59
+ |---------------------------------------------|----------------------------|
60
+ | `.linkage("源组件名", linkage1, linkage2, ...)` | 给已声明的数据组件追加主动联动配置(显式字段对,查看态按声明字段过滤;被联动组件上的反向条目自动派生)。 |
61
+ | `.linkageEffect("源组件名", click, "目标1", "目标2", ...)` | 声明一条持久化联动效果(设计器里点击组件联动后的自动保存产物,打开仪表板即生效)。 |
62
+ | `.jump("源组件名", jump1, jump2, ...)` | 给已声明的数据组件追加跳转配置。 |
63
+ | `.cancelDefaultLinkage()` | 关闭仪表板默认联动,只保留显式声明的联动规则。 |
64
+
65
+ 业务补充:
66
+
67
+ - `linkage` 和 `jump` 都按组件业务名工作;多次调用是累加关系。
68
+ - 联动目标必须是同板已声明的数据组件或文本组件(控件、图片不可被联动);不声明联动 = 平台天然联动(同表/关联表/同指标集自动配对)。
69
+ - `LinkageModel.of(源字段, "目标组件名", 目标字段)` 声明显式字段对;`LinkageModel.disable("目标组件名")` 对单个目标显式关闭联动(含天然联动)。
70
+ - `linkageEffect` 与 `linkage` 正交:`linkage` 描述「怎么联动」(配置),`linkageEffect` 描述「当前联动已发生」(持久化点击态)。点击坐标 `LinkageEffect.click(点击轴字段)` + `.cell(维度字段, "显示值")` 维度坐标 / `.summaryCell("合计")` 合计行坐标 / `.metricNameCell("指标名")` 指标名称坐标(源组件须声明指标名称维度)。同一源至多一条;目标集可为空(点击时源无可联动目标);每条效果独立一跳、**不传递**(A 联动 B、B 联动 C 时点击 A 不会传导到 C——前端运行态限制);明细表不可发起(同 `linkage`)。
71
+ - 跳转名称(`.name(...)`)同一组件内不可重复;未命名的跳转用平台默认名(分析模板/网页链接),可多条。
72
+ - 跳转目标仪表板可跨主题:目标板按名称解析(同主题同名板优先,未命中查全局);目标字段的 fieldId 属于目标板用到的表,跨主题前先 `dashboard tables --id <目标板id>` 查候选字段名。
73
+ - `title` 和 `showTitle` 只作用于数据组件,不作用于控件、文本和图片组件。
74
+
75
+ ## 4. 布局与样式域
76
+
77
+ ### 4.1 布局与自适应
78
+
79
+ ```js
80
+ AdaptiveModel.flowLayout()
81
+ AdaptiveModel.origin(width, height)
82
+ ```
83
+
84
+ | DSL API | 业务含义 |
85
+ |-------------------------------------------|-----------------------|
86
+ | `.adaptive(AdaptiveModel.flowLayout())` | 自动适应:仅重排布局,不整体缩放(省略语句 = 自动适应 + 整体缩放,即设计器默认)。 |
87
+ | `.adaptive(AdaptiveModel.origin(w, h))` | 固定基准尺寸:保持原始尺寸不缩放。 |
88
+ | `.adaptive(AdaptiveModel.fitWidth(w, h))` | 固定基准尺寸:按宽度铺满等比缩放。 |
89
+ | `.adaptive(AdaptiveModel.fitHeight(w, h))`| 固定基准尺寸:按高度铺满等比缩放。 |
90
+ | `.adaptive(AdaptiveModel.fitAuto(w, h))` | 固定基准尺寸:按屏幕自适应铺满(宽高取小)。 |
91
+ | `.position(name, col, row, wCols, hRows)` | 按 72 列网格给条目设置位置和占位大小。 |
92
+
93
+ 参数语义(adaptive):
94
+
95
+ - `w` / `h`:基准尺寸,取值 100~10000(整数,超界 fail-loud)
96
+
97
+ 参数语义(position):
98
+
99
+ - `name`:已声明条目的业务名
100
+ - `col`:起始列
101
+ - `row`:起始行
102
+ - `wCols`:占用列数
103
+ - `hRows`:占用行数
104
+
105
+ 业务规则:
106
+
107
+ - 仪表板宽度固定为 72 列。
108
+ - `col + wCols` 不能超过 72。
109
+ - `row` 与 `hRows` 不做画布行上限硬校验(支持纵向延展,超出一屏时可滚动查看)。
110
+ - 没有显式 `position(...)` 的条目会按默认尺寸自动排版;显式和 auto 条目统一经全量压实(对齐前端查看态);**悬浮条目例外**(原样落位不压实)。
111
+
112
+ ### 4.2 悬浮与图层
113
+
114
+ ```js
115
+ .float(name)
116
+ ```
117
+
118
+ | DSL API | 业务含义 |
119
+ |-------------------------------------------|-----------------------|
120
+ | `.float(name)` | 声明条目悬浮:允许重叠、不参与压实,悬浮恒压网格条目。 |
121
+
122
+ 参数语义:
123
+
124
+ - `name`:已声明条目的业务名;多次调用累加
125
+ - **声明序即图层顺序**:后 `.float(...)` 声明的条目在上(置顶 = 调整声明序)
126
+ - 悬浮条目必须同时有显式 `.position(...)`(自由层无自动排布,缺省 fail-loud)
127
+ - 同名重复悬浮 fail-loud
128
+
129
+ ### 4.3 模板样式
130
+
131
+ | DSL API | 业务含义 |
132
+ |--------------------------------|---------------------------|
133
+ | `.stylePreset("DEFAULT_DARK")` | 使用平台内置的整板样式预设,按预设 id 选择。 |
134
+ | `.customStyle("我的样式")` | 使用管理员保存的全局自定义样式,按样式显示名选择。 |
135
+ | `.templateStyle(TemplateStyle.of()....build())` | 在基底上分区微调样式(可与上面任一组合:基底 + 逐项覆盖)。 |
136
+
137
+ 业务补充:
138
+
139
+ - `stylePreset` 适合快速套用平台标准主题。
140
+ - `customStyle` 适合复用团队已有的大屏或看板风格。
141
+ - `templateStyle` 全部可选、省略 = 基底值/平台默认;只声明要改的项。
142
+
143
+ 微调方法速查(按面板 6 分区):
144
+
145
+ | 分区 | 方法 | 值域 |
146
+ |---|---|---|
147
+ | 仪表板 | `widgetGap(gap)` / `background(color)` / `background(TemplateBackground)` | gap 偶数 0~20;颜色 `#RGB`/`#RRGGBB`/`transparent` |
148
+ | 组件 | `widgetBackground(color)` 或 `widgetBackground(color, radius, borderSize, borderColor)` 或 `widgetBackground(TemplateBackground)` / `hoverShadow(bool)` / `titleBackground(color\|TemplateBackground)` / `titleFont(font)` | 圆角 0~6、边框 0~5 |
149
+ | 图表 | `chartColor([colors])` / `clearChartColor()` / `chartFont(font)` | 色板非空;`clearChartColor()` = 面板「自动」回退平台配色;图表字体无对齐 |
150
+ | 表格 | `tableStyle(TemplateStyle.PLAIN\|BLUE_HEADER\|INTERVAL)` / `tableThemeColor(color)` / `tableFont(font)` / `scrollbar(TemplateStyle.STATIC\|DYNAMIC)` | |
151
+ | 过滤组件 | `controlTheme(color)` / `controlTitleFont(font)` / `controlTitleBackground(color\|TemplateBackground)` / `controlBackground(color[...]\|TemplateBackground)` | 此分区背景无样式皮肤入口 |
152
+ | 图片组件 | `imageBackground(color[...]\|TemplateBackground)` | |
153
+
154
+ 背景值对象(6 个背景槽位通用,镜像设计器背景面板的颜色/图片/组件样式三选一):
155
+
156
+ ```js
157
+ TemplateBackground.color("#13141f") // 纯色(等价于 background("#13141f") 便捷形态)
158
+ TemplateBackground.color("#1a1a2e", 4, 1, "#5a80ff") // 纯色 + 圆角 0~6 / 边框 0~5 / 边框色
159
+ TemplateBackground.image("image1788431093821_aft0uG6q_png") // 上传图片(attach id,先跑 dashboard upload-image)
160
+ TemplateBackground.style(TemplateBackground.STYLE2) // 预置装饰皮肤 STYLE1..STYLE6
161
+ ```
162
+
163
+ - 图片 `attachId` 必须来自 `dashboard upload-image`(或 `data:image...`、`resources?path=`);绝对 URL 渲染不出,构造期报错。
164
+ - 样式皮肤仅组件背景(`STYLE1/2/3/5/6`)、标题背景(`STYLE1..STYLE6`)、图片组件背景(`STYLE1/2/3/5/6`)可用;模板背景与过滤组件分区无此入口。
165
+ - 边框三件只在组件 / 过滤组件 / 图片组件背景三个分区设置;图片与皮肤形态不消费颜色与边框。
166
+
167
+ 字体值(`FontModel.of().family(...).size(...).bold(bool).italic(bool).underline(bool).color(...).align(FontModel.LEFT|CENTER|RIGHT).build()`;`FontModel.auto()` 把槽位重置回自动):
168
+
169
+ - `size` 必须是设计器字号选项之一:12~40(步进见面板)、64、128。
170
+ - 表格字体 `TableFont.of().header(FontModel).body(TableBodyFont.of()....dimAlign(...).tarAlign(...).build()).build()`(表头单对齐、表身维度/指标双对齐);`TableFont.auto()` 整体重置(表头/表身共用一个开关)。
171
+
172
+ ## 5. 移动端域
173
+
174
+ | DSL API | 业务含义 |
175
+ |-------------------------------------------------------|--------------|
176
+ | `.mobileConfig(MobileConfigModel.defaults())` | 使用默认移动端配置。 |
177
+ | `.mobileConfig(MobileConfigModel.of(["组件A", "组件B"]))` | 显式指定移动端组件顺序。 |
178
+
179
+ 默认配置语义:
180
+
181
+ - `controlShowType = 1`
182
+ - `fitGap = 10`
183
+ - `autoSequence = true`
184
+
185
+ ## 7. 字段写法
186
+
187
+ Dashboard DSL 中涉及字段的地方,包括控件、联动和跳转,都统一使用 source-scoped 写法:
188
+
189
+ ```js
190
+ from("销售表").dim("地区")
191
+ from("销售表").sum("销售额")
192
+ from("销售表").measure("销售额")
193
+ ```
194
+
@@ -0,0 +1,378 @@
1
+ # Dashboard DSL API:推荐写法示例与场景要点
2
+
3
+ > Dashboard DSL API 总导航见 [dashboard-dsl-api.md](dashboard-dsl-api.md)。
4
+
5
+ ## 8. 推荐写法示例
6
+
7
+ ### 8.1 引用已有组件
8
+
9
+ ```js
10
+ DashboardDsl.create("经营总览")
11
+ .content()
12
+ .reference("区域销售额")
13
+ .reference("月度趋势")
14
+ .presentation()
15
+ .position("区域销售额", 0, 0, 24, 16)
16
+ .position("月度趋势", 24, 0, 24, 16)
17
+ .build()
18
+ ```
19
+
20
+ 适用场景:已有组件已经保存到平台,只负责组织它们在仪表板上的摆放。
21
+
22
+ ### 8.2 筛选控件
23
+
24
+ ```js
25
+ DashboardDsl.create("带筛选控件")
26
+ .content()
27
+ .reference("月度趋势")
28
+ .control(
29
+ ControlItem.builder("区域筛选", ControlItem.TEXT)
30
+ .bindField(from("销售表").dim("地区"))
31
+ .controlRange(["月度趋势"])
32
+ .title("区域")
33
+ .showTitle(true)
34
+ .build()
35
+ )
36
+ .presentation()
37
+ .position("月度趋势", 0, 0, 24, 16)
38
+ .position("区域筛选", 0, 16, 24, 4)
39
+ .build()
40
+ ```
41
+
42
+ 适用场景:给指定组件加一个局部生效的文本筛选控件。
43
+
44
+ ### 8.3 数据组件标题
45
+
46
+ ```js
47
+ DashboardDsl.create("经营总览")
48
+ .content()
49
+ .reference("区域销售额")
50
+ .title("区域销售额", "各区域销售额")
51
+ .showTitle("区域销售额", true)
52
+ .presentation()
53
+ .position("区域销售额", 0, 0, 24, 16)
54
+ .build()
55
+ ```
56
+
57
+ 标题也可以带动态字段值(富文本标题,形态与文本组件富文本一致):
58
+
59
+ ```js
60
+ DashboardDsl.create("经营总览")
61
+ .content()
62
+ .reference("区域销售额")
63
+ .title("区域销售额", RichText.of()
64
+ .line("各区域销售额(", widgetName(), ")") // 组件名只有标题可用
65
+ .line("更新至:", from("销售表").dim("统计日期"))
66
+ .build())
67
+ .presentation()
68
+ .position("区域销售额", 0, 0, 24, 16)
69
+ .build()
70
+ ```
71
+
72
+ 标题富文本的片段类型与文本组件一致(`line` / `listItem` / `styled` / `link` / 字段引用 / `widgetName()` / `componentField(...)`),但**标题没有整块垂直对齐**(前端标题面板无该入口,声明 `verticalAlign(...)` 会报错)。
73
+
74
+ 适用场景:复用已有组件,但在当前仪表板中使用新的业务标题。
75
+
76
+ ### 8.4 时间控件
77
+
78
+ ```js
79
+ DashboardDsl.create("按月分析")
80
+ .content()
81
+ .reference("月度趋势")
82
+ .control(
83
+ ControlItem.builder("月份控件", ControlItem.MONTH)
84
+ .bindField(from("销售表").dim("月份"))
85
+ .title("月份")
86
+ .showTitle(true)
87
+ .build()
88
+ )
89
+ .presentation()
90
+ .position("月份控件", 0, 0, 24, 4)
91
+ .position("月度趋势", 0, 4, 24, 16)
92
+ .build()
93
+ ```
94
+
95
+ 适用场景:用月份控件驱动时间分析。
96
+
97
+ ### 8.5 文本 + 数据组件
98
+
99
+ ```js
100
+ DashboardDsl.create("销售总览")
101
+ .content()
102
+ .text(
103
+ TextItem.ofRichText("标题", RichText.of()
104
+ .line(styled("销售总览", {"font-size": "24px", "font-weight": "600", "color": "#333333"}))
105
+ .build())
106
+ )
107
+ .reference("区域销售额")
108
+ .presentation()
109
+ .position("标题", 0, 0, 24, 4)
110
+ .position("区域销售额", 0, 4, 24, 16)
111
+ .build()
112
+ ```
113
+
114
+ 适用场景:用标题文本、说明文本给数据组件做语义包装。
115
+
116
+ ### 8.6 富文本动态指标(KPI 风格)
117
+
118
+ ```js
119
+ DashboardDsl.create("经营速览")
120
+ .content()
121
+ .text(TextItem.ofRichText("核心指标", RichText.of()
122
+ .line("总销售额:", from("销售表").sum("销售额"), " 元")
123
+ .line("订单数:", count(from("销售表").dim("订单号")))
124
+ .build()))
125
+ .presentation()
126
+ .position("核心指标", 0, 0, 24, 8)
127
+ .build()
128
+ ```
129
+
130
+ 适用场景:在文本组件里展示字段真实数据(维度值、聚合指标、记录数),做 KPI 概览或说明行;字段写法同 [§7](dashboard-dsl-core.md#7-字段写法)。
131
+
132
+ ### 8.7 主动联动
133
+
134
+ ```js
135
+ DashboardDsl.create("区域销售分析")
136
+ .content()
137
+ .reference("区域销售图")
138
+ .reference("订单明细")
139
+ .linkage(
140
+ "区域销售图",
141
+ LinkageModel.of(
142
+ from("销售表").dim("地区"),
143
+ "订单明细",
144
+ from("销售表").dim("地区")
145
+ )
146
+ )
147
+ .presentation()
148
+ .position("区域销售图", 0, 0, 24, 16)
149
+ .position("订单明细", 24, 0, 24, 16)
150
+ .build()
151
+ ```
152
+
153
+ 适用场景:点击左侧汇总图,右侧明细表跟随过滤。
154
+
155
+ ### 8.8 组件跳转
156
+
157
+ ```js
158
+ DashboardDsl.create("销售驾驶舱")
159
+ .content()
160
+ .reference("区域销售图")
161
+ .jump(
162
+ "区域销售图",
163
+ JumpModel.toReport(
164
+ from("销售表").dim("地区"),
165
+ "区域专题看板",
166
+ from("销售表").dim("地区")
167
+ )
168
+ .openPosition(JumpModel.DIALOG)
169
+ .name("查看区域专题")
170
+ )
171
+ .presentation()
172
+ .position("区域销售图", 0, 0, 24, 16)
173
+ .build()
174
+ ```
175
+
176
+ 适用场景:从总览看板跳到专题看板(也可用 `JumpModel.toUrl` 跳网页链接)。
177
+
178
+ ### 8.9 关闭默认联动与单目标禁用
179
+
180
+ ```js
181
+ DashboardDsl.create("显式联动看板")
182
+ .content()
183
+ .reference("chartA")
184
+ .reference("chartB")
185
+ .reference("chartC")
186
+ .linkage("chartA", LinkageModel.of(
187
+ from("销售表").dim("地区"),
188
+ "chartB",
189
+ from("销售表").dim("地区")
190
+ ))
191
+ .linkage("chartA", LinkageModel.disable("chartC"))
192
+ .cancelDefaultLinkage()
193
+ .presentation()
194
+ .position("chartA", 0, 0, 24, 16)
195
+ .position("chartB", 24, 0, 24, 16)
196
+ .position("chartC", 48, 0, 24, 16)
197
+ .build()
198
+ ```
199
+
200
+ 适用场景:只保留显式编排的联动关系(天然联动整板关闭;`LinkageModel.disable` 对单个目标关闭)。
201
+
202
+ ### 8.10 持久化联动效果
203
+
204
+ ```js
205
+ DashboardDsl.create("留存联动看板")
206
+ .content()
207
+ .reference("区域销售图")
208
+ .reference("订单明细")
209
+ .text(TextItem.of("区域说明", "当前聚焦区域"))
210
+ .linkageEffect(
211
+ "区域销售图",
212
+ LinkageEffect.click(from("销售表").dim("销售额"))
213
+ .cell(from("销售表").dim("地区"), "华东")
214
+ .summaryCell("合计"),
215
+ "订单明细", "区域说明"
216
+ )
217
+ .presentation()
218
+ .position("区域销售图", 0, 0, 24, 16)
219
+ .position("订单明细", 24, 0, 24, 16)
220
+ .position("区域说明", 0, 16, 24, 4)
221
+ .build()
222
+ ```
223
+
224
+ 适用场景:看板打开即呈现「区域销售图点击华东后」的联动状态(数据/文本目标跟随过滤)。与 `linkage` 配置正交;一条效果一跳生效、不传递。
225
+
226
+ ### 8.11 使用平台预设样式
227
+
228
+ ```js
229
+ DashboardDsl.create("大屏主题示例")
230
+ .content()
231
+ .reference("经营概览")
232
+ .presentation()
233
+ .stylePreset("DEFAULT_DARK")
234
+ .position("经营概览", 0, 0, 24, 16)
235
+ .build()
236
+ ```
237
+
238
+ 适用场景:快速套用平台内置深色或浅色风格。
239
+
240
+ ### 8.12 使用全局自定义样式
241
+
242
+ ```js
243
+ DashboardDsl.create("品牌看板")
244
+ .content()
245
+ .reference("区域销售额")
246
+ .presentation()
247
+ .customStyle("销售总览样式")
248
+ .position("区域销售额", 0, 0, 24, 16)
249
+ .build()
250
+ ```
251
+
252
+ 适用场景:复用团队统一维护的品牌样式。
253
+
254
+ ### 8.13 移动端顺序
255
+
256
+ ```js
257
+ DashboardDsl.create("移动端示例")
258
+ .content()
259
+ .reference("w1")
260
+ .reference("w2")
261
+ .reference("w3")
262
+ .mobile()
263
+ .mobileConfig(MobileConfigModel.of(["w2", "w1", "w3"]))
264
+ .build()
265
+ ```
266
+
267
+ 适用场景:移动端展示顺序与桌面端布局顺序不同,需要单独编排。
268
+
269
+ ### 8.14 多字段控件
270
+
271
+ ```js
272
+ DashboardDsl.create("多字段筛选")
273
+ .content()
274
+ .reference("区域销售额")
275
+ .reference("订单明细")
276
+ .control(
277
+ ControlItem.builder("地区与大区筛选", ControlItem.TEXT_LIST)
278
+ .bindFields([
279
+ from("销售表").dim("地区"),
280
+ from("销售表").dim("大区")
281
+ ])
282
+ .controlRange(["区域销售额", "订单明细"])
283
+ .title("区域范围")
284
+ .showTitle(true)
285
+ .build()
286
+ )
287
+ .presentation()
288
+ .position("地区与大区筛选", 0, 0, 24, 8)
289
+ .position("区域销售额", 0, 8, 24, 16)
290
+ .position("订单明细", 24, 8, 24, 16)
291
+ .build()
292
+ ```
293
+
294
+ 适用场景:同一个控件要同时绑定多个业务字段,用一组筛选驱动多个组件。
295
+
296
+ ### 8.15 控件默认值与排序
297
+
298
+ ```js
299
+ DashboardDsl.create("带默认值的筛选")
300
+ .content()
301
+ .reference("月度趋势")
302
+ .control(
303
+ ControlItem.builder("地区筛选", ControlItem.TEXT_BUTTON_GROUP)
304
+ .bindField(from("销售表").dim("地区"))
305
+ .defaultValue(["华东"])
306
+ .sort("asc")
307
+ .multiSelect(false)
308
+ .build()
309
+ )
310
+ .presentation()
311
+ .position("地区筛选", 0, 0, 24, 8)
312
+ .position("月度趋势", 0, 8, 24, 16)
313
+ .build()
314
+ ```
315
+
316
+ 适用场景:控件需要预选某个业务值,并按升序稳定展示候选项。
317
+
318
+ ### 8.16 带目标字段的跳转
319
+
320
+ ```js
321
+ DashboardDsl.create("区域驾驶舱")
322
+ .content()
323
+ .reference("区域销售图")
324
+ .jump(
325
+ "区域销售图",
326
+ JumpModel.toReport(
327
+ from("销售表").dim("地区"),
328
+ "区域专题看板",
329
+ from("销售表").dim("地区")
330
+ )
331
+ )
332
+ .presentation()
333
+ .position("区域销售图", 0, 0, 24, 16)
334
+ .build()
335
+ ```
336
+
337
+ 适用场景:从当前看板跳转到目标看板时,把当前选中的业务字段一并带过去做定位。
338
+
339
+ ### 8.17 默认移动端配置
340
+
341
+ ```js
342
+ DashboardDsl.create("移动端默认配置")
343
+ .content()
344
+ .reference("经营概览")
345
+ .reference("订单明细")
346
+ .mobile()
347
+ .mobileConfig(MobileConfigModel.defaults())
348
+ .build()
349
+ ```
350
+
351
+ 适用场景:明确声明“移动端沿用平台默认配置”,避免由调用方再补默认值。
352
+
353
+ ## 9. 场景模板与设计要点
354
+
355
+ `dashboard template` 的每个场景都给出可抄脚本 + 变量契约 + `guidance`(设计要点,共享要点在前、
356
+ 场景专属在后)。设计要点只讲**决策**(怎么摆、怎么取舍),语法与取值约束以本文档与
357
+ `dashboard schema` 为准。
358
+
359
+ | 场景 id | 形态 | 覆盖能力 |
360
+ |---|---|---|
361
+ | `basic` | 经营看板:筛选条 + KPI 富文本行 + 封面图 + 双图表联动 | 引用/标题/富文本(列表、链接、行内样式)/图片/控件 + controlRange/联动/网格 position/stylePreset/移动端 |
362
+ | `kpi` | KPI 概览:富文本指标行 + 一张图 | 富文本动态字段;注释给出 KPI 指标卡组件的替代路径(`widget template --chart-type KPI_CARD`) |
363
+ | `filter` | 筛选控件:多选列表 + 数值区间 + 日期区间 + 查询/重置/清空 | 控件属性族(title/required/sortByField/closeRange)与按钮族;日期过滤不写死默认区间 |
364
+ | `style` | 样式面:预设基底 + 六分区微调 | stylePreset/customStyle + templateStyle(背景/卡片/图表配色/表格/过滤/图片)+ FontModel/TableFont |
365
+ | `screen` | 大屏驾驶舱:固定基准 + 悬浮装饰 + 深色预设 | adaptive(AdaptiveModel.fitAuto/origin) + float + dynamicDefault 日期控件 |
366
+ | `rich-text` | 富文本与动态字段:富标题 + 组件字段 + 行内样式 + 列表链接 | title(name, RichText)/widgetName()/componentField/styled/formatted/fieldValue 子链/图片 withHref |
367
+ | `linkage-jump` | 联动与跳转:跨表自定义依赖字段联动 + 两型跳转(分析模板传值 / 网页链接占位符)+ 持久化联动效果 | linkage(LinkageModel.of)/linkageEffect(LinkageEffect.click + cell)/jump(JumpModel.toReport/toUrl + openPosition/name);目标板字段先 `dashboard tables --id` 查候选;clickedValue 须取源组件数据里的真实显示值(空组合联动结果为空) |
368
+ | `tree-time` | 层级与时间筛选:二级树(省→市)+ 时间按钮组驱动一张图 | TREE 的 bindField 声明序=层级(跨表层级须同关联分量)/多层级树无 defaultValue;TIME_GROUP + timeTags(TimeTag.preset(...).selected()),未标 selected 则首屏不过滤 |
369
+ | `blocks` | 容器区块:冻结筛选栏 + Tab 页签(页内组合区块 + 明细页)+ 页脚长板 | combine(CombineItem.of/gap/withTitle)/tab(TabItem.of/page/selected/style)/freeze(FreezeItem.of/gap/showExpand);成员单容器归属、成员不得顶层 position、组合悬浮须成员全悬浮 |
370
+
371
+ 通用设计要点(每个场景响应都会带回,节选):
372
+
373
+ - 结构:标题 → 筛选区 → 关键指标行 → 主分析区(1–2 行图表)→ 明细表(可选)。
374
+ - 节奏:一屏 2–3 行组件;同类组件等宽(36+36 或 24+24+24);`widgetGap` 8–16 留白。
375
+ - 自适应:日常分析用省略态;汇报/大屏改固定基准尺寸(`origin`/`fitWidth`/`fitAuto`)。
376
+ - 样式:整板一个基底 + `templateStyle` 局部微调;图表配色统一;字号不超过三档。
377
+ - 交互:筛选组件置顶并用 `controlRange` 圈定;查询按钮保持默认自动查询(写 `autoQuery(false)`
378
+ 且无默认值时首屏可能空板)。