[]
        
(Showing Draft Content)

标准模式集成概览与API介绍

根据之前对标准 Lite 模式与高级分析模式的介绍,我们知道标准分析模式可使仪表板的文件包大大减小,从而大幅度提高文档的加载速度。

并且标准分析模式为用户提供了更加丰富细致的 API。因此在集成时,用户可以最大限度的自主设计仪表板外观样式以及入场动画等。

本文为您整体介绍集成标准版仪表板的方式并为您介绍标准分析模式的集成 API。

设计

1. 首先需要导入以下文件:

  • dashboard.viewerLite.css

  • dashboard.viewerLite.vendor.css

  • dashboard.libs.common.js

  • dashboard.libs.chart.js

  • dashboard.libs.sheet.js

  • dashboard.viewerLite.js

2. 然后参考以下代码创建一个viewerLite(即标准分析查看器)实例。

const ins = WynBi.createViewerLite({ 
	dashboardId: 'xxxxxxxxxxxxxxxx', // required 
	token: 'xxxxxxxxxxxxxxxx', // optional 
	baseUrl: 'xxxxxxxx', // optional 
	lng: 'en-us', // optional 
	dp: '', // optional
	theme: 'default' // options: custom should work with correct css file 
}); 
const viewerRoot = document.querySelector('#root'); 
//... code to integrate the viewer. Refer to next section
// destroy the instance if needed 
ins.destroy();

3. 支持3种方式来集成仪表板标准分析版。

  1. 集成整个仪表板

    ins.initialize({ container: viewerRoot, }).then((uiDashboard) => {
    const dashboardDom = document.querySelector('#dashboard-root');
    uiDashboard.connect(dashboardDom); // mount the dashboard onto this dom
    // listen to the event if you needed
    uiDashboard.on('render', () => {
    console.log('>>>', uiDashboard.name, 'uiDashboard render start');
    });
    uiDashboard.on('rendered', () => {
    console.log('>>>', uiDashboard.name, 'uiDashboard render end');
    });
    uiDashboard.on('mounted', () => {
    console.log('>>>', uiDashboard.name, 'uiDashboard mounted');
    });
    // trigger dashboard render
    uiDashboard.refresh();
    });
  2. 集成单个仪表板页面

    ins.initialize({ container: viewerRoot, }).then((uiDashboard) => {
    const firstPage = uiDashboard.pages[0]; // UIPage
    const pageDom = document.querySelector('#page-1');
    firstPage.connect(pageDom);
    firstPage.on('render', () => {
    console.log('>>>', firstPage.name, 'page render start')
    });
    firstPage.on('rendered', () => {
    console.log('>>>', firstPage.name, 'page render end')
    });
    firstPage.on('mounted', () => {
    console.log('>>>', firstPage.name, 'page mounted')
    });
    firstPage.refresh();
    });
  3. 集成单个组件

    此时用户可以自定义组件的布局以及添加入场动画。

    ins.initialize({ container: viewerRoot, }).then((uiDashboard) => {
    const firstPage = uiDashboard.pages[0];
    const firstScenario = firstPage.widgets[0]; // UIScenario or UIContainer
    const scenarioDom = document.querySelector('#scenario-1');
    firstScenario.connect(scenarioDom);
    firstScenario.on('render', () => {
    console.log('>>>', firstScenario.name, ' scenario render start')
    });
    firstScenario.on('rendered', () => {
    console.log('>>>', firstScenario.name, ' scenario render end')
    });
    firstScenario.on('mounted', () => {
    console.log('>>>', firstScenario.name, ' scenario mounted')
    });
    firstScenario.on('update', () => {
    console.log('>>>', firstScenario.name, ' scenario update')
    });
    firstScenario.refresh();
    });

API 介绍

EventType

  • mounted: 将部件挂载到 dom 后触发。

    dashboard.on('mounted', () => {
        console.log('>>> mounted');
    });
  • render: 部件开始渲染时触发。

    dashboard.on('render', () => {
        console.log('>>> render');
    });
  • rendered: 部件完成渲染后触发。

    dashboard.on('rendered', () => {
        console.log('>>> rendered');
    });
  • 仅适用于UIScenario。在组件更新前触发。更新和渲染的区别在于,更新表示数据已准备好但尚未渲染。

    scenario.on('update', () => {
        console.log('>>> update');
    });
  • error: 发生错误时触发。

    dashboard.on('error', (dashboardId, sourceId, err) => {
        //sourcerId is the id of widget which cause this err
    });
  • selectionChange: 在更改图表选择时触发(通过用户或API)。

    dashboard.on('selectionChange', (dashboardId, sourceId, filter) => {
        //sourcerId is the id of widget which selection changed, filter is the selection state
    });
    // https://wiki.grapecity.io/display/GEDS/Visual+API#VisualAPI-SelectionId
    interface ISelection {
        measures: string[];
        dimensions: {
          [columnName: string]: string | number;
        };
      }
    // eg: 
    {
    	dimensions: {CarType: "SUV", Gender: "Male"}
    	measures: []
    }
    // https://wiki.grapecity.io/display/GEDS/Visual+API#VisualAPI-TupleFilter
    type ITuple = { value: any }[];
    interface ITupleFilter {
        target: IFilterTarget[];
        filterType: VisualFilterType;
        operator: BasicFilterOperator;
        values: ITuple[];
    }
    // eg:
    {
        target: [
          {
            column: 'CarType'
          },
          {
            column: 'Gender'
          },
          {
            column: 'CustomerSatisfaction'
          }
        ],
        operator: 'In',
        filterType: 'tuple',
        values: [
          [
            {
              value: 'Sedan'
            },
            {
              value: 'Male'
            },
            {
              value: 'Excellent'
            }
          ],
          [
            {
              value: 'SportsCar'
            },
            {
              value: 'Female'
            },
            {
              value: 'Excellent'
            }
          ],
          [
            {
              value: 'Pickup'
            },
            {
              value: 'Female'
            },
            {
              value: 'Poor'
            }
          ]
        ]
      }

