编写图表

使用 Chart DSL 编写图表界面, 可用于实现数据看板等功能模块。

约定

  1. 示例中约定应用根目录为 /data/app, 实际编写时需替换为应用根目录。
  2. 使用 <> 标识自行替换的内容。 例如: icon-<图标名称>, 实际编写时应替换为: icon-foo, icon-bar ...

编写图表

编排数据查询逻辑

flows/stat 目录下创建一个数据流, 用来编排统计数据。

聚合查询推荐使用 Query DSL 编写, 常规查询可以使用模型处理器实现。

查看 Query DSL 手册

查看 Model Widget 手册

/data/app/flows/stat/product.flow.yao

{
"label": "产品",
"version": "1.0.0",
"description": "产品统计",
"nodes": [
{
"name": "总数",
"engine": "default",
"query": {
"select": [":COUNT(id) as 数量"],
"from": "$product",
"first": true
}
},
{
"name": "分布",
"engine": "default",
"query": {
"select": [":COUNT(id) as 数量", ":TIME(created_at) as 时刻"],
"from": "$product",
"orders": "时刻",
"groups": "时刻"
}
}
],
"output": {
"数量": "{{$res.总数.数量}}",
"分布": "{{$res.分布}}"
}
}

运行调试

yao run flows.stat.product

添加图表 DSL 文件

charts 目录下, 创建一个 Chart DSL 文件, 将数据处理器指定为 flows.stat.product, 并设置图表布局。

在浏览器输入图表路由地址访问:

http://<IP>:<YAO_PORT>/<管理后台路由前缀>/x/Chart/stat

/data/app/charts/stat.chart.yao

{
"name": "统计",
"action": {
"data": { "process": "flows.stat.product" }
},
"layout": {
"operation": { "actions": [] },
"chart": {
"columns": [
{ "name": "产品数量", "width": 6 },
{ "name": "时刻分布", "width": 24 }
]
}
},
"fields": {
"chart": {
"产品数量": {
"bind": "数量",
"link": "/x/Table/product",
"view": { "type": "Number", "props": { "unit": "个" } }
},
"时刻分布": {
"bind": "分布",
"link": "/x/Table/product",
"view": {
"type": "Bar",
"props": {
"height": 240,
"nameKey": "时刻",
"axisLabel": { "interval": 0, "fontSize": 12 },
"series": [
{
"valueKey": "数量",
"type": "bar",
"colorBy": "data",
"itemStyle": { "borderRadius": 6 },
"splitLine": { "show": false },
"axisLabel": { "show": false }
}
]
}
}
}
}
},
"config": { "full": false }
}

增加筛选器

修改数据查询逻辑

增加按时间范围查询

/data/app/flows/stat/product.flow.yao

{
"label": "产品",
"version": "1.0.0",
"description": "产品统计",
"nodes": [
{
"name": "总数",
"engine": "default",
"query": {
"select": [":COUNT(id) as 数量"],
"from": "$product",
"wheres": [
{ "field": ":TIME(created_at)", ">=": "?:$range[0]" },
{ "field": ":TIME(created_at)", "<=": "?:$range[1]" }
],
"first": true
}
},
{
"name": "分布",
"engine": "default",
"query": {
"debug": true,
"select": [":COUNT(id) as 数量", ":TIME(created_at) as 时刻"],
"from": "$product",
"wheres": [
{ "field": ":TIME(created_at)", ">=": "?:$range[0]" },
{ "field": ":TIME(created_at)", "<=": "?:$range[1]" }
],
"orders": "时刻",
"groups": "时刻"
}
}
],
"output": {
"IN": "{{$in}}",
"数量": "{{$res.总数.数量}}",
"分布": "{{$res.分布}}"
}
}
在 Query DSL 中使用上下文变量或参数表,使用 ?: 作为标识符。 例如: {{$range[0]}}, 在 Query DSL 中使用时, 写做 \?:$range[0]查阅 Query DSL 手册

运行调试

yao run flows.stat.product '::{"range":["08:00", "16:00"]}'

添加筛选器

增加按时间范围筛选,并设置为 TimePicker 组件。

/data/app/charts/stat.chart.yao

{
"name": "统计",
"action": {
"data": { "process": "flows.stat.product" }
},
"layout": {
"operation": { "actions": [] },
"filter": {
"columns": [{ "name": "时间区间", "width": 6 }]
},
"chart": {
"columns": [
{ "name": "产品数量", "width": 6 },
{ "name": "时刻分布", "width": 24 }
]
}
},
"fields": {
"filter": {
"时间区间": {
"bind": "range",
"edit": { "type": "TimePicker", "props": { "range": true } }
}
},
"chart": {
"产品数量": {
"bind": "数量",
"link": "/x/Table/product",
"view": { "type": "Number", "props": { "unit": "个" } }
},
"时刻分布": {
"bind": "分布",
"link": "/x/Table/product",
"view": {
"type": "Bar",
"props": {
"height": 240,
"nameKey": "时刻",
"axisLabel": { "interval": 0, "fontSize": 12 },
"series": [
{
"valueKey": "数量",
"type": "bar",
"colorBy": "data",
"itemStyle": { "borderRadius": 6 },
"splitLine": { "show": false },
"axisLabel": { "show": false }
}
]
}
}
}
}
},
"config": { "full": false }
}

