gooflow 自定义流程图-程序员宅基地

技术标签: js  

demo链接:https://pan.baidu.com/s/1mJ46mlh8v2Q1XnZ8i5DceQ 密码:0lra

注意:本地直接打开会报错。

不支持 file地址: Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.at init (file:///C:/Users/24950/Desktop/gooflow/gooflow.html?size=big&edit=true:122:31)

在webstrom中打开即可。http://localhost:63342/Desktop/gooflow/index.html

 

流程图原理:

①gooflow相关页面,功能倒入项目。初始化流程图,页面封装流程图展示,数据获取,保存,复制等功能

②页面创建2个iframe窗口分别指向gooflow.html

    1、小窗口展示流程图缩略图不可编辑,可放大

    2、大窗口全屏观看,可编辑,可缩小

    3、放大功能即打开big iframe,  缩小即关闭big iframe。 可否编辑功能控制流程图上面的遮罩层 show/hide

③公共js封装流程图相关方法

    1、流程图后台数据获取,保存等

    2、iframe跨页面操作

// 父 --> 子   loadData:子页面方法
document.getElementById("iframe").contentWindow.loadData(data.json, data.currentNodes);
document.getElementById("bigiframe").contentWindow.loadData(data.json, data.currentNodes);

// 子 --> 父  
var _iframe = window.parent;
var _iframe_big_div =_iframe.document.getElementById('parDiv');
_iframe_big_div.style.display = 'none';

window.parent.document.getElementById("bigiframe").contentWindow.jsondata=data.json;

 

代码示例仅展示一部分,详细请下载代码查看!

gooflow.html: 流程图页面

<!DOCTYPE html>
<html xmlns:v="urn:schemas-microsoft-com:vml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>jQuery网页在线流程图</title>
    <meta name="keywords" content="在线流程图,GooFlow流程图">
    <META HTTP-EQUIV="pragma" CONTENT="no-cache">
    <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
    <META HTTP-EQUIV="expires" CONTENT="0">
    <link rel="stylesheet" type="text/css" href="gooflow/common.css">
    <!--[if lt IE 9]>    <?import namespace="v" implementation="#default#VML" ?><![endif]-->
    <link rel="stylesheet" type="text/css" href="gooflow/GooFlow2.css">
    <link rel="stylesheet" type="text/css" href="gooflow/default.css">
</head>

<body>

    <div id="demo"></div>
    <textarea id="result" row="6" style="display: none;"></textarea>
    <div class="role_info">
        <input id="role_info_name"/>
        <input id="role_info_role"/>
        <input id="role_info_limit"/>
        <input id="role_info_role_val"/>
        <input id="role_info_limit_val"/>
    </div>

    <!-- 节点编辑 -->
    <div class="shade_edit_disabled"></div>
    <div class="shade"></div>
    <div class="pop pop_node">
        <div class="pop_h"><span class="pop_h_title"><span class="line"></span>节点编辑</span><span class="close" onclick="nodeClose()"></span></div>
        <div class="pop_cont">
            <div class="pop_cont_box">
                <p class="title"><span class="line"></span>基本信息</p>
                <div class="pop_one pop450_span4"><span class="xing">*</span><div class="ipt_box"><i>节点名称:</i><input type="text" id="node_name"></div></div>
                <div class="pop_one pop450_span4"><span class="xing">*</span><div class="ipt_box"><i>节点角色:</i>
                    <select id="node_role" class="poprole">
                        <!--<option value="0">团队成员</option>-->
                        <!--<option value="1">团队负责人</option>-->
                        <!--<option value="2">质控负责人</option>-->
                    </select>
                </div></div>
                <p class="title mar_top20"><span class="line"></span>选择节点权限</p>
                <div class="pop_one  select_mb">
                    <span class="xing">*</span>
                    <div class="ipt_box">
                        <ul class="select_com_ul" id="node_limit">
                            <li><input class="ipt1" value="1" name="node_limit" type="radio"><span class="sel_name">立项管理</span></li>
                            <li><input class="ipt1" value="5" name="node_limit" type="radio"><span class="sel_name">立项申请</span></li>
                            <li><input class="ipt1" value="9" name="node_limit" type="radio"><span class="sel_name">质评管理</span></li>
                            <li><input class="ipt1" value="16" name="node_limit" type="radio"><span class="sel_name">投票</span></li>
                            <li><input class="ipt1" value="17" name="node_limit" type="radio"><span class="sel_name">内核委员</span></li>
                            <li><input class="ipt1" value="18" name="node_limit" type="radio"><span class="sel_name">内核主任</span></li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
        <div class="btn_box">
            <span class="btn btn_cancle" onclick="nodeClose()">取消</span>
            <span class="btn btn_sure" id="node_save">确定</span>
        </div>
    </div>

    <!-- 编辑流程图页面 遮罩层 -->
    <div class="shade_big_disabled"></div>

<!--<script type="text/javascript" src="gooflow/jquery.js"></script>-->
<script type="text/javascript" src="../js/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="gooflow/data2.js"></script>
<script type="text/javascript" src="gooflow/GooFunc.js"></script>
<script type="text/javascript" src="gooflow/json2.js"></script>
<script type="text/javascript" src="gooflow/GooFlow.js"></script>
<script type="text/javascript" src="../js/layer/layer.js"></script>
<script>
    var demo, out, width, height, GooFlow_work_auto = false, scale = 1,headBtns, popRole, roles,
            node_name, node_role , node_limit, node_role_val, node_limit_val;
    $(document).ready(function(){
        init();
        listAuthority();
    });

    //  页面初始化
    function init(){
        var url = window.location.href;
        if(url.indexOf("small") > 0){   // 小窗口流程图展示
            scale = 1;
            width= 735;
            height= 345;
            GooFlow_work_auto = true;
            headBtns = ["save", "undo", "redo","copy","enlarge"];
            $(".shade_edit_disabled").show();
        }
        if(url.indexOf("big") > 0){ // 大窗口流程图展示
            scale = 2;
            var _iframe = window.parent;
            var _div =_iframe.document.getElementById('parDiv');
            var width = $(_div).width();
            var height = $(_div).height();
            headBtns = ["save", "undo", "redo","copy","narrow"];
            $(".shade_edit_disabled").hide();
        };

        // 系统管理-流程管理页面  遮罩层隐藏流程图可编辑,其他页面遮罩层默认显示流程图不可编辑
        if(url.indexOf("edit") > 0){ $(".shade_big_disabled").hide(); }

        var property = {
            width: width,
            height: height,
            scale: scale,
            toolBtns: ["start round", "end round", "task"],
            haveHead: true,
            headBtns: headBtns,
            //如果haveHead=true,则定义HEAD区的按钮
            haveTool: true,
            haveGroup: true,
            useOperStack: true
        };
        var remark = {
            cursor: "选择指针",
            direct: "结点连线",
            start: "开始结点",
            "end": "结束结点",
            state: "状态结点",
            node: "自动结点",
            chat: "决策结点",
            plug: "附加插件",
            fork: "分支结点",
            "join": "联合结点",
            "task": "任务结点",
            "complex mix": "复合结点",
            group: "组织划分框编辑开关"
        };
        demo = $.createGooFlow($("#demo"), property);
        demo.setNodeRemarks(remark);
//        demo.clearData();
        demo.loadData(jsondata);



        // 小弹窗 流程图禁止滚轮
        if(GooFlow_work_auto){ $(".GooFlow_work").css("overflow","hidden"); }

        roles = getRoles();
        for(var i=0;i<roles.length;i++){
            popRole+='<option value="'+ roles[i].role_id +'">'+roles[i].role_name+'</option>';
        }
        $("#node_role").append(popRole);


        //  线程方向弹框
        var popDirect = '<ul class="popdirect"><li>同意</li><li>拒绝</li><li>弃权</li></ul>';
        $(".GooFlow").append(popDirect);
        $(".poprole li").click(function(){
            $(".poprole li").removeClass("active");
            $(this).addClass("active");
            $("textarea").val($(this).html() +"  ");
            $(".poprole").hide();
        });
        $(".popdirect li").click(function(){
            $(".popdirect li").removeClass("active");
            $(this).addClass("active");
            $("textarea").val($(this).html() +"  ");
            $(".popdirect").hide();
        });
        
    }

    // 导出数据
    function Export() {
//        console.log(demo.exportData());
        document.getElementById("result").value = JSON.stringify(demo.exportData());
//         console.log(document.getElementById("result").value);
        return document.getElementById("result").value;
    }

    // 获取角色
    function getRoles(){
        var roles;
        $.ajax({
            url:"../role/getAllRoles",
            type: 'POST',
            async:false,
            success:function(data){
                if(data.ret.succeed){
                    roles=data.list;
                }else{
                    layer.msg(data.ret.retMsg);
                }
            }
        });
        return roles;
    }

    //  加载流程图数据  渲染流程图
    function loadData(json,currentNodes){
    	console.log(json);
    	
    	demo.clearData(); demo.loadData(json,currentNodes);  }
    // 清除流程图数据
    function clearData(){ demo.clearData(); }

    //  流程图 放大,缩小功能
    function enlarge(){
        var _iframe = window.parent;
        var _div =_iframe.document.getElementById('parDiv');
        _div.style.display = 'block';
        Export();

    }
    
    function narrow(){
        var _iframe = window.parent;
        var _iframe_big_div =_iframe.document.getElementById('parDiv');
        _iframe_big_div.style.display = 'none';
        // 大的流程编辑 缩放时  将数据保存到本地 以供小的流程图预览实时 显示最新流程
        var data = Export();
        localStorage.setItem("jsondata",data);
        if(window.location.href.indexOf("edit")>0)
        	window.parent.lcsave();
    }

	function copyFlowModel(modelId){
        $.ajax({
            url:"../workflowModel/getWithJson",
            data:{"id":modelId},
            type: 'POST',
            success:function(data){
                if(data.ret.succeed){
                	console.log(data.json);
                	jsondata=data.json;
            		if(window.parent.document.getElementById("bigiframe")!=undefined&&window.parent.document.getElementById("bigiframe")!=null){
            			window.parent.document.getElementById("bigiframe").contentWindow.jsondata=data.json;
            		}
                	layer.msg("成功复制到创建面板");
                }else{
                    layer.msg(data.ret.retMsg);
                }
            }
        });
	}
    
	function loadCopy(){
		loadData(jsondata);
		Export();
		
		
		if(window.parent.document.getElementById("bigiframe")!=undefined&&window.parent.document.getElementById("bigiframe")!=null){
			console.log(window.parent.document.getElementById("bigiframe"));
			console.log('jsondata= '+jsondata);
			window.parent.document.getElementById("bigiframe").contentWindow.loadData(jsondata);
			window.parent.document.getElementById("bigiframe").contentWindow.Export();
		}
	}
	
	function bindCopy(modelId){
		$("#copy").click(function(){
			copyFlowModel(modelId);
		});
	}
	
	function unbindCopy(modelId){
		$("#copy").unbind();
	}
    //  节点窗口按钮操作
    function nodeClose(){
        $(".shade,.pop_node").hide();
    }

    // 双击获取节点信息
    function getNodeInfo(id){
        var jsonDate = JSON.parse( JSON.stringify(demo.exportData()));
        var nodeInfo  = jsonDate.nodes[id];
        $("#node_name").val(nodeInfo.name);
        $("#node_role").val(nodeInfo.role);
        $('#node_limit input').prop("checked",false);
        $('#node_limit input[value="'+ nodeInfo.limit +'"]').prop("checked",true);
    }

    
    function listAuthority(){
    	$.ajax({
            url:"../authority/getDiffAuthority",
            type: 'POST',
            async:false,
            success:function(data){
                if(data.ret.succeed){
                    var authorities=data.clist;
                    $('#node_limit').empty(); 
                    for(var i=0;i<authorities.length;i++){
                    	var authority=authorities[i];
                    	var html='<li><input class="ipt1" value="'+authority.authority_short_name+'" name="node_limit" type="radio"><span class="sel_name">'+authority.authority_name+'</span></li>'
                    	$('#node_limit').append(html);
                    }
                }else{
                    layer.msg(data.ret.retMsg);
                }
            }
        });
    }
</script>

</body>
</html>

data2.js:  流程图数据结构示例,默认此数据展示

GooFunc.js,json2.js:  流程图默认设置,无需更改

GooFlow.js: 流程图功能,展示相关,可自行优化项目需要

上面百度云项目优化的地方:

①头部,左侧按钮的优化

②  添加节点  样式控制

③节点,连线  单击双击事件,与节点信息弹框相关联

//绑定双击编辑事件
this.$workArea.delegate(".GooFlow_item > .span","dblclick",{inthis:this},function(e){
	var oldTxt=this.innerHTML;
	var This=e.data.inthis;
	var id=this.parentNode.id;
	var t=getElCoordinate(This.$workArea[0]);

	// 结束节点 禁止打开弹框
	if(oldTxt.indexOf("归档") > 0) return;

	This.$textArea.data("id",This.$focus).focus();
	This.$workArea.parent().one("mousedown",function(e){    // 仅第一次双击不触发
		if(e.button==2)return false;
		This.$textArea.data("id",This.$focus).focus();
		node_name = $("#node_name").val();
		node_role = $("#node_role").val();
		node_limit = $("#node_limit input:checked").val();
		node_role_val = $('#node_role option[value="'+node_role+'"]').html();
		node_limit_val = $('#node_limit input[value="'+node_limit+'"]').siblings("span").html();
		This.setName(This.$textArea.data("id"),node_name,"node", node_role, node_role_val, node_limit,node_limit_val);
		This.$textArea.val("").removeData("id").hide();
		$(".shade,.pop_node").hide();
	});

	// 角色弹框  圆圈按钮角色选择
	$(".shade,.pop_node").show();
	getNodeInfo(This.$textArea.data("id"));
	$(".pop_node .btn_sure").click(function(e){
		if(e.button==2)return false;
		node_name = $("#node_name").val();
		node_role = $("#node_role").val();
		node_limit = $("#node_limit input:checked").val();
		node_role_val = $('#node_role option[value="'+node_role+'"]').html();
		node_limit_val = $('#node_limit input[value="'+node_limit+'"]').siblings("span").html();
		if(!node_name) { layer.msg('请输入节点名称'); return; }
		if(!node_role) { layer.msg('请选择节点角色');  return; }
		if(!node_limit) { layer.msg('请选择节点权限'); return;  }
		This.setName(This.$textArea.data("id"),node_name,"node", node_role, node_role_val, node_limit,node_limit_val);
		This.$textArea.val("").removeData("id").hide();
		$(".shade,.pop_node").hide();
});

		});
this.$workArea.delegate(".ico + td","dblclick",{inthis:this},function(e){
	var oldTxt=this.innerHTML;
	var This=e.data.inthis;
	var id=$(this).parents(".GooFlow_item").attr("id");
	var t=getElCoordinate(This.$workArea[0]);

	This.$textArea.data("id",This.$focus).focus();
	This.$workArea.parent().one("mousedown",function(e){    // 仅第一次双击不触发
	if(e.button==2)return false;
	This.$textArea.data("id",This.$focus).focus();
	node_name = $("#node_name").val();
	node_role = $("#node_role").val();
	node_limit = $("#node_limit input:checked").val();
	node_role_val = $('#node_role option[value="'+node_role+'"]').html();
	node_limit_val = $('#node_limit input[value="'+node_limit+'"]').siblings("span").html();
	This.setName(This.$textArea.data("id"),node_name,"node", node_role, node_role_val, node_limit,node_limit_val);
	This.$textArea.val("").removeData("id").hide();
		$(".shade,.pop_node").hide();
	});

			// 角色弹框  方框按钮角色选择
	$(".shade,.pop_node").show();
	getNodeInfo(This.$textArea.data("id"));
	$(".pop_node .btn_sure").click(function(e){
		if(e.button==2)return false;
		node_name = $("#node_name").val();
		node_role = $("#node_role").val();
		node_limit = $("#node_limit input:checked").val();
		node_role_val = $('#node_role option[value="'+node_role+'"]').html();
		node_limit_val = $('#node_limit input[value="'+node_limit+'"]').siblings("span").html();
		if(!node_name) { layer.msg('请输入节点名称'); return; }
		if(!node_role) { layer.msg('请选择节点角色');  return; }
		if(!node_limit) { layer.msg('请选择节点权限'); return; }
		This.setName(This.$textArea.data("id"),node_name,"node", node_role, node_role_val, node_limit,node_limit_val);
		This.$textArea.val("").removeData("id").hide();
		$(".shade,.pop_node").hide();
	});

});

1.小窗口预览

<iframe class="spinfo sp_lc" src="gooflow.html?size=small" name="iframe" id="iframe" frameborder="no" scrolling="no"></iframe>

2.全屏大窗口查看  可编辑

// 流程图大窗口  在公共js里添加,不需要每个html页面都添加一次
if (window.location.href.indexOf("xtgl_lcgl") > 0) {  // 流程图可编辑大窗口
	var popBigLcDiv = '<div class="pop_big_lc" id="parDiv"><iframe name="bigiframe" id="bigiframe" class="spinfo sp_lc" src="gooflow.html?size=big:edit=true" frameborder="no" scrolling="no"></iframe></div>';
} else {    // 流程图不可编辑大窗口
	var popBigLcDiv = '<div class="pop_big_lc" id="parDiv"><iframe name="bigiframe" id="bigiframe" class="spinfo sp_lc" src="gooflow.html?size=big" frameborder="no" scrolling="no"></iframe></div>';
}

3.全屏大窗口  每个节点编辑

iframe 跨页面操作示例如下:

父页面操作子页面:

// 流程图 保存
function lcsave() {
	var datajson = JSON.parse(localStorage.getItem("jsondata"));
	document.getElementById("iframe").contentWindow.loadData(datajson);
}
/**
 * 展示流程进度图
 */
function showCommonFlowProgress(project_id, type) {
	// var project_id = $("#project_name")[0].lang;
	$.ajax({
		url : "../workflowModel/getWorkflowProgress",
		data : {
			project_id : project_id,
			workflow_type : type
		},
		type : "POST",
		success : function(data) {
			if (data.ret.succeed) {
				document.getElementById("iframe").contentWindow.loadData(
						data.json, data.currentNodes);
				document.getElementById("bigiframe").contentWindow.loadData(
						data.json, data.currentNodes);
			} else {
				// layer.msg(data.ret.retMsg);
				document.getElementById("iframe").contentWindow.clearData();
				document.getElementById("bigiframe").contentWindow.clearData();
			}
		}

	});
}

子页面操作父页面:

//  流程图 放大,缩小功能
    function enlarge(){
        var _iframe = window.parent;
        var _div =_iframe.document.getElementById('parDiv');
        _div.style.display = 'block';
        Export();

    }
    
    function narrow(){
        var _iframe = window.parent;
        var _iframe_big_div =_iframe.document.getElementById('parDiv');
        _iframe_big_div.style.display = 'none';
        // 大的流程编辑 缩放时  将数据保存到本地 以供小的流程图预览实时 显示最新流程
        var data = Export();
        localStorage.setItem("jsondata",data);
        if(window.location.href.indexOf("edit")>0)
        	window.parent.lcsave();
    }

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zjl199303/article/details/80625994

智能推荐

Vue 食用指南-程序员宅基地

文章浏览阅读738次,点赞13次,收藏16次。本文记录了 Yukiii 学习 Vue 期间的心得和相关功能的具体实现及 Vue 的基本使用方法,方便后续开发时的查阅~

【Android】高版本访问网络失败问题,解决方法整合_android eperm (operation not permitted)-程序员宅基地

文章浏览阅读6.4k次,点赞3次,收藏25次。报错各种问题,真的很烦java.net.SocketException: socket failed: EPERM (Operation not permitted)java.net.SocketException:socket failed:EACCES (Permission denied)java.io.IOException: Cleartext HTTP traffic to 10.0.2.2 not permittedD/Netw at java.net.Socket.creat_android eperm (operation not permitted)

p88 SRC挖掘-拿下CNVD证书开源&闭源&售卖系统_ihsdus.cn-程序员宅基地

文章浏览阅读826次,点赞2次,收藏9次。SRC挖掘-拿下CNVD证书开源&闭源&售卖系统_ihsdus.cn

文章详情页面评论功能添加及实现原理_在页面中输入你的评论,单击“评论”按钮,如果留言区没有评论,则直接添加评论,如果-程序员宅基地

文章浏览阅读9.9k次,点赞4次,收藏44次。1.评论框及评论内容展示模板如下: div id="comment"> h3>strong>发表评论:strong>h3> p>span>标题:span> input type="text" name="" id="comm_title" class="text">p> p>span>内容:span>textarea rows="10"_在页面中输入你的评论,单击“评论”按钮,如果留言区没有评论,则直接添加评论,如果

mitmdump 详解(3)-程序员宅基地

文章浏览阅读1.2k次。一 什么是mitmproxy 抓包工具2 mitmproxy抓包工具介绍pip install mitmproxy检测是否安装成功mitmproxy --version默认监听 8080端口,使用 -p 指定端口3 下载证书linux 中操作mitmproxytab 切换显..._mitm框架

JSTL中的<c:out>_jstl c:out输出有小数点-程序员宅基地

文章浏览阅读1.7k次。一般情况使用c:out和el表达式的效果是一样的,如: hello(使用标签):hello(使用el表达式):${hello}那一般什么时候会使用c:out标签呢?有两种情况: (1)使用缺省值。有的时候某个东西没设值,但要输出缺省值,如果用el表达式什么都不输出,但可以使用c:out输出想要输出的缺省值;如下: hello(default="123"):这样就输出了想要输出的_jstl c:out输出有小数点

随便推点

Python菜鸟晋级04----raw_input() 与 input()的区别_pycharm没有raw input-程序员宅基地

文章浏览阅读2.5k次。raw_input() 与 input()均是python 的内建函数,通过读取控制台的输入与用户实现交互。但他们的功能不尽相同。举两个小例子>>> raw_input_A = raw_input("raw_input: ")raw_input: abc >>> input_A = input("Input: ")Input: abcTraceback (most recent ca_pycharm没有raw input

高通AR增强现实多卡识别和扩展跟踪Unity_imagetarget扩展追踪-程序员宅基地

文章浏览阅读1k次。只需修改ARcamera上的Max Simutaneous Tracked Images 的值就好了。初始是1,默认只能识别一张图。 扩展跟踪是一个更简单的事情,高通把这个功能封装成了ImageTarget的一个属性 Extended Tracking,只要将其勾上就可以了._imagetarget扩展追踪

对于三星手机的手工root方法-程序员宅基地

文章浏览阅读172次。现在很多一键化的root工具,但是仍然有不少的三星手机是无法用全自动方式进行root的,这时候,我们可以选择使用手工的方式进行root,本文章对手工root的一些方法进行一些介绍。   常规方法:..._三星手机用面具root

2021年佛山高考成绩查询,2021年高三佛山一模,看佛山高中排名-程序员宅基地

文章浏览阅读1.7k次。原标题:2021年高三佛山一模,看佛山高中排名2021年1月11日佛山进行了新高考改革后第一次佛山一模考试,作为高考风向标,各高中的成绩具有很大参考意义。结合2018年中考录取分数、2021年佛山一模、2020年佛山一模对佛山56所高中进行简要分析,从而展望2021年高考。 1-10名石门中学稳居第一,佛山一中重夺第二,南海中学增长强劲,顺德一中略显颓势,李兆基中学增长强劲,郑裕彤中学加工能..._佛山国华纪念中学2021年高考成绩

删除并清空应收应付模块 期初数据_应付管理系统怎么清除数据-程序员宅基地

文章浏览阅读1k次。---------查询公司pkselect pk_corp from bd_corp where unitcode='公司编码' 进行删除应收应付模块启用功能 删除2008与2006的行即可(删除行前,要删除期初录入的数据。) select * from sm_createcorp where pk_corp='1025' for update 解锁,删除行,点对勾,然后提前端f10_应付管理系统怎么清除数据

嵌入式固件加密的几种方式-程序员宅基地

文章浏览阅读669次,点赞13次,收藏8次。嵌入式固件加密的几种方式_固件加密

推荐文章

热门文章

相关标签