图表数据源

前言

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

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

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

fb75ec82f946408eb1ae63071a592f77

ba1e77e89092433c92369b5cd1e2d042

上述场景中,可能仅数据输入部分无法满足需求,在图表分析要素设置上完全可以使用标准组件能力来实现,如果能将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 4ff62fbca24c47208b15ce6e49474bfc

clazz的数据来源为维度class c45b174bf5d84b8a884bbf72ade5aa3c

则可如下定义元数据结构

[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函数

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

d637f884fc834b8fb1da48f98396a2b6

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

dc78f7506eba49628c96f4d7c908e567

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

7e3fd6b0ced7449c99b44c7fd881751c

组织数据

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

示例完整脚本

cdaf18a62c574f24b785642fd9a514bb

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

使用效果

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

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

f316106264094c419236e75a6ba25aa9

POV的详细配置

1d767fa6828049029f4b5f74287602a6

类别轴的详细配置

5281f57f3c5d44b3addac09ed0954353

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

f87657e17a874b33bea0ba7ebb879af2

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

4cd21e9e4a3c47c9bbeec5ebe059053a

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

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

af3b9bda04ba406c9d2a220e5fdf50f9

得到的结果为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]]

完整脚本

f4fddd648938467ea662180c3f9d7aac

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

16eae19d8f66421990acf123d759824a

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

定制Engine

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

[3]:
import pandas as pd

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

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

aaf524b98fa645ee915806136de09eff

完整脚本

f2958eaf8e17496896ca19157d4446f4