1. HENGSHI SENSE 嵌入式数据分析场景解决方案
1.1. 方案概览
要点 | 方案 | 参考 | 备注 |
---|---|---|---|
账号打通 | 对接SSO认证方式,解决应用身份与用户身份的统一认证问题,提供安全可靠的用户身份认证和用户身份传递 | SSO文档 | |
单点登录 | 对接SSO认证方式,解决应用身份与用户身份的统一认证问题,提供安全可靠的用户身份认证和用户身份传递 | SSO文档 | |
功能权限 | 利用用户角色管理 | 用户管理文档 | |
数据权限 | 利用数据连接; 或者利用应用发布权限控制; 或者直接使用发布页面嵌入的参数控制 |
连接权限权限 发布权限控制 本文档“发布页面嵌入数据过滤指南”部分 |
|
创作页面嵌入 | 将衡石产品的链接嵌入iframe,并加属性 name="export".例如 https://preview.hengshi.com/app 的 iframe 写成 <iframe src="https://preview.hengshi.com/app" name="export"></iframe> | 创作区页面不支持移动端嵌入 | |
发布页面嵌入 | 支持类似创作区页面的嵌入方式;或者利用发布区页面的分享按钮获取嵌入链接,用iframe方式嵌入 | 应用分享嵌入 | 发布区页面支持页面自适应适配 |
API支持 | 衡石系统支持客户端模式的Restful API | API文档 |
备注:
- 页面嵌入支持参数,包括数据过滤和样式定制化两类,下面会分别阐述
- 需要的API清单需要集成方从产品角度考虑,建议尽量采用页面集成的方式,避免API的复杂性;
- 在用户角色用户组端,集成方需要考虑功能权限的问题:将用户信息同步到衡石系统;用户注册/删除都将触发衡石API的调用,用户角色修改;用户组的协调
1.2. 分层级嵌入的功能
1.2.1. 1. 平台整体嵌入
在这种应用场景中,把所有功能通过iframe的方式都开放给登陆用户,嵌入的示例如下:
<iframe name="" src="https://preview.hengshi.com/app/1">
1.2.2. 2. 单个模块嵌入
在这种应用场景中,把一个一级功能通过iframe的方式开放给登陆用户,嵌入的示例如下:
<iframe name="export,noHeader" src="https://preview.hengshi.com/app/1">
通过指定name="noHeader"
,嵌入的页面将隐藏最顶端的banner以及一级功能的切换菜单。
1.2.3. 2. 单个实体嵌入
<iframe name="export,noHeader,noRoute" src="https://preview.hengshi.com/app/1"></div>
在这种应用场景中,把一个实体通过iframe的方式开放给登陆用户。实体的种类可以是一个app,或者一个数据连接,或者是一个数据科学笔记本,也可以是一个已发布的应用。 嵌入的示例如下:
通过指定name="noRoute"
,嵌入的页面将隐藏功能目录切换的入口。用户的操作就限制在一个应用内部。
1.3. 使用appParam传入参数信息
在仪表盘制作过程中会使用参数控制仪表盘内容的展示。在嵌入场景下,可以通过appParam将参数信息拼接到URL后面,系统在预览时会将appParam中的参数信息转发到最终执行的SQL代码中,查看不同参数值下的仪表盘数据信息。
appParam是数组,可包含多个项目,每个项目是一个object,为一个参数信息,由3个键值构成。参数可通过id或name来指定,所以appParam的object支持两种形式{"appId":1,"id":1,"value":"参数值"}
或{"appId":1,"name":"参数名称","value":"参数值"}]
。
每个键值代表的含义如下:
appId
是创建参数的数据包或应用的ID。id
是参数的id
,可通过网络请求消息获取。name
是参数名称。value
是参数值,类型与参数类型保持一致。
嵌入的URL和appParam拼接后格式为嵌入url?appParam=[{"appId":1,"name":"参数名称","value":"参数值"}]
appParam使用说明
- appParam中可使用参数id或参数name来确定参数,二者选一个即可。
- appParam的appId指的是参数创建时的应用ID,不是参数使用中的应用ID。如参数在数据集市中数据包A(appId为3)中创建,在应用创作中应用A(appId为5)中使用,那么在appParam中需要输入的appId为3。
- appParam的appId和参数id(或参数名称)一起确定参数,如果appId省略,可能会导致结果不正确。
- appParam中支持传入多个参数。
1.3.1. appParam举例
参数控制仪表盘内容展示的方式有很多种,可参照参数使用场景中介绍的方法。 下面以数据集制作图表过程中使用参数为例,介绍如何在嵌入场景下通过appParam传入参数。
如图所示,在某医院的就诊信息展示过程中,诊室和出诊医生信息使用科室参数进行内容控制,当改变科室参数时,图表的信息会跟随改变。
仪表盘的URL地址为https://develop.hengshi.org/app/127572/dashboard/93
,展示内容如下:
使用appParam传入科室参数,仅展示消化内科、神经内科两个科室的信息,在URL后面拼接appParam为https://develop.hengshi.org/app/127572/dashboard/93?appParam=[{"appId":127572,"name":"科室参数","value":["消化内科","神经内科"]}]
,仪表盘展示如下。
当appParam中包含多个参数,如通过科室参数控制科室相关信息,通过地域参数控制就诊用户地域相关信息。 此时拼接后的URL为https://develop.hengshi.org/app/127572/dashboard/93?appParam=[{"appId":127572,"name":"科室参数","value":["消化内科","神经内科"]},{"appId":127572,"name":"地域参数","value":["北京","天津"]}]
,仪表盘展示如下。
1.4. 发布页面嵌入数据过滤指南
在访问或者嵌入衡石智能分析平台仪表盘/图表的时候,可以在URL中添加参数,实现和仪表盘/图表中过滤器类似的功能。下面列举示例介绍,并做详细解释。
1.4.1. 示例
{%raw%}https://preview.hengshi.com/share/3B4888A0/dashboard/FC3BBDE7?where=[{%22args%22:[{%22kind%22:%22field%22,%22op%22:%22_c7%22},{%22kind%22:%22constant%22,%22op%22:[%22%E7%AB%A3%E5%B7%A5%22]}],%22datasetId%22:961,%22fieldName%22:%22_c7%22,%22kind%22:%22function%22,%22op%22:%22in%22,%22use%22:%22checkbox%22}]{%endraw%}
这个例子里,具体参数为
[
{"args": [
{"kind": "field",
"op": "_c7"
},
{"kind": "constant",
"op": [
"竣工"
]
}
],
"datasetId": 961,
"fieldName": "_c7",
"kind": "function",
"op": "in",
"use": "checkbox"
}
]
含义为过滤_c7字段值为"竣工"的记录。参数的具体解释参考下面的HQL部分。
下面介绍下获取这个参数的一个简单方法:
打开Chrome浏览器的“开发者工具”,输入URL:https://preview.hengshi.com/share/3B4888A0/dashboard/FC3BBDE7
打开过滤器,选择项目阶段,并选择值为“竣工”
然后查看"开发者工具"的"Network" tab,选择对应的chart data接口,查看Headers里面的请求参数:
找到如上图所示的where部分,将它的值JSON.stringify后传给URL的where参数即可,参考上面的示例。
1.4.2. HQL 简介
仪表盘URL参数值的语法用的是衡石计算过程描述语言Hengshi SENSE Query Language (HQL) 。在这里,简单介绍一下HQL的语法规则,详情请参考API文档
语法规定
使用统一的 JSON 来描述各个计算过程. HQL 由多个递归的 HE (Hengshi Expression) 组成.
定义
HE: {
"uid": "本节点的全局唯一标识符",
"kind" "节点类型, 可以是 function, field, constant, setgroup, rangegroup, formula, reference 中的任意一种",
"op", "function类型的函数名, field类型的字段名, constant类型的具体值, setgroup和rangegroup的来源列, formula的公式, reference的指向uid",
"args": "function 类型的参数, 其他类型节点此项为null",
"type": "指定这个节点的数据类型, 可以是string, number, integer, date, time, json, bool 中的一种",
"value": "只有rangegroup和setgroup有这个字段"
"其他": "特定类型的字段还有各自额外的参数, 另行约定"
}
quickstart
下面看具体的例子. 比如, 我要执行一个 select f1, f2::float * 100 as percent from table 的操作:
options.axes = [
{
"kind": "field",
"op": "f1",
},
{
"kind": "field",
"op": "*",
"type": "integer",
"args": [
{
"kind": "field",
"op": "f2",
"type": "number"
},
{
"kind": "constant",
"op": 100
}
],
"uid": "percent"
}
]
对于上述例子, 我们可以对其进行简写:
options.axes = [
"f1",
{
"kind": "function",
"op": "*",
"args": ["f2", 100]
}
]
或者
options.axes = [
"f1",
{
"kind": "formula",
"op": "{f2} * 100"
}
]
field
{
"kind": "field",
"op": "field1"
}
或dataset5.field
{
"kind": "field",
"op": "field1",
"args": [{"kind":"dataset", "op":5}]
}
where 过滤
如果需要过滤 price > 20 的商品:
where = [
{
"kind": "function",
"op": ">",
args[
{
"kind":"field",
"op": "price",
},
{
"kind": "constant",
"op": 20
}
]
}
]
当然, 也可以缩写成:
where = [
{
"kind": "function",
"op": ">",
"args": ["time", {"kind":"constant", "op":"2018-12-31", "type": "date"}]
}
]
或者
where = [
{
"kind": "formula",
"op": "{price} > 20"
}
]
having 过滤
如果需要过滤 price > 20 的商品:
having = [
{
"kind": "function",
"op": "notin",
args[
{
"kind":"reference",
"op": "x1",
},
{
"kind": "constant",
"op": [1, 2, 3]
}
]
}
]
当然, 也可以缩写成:
having = [
{
"kind": "function",
"op": "notin",
"args": [{"kind": "reference"}, [1, 2, 3]]
}
]
或者
having = [
{
"kind": "formula",
"op": "{x1} notin [1, 2, 3]"
}
]
1.5. 发布页面嵌入样式定制化指南
使用衡石智能分析平台制作好Dashboard和Chart以后,可以通过iframe的方式嵌入到已有系统中。为了达到风格统一,嵌入iframe的时候支持丰富的定制化选项。
1.5.1. 定制Dashboard的iframe
参数列表
仪表盘嵌入时支持以下参数。
参数名 | 参数作用 | 参数类型 | 参数值 |
---|---|---|---|
copyright | 该参数控制仪表盘页头、页脚显示状态。 | Boolean | 参数取值: true 显示页头页脚,默认为true。 false 不显示页头页脚。 |
header | 该参数控制仪表盘页头显示状态。 | Boolean | 参数取值: true 显示页头,默认为true。 false 不显示页头。 |
pager | 该参数控制仪表盘翻页器显示状态。 | Boolean | 参数取值: true 显示翻页器,默认为true。 false 不显示翻页器。 |
scrollable | 该参数控制仪表盘内滚动行为。 | Boolean | 参数取值: true 支持在仪表盘内滚动,默认为true。 false 不支持在仪表盘内滚动。 |
chartAccessible | 该参数控制仪表盘的图表交互行为。 | Boolean | 参数取值: true 支持打开图表,进行图标交互。 默认为true。 false 不支持打开图表进行图表交互。 |
background | 通过该参数设置仪表盘背景色,如果仪表盘主题已经设置背景色,则该参数不生效。 | String | 参数取值样式为rgba(255,255,255,1)。 |
wrapperBackground | 通过该参数设置仪表盘父级div元素背景色,可以覆盖仪表盘主题背景色。 | String | 参数取值样式为rgba(255,255,255,1)。 |
chartTitleColor | 通过该参数可以设置图表标题颜色,作用范围是仪表盘内所有图表标题(过滤器除外),请谨慎使用。 | String | 参数取值样式为rgba(255,255,255,1)。 |
chartGap | 通过该参数可以设置仪表盘内图表之间的间距。 | String | 参数使用时需要包含像素信息,如10px。 |
以下是仪表盘嵌入场景中的废弃参数。
参数名 | 参数作用 | 参数类型 | 参数值 | 废弃说明 |
---|---|---|---|---|
padding | 该参数设置仪表盘内边距。 | String<number> |
参数取值样例0 0 0 0 | 不再支持该参数。 |
chartBackground | 该参数设置内图表控件背景色。 | String | 参数取值样例rgba(255,255,255,1) | 不再支持该参数。 |
chartPadding | 该参数设置图表内边距。 | String<number> |
参数取值样例0 0 0 0 | 不再支持该参数。 |
borderRadius | 该参数设置图表控件圆角大小。 | String | 参数取值样例2px | 遵循仪表盘主题设置。 |
borderWidth | 该参数设置图表外边框大小。 | String | 参数取值样例1px | 遵循仪表盘主题设置。 |
borderColor | 该参数设置图表外边框颜色。 | String | 参数取值样式rgba(255,255,255,1) | 遵循仪表盘主题设置。 |
borderStyle | 该参数设置图表外边框样式。 | String | 可设置solid、dashed、dotted | 遵循仪表盘主题设置。 |
filterPadding | 该参数设置过滤器内边距。 | String<number> |
参数取值样例0 0 0 0 | 不再支持该参数。 |
例子
如下图所示仪表盘,在嵌入时对其背景颜色及图表标题颜色进行修改 。
原始仪表盘链接及样式:
https://preview.hengshi.com/private/share/E454FF2E910B7B9445C8F66391B25CCA/dashboard/EC0E826AB75FD2AA2C3D755CF8374DD6C
嵌入后仪表盘链接及样式:
https://preview.hengshi.com/private/share/E454FF2E910B7B9445C8F66391B25CCA/dashboard/EC0E826AB75FD2AA2C3D755CF8374DD6C?wrapperBackground=rgba(180,246,254,1)&chartTitleColor=rgb(0,0,0)©right=false&scrollable=false>
1.5.2. 定制Chart的iframe
参数列表
图表嵌入时支持以下参数。
参数名 | 参数作用 | 参数类型 | 参数值 |
---|---|---|---|
showAction | 该参数设置右上角交互按钮。 | Boolean | 参数取值: true 显示右上角交互按钮,默认为true。 false 不显示右上角交互按钮。 |
chartPadding | 该参数设置图表内边距。 | String<number> |
参数取值样例0 0 0 0。 |
以下参数为废弃参数,不再支持。
参数名 | 参数作用 | 参数类型 | 参数值 | 废弃说明 |
---|---|---|---|---|
noFilter | 该参数控制是否展示过滤器。 | Boolean | 参数取值: true 显示过滤器,默认为true。 false 不显示过滤器。 |
嵌入图表时不再支持展示过滤器。 |
titleColor | 该参数设置图表标题颜色展示。 | String | 参数取值样式rgba(255,255,255,1)。 | 嵌入页面不再展示图表标题。 |
chartBackground | 该参数设置图表背景色。 | String | 参数取值样式rgba(255,255,255,1)。 | 图表背景色会被图表使用的主题背景色覆盖。 |
1.6. 动态改变嵌入URL指南
嵌入场景中,经常会遇到根据业务和交互需要,动态修改嵌入页面URL的情况。针对这种需求,HENGSHI SENSE嵌入的页面支持以下2种方式动态修改嵌入iFrame的URL。
1.6.1. PostMessage
嵌入过程中可以使用PostMessage动态修改嵌入页面的URL,支持hs_urlpush
和hs_urlchange
两种方式。使用PostMessage动态修改嵌入页面URL时不会重新加载页面。
URL push
下面是在PostMessage中使用hs_urlpush
方式动态修改页面URL的示例。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Local Test</title>
<style>
h2 {
font-size: 16px;
font-weight: normal;
color: #999;
}
h2 i {
color: #333;
}
</style>
</head>
<body>
<button onClick="onUrlFilterChange()">发事件</button>
<iframe
allowFullScreen="true"
width="1280"
height="800"
frameborder="0"
id="iframe"
src="http://192.168.2.243:9998/share/2351A2F5/infographic/46CA0B3B">
</iframe>
<script>
var $iframe = document.getElementById('iframe');
function onUrlFilterChange() {
var pathname = '/share/2351A2F5/infographic/46CA0B3B';
var search = `?where=[{"field":{"fieldName":"_c6","dataset":39713,"label":"time","type":"date"},"dataset":39713,"kind":"function","op":"in","args":[{"kind":"function","op":"dow","args":[{"kind":"field","op":"_c6","dataset":39713}]},{"kind":"constant","op":[${randomNumber(1, 7)}, ${randomNumber(1, 7)}]}]}]`;
$iframe.contentWindow.postMessage(JSON.stringify({
event: 'dispatchCustomEvent',
data: ['hs_urlpush', {
pathname: pathname,
search: search,
}],
}), '*');
}
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
</script>
</body>
</html>
URL change
系统也支持在PostMessage中使用hs_urlchange
方式动态修改页面URL,参考示例如下。
// JSON.parse(event.data) 后:
{
event: 'HengshiInteractiveEvent',
data: {
event: 'hs_urlchange',
data: {
pathname: '/app/xxx?aa=bb',
search: '?aa=bb'
query: {
aa: 'bb',
},
},
},
}
1.6.2. 直接修改iframe.src
可以通过直接编辑iframe url来实现嵌入页面URL的动态变化,效果和使用ontentWindow.postMessage是一样的,只是该方法会使页面重新加载,对性能会略有影响。
$iframe.src = 'http://preview.hengshi.com' + pathname + search;
1.7. 嵌入页面的外部控制
衡石支持使用外部按钮来操作嵌入页面,包括刷新页面内容、导出页面PDF、PNG等。
1.7.1. 刷新页面
客户嵌入的页面需要刷新仪表盘数据,但是又不希望重新加载iframe,此时可以通过外部按钮进行刷新。下面是通过外部按钮刷新嵌入页面的代码示例和展示样式,供参考。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>Refresh</button>
<iframe
frameborder="0"
importance="high"
allowFullScreen="true"
width="1080"
height="800"
src="https://develop.hengshi.org/private/share/app/EAD43BC71B87137928BB1D7D62E639078">
</iframe>
<script>
const button = document.querySelector('button');
// 1. 从iframe外部点击按钮
button.addEventListener('click', () => {
const iframe = document.querySelector('iframe');
// 2. 给iframe发送刷新仪表盘的信息
iframe.contentWindow.postMessage(JSON.stringify({
event: 'dispatchCustomEvent',
// 3. 刷新仪表盘标识符 `hs_dashboard_refresh`
data: ['hs_dashboard_refresh', {}]
}), '*');
});
</script>
</body>
</html>
1.7.2. 导出仪表盘PDF/PNG
嵌入页面可以通过外部按钮导出仪表盘的PDF和PNG。下面是相关代码示例和展示截图。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="exportPNG">Export PNG</button>
<button id="exportPDF">Export PDF</button>
<iframe
frameborder="0"
importance="high"
allowFullScreen="true"
width="1080"
height="800"
src="https://develop.hengshi.org/private/share/app/EAD43BC71B87137928BB1D7D62E639078">
</iframe>
<script>
document.addEventListener('click', e => {
if (!['exportPNG', 'exportPDF'].includes(e.target.id)) return;
// 获取导出类型、pdf或png
const type = e.target.id === 'exportPNG' ? 'png' : 'pdf';
const iframe = document.querySelector('iframe');
// 发送导出事件message
iframe.contentWindow.postMessage(JSON.stringify({
event: 'dispatchCustomEvent',
data: ['hs_dashboard_export', {
type,
}]
}), '*');
});
</script>
</body>
</html>
1.8. 监听嵌入页面的事件
在页面交互过程中,使用 postMessage 广播以下事件以方便更好的与业务融合,在业务页面使用 window.addEventListener('message', function handlePostMessage(event) {})
来监听我们广播出的事件:
- 点击系统元素,点击对象为应用、文件夹、仪表盘、图表、数据集
- URL change
handlePostMessage
收到的 event 是 JavaScript 的 MessageEvent
,其中 event.data
即为广播内容,event.data
是经过序列化的 JSON 字符串,经过 JSON.parse(event.data)
即可使用。
1.8.1. 点击系统元素
// JSON.parse(event.data) 后:
{
event: 'HengshiInteractiveEvent',
data: {
event: 'clickItem',
data: {
type: 'app',
data: {
id: xxx,
...
},
},
},
}
其中 type
是指所点击元素的类型,除 app 外还有
- publishApp: 发布的应用
- dashboard: 仪表盘
- chart: 图表
- publishChart: 发布的图表
- dataset: 数据集
- folder: 文件夹
- datamart: 数据包
results matching ""
No results matching ""
衡石文档
- 产品功能一览
- 发布说明
- 新手上路
- 安装与启动
- 系统管理员手册
- 数据管理员手册
- 分析人员手册
- 数据查看员手册
- 数据服务
- 最佳实践
- 衡石分析平台 API 手册
- 附录