Web流程图绘制使用raphael

林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

摘要:本文要实现一个流程图的绘制,最终的目标是实现流程图的自动绘制,并可进行操作,直接点击流程图上对应的方框就可以让后台跑相应的程序。

一、插件介绍

1、图形绘制raphael

其中图形绘制使用了raphael,下载地址:http://raphaeljs.com,它的功能非常强大。

中文帮助教程:http://html5css3webapp.com/raphaelApi.htm#Paper.text

其中有一些DEMO如下:

2、鼠标右键菜单栏弹出smartMenu

教程及下载地址: http://www.cnblogs.com/ATree/archive/2011/06/30/jQuery-smartMenu-javascript.html

3、字体大小变化利器插件jquery.fontFlex

随着页面的放大或者缩小,字体也跟随着放大或者缩小。当然,可以设置一个最大值,一个中间值和一个最小值。此效果多半应用于响应式页面中,或者需要适用多版本终端浏览器的页面中

二、使用

1、首先,来看看要实现的流程图的样子。

2、代码实现

这里其实就是把上面的插件都引用进来,然后其它的就是用JS不断画椭圆、直线箭头、方框等。

画好之后,添加文字,给方框添加右键点击事件

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="smartMenu.css" rel="stylesheet">
<script src="jquery-1.8.1.min.js"></script>
<script src="jQuery.fontFlex.js"></script>
<script src="jquery-smartMenu.js"></script>
<script src="raphael-min.js"></script>
<script src="jQuery.fontFlex.js"></script>

