`

canvas__2 饼状图

    博客分类:
  • HTML
阅读更多
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="GBK">
    <title></title>
    <style>
        canvas{
            border: 1px solid #A4E2F9;
        }
    </style>
</head>
<body>
    <div height="400" width="600" style="margin:50px">
        <canvas id="chart"> 你的浏览器不支持HTML5 canvas </canvas>
    </div>
    
    <script type="text/javascript">
        function goChart(dataArr){
            
            // 声明所需变量
            var canvas,ctx;
            // 图表属性
            var cWidth, cHeight, cMargin, cSpace;
            // 饼状图属性
            var radius,ox,oy;//半径 圆心
            var tWidth, tHeight;//图例宽高
            var posX, posY, textX, textY;
            var startAngle, endAngle;
            var totleNb;
            // 运动相关变量
            var ctr, numctr, speed;
            //鼠标移动
            var mousePosition = {};
            
            //线条和文字
            var lineStartAngle,line,textPadding,textMoveDis;
        
            // 获得canvas上下文
            canvas = document.getElementById("chart");
            if(canvas && canvas.getContext){
                ctx = canvas.getContext("2d");
            }
            initChart(); 
            
            // 图表初始化
            function initChart(){
                // 图表信息
                cMargin = 20;
                cSpace = 40;
                
                canvas.width = canvas.parentNode.getAttribute("width")* 2 ;
                canvas.height = canvas.parentNode.getAttribute("height")* 2;
                canvas.style.height = canvas.height/2 + "px";
                canvas.style.width = canvas.width/2 + "px";
                cHeight = canvas.height - cMargin*2;
                cWidth = canvas.width - cMargin*2;
        
                //饼状图信息
                radius = cHeight*2/6;  //半径  高度的2/6
                ox = canvas.width/2 + cSpace;  //圆心
                oy = canvas.height/2;
                tWidth = 60; //图例宽和高
                tHeight = 20; 
                posX = cMargin;
                posY = cMargin;   //
                textX = posX + tWidth + 15
                textY = posY + 18;
                startAngle = endAngle = 90*Math.PI/180; //起始弧度 结束弧度
                rotateAngle = 0; //整体旋转的弧度
    
                //将传入的数据转化百分比
                totleNb = 0;
                new_data_arr = [];
                for (var i = 0; i < dataArr.length; i++){
                    totleNb += dataArr[i][0];
                }
                for (var i = 0; i < dataArr.length; i++){
                    new_data_arr.push( dataArr[i][0]/totleNb );
                }
                totalYNomber = 10;
                // 运动相关
                ctr = 1;//初始步骤
                numctr = 50;//步骤
                speed = 1.2; //毫秒 timer速度
                
                //指示线 和 文字
                lineStartAngle = -startAngle;
                line=40;         //画线的时候超出半径的一段线长
                textPadding=10;  //文字与线之间的间距
                textMoveDis = 200; //文字运动开始的间距
            }
        
            drawMarkers();
            //绘制比例图及文字
            function drawMarkers(){
                ctx.textAlign="left";
                for (var i = 0; i < dataArr.length; i++){
                    //绘制比例图及文字
                    ctx.fillStyle = dataArr[i][1];
                    ctx.fillRect(posX, posY + 40 * i, tWidth, tHeight);
                    ctx.moveTo(posX, posY + 40 * i);
                    ctx.font = 'normal 24px 微软雅黑';    //斜体 30像素 微软雅黑字体
                    ctx.fillStyle = dataArr[i][1]; //"#000000";
                    var percent = dataArr[i][2] + ":" + parseInt(100 * new_data_arr[i]) + "%";
                    ctx.fillText(percent, textX, textY + 40 * i);
                }
            };
            
            //绘制动画
            pieDraw();
            function pieDraw(mouseMove){
                
                for (var n = 0; n < dataArr.length; n++){
                    ctx.fillStyle = ctx.strokeStyle = dataArr[n][1];
                    ctx.lineWidth=1;
                    var step = new_data_arr[n]* Math.PI * 2; //旋转弧度
                    var lineAngle = lineStartAngle+step/2;   //计算线的角度
                    lineStartAngle += step;//结束弧度
                    
                    ctx.beginPath();
                    var  x0=ox+radius*Math.cos(lineAngle),//圆弧上线与圆相交点的x坐标
                         y0=oy+radius*Math.sin(lineAngle),//圆弧上线与圆相交点的y坐标
                         x1=ox+(radius+line)*Math.cos(lineAngle),//圆弧上线与圆相交点的x坐标
                         y1=oy+(radius+line)*Math.sin(lineAngle),//圆弧上线与圆相交点的y坐标
                         x2=x1,//转折点的x坐标
                         y2=y1,
                         linePadding=ctx.measureText(dataArr[n][2]).width+10; //获取文本长度来确定折线的长度
                         
                         ctx.moveTo(x0,y0);
                         //对x1/y1进行处理,来实现折线的运动
                         yMove = y0+(y1-y0)*ctr/numctr;
                         ctx.lineTo(x1,yMove);
                         if(x1<=x0){
                             x2 -= line;
                             ctx.textAlign="right";
                             ctx.lineTo(x2-linePadding,yMove);
                            ctx.fillText(dataArr[n][2],x2-textPadding-textMoveDis*(numctr-ctr)/numctr,y2-textPadding);
                         }else{
                             x2 += line;
                             ctx.textAlign="left";
                             ctx.lineTo(x2+linePadding,yMove);
                            ctx.fillText(dataArr[n][2],x2+textPadding+textMoveDis*(numctr-ctr)/numctr,y2-textPadding);
                         }
                         
                        ctx.stroke();
                        
                }
                
                //设置旋转
                ctx.save();
                ctx.translate(ox, oy);
                ctx.rotate((Math.PI*2/numctr)*ctr/2);
                
                //绘制一个圆圈
                ctx.strokeStyle = "rgba(0,0,0,"+ 0.5*ctr/numctr +")"
                ctx.beginPath();
                ctx.arc(0, 0 ,(radius+20)*ctr/numctr, 0, Math.PI*2, false);
                ctx.stroke();
                
                for (var j = 0; j < dataArr.length; j++){
                    
                    //绘制饼图
                    endAngle = endAngle + new_data_arr[j]* ctr/numctr * Math.PI * 2; //结束弧度
                    
                    ctx.beginPath();
                    ctx.moveTo(0,0); //移动到到圆心
                    ctx.arc(0, 0, radius*ctr/numctr, startAngle, endAngle, false); //绘制圆弧
                    
                    ctx.fillStyle = dataArr[j][1];
                    if(mouseMove && ctx.isPointInPath(mousePosition.x*2, mousePosition.y*2)){
                        ctx.globalAlpha = 0.8;
                    }
                    
                      ctx.closePath();
                      ctx.fill();
                    ctx.globalAlpha = 1;
                    
                    startAngle = endAngle; //设置起始弧度
                    if( j == dataArr.length-1 ){
                        startAngle = endAngle = 90*Math.PI/180; //起始弧度 结束弧度
                    }
                }
                
                ctx.restore();
                    
                if(ctr<numctr){
                    ctr++;
                    setTimeout(function(){
                        //ctx.clearRect(-canvas.width,-canvas.width,canvas.width*2, canvas.height*2);
                        ctx.clearRect(-canvas.width, -canvas.height,canvas.width*2, canvas.height*2);
                        drawMarkers();
                        pieDraw();
                    }, speed*=1.085);
                }
            }
            
            //监听鼠标移动
            var mouseTimer = null;
            canvas.addEventListener("mousemove",function(e){
                e = e || window.event;
                if( e.offsetX || e.offsetX==0 ){
                    mousePosition.x = e.offsetX;
                    mousePosition.y = e.offsetY;
                }else if( e.layerX || e.layerX==0 ){
                    mousePosition.x = e.layerX;
                    mousePosition.y = e.layerY;
                }
                
                clearTimeout(mouseTimer);
                mouseTimer = setTimeout(function(){
                    ctx.clearRect(0,0,canvas.width, canvas.height);
                    drawMarkers();
                    pieDraw(true);
                },10);
            });
            
        }
        
        var chartData = [[50,"#2dc6c8","瓜子"], [100,"#b6a2dd", "花生"], [200,"#5ab1ee","土豆"], [700,"#d7797f","南瓜四号"]];
        
        goChart(chartData);


    </script>
</body>
</html>


参考:https://www.cnblogs.com/chengduxiaoc/p/7688794.html
分享到:
评论

相关推荐

    Canvas饼状图、绘制文字、绘制图像.zip

    这个压缩包文件"Canvas饼状图、绘制文字、绘制图像.zip"显然包含了关于如何使用Canvas进行特定图形绘制的教程或示例,特别是饼状图、文字和图像的绘制方法。 首先,让我们详细了解一下饼状图的绘制。饼状图是一种...

    HTML5 canvas简单饼状图动画.zip

    2. **饼状图**: 饼状图是一种用于展示数据比例的图表,各个扇区代表不同的数据类别,其大小与该类别的数值成正比。在canvas上绘制饼状图,通常需要计算每个扇区的角度,然后用`arc`方法绘制。 3. **动态效果**: ...

    html5 canvas简单的饼状图动画效果

    在本教程中,我们将探讨如何利用HTML5 Canvas实现一个简单的饼状图动画效果。 首先,我们需要在HTML文件中创建一个`&lt;canvas&gt;`元素,这是Canvas画布的基础。例如: ```html &lt;!DOCTYPE html&gt; &lt;title&gt;...

    基于html5 canvas实现的动态的饼状图动画特效源码.zip

    本压缩包包含了一个基于HTML5 Canvas实现的动态饼状图动画特效源码,这为我们深入理解和运用Canvas提供了实践案例。 饼状图是一种常用于数据可视化的方法,它将整体数据以圆形表示,各个部分所占比例以扇形面积展示...

    html5 canvas动态饼状图动画代码

    在饼状图中,起始角度通常是0(或Math.PI*1.5,因为Canvas的坐标原点在左上角,角度按顺时针计数),结束角度则是起始角度加上该数据项所占比例对应的弧度。 饼状图动画效果通常通过改变结束角度来实现。例如,点击...

    js+canvas绘制学院各院部饼状分布图特效.zip

    本示例"js+canvas绘制学院各院部饼状分布图特效.zip"显然旨在教你如何利用JavaScript和HTML5的Canvas API来创建一个展示学院各院部比例的饼状图,并添加动态特效。下面我们将深入探讨这个主题。 首先,你需要在HTML...

    html5 canvas动态饼状图动画代码.zip

    在这个“html5 canvas动态饼状图动画代码”中,我们可以看到一个利用Canvas API创建的动态饼状图,同时结合了jQuery库以实现更便捷的DOM操作和动画效果。 饼状图是一种常用于数据可视化的方法,它可以直观地表示每...

    qml中使用Canvas绘制饼状图

    在qml中使用Canvas绘制饼状图,可以直接使用qmlscene运行,支持Qt5.5及其以上

    Android之动态折线、柱状、饼状图的实现

    本教程将探讨如何在Android平台上动态地实现折线图、柱状图和饼状图,这些图表是数据呈现的常见方式,尤其适用于数据分析和展示。 首先,让我们了解这三种图表的基本概念: 1. **折线图**:折线图通过连接一系列...

    html5 canvas动态的饼状图动画特效.zip

    在Canvas上绘制饼状图,我们需要计算每个扇形的起始角度和结束角度,这通常基于数据的比例。例如,如果一个数据项占总数据的30%,那么对应的扇形应该占据360度中的90度。 接下来,我们讨论如何实现饼状图的动画效果...

    Canvas绘制饼状分布图特效.zip

    2. **饼状图绘制** - 饼状图是一种常见的统计图表,用于显示数据中各部分占总体的比例。 - 在Canvas上绘制饼状图需要计算每个扇区的角度,角度与数据值成正比。每个扇区的起始角度通常是0(或270度),结束角度是...

    立体饼状图资源源码.rar

    立体饼状图是一种数据可视化工具,它以三维立体的形式展示数据的比例关系,使得数据更加直观易懂。在IT行业中,特别是在数据分析、报表制作以及UI设计等领域,立体饼状图经常被用于表现各部分占整体的比例,同时其...

    HTML中的3D饼状图

    4. **数据绑定**:将数据与饼状图的各个部分关联起来,通过改变数据,饼状图的形状和大小也会相应变化,这有助于用户理解数据的分布。 5. **交互性**:3D饼状图通常会添加鼠标悬停、点击等交互效果,例如显示详细的...

    html5 canvas动态的饼状图动画特效

    通过不断重绘Canvas并逐步改变饼状图各部分的大小或颜色,可以创建出平滑的过渡效果。例如,点击分割线时,某个扇形可能逐渐放大或缩小,同时配合淡入淡出等过渡效果,以增加用户体验。 为了实现这个特效,首先需要...

    delphi 编程实现饼状图

    6. **自定义绘图**: 如果VCL的TChart组件不能满足你的特定需求,你可以利用Graphics单元提供的低级别绘图函数,如Canvas对象的Arc、Pie等方法直接绘制饼状图。这提供了更大的灵活性,但需要更多的代码来实现。 7. *...

    自定义View之饼状图

    2. **数据处理**:在饼状图中,数据通常是各个部分的权重或占比。你需要为每个部分分配一个值,然后计算总和,以便确定每个部分相对于整体的比例。这个比例将决定每个扇形的角度。 3. **计算扇形角度**:基于每个...

    在asp网页中实现饼状图

    在ASP(Active Server Pages)网页中实现饼状图是一种常用的数据可视化方法,它能清晰地展示数据比例关系,尤其适用于表现各个部分与整体之间的占比。本文将深入探讨如何利用ASP技术来创建饼状图,以及如何结合...

Global site tag (gtag.js) - Google Analytics