web设计器--设计流程图(raphael)源码myflow.js(三)

来源:互联网 发布:正方软件股份有限公司 编辑:程序博客网 时间:2024/05/13 11:53

分享一下myflow.js源码:

其余的文件比如myflow.editors.js等就不贴出来了,代码太多,只是贴出核心的js。如果想要别的文件,私信我。

[javascript] view plain copy
  1. (function($) {  
  2.     var myflow = {};  
  3.     myflow.config = {  
  4.         editable : true,  
  5.         lineHeight : 15,  
  6.         basePath : '',  
  7.         rect : {// 状态  
  8.             attr : {  
  9.                 x : 10,  
  10.                 y : 10,  
  11.                 width : 100,  
  12.                 height : 50,  
  13.                 r : 5,  
  14.                 fill : '90-#fff-#C0C0C0',  
  15.                 stroke : '#000',  
  16.                 "stroke-width" : 1  
  17.             },  
  18.             showType : 'image&text',// image,text,image&text  
  19.             type : 'state',  
  20.             name : {  
  21.                 text : 'state',  
  22.                 'font-style' : 'italic'  
  23.             },  
  24.             text : {  
  25.                 text : '状态',  
  26.                 'font-size' : 13  
  27.             },  
  28.             margin : 5,  
  29.             props : [],  
  30.             img : {}  
  31.         },  
  32.         path : {// 路径转换  
  33.             attr : {  
  34.                 path : {  
  35.                     path : 'M10 10L100 100',  
  36.                     stroke : '#808080',  
  37.                     fill : "none",  
  38.                     "stroke-width" : 2  
  39.                 },  
  40.                 arrow : {  
  41.                     path : 'M10 10L10 10',  
  42.                     stroke : '#808080',  
  43.                     fill : "#808080",  
  44.                     "stroke-width" : 2,  
  45.                     radius : 4  
  46.                 },  
  47.                 fromDot : {  
  48.                     width : 5,  
  49.                     height : 5,  
  50.                     stroke : '#fff',  
  51.                     fill : '#000',  
  52.                     cursor : "move",  
  53.                     "stroke-width" : 2  
  54.                 },  
  55.                 toDot : {  
  56.                     width : 5,  
  57.                     height : 5,  
  58.                     stroke : '#fff',  
  59.                     fill : '#000',  
  60.                     cursor : "move",  
  61.                     "stroke-width" : 2  
  62.                 },  
  63.                 bigDot : {  
  64.                     width : 5,  
  65.                     height : 5,  
  66.                     stroke : '#fff',  
  67.                     fill : '#000',  
  68.                     cursor : "move",  
  69.                     "stroke-width" : 2  
  70.                 },  
  71.                 smallDot : {  
  72.                     width : 5,  
  73.                     height : 5,  
  74.                     stroke : '#fff',  
  75.                     fill : '#000',  
  76.                     cursor : "move",  
  77.                     "stroke-width" : 3  
  78.                 },  
  79.                 text : {  
  80.                     cursor : "move",  
  81.                     'background' : '#000'  
  82.                 }  
  83.             },  
  84.             text : {  
  85.                 patten : 'TO {to}',  
  86.                 textPos : {  
  87.                     x : 0,  
  88.                     y : -10  
  89.                 }  
  90.             },  
  91.             props : {  
  92.                 text : {  
  93.                     name : 'text',  
  94.                     label : '显示',  
  95.                     value : '',  
  96.                     editor : function() {  
  97.                         return new myflow.editors.textEditor();  
  98.                     }  
  99.                 }  
  100.             }  
  101.         },  
  102.         tools : {// 工具栏  
  103.             attr : {  
  104.                 left : 10,  
  105.                 top : 10  
  106.             },  
  107.             pointer : {},  
  108.             path : {},  
  109.             states : {},  
  110.             save : {  
  111.                 onclick : function(data) {  
  112.                     alert(data);  
  113.                 }  
  114.             }  
  115.         },  
  116.         props : {// 属性编辑器  
  117.             attr : {  
  118.                 top : 10,  
  119.                 right : 30  
  120.             },  
  121.             props : {}  
  122.         },  
  123.         restore : '',  
  124.         activeRects : {// 当前激活状态  
  125.             rects : [],  
  126.             rectAttr : {  
  127.                 stroke : '#ff0000',  
  128.                 "stroke-width" : 2  
  129.             }  
  130.         },  
  131.         historyRects : {// 历史激活状态  
  132.             rects : [],  
  133.             pathAttr : {  
  134.                 path : {  
  135.                     stroke : '#00ff00'  
  136.                 },  
  137.                 arrow : {  
  138.                     stroke : '#00ff00',  
  139.                     fill : "#00ff00"  
  140.                 }  
  141.             }  
  142.         }  
  143.     };  
  144.   
  145.     myflow.util = {  
  146.         isLine : function(p1, p2, p3) {// 三个点是否在一条直线上  
  147.             var s, p2y;  
  148.             if ((p1.x - p3.x) == 0)  
  149.                 s = 1;  
  150.             else  
  151.                 s = (p1.y - p3.y) / (p1.x - p3.x);  
  152.             p2y = (p2.x - p3.x) * s + p3.y;  
  153.             // $('body').append(p2.y+'-'+p2y+'='+(p2.y-p2y)+', ');  
  154.             if ((p2.y - p2y) < 10 && (p2.y - p2y) > -10) {  
  155.                 p2.y = p2y;  
  156.                 return true;  
  157.             }  
  158.             return false;  
  159.         },  
  160.         center : function(p1, p2) {// 两个点的中间点  
  161.             return {  
  162.                 x : (p1.x - p2.x) / 2 + p2.x,  
  163.                 y : (p1.y - p2.y) / 2 + p2.y  
  164.             };  
  165.         },  
  166.         nextId : (function() {  
  167.             var uid = 0;  
  168.             return function() {  
  169.                 return ++uid;  
  170.             };  
  171.         })(),  
  172.   
  173.         connPoint : function(rect, p) {// 计算矩形中心到p的连线与矩形的交叉点  
  174.             var start = p, end = {  
  175.                 x : rect.x + rect.width / 2,  
  176.                 y : rect.y + rect.height / 2  
  177.             };  
  178.             // 计算正切角度  
  179.             var tag = (end.y - start.y) / (end.x - start.x);  
  180.             tag = isNaN(tag) ? 0 : tag;  
  181.   
  182.             var rectTag = rect.height / rect.width;  
  183.             // 计算箭头位置  
  184.             var xFlag = start.y < end.y ? -1 : 1, yFlag = start.x < end.x  
  185.                     ? -1  
  186.                     : 1, arrowTop, arrowLeft;  
  187.             // 按角度判断箭头位置  
  188.             if (Math.abs(tag) > rectTag && xFlag == -1) {// top边  
  189.                 arrowTop = end.y - rect.height / 2;  
  190.                 arrowLeft = end.x + xFlag * rect.height / 2 / tag;  
  191.             } else if (Math.abs(tag) > rectTag && xFlag == 1) {// bottom边  
  192.                 arrowTop = end.y + rect.height / 2;  
  193.                 arrowLeft = end.x + xFlag * rect.height / 2 / tag;  
  194.             } else if (Math.abs(tag) < rectTag && yFlag == -1) {// left边  
  195.                 arrowTop = end.y + yFlag * rect.width / 2 * tag;  
  196.                 arrowLeft = end.x - rect.width / 2;  
  197.             } else if (Math.abs(tag) < rectTag && yFlag == 1) {// right边  
  198.                 arrowTop = end.y + rect.width / 2 * tag;  
  199.                 arrowLeft = end.x + rect.width / 2;  
  200.             }  
  201.             return {  
  202.                 x : arrowLeft,  
  203.                 y : arrowTop  
  204.             };  
  205.         },  
  206.   
  207.         arrow : function(p1, p2, r) {// 画箭头,p1 开始位置,p2 结束位置, r前头的边长  
  208.             var atan = Math.atan2(p1.y - p2.y, p2.x - p1.x) * (180 / Math.PI);  
  209.   
  210.             var centerX = p2.x - r * Math.cos(atan * (Math.PI / 180));  
  211.             var centerY = p2.y + r * Math.sin(atan * (Math.PI / 180));  
  212.   
  213.             var x2 = centerX + r * Math.cos((atan + 120) * (Math.PI / 180));  
  214.             var y2 = centerY - r * Math.sin((atan + 120) * (Math.PI / 180));  
  215.   
  216.             var x3 = centerX + r * Math.cos((atan + 240) * (Math.PI / 180));  
  217.             var y3 = centerY - r * Math.sin((atan + 240) * (Math.PI / 180));  
  218.             return [p2, {  
  219.                         x : x2,  
  220.                         y : y2  
  221.                     }, {  
  222.                         x : x3,  
  223.                         y : y3  
  224.                     }];  
  225.         }  
  226.     }  
  227.   
  228.     myflow.rect = function(o, r, id) {  
  229.         var _this = this, _uid = myflow.util.nextId(), _o = $.extend(true, {},  
  230.                 myflow.config.rect, o), _id = 'rect' + _uid, _r = r, // Raphael画笔  
  231.         _rect, _img, // 图标  
  232.         _name, // 状态名称  
  233.         _text, // 显示文本  
  234.         _ox, _oy; // 拖动时,保存起点位置;  
  235.         _o.text.text = id;  
  236.         _o.name.text = "";  
  237.   
  238.         _rect = _r.rect(_o.attr.x, _o.attr.y, _o.attr.width, _o.attr.height,  
  239.                 _o.attr.r).hide().attr(_o.attr);  
  240.   
  241.         _img = _r.image(myflow.config.basePath + _o.img.src,  
  242.                 _o.attr.x + _o.img.width / 2,  
  243.                 _o.attr.y + (_o.attr.height - _o.img.height) / 2, _o.img.width,  
  244.                 _o.img.height).hide();  
  245.         _name = _r.text(  
  246.                 _o.attr.x + _o.img.width + (_o.attr.width - _o.img.width) / 2,  
  247.                 _o.attr.y + myflow.config.lineHeight / 2, _o.name.text).hide()  
  248.                 .attr(_o.name);  
  249.         _text = _r.text(  
  250.                 _o.attr.x + _o.img.width + (_o.attr.width - _o.img.width) / 2,  
  251.                 _o.attr.y + (_o.attr.height - myflow.config.lineHeight) / 2  
  252.                         + myflow.config.lineHeight, _o.text.text).hide()  
  253.                 .attr(_o.text);// 文本  
  254.   
  255.         // 拖动处理----------------------------------------  
  256.         _rect.drag(function(dx, dy) {  
  257.                     dragMove(dx, dy);  
  258.                 }, function() {  
  259.                     dragStart()  
  260.                 }, function() {  
  261.                     dragUp();  
  262.                 });  
  263.         _img.drag(function(dx, dy) {  
  264.                     dragMove(dx, dy);  
  265.                 }, function() {  
  266.                     dragStart()  
  267.                 }, function() {  
  268.                     dragUp();  
  269.                 });  
  270.         _name.drag(function(dx, dy) {  
  271.                     dragMove(dx, dy);  
  272.                 }, function() {  
  273.                     dragStart()  
  274.                 }, function() {  
  275.                     dragUp();  
  276.                 });  
  277.         _text.drag(function(dx, dy) {  
  278.                     dragMove(dx, dy);  
  279.                 }, function() {  
  280.                     dragStart()  
  281.                 }, function() {  
  282.                     dragUp();  
  283.                 });  
  284.   
  285.         var dragMove = function(dx, dy) {// 拖动中  
  286.             if (!myflow.config.editable)  
  287.                 return;  
  288.   
  289.             var x = (_ox + dx);// -((_ox+dx)%10);  
  290.             var y = (_oy + dy);// -((_oy+dy)%10);  
  291.   
  292.             _bbox.x = x - _o.margin;  
  293.             _bbox.y = y - _o.margin;  
  294.             resize();  
  295.         };  
  296.   
  297.         var dragStart = function() {// 开始拖动  
  298.             _ox = _rect.attr("x");  
  299.             _oy = _rect.attr("y");  
  300.             _rect.attr({  
  301.                         opacity : 0.5  
  302.                     });  
  303.             _img.attr({  
  304.                         opacity : 0.5  
  305.                     });  
  306.             _text.attr({  
  307.                         opacity : 0.5  
  308.                     });  
  309.         };  
  310.   
  311.         var dragUp = function() {// 拖动结束  
  312.             _rect.attr({  
  313.                         opacity : 1  
  314.                     });  
  315.             _img.attr({  
  316.                         opacity : 1  
  317.                     });  
  318.             _text.attr({  
  319.                         opacity : 1  
  320.                     });  
  321.         };  
  322.   
  323.         // 改变大小的边框  
  324.         var _bpath, _bdots = {}, _bw = 5, _bbox = {  
  325.             x : _o.attr.x - _o.margin,  
  326.             y : _o.attr.y - _o.margin,  
  327.             width : _o.attr.width + _o.margin * 2,  
  328.             height : _o.attr.height + _o.margin * 2  
  329.         };  
  330.   
  331.         _bpath = _r.path('M0 0L1 1').hide();  
  332.         _bdots['t'] = _r.rect(0, 0, _bw, _bw).attr({  
  333.                     fill : '#000',  
  334.                     stroke : '#fff',  
  335.                     cursor : 's-resize'  
  336.                 }).hide().drag(function(dx, dy) {  
  337.                     bdragMove(dx, dy, 't');  
  338.                 }, function() {  
  339.                     bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw  
  340.                                     / 2, 't');  
  341.                 }, function() {  
  342.                 });// 上  
  343.         _bdots['lt'] = _r.rect(0, 0, _bw, _bw).attr({  
  344.                     fill : '#000',  
  345.                     stroke : '#fff',  
  346.                     cursor : 'nw-resize'  
  347.                 }).hide().drag(function(dx, dy) {  
  348.                     bdragMove(dx, dy, 'lt');  
  349.                 }, function() {  
  350.                     bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw  
  351.                                     / 2, 'lt');  
  352.                 }, function() {  
  353.                 });// 左上  
  354.         _bdots['l'] = _r.rect(0, 0, _bw, _bw).attr({  
  355.                     fill : '#000',  
  356.                     stroke : '#fff',  
  357.                     cursor : 'w-resize'  
  358.                 }).hide().drag(function(dx, dy) {  
  359.                     bdragMove(dx, dy, 'l');  
  360.                 }, function() {  
  361.                     bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw  
  362.                                     / 2, 'l');  
  363.                 }, function() {  
  364.                 });// 左  
  365.         _bdots['lb'] = _r.rect(0, 0, _bw, _bw).attr({  
  366.                     fill : '#000',  
  367.                     stroke : '#fff',  
  368.                     cursor : 'sw-resize'  
  369.                 }).hide().drag(function(dx, dy) {  
  370.                     bdragMove(dx, dy, 'lb');  
  371.                 }, function() {  
  372.                     bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw  
  373.                                     / 2, 'lb');  
  374.                 }, function() {  
  375.                 });// 左下  
  376.         _bdots['b'] = _r.rect(0, 0, _bw, _bw).attr({  
  377.                     fill : '#000',  
  378.                     stroke : '#fff',  
  379.                     cursor : 's-resize'  
  380.                 }).hide().drag(function(dx, dy) {  
  381.                     bdragMove(dx, dy, 'b');  
  382.                 }, function() {  
  383.                     bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw  
  384.                                     / 2, 'b');  
  385.                 }, function() {  
  386.                 });// 下  
  387.         _bdots['rb'] = _r.rect(0, 0, _bw, _bw).attr({  
  388.                     fill : '#000',  
  389.                     stroke : '#fff',  
  390.                     cursor : 'se-resize'  
  391.                 }).hide().drag(function(dx, dy) {  
  392.                     bdragMove(dx, dy, 'rb');  
  393.                 }, function() {  
  394.                     bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw  
  395.                                     / 2, 'rb');  
  396.                 }, function() {  
  397.                 });// 右下  
  398.         _bdots['r'] = _r.rect(0, 0, _bw, _bw).attr({  
  399.                     fill : '#000',  
  400.                     stroke : '#fff',  
  401.                     cursor : 'w-resize'  
  402.                 }).hide().drag(function(dx, dy) {  
  403.                     bdragMove(dx, dy, 'r');  
  404.                 }, function() {  
  405.                     bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw  
  406.                                     / 2, 'r')  
  407.                 }, function() {  
  408.                 });// 右  
  409.         _bdots['rt'] = _r.rect(0, 0, _bw, _bw).attr({  
  410.                     fill : '#000',  
  411.                     stroke : '#fff',  
  412.                     cursor : 'ne-resize'  
  413.                 }).hide().drag(function(dx, dy) {  
  414.                     bdragMove(dx, dy, 'rt');  
  415.                 }, function() {  
  416.                     bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw  
  417.                                     / 2, 'rt')  
  418.                 }, function() {  
  419.                 });// 右上  
  420.         $([_bdots['t'].node,_bdots['lt'].node,_bdots['l'].node,_bdots['lb'].node,_bdots['b'].node,_bdots['rb'].node,_bdots['r'].node,_bdots['rt'].node]).click(function(){return false;});  
  421.   
  422.         var bdragMove = function(dx, dy, t) {  
  423.             if (!myflow.config.editable)  
  424.                 return;  
  425.             var x = _bx + dx, y = _by + dy;  
  426.             switch (t) {  
  427.                 case 't' :  
  428.                     _bbox.height += _bbox.y - y;  
  429.                     _bbox.y = y;  
  430.                     break;  
  431.                 case 'lt' :  
  432.                     _bbox.width += _bbox.x - x;  
  433.                     _bbox.height += _bbox.y - y;  
  434.                     _bbox.x = x;  
  435.                     _bbox.y = y;  
  436.                     break;  
  437.                 case 'l' :  
  438.                     _bbox.width += _bbox.x - x;  
  439.                     _bbox.x = x;  
  440.                     break;  
  441.                 case 'lb' :  
  442.                     _bbox.height = y - _bbox.y;  
  443.                     _bbox.width += _bbox.x - x;  
  444.                     _bbox.x = x;  
  445.                     break;  
  446.                 case 'b' :  
  447.                     _bbox.height = y - _bbox.y;  
  448.                     break;  
  449.                 case 'rb' :  
  450.                     _bbox.height = y - _bbox.y;  
  451.                     _bbox.width = x - _bbox.x;  
  452.                     break;  
  453.                 case 'r' :  
  454.                     _bbox.width = x - _bbox.x;  
  455.                     break;  
  456.                 case 'rt' :  
  457.                     _bbox.width = x - _bbox.x;  
  458.                     _bbox.height += _bbox.y - y;  
  459.                     _bbox.y = y;  
  460.                     break;  
  461.             }  
  462.             resize();  
  463.             // $('body').append(t);  
  464.         };  
  465.         var bdragStart = function(ox, oy, t) {  
  466.             _bx = ox;  
  467.             _by = oy;  
  468.         };  
  469.   
  470.         // 事件处理--------------------------------  
  471.         $([_rect.node, _text.node, _name.node, _img.node]).bind('click',  
  472.                 function() {  
  473.                     if (!myflow.config.editable)  
  474.                         return;  
  475.   
  476.                     showBox();  
  477.                     var mod = $(_r).data('mod');  
  478.                     switch (mod) {  
  479.                         case 'pointer' :  
  480.                             break;  
  481.                         case 'path' :  
  482.                             var pre = $(_r).data('currNode');  
  483.                             if (pre && pre.getId() != _id  
  484.                                     && pre.getId().substring(0, 4) == 'rect') {  
  485.                                 $(_r).trigger('addpath', [pre, _this]);  
  486.                             }  
  487.                             break;  
  488.                     }  
  489.                     $(_r).trigger('click', _this);  
  490.                     $(_r).data('currNode', _this);  
  491.                     return false;  
  492.                 });  
  493.   
  494.         var clickHandler = function(e, src) {  
  495.             if (!myflow.config.editable)  
  496.                 return;  
  497.             if (src.getId() == _id) {  
  498.                 $(_r).trigger('showprops', [_o.props, src]);  
  499.             } else {  
  500.                 hideBox();  
  501.             }  
  502.         };  
  503.         $(_r).bind('click', clickHandler);  
  504.   
  505.         var textchangeHandler = function(e, text, src) {  
  506.             if (src.getId() == _id) {  
  507.                 _text.attr({  
  508.                             text : text  
  509.                         });  
  510.             }  
  511.         };  
  512.         $(_r).bind('textchange', textchangeHandler);  
  513.   
  514.         // 私有函数-----------------------  
  515.         // 边框路径  
  516.         function getBoxPathString() {  
  517.             return 'M' + _bbox.x + ' ' + _bbox.y + 'L' + _bbox.x + ' '  
  518.                     + (_bbox.y + _bbox.height) + 'L' + (_bbox.x + _bbox.width)  
  519.                     + ' ' + (_bbox.y + _bbox.height) + 'L'  
  520.                     + (_bbox.x + _bbox.width) + ' ' + _bbox.y + 'L' + _bbox.x  
  521.                     + ' ' + _bbox.y;  
  522.         }  
  523.         // 显示边框  
  524.         function showBox() {  
  525.             _bpath.show();  
  526.             for (var k in _bdots) {  
  527.                 _bdots[k].show();  
  528.             }  
  529.         }  
  530.         // 隐藏  
  531.         function hideBox() {  
  532.             _bpath.hide();  
  533.             for (var k in _bdots) {  
  534.                 _bdots[k].hide();  
  535.             }  
  536.         }  
  537.   
  538.         // 根据_bbox,更新位置信息  
  539.         function resize() {  
  540.             var rx = _bbox.x + _o.margin, ry = _bbox.y + _o.margin, rw = _bbox.width  
  541.                     - _o.margin * 2, rh = _bbox.height - _o.margin * 2;  
  542.   
  543.             _rect.attr({  
  544.                         x : rx,  
  545.                         y : ry,  
  546.                         width : rw,  
  547.                         height : rh  
  548.                     });  
  549.             switch (_o.showType) {  
  550.                 case 'image' :  
  551.                     _img.attr({  
  552.                                 x : rx + (rw - _o.img.width) / 2,  
  553.                                 y : ry + (rh - _o.img.height) / 2  
  554.                             }).show();  
  555.                     break;  
  556.                 case 'text' :  
  557.                     _rect.show();  
  558.                     _text.attr({  
  559.                                 x : rx + rw / 2,  
  560.                                 y : ry + rh / 2  
  561.                             }).show();// 文本  
  562.                     break;  
  563.                 case 'image&text' :  
  564.                     _rect.show();  
  565.                     _name.attr({  
  566.                                 x : rx + _o.img.width + (rw - _o.img.width) / 2,  
  567.                                 y : ry + myflow.config.lineHeight / 2  
  568.                             }).show();  
  569.                     _text.attr({  
  570.                         x : rx + _o.img.width + (rw - _o.img.width) / 2,  
  571.                         y : ry + (rh - myflow.config.lineHeight) / 2  
  572.                                 + myflow.config.lineHeight  
  573.                     }).show();// 文本  
  574.                     _img.attr({  
  575.                                 x : rx + _o.img.width / 2,  
  576.                                 y : ry + (rh - _o.img.height) / 2  
  577.                             }).show();  
  578.                     break;  
  579.             }  
  580.   
  581.             _bdots['t'].attr({  
  582.                         x : _bbox.x + _bbox.width / 2 - _bw / 2,  
  583.                         y : _bbox.y - _bw / 2  
  584.                     });// 上  
  585.             _bdots['lt'].attr({  
  586.                         x : _bbox.x - _bw / 2,  
  587.                         y : _bbox.y - _bw / 2  
  588.                     });// 左上  
  589.             _bdots['l'].attr({  
  590.                         x : _bbox.x - _bw / 2,  
  591.                         y : _bbox.y - _bw / 2 + _bbox.height / 2  
  592.                     });// 左  
  593.             _bdots['lb'].attr({  
  594.                         x : _bbox.x - _bw / 2,  
  595.                         y : _bbox.y - _bw / 2 + _bbox.height  
  596.                     });// 左下  
  597.             _bdots['b'].attr({  
  598.                         x : _bbox.x - _bw / 2 + _bbox.width / 2,  
  599.                         y : _bbox.y - _bw / 2 + _bbox.height  
  600.                     });// 下  
  601.             _bdots['rb'].attr({  
  602.                         x : _bbox.x - _bw / 2 + _bbox.width,  
  603.                         y : _bbox.y - _bw / 2 + _bbox.height  
  604.                     });// 右下  
  605.             _bdots['r'].attr({  
  606.                         x : _bbox.x - _bw / 2 + _bbox.width,  
  607.                         y : _bbox.y - _bw / 2 + _bbox.height / 2  
  608.                     });// 右  
  609.             _bdots['rt'].attr({  
  610.                         x : _bbox.x - _bw / 2 + _bbox.width,  
  611.                         y : _bbox.y - _bw / 2  
  612.                     });// 右上  
  613.             _bpath.attr({  
  614.                         path : getBoxPathString()  
  615.                     });  
  616.   
  617.             $(_r).trigger('rectresize', _this);  
  618.         };  
  619.   
  620.         // 函数----------------  
  621.         // 转化json字串  
  622.         this.toJson = function() {  
  623.             var data = "{type:'" + _o.type + "',text:{text:'"  
  624.                     + _text.attr('text') + "'}, attr:{ x:"  
  625.                     + Math.round(_rect.attr('x')) + ", y:"  
  626.                     + Math.round(_rect.attr('y')) + ", width:"  
  627.                     + Math.round(_rect.attr('width')) + ", height:"  
  628.                     + Math.round(_rect.attr('height')) + "}, props:{";  
  629.             for (var k in _o.props) {  
  630.                 data += k + ":{value:'"  
  631.                         + _o.props[k].value + "'},";  
  632.             }  
  633.             if (data.substring(data.length - 1, data.length) == ',')  
  634.                 data = data.substring(0, data.length - 1);  
  635.             data += "}}";  
  636.             return data;  
  637.         };  
  638.         // 从数据中恢复图  
  639.         this.restore = function(data) {  
  640.             var obj = data;  
  641.             // if (typeof data === 'string')  
  642.             // obj = eval(data);  
  643.   
  644.             _o = $.extend(true, _o, data);  
  645.   
  646.             _text.attr({  
  647.                         text : obj.text.text  
  648.                     });  
  649.             resize();  
  650.         };  
  651.   
  652.         this.getBBox = function() {  
  653.             return _bbox;  
  654.         };  
  655.         this.getId = function() {  
  656.             return _id;  
  657.         };  
  658.         this.remove = function() {  
  659.             _rect.remove();  
  660.             _text.remove();  
  661.             _name.remove();  
  662.             _img.remove();  
  663.             _bpath.remove();  
  664.             for (var k in _bdots) {  
  665.                 _bdots[k].remove();  
  666.             }  
  667.         };  
  668.         this.text = function() {  
  669.             return _text.attr('text');  
  670.         };  
  671.         this.attr = function(attr) {  
  672.             if (attr)  
  673.                 _rect.attr(attr);  
  674.         };  
  675.   
  676.         resize();// 初始化位置  
  677.     };  
  678.   
  679.     myflow.path = function(o, r, from, to) {  
  680.         var _this = this, _r = r, _o = $.extend(true, {}, myflow.config.path), _path, _arrow, _text, _textPos = _o.text.textPos, _ox, _oy, _from = from, _to = to, _id = 'path'  
  681.                 + myflow.util.nextId(), _dotList, _autoText = true;  
  682.   
  683.         // 点  
  684.         function dot(type, pos, left, right) {  
  685.             var _this = this, _t = type, _n, _lt = left, _rt = right, _ox, _oy, // 缓存移动前时位置  
  686.             _pos = pos;// 缓存位置信息{x,y}, 注意:这是计算出中心点  
  687.   
  688.             switch (_t) {  
  689.                 case 'from' :  
  690.                     _n = _r.rect(pos.x - _o.attr.fromDot.width / 2,  
  691.                             pos.y - _o.attr.fromDot.height / 2,  
  692.                             _o.attr.fromDot.width, _o.attr.fromDot.height)  
  693.                             .attr(_o.attr.fromDot);  
  694.                     break;  
  695.                 case 'big' :  
  696.                     _n = _r.rect(pos.x - _o.attr.bigDot.width / 2,  
  697.                             pos.y - _o.attr.bigDot.height / 2,  
  698.                             _o.attr.bigDot.width, _o.attr.bigDot.height)  
  699.                             .attr(_o.attr.bigDot);  
  700.                     break;  
  701.                 case 'small' :  
  702.                     _n = _r.rect(pos.x - _o.attr.smallDot.width / 2,  
  703.                             pos.y - _o.attr.smallDot.height / 2,  
  704.                             _o.attr.smallDot.width, _o.attr.smallDot.height)  
  705.                             .attr(_o.attr.smallDot);  
  706.                     break;  
  707.                 case 'to' :  
  708.                     _n = _r.rect(pos.x - _o.attr.toDot.width / 2,  
  709.                             pos.y - _o.attr.toDot.height / 2,  
  710.                             _o.attr.toDot.width, _o.attr.toDot.height)  
  711.                             .attr(_o.attr.toDot);  
  712.   
  713.                     break;  
  714.             }  
  715.             if (_n && (_t == 'big' || _t == 'small')) {  
  716.                 _n.drag(function(dx, dy) {  
  717.                             dragMove(dx, dy);  
  718.                         }, function() {  
  719.                             dragStart()  
  720.                         }, function() {  
  721.                             dragUp();  
  722.                         });// 初始化拖动  
  723.                 var dragMove = function(dx, dy) {// 拖动中  
  724.                     var x = (_ox + dx), y = (_oy + dy);  
  725.                     _this.moveTo(x, y);  
  726.                 };  
  727.   
  728.                 var dragStart = function() {// 开始拖动  
  729.                     if (_t == 'big') {  
  730.                         _ox = _n.attr("x") + _o.attr.bigDot.width / 2;  
  731.                         _oy = _n.attr("y") + _o.attr.bigDot.height / 2;  
  732.                     }  
  733.                     if (_t == 'small') {  
  734.                         _ox = _n.attr("x") + _o.attr.smallDot.width / 2;  
  735.                         _oy = _n.attr("y") + _o.attr.smallDot.height / 2;  
  736.                     }  
  737.                 };  
  738.   
  739.                 var dragUp = function() {// 拖动结束  
  740.   
  741.                 };  
  742.             }  
  743.             $(_n.node).click(function(){return false;});  
  744.   
  745.             this.type = function(t) {  
  746.                 if (t)  
  747.                     _t = t;  
  748.                 else  
  749.                     return _t;  
  750.             };  
  751.             this.node = function(n) {  
  752.                 if (n)  
  753.                     _n = n;  
  754.                 else  
  755.                     return _n;  
  756.             };  
  757.             this.left = function(l) {  
  758.                 if (l)  
  759.                     _lt = l;  
  760.                 else  
  761.                     return _lt;  
  762.             };  
  763.             this.right = function(r) {  
  764.                 if (r)  
  765.                     _rt = r;  
  766.                 else  
  767.                     return _rt;  
  768.             };  
  769.             this.remove = function() {  
  770.                 _lt = null;  
  771.                 _rt = null;  
  772.                 _n.remove();  
  773.             };  
  774.             this.pos = function(pos) {  
  775.                 if (pos) {  
  776.                     _pos = pos;  
  777.                     _n.attr({  
  778.                                 x : _pos.x - _n.attr('width') / 2,  
  779.                                 y : _pos.y - _n.attr('height') / 2  
  780.                             });  
  781.                     return this;  
  782.                 } else {  
  783.                     return _pos  
  784.                 }  
  785.             };  
  786.   
  787.             this.moveTo = function(x, y) {  
  788.                 this.pos({  
  789.                             x : x,  
  790.                             y : y  
  791.                         });  
  792.   
  793.                 switch (_t) {  
  794.                     case 'from' :  
  795.                         if (_rt && _rt.right() && _rt.right().type() == 'to') {  
  796.                             _rt.right().pos(myflow.util.connPoint(  
  797.                                     _to.getBBox(), _pos));  
  798.                         }  
  799.                         if (_rt && _rt.right()) {  
  800.                             _rt  
  801.                                     .pos(myflow.util.center(_pos, _rt.right()  
  802.                                                     .pos()));  
  803.                         }  
  804.                         break;  
  805.                     case 'big' :  
  806.   
  807.                         if (_rt && _rt.right() && _rt.right().type() == 'to') {  
  808.                             _rt.right().pos(myflow.util.connPoint(  
  809.                                     _to.getBBox(), _pos));  
  810.                         }  
  811.                         if (_lt && _lt.left() && _lt.left().type() == 'from') {  
  812.                             _lt.left().pos(myflow.util.connPoint(_from  
  813.                                             .getBBox(), _pos));  
  814.                         }  
  815.                         if (_rt && _rt.right()) {  
  816.                             _rt  
  817.                                     .pos(myflow.util.center(_pos, _rt.right()  
  818.                                                     .pos()));  
  819.                         }  
  820.                         if (_lt && _lt.left()) {  
  821.                             _lt.pos(myflow.util.center(_pos, _lt.left().pos()));  
  822.                         }  
  823.                         // 三个大点在一条线上,移除中间的小点  
  824.                         var pos = {  
  825.                             x : _pos.x,  
  826.                             y : _pos.y  
  827.                         };  
  828.                         if (myflow.util.isLine(_lt.left().pos(), pos, _rt  
  829.                                         .right().pos())) {  
  830.                             _t = 'small';  
  831.                             _n.attr(_o.attr.smallDot);  
  832.                             this.pos(pos);  
  833.                             var lt = _lt;  
  834.                             _lt.left().right(_lt.right());  
  835.                             _lt = _lt.left();  
  836.                             lt.remove();  
  837.                             var rt = _rt;  
  838.                             _rt.right().left(_rt.left());  
  839.                             _rt = _rt.right();  
  840.                             rt.remove();  
  841.                             // $('body').append('ok.');  
  842.                         }  
  843.                         break;  
  844.                     case 'small' :// 移动小点时,转变为大点,增加俩个小点  
  845.                         if (_lt && _rt && !myflow.util.isLine(_lt.pos(), {  
  846.                                     x : _pos.x,  
  847.                                     y : _pos.y  
  848.                                 }, _rt.pos())) {  
  849.   
  850.                             _t = 'big';  
  851.   
  852.                             _n.attr(_o.attr.bigDot);  
  853.                             var lt = new dot('small', myflow.util.center(_lt  
  854.                                                     .pos(), _pos), _lt, _lt  
  855.                                             .right());  
  856.                             _lt.right(lt);  
  857.                             _lt = lt;  
  858.   
  859.                             var rt = new dot('small', myflow.util.center(_rt  
  860.                                                     .pos(), _pos), _rt.left(),  
  861.                                     _rt);  
  862.                             _rt.left(rt);  
  863.                             _rt = rt;  
  864.   
  865.                         }  
  866.                         break;  
  867.                     case 'to' :  
  868.                         if (_lt && _lt.left() && _lt.left().type() == 'from') {  
  869.                             _lt.left().pos(myflow.util.connPoint(_from  
  870.                                             .getBBox(), _pos));  
  871.                         }  
  872.                         if (_lt && _lt.left()) {  
  873.                             _lt.pos(myflow.util.center(_pos, _lt.left().pos()));  
  874.                         }  
  875.                         break;  
  876.                 }  
  877.   
  878.                 refreshpath();  
  879.             };  
  880.         }  
  881.   
  882.         function dotList() {  
  883.             // if(!_from) throw '没有from节点!';  
  884.             var _fromDot, _toDot, _fromBB = _from.getBBox(), _toBB = _to  
  885.                     .getBBox(), _fromPos, _toPos;  
  886.   
  887.             _fromPos = myflow.util.connPoint(_fromBB, {  
  888.                         x : _toBB.x + _toBB.width / 2,  
  889.                         y : _toBB.y + _toBB.height / 2  
  890.                     });  
  891.             _toPos = myflow.util.connPoint(_toBB, _fromPos);  
  892.   
  893.             _fromDot = new dot('from', _fromPos, nullnew dot('small', {  
  894.                                 x : (_fromPos.x + _toPos.x) / 2,  
  895.                                 y : (_fromPos.y + _toPos.y) / 2  
  896.                             }));  
  897.             _fromDot.right().left(_fromDot);  
  898.             _toDot = new dot('to', _toPos, _fromDot.right(), null);  
  899.             _fromDot.right().right(_toDot);  
  900.   
  901.             // 转换为path格式的字串  
  902.             this.toPathString = function() {  
  903.                 if (!_fromDot)  
  904.                     return '';  
  905.   
  906.                 var d = _fromDot, p = 'M' + d.pos().x + ' ' + d.pos().y, arr = '';  
  907.                 // 线的路径  
  908.                 while (d.right()) {  
  909.                     d = d.right();  
  910.                     p += 'L' + d.pos().x + ' ' + d.pos().y;  
  911.                 }  
  912.                 // 箭头路径  
  913.                 var arrPos = myflow.util.arrow(d.left().pos(), d.pos(),  
  914.                         _o.attr.arrow.radius);  
  915.                 arr = 'M' + arrPos[0].x + ' ' + arrPos[0].y + 'L' + arrPos[1].x  
  916.                         + ' ' + arrPos[1].y + 'L' + arrPos[2].x + ' '  
  917.                         + arrPos[2].y + 'z';  
  918.                 return [p, arr];  
  919.             };  
  920.             this.toJson = function() {  
  921.                 var data = "[", d = _fromDot;  
  922.   
  923.                 while (d) {  
  924.                     if (d.type() == 'big')  
  925.                         data += "{x:" + Math.round(d.pos().x) + ",y:"  
  926.                                 + Math.round(d.pos().y) + "},";  
  927.                     d = d.right();  
  928.                 }  
  929.                 if (data.substring(data.length - 1, data.length) == ',')  
  930.                     data = data.substring(0, data.length - 1);  
  931.                 data += "]";  
  932.                 return data;  
  933.             };  
  934.             this.restore = function(data) {  
  935.                 var obj = data, d = _fromDot.right();  
  936.   
  937.                 for (var i = 0; i < obj.length; i++) {  
  938.                     d.moveTo(obj[i].x, obj[i].y);  
  939.                     d.moveTo(obj[i].x, obj[i].y);  
  940.                     d = d.right();  
  941.                 }  
  942.   
  943.                 this.hide();  
  944.             };  
  945.   
  946.             this.fromDot = function() {  
  947.                 return _fromDot;  
  948.             };  
  949.             this.toDot = function() {  
  950.                 return _toDot;  
  951.             };  
  952.             this.midDot = function() {// 返回中间点  
  953.                 var mid = _fromDot.right(), end = _fromDot.right().right();  
  954.                 while (end.right() && end.right().right()) {  
  955.                     end = end.right().right();  
  956.                     mid = mid.right();  
  957.                 }  
  958.                 return mid;  
  959.             };  
  960.             this.show = function() {  
  961.                 var d = _fromDot;  
  962.                 while (d) {  
  963.                     d.node().show();  
  964.                     d = d.right();  
  965.                 }  
  966.             };  
  967.             this.hide = function() {  
  968.                 var d = _fromDot;  
  969.                 while (d) {  
  970.                     d.node().hide();  
  971.                     d = d.right();  
  972.                 }  
  973.             };  
  974.             this.remove = function() {  
  975.                 var d = _fromDot;  
  976.                 while (d) {  
  977.                     if (d.right()) {  
  978.                         d = d.right();  
  979.                         d.left().remove();  
  980.                     } else {  
  981.                         d.remove();  
  982.                         d = null;  
  983.                     }  
  984.                 }  
  985.             };  
  986.         }  
  987.   
  988.         // 初始化操作  
  989.         _o = $.extend(true, _o, o);  
  990.         _path = _r.path(_o.attr.path.path).attr(_o.attr.path);  
  991.         _arrow = _r.path(_o.attr.arrow.path).attr(_o.attr.arrow);  
  992.   
  993.         _dotList = new dotList();  
  994.         _dotList.hide();  
  995.   
  996.         _text = _r.text(0, 0, _o.text.text||_o.text.patten.replace('{from}', _from.text()).replace('{to}',  
  997.                     _to.text())).attr(_o.attr.text);  
  998.         _text.drag(function(dx, dy) {  
  999.                     if (!myflow.config.editable)  
  1000.                         return;  
  1001.                     _text.attr({  
  1002.                                 x : _ox + dx,  
  1003.                                 y : _oy + dy  
  1004.                             });  
  1005.                 }, function() {  
  1006.                     _ox = _text.attr('x');  
  1007.                     _oy = _text.attr('y');  
  1008.                 }, function() {  
  1009.                     var mid = _dotList.midDot().pos();  
  1010.                     _textPos = {  
  1011.                         x : _text.attr('x') - mid.x,  
  1012.                         y : _text.attr('y') - mid.y  
  1013.                     };  
  1014.                 });  
  1015.   
  1016.         refreshpath();// 初始化路径  
  1017.   
  1018.         // 事件处理--------------------  
  1019.         $([_path.node, _arrow.node, _text.node]).bind('click'function() {  
  1020.                     if (!myflow.config.editable)  
  1021.                         return;  
  1022.                     $(_r).trigger('click', _this);  
  1023.                     $(_r).data('currNode', _this);  
  1024.                     return false;  
  1025.                 });  
  1026.   
  1027.         // 处理点击事件,线或矩形  
  1028.         var clickHandler = function(e, src) {  
  1029.             if (!myflow.config.editable)  
  1030.                 return;  
  1031.             if (src && src.getId() == _id) {  
  1032.                 _dotList.show();  
  1033.                 $(_r).trigger('showprops', [_o.props, _this]);  
  1034.             } else {  
  1035.                 _dotList.hide();  
  1036.             }  
  1037.   
  1038.             var mod = $(_r).data('mod');  
  1039.             switch (mod) {  
  1040.                 case 'pointer' :  
  1041.   
  1042.                     break;  
  1043.                 case 'path' :  
  1044.   
  1045.                     break;  
  1046.             }  
  1047.   
  1048.         };  
  1049.         $(_r).bind('click', clickHandler);  
  1050.   
  1051.         // 删除事件处理  
  1052.         var removerectHandler = function(e, src) {  
  1053.             if (!myflow.config.editable)  
  1054.                 return;  
  1055.             if (src  
  1056.                     && (src.getId() == _from.getId() || src.getId() == _to  
  1057.                             .getId())) {  
  1058.                 // _this.remove();  
  1059.                 $(_r).trigger('removepath', _this);  
  1060.             }  
  1061.         };  
  1062.         $(_r).bind('removerect', removerectHandler);  
  1063.   
  1064.         // 矩形移动时间处理  
  1065.         var rectresizeHandler = function(e, src) {  
  1066.             if (!myflow.config.editable)  
  1067.                 return;  
  1068.             if (_from && _from.getId() == src.getId()) {  
  1069.                 var rp;  
  1070.                 if (_dotList.fromDot().right().right().type() == 'to') {  
  1071.                     rp = {  
  1072.                         x : _to.getBBox().x + _to.getBBox().width / 2,  
  1073.                         y : _to.getBBox().y + _to.getBBox().height / 2  
  1074.                     };  
  1075.                 } else {  
  1076.                     rp = _dotList.fromDot().right().right().pos();  
  1077.                 }  
  1078.                 var p = myflow.util.connPoint(_from.getBBox(), rp);  
  1079.                 _dotList.fromDot().moveTo(p.x, p.y);  
  1080.                 refreshpath();  
  1081.             }  
  1082.             if (_to && _to.getId() == src.getId()) {  
  1083.                 var rp;  
  1084.                 if (_dotList.toDot().left().left().type() == 'from') {  
  1085.                     rp = {  
  1086.                         x : _from.getBBox().x + _from.getBBox().width / 2,  
  1087.                         y : _from.getBBox().y + _from.getBBox().height / 2  
  1088.                     };  
  1089.                 } else {  
  1090.                     rp = _dotList.toDot().left().left().pos();  
  1091.                 }  
  1092.                 var p = myflow.util.connPoint(_to.getBBox(), rp);  
  1093.                 _dotList.toDot().moveTo(p.x, p.y);  
  1094.                 refreshpath();  
  1095.             }  
  1096.         };  
  1097.         $(_r).bind('rectresize', rectresizeHandler);  
  1098.   
  1099.         var textchangeHandler = function(e, v, src) {  
  1100.             if (src.getId() == _id) {// 改变自身文本  
  1101.                 _text.attr({  
  1102.                             text : v  
  1103.                         });  
  1104.                 _autoText = false;  
  1105.             }  
  1106.             //$('body').append('['+_autoText+','+_text.attr('text')+','+src.getId()+','+_to.getId()+']');  
  1107.             if (_autoText) {  
  1108.                 if (_to.getId() == src.getId()){  
  1109.                     //$('body').append('change!!!');  
  1110.                     _text.attr({  
  1111.                                 text : _o.text.patten.replace('{from}',  
  1112.                                         _from.text()).replace('{to}', v)  
  1113.                             });  
  1114.                 }  
  1115.                 else if (_from.getId() == src.getId()){  
  1116.                     //$('body').append('change!!!');  
  1117.                     _text.attr({  
  1118.                                 text : _o.text.patten.replace('{from}', v)  
  1119.                                         .replace('{to}', _to.text())  
  1120.                             });  
  1121.                 }  
  1122.             }  
  1123.         };  
  1124.         $(_r).bind('textchange', textchangeHandler);  
  1125.   
  1126.         // 函数-------------------------------------------------  
  1127.         this.from = function() {  
  1128.             return _from;  
  1129.         };  
  1130.         this.to = function() {  
  1131.             return _to;  
  1132.         };  
  1133.         // 转化json数据  
  1134.         this.toJson = function() {  
  1135.             var data = "{from:'" + _from.getId() + "',to:'" + _to.getId()  
  1136.                     + "', dots:" + _dotList.toJson() + ",text:{text:'"  
  1137.                     + _text.attr('text') + "',textPos:{x:"  
  1138.                     + Math.round(_textPos.x) + ",y:" + Math.round(_textPos.y)  
  1139.                     + "}}, props:{";  
  1140.             for (var k in _o.props) {  
  1141.                 data += k + ":{value:'"  
  1142.                         + _o.props[k].value + "'},";  
  1143.             }  
  1144.             if (data.substring(data.length - 1, data.length) == ',')  
  1145.                 data = data.substring(0, data.length - 1);  
  1146.             data += '}}';  
  1147.             return data;  
  1148.         };  
  1149.         // 恢复  
  1150.         this.restore = function(data) {  
  1151.             var obj = data;  
  1152.   
  1153.             _o = $.extend(true, _o, data);  
  1154.             //$('body').append('['+_text.attr('text')+','+_o.text.text+']');  
  1155.             if(_text.attr('text')!=_o.text.text){  
  1156.                  //$('body').append('['+_text.attr('text')+','+_o.text.text+']');  
  1157.                  _text.attr({text:_o.text.text});  
  1158.                  _autoText = false;  
  1159.             }  
  1160.   
  1161.             _dotList.restore(obj.dots);  
  1162.         };  
  1163.         // 删除  
  1164.         this.remove = function() {  
  1165.             _dotList.remove();  
  1166.             _path.remove();  
  1167.             _arrow.remove();  
  1168.             _text.remove();  
  1169.             try {  
  1170.                 $(_r).unbind('click', clickHandler);  
  1171.             } catch (e) {  
  1172.             }  
  1173.             try {  
  1174.                 $(_r).unbind('removerect', removerectHandler);  
  1175.             } catch (e) {  
  1176.             }  
  1177.             try {  
  1178.                 $(_r).unbind('rectresize', rectresizeHandler);;  
  1179.             } catch (e) {  
  1180.             }  
  1181.             try {  
  1182.                 $(_r).unbind('textchange', textchangeHandler);  
  1183.             } catch (e) {  
  1184.             }  
  1185.         };  
  1186.         // 刷新路径  
  1187.         function refreshpath() {  
  1188.             var p = _dotList.toPathString(), mid = _dotList.midDot().pos();  
  1189.             _path.attr({  
  1190.                         path : p[0]  
  1191.                     });  
  1192.             _arrow.attr({  
  1193.                         path : p[1]  
  1194.                     });  
  1195.             _text.attr({  
  1196.                         x : mid.x + _textPos.x,  
  1197.                         y : mid.y + _textPos.y  
  1198.                     });  
  1199.             // $('body').append('refresh.');  
  1200.         }  
  1201.   
  1202.         this.getId = function() {  
  1203.             return _id;  
  1204.         };  
  1205.         this.text = function() {  
  1206.             return _text.attr('text');  
  1207.         };  
  1208.         this.attr = function(attr) {  
  1209.             if (attr && attr.path)  
  1210.                 _path.attr(attr.path);  
  1211.             if (attr && attr.arrow)  
  1212.                 _arrow.attr(attr.arrow);  
  1213.             // $('body').append('aaaaaa');  
  1214.         };  
  1215.   
  1216.     };  
  1217.   
  1218.     myflow.props = function(o, r) {  
  1219.         var _this = this, _pdiv = $('#myflow_props').hide().draggable({  
  1220.                     handle : '#myflow_props_handle'  
  1221.                 }).resizable().css(myflow.config.props.attr).bind('click',  
  1222.                 function() {  
  1223.                     return false;  
  1224.                 }), _tb = _pdiv.find('table'), _r = r, _src;  
  1225.   
  1226.         var showpropsHandler = function(e, props, src) {  
  1227.             if (_src && _src.getId() == src.getId()) {// 连续点击不刷新  
  1228.                 return;  
  1229.             }  
  1230.             _src = src;  
  1231.             $(_tb).find('.editor').each(function() {  
  1232.                         var e = $(this).data('editor');  
  1233.                         if (e)  
  1234.                             e.destroy();  
  1235.                     });  
  1236.   
  1237.             _tb.empty();  
  1238.             _pdiv.show();  
  1239.             for (var k in props) {  
  1240.                 _tb.append('<tr><th>' + props[k].label + '</th><td><div id="p'  
  1241.                         + k + '" class="editor"></div></td></tr>');  
  1242.                 if (props[k].editor)  
  1243.                     props[k].editor().init(props, k, 'p' + k, src, _r);  
  1244.                 // $('body').append(props[i].editor+'a');  
  1245.             }  
  1246.         };  
  1247.         $(_r).bind('showprops', showpropsHandler);  
  1248.   
  1249.     };  
  1250.   
  1251.     // 属性编辑器  
  1252.     myflow.editors = {  
  1253.         textEditor : function() {  
  1254.             var _props, _k, _div, _src, _r;  
  1255.             this.init = function(props, k, div, src, r) {  
  1256.                 _props = props;  
  1257.                 _k = k;  
  1258.                 _div = div;  
  1259.                 _src = src;  
  1260.                 _r = r;  
  1261.   
  1262.                 $('<input  style="width:100%;"/>').val(_src.text()).change(  
  1263.                         function() {  
  1264.                             props[_k].value = $(this).val();  
  1265.                             $(_r).trigger('textchange', [$(this).val(), _src]);  
  1266.                         }).appendTo('#' + _div);  
  1267.                 // $('body').append('aaaa');  
  1268.   
  1269.                 $('#' + _div).data('editor'this);  
  1270.             };  
  1271.             this.destroy = function() {  
  1272.                 $('#' + _div + ' input').each(function() {  
  1273.                             _props[_k].value = $(this).val();  
  1274.                             $(_r).trigger('textchange', [$(this).val(), _src]);  
  1275.                         });  
  1276.                 // $('body').append('destroy.');  
  1277.             };  
  1278.         }  
  1279.     };  
  1280.   
  1281.     // 初始化流程  
  1282.     myflow.init = function(c, o) {  
  1283.         var _w = $(window).width(), _h = $(window).height(), _r = Raphael(c, _w  
  1284.                         * 1.5, _h * 1.5), _states = {}, _paths = {};  
  1285.   
  1286.         $.extend(true, myflow.config, o);  
  1287.   
  1288.         /** 
  1289.          * 删除: 删除状态时,触发removerect事件,连接在这个状态上当路径监听到这个事件,触发removepath删除自身; 
  1290.          * 删除路径时,触发removepath事件 
  1291.          */  
  1292.         $(document).keydown(function(arg) {  
  1293.             if (!myflow.config.editable)  
  1294.                 return;  
  1295.             if (arg.keyCode == 46) {  
  1296.                 var c = $(_r).data('currNode');  
  1297.                 if (c) {  
  1298.                     if (c.getId().substring(0, 4) == 'rect') {  
  1299.                         $(_r).trigger('removerect', c);  
  1300.                     } else if (c.getId().substring(0, 4) == 'path') {  
  1301.                         $(_r).trigger('removepath', c);  
  1302.                     }  
  1303.   
  1304.                     $(_r).removeData('currNode');  
  1305.                 }  
  1306.             }  
  1307.                 // alert(arg.keyCode);  
  1308.             });  
  1309.   
  1310.         $(document).click(function() {  
  1311.                     $(_r).data('currNode'null);  
  1312.                     $(_r).trigger('click', {  
  1313.                                 getId : function() {  
  1314.                                     return '00000000';  
  1315.                                 }  
  1316.                             });  
  1317.                     $(_r).trigger('showprops', [myflow.config.props.props, {  
  1318.                                         getId : function() {  
  1319.                                             return '00000000';  
  1320.                                         }  
  1321.                                     }]);  
  1322.                 });  
  1323.   
  1324.         // 删除事件  
  1325.         var removeHandler = function(e, src) {  
  1326.             if (!myflow.config.editable)  
  1327.                 return;  
  1328.             if (src.getId().substring(0, 4) == 'rect') {  
  1329.                 _states[src.getId()] = null;  
  1330.                 src.remove();  
  1331.             } else if (src.getId().substring(0, 4) == 'path') {  
  1332.                 _paths[src.getId()] = null;  
  1333.                 src.remove();  
  1334.             }  
  1335.         };  
  1336.         $(_r).bind('removepath', removeHandler);  
  1337.         $(_r).bind('removerect', removeHandler);  
  1338.   
  1339.         // 添加状态  
  1340.         $(_r).bind('addrect'function(e, type, o, id) {  
  1341.             // $('body').append(type+', ');r  
  1342.             var rect = new myflow.rect($.extend(true, {},  
  1343.                             myflow.config.tools.states[type], o), _r, id)  
  1344.             _states[rect.getId()] = rect;  
  1345.         });  
  1346.         // 添加路径  
  1347.         var addpathHandler = function(e, from, to) {  
  1348.             var path = new myflow.path({}, _r, from, to);  
  1349.             _paths[path.getId()] = path;  
  1350.         };  
  1351.         $(_r).bind('addpath', addpathHandler);  
  1352.   
  1353.         // 模式  
  1354.         $(_r).data('mod''point');  
  1355.         if (myflow.config.editable) {  
  1356.             // 工具栏  
  1357.             $("#myflow_tools").draggable({  
  1358.                         handle : '#myflow_tools_handle'  
  1359.                     }).css(myflow.config.tools.attr);  
  1360.   
  1361.             $('#myflow_tools .node').hover(function() {  
  1362.                         $(this).addClass('mover');  
  1363.                     }, function() {  
  1364.                         $(this).removeClass('mover');  
  1365.                     });  
  1366.             $('#myflow_tools .selectable').click(function() {  
  1367.                         $('.selected').removeClass('selected');  
  1368.                         $(this).addClass('selected');  
  1369.                         $(_r).data('mod'this.id);  
  1370.   
  1371.                     });  
  1372.   
  1373.             $('#myflow_tools .state').each(function() {  
  1374.                         $(this).draggable({  
  1375.                                     helper : 'clone'  
  1376.                                 });  
  1377.                     });  
  1378.   
  1379.             $(c).droppable({  
  1380.                         accept : '.state',  
  1381.                         drop : function(event, ui) {  
  1382.                             //console.log(ui.helper.context);  
  1383.                             var temp = ui.helper.context.innerHTML;  
  1384.                             var id = temp.substring(temp.indexOf(">")+1,temp.length);  
  1385.                             $(_r).trigger('addrect', [ui.helper.attr('type'), {  
  1386.                                                 attr : {  
  1387.                                                     x : ui.helper.offset().left,  
  1388.                                                     y : ui.helper.offset().top  
  1389.                                                 }  
  1390.                                             },id]);  
  1391.                             // $('body').append($(ui).attr('type')+'drop.');  
  1392.                         }  
  1393.                     });  
  1394.   
  1395.             $('#myflow_save').click(function() {// 保存  
  1396.                         var data = '{states:{';  
  1397.                         for (var k in _states) {  
  1398.                             if (_states[k]) {  
  1399.                                 data += _states[k].getId() + ':'  
  1400.                                         + _states[k].toJson() + ',';  
  1401.                             }  
  1402.                         }  
  1403.                         if (data.substring(data.length - 1, data.length) == ',')  
  1404.                             data = data.substring(0, data.length - 1);  
  1405.                         data += '},paths:{';  
  1406.                         for (var k in _paths) {  
  1407.                             if (_paths[k]) {  
  1408.                                 data += _paths[k].getId() + ':'  
  1409.                                         + _paths[k].toJson() + ',';  
  1410.                             }  
  1411.                         }  
  1412.                         if (data.substring(data.length - 1, data.length) == ',')  
  1413.                             data = data.substring(0, data.length - 1);  
  1414.                         data += '},props:{props:{';  
  1415.                         data += '}}}';  
  1416.   
  1417.                         myflow.config.tools.save.onclick(data);  
  1418.                         // alert(data);  
  1419.                     });  
  1420.   
  1421.             // 属性框  
  1422.             new myflow.props({}, _r);  
  1423.         }  
  1424.         // 恢复  
  1425.         if (o.restore) {  
  1426.             // var data = ((typeof o.restore === 'string') ? eval(o.restore) :  
  1427.             // o.restore);  
  1428.             var data = o.restore;  
  1429.             var rmap = {};  
  1430.             if (data.states) {  
  1431.                 for (var k in data.states) {  
  1432.                     var rect = new myflow.rect(  
  1433.                             $  
  1434.                                     .extend(  
  1435.                                             true,  
  1436.                                             {},  
  1437.                                             myflow.config.tools.states[data.states[k].type],  
  1438.                                             data.states[k]), _r);  
  1439.                     rect.restore(data.states[k]);  
  1440.                     rmap[k] = rect;  
  1441.                     _states[rect.getId()] = rect;  
  1442.                 }  
  1443.             }  
  1444.             if (data.paths) {  
  1445.                 for (var k in data.paths) {  
  1446.                     var p = new myflow.path($.extend(true, {},  
  1447.                                     myflow.config.tools.path, data.paths[k]),  
  1448.                             _r, rmap[data.paths[k].from],  
  1449.                             rmap[data.paths[k].to]);  
  1450.                     p.restore(data.paths[k]);  
  1451.                     _paths[p.getId()] = p;  
  1452.                 }  
  1453.             }  
  1454.         }  
  1455.         // 历史状态  
  1456.         var hr = myflow.config.historyRects, ar = myflow.config.activeRects;  
  1457.         if (hr.rects.length || ar.rects.length) {  
  1458.             var pmap = {}, rmap = {};  
  1459.             for (var pid in _paths) {// 先组织MAP  
  1460.                 if (!rmap[_paths[pid].from().text()]) {  
  1461.                     rmap[_paths[pid].from().text()] = {  
  1462.                         rect : _paths[pid].from(),  
  1463.                         paths : {}  
  1464.                     };  
  1465.                 }  
  1466.                 rmap[_paths[pid].from().text()].paths[_paths[pid].text()] = _paths[pid];  
  1467.                 if (!rmap[_paths[pid].to().text()]) {  
  1468.                     rmap[_paths[pid].to().text()] = {  
  1469.                         rect : _paths[pid].to(),  
  1470.                         paths : {}  
  1471.                     };  
  1472.                 }  
  1473.             }  
  1474.             for (var i = 0; i < hr.rects.length; i++) {  
  1475.                 if (rmap[hr.rects[i].name]) {  
  1476.                     rmap[hr.rects[i].name].rect.attr(hr.rectAttr);  
  1477.                 }  
  1478.                 for (var j = 0; j < hr.rects[i].paths.length; j++) {  
  1479.                     if (rmap[hr.rects[i].name].paths[hr.rects[i].paths[j]]) {  
  1480.                         rmap[hr.rects[i].name].paths[hr.rects[i].paths[j]]  
  1481.                                 .attr(hr.pathAttr);  
  1482.                     }  
  1483.                 }  
  1484.             }  
  1485.             for (var i = 0; i < ar.rects.length; i++) {  
  1486.                 if (rmap[ar.rects[i].name]) {  
  1487.                     rmap[ar.rects[i].name].rect.attr(ar.rectAttr);  
  1488.                 }  
  1489.                 for (var j = 0; j < ar.rects[i].paths.length; j++) {  
  1490.                     if (rmap[ar.rects[i].name].paths[ar.rects[i].paths[j]]) {  
  1491.                         rmap[ar.rects[i].name].paths[ar.rects[i].paths[j]]  
  1492.                                 .attr(ar.pathAttr);  
  1493.                     }  
  1494.                 }  
  1495.             }  
  1496.         }  
  1497.     }  
  1498.   
  1499.     // 添加jquery方法  
  1500.     $.fn.myflow = function(o) {  
  1501.         return this.each(function() {  
  1502.                     myflow.init(this, o);  
  1503.                 });  
  1504.     };  
  1505.   
  1506.     $.myflow = myflow;  
  1507. })(jQuery);  
原创粉丝点击