Event 顺序

mounted -> (update) -> render -> rendered

UIWidget

仪表板/页面/组件的基类。

connect(container: HTMLElement): void  // Connect the widget on a dom.
isConnected(): boolean // Indicate that does this widget has been connected on a dom.
disconnect(): void // Disconnect this widget. Do something to clean up.
getName(): string // get the widget name
on(type: EventType, cb: (...args) => void): void  // Register event listener.
once(type: EventType, cb: (...args) => void): void  // Register event listener for once.
off(type: EventType, cb: (...args) => void): void  // Remove event listener.
refresh(): void // Refresh the widget. Including refresh data and resize this widget
resize(): void // Resize the widget.
suspend(): void //  Freeze the render of every scenario. 
resume(): void //  Recover the render of every scenario.

UIDashboard

UIDashboard扩展了UIWidget。

pages: UIPage[]  // All the visiable pages.
getCurrentPage(): UIPage //  Get current rendered page.
showPrevPage(): UIPage // Switch to prev page.
showNextPage(): UIPage // Switch to next page.
getPageByName(pageName: string): UIPage // Get page by page name.
getPageByID(id: string): UIPage // Get page by page id.
getScenarioByName(scenarioName: string): UIScenario // get scenario by scenario name
getScenarioByID(scenarioID: string): UIScenario // get scenario by scenario id

UIPage

UIPage扩展了UIWidget。

scenarios: UIScenario[] // All the scenarios(exclude container/tabContainer/group) on the page.
containers: UIScenario[] // All the containers(container/tabContainer/group) on the page.
widgets: UIScenario[] // All ths widgets(scenarios and containers) on page.
getScenarioByName(scenarioName: string): UIScenario // get scenario by scenario name
getScenarioByID(scenarioID: string): UIScenario // get scenario by scenario id

用户可以用 'widgets' 连接 dom上的 widget。如果容器/选项卡/组 有特殊的逻辑(例如不渲染组,提取其中的所有组件),用户可以用 'scenarios' 和 'containers' 来代替。

UIContainer

UIContainer扩展了UIWidget。

scenarios: UIScenario[] // All the scenarios on the container/group/tab container.
scenarioType: ScenarioType
getScenarioByName(scenarioName: string): UIScenario // get scenario by scenario name
getScenarioByID(scenarioID: string): UIScenario // get scenario by scenario id

UIScenario

UIScenario扩展了UIWidget。

scenarioType: ScenarioType

注意以及说明

  • 同一部件不能集成连接两次。比如,组件A 在第一页中。如果连接了整个页面,那么就不可以再单独连接组件A了。

  • 同理,容器、选项卡以及组均仅可以连接一次。如果在dom 汇总连接了容器,那么就不可以再连接这个容器中的组件了。也就是说组件与包含该组件的容器/ 组 不可以共存。

// The follow two case will not work correctly
// case 1:  firstScenario will be connect twice. One is in firstPage.connect, the other is connect with dom2.
const firstPage = uiDashboard.pages[0]; 
const firstScenario = firstPage.scenarios[0];
firstPage.connect(dom1);
firstScenario.connect(dom2);
// case 2: firstScenario will be connect twice. One is in firstContainer.connect, the other is connect with dom2.
const firstPage = uiDashboard.pages[0]; 
const firstContainer = firstPage.containers[0];
const firstScenario =  firstContainer.scenarios[0];
firstContainer.connect(dom1);
firstScenario.connect(dom2);
  • 组件之间的交叉过滤、数据筛选器等效果都是遵循原仪表板中的设置。也就是说,即使将多个仪表板页面中的组件集成时放到了同一个页面中,那么他们之间也不会产生交叉过滤等效果,还是会保持原仪表板中的设置。不会因为UI 摆放到了一起就产生过滤影响。

const firstPage = uiDashboard.pages[0]; 
const secondPage = uiDashboard.pages[1]; 
const scenarioFromFirstPage = firstPage.scenarios[0];
const scenarioFromSecondPage =  secondPage.scenarios[0];
scenarioFromFirstPage.connect(dom1);
scenarioFromSecondPage.connect(dom2);
// warning: On this case, the two scenario could not affect to each other by crossfilter.