1、基础要求
(1)通过安装包:node-v16.14.2-win-x64.zip 安装node环境,详情可参考:node环境安装文档;
(2)此版本已经自带npm,对于二开人员:
2、环境配置
(1)进入扩展包根目录的src;
(2)解压webpack项目,打开终端控制台cd 到webpack目录,运行下载smartbi二开环境基础包命令:
npm install smartbi-ext-env
得到的目录结构如下:
在二开环境中,常用命令如下:
3、开发调试
运行开发调试命令:
每当代码修改的时候,系统会帮你自动编译,刷新页面即可看到新的效果。
3.1 常见问题
问题:为什么改了代码,没有效果?
解决方法:请仔细查看以下几个步骤:
1、如果要调试smartbi,最好在url中增加debug=true参数(如:http://192.168.1.10:16000/smartbi/vision/index.jsp?debug=true),否则扩展包会有缓存,代码修改后不会更新。
2、配置extension.list;
3、修改SmartbiPluginApp/apache-tomcat-7.0.42/webapps/smartbi/WEB-INF下的web.xml文件:
- 在文件中加入 DevEnv 对应的四行代码;
- 在文件中找到 ProductName 的 <context-param>;
- 在其下面添加 DevEnv 对应的四行<context-param>,其值为 true。
具体调试技巧可参考:调试&定位技巧。
4、仪表盘组件新增和修改
4.1 组件新增示例
4.1.1 入门版
(1)需求场景
在仪表盘的组件选择器中,新增一个组件,组件中显示一个简单的文字hello。
(2)示例效果
(3)操作步骤
a.在根目录下的src/webpack/src/plugins/addExtenders中创建组件文件夹:
- 添加文件夹helloView
- 在文件夹下创建index.js及HelloView.vue
b.在index.js文件中实现providerMetaInfo方法,返回的是一个对象,具体对象的属性可以参考仪表盘组件接口文档;
import HelloView from './HelloView.vue'
const provideMetaInfo = () => { //入口方法
return {
name: '模版DEMO', // 组件名称
type: 'HELLO', // 组件类型(不能轻易修改)
svg: 'db-left-widget__chart-pie',
entry: { // 组件入口,可以从仪表盘工具栏中直接添加(不配置就只能通过智能配图切换出来)
title: 'Hello入口', // 在组件入口中显示的名称,不填显示组件名称
order: 15, // 组件入口中的顺序,默认放在最后
},
// 组件文件
portletImplement:HelloView
}
}
export default {
provideMetaInfo
}
c.在HelloView.vue中编写自己的业务代码
<template>
<div>hello</div>
</template>
<script>
export default {
name: 'hello'
}
</script>
4.1.2 简单版
(1)需求场景
在仪表盘的组件选择器中,新增一个清单表组件,具备取数功能。
(2)示例效果
(3)操作步骤
a.在根目录下的src/webpack/src/plugins/addExtenders下创建组件文件夹:
- 添加文件夹newTableView;
- 在文件夹下创建index.js及NewTableView.vue;
b.在index.js文件中实现providerMetaInfo方法,返回的是一个对象,具体对象的属性可以参考仪表盘组件接口文档;
import NewTableView from './NewTableView.vue'
function provideMetaInfo () {
return {
name: '新清单表', // 组件名称
type: 'NEW_TABLE', // 组件类型
svg: 'db-left-widget__table-list',
icon: 'sx-icon-widget-table-list icon-16',
class: 'TABLE_LIST',
entry: { // 组件入口
id: 'Table', // 组件入口中的分类类别 Chart | Table | Indicator,默认为Custom
index: 1, // 组件入口中的顺序,默认放在最后,注意:这里是分类中包含所有子类型的排序
canSwitch: true // 是否能切换组件
},
freeSize: {
width: 400,
height: 260
},
fieldRules: [{ // 字段区配置,可以理解为行列区和标记区配置
areaType: 'cols',
tips: '',
rule: {
fieldCount: {
min: 0
}
}
}],
// 组件文件
portletImplement: NewTableView
}
}
export default {
provideMetaInfo
}
(说明:fieldRules:是字段区配置,可以理解为行列区和标记区规则配置)
c.在NewTableView.vue中编写自己的业务代码:
- Smartbi 节点下main节点下,refresh方法,是系统通知组件更新的一个时机
- this.pageProxy.api.fetchPortletData(queryFields)是组件主动调用系统取数api,进行取数。
<template>
<div slot="notEmpty" style="height: 100%;" >
<table v-if = "gridDataModel">
<th>
<td
v-for="field in gridDataModel.getFields()"
:key="field.uniqueId">
{{ field.alias }}
</td>
</th>
<tr
v-for="row in gridDataModel.getRowCount()"
:key="row">
<td
v-for="field in gridDataModel.getFields()"
:key="row + field.uniqueId">
{{ gridDataModel.getDisplayValueByRowAndUid(row - 1, field.uniqueId) }}
</td>
</tr>
</table>
</div>
</template>
<script>
export default {
name: 'NewTableView',
data () {
return {
options: {},
gridDataModel: null
}
},
props: {
pageProxy: {}
},
smartbi: {
main: {
refresh () {
this.fetchData()
}
}
},
methods: {
async fetchData () {
console.log(123)
let queryFields = this.generateQueryFields()
if (queryFields.length === 0) {
return
}
let options = await this.pageProxy.api.fetchPortletData(queryFields)
let {
gridDataModel, // 二维表模型,提供基本的数据获取方法
gridData, // 原始二维表对象
queryFields: fields, // 实际取数查询的字段
drillableFields, // 可下钻字段
drilledFieldPath // 当前下钻字段路径
} = options
this.options = options
this.gridDataModel = gridDataModel
// 刷新取数完成后需调用commitRefresh通知系统该组件已完成刷新,否则可能影响导出截图和定时刷新功能
this.pageProxy.portlet.commitRefresh(true)
},
generateQueryFields () {
let queryFields = this.pageProxy.field.getFieldsByZones(['cols'])
// 不需要groupBy的字段如提示区的字段可通过接口生成对应的groupBy字段,在取数时不groupBy
let tooltipFields = this.pageProxy.field.getFieldsByZone('tooltip')
return queryFields.concat(tooltipFields.map(field => {
return this.pageProxy.field.createGroupByField(field, false)
}))
}
}
}
</script>
4.2 功能修改示例
(1)需求场景
在仪表盘预览菜单栏,点击工具栏弹出hello
(2)示例效果
(3)操作步骤
a.在根目录下的src/webpack/src/plugins/modifyExtenders下创建组件文件夹,下面以仪表盘预览菜单栏为例:
- 添加文件夹dashFlexMenuExtension;
- 在文件夹下创建index.js及FlexMenuExtension.js两个文件;
b.在index.js文件中实现provdieMetaInfo方法,FlexMenuExtension.vue导出的是一个FlexMenuExtension对象:
import FlexMenuExtension from './FlexMenuExtension'
const provideMetaInfo = () => {
// 二开文件
return { implement: FlexMenuExtension}
}
export default {
provideMetaInfo
}
c.FlexMenuExtension.j s:
import SmartBIExt from 'smartbi-ext'
let {
DashModule: {
DashEventEmum: {
PAGE_ON_FLEX_MENU_INIT
},
BaseDashExtender
}
} = SmartBIExt
class FlexMenuExtender extends BaseDashExtender {
constructor() {
super()
}
install () {
// page菜单初始化
this.on(PAGE_ON_FLEX_MENU_INIT, iFlexMenu => {
iFlexMenu.removeItem(1)
iFlexMenu.insertItem(3, {
id: 'TEST',
icon: 'sx-icon-like',
label: '测试',
color: '#ed6b1f',
handler: () => {
alert('测试按钮')
}
})
})
}
}
export default FlexMenuExtender