X6在数栈指标管理中的应用

一、需求背景

产品成立之初,产品的需求是需要对各种指标进行公式运算,组合成一个新的复合指标,供后续使用。当时产品提出的形式是有两种:

一种是直接让用户输入,不作任何其他操作,但这种方式带来的问题一个是,需要前端对公式进行复杂的校验,太多不可控的问题,另一个是操作指导性很弱,用户在使用的时候没有任何限制,也并不太能明白如何操作;

另一种方式就是让用户通过拖拽的方式,添加运算符,去组成自己需要的公式,比较直观,且视觉效果更好,所以最终产品交互选定用这种方式。

二、选型考虑

复合指标的高级模式功能点分解:拖拽指标、新增运算符,设置指标的过滤条件,设置条件的过滤,去更新数据;节点新增后,重新计算位置,更新渲染。

关于拖拽后生成一个节点、且有序排列,针对当前节点新增前后节点,使其整齐排列,技术范围确定到G6、X6上面。但对于是选用G6还是X6,从以下五个方面考虑:

1、针对上述需求分解,可以看到我们这个需求是偏重数据编辑的,而官方对于G6、X6的建议是,G6偏向于图可视化和分析,X6偏向于图编辑和数据编辑

2、自定义能力大小。由于指标管理中的节点并非只是个节点,而是可能是指标、操作符、输入框,形式多样,且,指标类型的节点需要展示的信息比较多,里面包含了图片、颜色、文本等信息,如果使用X6是可以直接用html写的,而使用G6就要熟悉了解canvas,新版本的G6可以支持jsx语法自定义节点,但并没有支持的那么好。

3、数据量大小。如果是节点繁多,图的规模较大,想要交互流畅,当然是用canvas的G6更合适,但如果数据量比较小,则都可以。

4、是否需要统计图表节点:G6 支持嵌入 G2 的统计图到一个节点中,而当前需求是不需要嵌入图表节点

5、是否需要支持移动端/小程序:在移动端,G6 可以支持展示和简单交互,且在不断完善中。而且移动端、小程序对性能的要求更高,所以如果是要支持移动端或小程序会优选G6

三、指标管理中复合指标的使用

关于X6在数栈指标管理的应用,主要是在复合指标的新增、编辑、删除模块,其中,分为普通、高级两种模式,其区别是:

普通模式仅可单公式,例如(A+B)*0.3;

而高级模式则可以配置多公式,例如当A >=0时,(A+B)*0.3;当A < 0时,(A+C-B)*0.4;

而本文主要叙述的是高级模式的相关内容,关于其操作,主要分为以下几个方面:

1、新增

图3-1

参考图3-1,可以点击“新增公式”新增一条包含条件和公式的单公式;拖动左侧指标目录中的指标到右侧对应区域,可以将指标添加到条件或者公式里去。

2、编辑

图3-2

图3-3

图3-4

图3-5

如图3-2所示,我们可以点击对应指标将其选中,对这个选中指标进行结果过滤设置;如图3-3所示,我们可以点击条件右上角的“设置”按钮,对当前条件进行结果过滤设置;可以点击条件或者公式后的图标,对条件名、公式名进行编辑;如图3-5所示,点击维度设置,可以对当前所有加入到画布中的指标的公共维度进行设置,与此同时选中某一个指标,可以对当前选中指标进行维值过滤设置。

3、删除

图3-6

图3-7

如图3-5所示,可以在选中某一个指标之后,点击窗口右上角的“删除”按钮,将选中指标从当前公式中删除,最终得到的结果如图3-6所示;同样可以点击公式右边的删除图标,会将当前一整条公式(包含条件、公式)都删除。

4、查看

查看是指从指标列表里的某个复合指标右侧的“编辑”操作进入编辑页面,可以看到上次保存的配置好的公式信息,选中不同指标、点击不同条件的设置,会回显出上一次你保存的结果过滤信息。

四、X6的具体使用

新手入门快速上手点这里:快速上手 | X6

而关于两种模式的实现区别则是数据处理上的区别,核心使用步骤有以下几点:

1、确定数据结构

高级模式下可以只配置一条公式,但是也可以通过点击新增公式按钮增加多条公式,公式数量上限为5条。对于X6来说,对HTML的支持、自定义的能力都是很不错的,所以对于自定义效果比较高的指标管理中的节点,我们根据视觉效果可以定出整体数据结构为

//指标基础信息
const indexInfo = {
	name: '',
  code: '',
  status: '',
  ...
}
// 高级模式数据结构
const advancedFormula = [
	...
  {
  	condition: {
      name: '条件1',
			conditionSet: {},
      formulaList: [
      	{
        	type: 'index', // index--指标节点  operator--运算符节点
          value: '', // 当type为operator,且value有值时,则有数值输入框类型
          ...indexInfo
        }
      ]
		},
    formula: {
      name: '公式1',
    	formulaList: [
      	{
        	type: 'index', // index--指标节点  operator--运算符节点
          value: '', // 当type为operator,且value有值时,则有数值输入框类型
          ...indexInfo
        }
      ]
    }
  }
]

2、从数据结构到视图的渲染过程

这个过程主要是调用X6的API中提供的graph.addNode方法去添加节点到画布。

但首先要遍历数据结构处理为带着层级信息的数据,然后通过遍历数据结构,并同时将层级关系和指标信息加入到节点信息里,以确保在操作新增、编辑等操作时可以准确获取到层级信息,能够准备新增、插入、编辑节点信息。

drawAdvancedNode = (data: any) => {
    // 画高级模式的层级结构,从单条公式父框 ---> 单条公式的条件 + 单条公式的公式 -----> 具体的操作、指标
    if (data.length === 0) {
      return false;
    }
    // 遍历数据结构调用graph.addNode方法添加对应节点到画布中: 计算每个节点对应的具体x、y坐标
};

3、更新

更新的过程主要是在进行了新增、插入、编辑等操作后,会更改原数据,生成一份新的数据,这时候需要拿到新的数据进行重新渲染,需要将画布上的内容清空,然后重新绘制,而涉及到画布清空会用到clearCells方法,但高级模式会存在层级,所以会发现,使用这个方法并不能有效的把画布清空,所以最终先将所有节点获取到,再一一移除。在移除之后,将当前新数据渲染到画布中,即重复步骤2中的操作

// 清空所有画布中的节点
const allNodes = this.state.graph.getCells();
allNodes.map((item: any) => {
   this.state.graph.removeCell(item.id);
});

4、提交

遍历所有的数据,将层级信息字段去掉;对一些为空字段做过滤处理;将一些额外字段整理到节点数据中去;对画布上的现有公式的合法性做出校验,若是不合法公式则弹出提示。格式化完成后则可允许用户将画布中的数据提交到后端。​

{{o.name}}
{{m.name}}

猜你喜欢

转载自my.oschina.net/u/3869098/blog/5448591