页面树结构

版本比较

标识

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。

...

Markdown
# V11X 模块扩展接口场景示例

# 入门文档:

[自助仪表盘二次开发快速入门](https://smartbi.feishu.cn/docs/doccnY0Tuaqlq9WPLksPflegeUh)

# 详细接口文档

[V11【X 模块】二次开发扩展接口文档 V2.0.0](https://smartbi.feishu.cn/docx/WhyUdyHAcomRsAxTe3WcJbaDnQg)

[https://smartbi.feishu.cn/docs/doccnY0Tuaqlq9WPLksPflegeUh](https://smartbi.feishu.cn/docs/doccnY0Tuaqlq9WPLksPflegeUh)

# 组件开发示例扩展包:(需要云桌面才能访问)

[二次开发示例扩展包:](https://smartbi.feishu.cn/docs/doccncQcTsEJ6sNXyeraYiqyWrd)

# 添加扩展器

在 SmartbiPluginsApp/webpack/src/plugins/modifyExtenders 下添加文件夹 DashExtender,并在文件夹下创建 `index.js` 及 `Extender.js` 两个文件,文件内容如下

- index.js

```javascript
import Extender from './Extender'

const provideMetaInfo = () => {
  return {
    implement: Extender
  }
}

export default {
  provideMetaInfo
}
```

- Extender.js

```javascript
import SmartBIExt from  'smartbi-ext'
import  * as Element from 'element-ui'
let {
  Utils: { //工具方法
    ExtensionUtil: { documentLoadResource, rmi }
  },
  InterfaceObject: {
    IGlobal //全局接口
  },
  Frameworks: {
    ECharts
  }
  Lang, //多语言
  Libs: { //包
    Lodash, 
    Debounce,
    Axios
  },
  DashModule: {
   DashEventEmum: {
     DASHBOARD_WIDGET_PANEL_INIT,//组件面板初始化
     DASHBOARD_COMPONENT_SELECTION_AREA_INIT,//组件选择面板初始化
     DASHBOARD_ON_TOOLBAR_INIT,//仪表盘工具栏初始化
     DASHBOARD_ON_READY,//仪表盘加载完成
     DASHBOARD_ON_SAVE_DIALOG_INIT,//仪表盘保存框初始化
     DASHBOARD_ON_PAGE_THEME_PANEL_INIT,//仪表盘页面主题初始化
     PAGE_TOOLBAR_INIT,//页面工具栏初始化
     PAGE_ON_INIT,//页面初始化
     PAGE_ON_PORTLET_INIT,//组件初始化
     PAGE_ON_PORTLET_TOOLBAR_INIT,//组件工具栏初始化
     PAGE_ON_PORTLET_MENU_SHOW,//组件菜单初始化
     PAGE_BEFORE_EXPORT, //组件导出前
   },
   BaseDashExtender
   },
 CommonModule: {
  CommonEventEmum: {
    COMMON_DATASET_PANEL_INIT,//公共数据面板初始化
    COMMON_SHRINKBAR_INIT,//公共折叠面板初始化
    COMMON_SHRINKBAR_CHANGE,//公共折叠面板改变
    COMMON_SETTING_PANEL_INIT,//公共组件设置面板初始化
    COMMON_DATASET_SELECTOR_INIT//公共组件选择面板初始化
  }
 },
class DashExtenter extends BaseDashExtender {
  install () {
    console.log('extenter install') // 仪表盘初始化时打印 => extenter install
  }
}
export default DashExtenter
```

# 数据面板相关场景

## 过滤下拉菜单的操作按钮

<strong>示例代码:</strong>

```javascript
import SmartBIExt from  'smartbi-ext-x'
let {
  DashModule: {
    BaseDashExtender
  },
  CommonModule: {
    CommonEventEmum: {
      COMMON_DATASET_PANEL_INIT,
    }
  }
} = SmartBIExt

class DataSetPanelExtender extends BaseDashExtender {

  install () {
    // 监听数据面板事件
    this.on(COMMON_DATASET_PANEL_INIT, async (iDataSetPanel) => {
      // 过滤下拉按钮
      iDataSetPanel.setDropDownBtnsFilter(btn => btn.id !== 'EDIT' && btn.id !== 'CREATE_AUGMENT')
    })
  }  
}
export default DataSetPanelExtender
```

## 禁用数据集选择

<strong>示例代码:</strong>

```javascript
class DataSetPanelExtender extends BaseDashExtender {
  install () {
    // 监听数据面板事件
    this.on(COMMON_DATASET_PANEL_INIT, async (iDataSetPanel) => {
     iDataSetPanel.setSelectDatasetDisabled(true)
    })
  }  
}
export default DataSetPanelExtender
```

## 打开数据选择面板

<strong>示例代码:</strong>

```javascript
class DataSetPanelExtender extends BaseDashExtender {

  install () {
    // 监听数据面板事件
    this.on(COMMON_DATASET_PANEL_INIT, async (iDataSetPanel) => {
      iDataSetPanel.openDatasetSeletor()
    })
  }  

}
```

# 数据选择面板相关场景

## 设置数据面板显示内容(只显示某个目录的数据)

<strong>示例代码:</strong>

```javascript
class DataSetPanelExtender extends BaseDashExtender {
  install () {
    this.on(COMMON_DATASET_SELECTOR_INIT, async (iDataSeletor) => {
      iDataSeletor.setRootNodeId('I8a8a918a016f598d598d6bb5016f5993bf700728')
    })
  }  
}
```

## 设置节点过滤方法

<strong>示例代码:</strong>

```javascript
class DataSetPanelExtender extends BaseDashExtender {
  install () {
    this.on(COMMON_DATASET_SELECTOR_INIT, async (iDataSeletor) => {
     iDataSeletor.setNodeFilter((item) => {
        if (item.type !== 'SELF_TREENODE') {
          return true
        }
      })
    })
  }  
}
```

## 设置搜索节点过滤方法

<strong>示例代码:</strong>

```javascript
class DataSetPanelExtender extends BaseDashExtender {
  install () {
    this.on(COMMON_DATASET_SELECTOR_INIT, async (iDataSeletor) => {
      iDataSeletor.setSearchNodeFilter(item => {
        if (item.idPath.indexOf(`I8a8a9f0b017f208d208d3641017f20922aa6003c`) > -1) {
          return false
        }
        return true
      })
    })
  }  
}
```

# 导出相关场景

## 页面和组件导出

<strong>示例代码:</strong>

```javascript
class ExportExtender extends BaseDashExtender {
  install () {
    //  页面导出
    this.on(PAGE_ON_BEFORE_EXPORT, (iPage, params) => {
      this.page.execExport(params)
    })
    // 组件导出
    this.on(PAGE_ON_PORTLET_BEFORE_EXPORT, (iPortlet, params) => {
      this.page.execExport(params)
    })
  }  
}
```

# 页面工具栏相关场景

## 添加按钮

<strong>示例代码</strong>

```javascript
class PageToolbarExtension extends BaseDashExtender {
  install () {
    //  page菜单初始化
    this.on(PAGE_TOOLBAR_INIT, iPageToolbar => {
       iPageToolbar.addItem({
        id: 'TEST1',
        icon: 'sx-icon-like',
        label: '测试',
        color: '#ed6b1f',
        handler: () => {
          alert('测试按钮')
        }
      })
    }  
}
```

## 插入按钮

<strong>示例代码</strong>

```javascript
class PageToolbarExtension extends BaseDashExtender {
  install () {
    //  page菜单初始化
    this.on(PAGE_TOOLBAR_INIT, iPageToolbar => {
      iPageToolbar.insertItem(3, {
        id: 'TEST',
        icon: 'sx-icon-like',
        label: '测试',
        color: '#ed6b1f',
        handler: () => {
          alert('测试按钮')
        }
      })
    }  

}
```

## 删除按钮

<strong>示例代码</strong>

```javascript
class PageToolbarExtension extends BaseDashExtender {
  install () {
    //  page菜单初始化
    this.on(PAGE_TOOLBAR_INIT, iPageToolbar => {
        iPageToolbar.removeItem(1)
      })
    }  
}
```

# 折叠面板相关场景

## 页面设置激活的 tab 设置为主题 tab

<strong>示例代码:</strong>

```javascript
class ShrinkbarExtension extends BaseDashExtender {
  install () {
      this.on(COMMON_SHRINKBAR_INIT, (iShrinkbar) => {
        let items = iShrinkbar.getItems()
        let activeItems =  iShrinkbar.getActiveItems()
        activeItems[0].active = 'THEME'
        iShrinkbar.setActiveItems(activeItems)
      })
    }
}
```

# 仪表盘工具栏相关场景

![](https://wiki.smartbi.com.cn/download/attachments/115002486/D2KRbVT8Go8l5nxXWzEcpeLDn8e.png)

## 在第零组添加按钮

<strong>示例代码</strong>

```javascript
class  ToolbarExtender extends BaseDashExtender {
  install () {
  // 添加工具栏按钮
    this.on(DASHBOARD_ON_TOOLBAR_INIT, iToolbar => {
      iToolbar.addItem(2, {
        id: 'TEST',
        icon: 'sx-icon-like',
        label: '测试',
        handler: () => {
          alert('测试按钮')
        }
     }, 0)
  }
 }
```

## 在第四组删除按钮

<strong>示例代码</strong>

```javascript
class  ToolbarExtender extends BaseDashExtender {
  install () {
  // 添加工具栏按钮
    this.on(DASHBOARD_ON_TOOLBAR_INIT, iToolbar => {
      iToolbar.addItem(2, {
        id: 'TEST',
        icon: 'sx-icon-like',
        label: '测试',
        handler: () => {
          alert('测试按钮')
        }
     }, 0)
  }
 }
```

## 在第一组插入按钮

<strong>示例代码</strong>

```javascript
class  ToolbarExtender extends BaseDashExtender {
  install () {
  // 添加工具栏按钮
    this.on(DASHBOARD_ON_TOOLBAR_INIT, iToolbar => {
      iToolbar.removeItem(0, 4)
  }
 }
```

# 主题相关场景

## 过滤主题项

过滤主题面板

```scala
import SmartBIExt from  'smartbi-ext-x'
let {
  DashModule: {
    DashEventEmum: {
      DASHBOARD_ON_PAGE_THEME_PANEL_INIT
    },
    BaseDashExtender
  }    
} = SmartBIExt
class DataPortal extends BaseDashExtender {
    this.on(DASHBOARD_ON_PAGE_THEME_PANEL_INIT, (iPageThemePanel) => {
        // 过滤图形、表格及过滤器设置
        let filterIds = ['chartSetting', 'tableSetting', 'filterSetting']
        iPageThemePanel.filterSettingGroup(item => {
          return !filterIds.some(id => id === item.id)
        })
     })
}
export default DataPortal
```

## 修改仪表盘默认主题

```javascript
import SmartBIExt from  'smartbi-ext-x'
let {
  DashModule: {
    DashEventEmum: {
      DASHBOARD_ON_READY
    },
    BaseDashExtender
  }    
} = SmartBIExt
class SwitchThemeExtension extends BaseDashExtender {
    this.on(DASHBOARD_ON_READY, (iDashboard) => {
        // 如果为新建仪表盘则切换主题
        if (iDashboard.isNewDashboard()) {
          iDashboard.switchTheme('Iff808081017ee7d2e7d20da7017eebff0310058f', false)
        }
     })
}
export default SwitchThemeExtension
```

# 保存弹框相关场景

## 限制资源保存位置

设置用户保存位置为我的空间下的分析展现,且不能新建文件夹或返回上级目录

- Extender.js

```javascript
import SmartBIExt from  'smartbi-ext'
let {
  DashModule: {
    DashEventEmum: {
      DASHBOARD_ON_SAVE_DIALOG_INIT
    },
    BaseDashExtender
  },
  Utils: {
    ExtensionUtil: { rmi }
  }
} = SmartBIExt
class DashExtenter extends BaseDashExtender {
  install () {
    let userInfoPromise = rmi('UserService', 'getCurrentUser')
    this.on(DASHBOARD_ON_SAVE_DIALOG_INIT, (iSaveDialog) => {
      iSaveDialog.setOperateButtonFilter(item => {
        return false
      })
      userInfoPromise.then(resp => {
        iSaveDialog.setRootNodeId(`SELF_ANALYSIS_${resp.result.id}`)
      })
    })
  }
}
export default DashExtenter
```

## 过滤右上角的操作按钮

<strong>示例代码:</strong>

```javascript
iSaveDialog.setOperateButtonFilter(item => {
  // 移除返回上一级按钮
  return item.id !== 'DRILL_UP'
})
```

## 过滤弹框初始化显示的结果

<strong>示例代码</strong>

```javascript
let whiteList = ['I8a8a9f0b017f6c946c94975c017f6d7fe0d7029f']
// 在我的空间下只显示资源及指定文件夹
iSaveDialog.setNodeFilter(item => {
  if (item.type !== 'SELF_TREENODE') {
    return true
  }
  return whiteList.some(id => item.id === id)
})
```

## 过滤搜索后的结果

<strong>示例代码</strong>

```javascript
// id路径中包含某个节点id的都不显示
iSaveDialog.setNodeFilter(item => {
  if (item.idPath.indexOf(`I8a8a9f0b017f208d208d3641017f20922aa6003c`) > -1) {
    return false
  }
  return true
})
```

# 组件工具栏相关场景

## 添加按钮

<strong>示例代码</strong>

```javascript
this.on(PAGE_ON_PORTLET_TOOLBAR_INIT, (iPortletToolbar, iPortlet) => {
      let item = {
          icon: "sx-icon-like",
          itemClass: [],
          location: {edit: true, view: false},
          id: "COMPONENT_SWITCH123",
          isEmit: true,
          qtp: "_DashboardPortlet_ComponentSwitch",
          tips: "组件切换",
          title: "组件切换"}
      iPortletToolbar.addItem(item)   
          
   })
```

## 插入按钮

<strong>示例代码</strong>

```javascript
this.on(PAGE_ON_PORTLET_TOOLBAR_INIT, (iPortletToolbar, iPortlet) => {
      let item = {
          icon: "sx-icon-like",
          itemClass: [],
          location: {edit: true, view: false},
          id: "COMPONENT_SWITCH123",
          isEmit: true,
          qtp: "_DashboardPortlet_ComponentSwitch",
          tips: "组件切换",
          title: "组件切换"}
     iPortletToolbar.insertItem(3, item)
   })
```

## 移除按钮

<strong>示例代码</strong>

```javascript
this.on(PAGE_ON_PORTLET_TOOLBAR_INIT, (iPortletToolbar, iPortlet) => {
      iPortletToolbar.removeItem(1)
   })
```

## 删除组件导出按钮

<strong>示例代码</strong>

```scala
import SmartBIExt from  'smartbi-ext-x'
let {
  DashModule: {
    DashEventEmum: {
      PAGE_ON_PORTLET_TOOLBAR_INIT,
    },
    BaseDashExtender
  }
} = SmartBIExt

class PortletExtender extends BaseDashExtender {

  install () {
    // 组件工具栏初始化
    this.on(PAGE_ON_PORTLET_TOOLBAR_INIT, (iPortletToolbar, iPortlet) => {
      iPortletToolbar.removeItemById("EXPORT")
    }  

}

export default PortletExtender
```

# 组件菜单相关场景

## 添加菜单

<strong>示例代码</strong>

```javascript
this.on(PAGE_ON_PORTLET_MENU_SHOW, iMenu => {
    iMenu.addItem({
      id: 'Test',
      label: '测试菜单',
      closeOnClick: true,
      handler: () => {
        alert('这是测试菜单')
      }
    })
  })
```

## 移除菜单

<strong>示例代码</strong>

```javascript
this.on(PAGE_ON_PORTLET_MENU_SHOW, iMenu => {
    let menus = iMenu.getItems()
    let index = menus.findIndex(menu => menu.id === 'setStyle' || menu.id === 'COMPONENT_SETTING')
     iMenu.removeItem(index)
  })
```

## 插入菜单

<strong>示例代码</strong>

```javascript
iMenu.insertItem(1, {
      id: 'Test1',
      label: '测试菜单',
      closeOnClick: true,
      handler: () => {
        alert('这是测试菜单')
      }
    })
```

# 设置面板相关场景

## 添加设置面板 Tab

```javascript
class DashSettingPanel extends BaseDashExtender {
  install () {
    this.on(COMMON_SETTING_PANEL_INIT, (iSettingPanel) => {
      let item = {
        component: 'Vuecomponent',
        id: "COMPONENT_INTERACTION1",
        label: "交互1"
      }
      iSettingPanel.addItem(item)
    })
}
}
```

## 插入设置面板 Tab

```javascript
let item = {
        component: 'Vuecomponent',
        id: "COMPONENT_INTERACTION1",
        label: "交互1"
      }
  iSettingPanel.insertItem(1, item)
```

## 移除设置面板 Tab

```javascript
iSettingPanel.removeItem(1)
```

## 激活设置面板 Tab

```javascript
iSettingPanel.setActiveItem('COMPONENT_INTERACTION')
```

# 组件面板相关场景

## 激活设计库组件面板 tab

```javascript
class DashIcomponentSeletorAreaExtension  extends BaseDashExtender {
  install () {
    this.on(DASHBOARD_COMPONENT_SELECTION_AREA_INIT, (iCompoentSeletorArea) => {
      console.log(iCompoentSeletorArea, 'iCompoentSeletorArea')
      iCompoentSeletorArea.setActiveItem('DESIGN_LIBRARY')
    })
  } 
}
```

## 新增一个测试组件面板 tab

```javascript
let item = {
        component: 'Vuecomponent',
        icon: 'sx-like',
        id: 'ABC',
        label: '测试'
      }
 iCompoentSeletorArea.addItem(item)
```

## 插入测试组件面板 tab

```javascript
let item = {
        component: 'Vuecomponent',
        icon: 'sx-like',
        id: 'ABC',
        label: '测试'
      }
 iCompoentSeletorArea.insertItem(1,item)
```

## 移除设计库组件面板 tab

```javascript
iCompoentSeletorArea.removeItem(1)
```

# 组件选择面板相关场景

## 设置柱图组件到指标分类

```javascript
this.on(DASHBOARD_WIDGET_PANEL_INIT, (iWidgetPanel) => {
      let list = iWidgetPanel.getWidgetListByGroupId("Chart")
      iWidgetPanel.setGroupWidget("Indicator", list[0]) // 添加对应组组件
    })
```

## 过滤柱图分类下的普通柱图组件

```javascript
let list = iWidgetPanel.getWidgetListByGroupId("Chart")
 iWidgetPanel.removeWidget("Chart", list[0].type)
```

## 过滤指标分类

```javascript
iWidgetPanel.removeGroup('Indicator')
```

## 筛选分类和图形分类交换位置

```javascript
iWidgetPanel.swapGroup(1,3)
```

## 新增分类

在扩展包新增组件中添加,index.js 文件中的 provideMetaInfo 加

![](https://wiki.smartbi.com.cn/download/attachments/115002486/QvnlbK4kcoKLRfxSARYc8nWun8e.png)

# 筛选器相关场景

## 配置筛选器自定义属性

需求: 根据自定义属性,配合筛选器二开接口实现自定义功能

代码
```typescript
import SmartBIExt from  'smartbi-ext'
let {
  DashModule: {
    DashEventEmum: {
      DASHBOARD_ON_FILTER_SETTING_DIALOG_INIT
    },
    BaseDashExtender
  }	
} = SmartBIExt
export default class DashInterfaceExtension extends BaseDashExtender {
  install () {
    // 您打算为筛选器添加的自定义属性的key
    const key = 'extBtnEnable'
    // 判断哪些筛选器您需要添加自定义属性
    const isCustomPropertyEnable = (type, componentType) => type === 'FILTER' && componentType === 'MULTI_SELECT'
    // 根据条件向筛选器设置弹窗添加/移除自定义属性的UI控件
    const addControl = (dialog) => {
      if (isCustomPropertyEnable(dialog.getType(), dialog.getComponentType())) {
        dialog.addCustomProperty({
          key,
          label: '开启excel导入',
          type: 'radio',
          props: {
            value: dialog.getCustomSettingByKey(key) || 'no',
            options: [{
              label: '开启',
              value: 'yes'
            }, {
              label: '关闭',
              value: 'no'
            }]
          }
        })
      } else {
        dialog.removeCustomProperty(key)
      }
    }

    this.on(DASHBOARD_ON_FILTER_SETTING_DIALOG_INIT, (dialog) => {
      // 筛选器设置变更处理器: 根据条件添加/移除自定义属性的UI控件
      dialog.setChangeHandler(() => { addControl(dialog) })
      // 初始化筛选器设置弹窗时: 根据条件添加/移除自定义属性的UI控件
      if (isCustomPropertyEnable(dialog.getType(), dialog.getComponentType())) {
        addControl(dialog)
      }
    })
  }
}
```
## 扩展筛选器功能

需求: 新增按钮实现开启excel导入功能(若此功能需要可开启或关闭,则需要搭配配置筛选器自定义属性使用)

代码
```typescript
import SmartBIExt from 'smartbi-ext'
import SuffixButton from './SuffixButton'
let {
  DashModule: {
    DashEventEmum: {
      PAGE_ON_FILTER_INIT
    },
    BaseDashExtender
  }	
} = SmartBIExt
export default class DashInterfaceExtension extends BaseDashExtender {
  install() {
    // 您打算为筛选器添加的自定义属性的key
    const key = 'extBtnEnable'
    // 根据自定义属性判断哪些筛选器需要添加后置插槽, 为筛选器扩展一个功能
    const isSuffixSlotEnable = (value) => value === 'yes'
    // 根据条件向筛选器添加/移除后置插槽
    const addSuffix = (filter) => {
      if (isSuffixSlotEnable(filter.getCustomSettingByKey(key))) {
        filter.setSuffixSlot({
          component: SuffixButton,
          listeners: {
            select: function (value) {
              filter.setValue(value)
              filter.commitChange()
            }
          }
        })
      } else {
        filter.setSuffixSlot()
      }
    }
    this.on(PAGE_ON_FILTER_INIT, (filter) => {
      // 筛选器初始化时: 根据条件向筛选器添加/移除后置插槽
      addSuffix(filter)
    })
  }
}
```
## 自定义筛选器备选值和输出条件值

需求: 新增按钮实现开启excel导入功能, 若开启, 则自定义筛选器备选值为excel文件名, 并用条件值处理器将筛选器的输出条件值替换为excel数据. 达到快速使用文件过滤数据的目的.

代码
```typescript
import SmartBIExt from 'smartbi-ext'
import SuffixButton from './SuffixButton'
import CustomStandbyValueApi from './CustomStandbyValueApi'

let {
  DashModule: {
    DashEventEmum: {
      PAGE_DEFINE_LOADED,
      DASHBOARD_ON_FILTER_SETTING_DIALOG_INIT,
      PAGE_ON_FILTER_INIT
    },
    BaseDashExtender
  }
} = SmartBIExt
export default class DashInterfaceExtension extends BaseDashExtender {
  install() {
    // 您打算为筛选器添加的自定义属性的key
    const key = 'extBtnEnable'
    // 根据自定义属性判断哪些筛选器需要添加后置插槽, 为筛选器扩展一个功能
    const isSuffixSlotEnable = (value) => value === 'yes'
    // 根据条件向筛选器添加/移除后置插槽
    const addSuffix = (filter) => {
      if (isSuffixSlotEnable(filter.getCustomSettingByKey(key))) {
        filter.setSuffixSlot({
          component: SuffixButton,
          listeners: {
            select: function (value) {
              filter.setValue(value)
              filter.commitChange()
            }
          }
        })
      } else {
        filter.setSuffixSlot()
      }
    }

    // 判断哪些筛选器您需要添加自定义属性
    const isCustomPropertyEnable = (type, componentType) => type === 'FILTER' && componentType === 'MULTI_SELECT'
    // 根据条件向筛选器设置弹窗添加/移除自定义属性的UI控件
    const addControl = (dialog) => {
      if (isCustomPropertyEnable(dialog.getType(), dialog.getComponentType())) {
        dialog.addCustomProperty({
          key,
          label: '开启excel导入',
          type: 'radio',
          props: {
            value: dialog.getCustomSettingByKey(key) || 'no',
            options: [{
              label: '开启',
              value: 'yes'
            }, {
              label: '关闭',
              value: 'no'
            }]
          }
        })
      } else {
        dialog.removeCustomProperty(key)
      }
    }

    // 由于条件值处理器是同步的, 因此excel数据需要提前加载
    const excelDataCache = {}

    // 备选值获取器, 返回 [{ value, displayValue }]
    const standbyValueGetter = async ({ keyword, pageNum, pageSize, queryType }) => {
      if (queryType === 'SEARCH') {
        // 搜索, 使用keyword, pageNum, pageSize 从定制接口获取备选值
        return await CustomStandbyValueApi.search(keyword, pageNum, pageSize)
      }
      // 使用pageNum, pageSize 从定制接口获取备选值
      return await CustomStandbyValueApi.get(pageNum, pageSize)
    }
    // 备选值获取器提供商, 返回standbyValueGetter
    const standbyValueGetterProvider = (filterInfo) => {
      if (isSuffixSlotEnable(filterInfo.customSetting?[key])) {
        return standbyValueGetter
      }
    }

    // 条件值处理器
    const conditionHandler = (condition) => {
      if (!condition) {
        return condition
      }
      if (!condition.field) {
        return condition
      }
      let values = condition.values
      let displayValues = condition.displayValues
      let newValues = []
      let newDisplayValues = displayValues && []
      for (let i = 0; i < values.length; i++) {
        let value = values[i]
        if (excelDataCache[value]) {
          for (let item of excelDataCache[value]) {
            if (newValues.indexOf(item.value) === -1) {
              newValues.push(item.value)
              newDisplayValues && newDisplayValues.push(item.displayValue)
            }
          }
        } else {
          if (newValues.indexOf(value) === -1) {
            newValues.push(value)
            newDisplayValues && newDisplayValues.push(displayValues[i])
          }
        }
      }
      return {
        ...condition,
        values: newValues,
        displayValues: newDisplayValues
      }
    }
    // 条件值处理器提供商
    const conditionHandlerProvider = (filterInfo) => {
      if (isSuffixSlotEnable(filterInfo.customSetting?[key])) {
        return conditionHandler
      }
    }

    this.on(PAGE_DEFINE_LOADED, (report) => {
      // 设置备选值获取器提供商
      report.setStandbyValueGetterProvider(standbyValueGetterProvider)
      // 设置条件值处理器提供商
      report.setConditionHandlerProvider(conditionHandlerProvider)
    })

    this.on(DASHBOARD_ON_FILTER_SETTING_DIALOG_INIT, (dialog) => {
      // 筛选器设置变更处理器: 根据条件添加/移除自定义属性的UI控件
      dialog.setChangeHandler(() => { addControl(dialog) })
      // 初始化筛选器设置弹窗时: 根据条件添加/移除自定义属性的UI控件
      if (isCustomPropertyEnable(dialog.getType(), dialog.getComponentType())) {
        addControl(dialog)
      }
    })

    this.on(PAGE_ON_FILTER_INIT, (filter) => {
      // 筛选器初始化时: 根据条件向筛选器添加/移除后置插槽
      addSuffix(filter)
    })
  }
}


```

# 使用系统弹窗

<strong>详细接口文档</strong>:[SmartbiX-弹出框插件 Layer 使用文档](https://smartbi.feishu.cn/wiki/wikcnZqsPjb3B5a2t9QEPXznuah)

<strong>示例代码</strong>

```kotlin
{
   openCodeDialog () {
       this.layerId = IGlobal.getLayer().iframe('弹窗名称'), {
        content: {
          content: Component, // 组件
          parent: this, // 父组件
          data: { // 传递的参数
            apply: (result) => { // 点击确定回调
              this.onApply(result)
            },
            cancel: () => { // 关闭回调
              this.closeCodeDialog()
            }
          }
        }
   },
    closeCodeDialog () {
      IGlobal.getLayer().close(this.layerId)
    },

    onApply () {
        // 业务代码
    }   
   
}
```

# 国际化

以下分区柱图为例

<strong>效果如下:</strong>

![](https://wiki.smartbi.com.cn/download/attachments/115002486/KMelbki7FoJyq6xW3qLcLpiSnZf.png)

## 步骤:

### 新建 lang.js

- 在新组件的目录下新建一个 lang 目录,新建一个 lang.js
- lang.js 如下:

```javascript
let Lang = {
  zh: {
    barZone: {
      title: '分区柱图'
    }
  },
  en: {
    barZone: {
      title: 'barZoneView'
    }
  },
  tw: {
    barZone: {
      title: '分區柱圖'
    }
  }
}

export default Lang
```

### 在 index.js 引入国际化文件 lang.js

### 并且导出 lang,将 metainfo 和 setttingpanel 改成 provideMetaInfo 和 provideSettingPanelOptions

代码如下:

```javascript
import BarZoneLang from './lang/Lang'
import SettingPanel from './setting-panel/SettingPanel'
const provideMetaInfo = function () {
  return {
    name: lang.$t('barZone.title'), // 组件名称
  }
 }
export default {
  provideMetaInfo,
  provideSettingPanelOptions: SettingPanel.provideSettingPanelOptions,
  lang: BarZoneLang
}
```

### Setttingpanel.js

```javascript
const LiquidFillSettingSchema = function () {
  return {
    $id: 'xx',
    type: 'xx',
    properties: {
    },
    ...
  }
}

function provideSettingPanelOptions () {
   const xxSchema = {}
   ...
   const settingPanelOptions = [{
    schema: xxScjema,
    control: 'xxControl'
  },
  ...
  ]
}
function provideSchema () {}

export default {
  provideSchema,
  provideSettingPanelOptions
}
```

# 二开使用系统 elementui

以使用菜单组件为例

```javascript
<template>
    <el-menu></el-menu>
</template>

<sciprt>
import {Menu} from 'element-ui'
export default {
    data: () {
        return {
        }
    },
    componenets: {
        ElMenu: Menu
    }

}
</script>
```

# 静态资源替换

仪表盘中的静态资源大多通过 css 引用 iconfont 或在 css 中使用 url 加载,因此替换静态资源只需将对应样式类中的属性进行覆盖,并引用自定义的资源即可

## 替换 iconfont

1. 参考[仪表盘二开外部资源使用文档](https://smartbi.feishu.cn/docs/doccnrJuqVvUOZjpGhSooqGFkkb#Yu0YnB) 添加 iconfont 相关资源,如下图

![](https://wiki.smartbi.com.cn/download/attachments/115002486/VdJ1bqgX3oSMh1xOykNctUHEnhw.png)

2. 找到所需要替换的目标样式类,重写样式类中的属性,引用自定义添加的 iconfont 资源

如工具栏中的预览图标样式类为 `.sx-icon-preview:before`,则定义同名类进行覆盖

- dashReplaceResource.css

```css
@font-face {
  font-family: "extension-iconfont"; /* Project id  */
  src: url('iconfont.ttf?t=1648543381991') format('truetype');
}
/* 替换预览图标 */
.sx-icon-preview:before {
  font-family: "extension-iconfont";
  content: "\e659";
}
```

- Extender.js

```javascript
import SmartBIExt from  'smartbi-ext'
let {
  DashModule: {
    DashEventEmum: {
      DASHBOARD_ON_READY
    }
    BaseDashExtender
  },
  Utils: {
    ExtensionUtil: { documentLoadResource }
  }
} = SmartBIExt
class DashExtenter extends BaseDashExtender {
  install () {
    this.on(DASHBOARD_ON_READY, (iDashboard) => {
      // 加载自定义样式资源
      documentLoadResource('/assets/replaceResource/dashReplaceResource.css')
    })
  }
} 
export default DashExtenter
```

![](https://wiki.smartbi.com.cn/download/attachments/115002486/P1eab8TNyoGKQrxfdZCcUYCwnTg.png)

## 替换 svg 或图片

1. 添加所需要用到的 svg

![](https://wiki.smartbi.com.cn/download/attachments/115002486/Nz7Abh8LUoHxGNxoE84cw4gxnch.png)

1. 参考[替换 iconfont](https://smartbi.feishu.cn/docs/doccni2ZdWpClm6SMrw6kOtRukc#DYz8kp) 第二步,覆盖样式类属性并引用自定义资源

如横条图无字段时对应样式类为 `.db-left-widget__chart-bar--horiz.disabled`,则定义同名类进行覆盖

- dashReplaceResource.css

```css
/* 替换横条图无字段时显示图标 */
.db-left-widget__chart-bar--horiz.disabled {
  background-image: url("./echartsBarHoriz.svg");
  background-position: center;
  background-repeat: no-repeat;
}
```

- Extender.js 同上

![](https://wiki.smartbi.com.cn/download/attachments/115002486/PnczbMMcIoBTDUxdZfjc0kABnhc.png)

<strong>注意</strong>

- 由于后加载的样式类会覆盖已加载的样式类,因此调用 documentLoadResource 的时机应比系统加载 css 晚,`DASHBOARD_ON_READY` 事件可满足绝大部分场景(如不满足可考虑使用 important 强制覆盖)
- 若有使用 img 标签加载图形等情况,则按原扩展包方式编写 filter,对相关资源进行拦截,转发到自定义资源或通过流返回资源

# 移除资源

移除无用资源:通过调用 documentUnloadResource,可以将通过 documentLoadResource 接口加载过的资源移除,移除资源的参数就是你添加资源的链接

<strong>使用场景:</strong>

用户可以通过一些状态判断是否需要隐藏,例如链接参数,如果要隐藏就添加资源,如果不要隐藏就要移除资源(

<strong>注意</strong>:由于仪表盘会缓存,所有需要移除加载过的资源)

<strong>代码如下</strong>:

```javascript
import SmartBIExt from  'smartbi-ext-x'
let {
  Utils: {
    ExtensionUtil: { documentLoadResource, documentUnloadResource }
  }
} = SmartBIExt

class DataPortal extends BaseDashExtender {
  constructor () {
    super ()
  }
  install () {
       documentUnloadResource("/assets/dashReplaceResource/dashReplaceResource.css")
    }
  
  }  
}

export default DataPortal
```

- dashReplaceResource.css

```css
/* 替换横条图无字段时显示图标 */
.db-left-widget__chart-bar--horiz.disabled {
  background-image: url("./echartsBarHoriz.svg");
  background-position: center;
  background-repeat: no-repeat;
}
```

...