添加 Hook 转换筛选器参数

添加一个 Befor Hook, 将参数转换为处理器需要格式。

在浏览器刷新图表路由地址访问:

http://<IP>:<YAO_PORT>/<管理后台路由前缀>/x/Chart/stat

添加一个 Hook 脚本用于转换参数。

/data/app/scripts/hook.js

/**
* Stat Hook
* @param {*} args
* @returns
*/
function FormatTime(args) {
log.Trace("[FormatTime] %v", args);
let range = args["range[]"] || [];
let start = range[0] ? range[0].split("T")[1].split("+")[0] : "08:00";
let end = range[1] ? range[1].split("T")[1].split("+")[0] : "18:00";
return [{ range: [start, end] }];
}

运行调试

yao run scripts.hook.FormatTime '::{"range[]":["2022-11-14T08:00:00+08:00", "2022-11-14T23:00:00+08:00"]}'

修改 Chart DSL 挂载 Hook

/data/app/charts/stat.chart.yao

{
"name": "统计",
"action": {
"before:data": "scripts.hook.FormatTime",
"data": { "process": "flows.stat.product" }
},
"layout": {
"operation": { "actions": [] },
"filter": {
"columns": [{ "name": "时间区间", "width": 6 }]
},
"chart": {
"columns": [
{ "name": "产品数量", "width": 6 },
{ "name": "时刻分布", "width": 24 }
]
}
},
"fields": {
"filter": {
"时间区间": {
"bind": "range",
"edit": { "type": "TimePicker", "props": { "range": true } }
}
},
"chart": {
"产品数量": {
"bind": "数量",
"link": "/x/Table/product",
"view": { "type": "Number", "props": { "unit": "个" } }
},
"时刻分布": {
"bind": "分布",
"link": "/x/Table/product",
"view": {
"type": "Bar",
"props": {
"height": 240,
"nameKey": "时刻",
"axisLabel": { "interval": 0, "fontSize": 12 },
"series": [
{
"valueKey": "数量",
"type": "bar",
"colorBy": "data",
"itemStyle": { "borderRadius": 6 },
"splitLine": { "show": false },
"axisLabel": { "show": false }
}
]
}
}
}
}
},
"config": { "full": false }
}

查看 Chart Widget 手册

添加菜单

编辑 /data/app/flows/app/menu.flow.yao 添加菜单项

查看源码

退出后台重新登录。

更新菜单

编写图表

使用 Chart DSL 编写图表界面, 可用于实现数据看板等功能模块。

约定

  1. 示例中约定应用根目录为 /data/app, 实际编写时需替换为应用根目录。
  2. 使用 <> 标识自行替换的内容。 例如: icon-<图标名称>, 实际编写时应替换为: icon-foo, icon-bar ...

编写图表

编排数据查询逻辑

flows/stat 目录下创建一个数据流, 用来编排统计数据。

聚合查询推荐使用 Query DSL 编写, 常规查询可以使用模型处理器实现。

查看 Query DSL 手册

查看 Model Widget 手册

/data/app/flows/stat/product.flow.yao

{
"label": "产品",
"version": "1.0.0",
"description": "产品统计",
"nodes": [
{
"name": "总数",
"engine": "default",
"query": {
"select": [":COUNT(id) as 数量"],
"from": "$product",
"first": true
}
},
{
"name": "分布",
"engine": "default",
"query": {
"select": [":COUNT(id) as 数量", ":TIME(created_at) as 时刻"],
"from": "$product",
"orders": "时刻",
"groups": "时刻"
}
}
],
"output": {
"数量": "{{$res.总数.数量}}",
"分布": "{{$res.分布}}"
}
}

运行调试

yao run flows.stat.product

添加图表 DSL 文件

charts 目录下, 创建一个 Chart DSL 文件, 将数据处理器指定为 flows.stat.product, 并设置图表布局。

在浏览器输入图表路由地址访问:

http://<IP>:<YAO_PORT>/<管理后台路由前缀>/x/Chart/stat

/data/app/charts/stat.chart.yao

{
"name": "统计",
"action": {
"data": { "process": "flows.stat.product" }
},
"layout": {
"operation": { "actions": [] },
"chart": {
"columns": [
{ "name": "产品数量", "width": 6 },
{ "name": "时刻分布", "width": 24 }
]
}
},
"fields": {
"chart": {
"产品数量": {
"bind": "数量",
"link": "/x/Table/product",
"view": { "type": "Number", "props": { "unit": "个" } }
},
"时刻分布": {
"bind": "分布",
"link": "/x/Table/product",
"view": {
"type": "Bar",
"props": {
"height": 240,
"nameKey": "时刻",
"axisLabel": { "interval": 0, "fontSize": 12 },
"series": [
{
"valueKey": "数量",
"type": "bar",
"colorBy": "data",
"itemStyle": { "borderRadius": 6 },
"splitLine": { "show": false },
"axisLabel": { "show": false }
}
]
}
}
}
}
},
"config": { "full": false }
}

