最近在设计新版的流程渲染引擎,考虑采用无损失放缩的矢量图SVG去搞,从技术调研到实现蛮有心得的,这里贴出自己的设计思路,欢迎拍砖~

首先说下诉求,简单说就是绘制流程地图。其次简单列举下需要注意的技术点:

(1) 图形元素和坐标元素解析(合并or分拆)

(2) DOM树解析,原生JAXP,DOM4J or SVG DOM utils(混用会带来很多问题)

(3) REST Service Lib选型

(4) SVG 元素渲染技巧

(5)一些几何算法(旋转矢量,斜率,两点中距,碰撞检测)

(6)XML,XPath等一些奇淫技巧(Axis,namespace,doctype,qname,EntityResolver等)

好,Mind有了,我们上图评设计;

图1 : 原型 - 比较丑

图2 : 预期 - 比较美

图3 : Core Class Diagram

图4 :  REST Request Response Sequence Diagram

图5:   Process-Figure Render Sequence Diagram

SVG代码片断一:(伪table样式)

<?xml version='1.0' standalone='no'?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN''http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
<svg width='100%' height='100%' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><title>SVG Tables</title><g id='columnGroup'><rect x='25' y='30' width='35' height='70' fill="#c9dae5"/><rect x='195' y='30' width='35' height='70' fill="#e0f0f9"/><rect x='395' y='30' width='35' height='70' fill="#e0f0f9"/><text x='30' y='30' font-size='12' text-anchor='left'><tspan x='30' dy='1em'>表头</tspan><tspan x='30' dy='2em'>表头</tspan><tspan x='30' dy='2em'>表头</tspan></text><text x='100' y='30' font-size='12' text-anchor='left'><tspan x='100' dy='1em'>同意</tspan><tspan x='100' dy='2em'>调查</tspan><tspan x='100' dy='2em'>中国</tspan></text><text x='200' y='30' font-size='12' text-anchor='left'><tspan x='200' dy='1em'>同意</tspan><tspan x='200' dy='2em'>调查</tspan><tspan x='200' dy='2em'>中国</tspan></text><text x='300' y='30' font-size='12' text-anchor='left'><tspan x='300' dy='1em'>同意</tspan><tspan x='300' dy='2em'>调查</tspan><tspan x='300' dy='2em'>中国</tspan></text><text x='400' y='30' font-size='12' text-anchor='left'><tspan x='400' dy='1em'>同意</tspan><tspan x='400' dy='2em'>调查</tspan><tspan x='400' dy='2em'>中国</tspan></text></g><g id='rowGroup' transform='translate(0, 160)'><rect id="b_rect" x='25' y='0' width='230' height='20' fill="#c9dae5"/><animateColor id="b_rect" attributeName="stroke" from="none" to="green" repeatCount="indefinite" dur="1.3s" calcMode="spline" /><rect x='25' y='40' width='230' height='20' fill="#e0f0f9"/><rect x='25' y='80' width='230' height='20' fill="#e0f0f9"/><text x='30' y='0' font-size='12' text-anchor='left'><tspan x='30' dy='1em'>表头</tspan><tspan x='100'>表头</tspan><tspan x='200'>表头</tspan></text><text x='30' y='0' font-size='12' text-anchor='left'><tspan x='30' dy='2.7em'>同意</tspan><tspan x='100'>Expenses</tspan><tspan x='200'>中国</tspan></text><text x='30' y='0' font-size='12' text-anchor='left'><tspan x='30' dy='4.4em' >同意</tspan><tspan x='100'>Expenses</tspan><tspan x='200'>中国</tspan></text><text x='30' y='0' font-size='12' text-anchor='left'><tspan x='30' dy='6.1em'>同意</tspan><tspan x='100'>Expenses</tspan><tspan x='200'>中国</tspan></text><text x='30' y='0' font-size='12' text-anchor='left'><tspan x='30' dy='7.8em'>同意</tspan><tspan x='100'>Expenses</tspan><tspan x='200'>中国</tspan></text></g><g><rect x="370.0" y="144.0" width="600" height="15" fill="#c9dae5"/><text x="377.0" y="144.0" font-size="11" text-anchor="left"><tspan id="t_blink" x="377.0" dy="1em">节点开始时间</tspan><animateColor id="t_blink" attributeName="stroke" from="none" to="red" repeatCount="indefinite" dur="1.3s" calcMode="discrete" /><tspan x="507.0">节点结束时间</tspan><tspan x="637.0">计划处理人</tspan><tspan x="767.0">实际处理人</tspan><tspan x="897.0">审批决策</tspan></text><text x="377.0" y="144.0" font-size="11" text-anchor="left"><tspan x="377.0" dy="2.5em">12-10-26 上午9:40</tspan><tspan x="507.0" >12-10-26 下午2:53</tspan><tspan x="637.0" >yun.ma</tspan><tspan x="637.0" dy="1.5em">@alibaba-inc.com</tspan><tspan x="767.0">admin@xbpms</tspan><tspan x="897.0">重新进入</tspan></text></g>
</svg>