<style>
body div{ background:#333333;}
#paperBox1{ background:#70AD47;}
.exp1 {color:#FFFFFF;line-height:80px;}
rect{cursor:pointer}
text{cursor:pointer}
#spinner{ position:absolute;
left:10px;top:10px;}
</style>
</head>
<body>
	<div>
		<h1 class="exp1">
			<center>任务计划流程</center>
		</h1>
		<!-- 在这上面画图 -->
		<div id="paper">
		<div id="paperBox1"></div>
		<div id="spinner"></div>
		</div>
	</div>
</body>
<script type="text/javascript">
$(‘h1‘).fontFlex(10, 120, 40);//字体大小自适应
console.log(Raphael.svg);//查看是否支持Raphael,true为支持
var window_w = $(window).width();//浏览器窗口可见宽度
var window_h = $(window).height();////浏览器窗口可见高度
var rect_w = window_w / 8;//矩形的宽
var rect_h = window_h / 20;//矩形的高
var rect_r = rect_w / 15;//矩形圆角
var arrow_h = 35; // 箭头高
console.log(window_w);
console.log(window_h);
console.log(rect_w);
console.log(rect_h);
//创建一个画布
var paper = new Raphael("paper",window_w,window_h + 200);
//直线箭头
var arrow1 = paper.path("M21.786,12.876l7.556-4.363l-7.556-4.363v2.598H2.813v3.5h18.973V12.876z" ).attr({fill: "#5B9BD5", stroke: "none"});
var arrow2 = arrow1.clone();
var arrow3_1_1 = arrow1.clone();
var arrow3_1_2 = arrow1.clone();

var arrow3_2_1 = arrow1.clone();
var arrow3_2_2 = arrow1.clone();
var arrow3_2_3 = arrow1.clone();

var arrow3_3_1 = arrow1.clone();
var arrow3_3_2 = arrow1.clone();
var arrow3_3_3 = arrow1.clone();

var arrow3_4_1 = arrow1.clone();
var arrow3_4_2 = arrow1.clone();
var arrow3_4_3 = arrow1.clone();

var arrow3 = arrow1.clone();
var arrow4 = arrow1.clone();
var arrow5 = arrow1.clone();
var arrow6 = arrow1.clone();

var attr = {
                fill: "#70AD47",//填充
                stroke: "none",//边框
                "stroke-width": 1,
                "stroke-linejoin": "round"
            };
//画圆角矩形
var rect1 = paper.rect((window_w-rect_w)*0.5,0,rect_w,rect_h,rect_r).attr(attr);
var rect2 = moveRectToRectDown(paper,rect1);

var rect3_1_1 = paper.rect((window_w-rect_w)*0.2,( arrow_h  + rect_h ) * 2.5,rect_w,rect_h,rect_r).attr(attr);
var rect3_1_2 = moveRectToRectDown(paper,rect3_1_1);
var rect3_1_3 = moveRectToRectDown(paper,rect3_1_2);

var rect3_2_1 = paper.rect((window_w-rect_w)*0.4 ,( arrow_h  + rect_h ) * 2.5,rect_w,rect_h,rect_r).attr(attr);
var rect3_2_2 = moveRectToRectDown(paper,rect3_2_1);
var rect3_2_3 = moveRectToRectDown(paper,rect3_2_2);
var rect3_2_4 = moveRectToRectDown(paper,rect3_2_3);

 var rect3_3_1 = paper.rect(window_w-(window_w-rect_w)*0.4-rect_w,( arrow_h  + rect_h ) * 2.5,rect_w,rect_h,rect_r).attr(attr);
 var rect3_3_2 = moveRectToRectDown(paper,rect3_3_1);
 var rect3_3_3 = moveRectToRectDown(paper,rect3_3_2);
 var rect3_3_4 = moveRectToRectDown(paper,rect3_3_3);

 var rect3_4_1 = paper.rect(window_w-(window_w-rect_w)*0.2-rect_w,( arrow_h  + rect_h ) * 2.5,rect_w,rect_h,rect_r).attr(attr);
 var rect3_4_2 = moveRectToRectDown(paper,rect3_4_1);
 var rect3_4_3 = moveRectToRectDown(paper,rect3_4_2);
 var rect3_4_4 = moveRectToRectDown(paper,rect3_4_3);

//文字描述
insertRectText(paper,rect1,"1.等待激活");
insertRectText(paper,rect2,"2.日切");
insertRectText(paper,rect3_1_1,"下载文件信息信息");

//直接箭头移动
moveArrowToRectDown(rect1,arrow1,90,2,null,null);
moveArrowToRectDown(rect2,arrow2,90,2,null,null);

moveArrowToRectDown(rect3_1_1,arrow3_1_1,90,2,null,null);
moveArrowToRectDown(rect3_1_2,arrow3_1_2,90,2,null,null);

moveArrowToRectDown(rect3_2_1,arrow3_2_1,90,2,null,null);
//moveArrowToRectDown(rect3_2_2,arrow3_2_2,90,2,null);
moveArrowToRectDown(rect3_2_3,arrow3_2_3,90,2,null,null);

moveArrowToRectDown(rect3_3_1,arrow3_3_1,90,2,null,null);
moveArrowToRectDown(rect3_3_2,arrow3_3_2,90,2,null,null);
moveArrowToRectDown(rect3_3_3,arrow3_3_3,90,2,null,null);

moveArrowToRectDown(rect3_4_1,arrow3_4_1,90,2,null,null);
moveArrowToRectDown(rect3_4_2,arrow3_4_2,90,2,null,null);
moveArrowToRectDown(rect3_4_3,arrow3_4_3,90,2,null,null);
//画边框
var rectbox3 = drawRectToRect(paper,rect3_1_1,rect3_4_4,( arrow_h  + rect_h ) * 0.5);
var rectbox3_1 = drawRectToRect(paper,rect3_1_1,rect3_1_3,( arrow_h  + rect_h ) * 0.15);
var rectbox3_2_1 = drawRectToRect(paper,rect3_2_1,rect3_2_2,( arrow_h  + rect_h ) * 0.05);
var rectbox3_2_2 = drawRectToRect(paper,rect3_2_3,rect3_2_4,( arrow_h  + rect_h ) * 0.05);
var rectbox3_3 = drawRectToRect(paper,rect3_3_1,rect3_3_4,( arrow_h  + rect_h ) * 0.15);

//对应从积分计算到完
moveArrowToRectDown(rectbox3,arrow3,90,2,null,18);//最大外框下方箭头
moveArrowToRectDown(rectbox3_2_1,arrow3_2_2,90,1.1,-8,5);
var xx = Math.round($(rectbox3.node).attr("y"))*1+$(rectbox3.node).attr("height")*1+15+arrow_h;
console.log(xx);
var rect4 = paper.rect((window_w-rect_w)*0.5, xx ,rect_w,rect_h,rect_r).attr(attr);
moveArrowToRectDown(rect4,arrow4,90,2,null,null);
var rect5_1 = paper.rect((window_w-rect_w)*0.4 ,( arrow_h  + rect_h ) * 8.5 ,rect_w,rect_h,rect_r).attr(attr);
var rect5_2 = paper.rect(window_w-(window_w-rect_w)*0.4-rect_w,( arrow_h  + rect_h ) * 8.5,rect_w,rect_h,rect_r).attr(attr);
var rectbox5 = drawRectToRect(paper,rect5_1,rect5_2,( arrow_h  + rect_h ) * 0.3);
moveArrowToRectDown(rectbox5,arrow5,90,2,null,18);//外框下方箭头
var rect6 = paper.rect((window_w-rect_w)*0.5 ,( arrow_h  + rect_h ) * 10 ,rect_w,rect_h,rect_r).attr(attr);
moveArrowToRectDown(rect6,arrow6,90,2,null,null);//外框下方箭头
var rect6 = paper.rect((window_w-rect_w)*0.5 ,( arrow_h  + rect_h ) * 11 ,rect_w,rect_h,rect_r).attr(attr);

//arrow2.transform("t650,300r90s4")
//给矩形增加居中的文字
function insertRectText(root,rectangle,str){
	var x = Math.round($(rectangle.node).attr("x"));
	var y = Math.round($(rectangle.node).attr("y"));
	var w = $(rectangle.node).attr("width");
	var h = $(rectangle.node).attr("height");
	var textStr = root.text(x + w / 2,y + h / 2,str).attr({fill:"#FFFFFF"});
	textStr.attr({
         "fill":"#FFFFFF",
         "font-size":"15px",
     });
	rectangle.data("cooperative", textStr);
}
//将箭头移动到矩形下方
function moveArrowToRectDown(rectangle,arrowbox,angle,scale,offset_x,offset_y){
	var angle = angle == null ?0:angle; //默认旋转90度
	var scale = scale == null ?1:scale;
	var offset_y =offset_y ==null?0:offset_y;
	var offset_x =offset_x ==null?0:offset_x;
	var x = Math.round($(rectangle.node).attr("x"));
	var y = Math.round($(rectangle.node).attr("y"));
	var w = $(rectangle.node).attr("width");
	var h = $(rectangle.node).attr("height");
	console.log("x=" + x);
	console.log("y=" + y);
	console.log("w=" + w);
	console.log("h=" + h);
	var xNew = x + w*0.5 -8*scale + offset_x;
	var yNew = y + h*1 + offset_y;
	var pos = "t"+ xNew + "," + yNew + ‘r‘ + angle + ‘s‘ + scale;
	console.log(pos);
	arrowbox.transform(pos);
}

//将一个矩形移动到另一个矩形下方
function moveRectToRectDown(root,rectangle){
	var x = Math.round($(rectangle.node).attr("x"));
	var y = Math.round($(rectangle.node).attr("y"));
	var w = Math.round($(rectangle.node).attr("width"));
	var h = Math.round($(rectangle.node).attr("height"));
    var r = $(rect1.node).attr("rx");
	var rectNew = root.rect(x,y + h + arrow_h,w,h,r).attr(attr);
	return rectNew;
}

function drawRectToRect(root,rectangle1,rectangle2,offset){
	var x1 = Math.round($(rectangle1.node).attr("x"));
	var y1 = Math.round($(rectangle1.node).attr("y"));

	var x2 = Math.round($(rectangle2.node).attr("x"));
	var y2 = Math.round($(rectangle2.node).attr("y"));
	var w2 = Math.round($(rectangle2.node).attr("width"));
	var h2 = Math.round($(rectangle2.node).attr("height"));
	x2 += w2;
	y2 += h2;
	return drawRect(root,x1,y1,x2,y2,offset);
}
//在一个矩形外画矩形,传入左上角和右下角的位置
function drawRect(root,x1,y1,x2,y2,offset){
	var offset =offset == null?0:offset;
	var x = x1 - offset;
	var y = y1 - offset;
	var w = x2 - x1 + 2*offset;
	var h = y2 - y1+ 2*offset;
	var rectbox = root.rect(x,y,w,h).attr({stroke: "#F4B183","stroke-width": 1,});
	return rectbox;
}

//更新圆盘
var spinner;
function spinner(holderid, R1, R2, count, stroke_width, colour) {
    var sectorsCount = count || 12,
        color = colour || "#fff",
        width = stroke_width || 15,
        r1 = Math.min(R1, R2) || 35,
        r2 = Math.max(R1, R2) || 60,
        cx = r2 + width,
        cy = r2 + width,
        spinner = Raphael(holderid, r2 * 2 + width * 2, r2 * 2 + width * 2),

        sectors = [],
        opacity = [],
        beta = 2 * Math.PI / sectorsCount,

        pathParams = {stroke: color, "stroke-width": width, "stroke-linecap": "round"};
        Raphael.getColor.reset();
    for (var i = 0; i < sectorsCount; i++) {
        var alpha = beta * i - Math.PI / 2,
            cos = Math.cos(alpha),
            sin = Math.sin(alpha);
        opacity[i] = 1 / sectorsCount * i;
        sectors[i] = spinner.path([["M", cx + r1 * cos, cy + r1 * sin], ["L", cx + r2 * cos, cy + r2 * sin]]).attr(pathParams);
        if (color == "rainbow") {
            sectors[i].attr("stroke", Raphael.getColor());
        }
    }
    var tick;
    (function ticker() {
        opacity.unshift(opacity.pop());
        for (var i = 0; i < sectorsCount; i++) {
            sectors[i].attr("opacity", opacity[i]);
        }
       // r.safari();
        tick = setTimeout(ticker, 1000 / sectorsCount);
    })();
    return function () {
        clearTimeout(tick);
        spinner.remove();
    };
}

rect1.node.onclick = function () {
	rect1.attr("fill", "red");
	var x = Math.round($(rect1.node).attr("x"));
	var y = Math.round($(rect1.node).attr("y"));
	var w = $(rect1.node).attr("width");
	var h = $(rect1.node).attr("height");
	var xx = (x*1 + w*1)+"px";
	var yy = (80 + y+ h/2 -20 )+"px";
	console.log("xx="+xx);
	var remove = spinner("spinner",10, 20, 8, 5, "#FFFF00");
	$(‘#spinner‘).css("left",xx);
	$(‘#spinner‘).css("top",yy);
};
function change(){
	var x = Math.round($(rect1.node).attr("x"));
	var y = Math.round($(rect1.node).attr("y"));
	var w = $(rect1.node).attr("width");
	var h = $(rect1.node).attr("height");
	var xx = (x*1 + w*1)+"px";
	var yy = (80 + y+ h/2 -20 )+"px";
	console.log("xx="+xx);
	//remove();
	var remove = spinner("spinner",10, 20, 8, 5, "#FFFF00");
	$(‘#spinner‘).css("left",xx);
	$(‘#spinner‘).css("top",yy);
}

var imageMenuData = [
[{
  text: "方法一",
  func: function() {
      alert("方法一")
      rect1.attr("fill", "blue");
     // remove();
      change()
  }
}, {
  text: "方法二",
  func: function() {
	  alert("方法二")
	  rect1.attr("fill", "yellow");
     // remove();
      change()
  }
}],
[{
  text: "方法三",
  func: function() {
	  alert("方法三")
	  rect1.attr("fill", "#FF84FF");
     // remove();
      change()
  }
}]
];
//增加右键菜单
$(rect1.node).smartMenu(imageMenuData, {
name: "image"
});
$("rect").smartMenu(imageMenuData, {
	name: "image"
	});
$(‘text‘).fontFlex(15, 50, 90);//字体大小自适应
//当浏览器窗口大小改变时,设置显示内容的高度
            window.onresize=function(){
            	//paper.safari()
            }  

</script>
</html>

最终效果展示:

右键点击:

方法调用后结果:

版权声明:本文为博主林炳文Evankaka原创文章,转载请注明出处http://blog.csdn.net/evankaka

时间: 2024-10-03 23:06:57

Web流程图绘制使用raphael的相关文章

【转】Visio绘制WEB流程图的心得

一个哥们在MSN上告诉我,他们公司的交互设计师只产出流程图,并问我用什么标准评价流程图的好坏.他的说法把我彻底震了-这分工也太细了吧!也不知道该说他们那里这样是好还是不好. 不过仔细想来,我倒的确没有仔细考虑过流程图的好坏,正好借此机会自我总结一下. 1.各司其职的形状 在我的流程图中,适用于不同目的和功能的形状都有各自确定的规范.到目前为止,我一共定义了以下一些形状: (1)开始和结束 作为整张流程图的头和尾,必须标清楚到底具体指哪个页面,以免日后出现歧义. (2)网页 如你所见,网页的形状是

atitit..代码生成流程图 流程图绘制解决方案 java &#160;c#.net &#160;php v2

atitit..代码生成流程图 流程图绘制解决方案 java  c#.net  php v2 1.1. Markdown 推荐,就是代码和flow都不能直接使用.1 1.2. Java code2flow 推荐,最起码代码能用,flow能看1 2. visus1211 3. 别的工具cvf 跟autoflowchart2 3.1. Code Visual 代码编辑器(code visual to flowchart v6.0) 推荐3 3.2. Axure不推荐,二进制的4 4. 参考4 1.1

流程图绘制控件WpfDiagram

WpfDiagram是一款功能强大的流程图绘制控件,可以绘制工作流程图.对象层次和关系图.网络拓扑图.实体关系图.IVR.工业自动化.genealogy trees .算法流程图.组织结构图.XML文档.类图等.杰出的功能.稳定的性能以及优雅的架构使它成为迄今为止MindFusion中最高级的编程控制组件.它是我们在控件开发中的顶尖体验,该开发结合了.NET平台提供的最新一代的图表展示工具.因此,编程过程变得更加简单快捷,最终的图表变得更加具有吸引力并更加生动 具体功能: 软件的再分配完全免费

流程图绘制的方法和技巧

流程图基本认识 流程由一系列相互关联或相互作用的活动所组成,它是一系列将输入转换为输出,并实现增值的过程.企业流程的本质是以顾客为中心,从顾客的需求为出发点,来安排企业的生产经营活动. 流程图的分类: 什么样的流程图需要管理? 流程图绘制步骤; 1.绘制流程图借助辅助工具会很方便,打开迅捷画图在线网站,进入网站中,在首页点击进入迅捷画图: 2.这时会跳转到另一个页面,这里我们讲述的是流程图,在新建文件夹里面选择流程图: 3.点击流程图之后就会跳转到流程图制作页面: 4.在面板的四周我们可以看到很

JointJS:JavaScript 流程图绘制框架

目录 JointJS:JavaScript 流程图绘制框架 JointJS 简介 JointJS Hello world 前后端分离架构 其他 自动布局 Automatic layout 使用 HTML 定制元素 JointJS:JavaScript 流程图绘制框架 最近调研了js画流程图的框架,最后选择了Joint.配合上 dagre 可以画出像模像样的流程图. JointJS 简介 JointJS 是一个开源前端框架,支持绘制各种各样的流程图.工作流图等.Rappid 是 Joint 的商业

Win7 下安装流程图绘制软件 Dia

1.我的环境 操作系统:32位 Win7 旗舰版 Service Pack 1 2.安装Dia OSC上Dia的页面地址:http://www.oschina.net/p/dia 软件首页地址:https://wiki.gnome.org/action/show/Apps/Dia 在这个页面点击链接"Download",可以进入到下载页面 这个页面会给出下载Dia的地址:http://dia-installer.de/ Overview下面有一个大按钮,点击后进入SourceForge

分享一个开源的流程图绘制软件--Diagram Designer

最近在写专利文件,在制作说明书附图时想到自己还只会用wps进行简单的绘制,于是想学习下,填补下这方面的短板.这两天查到了DiagramDesigner这个小工具,派上了大用场.用它写完了一个发明专利,还给zigbee产品设计了一个测试架. 对比了几个小工具.首先是产品经理们爱用的VISIO,功能强大,但是收费.其次有一个开源的特别简单的软件EVE,http://www.goosee.com/,试用了下,对于流程图应用来说功能还是太简单.于是最终选择了DiagramDesigner,如果你像我一样

[笔记]目前见到的最符合我的需求的消息流程图绘制工具

消息流程图工具非常多,有离线的,也有在线的,我的需求是: 支持文本描述转为图形化消息流程图(受够了Office系列,往往时间要浪费一半在各种调整格式) 支持中文(真有不少开源工具不支持) 角色名称支持缩写别名(如显示为“服务器”,后面调用时只需要写“S”即可) UI效果简单粗暴,排版合理(有收费版UI效果更炫,但是我用不着) 如果能在UI上直接WYSIWYG的编辑更好(没有也能忍了) 能够将生成的图片导出 免费或开源(盗版或试用版用着还是心里不踏实) 如果是在线工具,最好能离线使用 尝试了很多款

用HTML5构建一个流程图绘制工具

在我们的开发工程中经常会使用到各种图,所谓的图就是由节点和节点之间的连接所形成的系统,数学上专门有一个分支叫图论(Graph Theroy).利用图我们可以做很多工具,比如思维导图,流程图,状态机,组织架构图,等等.今天我要做的是用开源的HTML5工具来快速构造一个做图的工具. 工具选择 预先善其事,必先利其器.第一件事是选择一件合适的工具,开源时代,程序员还是很幸福的,选择很多. flowchart.js  http://adrai.github.io/flowchart.js/ , 基于SV