`
bigablecat
  • 浏览: 5456 次
文章分类
社区版块
存档分类
最新评论

(原创) 工作流程图的树形展示-使用qunee插件实现

阅读更多

        实际工作中遇到一个问题,在html页面以树形节点的方式展示工作流程图。
        echarts2的树形图可以实现,但是页面样式不够灵活。架构师从网上找来qunee插件,大致能满足客户要求。
        qunee是"一套基于HTML5的网络图组件",详情可以去官网http://qunee.com查看。

        这里只介绍如何用qunee来实现树形图。

        在qunee的demo里找到
        Treelayouter Demo (http://demo.qunee.com/#TreeLayouter Demo)

        和Work Flow Demo中的

        development guide (http://demo.qunee.com/#Development Guide)
        本例需要将两者的效果结合。

        流程图结构如下(局部放大):

        

        流程图结构如下(完整):

       

 

        节点数据是json格式,举例如下:

var test = {
	"children": [{
		"children": [{
			"children": null,
			"codeDescription": "2级节点",
			"nodeLevel": 2,
			"nodeName": "test1_1",
			"nodeOrder": 0
		}],
		"codeDescription": "1级节点",
		"nodeLevel": 1,
		"nodeName": "test1",
		"nodeOrder": 0
	}],
	"codeDescription": "根节点",
	"nodeLevel": 0,
	"nodeName": "test0",
	"nodeOrder": 0
}
 

 

        完整的html代码,每一部分都有较详细的注释。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Qunee Treelayout Demo 20160801 update</title>
<!--引入qunee插件的js文件-->
<script src="./qunee-min.js"></script>
<!--引入json数据 -->
<script src="./dataserver1.js"></script>


</head>
<body>
	<div id="root_box"
		style="width: 1000px; height: 600px; margin: auto; border: solid 1px #2898E0;"></div>

	<!-- <script type="text/javascript" src="work-process.js"></script> -->
	<script type="text/javascript">
		//指定一个div元素,初始化qunee画布
		var graph = new Q.Graph("root_box");
		//graph.originAtCenter为false时表示设置左上角为坐标原点
		graph.originAtCenter = false;
		
		//创建一个数组存放所有的子孙节点
		var allChildren = [];
		
		//用来记录最大层级
		var maxLevel = 1;
		
		//递归函数,将传入的数据创建成树形图的节点
		function loadDatas(json, parent, layoutType) {
			json.forEach(function(data) {
				//获取最深的层级
				if (data.nodeLevel > maxLevel) {
					maxLevel = data.nodeLevel;
				}
				
				var node = createNode(data.nodeName, parent, layoutType);
				allChildren.push(node);

				if (layoutType == Q.Consts.LAYOUT_TYPE_EVEN_VERTICAL) {
					node.vGap = 20; //设置孩子布局的垂直间距,hGap为水平间距
				}
				
				//递归创建所有节点
				if (data.children) {
					loadDatas(data.children, node, Q.Consts.LAYOUT_TYPE_EVEN_VERTICAL);
				}
			});
		}
		
		//传入根节点(根节点属性中包含了所有子孙节点),生成树形图
		function init(rootNode) {
			//建立一个数组用于存放主流程节点
			var nodeL1Arr = [];

			//在本demo中,rootNode根节点不展示,根节点下的第一级节点作为主流程节点
			if (rootNode.children) {
				rootNode.children.forEach(function(nodeL1) {
					var newNode = createStep(nodeL1.nodeName);
					nodeL1Arr.push(newNode);
					if (nodeL1.children) {
						loadDatas(nodeL1.children, newNode, Q.Consts.LAYOUT_TYPE_EVEN_VERTICAL);
					}
				});
			} else {
				var newNode = createNode("没有流程信息");
			}
			//设置树形图布局
			setLayout(nodeL1Arr);
		}

		//创建单个流程节点
		function createNode(name, from, layoutType) {
			var node = graph.createText(name);
			node.setStyle(Q.Styles.LABEL_BORDER, 1);
			node.setStyle(Q.Styles.LABEL_BORDER_STYLE, "#1D4876");
			node.setStyle(Q.Styles.LABEL_FONT_SIZE, 16);
			node.setStyle(Q.Styles.LABEL_PADDING, 5);
			node.setStyle(Q.Styles.LABEL_SIZE, new Q.Size(70, 35));
			node.setStyle(Q.Styles.LABEL_BACKGROUND_COLOR, "#FFF");
			//节点是否可见
			node.visible = true;
			//节点是否能用鼠标拖动,false为不能拖动
			node.movable = false
			node.layoutType = layoutType;
			
			if (from) {
				node.parent = from;
				node.host = from;
			}
			
			if (from instanceof Q.Node) {
				//创建连线
				var nodeEdge = graph.createEdge(from, node);
				if (from.layoutType == Q.Consts.LAYOUT_TYPE_EVEN_VERTICAL) {
					nodeEdge.edgeType = Q.Consts.EDGE_TYPE_VERTICAL_HORIZONTAL;
				} else {
					nodeEdge.edgeType = Q.Consts.EDGE_TYPE_ORTHOGONAL;
				}
			}
			return node;
		}

		//创建主流程节点
		function createStep(label) {
			var node = graph.createText(label);
			node.setStyle(Q.Styles.LABEL_BORDER, 1);
			node.setStyle(Q.Styles.LABEL_BACKGROUND_COLOR, "#FFF");
			node.setStyle(Q.Styles.LABEL_BORDER_STYLE, "#1D4876");
			node.setStyle(Q.Styles.LABEL_FONT_SIZE, 20);
			node.setStyle(Q.Styles.LABEL_SIZE, new Q.Size(120, 50));
			node.visible = true;
			//节点是否能用鼠标拖动,false为不能拖动
			node.movable = false
			node.layoutType = Q.Consts.LAYOUT_TYPE_EVEN_VERTICAL;
			//node.vGap = 30;//设置孩子布局的垂直间距,hGap为水平间距

			return node;
		}

		//创建连线
		function createEdge(from, to, lineWidth, dash) {
			var edge = graph.createEdge(from, to);
			edge.setStyle(Q.Styles.EDGE_WIDTH, lineWidth || 3);
			edge.setStyle(Q.Styles.EDGE_COLOR, "#1D4876");
			if (dash) {
				edge.setStyle(Q.Styles.EDGE_LINE_DASH, [ 10, 10 ]);
			}
			return edge;
		}

		//调整树状图各分支的位置,形成美观的对称结构
		function moveNodes() {
			var rightBound = 0; //节点右边界
			var rightX = 0 //用于记录最右侧节点的横坐标
			var rightElementName; //边界节点的名称
			var prevElement; //前一主流程
			var dx = 20 * maxLevel; //移动基数20乘以获取的最大层级
			graph.graphModel.forEachByTopoBreadthFirstSearch(function(element) {
				if (element instanceof Q.Node) {
					//每次移动,整个父子节点链的线条都会移动
					graph.moveElements([ element ], dx, 0);
					
					if (!element.parent) {
						//如果节点横坐标小于上一节点的右边界,则移动节点,避免重合
						if (element.x < rightBound) {
							graph.moveElements([ element ], rightBound - element.x, 0);
						}

						//如果主流程没有子流程,需要单独移动固定距离dx,否则连线会非常短
						if (prevElement && !prevElement.hasChildren()) {
							graph.moveElements([ element ], dx, 0);
						}
						prevElement = element;
					}

					if (element.x >= rightX) {
						//更新最右侧节点横坐标的值
						rightX = element.x;
						
						//rightX为最右侧节点的横坐标,加上该节点边框的宽度,得到最右侧边界的位置
						rightBound = rightX + graph.getUIBounds(element).width;
						
						//获取最右侧节点的名称,用于打印测试
						rightElementName = element.name;
					}
				}
			});
		}

		graph.visibleFilter = function(node) {
			return node.visible !== false;
		}

		var nodeClicked;
		// 设置点击事件
		graph.onclick = function(evt) {
			nodeClicked = evt.getData();

			if (!nodeClicked) {
				Q.forEach(allChildren, function(p) {
					p.visible = true;
					p.invalidateVisibility();
				})
				graph.invalidate();
				return;
			}

			//点击主流程节点,只显示子孙节点,隐藏其他节点
			/* if (!nodeClicked.parent && !nodeClicked.from) {
				Q.log(nodeClicked);
				Q.forEach(allChildren, function(p) {
					var visible = p.isDescendantOf(nodeClicked);
					p.visible = visible;
					p.invalidateVisibility();
				})
				graph.invalidate();
			} */
			
			//点击主流程节点,显示或隐藏其子孙节点
			if (!nodeClicked.parent && !nodeClicked.from&&nodeClicked.hasChildren()) {
				setAllChildren(nodeClicked);
				graph.invalidate();
			} 
		}
		
		//显示或隐藏子孙节点的函数
		function setAllChildren(parent){
			Q.forEach(parent.children, function(p) {
				p.visible = !p.visible;
				p.invalidateVisibility();
				if(p.hasChildren()){
					setAllChildren(p);
				}
			})
		}
		
		//设置树形图布局
		var layouter = new Q.TreeLayouter(graph);
		function setLayout(nodeL1Arr) {
			layouter.layoutType = Q.Consts.LAYOUT_TYPE_EVEN_HORIZONTAL;
			//qunee新特性,节点连线能够等长排列
			layouter.parentChildrenDirection = Q.Consts.DIRECTION_BOTTOM_RIGHT;
			layouter.doLayout({
				callback : function() {
					//graph.moveToCenter(1);
					graph.zoomToOverview();
					moveNodes();
					if (nodeL1Arr.length > 0) {
						var index = 0
						nodeL1Arr.forEach(function(obj) {
							if (index > 0) {
								createEdge(nodeL1Arr[index - 1], obj);
							}
							index++;
						});
					}
				}
			});
		}
		init(test);
	</script>
</body>
</html>

 

 附件有完整的代码和数据供测试用。

  • 大小: 28 KB
  • 大小: 24 KB
分享到:
评论

相关推荐

    使用qunee插件实现html工作流程图

    本文将深入探讨如何使用Qunee插件来实现HTML工作流程图的创建,以及它相较于Echarts2树形图的优势。 Qunee是一款强大的JavaScript库,它提供了一套全面的UI组件和丰富的图形绘制功能,包括工作流程图的绘制。与...

    flowable-bpmn---idea的插件--超级好用

    Flowable BPMN是一款开源的工作流引擎,它基于BPMN 2.0标准,提供了强大的业务流程管理和工作流实现能力。对于开发人员来说,能够在一个高效、直观的环境中设计和管理流程模型是至关重要的,而IntelliJ IDEA作为Java...

    基于dagre-d3自动画流程图的demo

    在当今的数据可视化领域,流程图是一种极为重要的工具,它能够清晰地展示系统、程序或工作流程的步骤和关系。本篇文章将深入探讨一个基于dagre-d3库的流程图Demo,这个Demo采用JavaScript和HTML技术,使得流程图的...

    Qunee for Html 兼容 Vue 版

    Qunee 是基于使用HTML5 Canvas技术,绘制清新、流畅的网络图,可用于社交网络图、拓扑图、流程图、地图等需求, JS组件封装,藏繁琐于简洁,轻松构建优雅的互联网应用与企业应用,让数据的在线可视化变得容易!...

    winform做的流程图编辑器-GDI+绘图技术,很好用

    WinForm流程图编辑器是基于C#编程语言和GDI+图形库开发的一款高效、实用的工具,主要用于创建和编辑各种流程图。GDI+(Graphics Device Interface Plus)是.NET Framework提供的一种强大的图形处理能力,使得开发者...

    支持layui树编辑的插件,也可以作为树形表格

    在IT领域,尤其是在Web...总的来说,这个“支持layui树编辑的插件”是一个强大且易用的工具,它为layui用户提供了树形结构编辑的功能,简化了开发流程,提高了开发效率,特别适合那些需要处理大量层次数据的Web应用。

    流程图转PAD,N-S图和伪码(软件工程)

    PAD图使用树形结构来表示程序的不同部分,非常适合于描述嵌套的控制结构。 ##### 2. 给定流程图的PAD图转换 接下来,我们将基于给定的流程图绘制其PAD图。具体的PAD图如下所示: ``` [流程开始] | +-- [S2] | | | ...

    web流程图动态绘制-使用raphael

    在给定的博客文章中,作者详细介绍了如何使用Raphael实现流程图的步骤。文章可能包含了以下内容: 1. **初始化Raphael画布**:在HTML中创建一个div元素,然后在JavaScript中使用`Raphael('div_id', width, height)`...

    JS 流程图 流程图插件

     多系统兼容性、可移植性:由于只包括前台UI,因此二次开发者可很方便将本插件用在任何一种需要流程图的B/S系统应用上,流程图的详细实现逻辑完全交于后台程序开发者自己实现;对于后台,只要能返回/接收能被本插件...

    jQuery+css 流程图插件

    在网页开发中,流程图是一种常见且重要的可视化工具,用于展示逻辑步骤或工作流程。"jQuery+css 实现的单分支流程图插件"是一个利用JavaScript库jQuery和CSS样式来创建简单、动态流程图的解决方案。这种插件特别适合...

    jQuery工作流程步骤进度插件

    在网页开发中,为了清晰地展示复杂的步骤流程,如用户注册、购物流程或者项目审批等,工作流程步骤进度插件显得尤为重要。ystep是一款基于jQuery的高效插件,它能帮助开发者轻松创建具有视觉吸引力的步骤进度条,...

    基于vue2.x+antdesign+antv x6实现的流程图编辑器.zip

    在本项目中,AntV X6被用来实现流程图的绘制和编辑功能。 Vue2.x与Ant Design Vue的结合,使得开发者能够利用Vue的声明式渲染和组件化特性,结合Ant Design Vue的UI组件,快速搭建出用户界面。而AntV X6的引入,则...

    myflow流程图绘制插件(js版)

    本文将深入探讨myflow插件的特性、使用方法以及如何将其与后端程序集成,以实现流程图的可视化操作。 首先,myflow的核心功能在于其强大的绘图能力。通过简单的API调用,开发者可以轻松添加、删除、移动和连接流程...

    antv-流程图,一个简易的基于antv x6实现的流程图绘制

    antv流程图是一款基于antv x6框架的轻量级流程图绘制工具,适用于Web端进行灵活、可交互的流程图设计。antv是阿里巴巴开源的一系列数据可视化库,而x6则是antv中的一个核心组件,专注于提供强大的图形编辑和绘图能力...

    bootstrap treeview可搜索下拉树形

    9. **运行图片**:可能包含的是应用运行时的截图,展示了功能的实现效果,帮助理解整个系统的外观和工作流程。 为了实现这个功能,开发者需要熟悉jQuery、Bootstrap的基本用法,理解如何通过JavaScript与后端接口...

    基于HTML5流程图绘制代码

    - **业务流程管理**:在企业系统中,流程图可以清晰地展示工作流,帮助管理者理解和优化业务流程。 - **网络拓扑**:在IT领域,拓扑图用于可视化网络设备和连接,便于网络管理和故障排查。 - **软件设计**:在...

    .NET 工作流程图 WinForm gdi+流程图 C#版流程图绘制 拖动即时刷新 0分下载

    本资源提供的是一套基于C#和GDI+实现的WinForm流程图绘制代码,它允许用户在界面上动态拖动和即时刷新流程图元素,非常适合用于创建自定义的工作流或流程设计工具。 GDI+(Graphics Device Interface Plus)是.NET ...

    struts+ibatis实现树形展示

    在Web应用中,可以使用JavaScript库如jQuery UI、AngularJS的ngTree或React的react-treebeard等来实现前端的树形展示。这些库提供了丰富的API和样式,可以轻松地处理节点的点击、展开、折叠等交互。 4. **组件设计*...

    vuetasknode是一个基于Vue的任务节点图绘制插件

    该插件适用于项目管理、工作流展示、决策树等场景,帮助用户直观地理解复杂的业务流程。 ### 安装与引入 要在Vue项目中使用`Vue-task-node`,首先需要通过npm进行安装: ```bash npm install vue-task-node --...

    Butterfly(基于JavaScript_React_Vue2的流程图组件).zip

    这个组件为开发者提供了构建复杂流程图、工作流和图表的强大工具,旨在提高用户体验并简化开发流程。 在JavaScript的世界里,Butterfly扮演着重要的角色,因为它允许开发者在Web应用中创建动态和交互式的流程图。...

Global site tag (gtag.js) - Google Analytics