1、写在前面:关于双边框形状,在mxgraph中有双边框椭圆形(doubleEllipse),我的双边框长方形就是据此拓展的。
2、该形状的用途:这个图形也是很有必要的,它可用在BPMN中的事务子流程。
3、关键拓展代码:
extension.js

/** * 新增表单样式doubleRectangle * **/function mxDoubleRectangle(bounds, fill, stroke, strokewidth){  this.bounds = bounds;    this.fill = fill;    this.stroke = stroke;    this.strokewidth = (strokewidth != null) ? strokewidth: 1;

}mxDoubleRectangle.prototype = new mxShape();mxDoubleRectangle.prototype.constructor = mxDoubleRectangle;mxDoubleRectangle.prototype.createVml = function() {    this.node = document.createElement('v:group');    var name = (this.isRounded) ? 'v:roundrect': 'v:rect';    this.background = document.createElement(name);    this.configureVmlShape(this.background);    this.node.appendChild(this.background);//    this.label = this.background;    this.isShadow = false;    this.fill = null;    this.foreground = document.createElement(name);    this.configureVmlShape(this.foreground);    this.node.appendChild(this.foreground);    this.stroke = null;    this.configureVmlShape(this.node);    return this.node;};mxDoubleRectangle.prototype.createSvg = function() {

 var g = this.createSvgGroup('rect');   this.foreground = document.createElementNS(mxConstants.NS_SVG, 'rect');    this.foreground.setAttribute('shape-rendering', 'optimizeSpeed');    this.foreground.setAttribute('fill', 'none');    g.appendChild(this.foreground);      return g;};mxDoubleRectangle.prototype.redrawSvg = function(node) { if (this.innerNode != null) {        this.updateSvgShape(this.innerNode);        if (this.shadowNode != null) {            this.updateSvgShape(this.shadowNode);        }    } else {        this.updateSvgShape(this.node);    }    this.updateSvgGlassPane();    this.updateSvgNode(this.foreground, 8);};mxDoubleRectangle.prototype.redrawVml = function() { this.node.style.visibility = 'hidden'; this.updateVmlShape(this.node);   this.updateVmlGlassPane();    this.node.style.visibility = 'hidden';

   this.background.style.visibility = 'hidden';   this.updateVmlShape(this.background); this.updateVmlGlassPane();    this.background.style.visibility = 'visible';

    this.foreground.style.visibility = 'hidden';   this.updateVmlShape(this.foreground); this.updateVmlGlassPane();    this.foreground.style.visibility = 'visible';  var inset = 8;   var w = Math.floor(this.bounds.width);   var h = Math.floor(this.bounds.height);  var x = Math.floor(this.bounds.x);   var y = Math.floor(this.bounds.y);   this.background.style.top = inset/2 + 'px';   this.background.style.left = inset/2 + 'px';  this.background.style.width = Math.max(0, w - inset) + 'px';  this.background.style.height = Math.max(0, h - inset) + 'px';};mxDoubleRectangle.prototype.updateSvgNode = function(node, inset) {    inset = (inset != null) ? inset: 0;    if (node != null) {        var strokeWidth = Math.max(1, this.strokewidth * this.scale);        if (this.crisp) {            node.setAttribute('shape-rendering', 'crispEdges');        } else {            node.removeAttribute('shape-rendering');        }        if (this.style != null && this.style[mxConstants.STYLE_SMOOTH]) {            var pts = this.points;            var n = pts.length;            if (n > 3) {                var points = 'M ' + pts[0].x + ' ' + pts[0].y + ' ';                points += ' Q ' + pts[1].x + ' ' + pts[1].y + ' ' + ' ' + pts[2].x + ' ' + pts[2].y;                for (var i = 3; i < n; i++) {                    points += ' T ' + pts[i].x + ' ' + pts[i].y;                }                node.setAttribute('d', points);            }        }        if (this.isDashed) {            var phase = Math.max(1, Math.floor(3 * this.scale));            node.setAttribute('stroke-dasharray', phase + ',' + phase);        }        if (this.isRounded) {            var w = this.bounds.width-inset;            var h = this.bounds.height-inset;            var r = Math.min(w * mxConstants.RECTANGLE_ROUNDING_FACTOR, h * mxConstants.RECTANGLE_ROUNDING_FACTOR);            node.setAttribute('rx', r);            node.setAttribute('ry', r);        }        node.setAttribute('stroke',this.stroke);        node.setAttribute('stroke-width', strokeWidth);        node.setAttribute('x', this.bounds.x +inset/2);        node.setAttribute('y', this.bounds.y +inset/2);        node.setAttribute('width', Math.max(0, this.bounds.width  - inset));        node.setAttribute('height', Math.max(0, this.bounds.height - inset));    }

};mxDoubleRectangle.prototype.configureVmlShape = function(node) {   node.style.position = 'absolute';     var color = this.stroke;     if (color != null && color != mxConstants.NONE) {           node.setAttribute('stroked', 'true');         node.setAttribute('strokecolor', color);        } else {          node.setAttribute('stroked', 'false');        }     color = this.fill;       node.style.background = '';        if (color != null && color != mxConstants.NONE) {           if (this.fillNode == null) {                this.fillNode = document.createElement('v:fill');              node.appendChild(this.fillNode);          }         this.updateVmlFill(this.fillNode, color, this.gradient, this.gradientDirection, this.opacity);        } else {          node.setAttribute('filled', 'false');         if (this.points == null) {              this.configureTransparentBackground(node);            }     }     if ((this.isDashed || this.opacity != null) && this.strokeNode == null) {          this.strokeNode = document.createElement('v:stroke');          node.appendChild(this.strokeNode);        }     if (this.strokeNode != null) {           if (this.strokeNode != null) {               if (this.isDashed) {                  var phase = Math.max(1, Math.floor(3 * this.scale));                 var pat = phase + ' ' + phase;                   if (this.strokeNode.getAttribute('dashstyle') != pat) {                        this.strokeNode.setAttribute('dashstyle', pat);                 }             } else if (this.strokeNode.getAttribute('dashstyle') != 'solid') {                   this.strokeNode.setAttribute('dashstyle', 'solid');               }         }         if (this.opacity != null) {              this.strokeNode.setAttribute('opacity', this.opacity + '%');         }     }     if (this.isShadow && this.fill != null) {            if (this.shadowNode == null) {              this.shadowNode = document.createElement('v:shadow');              this.shadowNode.setAttribute('on', 'true');               this.shadowNode.setAttribute('color', mxConstants.SHADOWCOLOR);             node.appendChild(this.shadowNode);            }     }     if (node.nodeName == 'roundrect') {           try {             node.setAttribute('arcsize', String(mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) + '%');         } catch(e) {}     }    this.strokeNode = null;};/** *拓展该形状输出img的绘制方法 **/mxImageExport.prototype.initShapes = function() {    this.shapes = [];//其他形状的绘制也在此定义,就是源码中的,在此只写了新增的代码    this.shapes['doubleRectangle'] = {      drawShape: function(canvas, state, bounds, background) {            if (background) {                if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false)) {                    var size = Math.max(bounds.width / 10, bounds.height / 10);                    canvas.roundrect(bounds.x, bounds.y, bounds.width, bounds.height, size, size);                } else {                    canvas.rect(bounds.x, bounds.y, bounds.width, bounds.height);                }                return true;            } else {                canvas.fillAndStroke();                var inset = 8;                var x = bounds.x;                var y = bounds.y;                var w = bounds.width;                var h = bounds.height;                x += inset/2;                y += inset/2;                w -=  inset;                h -=  inset;                if (w > 0 && h > 0) {                  if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false)) {                       var size = Math.max(w / 10, h / 10);                     canvas.rect(x, y, w,h,size,size);                  }else {                       canvas.rect(x,y,w,h);                     }                }                canvas.stroke();            }        }       };    };

4、应用方法:
应用新的样式时可以在default-style.xml中写该样式:

 <add as="transaction" >      <add as="shape" value="doubleRectangle"/>     <add as="strokeColor" value="black"/>     <add as="fillColor" value="#F2F2F2"/>     <add as="gradientColor" value="#F2F2F2"/>     <add as="verticalAlign" value="top"/>     <add as="rounded" value="0"/>

   </add>

这就是BPMN中事务子流程的样式定义。
然后,在graph的js中:

 graph.cellRenderer.registerShape('doubleRectangle', mxDoubleRectangle);     var style = graph.getStylesheet().getDefaultVertexStyle();       style[mxConstants.STYLE_SHAPE] = 'doubleRectangle';

这样就可以用这个样式啦啦~~
*************************格叽格叽**************************
终于写完了 lysh miss wanan~

mxgraph 之 自定义双边框长方形(即:doubleRectangle)相关推荐

  1. 【QT】自定义无边框窗口分享

    [QT/天下wu双]自定义无边框窗口分享 https://www.bilibili.com/video/BV1HA411Y7d4 源码链接:https://github.com/Bili-TianX/ ...

  2. Boost:自定义双端队列的测试程序

    Boost:自定义双端队列的测试程序 实现功能 C++实现代码 实现功能 Boost的container模块,Boost:自定义双端队列的测试程序 C++实现代码 #include <boost ...

  3. 【Qt】仿360安全卫士界面(自定义阴影边框类)

    00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 自定义阴影边框类设计与实现 04. 测试代码 05. 示例下载 06. 附录 01. 概述 Qt默认的QDialog和QW ...

  4. winform自定义窗体边框样式模板(支持四周边框拖拽改变窗体大小,支持鼠标拖动头部移动窗体)

    winform自己的边框已经过时,但小伙伴们又觉得自定义太过麻烦.本文将手把手教你自定义winform边框样式,并提供源代码链接(可直接作为模板使用).话不多说,直接上操作步骤. 先上一张完成截图 一 ...

  5. Android自定义圆角边框

    Android自定义圆角边框 一. 说明 本文主要讲如何自定义一个圆角的边框 二. 所用工具 Android Studio 三. 内容 1. 涉及到的内容 solid:设置背景色 stroke:设置边 ...

  6. css合并两个文本框,css实现input文本框的双边框美化

    css实现input文本框的双边框美化 .input_div{width:250px; height:22px; border-style:solid; border-width:1px 0 1px ...

  7. html5用css做样式边框,纯CSS3实现自定义Tooltip边框 涂鸦风格

    本文作者html5tricks,转载请注明出处 这是一款用纯CSS3打造的自定义Tooltip边框的应用,之前我们讨论过如何用CSS3来实现不同样式的Tooltip,今天的这款Tooltip却可以用C ...

  8. Innovasys实用教程(新手教学实用教程):如何在软件当中自定义表格边框

        Innovasys是一家成立于1997年的文档和帮助创作工具提供商,致力于使广大开发人员和技术方面的作家能够生成专业质量的文档.帮助系统和程序.本系列教程主要讨论Innovasys的实用性提示 ...

  9. Android实现自定义圆角边框渐变

    1.定义全部圆角的通用接口 public interface IRadiusLayout {int DEFAULT_RADIUS = 0; // 默认没有圆角int SOLID_TYPE_SOLID ...

最新文章

  1. EXCLE图形插入实例
  2. st7789v tft 驱动电路_OLED显示屏,行驱动电路设计,单片机AT89C51与和显示屏的硬件接线...
  3. linux学习总结之磁盘管理
  4. python使用ORM之如何调用多对多关系
  5. 面试经历-19-03-14
  6. 7-11 数列求和-加强版 (20 分)
  7. mysql查询临时表是否存在_[转]SQL判断临时表是否存在
  8. mysql字符串拼接有空值_mysql字符串如何拼接并设置null值 mysql字符串拼接并设置null值实例方法...
  9. 北大pkuseg分词 和 jieba 分词对比测试,结果出乎意料...
  10. 中国公路客运中心产业运营现状与十四五管理规划报告2022-2028年
  11. USB Type-C和USB PD
  12. 互联网运营之道读书笔记
  13. 【Python基础】3-语法进阶
  14. 有利可图网_有利可图的项目的目录
  15. Python小爬虫:爬取开心网日记,乐趣无穷
  16. 【笔记】linux下查看文件夹大小
  17. 示波器直流增益|通道隔离度|带宽|时基|瞬态响应校准软件NSAT-3010
  18. 离轴高数值孔径抛物面反射镜的聚焦
  19. jar文件打开方式和直接运行方法
  20. 2021年“金三银四”来袭!2021年阿里+头条+腾讯大厂Android笔试真题,含答案解析

热门文章

  1. ⑩【图神经网络×自监督×时空】视频自监督学习、时间对比图学习、多尺度时间依赖性(长期、短期) 、频域学习
  2. V4L2开发应用流程的各类超实用VIDIOC命令及其结构体集锦
  3. 电工技术(2)—电路的分析方法一
  4. PY爬虫 | 爬取下厨房的本周最受欢迎
  5. [IO系统]06 因OPEN建立的结构体关系
  6. 菜鸟教程Cpp学习笔记
  7. 74161/74LS161 四位二进制同步计数器
  8. IT审计与信息安全审计
  9. 《小强升职记》读书笔记(上)
  10. 【XLL API 函数】xlSheetNm