5

数据可视化探索-杜邦分析图

 1 year ago
source link: https://jelly.jd.com/article/62a6d1325deaaa01b341d09b
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
数据可视化旨在借助图形化的展示,更清晰有效地传达数据信息,降低数据指标的认知难度。相比传统的数据表格展示,图形化能将数据以更符合用户理解的方式转化呈现,使数据更具说服力与生命力,能够帮助用户实现更高效准确的分析决策。本文以JMT组件库的杜邦分析图为例,介绍在深度定制化的数据分析场景下,如何结合数据指标与可视化图形,进行指标关系的分解与层级化展示。

一、杜邦分析简介

杜邦分析法(DuPont Analysis)是综合利用多种财务指标比率之间的关系来分析企业财务状况的分析方法。其基本思想是将企业净资产收益率逐级分解为多项财务比率乘积,这样有助于深入分析、比较企业经营业绩。由于这种分析方法最早由美国杜邦公司使用,故名杜邦分析法。
使用杜邦分析法可以清晰的描述指标体系内指标的层次和指标间的关系,如下图所示,杜邦分析法通过树形结构自顶向下的展示了指标间的构成和层级关系,同时,通过指标之间的运算符号清晰的展现出指标之间的计算关系,例如“净资产收益率=总资产净利率 * 权益乘数”、“总资产净利率=销售净利率 * 总资产周转率”、“销售净利率=净利润 / 销售收入”、“总资产周转率=销售收入 / 资产总额”。采用这一方法,可使财务比率分析的层次更清晰、条理更突出,为报表分析者全面仔细地了解企业的经营和盈利状况提供方便。(图片仅为demo展示并非真实数据)

11d36b920f7b79f2.png

除了财务指标,杜邦分析法还可以用于分析流量、用户、交易等指标。

二、具体实现

下面将从技术选型、格式定义、布局策略、关系展示、交互功能5个方向详细介绍如何实现杜邦分析图。

1. 技术选型

为了实现灵活性、性能、可拓展性具佳的杜邦分析图,我们分别调研了D3.js与SVG,下方表格对二者在实现可视化图表方面,做出了详细的对比:

D3SVG
官网 https://d3js.org/ https://developer.mozilla.org/zh-CN/docs/Web/SVG
简介D3.js是一个JavaScript库,可以通过数据来操作文档,是数据驱动DOM。D3可以通过使用HTML、SVG和CSS把数据鲜活形象地展现出来。SVG是一种用于描述二维的矢量图形,基于XML的标记语言,具有XML的开放性、可移植性和可交互性SVG 能够优雅而简洁地渲染不同大小的图形。
优点1、灵活性强,具备基础算法,功能十分强大。2、数据转换和绘制是独立的。3、绘制主要使用SVG实现。4、运行速度很快,支持大数据集和动态交互及动画。1、绘制高质量的矢量图形。2、具备强大的交互能力。
缺点学习曲线比较高,需要一定的基础。更底层,无基础算法

由于业务场景中有很多个性化的需求与交互方式,因此选用D3.js技术开发,虽然它的上手成本更高一些,但是灵活度高、功能拓展方便,D3.js的数据转换与绘制(使用SVG,包含SVG的所有优点)是独立的,数据转换计算与图形绘制互不干扰、各有各的分工。

2. 格式定义

在研发前需要设计通用的数据格式,通用的数据格式可以实现更灵活的个性化需求。通过沟通业务需求场景及未来可能展示的场景,将杜邦分析图的数据格式主要定义为3大类:node节点、节点关系、多种配置。
node节点:是一个数组,数组里包含多个对象,对象里有两个主要信息:指标id(唯一值)和parent(父节点),其他信息可以根据业务需要来进行展示;
节点关系:是一个数组,数组里包含多个对象,对象里有多个信息:source(源节点)、target(目标节点)、relation(源节点与目标节点的关系)、top(源节点上方展示内容)、bottom(源节点下方展示内容)、left(源节点左侧展示内容)、right(源节点右侧展示内容);
多种配置:是针对node节点、容器、布局类型等基础信息进行配置。