SVG代码片断二:(流程结点)

<?xml version="1.0" standalone="no"?>
<svg width="640" height="480" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><!-- Created with SVG-edit - http://svg-edit.googlecode.com/ --><g><title>公安机关财务报销申请</title><g id="svg_60"><rect id="svg_11" x="206" y="232" width="123" height="38" fill="#cbeddb" stroke="#0000bf" stroke-width="2"/><text id="svg_12" xml:space="preserve" text-anchor="middle" font-family="serif" font-size="12" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#000000" y="263" x="274">结束</text><text id="svg_13" xml:space="preserve" text-anchor="middle" font-family="serif" font-size="12" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#008000" y="245" x="272"><<End State>></text><rect x="216" y="247" width="12" height="12" id="svg_24" fill="#ff0000" stroke="#bf0000" stroke-width="2" stroke-dasharray="null"/></g><g id="svg_61"><path d="m253,140l11,5.199997l-11,7.800003l0,-13z" id="svg_32" fill="#000000" stroke="#000000" stroke-dasharray="null" transform="rotate(92.72631072998047 258.50000000000006,146.5) "/><line x1="254" y1="95.000002" x2="259" y2="140" id="svg_33" stroke="#000000" stroke-dasharray="null" fill="none"/></g><g id="svg_62"><rect stroke-opacity="0.71" x="198" y="56" width="123" height="38" id="svg_1" fill="#cbeddb" stroke="#261b1b" stroke-width="2"/><text xml:space="preserve" text-anchor="middle" font-family="serif" font-size="12" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#000000" id="svg_4" y="88" x="266">财务报销申请</text><text xml:space="preserve" text-anchor="middle" font-family="serif" font-size="12" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#008000" id="svg_5" y="69" x="264"><<Start State>></text><g id="svg_23"><circle cx="211.500001" cy="78" r="8.425827" id="svg_21" fill="#007f00" stroke="#007f00" stroke-width="null" stroke-dasharray="null"/><path d="m208.96106,71.672707l0.005127,12.181953l10.376938,-6.133987l-10.382065,-6.047951z" id="svg_22" fill="#d0e0d0" stroke="#007f00" stroke-width="null" stroke-dasharray="null"/></g></g><g id="svg_63"><rect id="svg_8" x="203" y="153" width="123" height="38" fill="#cbeddb" stroke="#ff0000" stroke-width="2"/><text id="svg_9" xml:space="preserve" text-anchor="middle" font-family="serif" font-size="12" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#000000" y="185" x="271">主管申请</text><text id="svg_10" xml:space="preserve" text-anchor="middle" font-family="serif" font-size="12" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#008000" y="166" x="269"><<Task State>></text><g id="svg_31"><rect x="211" y="169" width="13.5" height="13.935483" id="svg_25" fill="#e5e5e5" stroke="#a59898" stroke-width="2" stroke-dasharray="null"/><g id="svg_30"><rect x="213.5" y="171.064516" width="13.5" height="13.935483" fill="#e5e5e5" stroke="#a59898" stroke-width="2" stroke-dasharray="null" id="svg_26"/><line x1="214.5" y1="174.677419" x2="225.5" y2="174.677419" id="svg_27" stroke="#a59898" stroke-width="2" stroke-dasharray="null" fill="none"/><line x1="215" y1="177.774193" x2="226" y2="177.774193" stroke="#a59898" stroke-width="2" stroke-dasharray="null" fill="none" id="svg_28"/><line x1="214.5" y1="180.870967" x2="225.5" y2="180.870967" stroke="#a59898" stroke-width="2" stroke-dasharray="null" fill="none" id="svg_29"/></g></g></g><g id="svg_64"><rect x="189" y="311" width="123" height="38" fill="#cbeddb" stroke="#0000bf" stroke-width="2" id="svg_43"/><text xml:space="preserve" text-anchor="middle" font-family="serif" font-size="12" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#000000" y="342" x="259" id="svg_44">Dubbo远程服务</text><text xml:space="preserve" text-anchor="middle" font-family="serif" font-size="12" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#008000" y="327" x="256" id="svg_45"><<Dubbo Node>></text><g id="svg_55"><circle cx="200.090371" cy="326.131744" r="4.032028" fill="#f7f77e" stroke="#e5e557" stroke-width="2" stroke-dasharray="null" id="svg_56"/><circle cx="204.73279" cy="334.544693" r="4.032028" fill="#f98a6b" stroke="#ff5656" stroke-width="2" stroke-dasharray="null" id="svg_57"/><circle cx="196.267203" cy="334.868268" r="4.032028" fill="#5692ce" stroke="#5858d3" stroke-width="2" stroke-dasharray="null" id="svg_58"/></g></g></g>
</svg>

