美文网首页
一种链式逻辑分析和可视化展现设计

一种链式逻辑分析和可视化展现设计

作者: 西5d | 来源:发表于2018-08-08 14:25 被阅读81次

在业务实现中,遇到一种场景,从开始传入多方的数据,经过多个不同种类环节的分析,最终得到一个分析结果。在对业务逻辑抽象后,我们实现了一种基于树形的分析结构,达到了比较理想的效果,优点主要有以下几个:

  1. 分析逻辑复用,避免了重复的代码;
  2. 结构简洁,清晰,维护成本低;
  3. 分析结构和结果的可视化,简化了分析流程;

考虑到这种分析方式可以在其他类似的场景下复用,因而做个简单分享记录。后面会从以下几个方面介绍,首先是分析结构的模块设计以及核心点的功能,之后简单介绍下分析流程。

一、分析结构模块和功能

1、处理上下文

实现为一个Context,主要包含入口数据,一个用作节点跟踪的有序List。入口数据是包装的业务参数,本例为待分析的原始数据;节点跟踪用于生成处理的结果链。代码模板如下,可以根据自己不同的需求做扩展。

public class ProcessContext {
    private LinkedList<ProcessNode> traces = Lists.newLinkedList();
    private CompareRequest data;
     ... 
        /**
     * 获取最终结果,待修改
     *
     * @return
     */
    public ProcessNode finalResult() {
        if (CollectionUtils.isNotEmpty(traces)) {
            return traces.getLast();
        }
        return null;
    }
    //结果链
    public String printShowChain() {
        if (CollectionUtils.isEmpty(showtraces)) {
            return "empty";
        }
        StringBuilder chain = new StringBuilder();
        for (String node : showtraces) {
            chain.append(node).append(" -> ");
        }
        chain.append("end");
        return chain.toString();
    }
}

2、树形处理结构和 节点

最初的方案是定义为一个ProcessTree,包含名称,描述,版本,以及一个根节点,树形结构采用XML文件形式定义,递归构造。之后采用的是直接以节点直接作为根开始,分类处理,将节点注册为SpringBean,也是配置在XML文件里。其中,节点包括描述,左右子节点,以及处理逻辑的接口。在树形中,叶子节点便是最终的原因,记录的整个处理链可以作为分析记录和辅助的分析数据。如下介绍:

/**
 * 类似二叉树流程节点
 */
public class ProcessNode {
    private String reason;
    private String desc;
    private ProcessNode left;
    private ProcessNode right;
    private ValidCheckService validCheckService;
}
    //获取下一个节点,返回null则终止
    public ProcessNode next(NodeType result) {
        return (left != null && result == NodeType.GO_LEFT) ? left : ((right != null && result == NodeType.GO_RIGHT) ? right : null);
    }
//左右节点标记
public enum NodeType {
        GO_LEFT(-1, "left"),
        GO_RIGHT(1, "right");

        private int code;
        private String desc;

        NodeType(int code, String desc) {
            this.code = code;
            this.desc = desc;
        }

        public int getCode() {
            return this.code;
        }
    }
}

初版树形定义和对应方法

/**
 * 逻辑处理树形,从root遍历
 */
public class ProcessTree {
    private String name;
    private String id;
    private String version;
    private ProcessNode root;

    public ProcessTree() {
    }

    /**
     * 全部执行,true --> goright  false --> goleft
     *
     * @return
     */
    public void processAll(ProcessContext context) throws ProcessException {
        List<ProcessNode> resultTrace = context.getTraces();

        ProcessNode node = root;
        ProcessNode.NodeType nodeType;

        while (node != null) {
            try {
                ValidCheckService validCheckService = node.getValidCheckService();
                //叶子节点,包含结论
                if (null == validCheckService) {
                    break;
                }
                nodeType = validCheckService.dataCheck(context.getData()) ? ProcessNode.NodeType.GO_RIGHT : ProcessNode.NodeType.GO_LEFT;
                node = node.next(nodeType);
            } catch (Exception e) {
                throw new ProcessException(e);
            } finally {
                resultTrace.add(node);
            }
        }
    }

    /**
     * 转换为echart 树形图
     *
     * @return
     */
    public TreeNode convertToEchartTree() {
        ProcessNode node = root;
        TreeNode treeNode = new TreeNode(root.getDesc());
        initTreeNode(treeNode, node);
        return treeNode;
    }

