完整示例:开发一个echarts图表

本文将介绍在 Quick BI 中开发一个基于 echarts 的圆角环形图自定义组件。

效果示例图

效果图详细代码请参见完整代码示例

步骤一:创建项目

  1. 创建一个自定义组件项目,创建完成后安装依赖初始化。

    请参见快速开始

    npm init qbi-app myEcharts
    cd myEcharts
    yarn
  2. Quick BI控制台,按照下图指引,注册组件。

    image

    说明

    开发模式请选择专业模式

    在线编辑的教程请参见教程:在线编辑模式下快速插入 echarts 代码

  3. 安装echarts。

    1. 执行以下命令,安装echarts类型定义。

      yarn add -D @types/echarts
    2. 选择以下任意一种方式,安装echarts。

      • 第三方CDN引入:该方式可以提升加载性能。

        操作方法:在编辑自定义组件中的依赖的第三方库中填入echartsCDN地址。

        image

        设置项目根目录下的webpack.config.js , 增加一项externals配置。

         // webpack.config.js
         externals: {
            lodash: '_',
            react: 'React',
            'react-dom': 'ReactDOM',
            moment: 'moment',
            echarts: 'echarts', // 新增一项
          },
      • npm安装:通过npm或者yarn安装。

        yarn add echarts
  4. 在组件管理列表中,找到目标组件并单击调试图标。

    image

    系统自动跳转至对应的仪表板中,您可以根据需求进行调试。请参见调试组件

步骤二:配置meta

meta配置包含数据面板和样式面板的配置。

配置数据面板

meta.ts中,dataSchema可以根据自身需求定制图表取数的方式。在大部分情况下, 直接在模板工程里创建好的 meta 的基础上修改即可,常见修改的地方有:

  • areaName:字段显示的名称

  • required:字段是否必填

  • maxColumn:最多可拖入的字段数量

假设您需要显示1个维度,3个度量,则只需要改对应的maxColumn即可,配置示例如下:

// meta.ts
const componentMeta: Interfaces.ComponentMeta = {
  propsSchema: {
    dataSchema: {
      areas: [
        {
          id: "drill",
          name: "钻取/维度",
          queryAxis: "drill",
          rule: {
            fieldTypes: ["dimension"],
            required: false, // 是否是更新图表必须字段
            /** 限制数量 */
            maxColNum: 3,
          },
        },
        {
          id: "area_row",
          name: "维度",
          queryAxis: "row",
          rule: {
            fieldTypes: ["dimension"],
            maxColNum: 1, // 最多允许的字段数
            required: true, // 是否是更新图标必须字段
          },
        },
        {
          id: "area_column",
          name: "度量",
          queryAxis: "column",
          rule: {
            fieldTypes: ["dimension", "measure"],
            maxColNum: 3, // 最多允许的字段数
            required: true, // 是否是更新图标必须字段
          },
        },
        {
          id: "filters",
          name: "过滤器", //  名称
          queryAxis: "filters",
          rule: {
            fieldTypes: ["dimension", "measure"],
            required: false,
          },
        },
      ],
      resultDisplay: {
        /** 限制条数 */
        upLimit: 1000,
      },
    },
  },
};
                

则可以生成数据面板,如下图所示。配置面板dataSchema具体配置请参考文档

配置样式面板

styleSchema用于定义样式面板的配置。您可以基于场景进行定制。在本例中样式面板需求为:

  • 可以勾选是否显示图例

  • 可以定义起始角度(数字)

通过分析需求可知,需要定义一个checkboxnumber 编辑器。因此在 styleSchema中定义,type: 'switch'type: 'number'。(目前支持的编辑器请参见schema.type。)

const componentMeta: Interfaces.ComponentMeta = {
  propsSchema: {
    styleSchema: {
      schema: {
        type: 'object',
        className: 'tabs-uischema-container',
        props: { mode: 'collapse' },
        properties: {
          // 请在此处填写你需要自定义的属性
          display: {
            type: 'object',
            title: '显示设置',
            properties: {
              showLegend: {
                type: 'switch',
                id: 'showLegend',
                defaultValue: true,
                props: {
                  mode: 'checkbox',
                  label: '显示图例',
                },
              },
              startAngle: {
                title: '起始角度',
                id: 'startAngle',
                type: 'number',
                defaultValue: 0,
                props: {
                  placeholder: '请输出起始角度',
                  maxLength: 140,
                },
              },
            },
          },
        },
      },
    },
  },
};

此时,在样式面板中就会自动生成这两个编辑器。编辑器输入的值也可以在自定义组件的customProps.viewConfig中获取。样式配置

步骤三:开发echarts图表