核心代码片段

/*** REST API for SVG Process-Runtime-Figure* * @author Von Gosling* @version 1.0.0*/
@Singleton
@Path("svg")
public class SVGProcessFigureResource {private final Logger log = LoggerFactory.getLogger(getClass());@SuppressWarnings("unchecked")@GET@Produces(MediaType.APPLICATION_SVG_XML)public Response get(@Context HttpServletRequest request,@DefaultValue("") @QueryParam("procId") String procId,@DefaultValue("") @QueryParam("procName") String procName,@DefaultValue("") @QueryParam("version") String version) {String content = "";try {Document doc = processDefinitionReader.getXmlProcessDefinition(procName,NumberUtils.toInt(version, -1));if (StringUtils.isNotBlank(procId)) {// 获取静态流程上下文long procInstId = Long.parseLong(procId);HashMap<String, Object> staticProcessContext = (HashMap<String, Object>) processEngine.getProcInstVarData(procInstId).get(0);// 获取流程运行期上下文Map<String, String> dynamicProcessContext = getProcRuntimeContext(procInstId);content = SVGProcessFigureGenerator.getSVG(doc, staticProcessContext,dynamicProcessContext);} else {content = SVGProcessFigureGenerator.getSVG(doc);}} catch (Exception e) {log.error("Error occurs when getting SVG.", e);return Response.status(Status.INTERNAL_SERVER_ERROR).entity("Error occurs,please visit later !").build();}return Response.ok().entity(content).build();}
/*** @author Von Gosling* @version 1.0.0*/
public class DomMappingPostProcessor {public static Document process(HashMap<String, Object> spContextMap,Map<String, String> dpContextMap, org.w3c.dom.Document svgDoc)throws DocumentException {//1. Xpath with namespace enabled Map<String, String> npURIs = Maps.newHashMap();npURIs.put("svg", SVGConstants.SVG_NAMESPACE_URI);npURIs.put("xlink", SVGConstants.XLINK_NAMESPACE_URI);DOMReader reader = new DOMReader();reader.getDocumentFactory().setXPathNamespaceURIs(npURIs);Document doc = reader.read(svgDoc);//doc.accept(new NameSpaceCleaner());//doc.setEntityResolver(new IngoreDtdEntityResolver());//2.Append inline and external scriptJSBuilder.buildInlineScript(spContextMap, doc);JSBuilder.buildExternalScript(doc);//3.Append process contextContextBuilder.buildStaticProcessContext(doc);ContextBuilder.buildDynamicProcessContext(dpContextMap, doc);return doc;}}

好了,差不多了,整个技术设计,编码实现都圆满KO~

欢迎大家对设计,实现部分提出异议,

Mind,Diagram,Design相关推荐

  1. 面向Mobile device的CNN模型手工设计与NAS分析总结,MobileNet V1,V2,V3,Efficient,MNasNet以及Efficient network design

    手工方法和NAS的高效网络模型设计总结与分析 这篇文章主要关注对于移动端,资源受限平台的高效神经网络设计(Manually)和搜索(NAS). ​​​​​​高效的CNN设计不只是用在服务器,云端,资源 ...

  2. CSS3 Media Queries 详细介绍与使用方法,Responsive Web Design 必备技术, 响应式设计

