最近有机会学习了一下RaphaelJS这个js组件,它可以实现类似html5 canvas的图形标签的功能,
什么是RaphaelJS?
插件描述:Raphael 是一个用于在网页中绘制矢量图形的 Javascript 库。它使用 SVG W3C 推荐标准和 VML 作为创建图形的基础,你可以通过 JavaScript 操作 DOM 来轻松创建出各种复杂的柱状图、饼图、曲线图等各种图表,还可以绘制任意形状的图形,可以进行图表或图像的裁剪和旋转等复杂操作。
下面模拟实现一下这样的效果。
其中里面的每个正方形代表一个流程环节,里面的数字代表该环节的工作耗时。环节的位置可以调整,当然默认的环节位置是写死(通过json数据提供)
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="js/raphael-min.js"></script>
<!--<script type="text/javascript" src="js/jquery-1.8.1.min.js"></script>-->
</head>
<body>
<div id="raphael"></div>
<script type="text/javascript">
//整体画布
var paper = Raphael("raphael", 1200, 500);
//环节数据
var jsonA = [{'taskId':201,'name':'任务1','duration':2,'xAxis':100,'yAxis':0},
{'taskId':202,'name':'任务2','duration':3,'xAxis':200,'yAxis':0},
{'taskId':203,'name':'任务3','duration':5,'xAxis':300,'yAxis':0},
{'taskId':204,'name':'任务4','duration':1,'xAxis':200,'yAxis':100},
{'taskId':205,'name':'任务5','duration':1,'xAxis':400,'yAxis':0}];
//环节与环节直接的关系
var jsonB = [{'taskId':201,'pTaskId':202},
{'taskId':202,'pTaskId':203},
{'taskId':201,'pTaskId':204},
{'taskId':203,'pTaskId':205},
{'taskId':204,'pTaskId':205}];
var jsonC =[];
//循环调用执行生成环节
for(var i in jsonA){
createNode(jsonA[i]);//环节绘制
}
function createNode(obj){
var move = function (dx, dy, x, y) {
//console.log(dx, dy, x, y);
var attr = {x: this.xx + dx, y: this.yy + dy};
this.attr(attr);
var lb = this.data("cooperative");
//console.log(this.xx, dx, this.yy, dy)
var attr1 = {x: this.xx+ dx+this.attr("width") / 2, y: this.yy+dy+this.attr("height") / 2};
lb.attr(attr1);
/*重绘指定线路*/
jsonC=[];
for (var i in jsonB) {
if (jsonB[i].taskId==obj.taskId) {
jsonC.push(jsonB[i]);
}
if (jsonB[i].pTaskId==obj.taskId) {
jsonC.push(jsonB[i]);
}
}
for(var i in jsonC){
var pn=paper.getById(jsonC[i].taskId+"_"+jsonC[i].pTaskId);
pn.remove();
drawArr(jsonC[i]);
}
}, start = function (x, y) {
this.attr({opacity: 1});
this.lastX = x;
this.lastY = y;
this.xx = this.attr("x");
this.yy = this.attr("y");
},up = function () {
this.attr({opacity: 0.8});
};
this.text = paper.text(obj.xAxis+25, obj.yAxis+25,obj.duration).attr({
"fill":"#17A9C6", // font-color
"font-size":12, // font size in pixels
"text-anchor":"start",
"font-family":"century gothic" // font family of the text
});
var p =paper.rect(obj.xAxis, obj.yAxis, 50, 50, 10);
p.attr({"fill":"green", stroke:"#666", 'opacity':0.3,"title":obj.name});
p.id=obj.taskId;
p.drag(move, start, up);
//p.dblclick(msg(obj));
p.dblclick(function a() {
jsonC=[];
for (var i in jsonB) {
if (jsonB[i].taskId==obj.taskId) {
// alert("<<<<<<<<"+jsonB[i].taskId);//获得该id下的名字
jsonC.push(jsonB[i]);
}
if (jsonB[i].pTaskId==obj.taskId) {
// alert("<<<<<<<<"+jsonB[i].taskId);//获得该id下的名字
jsonC.push(jsonB[i]);
}
}
console.log(jsonC);
}
);
p.data("cooperative", this.text).toBack();
}
//循环执行
for(var i in jsonB){
drawArr(jsonB[i]);
}
function drawArr(obj) {
var obj1=paper.getById(obj.taskId);
var obj2=paper.getById(obj.pTaskId);
var json1 = getStartEnd(obj1, obj2);
var x2=(json1.end.x-json1.start.x)/2;
var y2=(json1.end.y-json1.start.y)/2;
// paper.path("M "+ json1.start.x +" "+json1.start.y +" h "+x2+" v "+ y2+" h "+x2+" ").attr({
var b=paper.path("M "+ json1.start.x +" "+json1.start.y +" L "+ json1.end.x +" "+json1.end.y +"");
b.attr({
stroke: "blue",
"stroke-width": "2px",
"arrow-end": "classic-wide-long" });
b.id=obj.taskId+"_"+obj.pTaskId;
return obj;
};
function getStartEnd(obj1, obj2) {
var bb1 = obj1.getBBox(),
bb2 = obj2.getBBox();
var p = [
{ x: bb1.x + bb1.width / 2, y: bb1.y - 1 },
{ x: bb1.x + bb1.width / 2, y: bb1.y + bb1.height + 1 },
{ x: bb1.x - 1, y: bb1.y + bb1.height / 2 },
{ x: bb1.x + bb1.width + 1, y: bb1.y + bb1.height / 2 },
{ x: bb2.x + bb2.width / 2, y: bb2.y - 1 },
{ x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height + 1 },
{ x: bb2.x - 1, y: bb2.y + bb2.height / 2 },
{ x: bb2.x + bb2.width + 1, y: bb2.y + bb2.height / 2 }
];
var d = {}, dis = [];
for (var i = 0; i < 4; i++) {
for (var j = 4; j < 8; j++) {
var dx = Math.abs(p[i].x - p[j].x),
dy = Math.abs(p[i].y - p[j].y);
if (
(i == j - 4) ||
(((i != 3 && j != 6) || p[i].x < p[j].x) &&
((i != 2 && j != 7) || p[i].x > p[j].x) &&
((i != 0 && j != 5) || p[i].y > p[j].y) &&
((i != 1 && j != 4) || p[i].y < p[j].y))
) {
dis.push(dx + dy);
d[dis[dis.length - 1]] = [i, j];
}
}
}
if (dis.length == 0) {
var res = [0, 4];
} else {
res = d[Math.min.apply(Math, dis)];
}
var result = {};
result.start = {};
result.end = {};
result.start.x = p[res[0]].x;
result.start.y = p[res[0]].y;
result.end.x = p[res[1]].x;
result.end.y = p[res[1]].y;
return result;
}
function msg(obj)
{
alert(obj.taskId) ;
for (var i in jsonB) {
if ([i].taskId==this.id) {
alert("<<<<<<<<"+[i].taskId);//获得该id下的名字
}
}
}
</script>
</body>
</html>
以上代码可以运行的,应该是做工作流组件或者显示流程图的必备基础。?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。