zl程序教程

您现在的位置是:首页 >  其它

当前栏目

Mind,Diagram,Design

Design Diagram
2023-09-14 09:00:28 时间
        最近在设计新版的流程渲染引擎,考虑采用无损失放缩的矢量图SVG去搞,从技术调研到实现蛮有心得的,这里贴出自己的设计思路,欢迎拍砖~         首先说下诉求,简单说就是绘制流程地图。其次简单列举下需要注意的技术点: (1) 图形元素和坐标元素解析(合并or分拆) (2) DOM树解析,原生JAXP,DOM4J or SVG DOM utils(混用会带来很多问题)

        最近在设计新版的流程渲染引擎,考虑采用无损失放缩的矢量图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 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 


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 /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/ -- 

 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 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 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 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 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"/ 

 /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 script         JSBuilder.buildInlineScript(spContextMap, doc);         JSBuilder.buildExternalScript(doc);
        //3.Append process context         ContextBuilder.buildStaticProcessContext(doc);         ContextBuilder.buildDynamicProcessContext(dpContextMap, doc);

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

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


【读书笔记】Algorithms for Decision Making(10) 在这一部分将不确定性扩展到状态。具体讲,接收到的观测值与状态只有概率关系,而不是精确地观察状态。此类问题可以建模为部分可观察的马尔可夫决策过程(POMDP),但POMDP很难以最佳方式解决所有问题,因而需要引入更多的近似策略。