h5 canvas手工写一个初级的饼状图,只为研究原理,自娱自乐

来源:互联网 发布:mysql logbin日志查看 编辑:程序博客网 时间:2024/05/17 03:09
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body><canvas id="pie" width="800px" height="600px" style="border: 1px solid #999999;margin: 0px;padding: 0;">    (Your browser doesn't support canvas)</canvas><script type="text/javascript">    DomUtils = {        addEventListener:function(obj,type,fn,context){            function handler(e){                return fn.call(context||obj,e);            }            if(obj.addEventListener){                obj.addEventListener(type,handler,false);            }            else if(obj.attachEvent){                obj.attachEvent("on"+type,handler);            }        },        removeEventListener:function(){            if(obj.addEventListener){                obj.removeEventListener(type,fn,false);            }            else if(obj.attachEvent){                obj.detachEvent("on"+type,handler);            }        }    }    var PieChart = function(){        // func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])        this.init.apply(this,arguments);    };    PieChart.prototype = {        init:function(id,options){            this.renderId = id;            this.canvas = document.getElementById(this.renderId);            this.data = options.data;            this.colors = options.colors;            this.labels = options.labels;            this.linecolor = options.linecolor||"rgba(229, 205, 205, 0.58)";            this.isCircle = options.isCircle;            this.radius = options.radius||[];            this.angles = [];            this.prompt = null;            this.center = {x:0,y:0,radius:50};            this.offset = options.offset||100;            this.legend = {                width:20,                height:10            };            this._calcAngle();        },        _calcAngle(){            var startAngle = 0;            var endAngle = 0;            for(var i=0;i<this.data.length;i++){                endAngle = startAngle+Number(this.data[i])*Math.PI*2;                this.angles.push({                    index:i,                    label:this.labels[i],                    color:this.colors[i],                    start:startAngle,                    end:endAngle                });                startAngle = endAngle;            }        },        _draw:function(){            // 开始绘画            var width = this.canvas.width;            var height = this.canvas.height;            var radius = Math.min(width,height)/2-this.offset;            var x = radius+this.offset;            var y = height/2+this.canvas.offsetTop-8;            this.center.x = x;            this.center.y = y;            this.center.radius = radius;            var ctx = this.canvas.getContext("2d");            this._antialiasing(ctx,width,height);            ctx.strokeStyle = this.linecolor;            for(var i=0;i<this.angles.length;i++){                ctx.beginPath();                ctx.moveTo(x,y);                ctx.fillStyle=this.angles[i].color;                ctx.arc(x,y,radius,this.angles[i].start,this.angles[i].end);                ctx.closePath();                ctx.lineWidth=1;                //ctx.strokeStyle="#ffffff";                ctx.fill();                ctx.stroke();            }            this._drawCircle(ctx);        },        _antialiasing:function(ctx,width,height){            if (window.devicePixelRatio) {                this.canvas.style.width = width + "px";                this.canvas.style.height = height + "px";                this.canvas.height = height * window.devicePixelRatio;                this.canvas.width = width * window.devicePixelRatio;                ctx.scale(window.devicePixelRatio, window.devicePixelRatio);            }        },        _drawCircle:function(ctx){            if(this.isCircle){                ctx.beginPath();                ctx.moveTo(this.center.x,this.center.y);                ctx.fillStyle="#ffffff";                ctx.arc(this.center.x,this.center.y,this.center.radius/3,0,Math.PI*2);                ctx.closePath();                ctx.fill();            }        },        _drawLegend:function(){            var ctx = this.canvas.getContext("2d");            var x = this.canvas.offsetWidth-150;            var y = this.offset;            for(var i=0;i<this.angles.length;i++){                ctx.beginPath();                ctx.moveTo(x,y);                ctx.fillStyle=this.angles[i].color;                ctx.fillRect(x,y,this.legend.width,this.legend.height);                // 绘制文字                ctx.moveTo(x+this.legend.width+5, y+this.offset/2);                ctx.font = 'bold 12px 微软雅黑';                ctx.fillStyle = color_arr[i];                ctx.fillText(this.angles[i].label,x+this.legend.width+5,y+this.offset/2)                //ctx.closePath();                //ctx.strokeStyle="#ffffff";                ctx.fill();                y = y + 20;            }        },        _drawPrompt(x,y,index){            var pie = this.angles[index];            var d = this.data[index];            if(!this.prompt){                this.prompt = document.createElement("div");                document.body.appendChild(this.prompt);            }            this.prompt.style.display = "block";            this.prompt.style.background = "rgba(50, 50, 50, 0.701961)";            this.prompt.style.position = "absolute";            this.prompt.style.padding = "5px";            this.prompt.style.zindex = "99999";            this.prompt.style.color = "#fff";            this.prompt.style.borderRadius = "4px";            this.prompt.style.top = y+20+"px";            this.prompt.style.left = x+20+"px";            this.prompt.innerHTML = pie.label+"<br/>"+d;        },        _getPieIndex:function(x,y){            var angle = Math.atan2(y,x);            if (angle < 0) angle = -angle;            else {                angle = Math.PI * 2 - angle;            }            for(var i=0;i<this.angles.length;i++){                if(angle<=this.angles[i].end){                    return i;                }            }        },        _onMouseOver:function(){            this._draw();            var e = arguments.callee.caller.arguments[0]||event;            var x = e.x|| e.clientX;            var y = e.y|| e.clientY;            var dx = x-this.center.x;            var dy = this.center.y-y;            var d = Math.sqrt(dx*dx+dy*dy);            if(this.center.radius>=d){                console.info(x+","+y);                var index = this._getPieIndex(dx,dy);                var ctx = this.canvas.getContext("2d");                ctx.beginPath();                ctx.moveTo(this.center.x,this.center.y);                ctx.fillStyle=this.angles[index].color;                ctx.lineWidth=1;                ctx.arc(this.center.x,this.center.y,this.center.radius+20,this.angles[index].start,this.angles[index].end);                ctx.closePath();                ctx.fill();                this._drawCircle(ctx);                this._drawPrompt(x,y,index);            }else{                if(this.prompt)this.prompt.style.display="none";            }        },        _dispatchEvent:function(){            DomUtils.addEventListener(this.canvas,'mouseover',this._onMouseOver,this);            //DomUtils.addEventListener(this.canvas,'mouseout',canvasOnMouseOut,this);            DomUtils.addEventListener(this.canvas,'mousemove',this._onMouseOver,this);        },        render:function(){            this._draw();            this._dispatchEvent();            this._drawLegend();        }    };    var data_arr = [0.05, 0.25, 0.6, 0.1];    var color_arr = ["#00FF21", "#FFAA00", "#00AABB", "#0044ff"];    var text_arr = ["河北", "山东", "河南", "山西"];    var piechart = new PieChart("pie",{        isCircle:true,        data:data_arr,        colors:color_arr,        labels:text_arr    });    piechart.render();</script></body></html>
原创粉丝点击