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>

原创粉丝点击