图表数据源

前言

对图表组件来说,在当前的数据分析场景中,有较多情况是目前基于财务模型、业务模型作为数据源是无法满足的:

  • 当分析的数据需要基于模型中原始数据进行计算的情况下,如计算 A列+B列,该类计算能力从产品框架划分来看,应该是由计算层提供,但短期内可能无法上线以满足需求场景

  • 当分析图表希望从多个数据模型中取数据时,如:展示A模型中的销售数据、B模型中的成本数据等,此类为多个数据模型作为数据源的需求

a183dd5b300741f28dd199fc6bed877c

809f68ab50914692a69d2401bddfb9ab

上述场景中,可能仅数据输入部分无法满足需求,在图表分析要素设置上完全可以使用标准组件能力来实现,如果能将Python的结果作为数据源输入到图表组件中,将极大的减少需要自定义开发的功能数量,提高项目实施效率。

简单示例

一个可以作为图表数据源的脚本,由如下部分组成

  • 字段信息,即元数据信息

  • main函数中返回符合元数据信息的 Pandas DataFrame

定义字段信息

例如需要定义如下数据的元数据信息:

describe

date

cost

active

clazz

for A

2021-07-12

100.00

true

class1

B

2021-02-01

200.00

true

class2

for C

2021-06-29

500.00

false

class3

for D

2021-12-31

700.00

true

class4

其中,active的数据来源为值列表active c64856274cd546449e98577f186f1b80

clazz的数据来源为维度class 29c6b61e6364435a83fd80054f4f6c1e

则可如下定义元数据结构

[1]:
from deepfos.lib.deepchart import *


class Data(Struct):
    desc = Text(name='describe', description='描述')
    date = Date(description='日期')
    cost = Number(description='开销')
    active = SmartList(element_name='active', path='/deepchart', value_field=['true', 'false'])
    clazz = Dimension(element_name='class', path='/deepchart', description='级别')


在如上定义中,比较特殊的是对于值列表元素字段active和维度元素字段class的定义,由于来自元素,需要提供元素信息(元素名,如元素名不唯一,需提供path和folder_id二选一)

针对值列表,支持提供参数 value_field 用以指定生效的值成员信息。

**当前支持的所有字段类型和可用参数见**字段类型

在定义了如上元数据后,以此作为as_datasourcestruct 参数装饰至main函数

完整脚本(仅包含元数据信息)

f99aae396bbd4b5b90420b99d7d38bc2

以此脚本作为数据源后初始化的图表编辑界面如下

9c8792a907744a5980a627e2dc8a4995

其中的active值列表的成员信息也已按照元数据设置被限制在true, false间

2e483dc61db84922bcbf46f125cdbccd

组织数据

main函数中返回符合元数据信息的 Pandas DataFrame,此处的 Pandas DataFrame 可以以任何方式组织,只需保证在main函数 return时,为 Pandas DataFrame 数据即可。

示例完整脚本

c779e30d848642729dc030c5a25055c2

此时该脚本就是一个可以提供元信息,并可以在使用时提供实际数据的数据源了

使用效果

现有图表界面的筛选配置可经过 ChartEngine 被解析理解,达到对结果数据的筛选聚合处理效果。

例如图表编辑界面设置如下

9883ae423f2e45b492bf2b6cac274099

POV的详细配置

f2b281ceaf9240fc88aebe24c7f61d5d

类别轴的详细配置

831cf674ecfb408dbef38949e83ad64b

图形属性的详细配置(只有describe字段有过滤规则)

feabb97ea9b54872b5553013706e9567

图表从编辑界面切换至使用界面

ab13656839364314953bee365c196926

可见,在使用时,筛去了describe不以’for ’开头且不在’A,B,C’中和active不为true的记录的数据,与图表设置一致

从中进一步选择class1的数据后点击查询

9a1228ecd8154ab3918e484c446a25ff

得到的结果为POV和筛选条件的交集

元数据

