avalon SVG 画流程图

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <style>
        vml:*
        {
            FONT-SIZE: 12px;
            behavior: url(#default#VML);
        }
    </style>
    <style>
        .itemnode
        {
            fill: #00EE00; stroke: #000000; stroke-width: 1; position: absolute; 
            vertical-align: middle; cursor: pointer; text-align: center; z-index: 1
        }
        .itemline
        {
            stroke: rgb(99,99,99); z-index: 2; stroke-width: 2;
        }
        .itemtext
        {
            font-size: 12px; opacity: 1; position: absolute; text-anchor: middle; fill: #000000;
            cursor:pointer;display:block;
        }
        .itempolygon
        {
            fill: #000000; stroke: #000000; stroke-width: 1; transform:translate(70,200)
        }
        .classp
        {
            font-size: 12px; opacity: 1;fill: #000000;
            cursor:pointer;display:block;margin-top:5px;text-align:center;
        }
    </style>
    
</head>
<body>
    <div ms-controller="controller">
       
        <svg id='contextsvg' xml:space='preserve' ms-css="@svgconfig" xmlns='http://www.w3.org/2000/svg'>
           
            <g ms-for="el in @data" ms-attr="{id:el.id}">
                <rect ms-attr="el.rect" ms-css="{fill:el.rect.fill}" />
                <g>
                <text ms-attr="el.text" onselectstart='return false;'>
                    <tspan >{{el.text.text}}</tspan>
                </text>
                <foreignObject width="100" height="50" ms-attr="{x:el.text.x,y:el.text.y,id:'fr_'+el.rect.id}" class="itemtext">
                  <body xmlns="http://www.w3.org/1999/xhtml">
                    <p class="classp">{{el.text.opter}}</p>
                    <p class="classp">{{el.text.msg}}</p>
                  </body>
                </foreignObject>
                    </g>
               <line ms-for="x in el.link" ms-attr="x" />
               <polygon ms-for="x in el.polygon" ms-attr="x" />
            </g>
        </svg>
    </div>

    <div id="contextBody" style="font-size: 12px;display:none">
    </div>


</body>
<script src="/Components/js/avalon2.2.8.js" type="text/javascript"></script>
<script>

    var data = [
        {
            name: "申报", opter: "操作人1", next: ["联审1", "联审2", "联审3", "联审4", "联审5"]
               , msg: "操作结果", state: 3
        }
, { name: "联审1", opter: "联审人1", next: ["汇签"], msg: "同意", state: 3 }
, { name: "联审2", opter: "联审人2", next: ["汇签"], msg: "同意", state: 3 }
, { name: "联审3", opter: "联审人3", next: ["汇签"], msg: "同意", state: 3 }
, { name: "联审4", opter: "联审人4", next: ["汇签"], msg: "同意", state: 3 }
, { name: "联审5", opter: "联审人5", next: ["汇签"], msg: "同意", state: 3 }
, { name: "汇签", opter: "汇签审核人", next: ["主管部门受理"], msg: "同意", state: 3 }
, { name: "主管部门受理", opter: "受理", next: ["主管领导审核"], msg: "同意", state: 3 }
, { name: "主管领导审核", opter: "领导审核", next: ["财政受理"], msg: "同意", state: 3 }
, { name: "财政受理", opter: "财政受理", next: ["财政审核"], msg: "同意", state: 3 }
, { name: "财政审核", opter: "财政审核", next: ["系统分析"], msg: "同意", state: 3 }
, { name: "系统分析", opter: "系统分析", next: ["专家评审A", "专家评审B", "专家评审C"], msg: "同意", state: 3 }
, { name: "专家评审A", opter: "天风国际专家评审A", next: ["资金安排"], msg: "同意", state: 3 }
, { name: "专家评审B", opter: "专家评审B", next: ["资金安排"], msg: "同意", state: 3 }
, { name: "专家评审C", opter: "专家评审C", next: ["资金安排"], msg: "同意", state: 3 }
, { name: "资金安排", opter: "资金安排", next: ["项目立项"], msg: "同意", state: 3 }
, { name: "项目立项", opter: "项目立项", next: ["项目公示"], msg: "同意", state: 3 }
, { name: "项目公示", opter: "项目公示", next: ["项目归档"], msg: "同意", state: 1 }
, { name: "项目归档", opter: "项目归档", next: [], msg: "同意项目归档", state: 0 }
    ];
</script>
<script type="text/javascript">
    function createRectObj() {
        return { id: '', x: '312', y: '170', rx: '5', ry: '5',  '100', height: '50', "class": "itemnode", x: '20', y: '50', rx: '5', ry: '5', transform: "matrix(1 0 0 1 0 0)" }
    }
    function createLineObj() {
        return { x1: '0', y1: '0', x2: '0', y2: '0', 'class': "itemline", source: '0', object: '0' }
    }

    function createPolygonObj() {
        return { id: 'polygon', points: "-3,-6 3,-6 0,0", transform: 'translate(70,200)', 'class': "itempolygon" }
    }
    function createTextObj() {
        return { id: 'text_', x: '20', y: '0', dx: '0', dy: '0', 'class': "itemtext", text: "", stroke: "black" }
    }

    function fillStyle(state) {
        switch (state) {
            case 0: return "#B2B2B3";
            case 1: return "#EA3241";
            case 3: return "#32C833";
            default: return "";
        }
    }

    function getPosition(index, item) {
        var obj = { x: 20, y: ystart + 30 };
        if (index == 0) {
            return obj
        }
        var flag = avalon.Array.remove(exists, index);
        if (flag == true) {
            obj.x += (item.index) * 150;
            obj.y = (item.px) * 100 + 30;
        }
        else {
            obj.x += (item.index) * 150;
            obj.y = ystart + 30;
        }
        var m = avalon(window).width()
        if (obj.x + 100 > m) {
            obj.x = (obj.x - m) < 0 ? 0 : (obj.x + 100 - m);
            obj.y += 200 + (flag ? 200 : 0);
            obj.x += (m / 2);
        }
        return obj;
    }

    var maxchild = 0, lineheight = 100, index = 0;
    var maxnext;
    avalon.each(data, function(index, el) {
        if (el.next.length > maxchild) {
            maxchild = el.next.length;
            maxnext = el;
            index = index;
        }
    })
    var xstart = 100;
    var ystart = 100;

    var nodedata = [];
    var existsPosition = [];
    var exists = [];
    var currIndex = 0;

    var pindex = 0;
    avalon.each(data, function(index, item) {
        if (item.next.length > 1) {
            item.index = pindex;
            avalon.each(data, function(i, x) {
                avalon.each(item.next, function(j, y) {
                    if (x.name == y) {
                        x.index = pindex + 1;
                        x.px = j;
                    }
                });
            });
            pindex += 2;
        }
        else {
            if (item.index) { }
            else {
                item.index = pindex;
                pindex++;
            }
        }

    });

    avalon.each(data, function(index, item) {
        if (item.next.length > 1) {
            avalon.Array.merge(exists, avalon.range(index + 1, item.next.length + index + 1));
            existsPosition.push({ name: item.name, index: index + 1, node: avalon.range(index + 1, item.next.length + index + 1) });

        }
        var p = getPosition(index, item);
        var g = { id: 'g' + item.name };
        g.rect = createRectObj();
        g.rect.state = item.state;
        g.rect.fill = fillStyle(item.state)
        g.rect.x = p.x;
        g.rect.y = p.y;
        g.rect.id = item.name;
        g.text = createTextObj();
        g.text.id += item.name;
        g.text.text = item.name;
        g.text.opter = item.opter;
        g.text.msg = item.msg;
        g.text.x = g.rect.x;
        g.text.y = g.rect.y;
        g.polygon = []
        g.link = [];

        avalon.each(item.next, function(i, x) {
            var l = createLineObj();
            l.source = item.name;
            l.object = x;
            g.link.push(l);
            var p = createPolygonObj();
            p.id = item.name + x;
            g.polygon.push(p);
        })
        nodedata.push(g);
    })

    avalon.each(nodedata, function(index, item) {

    })

    var model = avalon.define({
        $id: 'controller'
        , d: new Date().getTime()
        , data: nodedata
        , svgconfig: {  avalon(window).width() - 40, height: 500 }
        , polygonpoints: "-3,-6 3,-6 0,0"
        , rectAttr: {  '100', height: '50', "class": "itemnode", _x: '20', _y: '50', _rx: '5', _ry: '5', transform: "matrix(1 0 0 1 0 0)" }
        , lineAttr: { x1: '0', y1: '0', x2: '0', y2: '0', 'class': "itemline", _source: '1', _object: '2' }
        , polygonAttr: { points: "-3,-6 3,-6 0,0", transform: 'translate(70,200)', 'class': "itempolygon" }
        , textAttr: { _id: 'text_1', _x: '20', _y: '50', _dx: '56', _dy: '30', 'class': "itemtext" }

    });

    setTimeout(function() {
        document.getElementById("contextsvg").innerHTML = document.getElementById("contextsvg").innerHTML;
        drawLine();
    }, 1000);
</script>
    <script type="text/javascript" src="set_main.js"></script>

</html>
set_main.js
//--- 图形化设计 ---
/**
* 是否开始拖拽
**/
var dragapproved = false;
/**
* 拖拽的对象,拖拽前鼠标的位置
**/
var eventsource, x, y;
/**
* 拖拽前对象的位置
**/
var temp1 = 0;
var temp2 = 0;
/**
* 拖拽前矩形中文字的位置
**/
var textX = 0;
var textY = 0;
/**
* svg vml类型初始化
**/
var VGType = function () { return window.SVGAngle || document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML"; }
var isSVG = function () { return VGType() == "SVG" ? true : false; }
var isVML = function () { return VGType() == "VML" ? true : false; }


//获得event对象方法
function getEvent() {
    if (document.all) return window.event;  //如果浏览器中可直接得到event对象 则直接返回     
    func = getEvent.caller;
    while (func != null) {
        var arg0 = func.arguments[0];
        if (arg0) {
            if ((arg0.constructor == Event || arg0.constructor == MouseEvent) || (typeof (arg0) == "object" && arg0.preventDefault && arg0.stopPropagation)) {
                return arg0;
            }
        }
        func = func.caller;
    }
    return null;
}


//获取浏览器类型
var Browser = GetBrowser();
function GetBrowser() {
    var Sys = {};
    var ua = navigator.userAgent.toLowerCase();


    var ie11;

    try {
        ie11 = window.ActiveXObject.length;
    }
    catch (e) { }

    if (s = ua.match(/msie ([d.]+)/))
        Sys.ie = s[1];
    else if (window.ActiveXObject)
        Sys.ie = 11;
    else if (ie11)
        Sys.ie = 11;
    else if (s = ua.match(/firefox/([d.]+)/))
        Sys.firefox = s[1];
    else if (s = ua.match(/chrome/([d.]+)/))
        Sys.chrome = s[1];
    else if (s = ua.match(/opera.([d.]+)/))
        Sys.opera = s[1];
    else if (s = ua.match(/version/([d.]+).*safari/))
        Sys.safari = s[1];


    return Sys;
}


/**
* 初始化
**/
drawLine();
document.onmousedown = drags;  //开始移动
document.onmouseup = nodrags;  //结束移动
//document.oncontextmenu = DoRightClick; //提示菜单

//-- 初始化移动参数 --
function nodrags()//停止拖动
{
    dragapproved = false;
}

function move()//移动中执行
{
    var event = getEvent();
    var context = document.getElementById("contextBody");
    var newleft = temp1 + event.clientX - x; //获得矩形当前位置
    var newtop = temp2 + event.clientY - y;
    var newwidth = newleft + 120;
    var newheight = newtop + 60;
    if (isSVG()) {
        if (event.button == 0 && dragapproved) {//如果鼠标左键点击并且移动开始
            eventsource.setAttribute("x", newleft); //设定矩形位置
            eventsource.setAttribute("y", newtop);

            var text = document.getElementById("text_" + eventsource.id); //获得矩形对应文本
            var newX = textX + event.clientX - x; //获得文本当前位置
            var newY = textY + event.clientY - y;
            text.setAttribute("x", newX); //设定文本位置
            text.setAttribute("y", newY);
            var fr = document.getElementById("fr_" + eventsource.id); //获得矩形对应文本
            fr.setAttribute("x", newX); //设定文本位置
            fr.setAttribute("y", newY);
            drawLine(); //设定箭头位置

            //宽度高度自适应
            var objsvg = document.getElementById("contextsvg");
            var w = objsvg.getAttribute("width");
            var h = objsvg.getAttribute("height");
            if (newwidth > w) {
                objsvg.setAttribute("width", newwidth);
                context.style.width = newwidth + 'px'
            }
            if (newheight > h) {
                objsvg.setAttribute("height", newheight);
                context.style.height = newheight + 'px';
            }
            return false;
        }
    }
    else if (isVML()) {
        if (event.button == 1 && dragapproved) {
            eventsource.style.pixelLeft = newleft;
            eventsource.style.pixelTop = newtop;
            drawLine();

            //宽度高度自适应
            var w = context.offsetWidth;
            var h = context.offsetHeight;
            if (newwidth > w)
                context.style.width = newwidth;
            if (newheight > h)
                context.style.height = newheight;

            return false;
        }
    }
}

function drags()//拖拽开始
{
    var event = getEvent();

    oPopupMenuHide(event);
    SetSel(event);

    if (isSVG()) {
        if (event.button != 0)//如果不是鼠标左键操作 则直接返回
            return;
    }
    else if (isVML()) {
        if (event.button != 1)
            return;
    }

    var objRect = null;
    if (isSVG()) {
        objRect = event.target;  //获得鼠标点击对象
    }
    else if (isVML()) {
        objRect = event.srcElement;
    }

    if (isSVG()) {
        if (objRect.tagName == 'text' || objRect.tagName == 'tspan'
            || objRect.tagName == 'rect' || objRect.tagName == 'svg') {
            //        var menu = document.getElementById("menu");
            //        menu.style.display = "none";
        }
        if (event.target.tagName.toLowerCase() == 'tspan') {
            objRect = objRect.parentNode;
        }
        if (event.target.tagName.toLowerCase() == 'foreignobject') {
            objRect = objRect.parentNode;
        }
        if (event.target.tagName.toLowerCase() == 'p') {
            objRect = objRect.parentNode.parentNode.parentNode.children[0];
        }
        if (objRect.tagName.toLowerCase() == 'text') {//如果鼠标点击对象为文本 
            var temp = objRect.id.split("_"); //通过文本id获得对应矩形对象
            var parantId = temp[1];
            objRect = document.getElementById(parantId);
        }

        if ((objRect.tagName == 'rect') && (!event.ctrlKey))//拖拽对象为矩形
        {
            dragapproved = true; //拖拽开始
            eventsource = objRect; //将矩形对象赋给全局变量

            temp1 = parseFloat(eventsource.getAttribute("x")); //存储未拖拽前矩形的位置
            temp2 = parseFloat(eventsource.getAttribute("y"));
            var text = document.getElementById("text_" + eventsource.id); //获得与矩形对应的文本
            textX = parseFloat(text.getAttribute("x")); //获得未拖拽前文本的位置
            textY = parseFloat(text.getAttribute("y"));
            x = event.clientX; //获得未拖拽前鼠标的位置
            y = event.clientY;
            document.onmousemove = move; //为鼠标移动添加监听
        }
    }
    else if (isVML()) {
        if (event.srcElement.tagName.toLowerCase() == 'textbox') objRect = event.srcElement.parentElement;

        if ((objRect.tagName == 'roundrect') && (!event.ctrlKey)) {
            dragapproved = true;
            eventsource = objRect;
            temp1 = eventsource.style.pixelLeft;
            temp2 = eventsource.style.pixelTop;
            x = event.clientX;
            y = event.clientY;
            document.onmousemove = move;
        }
    }
}

//-- 画线 --
function drawLine() {
    var source; //箭头的开始对象id
    var object; //箭头结束对象id
    var sourceObj; //箭头开始对象
    var objectObj; //箭头结束对象
    var x0, y0, x1, y1; //箭头开始位置与结束位置
    var a = document.getElementsByTagName('line'); //所有箭头对象

    for (var i = 0; i < a.length; i++) {
        source = a[i].getAttribute('source');
        object = a[i].getAttribute('object');

        if ((source != null) && (object != null)) {

            sourceObj = document.getElementById(source);
            objectObj = document.getElementById(object);

            if ((sourceObj == null) || (objectObj == null)) continue;
            //计算箭头开始位置与结束位置

            var sourceX = isSVG() ? parseFloat(sourceObj.getAttribute("x")) : sourceObj.style.pixelLeft;
            var sourceY = isSVG() ? parseFloat(sourceObj.getAttribute("y")) : sourceObj.style.pixelTop;
            var sourceWidth = isSVG() ? parseFloat(sourceObj.getAttribute("width")) : sourceObj.style.pixelWidth;
            var sourceHeight = isSVG() ? parseFloat(sourceObj.getAttribute("height")) : sourceObj.style.pixelHeight;

            var objectX = isSVG() ? parseFloat(objectObj.getAttribute("x")) : objectObj.style.pixelLeft;
            var objectY = isSVG() ? parseFloat(objectObj.getAttribute("y")) : objectObj.style.pixelTop;
            var objectWidth = isSVG() ? parseFloat(objectObj.getAttribute("width")) : objectObj.style.pixelWidth;
            var objectHeight = isSVG() ? parseFloat(objectObj.getAttribute("height")) : objectObj.style.pixelHeight;

            if (sourceX > objectX) {
                if ((sourceX - objectX) <= objectWidth) {
                    x0 = sourceX + sourceWidth / 2;
                    x1 = objectX + objectWidth / 2;
                    if (sourceY > objectY) {
                        y0 = sourceY;
                        y1 = objectY + objectHeight;
                    } else {
                        y0 = sourceY + sourceHeight;
                        y1 = objectY;
                    }
                } else {
                    x0 = sourceX;
                    x1 = objectX + objectWidth;
                    y0 = sourceY + sourceHeight / 2;
                    y1 = objectY + objectHeight / 2;
                }
            } else {
                if ((objectX - sourceX) <= objectWidth) {
                    x0 = sourceX + sourceWidth / 2;
                    x1 = objectX + objectWidth / 2;
                    if (sourceY > objectY) {
                        y0 = sourceY;
                        y1 = objectY + objectHeight;
                    } else {
                        y0 = sourceY + sourceHeight;
                        y1 = objectY;
                    }
                } else {
                    x0 = sourceX + sourceWidth;
                    x1 = objectX;
                    y0 = sourceY + sourceHeight / 2;
                    y1 = objectY + objectHeight / 2;
                }
            }

            if (isSVG()) {
                a[i].setAttribute("x1", x0);
                a[i].setAttribute("y1", y0);
                a[i].setAttribute("x2", x1);
                a[i].setAttribute("y2", y1);
            }
            else if (isVML()) {
                a[i].from = String(x0) + ',' + String(y0);
                a[i].to = String(x1) + ',' + String(y1);
                a[i].style.pixelLeft = x0 + 'px';
                a[i].style.pixelTop = y0 + 'px';
            }

            if (isSVG()) {
                //设定箭头位置
                var arrow = document.getElementById(source + object);
                var temp = -(objectX - sourceX) / (objectY - sourceY);
                if (objectY - sourceY >= 0) {
                    arrow.setAttribute("transform", "rotate(" + Math.atan(temp) * 180 / Math.PI + "," + x1 + "," + y1 + ") translate(" + x1 + "," + y1 + ")");
                } else {
                    arrow.setAttribute("transform", "rotate(" + (Math.PI + Math.atan(temp)) * 180 / Math.PI + "," + x1 + "," + y1 + ") translate(" + x1 + "," + y1 + ")");
                }
            }

            if (isVML()) {
                //条件
                strIF = a[i].getAttribute('title');
                if ((strIF != null) && (strIF != '')) {
                    var id = 'if_' + source + '_' + object;
                    var obj = document.getElementById(id);

                    var left = (x0 + (x1 - x0) / 2 - 30);
                    var top = (y0 + (y1 - y0) / 2 - 15);

                    if (obj != null) {
                        obj.style.pixelLeft = left + 'px';
                        obj.style.pixelTop = top + 'px';

                        obj.style.left = left + 'px';
                        obj.style.top = top + 'px';

                        obj.style.display = '';
                    }
                }
                a[i].style.display = '';
            }
        }
    }
}

function SetSel(event)//选中的矩形改变颜色
{
    var flowType = '';
    var flowID = 0;
    var passCount = 0;
    var flowColor = '';
    /*
    var strStart = "#00EE00";
    var strEnd = "#F4A8BD";
    var strOut = "#EEEEEE";
    var strSelect = "#8E83F5";
    */

    var strStart = "#8E83F5";
    var strEnd = "#8E83F5";
    var strOut = "#00EE00";
    var strSelect = "#8E83F5";

    var rect = isSVG() ? document.getElementsByTagName('rect') : document.getElementsByTagName('roundrect');
    for (var i = 0; i < rect.length; i++) {
        flowType = rect[i].getAttribute('flowtype');
        if (flowType == 'start') {
            flowColor = strStart;
        }
        else if (flowType == 'end') {
            flowColor = strEnd;
        }
        else {
            flowColor = strOut;
        }
        if (isSVG()) {
           // rect[i].setAttribute("style", "stroke:#000000;fill:" + flowColor);
        }
        else if (isVML()) {
            rect[i].fillcolor = flowColor;
        }
    }

    var objRect = isSVG() ? event.target : event.srcElement;
    if (isSVG()) {
        if (event.target.tagName.toLowerCase() == 'tspan') {
            var temp = objRect.parentNode.id.split("_");
            var parantId = temp[1];
            objRect = document.getElementById(parantId);
        }
        if (event.target.tagName.toLowerCase() == 'text') {//如果鼠标点击当前对象是文本对象 则获取它对应的矩形对象
            var temp = objRect.id.split("_");
            var parantId = temp[1];
            objRect = document.getElementById(parantId);
        }
    }
    else if (isVML()) {
        if (event.srcElement.tagName.toLowerCase() == 'textbox')
            objRect = event.srcElement.parentElement;
    }

    //步骤类型
    if (isSVG()) {
        try {
            if (objRect.tagName == 'rect') {
                //objRect.setAttribute("style", "stroke:#000000;fill:" + strSelect);
            }
        } catch (e) { }
    }
    else if (isVML()) {
        try { if (objRect.tagName == 'roundrect') objRect.fillcolor = strSelect; } catch (e) { }
    }
}

// 形成菜单行
function getMenuRow(s_Event, s_Html) {
    var s_MenuRow = "";
    s_MenuRow = "<tr><td align=center valign=middle nowrap><TABLE border=0 cellpadding=0 cellspacing=0 width=132><tr><td nowrap valign=middle height=20 class=MouseOut onMouseOver=this.className='MouseOver'; onMouseOut=this.className='MouseOut';";
    if (Browser.id) {
        s_MenuRow += " onclick="window.parent." + s_Event + ";window.parent.oPopupMenu.hide();"";
    }
    else {
        s_MenuRow += " onclick="" + s_Event + ";oPopupMenu.hide();"";
    }
    s_MenuRow += ">&nbsp;";
    s_MenuRow += s_Html + "</td></tr></TABLE></td></tr>";
    return s_MenuRow;
}

//-- 右键菜单 --
var sMenuHr = "<tr><td align=center valign=middle height=2><TABLE border=0 cellpadding=0 cellspacing=0 width=128 height=2><tr><td height=1 class=HrShadow></td></tr><tr><td height=1 class=HrHighLight></td></tr></TABLE></td></tr>";
var sMenu1 = "<TABLE onmousedown='if (event.button==1) return true; else return false;' border=0 cellpadding=0 cellspacing=0 class=Menu width=150><tr><td width=18 valign=bottom align=center style='background:url(/images/bg_left.gif.gif);background-position:bottom;'></td><td width=132 class=RightBg><TABLE border=0 cellpadding=0 cellspacing=0>";
var sMenu2 = "</TABLE></td></tr></TABLE>";
var oPopupMenu = null;

MyCreatePopup();
oPopupMenu = window.createPopup();

function oPopupMenuHide(event) {
    var opkey = false;
    if (Browser.firefox || Browser.chrome || Browser.ie == 11) {
        if (event.button == 0) {
            opkey = true;
        }
    }
    else {
        if (Browser.ie) {
            if (event.button == 1) {
                opkey = true;
            }
        }
    }
    if (opkey) {
        var obje = isSVG() ? event.target : event.srcElement;
        if (obje.tagName == 'TABLE' && obje.className == 'Menu')
            return false;
        for (i = 0; i < 15; i++) {
            obje = obje.parentNode;
            if (!obje)
                break;
            if (obje.tagName == 'TABLE' && obje.className == 'Menu')
                return false;
        }
        oPopupMenu.document.body.innerHTML = "";
        oPopupMenu.hide();
        return false;
    }
}

function showContextMenu(event, type) {
    oPopupMenuHide(event);

    var style = "";
    style = "BODY {margin:0px;border:0px}";
    style += " TD {font-size:9pt;font-family:宋体,Verdana,Arial}";
    style += " TABLE.Menu {border-top:window 1px solid;border-left:window 1px solid;border-bottom:buttonshadow 1px solid;border-right:buttonshadow 1px solid;background-color:#0072BC}";
    style += "TD.RightBg {background-color:buttonface}";
    style += "TD.MouseOver {background-color:highlight;color:highlighttext;cursor:default;}";
    style += "TD.MouseOut {background-color:buttonface;color:buttontext;cursor:default;}";
    style += "TD.HrShadow {background-color:buttonshadow;}";
    style += "TD.HrHighLight {background-color:buttonhighlight;}";
    style = "<style>" + style + "</style>";

    var width = 150;
    var height = 0;
    var lefter = event.clientX;
    var topper = event.clientY;

    var oPopDocument = oPopupMenu.document;
    var oPopBody = oPopupMenu.document.body;

    //object
    var objRect = isSVG() ? event.target : event.srcElement;
    var Process_ID = null;

    if (isSVG()) {
        if (objRect.tagName.toLowerCase() == 'tspan')
            objRect = objRect.parentNode;
        Process_ID = objRect.getAttribute('table_id');
    }
    else if (isVML()) {
        if (objRect.tagName.toLowerCase() == 'textbox')
            objRect = objRect.parentElement;
        Process_ID = objRect.getAttribute('table_id');
    }

    var sMenu = style;

    switch (type) {
        case 1:
            sMenu += getMenuRow("viewPage(" + Process_ID + ")", "查看该节点页面");
            height += 20;

            sMenu += getMenuRow("Edit_Process(" + Process_ID + ")", "步骤基本属性");
            height += 20;

            sMenu += getMenuRow("set_next(" + Process_ID + ")", "在此步骤下追加");
            height += 20;

            sMenu += getMenuRow("set_item(" + Process_ID + ")", "可写字段");
            height += 20;

            sMenu += getMenuRow("set_condition(" + Process_ID + ")", "条件设置");
            height += 20;

            sMenu += getMenuRow("set_user(" + Process_ID + ")", "经办人");
            height += 20;

            sMenu += getMenuRow("set_dept(" + Process_ID + ")", "下一步骤设置");
            height += 20;



            sMenu += sMenuHr;
            height += 2;

            sMenu += getMenuRow("Del_Process(" + Process_ID + ")", "删除该步骤");
            height += 20;

            break;
        case 2:

            sMenu += getMenuRow("Add_Process()", "新建步骤");
            height += 20;

            sMenu += getMenuRow("SavePosition()", "保存布局");
            height += 20;

            sMenu += getMenuRow("Refresh()", "刷新视图");
            height += 20;

            break;
    }

    sMenu = sMenu1 + sMenu + sMenu2;

    height += 2;
    if (lefter + width > document.body.clientWidth) lefter = lefter - width + 2;
    if (topper + height > document.body.clientHeight) topper = topper - height + 2;

    oPopupMenu.document.body.innerHTML = sMenu;
    oPopupMenu.show(lefter, topper, width, height, document.body);

    return false;
}

//-- 鼠标右击 --
function DoRightClick(event) {
    event = event || window.event;

    pub_x = event.clientX;
    pub_y = event.clientY;

    SetSel(event);

    var objRect = isSVG() ? event.target : event.srcElement;
    if (isSVG()) {
        if (event.target.tagName.toLowerCase() == 'tspan') objRect = objRect.parentNode;

        if (objRect.tagName.toLowerCase() == 'rect' || objRect.tagName.toLowerCase() == 'text') {

            if (event.button == 2 || event.button == 0) {
                return showContextMenu(event, 1);
            }
        }
        else {
            if (objRect.tagName.toLowerCase() == 'line') {
                //if (event.button == 2 || event.button == 0) return showContextMenu(event,3);
            }
            else {
                if (event.button == 2 || event.button == 0) return showContextMenu(event, 2);
            }
        }
    }
    else if (isVML()) {
        //        var objRect = event.srcElement;
        if (event.srcElement.tagName.toLowerCase() == 'textbox') objRect = event.srcElement.parentElement;


        if (objRect.tagName.toLowerCase() == 'roundrect') {


            if (event.button == 2 || event.button == 0) {
                return showContextMenu(event, 1);
            }
        }
        else {
            if (objRect.tagName.toLowerCase() == 'line') {
                //if (event.button == 2 || event.button == 0) return showContextMenu(event,3);
            }
            else {
                if (event.button == 2 || event.button == 0) return showContextMenu(event, 2);
            }
        }
    }
    return false;
}

//-- 删除流程线 --
function SetSqlDelFlow(fid) {
    var strSql = '';
    strSql = "delete from office_missive_flow_run where office_missive_flow_run_id='" + fid + "' ";
    document.all('tbSQL').value += strSql;
}

//-- 保存布局 --
function SavePosition() {
    var id = 0;
    var strSql = '';
    var mf_pixel_left = 0;
    var mf_pixel_top = 0;

    if (isSVG()) {
        a = document.getElementsByTagName('rect');
        for (var i = 0; i < a.length; i++) {
            table_id = eval(a[i].getAttribute('table_id'));
            mf_pixel_left = a[i].getAttribute('x');
            mf_pixel_top = a[i].getAttribute('y');

            if (table_id > 0) {
                strSql += "SetLeft=" + mf_pixel_left + ",SetTop=" + mf_pixel_top + " where ID=" + table_id + ";";
            }
        }
    }
    else if (isVML()) {
        a = document.getElementsByTagName('roundrect');
        for (var i = 0; i < a.length; i++) {
            table_id = eval(a[i].getAttribute('table_id'));
            mf_pixel_left = a[i].style.pixelLeft;
            mf_pixel_top = a[i].style.pixelTop;

            if (table_id > 0) {
                strSql += "SetLeft=" + mf_pixel_left + ",SetTop=" + mf_pixel_top + " where ID=" + table_id + ";";
            }
        }
    }

}

//-- 删除流程线 --
function DelFlowRun(fid) {
    if ((fid == null) || (fid == 0)) return;

    SavePosition();
    SetSqlDelFlow(fid);

    document.all('btnSave').click();
}

//自定义createPopup
function MyCreatePopup() {
    if (!window.createPopup) {
        var __createPopup = function () {
            var SetElementStyles = function (element, styleDict) {
                var style = element.style;
                for (var styleName in styleDict) style[styleName] = styleDict[styleName];
            }
            var eDiv = document.createElement('div');
            SetElementStyles(eDiv, { 'position': 'absolute', 'top': 0 + 'px', 'left': 0 + 'px', 'width': 0 + 'px', 'height': 0 + 'px', 'zIndex': 1000, 'display': 'none', 'overflow': 'hidden' });
            eDiv.body = eDiv;
            var opened = false;
            var setOpened = function (b) {
                opened = b;
            }
            var getOpened = function () {
                return opened;
            }
            var getCoordinates = function (oElement) {
                var coordinates = { x: 0, y: 0 };
                while (oElement) {
                    coordinates.x += oElement.offsetLeft;
                    coordinates.y += oElement.offsetTop;
                    oElement = oElement.offsetParent;
                }
                return coordinates;
            }

            return { htmlTxt: '', document: eDiv, isOpen: getOpened(), isShow: false, hide: function () { SetElementStyles(eDiv, { 'top': 0 + 'px', 'left': 0 + 'px', 'width': 0 + 'px', 'height': 0 + 'px', 'display': 'none' }); eDiv.innerHTML = ''; this.isShow = false; }, show: function (iX, iY, iWidth, iHeight, oElement) {
                if (!getOpened()) { document.body.appendChild(eDiv); setOpened(true); }; this.htmlTxt = eDiv.innerHTML; if (this.isShow) { this.hide(); }; eDiv.innerHTML = this.htmlTxt; var coordinates = getCoordinates(oElement); eDiv.style.left = (iX + coordinates.x) + 'px'; eDiv.style.top = (iY + coordinates.y) + 'px'; eDiv.style.width = iWidth + 'px';
                eDiv.style.height = iHeight + 'px';
                eDiv.style.display = 'block'; this.isShow = true;
            }
            }
        }
        window.createPopup = function () {
            return __createPopup();
        }
    }
}
原文地址:https://www.cnblogs.com/gxivwshjj/p/9732922.html