/*
|
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);
|
}
|
});
|