/* Graph类来管理整个流程图,包括所有部件、上下文菜单等等都由Graph来统一管理和调度 */ var HH = {}; HH.Libra = {}; HH.Libra.Graph = function (type, options) { var graph = this, activities = {}, transitions = {}; graph.contextMenuItems = []; // graph.contextMenuItems.push(new HH.Libra.ContextMenuExecuteItem({ text: '新增文本', url: this })); var zrenderInstance, contextMenuContainer; this.type = type; //1. 新增元素 this.addEventListener = function (name, handler) { this.addEventListener(name, handler); }; this.addActivity = function (activity) { activity.graph = graph; activities[activity.id] = { object: activity }; }; //1. 新增元素 this.delActivity = function (activity) { activity.graph = graph; activities[activity.id] = { object: null }; }; // 2. 更新元素 this.UpdateActivity = function (id, activity) { activity.graph = graph; activities[id] = { object: activity }; }; //3.根据ID,得到元素实体 this.getActivity = function (id) { return activities[id].object; }; //4.获取所有元素的集合 this.getAllActivity = function () { return activities; }; //5.线条对象 this.addTransition = function (transition) { transition.graph = graph; transitions[transition.id] = { object: transition }; }; //6.更新元素视图 function modElements(shapes) { shapes.each(function (shape) { zrenderInstance.modElement(shape); }); return shapes; } var dragingActivity = null; // 当前正在拖放的节点 // 活动节点拖放开始 this.onActivityDragStart = function (activity) { dragingActivity = activity; }; // 活动节点拖放结束 this.onActivityDragEnd = function () { if (dragingActivity) refreshActivityTransitions(dragingActivity); dragingActivity = null; }; //单元素实时刷新 this.refreshActivity = function (shape) { zrenderInstance.modElement(shape); } // 拖动过程处理 function zrenderInstanceOnMouseMove() { if (dragingActivity != null) refreshActivityTransitions(dragingActivity); } function onClickTest(obj) { // console.log(obj); if (obj.target == undefined) { addText(obj.event.offsetX, obj.event.offsetY); } } // 刷新活动相关的所有连接弧 function refreshActivityTransitions(activity) { var activityId = activity.id; for (var key in transitions) { var transition = transitions[key].object; if (transition.from === activityId || transition.to == activityId) { zrenderInstance.refreshShapes(modElements(transition.refresh(graph))); } } } // 当前选中的部件 var selectedUnit = null; this.onUnitSelect = function (unit) { if (selectedUnit) zrenderInstance.refreshShapes(modElements(selectedUnit.unselect(graph))); zrenderInstance.refreshShapes(modElements(unit.select(graph))); selectedUnit = unit; }; //记录当前鼠标在哪个部件上,可以用来生成上下文相关菜单 var currentUnit = null; this.onUnitMouseOver = function (unit) { currentUnit = unit; }; this.onUnitMouseOut = function (unit) { if (currentUnit === unit) currentUnit = null; }; //上下文菜单事件响应 function onContextMenu(event) { Event.stop(event); if (currentUnit) { currentUnit.showContextMenu(event, contextMenuContainer, graph); } } //增加新的对象元素 this.addShape = function (shape) { zrenderInstance.addShape(shape); }; //删除对象元素 this.delShape = function (shape) { zrenderInstance.delShape(shape); contextMenuContainer.hide(); }; // 增加新的对象元素 this.modShape = function (_activity, x, y) { // 更新元素的坐标信息 //alert(_activity.id) //alert(x) //alert(y) for (var key in activities) { if (activities[key].object != null) { if (activities[key].object.id == _activity.id) { activities[key].object.position.x = x; activities[key].object.position.y = y; // alert(_activity.position.y); break; } } } }; // 初始化 this.init = function (widthstr, heightstr) { if (widthstr == "" || widthstr == null || widthstr == undefined) widthstr = "500"; if (heightstr == "" || heightstr == null || heightstr == undefined) heightstr = "350"; var canvasElement = options.canvas.element; try { canvasElement.empty(); } catch (exception) { window.location.reload(); return false; } //canvasElement.setStyle({ height: document.viewport.getHeight() + 'px' }); canvasElement.setStyle({ height: heightstr + 'px', width: widthstr + 'px' }); zrenderInstance = graph.type.zrender.init(document.getElementById(canvasElement.identify())); // 创建上下文菜单容器 contextMenuContainer = new Element('div', { 'class': 'context-menu' }); contextMenuContainer.hide(); document.body.appendChild(contextMenuContainer); Event.observe(contextMenuContainer, 'mouseout', function (event) { // 关闭时,应判断鼠标是否已经移出菜单容器 if (!Position.within(contextMenuContainer, event.clientX, event.clientY)) { contextMenuContainer.hide(); } }); zrenderInstance.on('dblclick', onClickTest); //alert(1); // 侦听拖动过程 zrenderInstance.on('mousemove', zrenderInstanceOnMouseMove); // 上下文菜单 Event.observe(document, 'contextmenu', onContextMenu); }; // 呈现或刷新呈现 this.render = function () { var canvasElement = options.canvas.element; canvasElement.setStyle({ height: document.viewport.getHeight() + 'px' }); zrenderInstance.render(); }; //获取二进制流 this.GetImgUrl = function () { var ShapeURL = zrenderInstance.toDataURL(); return ShapeURL; }; }; /* * 部件(包括活动和连接弧): 定义了Unit(部件基类),所有的部件都继承自这个基类 */ HH.Libra.Unit = Class.create({ id: null, title: null, graph: null, // 当前是否被选中 selected: false, // 上下文菜单项集合 contextMenuItems: [], initialize: function (options) { var _this = this; _this.id = options.id; _this.title = options.title; }, createShapeOptions: function () { var _this = this; return { hoverable: true, clickable: true, onclick: function (params) { // 选中并高亮 _this.graph.onUnitSelect(_this); }, onmouseover: function (params) { _this.graph.onUnitMouseOver(_this); }, onmouseout: function (params) { _this.graph.onUnitMouseOut(_this); } }; }, addTo: function (graph) { }, // 刷新显示 refresh: function (graph) { return []; }, // 选中 select: function (graph) { this.selected = true; return this.refresh(graph); }, // 取消选中 unselect: function (graph) { this.selected = false; return this.refresh(graph); }, // 显示上下文菜单 showContextMenu: function (event, container, graph) { container.hide(); container.innerHTML = ''; var ul = new Element('ul'); container.appendChild(ul); this.buildContextMenuItems(ul, graph); // 加偏移,让鼠标位于菜单内 var offset = -5; var rightEdge = document.body.clientWidth - event.clientX; var bottomEdge = document.body.clientHeight - event.clientY; if (rightEdge < container.offsetWidth) container.style.left = document.body.scrollLeft + event.clientX - container.offsetWidth + offset; else container.style.left = document.body.scrollLeft + event.clientX + offset; if (bottomEdge < container.offsetHeight) container.style.top = document.body.scrollTop + event.clientY - container.offsetHeight + offset; else container.style.top = document.body.scrollTop + event.clientY + offset; container.show(); }, // 创建上下文菜单项 buildContextMenuItems: function (container, graph) { var unit = this; unit.contextMenuItems.each(function (item) { item.addTo(container); }); } }); /* * 上下文菜单项基类 */ HH.Libra.ContextMenuItem = Class.create({ options: null, // 菜单文本 text: null, initialize: function (options) { this.options = options; this.text = options.text; }, // addTo: function (container) { var _this = this; var li = new Element('li'); container.appendChild(li); var a = new Element('a', { href: 'javascript:;' }); li.appendChild(a); a.insert(_this.text); Event.observe(a, 'click', function () { _this.onClick(); }); } }); /* * 上下文菜单项(直接执行) */ HH.Libra.ContextMenuExecuteItem = Class.create(HH.Libra.ContextMenuItem, { url: null, initialize: function ($super, options) { $super(options); this.url = options.url;//此处传递的是右键的对象 }, onClick: function () { var shape = this.url.shape; graph.delShape(shape); graph.delActivity(this.url); // this.url.shape = shape; var tagActivities = graph.getAllActivity(); var has = false; var delHot =this.url.shape.style.text; for (var key in tagActivities) { if (tagActivities[key].object != null) { var hotname = tagActivities[key].object.shape.style.text; if(hotname==delHot) has=true; } } //左侧有重复热点情况下,删除其中一个热点时,需要保持右侧列表剩余热点的行“已存在”颜色 if(!has) changeRowColor(delHot, 0); } });