# 仪表盘设计
仪表盘通常是系统中的一个可视化界面,用于展示关键数据和指标的概览。它通常以图表、 图形、数字等形式呈现,旨在帮助用户直观地监测和了解系统的状态、性能或其他关键指标。
本系统支持通过客制化的方式,定制仪表盘,用以显示各类图表、链接、文字说明等
# 目标读者
本文档的目标读者为:本系统的开发和实施人员,或者对定制仪表盘感兴趣的高级用户
# 操作概述
# 创建仪表盘
具有创建仪表盘权限的用户登陆进入系统后,会在首页看到新建仪表盘的按钮如下所示
点击该按钮后,会弹出仪表盘的创建表单如下
其中重点的相关字段描述如下:
字段名称 | 字段说明 |
---|---|
Form Type | 创建仪表盘时,值设定为 Dashboard |
Name | 该仪表盘的名称,设定后不允许修改 |
Label | 该仪表盘在界面上显示的名称 |
Organization | 该仪表盘的所属组织 |
Enable Role | 可以查看该仪表盘的用户角色列表, 如果该用户也具有仪表盘编辑的权限,则该用户同时可以编辑仪表盘 |
提示
用户是否具有创建、编辑、删除 Dashboard 的权限判断,是看用户是否具有 DynamicForm 这一 Domain 对象的对应权限。
# 仪表盘编辑及其他相关操作
- 切换到待修改的仪表盘,并点击仪表盘显示标签后的齿轮图标,即可弹出仪表盘操作菜单,其中包括如下相关功能
编辑仪表盘的操作与创建类似,此处不再赘述。
# 新增 widget
在上述仪表盘的操作菜单中,点击 Add new widget
即可在当前仪表盘下新增一个 widget ,新增 widget 的表单如下所示:
其中重点的相关字段描述如下:
字段名称 | 字段说明 |
---|---|
Dashboard | 该 widget 所属的 dashboard |
Type | 该 widget 的类型,决定了该 widget 在前台如何进行渲染 |
Name | 该 widget 的名称,唯一标识,创建后即无法修改 |
Label | 该 widget 的显示名称 |
Display Sequence | 该 widget 的显示顺序,display sequence 越小的 widget, 显示越靠前 |
Enable Logic | 该 widget 是否显示的动态逻辑,如执行的结果为 false 则该 widget 会隐藏 |
Core Logic | 该 widget 的数据准备和显示配置的核心逻辑 |
Options | 一个 JSON 字符串,保存该 widget 的显示配置 |
- 关于 widget 的
Options
字段的详细描述请见 Widget Options 设定 章节 - 关于 widget 的 enable logic 及 core logic 的详细描述见 Widget 相关动态逻辑 章节
# 修改及删除 widget
将鼠标放到 widget 上,在 widget 的右上方会出现一个齿轮图标,点击该齿轮图标,则会出现操作菜单如下所示:
如果当前用户有编辑 widget 的权限,则会出现如下的相关操作菜单
- Refresh data: 刷新数据
- Show in popup window: 在更大的弹出窗口中显示该 widget 的内容
- Edit Widget settings: 编辑 Widget 的相关设定
- Edit widget core logic: 编辑该 widget 的核心逻辑,widget 的核心逻辑是一个 dynamic logic 对象,用于向前台返回渲染 widget 所需要的数据和配置信息
# Widget 显示宽度设定及换行
系统排版 widget 时,在水平方向,将所有可显示宽度划分为 24 个网格,每个 widget 均可以设定 1 到 24 的显示宽度, 系统会根据 display Sequence 对 widget 进行排序,并根据每个 widget 的宽度设定计算出 每行可显示的 widget 个数,并确保每行所有 widget 的总宽度不大于 24。如果某行剩余的网格宽度不够容 纳下一个待显示的 widget, 则该 widget 会被挪到下一行显示。
显示宽度保存在 Options
字段中,通过如下的 json 数据进行指定:
// "col": 8 表示该 widget 的显示宽度占据 8 个水平方向的宽度,即全部宽度的 1/3
{"position": {"col": 8}}
2
提示
如果在 Options
中不指定 widget 的宽度,则 widget 的默认宽度为 12, 占据一行的 1/2。
# Widget 显示高度
在同一行显示的所有 Widget, 其高度均相同。
# Widget Options
设定
Widget 定义中的 Options
是一个 json 字符串,定义了 widget 的显示配置,
包括宽度和其他只适用于特定 widget 类型的配置。
此外,在 Options
字段的 config
下定义的配置,在前端渲染 widget 时,会不经任何修改的,
传递给渲染的 React 控件。如下的 Options
设定中,{"xField": "year", "yField": "value", "tooltip": {"showMarkers": true}}
这个 json 对象,会被原样传递给渲染的 React 控件。
{"config": {"xField": "year", "yField": "value", "tooltip": {"showMarkers": true}}, "position": {"col": 8}}
# Widget 相关动态逻辑
# Enable logic
Widget 是否显示是通过 widget 的 enable logic 进行控制,而显示的相关配置和数据,
Widget 的 enable logic 是 Logic Type 为 "Dashboard widget enable logic" 的 Dynamic Logic 对象
# 注入变量
前台获取某个 Dashboard 的 widget 列表时,会先调用每个 widget 定义中的 enable logic 动态逻辑并进行计算, 如果计算结果为 false, 则不会将该 widget 返回,运行时注入的变量列表如下:
# 返回结果
客制化代码需要返回一个 Map<String, Boolean>
对象,该对象需要包含一个 key 为 result
的元素,示例如下:
// 表示该 action 或 task 或 widget 是否启用
// Indicates whether this action or task or widget is enabled
[result: true | false]
2
提示
如果 widget 定义中的 enable logic 字段为空,则表示该 widget 默认显示
# Core logic
系统通过 widget 的 core logic 生成具体要显示的数据及相关的显示属性,并传递给前台。
# 注入变量
Widget core logic 运行时的注入变量如下表所示:
# 返回结果
Widget core logic 运行返回的结果是一个类型为 Map<String, Object>
类型的对象, 系统会将返回的该 Map
对象直接传递给前台。前台在渲染时,会将该 Map 对象直接转化为一个 JSON 对象, 并与前台的 Widget 渲染控件
中定义的默认属性和 Widget 定义的 Options
中, key 为 config
的 JSON 对象进行合并, 合并后,
将合并结果作为 Widget 的前台渲染控件的属性集。
举例如下:
- Widget 定义的
Options
字段的值如下,其中xField
定义了图表的横坐标为year
,yField
定义了图表的纵坐标为value
{"config": {"xField": "year", "yField": "value", "position": {"col": 8}}
- 在 Widget core logic 中返回的 Map 的值如下
def data = [
[x: 1, y: 2],
[x: 3, y: 4]
]
def result = [
data: data,
legend: [
custom: true,
position: 'bottom',
]
]
return result
2
3
4
5
6
7
8
9
10
11
12
那么最终传递给 React 的渲染控件的属性是上述两个来源的合并。
其中, xField 和 yField 属性来自 widget 定义中的 Options
字段, data, legend 两个属性来自 Widget core logic 的返回值
{
"xField": "year",
"yField": "value",
"data": [
{"x": 1, "y": 2},
{"x": 3, "y": 4}
],
"legend": {
"custom": true,
"position": "bottom"
}
}
2
3
4
5
6
7
8
9
10
11
12
# Widget 类型详述
# 支持的 Widget 类型列表
以下列出了系统当前支持的 widget 类型及其简要描述
相关的 widget 类型有特定的一些设定或者使用中的注意事项,详述如下
# 非图表类 Widget 属性结构
# Markdown 及 Html Widget
以下是 markdown 及 html 类型 widget 的 core logic 返回值的结构
// 包含 key 为 data, value 为显示文本的一个 Map 对象
[ data: "Markdown 文本" ]
:::
可以在 Html widget 的 options 中,通过 `config` 字段来设置 widget 整体的样式,例如
``` json
{
"config": {
"style": {
"color": "red",
"fontSize": "32px",
"textAlign": "center"
}
}
}
也可以在 widget 的 core logic 返回值中,通过 `style` 字段来设置 widget 整体的样式,例如
``` groovy
return [
data: "Hello World",
style: [
// 可选的 CSS 样式
fontSize: "12px"
]
]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
:::
::: tip
Markdown widget 通过 [remark-gfm](https://github.com/remarkjs/remark-gfm) 支持
[gfm 标准](https://github.github.com/gfm/)支持包括表格、列表、TODO 等在内的一些
列高级格式控制。
:::
#### 倒计时 Widget
以下是倒计时类型 widget 的 core logic 返回值的结构示例
``` groovy
Date d = new Date()
d.setYear(2022 - 1900);
d.setMonth(1)
d.setDate(4);
return [
// Title 是界面上显示的倒计时的标题
title: '冬奥会倒计时',
// Value 是倒计时的目标时间,系统会根据当前时间自动生成倒计时显示
value: d.getTime()
]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 数据表 Widget
以下是数据表类型 widget 的 core logic 返回值的结构示例
return [
// 包含 key 为 data, value 为待显示的数据的数组
// 数组的每个元素都是一个 Map 类型的结构
// 如下的结构会在前台渲染成一个具有两列的表格
// 列标题分别为 First Column 和 Second Column
data: [
[
"FirstColumn": "Hahaha",
"SecondColumn": "Good"
], [
"FirstColumn": "Hahaha2",
"SecondColumn": "Good2"
]
]
]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Statistic Widget
以下是 Statistic 类型 widget 的 core logic 返回值的结构示例
return [
// title 是界面显示的标题
title: "昨天的销售情况",
// value 是界面显示的值
value: 50
// direction 可选值为 up 和 down, 决定界面显示的箭头的颜色和方向
direction: "up" | "down"
]
2
3
4
5
6
7
8
Widget 显示效果及各部分与后台传递参数的对应关系如下图所示
# 图表类型 Widget
所有的仪表盘图表,均使用 antd chart (opens new window) 图表库进行渲染, 但当前只支持部分的图表类型,具体支持列表请参考上述表格。
图表 Widget 被渲染时,会将 Widget 定义中的 Options
字段中, key 为 config
的部分与 Core Logic
中返回的 Map 的最顶层 key 进行合并,将合并结果直接作为参数传递给 antd chart 的渲染控件。
兼容性提示
当前的 widget 渲染不支持 javascript 回调函数类型的渲染属性。
# 图表的坐标轴设定
对于包含坐标轴的图表类型,需要在 widget 的 Options
或者 core logic 的返回值中,包含
坐标轴的设定,否则有可能出现图表显示为空或者显示出错的情况。
- 在
Options
字段中进行设定
// 设定 x 轴为 year, y 轴为 value
{"config": {"xField": "year", "yField": "value", "position": {"col": 8}}
2
- 在 core logic 中直接返回
return [
xField: "时间",
yField: "销售额"
data: [...]
]
2
3
4
5
xField
和 yField
为必传属性的图表列表如下:
- 线图 Line chart
- 面积图 Area chart
- 柱形图 Column chart
- 条形图 Bar chart
xField
为可选属性的图表列表如下:
- 子弹图进度图 Bullet chart
# 图表的传值属性列表
按照 Antd chart 的 API, 设定图表中的显示数据的属性名称可能不尽相同, 下表列出了各图表的数据属性名称供参考, 具体属性的值格式请参考 antd chart 文档。
图表类型 | 数据属性名称 |
---|---|
线图 Line chart | data |
面积图 Area chart | data |
柱形图 Column chart | data |
条形图 Bar chart | data |
饼图 Pie chart | data |
仪表盘进度图 Gauge | percent |
水滴图进度图 Liquid | percent |
迷你进度条 Progress chart | percent |
子弹图进度图 Bullet | data |
迷你进度环图 Ring progress chart | percent |
迷你面积图 Tiny area chart | data |
迷你折线图 Tiny line chart | data |
迷你柱形图 Tiny column chart | data |
对称条形图 Bi direction bar | data |
直方图 Histogram | data |
提示
传递值的属性在 core logic 运行的返回结果中是必须的,否则图表将无法显示。
兼容性提示
当前使用的 antd chart 版本为 1.0.11
, 请注意在未来的版本中,antd chart 的 API 可能会有变化,如果上述属性失效,请参考各图表最新的 API 文档
# 注意事项
以下列出了相关仪表盘实现过程的注意事项及最佳实践
# Widget 显示的属性的优先级
系统在渲染 widget 控件时,会将 widget 的 core logic, Options
字段及前台渲染控件中
定义的默认属性进行合并,作为最终的控件渲染属性,如下列出了这三个属性来源的属性的优先级,
对于相同名称的属性,优先级高来源的值会覆盖优先级低来源的值。
* 最高:在 widget 的 core logic 中返回的显示属性
* 其次:在 widget 的 Options 字段中定义的显示属性
* 最低:各 widget 的 React 控件的默认显示属性
# 最佳实践
# Markdown widget 中的换行
如果需要在渲染结果中,增加换行,可以在行后面增加两个空格,最终渲染出来的效果,会进行换行
# Widget 最小宽度
如果 widget 的宽度设定小于 4(Widget Options
中设定的宽度为1, 2 或3 {"position": {"col": 1 | 2 | 3}}
),
那么有一定概率出现该 widget 与后面的 widget 显示有重叠的情况,因此建议在设计 widget 排版时,widget 的宽度
最小为 4 或以上(占据整体宽度的 1/6 以上)
# Options
字段格式特别说明
Widget 定义中的 Options
字段在数据库中,是以 jsonb
类型的字段保存,因 postgresql 要求,该 json 字符串中的
字符串均需要包含在 双引号 中,不能使用单引号,如 {"position": {"col": 8}}
不能写作 {'position': {'col': 8}}
,
否则保存到数据库会失败。
# 相关实现背景 开发
以下列出了一些可能对于创建 Dashboard 和进行问题排查有帮助的框架实现细节
- 仪表盘在系统中,是一种类型为 Dashboard 的表单(Form),与对象的 CRUD 及向导定义
的表单相同,都存放在
dynamic_form
数据库表中。 - 仪表盘的元数据获取、渲染、数据获取等 API 均以
/dashboard/
开头,具体可以参考 系统中的 swagger 页面
← 🧭 引导指南(向导) 📄 高级表单 →