增加筛选器

修改数据查询逻辑

增加按时间范围查询

/data/app/flows/stat/product.flow.yao

{
"label": "产品",
"version": "1.0.0",
"description": "产品统计",
"nodes": [
{
"name": "总数",
"engine": "default",
"query": {
"select": [":COUNT(id) as 数量"],
"from": "$product",
"wheres": [
{ "field": ":TIME(created_at)", ">=": "?:$range[0]" },
{ "field": ":TIME(created_at)", "<=": "?:$range[1]" }
],
"first": true
}
},
{
"name": "分布",
"engine": "default",
"query": {
"debug": true,
"select": [":COUNT(id) as 数量", ":TIME(created_at) as 时刻"],
"from": "$product",
"wheres": [
{ "field": ":TIME(created_at)", ">=": "?:$range[0]" },
{ "field": ":TIME(created_at)", "<=": "?:$range[1]" }
],
"orders": "时刻",
"groups": "时刻"
}
}
],
"output": {
"IN": "{{$in}}",
"数量": "{{$res.总数.数量}}",
"分布": "{{$res.分布}}"
}
}
在 Query DSL 中使用上下文变量或参数表,使用 ?: 作为标识符。 例如: {{$range[0]}}, 在 Query DSL 中使用时, 写做 \?:$range[0]查阅 Query DSL 手册

运行调试

yao run flows.stat.product '::{"range":["08:00", "16:00"]}'

添加筛选器

增加按时间范围筛选,并设置为 TimePicker 组件。

/data/app/charts/stat.chart.yao

{
"name": "统计",
"action": {
"data": { "process": "flows.stat.product" }
},
"layout": {
"operation": { "actions": [] },
"filter": {
"columns": [{ "name": "时间区间", "width": 6 }]
},
"chart": {
"columns": [
{ "name": "产品数量", "width": 6 },
{ "name": "时刻分布", "width": 24 }
]
}
},
"fields": {
"filter": {
"时间区间": {
"bind": "range",
"edit": { "type": "TimePicker", "props": { "range": true } }
}
},
"chart": {
"产品数量": {
"bind": "数量",
"link": "/x/Table/product",
"view": { "type": "Number", "props": { "unit": "个" } }
},
"时刻分布": {
"bind": "分布",
"link": "/x/Table/product",
"view": {
"type": "Bar",
"props": {
"height": 240,
"nameKey": "时刻",
"axisLabel": { "interval": 0, "fontSize": 12 },
"series": [
{
"valueKey": "数量",
"type": "bar",
"colorBy": "data",
"itemStyle": { "borderRadius": 6 },
"splitLine": { "show": false },
"axisLabel": { "show": false }
}
]
}
}
}
}
},
"config": { "full": false }
}

添加 Hook 转换筛选器参数

添加一个 Befor Hook, 将参数转换为处理器需要格式。

在浏览器刷新图表路由地址访问:

http://<IP>:<YAO_PORT>/<管理后台路由前缀>/x/Chart/stat

添加一个 Hook 脚本用于转换参数。

/data/app/scripts/hook.js

/**
* Stat Hook
* @param {*} args
* @returns
*/
function FormatTime(args) {
log.Trace("[FormatTime] %v", args);
let range = args["range[]"] || [];
let start = range[0] ? range[0].split("T")[1].split("+")[0] : "08:00";
let end = range[1] ? range[1].split("T")[1].split("+")[0] : "18:00";
return [{ range: [start, end] }];
}

运行调试

yao run scripts.hook.FormatTime '::{"range[]":["2022-11-14T08:00:00+08:00", "2022-11-14T23:00:00+08:00"]}'

修改 Chart DSL 挂载 Hook

/data/app/charts/stat.chart.yao

{
"name": "统计",
"action": {
"before:data": "scripts.hook.FormatTime",
"data": { "process": "flows.stat.product" }
},
"layout": {
"operation": { "actions": [] },
"filter": {
"columns": [{ "name": "时间区间", "width": 6 }]
},
"chart": {
"columns": [
{ "name": "产品数量", "width": 6 },
{ "name": "时刻分布", "width": 24 }
]
}
},
"fields": {
"filter": {
"时间区间": {
"bind": "range",
"edit": { "type": "TimePicker", "props": { "range": true } }
}
},
"chart": {
"产品数量": {
"bind": "数量",
"link": "/x/Table/product",
"view": { "type": "Number", "props": { "unit": "个" } }
},
"时刻分布": {
"bind": "分布",
"link": "/x/Table/product",
"view": {
"type": "Bar",
"props": {
"height": 240,
"nameKey": "时刻",
"axisLabel": { "interval": 0, "fontSize": 12 },
"series": [
{
"valueKey": "数量",
"type": "bar",
"colorBy": "data",
"itemStyle": { "borderRadius": 6 },
"splitLine": { "show": false },
"axisLabel": { "show": false }
}
]
}
}
}
}
},
"config": { "full": false }
}

查看 Chart Widget 手册

添加菜单

编辑 /data/app/flows/app/menu.flow.yao 添加菜单项

查看源码

退出后台重新登录。

更新菜单