    /**
     * 递归遍历左右子树,作为转换
     *
     * @param treeNode
     * @param processNode
     * @see ProcessTree#convertToEchartTree()
     */
    private void initTreeNode(TreeNode treeNode, ProcessNode processNode) {
        if (processNode == null) {
            return;
        }

        if (processNode.getLeft() != null) {
            TreeNode left = new TreeNode(processNode.getLeft().getDesc());
            treeNode.addChildren(left);
            initTreeNode(left, processNode.getLeft());
        }

        if (processNode.getRight() != null) {
            TreeNode right = new TreeNode(processNode.getRight().getDesc());
            treeNode.addChildren(right);
            initTreeNode(right, processNode.getRight());
        }
    }
}

echart的Tree Node

/**
 * Echart tree base node
 * http://echarts.baidu.com/option.html#series-tree.type
 */
public class TreeNode {
    private String name;
    private List<TreeNode> children = Lists.newLinkedList();

    public TreeNode(String name) {
        this.name = name;
    }

3、处理逻辑抽象接口

接口只有一个方法,根据不同的业务逻辑实现,最终调用各自对应的处理逻辑。

public interface ValidCheckService {

    public boolean dataCheck(CompareRequest compareRequest) throws ProcessException;
}

二、分析流程和结果展现

实现的分析流程展现,最终通过echart画出图形,实际分析即从根节点开始,按照各自的处理逻辑,由结果确定下一个节点,直到遍历到叶子节点为止:


1.JPG

最终的分析链类似如下结构,业务原因不提供实际数据,见谅:

A->B->C->D->E->F->end

以上,就是分析流程的简单介绍,业务中也得到了良好的效果,有考虑过两个想法,未有实现。一是在创建树形时,可以用类似Activity等流程引擎的工具,做到创建可视化,但这个工作量可能较大,而且目前的业务中,分析流程基本固定,变化很少,单纯操作XML文件足够,暂不考虑这种方案;其次,分析链可以和展示树形结合,带一个固定key,然后按照链的数据在树形上突出展现,当时在echart一时没有找到简洁的接口,也就作罢。
感谢阅读。

相关文章

  • 一种链式逻辑分析和可视化展现设计

    在业务实现中,遇到一种场景,从开始传入多方的数据,经过多个不同种类环节的分析,最终得到一个分析结果。在对业务逻辑抽...

  • 【数据产品设计】-01总览

    数据产品流程设计可分为几大步骤,需求分析,数据指标设计,数据可视化设计(用什么样的图表表达数据),数据展现逻辑设计...

  • 【数据产品设计】-07数据展现逻辑设计

    时间逻辑 从时间角度去设计数据指标的展现逻辑,分为实时数据(在线监测)和历史数据(数据分析) 空间逻辑 也可以理解...

  • MAC系统下ELK6.5(ElasticSearch+Logst

    ELK是一种能够从任意数据源抽取数据,并实时对数据进行搜索、分析和可视化展现的数据分析框架。此篇文章对ELK环境部...

  • 只需两步,Excel变身可视化数据分析报表

    只需两步,就能成功将Excel数据成功转变为可视化数据分析报表,实现数据智能分析、可视化展现?这是什么神仙系统? ...

  • 一图看懂如何使用kibana

    概述 Kibana 是为 Elasticsearch设计的分析和可视化平台。通过 Kibana 来搜索和查看存储在...

  • 第二部分-上手

    定义数据可视化是数据内在价值的最终呈现手段,它利用各类图表及图形化的设计手段将复杂不直观的数据有逻辑地展现出来,使...

  • OC:链式编程

    概念: 链式编程:将多个业务逻辑(方法)通过“.”(点号)串联起来的一种代码风格,形似链条,故称链式编程。核心思想...

  • 2018-12-25 web项目开发的一般流程

    1、需求确定 2、分析与设计:架构分析与设计 3、分析与设计:业务逻辑设计 4、分析与设计:界面设计 5、开发环境搭建

  • 数据结构 —线性表,LruCache实现原理

    逻辑结构和物理结构 物理结构:是指数据的逻辑结构在计算机中的存储形式 顺序存储结构顺序存储 链式存储结构链式存储 ...

网友评论

      本文标题:一种链式逻辑分析和可视化展现设计

      本文链接:https://www.haomeiwen.com/subject/geitbftx.html