zoukankan      html  css  js  c++  java
  • canvas绘制折线图

    先分析确认起始坐标点

    <!DOCTYPE HTML>
    <html>
    <head>
    <title>New Document</title>
    <meta charset="utf-8" />
    <script src="jquery-1.11.1.js"></script>
    </head>
    <body>
        <div id="statContainer">
              <canvas id="statCanvas"
                      width="800" height="600">
                  您的浏览器不支持Canvas
              </canvas>
          </div>
    </body>
    <script>
        /*页面加载完成后,向服务器请求当前用户的消费统计信息
         并输出在canvas图形中*/
        $(function () {
            $.getJSON('user-list.php', function (arr) {
                console.log(arr);
                drawStat(arr);
            })
        });
        //该函数用来绘制折线图
        function drawStat(arr) {
            var canvas = $('#statCanvas')[0];//获取dom对象
            var ctx = canvas.getContext('2d');
            //画布的款高
            var cw = canvas.width;
            var ch = canvas.height;
            //内间距padding
            var padding = 80;
            //原点,bottomRight:X轴终点,topLeft:Y轴终点
            var origin = {x:padding,y:ch-padding};
            var bottomRight = {x:cw-padding,y:ch-padding};
            var topLeft = {x:padding,y:padding};
            //绘制X轴
            ctx.beginPath();
            ctx.moveTo(origin.x,origin.y);
            ctx.lineTo(bottomRight.x,bottomRight.y);
            //绘制X轴箭头
            ctx.lineTo(bottomRight.x-20,bottomRight.y-10);
            ctx.moveTo(bottomRight.x,bottomRight.y);
            ctx.lineTo(bottomRight.x-20,bottomRight.y+10);
            //绘制Y轴
            ctx.moveTo(origin.x,origin.y);
            ctx.lineTo(topLeft.x,topLeft.y);
            //绘制Y轴箭头
            ctx.lineTo(topLeft.x-10,topLeft.y+20);
            ctx.moveTo(topLeft.x,topLeft.y);
            ctx.lineTo(topLeft.x+10,topLeft.y+20);
            //设置字号
            ctx.font = '16px SimHei';
            //绘制X方向刻度
            //计算刻度可使用的总宽度
            var avgWidth = (cw - 2*padding - 50)/(arr.length-1);
            for(var i=0;i<arr.length;i++){
                //循环绘制所有刻度线
                if(i > 0){
                    //移动刻度起点
                    ctx.moveTo(origin.x+i*avgWidth,origin.y);
                    //绘制到刻度终点
                    ctx.lineTo(origin.x+i*avgWidth,origin.y-10);
                }
                //X轴说明文字:1月,2月...
                var txtWidth = ctx.measureText(arr[i].key).width;
                ctx.fillText(
                        arr[i].key,
                        origin.x+i*avgWidth-txtWidth/2,
                        origin.y+32);
            }
            //绘制Y方向刻度
            //最大刻度max
            var max = 0;
            for(var i=0;i<arr.length;i++){
                if(arr[i].value>max){
                    max=arr[i].value;
                }
            }
            console.log(max);
    
            /*var max = Math.max.apply(this,arr);
            console.log(max);*/
            var avgValue=Math.floor(max/5);
            var avgHeight = (ch-padding*2-50)/5;
            for(var i=1;i<arr.length;i++){
                //绘制Y轴刻度
                    ctx.moveTo(origin.x,origin.y-i*avgHeight);
                    ctx.lineTo(origin.x+10,origin.y-i*avgHeight);
                //绘制Y轴文字
                var txtWidth = ctx.measureText(avgValue*i).width;
                ctx.fillText(avgValue*i,
                        origin.x-txtWidth-5,
                        origin.y-i*avgHeight+6);
            }
    
            //绘制折线
            for(var i=0;i<arr.length;i++){
                var posY = origin.y - Math.floor(arr[i].value/max*(ch-2*padding-50));
                if(i==0){
                    ctx.moveTo(origin.x+i*avgWidth,posY);
                }else{
                    ctx.lineTo(origin.x+i*avgWidth,posY);
                }
                //具体金额文字
                ctx.fillText(arr[i].value,
                        origin.x+i*avgWidth,
                        posY
                )
            }
            ctx.stroke();
            //绘制折线上的小圆点
            ctx.beginPath();
            for(var i=0;i<arr.length;i++){
                var posY = origin.y - Math.floor(arr[i].value/max*(ch-2*padding-50));
                ctx.arc(origin.x+i*avgWidth,posY,4,0,Math.PI*2);//圆心,半径,画圆
                ctx.closePath();
            }
            ctx.fill();
        }
    </script>
    </html>

    PHP数据代码

    <?php
        //构造前台需要的最近几个月的消费统计信息
        $output = [];
        $output[] = ['key'=>'3月','value'=>3000];
        $output[] = ['key'=>'4月','value'=>2000];
        $output[] = ['key'=>'5月','value'=>0];
        $output[] = ['key'=>'6月','value'=>3500];
        $output[] = ['key'=>'7月','value'=>2800];
        $output[] = ['key'=>'8月','value'=>800];
        //返回json数据
        echo json_encode($output);
    ?>

    实现效果图

  • 相关阅读:
    ACCESS中不支持FULL JOIN的解决方案
    C#語法學習異常處理(Exception)
    C#語法學習(索引器[indexer])
    C#語法學習四(Char)
    人生的35个经典好习惯
    自学.NET之路属性,索引器
    Lucene.Net介紹
    Sql Server 日期格式转换
    MS SQL中的交叉数据报表
    C#語法學習一(Array,ArrayList)
  • 原文地址:https://www.cnblogs.com/liyuhuan/p/5459305.html
Copyright © 2011-2022 走看看