开发图表需要调用setOption(option) 方法,下面为您介绍如何将Quick BI传入的属性转换为echarts的接收的参数。

  1. 创建 echarts 实例。

    mount方法中创建echarts实例。

        // src/component.ts
      mount(props: Interfaces.LifecycleProps<Interfaces.ComponentProps>) {
        // ...
        this.chart = echarts.init(props.container as HTMLDivElement);
        this.setOption(props);
      }
  2. 转换 data。

    封装一个setOption方法,方便在mount和update阶段调用。

    customProps.data是个二维数组,customProps.data[i]代表数据库表中的一行数据,每行包括了所配置的维度和度量字段所对应的值。

    customProps.data[i][j] 代表数据库表一个单元格的值,数据结构请参见自定义组件API,其中fieldId为维度和度量的字段ID。

    由于数据每行的位置都是固定的,为了方便通过fieldId获取到value值,可以建立一个fieldId与数组下标映射的map。

    // src/component.ts
        setOption(props: Interfaces.LifecycleProps<Interfaces.ComponentProps>) {
        // 图表数据
        const data = props.customProps.data;
        // 数据面板格式设置
        const fieldSettingMap = props.customProps.viewConfig.fieldSettingMap;
        // 第一行数据
        const [firstRow] = data;
        // 数据每行的位置都是固定的, 通过建立数组下标与 fieldId 的映射关系, 方便通过 fieldId 取值
        const fieldColumnIndexMap: {
          [key: string]: number;
        } = firstRow.reduce(
          (prev, curr, i: number) => ({
            ...prev,
            [curr.fieldId]: i,
          }),
          {},
        );
        }
  3. 设置 series。

    series系列设置,在数据面板配置的维度和度量字段,可以通过customProps.dataConfig获取。

    // src/component.ts
        setOption(props: Interfaces.LifecycleProps<Interfaces.ComponentProps>) {
            // ... data
        // 筛选出所有度量
        const columnsFields = props.customProps.dataConfig.find(each => each.areaType === 'column')?.fields ?? [];
        // 数据面板数据格式设置
        const fieldSettingMap = props.customProps.viewConfig.fieldSettingMap;
        // 转换格式
        const series = columnsFields.map((each, i) => {
          const filedSetting = fieldSettingMap[each.fieldId];
          return {
            id: each.fieldId,
            type: 'bar',
            // 根据 fieldId 与数组下标的映射, 每一行的数据值
            data: data.map(row => row[fieldColumnIndexMap[each.fieldId]]?.value),
              coordinateSystem: 'polar',
              // 设置别名
              name: filedSetting?.aliasName ?? each.showName,
          };
        });
        // ...
        this.chart.setOption({
          series,
          // ...
        });
        }
  4. 设置category。

    设置类别,由于圆角环形图只接收一个维度,故取第一个维度即可。

    // src/component.ts
        setOption(props: Interfaces.LifecycleProps<Interfaces.ComponentProps>) {
        // 筛选出所有度量
        const rowFields = props.customProps.dataConfig.find(each => each.areaType === 'row')?.fields ?? [];
        // meta 中限制了只有一个维度
        const [onlyRow] = rowFields;
        const category = data.map(row => row[fieldColumnIndexMap[onlyRow?.fieldId]]?.value);
        // ...
        this.chart.setOption({
          radiusAxis: {
            type: 'category',
            data: category,
            z: 10,
          },
          // ...
        });
        }
  5. 读取样式面板。

    在样式面板中配置的表单的值,可以通过customProps.viewConfig获取。在本例中, checkbox编辑器的表单名为 showLegend,number输入框的表单名为startAngle, 并且他们都定在了display下, 因此您可以通过 customProps.viewConfig.display?.showLegend 获取。

    // src/component.ts
        setOption(props: Interfaces.LifecycleProps<Interfaces.ComponentProps>) {
        const showLegend = props.customProps.viewConfig.display?.showLegend;
            const startAngle = props.customProps.viewConfig.display?.startAngle;
        // 设置 echarts
        this.chart.setOption({
          angleAxis: {
            startAngle,
          },
          legend: {
            show: viewConfig.display?.showLegend,
            data: legend,
            top: 10,
            padding: 0,
          },
          // ...
        });
        }
  6. 创建下钻、联动和跳转效果。

    Quick BI提供了customProps.dispatch方法,通过调用该方法,即可实现下钻、联动和跳转。其中dataIndex为需要现在的维度在customProps.data中的数组下标。

    // component.ts
        const dispatch = props.customProps.dispatch;
        if (typeof dispatch === 'function') {
          // 下钻/联动/跳转事件
          echarts.on('click', (serie: any) => {
            dispatch({
              type: 'select',
              payload: {
                dataIndex: serie.dataIndex, // dataIndex 为所点击的行在 data 中的数组下标
              },
            });
          });
          // 点击空白处事件, 用于适配移动端下钻
          echarts.getZr().on('click', function (e) {
            if (!e.target) {
              dispatch({
                type: 'cancelSelect',
              });
            }
          });
        }

完成上述步骤,图表就可以显示出来了。接下来就是对样式做修改,以及数据格式的调整。详情请参考完整代码示例中的注释。

步骤四:打包

开发完成后,需要对自定义组件进行打包。

npm run pack

产出结果在build目录下,您可以通过自定义组件平台中上传,发布组件即可。

image详情请参见在Quick BI仪表板中调试组件