    上一篇我们介绍了Responsive Web Design之后,这次要来详细介绍CSS3 Media Queries了. 在上一篇中,我们提到Responsive Web Desig n的实作方式有大 ...

  3. 一款在线视频 App,基于 Material Design + MVP + RxJava + Retrofit + Realm + Glide

    Ghost 项目地址:GeekGhost/Ghost 简介:一款在线视频 App,基于 Material Design + MVP + RxJava + Retrofit + Realm + Glid ...

  4. ant design pro模板_Ant Design Pro入门教程,安装,运行(V5 Typescript版)

    [前言] 找了很多Admin模板,最后还是看中了AntDesignPro这个阿里巴巴开源的Admin框架,长这样(还行吧,目前挺主流的): 该套模板是使用了React开发框架作为基础,AntDesig ...

  5. 傻白探索Chiplet,Modular Routing Design for Chiplet-based Systems(十一)

    阅读了Modular Routing Design for Chiplet-based Systems这篇论文,是关于多chiplet通信的,个人感觉核心贡献在于实现了 deadlock-freedo ...

  6. java毕设可以用结构化方法吗,php,java,jsp网络留言薄,怎么实现一个网络留言簿好毕设指导轻松完成...

    本文采用自顶向下的结构化的系统分析方法,阐述了一个功能全面的超市管理系统的开发过程.操作流程及其一些核心的技术.本文首先进行了项目概述,简单介绍了项目开发的背景.项目开发的目的和项目开发的意义:接下来 ...

  7. php毕设代做,客户管理系统,java,jsp,php,好毕设为你指导如何完成一个客户管理系统...

    本文采用自顶向下的结构化的系统分析方法,阐述了一个功能全面的超市管理系统的开发过程.操作流程及其一些核心的技术.本文首先进行了项目概述,简单介绍了项目开发的背景.项目开发的目的和项目开发的意义:接下来 ...

  8. 如何成为一个程序员:短,全面,个人摘要

    本章转载至:http://samizdat.mines.edu/howto/HowToBeAProgrammer.html,部分内容并通过Google Translation翻译过来的,可能翻译的并不 ...

  9. TVM示例展示 README.md,Makefile,CMakeLists.txt

    TVM示例展示 README.md,Makefile,CMakeLists.txt TVM/README.md Open Deep Learning Compiler Stack Documentat ...

最新文章

  1. YOLOv5初探(看来这个YOLO5做得还不是很完善,过段时间再试试??)
  2. [转] CMake入门
  3. 给用户权限数据添加缓存
  4. vim 打开文件末尾带有^M的解决办法
  5. java restsharp_C# RestSharp应用
  6. 佛罗里达大学计算机专业世界排名,2020年佛罗里达大学排名TFE Times美国最佳计算机科学硕士专业排名第55...
  7. Android下载自带开源图标库教程
  8. 幻灯片母版的问题-模板制作
  9. 野蛮人传教士问题(上)
  10. 解决”企业证书打包的ipa,点击app提示未受信任的企业级开发者“的问题
  11. 一年时间,拿到了人生中的第一个20万
  12. MEPR500+电子护照阅读器|识读模块嵌入式安装与应用说明
  13. 网络适配器不见了网络连接不见了的解决方法
  14. vivo手机html有吗,vivo手机有哪些系列?区别是什么?
  15. 怀揣梦想,我依靠自己,往后余生越来越精彩
  16. (转)给想立志入行网络或已经初入行的朋友的建议
  17. Android权限系统(三):运行时权限检查和申请,PermissionController
  18. JVM分代回收机制和垃圾回收算法
  19. 岁月温柔-12 妈妈害怕去医院-疑似有医院恐惧症
  20. SQL基础-更新删除视图

热门文章

  1. 手机操作系统开源软件
  2. 【Golang画图】2D渲染绘图库gg的概念与用法详解(一)
  3. 让3个线程打印ABC
  4. Q4财报一如既往增长稳健 陌陌为何能逆势增长?
  5. 【Chrome】Chrome主页被毒霸篡改,重新设置主页也没作用解决办法
  6. fastboot 快速引导模式 介绍
  7. java Char与char_JAVAc++中char和char[]的区别
  8. 如何在本地搭建网站(图文教程)
  9. 无法验证到服务器的安全证书,打开outlook提示…无法验证的安全证书……
  10. 当“大嘴”李国庆遇见“大炮”罗永浩