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);
?>

實現效果圖


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM