先分析確認起始坐標點

<!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); ?>
實現效果圖