最終效果圖如下:

實現步驟如下:注-引用了jQuery
HTML代碼
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>canvas繪制折線圖</title> <script src="scripts/jquery-1.11.3.js"></script> <script src="scripts/recordPaint.js"></script> <style> </style> </head> <script> $(function(){ /* * 定義繪制折線圖的關鍵數據(12個月的消費記錄-金額) * 封裝函數專門用於繪制折線圖 recordPaint(Elem,Data)方法 * Elem - 表示<canvas>元素 * Data - 表示關鍵數據 */ var datas = [1200,2000,3000,500,200,800,1800,2200,2600,1000,600,300]; recordPaint($("#recordCvs")[0],datas); }); </script> <body> <div id="recordContent"> <canvas id="recordCvs" width="600" height="400"></canvas> </div> </body> </html>
JS代碼:即HTML中引用的外部JS文件<script src="scripts/recordPaint.js"></script>
/**
* Created by walker on 2015/11/26.
* 定義recordPaint()方法
*/
function recordPaint(Elem,Data){
// 1. 創建畫布對象
var context = Elem.getContext('2d');
// 2. 獲取畫布的寬度和高度
const WIDTH = Elem.width;
const HEIGHT = Elem.height;
// 3. 定義坐標軸相對畫布的內邊距
var padding = 20;//初始化內邊距
var paddingLeft = 60;//至少大於繪制文字的寬度
var paddingBottom = 30;//至少大於繪制文字的高度
// 4. 定義繪制坐標軸的關鍵點的坐標值
var axisY = {// y軸的起點坐標值
x : paddingLeft,
y : padding
};
var origin = {// 原點坐標值(x軸與y軸相交點)
x : paddingLeft,
y : HEIGHT - paddingBottom
};
var axisX = {
x : WIDTH - padding,
y : HEIGHT - paddingBottom
};
// 5. 繪制坐標軸
context.beginPath();
context.moveTo(axisY.x,axisY.y);
context.lineTo(origin.x,origin.y);
context.lineTo(axisX.x,axisX.y);
context.stroke();
// 6. 繪制坐標軸的箭頭
context.beginPath();
context.moveTo(axisY.x-5,axisY.y+10);
context.lineTo(axisY.x,axisY.y);
context.lineTo(axisY.x+5,axisY.y+10);
context.stroke();
context.beginPath();
context.moveTo(axisX.x-10,axisX.y-5);
context.lineTo(axisX.x,axisX.y);
context.lineTo(axisX.x-10,axisX.y+5);
context.stroke();
// 定義折點的x軸值
var pointsX = [];
// 7. 繪制坐標軸的刻度(x軸的月份和y軸的金額)
// x軸的月份
var month = {
x : paddingLeft,
y : HEIGHT - paddingBottom
}
// 設置字體
context.font = "14px 微軟雅黑";
// 設置垂直對齊
context.textBaseline = "top";
for(var i=1;i<=12;i++){
pointsX[pointsX.length] = month.x;
// 繪制月份信息
context.fillText(i+"月",month.x,month.y);
// 改變每次繪制的x坐標軸的值
month.x += (axisX.x - origin.x)/12;
}
// 繪制y軸的金額
// 從眾多的關鍵金額中,取到最高金額
/*
var datas = [];
for(index in Data){
datas[datas.length] = Data[index];
}
function sortNumber(a,b){
return a - b;
}
var max = datas.sort(sortNumber)[datas.length-1];
*/
var max = Math.max.apply(Math,Data);
var moneyY = (origin.y - axisY.y)/(max/500+1);
// 定義繪制的坐標值
var money = {
x : axisY.x - 5,
y : axisY.y + moneyY,
jin : max
}
// 設置水品對齊
context.textAlign = "right";
// 遍歷"最高值/間隔"次
for(var i=0;i<max/500;i++){
// 繪制金額
context.fillText(money.jin+"元",money.x,money.y);
// y軸向下移動(增加)
money.y += moneyY;
// 金額每次減500
money.jin -= 500;
}
/*
繪制折線
* 12個折點的x軸值,對應12個月文字的x軸值
* 折點的y軸值等於原點的y軸值-折點到原點的距離
* 折點到原點的距離 = (3000點的y到原點的y的長度)*當前金額/3000
*/
context.beginPath();
for(var i=0;i<Data.length;i++){
// 獲取折點的x和y值
var pointY = origin.y - (origin.y - (axisY.y + moneyY))*Data[i]/max;
var pointX = pointsX[i];
// 繪制折線
if(i == 0){
context.textAlign = "left";
//context.textBaseline = "bottom";
context.moveTo(pointX,pointY);
}else{
context.textAlign = "center";
context.textBaseline = "bottom";
context.lineTo(pointX,pointY);
}
// 繪制折點的金額
context.fillText(Data[i],pointX,pointY);
}
context.stroke();
// 繪制12個折點的圓
for(var i=0;i<Data.length;i++){
// 獲取折點的x和y值
var pointY = origin.y - (origin.y - (axisY.y + moneyY))*Data[i]/max;
var pointX = pointsX[i];
// 繪制圓
context.fillStyle = "red";
context.beginPath();
context.arc(pointX,pointY,3,0,Math.PI*2);
context.fill();
}
}
總結:每個拐點的坐標值要清晰
