jquery canvas 实现时序图|接续图|顺序图
来源:互联网 发布:西南科技大学软件下载 编辑:程序博客网 时间:2024/06/05 11:19
<div id="chart" style="position: absolute;top:0px;left:0px;right: 0;bottom: 0px; min-height:300px;min-width:500px;"></div>
1.效果图
2、数据格式
var posts=["item1","item2","item3","item4","item5"];//柱子元素
var relations=[{"from":"item1","to":"item2","content":{"desc":"11223","time":"2017-09-22 16:38:12","flag":0}},{"from":"item1","to":"item2","content":{"desc":"11223","time":"2017-09-22 16:38:12","flag":0}},{"from":"item1","to":"item3","content":{"desc":"11223","time":"2017-09-22 16:38:12","flag":0}},{"from":"item4","to":"item2","content":{"desc":"11223","time":"2017-09-22 16:38:12","flag":1}}];//关联关系
3、html代码
<div id="chart" style="position: absolute;top:0px;left:0px;right: 0;bottom: 0px; min-height:300px;min-width:500px;"></div>4、js代码
var chart=new followchart("chart",posts,relations,clickfunc); $(window).resize(function() { chart.redraw(); }); function clickfunc(obj,type){ console.log("obj:",obj); console.log("type:",type); }5、不造咋上传文件。。。。
<!DOCTYPE html><html> <head> <style> .charttitle{ color:#fff; text-align: center; position: absolute; } .charttitle:hover{ cursor: pointer; background-color: #4877E1; } .chartcontent{ position: absolute; background-color:#5A9BD5; padding: 5px; color: #fff; font-size: 10px; } .chartcontent:hover{ cursor: pointer; background-color: #4877E1; } .chartcontent span{ text-align: left; display: block; } .flag_0{ color:red; } body,#chart{ margin: 0; padding: 0; } .followchart_warp{ position: relative; height: 100%; width: 100%; } </style> </head> <body> <div id="chart" style="position: absolute;top:0px;left:0px;right: 0;bottom: 0px; min-height:300px;min-width:500px;"></div> <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script> <script> var posts=["item1","item2","item3","item4","item5"] var relations=[{"from":"item1","to":"item2","content":{"desc":"11223","time":"2017-09-22 16:38:12","flag":0}},{"from":"item1","to":"item2","content":{"desc":"11223","time":"2017-09-22 16:38:12","flag":0}},{"from":"item1","to":"item3","content":{"desc":"11223","time":"2017-09-22 16:38:12","flag":0}},{"from":"item4","to":"item2","content":{"desc":"11223","time":"2017-09-22 16:38:12","flag":1}}]; $(function(){ var chart=new followchart("chart",posts,relations,clickfunc); $(window).resize(function() { chart.redraw(); }); }); function clickfunc(obj,type){ console.log("obj:",obj); console.log("type:",type); } function drawArrow(ctx, fromX, fromY, toX, toY, theta, headlen, width, color) { theta = typeof(theta) != 'undefined' ? theta : 30; headlen = typeof(theta) != 'undefined' ? headlen : 10; width = typeof(width) != 'undefined' ? width : 1; color = typeof(color) != 'color' ? color : '#5A9BD5'; // 计算各角度和对应的P2,P3坐标 var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI, angle1 = (angle + theta) * Math.PI / 180, angle2 = (angle - theta) * Math.PI / 180, topX = headlen * Math.cos(angle1), topY = headlen * Math.sin(angle1), botX = headlen * Math.cos(angle2), botY = headlen * Math.sin(angle2); ctx.save(); ctx.beginPath(); var arrowX = fromX - topX, arrowY = fromY - topY; ctx.moveTo(arrowX, arrowY); ctx.moveTo(fromX, fromY); ctx.lineTo(toX, toY); arrowX = toX + topX; arrowY = toY + topY; ctx.moveTo(arrowX, arrowY); ctx.lineTo(toX, toY); arrowX = toX + botX; arrowY = toY + botY; ctx.lineTo(arrowX, arrowY); ctx.strokeStyle = color; ctx.lineWidth = width; ctx.stroke(); ctx.restore(); } function Rect(name,x,y,isSelected,color){ this.name=name; this.x=x; this.y=y; this.isSelected=isSelected; this.color=color; } function RectLine(name,x,y,endx,endy,isSelected,color){ this.name=name; this.x=x; this.y=y; this.endx=endx; this.endy=endy; this.isSelected=isSelected; this.color=color; } function LineArrow(fromname,toname,fromx,fromy,tox,toy,isSelected,color,content){ this.fromname=fromname; this.toname=toname; this.fromx=fromx; this.fromy=fromy; this.tox=tox; this.toy=toy; this.isSelected=isSelected; this.color=color; this.content=content; } var followchart=function(elemid,posts,relations,clickbackcall){ this.rects=[]; this.rectLines=[]; this.lineArrows=[]; this.preselectedindex=null; this.preselectedarrowindex=null; this.prehoverdname=""; this.posts=posts; this.relations=relations; this.clickbackcall=clickbackcall; this.rectwidth=65; this.rectheight=30; this.color="#5A9BD5"; this.hovercolor="#4877E1"; this.elemid=elemid this.elem=$("#"+elemid); this.height=$("#"+elemid).height()-10; this.width=$("#"+elemid).width(); this.elem.html("<div class='followchart_warp'></div>"); this.context=$("<canvas/>") .attr({ width: this.width, height: this.height, id: this.elemid+"_followchart" }) .appendTo(this.elem.find(".followchart_warp")).get(0).getContext('2d'); this.canvas=$("#"+this.elemid+"_followchart")[0]; this.realrectwidth(); this.addrect(); this.addlinearrow(); this.initchart(); this.render(); } followchart.prototype.render=function(){ this.canvas.onmousedown = this.canvasClick.bind(this); this.canvas.onmousemove = this.canvasHover.bind(this); this.elem.on("click",".charttitle",this.canvasClick.bind(this)) } followchart.prototype.initchart=function(){ this.context.clearRect(0, 0, this.width, this.height); this.elem.find(".charttitle").remove(); this.elem.find(".chartcontent").remove(); this.context.fillStyle=this.color; this.context.strokeStyle =this.color; this.drawrect(); this.drawrectLine(); this.drawarrow(); } followchart.prototype.realrectwidth=function(){ var areawidth=this.width/this.posts.length; if(areawidth<=75){ if(areawidth>45) this.rectwidth=35; else this.rectwidth=1; } } followchart.prototype.addrect=function(){ this.rects=[]; this.rectLines=[]; for(var i=0;i<this.posts.length;i++){ var post=this.posts[i]; var starty=15; var startx=Math.round(this.width/this.posts.length*i+this.width/this.posts.length/2-this.rectwidth/2); var linestartx=Math.round(startx+this.rectwidth/2); var linestarty=Math.round(starty+this.rectheight); var lineendx=linestartx; var lineendy=Math.round(this.height-starty); var rect=new Rect(post,startx,starty,false,this.color); var rectline=new RectLine(post,linestartx,linestarty,lineendx,lineendy,false,this.color); this.rects.push(rect); this.rectLines.push(rectline); } } followchart.prototype.addlinearrow=function(){ this.lineArrows=[]; for(var i=0;i<this.relations.length;i++){ var relation=this.relations[i]; var fromname=relation.from; var toname=relation.to; var content=relation.content; var fromx=0,fromy=0,tox=0,toy=0; for(var j=0;j<this.rectLines.length;j++){ var rectline=this.rectLines[j]; if(rectline.name==fromname){ fromx=rectline.x; } if(rectline.name==toname){ tox=rectline.x; } } fromy=Math.round((this.height-30-this.rectheight)/this.relations.length*i +(this.height-30-this.rectheight)/this.relations.length/2)+15+this.rectheight; toy=fromy; var color=this.color; if(content.flag==0) color="red"; var arrow=new LineArrow(fromname,toname,fromx,fromy,tox,toy,false,color,content); this.lineArrows.push(arrow); } } followchart.prototype.drawrect=function(){ for(var i=0;i<this.rects.length;i++){ var rect=this.rects[i]; this.context.fillStyle=rect.color; this.context.fillRect(rect.x,rect.y,this.rectwidth,this.rectheight); this.context.stroke(); if(rect.isSelected){ this.context.lineWidth = 1;//边框宽度 this.context.strokeStyle = "#00f";//边框颜色 this.context.strokeRect(rect.x,rect.y,this.rectwidth,this.rectheight); } this.drawtitle(rect.x,rect.y,this.rectwidth,this.rectheight,this.posts[i]) } } followchart.prototype.drawrectLine=function(){ for(var i=0;i<this.rectLines.length;i++){ var rectline=this.rectLines[i]; this.context.beginPath() this.context.moveTo(rectline.x,rectline.y); this.context.lineTo(rectline.endx,rectline.endy); this.context.lineWidth = 1; this.context.strokeStyle =rectline.color; if(rectline.isSelected){ this.context.lineWidth = 2; this.context.strokeStyle =this.hovercolor; } this.context.stroke(); this.context.closePath(); } } followchart.prototype.drawtitle=function(x,y,width,height,title){ this.elem.append("<div class=\"charttitle\" style=\"left:"+x+"px;top:"+y+"px;width:"+width+"px;height:"+height+"px;line-height:"+height+"px;\">"+title+"</div>"); } followchart.prototype.drawarrow=function(){ for(var i=0;i<this.lineArrows.length;i++){ var arrow=this.lineArrows[i]; drawArrow(this.context,arrow.fromx,arrow.fromy,arrow.tox,arrow.toy,30,10,3,arrow.color); var startx=arrow.tox<arrow.fromx?arrow.tox:arrow.fromx; var contentx=Math.abs(arrow.tox-arrow.fromx)/2+startx; if((contentx-40)>startx){ contentx=contentx-40; }else{ contentx=startx; } this.drawcontent(contentx,arrow.fromy-50,arrow.content); } } followchart.prototype.drawcontent=function(x,y,content){ var html="<div class=\"chartcontent\" style=\"left:"+x+"px;top:"+y+"px; \">"; var str = JSON.stringify(content); var objKey = JSON.parse(str); var propertys = Object.keys(objKey); for(var i=0;i<propertys.length;i++){ html+="<span"; if(propertys[i]=="flag"){ html+=" class=\"flag_"+content[propertys[i]]+"\"" } html+=">"+content[propertys[i]]+"</span>" } html+="</div>" this.elem.append(html); } followchart.prototype.canvasClick=function(e){ var clickX = e.pageX - this.elem[0].offsetLeft; var clickY = e.pageY - this.elem[0].offsetTop; var i=0,hasfind=false,findarrow=false,selectindex=0; for( i=0;i<this.rects.length;i++){ var rect=this.rects[i]; if(clickX>=rect.x&&clickX<=(rect.x+this.rectwidth)&&clickY>=rect.y&&clickY<=(rect.y+this.rectheight)){ rect.isSelected=true; this.rectLines[i].isSelected=true; hasfind=true; selectindex=i; if(this.preselectedindex!=selectindex)this.setunselect(this.preselectedindex); this.preselectedindex=selectindex; break; } } if(!hasfind){ for( i=0;i<this.rectLines.length;i++){ var rectLine=this.rectLines[i]; if(clickX>=(rectLine.x-1)&&clickX<=(rectLine.x+1)&&clickY>=rectLine.y&&clickY<=rectLine.endy){ rectLine.isSelected=true; this.rects[i].isSelected=true; hasfind=true; selectindex=i; if(this.preselectedindex!=selectindex)this.setunselect(this.preselectedindex); this.preselectedindex=selectindex; break; } } } if(!hasfind){ for( i=0;i<this.lineArrows.length;i++){ var arrow=this.lineArrows[i]; var minx=arrow.tox<arrow.fromx?arrow.tox:arrow.fromx; var max=arrow.tox>arrow.fromx?arrow.tox:arrow.fromx; if(clickX>=minx&&clickX<=max&&clickY>=(arrow.fromy-3)&&clickY<=(arrow.toy+3)){ arrow.isSelected=true; findarrow=true; selectindex=i; if(this.preselectedarrowindex!=null&&this.preselectedarrowindex!=selectindex) this.relations[this.preselectedarrowindex].isSelected=false; this.preselectedarrowindex=selectindex; break; } } } if(hasfind){ if(typeof(this.clickbackcall)=="function"){ this.clickbackcall(this.posts[selectindex],"item"); } } if(findarrow){ if(typeof(this.clickbackcall)=="function"){ this.clickbackcall(this.relations[selectindex],"relation"); } } this.initchart(); } followchart.prototype.setunselect=function(index){ if(index!=null){ this.rectLines[index].isSelected=false; this.rects[index].isSelected=false; } } followchart.prototype.canvasHover=function(e){ var clickX = e.pageX - this.elem[0].offsetLeft; var clickY = e.pageY - this.elem[0].offsetTop; this.setunhover(this.rects); this.setunhover(this.rectLines); this.setunhover(this.lineArrows); var i=0,hasfind=false,selectname=""; for( i=0;i<this.rects.length;i++){ var rect=this.rects[i]; if(clickX>=rect.x&&clickX<=(rect.x+this.rectwidth)&&clickY>=rect.y&&clickY<=(rect.y+this.rectheight)){ rect.isSelected.color=this.hovercolor; this.rectLines[i].color=this.hovercolor; hasfind=true; selectname=rect.name; break; } } if(!hasfind){ for( i=0;i<this.rectLines.length;i++){ var rectLine=this.rectLines[i]; if(clickX>=(rectLine.x-1)&&clickX<=(rectLine.x+1)&&clickY>=(rectLine.y-1)&&clickY<=rectLine.endy){ rectLine.color=this.hovercolor; this.rects[i].color=this.hovercolor; hasfind=true; selectname=rect.name; break; } } } if(!hasfind){ for( i=0;i<this.lineArrows.length;i++){ var arrow=this.lineArrows[i]; var minx=arrow.tox<arrow.fromx?arrow.tox:arrow.fromx; var max=arrow.tox>arrow.fromx?arrow.tox:arrow.fromx; if(clickX>=minx&&clickX<=max&&clickY>=(arrow.fromy-3)&&clickY<=(arrow.toy+3)){ arrow.color=this.hovercolor; if(arrow.content.flag==0){ arrow.color="red"; } hasfind=true; selectname=arrow.fromname+"-"+arrow.toname; break; } } } if(selectname!=this.prehoverdname){ if(selectname==""){ this.elem.css("cursor","default") }else{ this.elem.css("cursor","pointer") } this.prehoverdname=selectname; this.initchart(); } } followchart.prototype.setunhover=function(objs){ for(var i=0;i<objs.length;i++){ objs[i].color=this.color; if(objs[i].content!=undefined&&objs[i].content.flag==0){ objs[i].color="red"; } } } followchart.prototype.redraw=function(){ this.elem.find(".followchart_warp").empty(); this.height=this.elem.height()-10; this.width=this.elem.width(); this.context=$("<canvas/>") .attr({ width: this.width, height: this.height, id: this.elemid+"_followchart" }) .appendTo(this.elem.find(".followchart_warp")).get(0).getContext('2d'); this.canvas=$("#"+this.elemid+"_followchart")[0]; this.realrectwidth(); this.realrectwidth(); this.addrect(); this.addlinearrow(); this.initchart(); this.render(); } </script> </body></html>
阅读全文
0 0
- jquery canvas 实现时序图|接续图|顺序图
- UML---序列图/时序图/顺序图
- UML系列---时序图(顺序图)
- UML 顺序图(时序图) sequence diagram
- 时序图
- 时序图
- 时序图
- 时序图
- 时序图
- 时序图
- 时序图
- 时序图
- 时序图
- 时序图
- 时序图
- 时序图
- 时序图
- 时序图
- Linux下进程通信预习(一)
- Maven+MyBatis 基础程序创建<2>
- 区块链学习-概念
- Liunx 安装文件一般原则
- 总结
- jquery canvas 实现时序图|接续图|顺序图
- 【平衡树维护序列】BZOJ3506(Cqoi2014)[排序机械臂]题解
- 两个二维数组进行合并成一个二维数组
- Spring Cloud Eureka源代码解析(2) EurekaServer 重要缓存解析
- linux共享目录挂载权限问题
- jQuery点击元素获取自定义属性的值,利用冒泡原理~
- 虚拟桌面架构VDI
- 简说JavaSE、JavaEE、JavaME的关系
- SSM项目从零开始到入门006-为mybatis项目添加日志支持