元数据,即图表编辑时所需的字段信息,包括字段的名称、描述、类型及其他必要信息,在选取Python元素作为图表数据源时,需提供。

deepfos.lib.deepchart中,包装了作为图表数据源已支持的字段类型,只需将其进行初始化后作为 Struct 子类的类成员即可。

字段类型

Python类名

图表中的字段类型

备注

Text

文本

Date

日期

* deepfos>=1.0.44 增加精度配置项 precision ,默认为年月日,在比较时会以该配置项的精度为准

Number

数字

SmartList

值列表

Dimension

维度

Person

用户

* 图表组件需在版本2.0.10.11及以上,deepfos版本在1.0.44及以上

类型参数

Python类名

name - 字段名

description - 字段描述

element_name - 元素名

folder_id - 元素folder_id

path - 元素path

value_field - 成员列表

precision - 精度

Text

Y

Y

Date

Y

Y

Y

Number

Y

Y

SmartList

Y

Y

Y

Y

Y

Y

Dimension

Y

Y

Y

Y

Y

Person

Y

Y

注:

  • name未提供时,默认以字段在Struct子类中成员名为字段名

  • description未提供时,默认以name为字段描述

  • Date 类型的精度默认为年月日,可选项为year/month/quarter/day,使用deepfos.lib.filterparserTimeType 提供

class TimeType(IntEnum):
    year = 1
    quarter = 2
    month = 3
    day = 4

日期精度与格式对照

精度

日期格式

年月日

YYYY-MM-DD

年月

YYYY-MM

年期间

YYYY-Qn

YYYY

数据处理

在定义了元数据后,将元数据结构赋值至as_datasourcestruct 字段,并装饰main函数

此时,main函数预期返回 Pandas DataFrame ,SDK将依据as_datasourceenginebefore_return 参数和入参的业务参数将main函数返回的 Pandas DataFrame 进行筛选聚合,最终变为图表组件可用于显示数据的格式。

参数说明

as_datasource方法签名如下

def as_datasource(
    func=None,
    struct: Type[Struct] = None,
    engine: Optional[Type[ChartEngine]] = ChartEngine,
    before_return: Optional[Callable[[pd.DataFrame, Dict], pd.DataFrame]] = None,
    date_round: bool = False
):
  • func: 即main函数,可为异步

  • struct: 元数据信息,即字段及其字段类型的类,不可为空

  • engine: 用于数据处理的引擎,默认为ChartEngine;如用户需自定义,应继承自ChartEngine;为None时,不对main函数的结果DataFrame作处理

  • before_return:用户自定义的同步方法,作为ChartEngine处理的后置逻辑,该方法应接受处理后的DataFrame和来自图表组件的原始参数为入参

  • date_round: 是否允许低精度日期值与筛选条件内高精度日期值进行比较,默认不允许。允许后则精度缺失* 时,除了相等以外,统一判定为不符合条件

注: 精度缺失:例如2012与2012-10,缺失了月份部分,而2011与2012-10本身在年份可比,不属于精度缺失

定制后置处理

简单示例的基础上增加后置处理,例如在代码层面保证只出一条结果数据记录,则可编辑后置方法如下

[2]:
def limit_to_one(df, param):
    return df.iloc[[0]]

完整脚本

91a5cff92ce446e6ac13b8c6eeb49ec7

图表查询结果(查询级别:class1, class2, class3)

f86d1f83e51d443d93c5bb7c4fabc4fe

可见即使符合条件的会有两条数据,经过了后置函数的处理后,也只有一条数据被返回

定制Engine

简单示例的基础上使用自定义的引擎来进行数据处理,例如强制结果数据固定为空

[3]:
import pandas as pd

class CustomEngine(ChartEngine):
    def _main(self, df: pd.DataFrame):
        return pd.DataFrame()

在使用了 CustomEngine 后,使用界面将一直为无数据

60782626b0d0483bb65b47b396507158

完整脚本

a5ad570be9524067898671d6d2d2c6c2