// node节点配置 name:节点名称  id:节点id  parent:节点的父节点
const node = [
        {
            name: '净资产收益率',
            id: 1,
            parent: null
        }
       // ...
];
// node节点关系
// source:源节点  target:目标节点  
// relation:源节点与目标节点的关系的配置(icon:展示内容  width:展示内容宽度  height:展示内容高度)
const graph = [
        {
            source: 2,
            target: 3,
            relation: {
                icon: 'icon内容',
                width: 10,
                height: 10
            }
        }
       // ...
];
// 其他配置(node节点配置、容器配置、收缩展开配置、连接线配置、连接处icon配置、场景配置等)
const config = {
        container: { // 节点的配置信息
            width: 300, // 节点的宽
            height: 96, // 节点的高
            margin: [60, 60] // 节点的上下、左右的间距
        },
        grid: { // 容器的配置信息
            top: 10, // 容器距离顶部的距离
        },
        scene: 'horizontal', // 场景信息,垂直与水平
        // ...
};

3. 布局策略

由于不同模块指标体系的使用场景不同,杜邦分析图展示的布局也是不同的,为了可以满足所有场景,一共设计了12种布局方案,如下图所示,主要分为两大类:垂直方向(自顶向下、自底向上)、水平方向(自左向右、自右向左)。(图片仅为demo展示并非真实数据)

11d36b920f7b79f2.png
11d36b920f7b79f2.png

基础布局算法主要应用D3.js提供的d3-hierarchy对层次结构数据进行布局计算。通过D3.js基础算法可以得到一个树形结构且带有node节点位置信息的数据: tree,根据需要展示的布局方式,对数据tree做不同的处理。

// 获取node节点的基础位置信息,node变量数据如格式定义里的node
const tree = d3
            .tree()
            .nodeSize([100,100]);
const root = d3
            .hierarchy(
                d3.stratify()
                    .id(function (d) { return d.id; })
                    .parentId(function (d) { return d.parent; })(node), 
                person => person.children
            );
// 根据不一样的布局方式,通过在eachBefore里重新计算node节点信息
root
    .eachBefore(d => {
        d.x0 = d.x;
        d.y0 = d.y;
})
tree(root);

如下图是通过node节点的坐标、节点的宽高绘制出的场景(图片仅为demo展示并非真实数据):

11d36b920f7b79f2.png

4. 关系展示

如布局策略所示,已经可以通过node节点的坐标、节点的宽高绘制出不同的场景,目前还只是单纯的把node节点、层级关系绘制出来,但并没有绘制出不同层级的node节点关系、同层级的node节点关系,所以还需要继续绘制出node节点间的关系。

  • 绘制不同层级的node节点关系:将不同层级的node节点连接起来,是通过SVG进行线的绘制将父与子的节点进行连接,主要是通过node节点的父子关系、node节点的位置信息、其他配置信息等内容计算线的path路径。(图片仅为demo展示并非真实数据)
    11d36b920f7b79f2.png
    如上图所示,将源节点、目标节点进行连接需要四个点A(X0,Y0)、B(X1,Y1),C(X2,Y2),D(X3,Y3)来进行绘制连接线,这四个点的坐标则是可以通过源节点的坐标信息、目标节点的坐标信息、其他配置信息来计算A、B、C、D四个点,之后将这四个点进行连接。
    <path d="MX0 Y0 LX1 Y1 LX2 Y2 LX3 Y3" />
    如下图是将父子节点进行连接的场景(图片仅为demo展示并非真实数据):
    11d36b920f7b79f2.png
  • 同层级的node节点关系:相同父节点下的同层级的子节点的关系我们也需要绘制,同层级的子节点的关系主要是加减乘除,用户可以通过配置的元素来进行展示,主要是通过判断某两个节点是否有关系,有关系则进行关系展示的位置计算并渲染展示。(图片仅为demo展示并非真实数据)
    11d36b920f7b79f2.png
    如上图所示,展示源节点、目标节点之间的关系,将关系icon在两个节点间的中间位置进行展示,根据源节点的坐标信息(X0,Y0)、目标节点的坐标信息(X1,Y1)、节点的宽高(nodeWidth, nodeHeight)、关系icon的宽高(iconWidth,iconHeight)计算出关系icon的坐标信息(X, Y),可以根据关系icon的坐标信息进行绘制和渲染。
// icon的信息
const icon = {
    width: iconWidth,
    height: iconHeight,
    x: (X0 - nodeWidth - X1) / 2 - iconWidth / 2,
    y: nodeHeight / 2 - iconHeight / 2
};

如下图是展示两个节点之间关系的场景(图片仅为demo展示并非真实数据):

11d36b920f7b79f2.png

除了可以展示源节点、目标节点的关系,还可以在源节点的上下左右的位置进行内容的绘制。如下图在销售净利率、总资产周转率指标的上方增加一个tag信息,可以代表该指标的某些具体信息(包含具体的值、颜色等)。(图片仅为demo展示并非真实数据)

11d36b920f7b79f2.png

5. 交互功能

杜邦分析图是以层次清晰、重点突出展示指标为特点的图表体系。但若某个模块的指标体系的指标量大,则需要用户需要通过交互找到自己关心的信息。因此杜邦分析图是否好用,交互功能会起到非常重要的作用。我们为此实现了两个功能:

  • 收缩展开:由于指标体系的指标量大,父节点指标具备收缩的功能非常重要,进行收缩可以从大量的指标中关注重点的指标。
  • 容器里内容缩放:由于指标体系的指标量大,但是容器的大小是固定的,那如何在有限的容器空间内展示更多的信息,首先可以将所有指标在容器内展示完全,可通过缩放的形式查看关注的指标。
    // 收缩展开按钮点击事件
    () => {
      // 点击收缩展开按钮时对node节点的children、_children属性进行设置于渲染
      if (d.children) {
          d._children = [...d.children];
          d.children = null;
      } else if (d._children) {
          d.children = [...d._children];
          d._children = null;
      }
      // 更新渲染
      this.update(d, {
          data: d.data.data,
          expand: !!d.children,
          node: d
      });
    }
    // 容器里内容缩放,使用viewBox实现
    // 这里定义的画布尺寸是containerWidth、containerHeight。但是,viewBox属性定义了画布上可以显示的区域:从(x,y)点开始,width、height的区域。这个区域,会放到containerWidth、containerHeight的画布上显示。于是就形成了放大缩小的效果。
    svg
      .attr('width', containerWidth)
      .attr('height', containerHeight)
      .attr('viewBox', [x, y, width, height]);
    如下图是对销售净利率、总资产周转率指标进行子节点收缩的场景(图片仅为demo展示并非真实数据):
    11d36b920f7b79f2.png
    除了可以实现以上案例的杜邦分析图,还可以根据不同的配置实现个性化的需求以达到用户的使用预期、满足用户的使用场景。(图片仅为demo展示并非真实数据)
    11d36b920f7b79f2.png

三、业务应用案例

目前杜邦分析图在黄金眼数据产品中已有多处应用,在疫情地区物流履约看板中展示物流履约流程指标体系的杜邦分析图,展示出物流履约流程的5个环节及每个环节的指标数据,通过查看物流指标排查物流异常原因;在毛利诊断的看板中展示毛利构成指标体系的杜邦分析图,展示出商品毛利额的计算公式,通过查看毛利指标排查异常指标原因。

物流履约流程指标体系的杜邦分析图。(图片仅为demo展示并非真实数据)

11d36b920f7b79f2.png

毛利构成分析指标体系的杜邦分析图。(图片仅为demo展示并非真实数据)

11d36b920f7b79f2.png

杜邦分析图是对指标体系的指标拆解、指标计算的可视化的体系化通用解决方案,帮助我们解决了不同模块指标体系的可视化的展示与交互,让指标体系的层次更清晰、条理更突出,帮助用户全面的了解指标情况。
截止目前,JMT组件库已沉淀包含杜邦分析图的可视化组件100+个 ,覆盖PC端与M端,并支持个性化主题定制,欢迎大家了解与使用: JMT组件库


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK