Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BI数据可视化 - 组件规范设计 #44

Open
chiyan-lin opened this issue Jan 30, 2024 · 5 comments
Open

BI数据可视化 - 组件规范设计 #44

chiyan-lin opened this issue Jan 30, 2024 · 5 comments

Comments

@chiyan-lin
Copy link
Owner

No description provided.

@chiyan-lin
Copy link
Owner Author

chiyan-lin commented Jan 31, 2024

前言

大数据平台对数据可视化报表的诉求高,这类需求多而且修改频率高,功能类似但差异偏多,目前,系统大部分仍然采用人工开发,随着分析领域的不断扩大和深入,报表开发会陷入业务需求的泥潭中。

更新后的研发流程
image

@chiyan-lin
Copy link
Owner Author

chiyan-lin commented Jan 31, 2024

一个组件需要什么

首先是配置数据,查一个sql需要什么,配置数据上就需要加什么

一个sql查询,最重要的就是 字段,过滤条件,在数据库的抽象中,字段可以分为 维度和指标,所以数据配置上要有维度,指标,过滤条件 这三个基本的选择框

第二个就是样式配置,大数据的展示都是基于图表库 echart 来做的,echart这么多配置就需要把代码上的 option 配置抽象成更好交互的选择式配置

第三个,前面两个处理了样式和数据,为了满足以后得扩展需求,我们额外加了一个高级配置,一些即不是数据也不是样式的配置可以归类到高级配置的某个配置项

大致的示意图
image

@chiyan-lin
Copy link
Owner Author

chiyan-lin commented Jan 31, 2024

配置协议设计

根据上面的示意图进行协议的 interface 设计

ComponentMeta

自定义组件元信息包含了 formSchema 等属性的对象。通过元信息可以控制自定义组件的数据面板/样式面板/高级面板功能

interface ComponentMeta {
    dataSchema: DataSchema;
    styleSchema: StyleSchema;
    advancedSchema: AdvancedSchema;
}

数据面板

type DataSchema = {
  // 控制维度、指标、过滤条件的区块
  block: DataSchemaBlock[],
  // 数据的展示,主要是条数
  display: DataSchemaDisplay
};

DataSchemaBlock

在 DataSchemaBlock 配置中, 数据集有 "维度" 和 " 指标" 两种类型的字段, 不同字段可以拖入到不同的区块中实现不同的取数方式,DataSchemaBlock 的类型: 维度(column) 指标(metrics) 过滤器(filter)

interface DataSchemaBlock{
  /** 类型 */
  type: 'column' | 'metrics' | 'filter';
  /** 区块名 */
  name: string;  
  /** 区块名提示 */
  nameTip?: string;
  /** 区块配置 */
  config: DataSchemaBlockConfig;
}

DataSchemaBlockConfig

单个配置块的配置项

interface DataSchemaBlockConfig{
  /** 占位显示内容,default:请拖入或双击 */
  placeholder?: string;
  /** 支持拖入的类型,(维度 | 指标)当所有的类型都可以拖入时, fieldTypes: ['column', 'metrics'] */
  fieldTypes: ('column' | 'metrics')[];
  /** 是否必填 */
  required?: boolean;
  /** 字段配置个数限制 */
  maxLen?: number;
}

DataSchemaDisplay

配置数据面板结果展示区

interface DataSchemaDisplay{
  /** 图表取数数量上限,图中蓝色块数字输入框的 max */
  upLimit?: number;
  /** 图表取数数量下限,图中蓝色块数字输入框的 min */
  downLimit?: number;
}

styleSchema

负责处理组件的样式配置项展示,为了保证组件的大小,我们决定使用JSON配置的方式控制组件的展示,实现了一个 JSONRender 的组件

配置实例

{
	is: 'jr-collapse',
	label: '卡片样式',
	children: [
		{
			is: 'el-checkbox',
			label: '是否显示',
			name: 'isShow',
			defaultValue: false
		}
	]
}

组件上,我们约定了一些特定字段,其中最重要的是name字段;组件接收一个 ref 的空对象,配置的name会挂在这个 ref 上透传给 组件实例,其他组件的配置直接写在外层,扁平化的处理

难点在于组件之前的关系处理,最常见的场景,配置A配置了特殊值a,配置B需要 disable 或者限制某些设置,这种动态的吹上,使用函数的方式,函数的参数是 ref对象,在给组件设置值的时候,使用函数设置方式的字段,会包裹上 computed 实现了动态的字段值设置

协议展示

type syleSchema = []StyleConfig

type StyleConfigItem = {
  /** 当前控件的标识,对应组件的 props */
  value?: string,
  /** 控件 label */
  label: string;
  /** 控件 label tip */
  tip?: string;
  /** 控件类型 */
  type?: string,
  /** 控件,支持开发者自定义 o-input */
  component?: Vnode,
  /** 子控件, 当存在这个 children 的时候,说明当前为容器  */
  children?: StyleConfigItem[],
  /** 根据具体目标和制约因素,选择最佳的标签对齐方式 */
  labelPosition: 'top' | 'left' | 'right'
  /** 控件 props {  min: 12 } */
  props?: object
  /** 根据具体目标和制约因素,选择最佳的标签对齐方式 */
  showEnable: boolean;
  /** 是否启用,默认为 false,当为 false 的时候,children不会展示 */
  /** 切换为 false 的时候,children 内的 value 需要清空 */
  enable?: boolean;
  /** 验证函数, 返回一个字符串当报错提示,不返回就通过 支持 promise */
  validate?: (value: any) => string | undefined;
}

AdvancedSchema

高级配置面板, 配置上跟样式的配置实现一致
展示上,平台为图表统一做了一些高级配置包含 自动刷新,图表联动等,所以组件自身的高级配置会被归拢到一个独立的展开层

@chiyan-lin
Copy link
Owner Author

chiyan-lin commented Feb 1, 2024

组件实例

组件结构

每一个组件的代码,由种子文件生成,核心的文件 mate.ts(导出组件配置) component.vue(导出组件实例控制ui) dev-data.ts(调试数据)

// component.vue
<script setup lang="ts" name="component">
import { computed, reactive, watch, ref } from 'vue'
// 抽离的统一方法包
import { chartDirective, chartUtils } from '@bi/util'
import { Data, ConfigData, ConfigAdvance, ConfigStyle, ConfigGlobal, MethodUtil } from './interface'

const props = defineProps<{
	/** 用户配置的数据配置获取到的数据 */
	data: Data
	config: {
		/** 用户配置的数据配置数据 */
		data: ConfigData
		/** 用户配置的样式配置数据 */
		style: ConfigStyle
		/** 用户配置的高级配置数据 */
		advanced: ConfigAdvance
		/** 用户配置的全局配置 */
		global: ConfigGlobal
	},
	// 平台提供的工具集合
	util: MethodUtil
}>()

const vEcharts = chartDirective.echarts
const selfOption = reactive(chartUtils.getDefault())

const options = computed(() => {
	chartUtils.setOption(selfOption, props, 'bar')
	chartUtils.setEnhanceOption(selfOption, props)
	return selfOption
})
</script>

<template>
	<div class="container" v-echarts="{ options, props }"></div>
</template>

<style scoped></style>

一个基础的柱状图如上所示,平台提供的工具包可以包揽大部分的配置

@chiyan-lin
Copy link
Owner Author

组件大小

我们规定,一个组件通过压缩后的代码大小不可以超过15k,常规的大小我们控制在10k以下

设计上我们把编辑和纯展示拆分为2种,更好地处理组件在不同场景的组件大小对平台的影响

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant