Canvas 画折线图
一、画折线图需要有如下准备如下:
1、绘制网格
2、绘制坐标系
3、绘制点
4、点连线就成了折线图
二、绘制网格
1、确认网格(每个格子)的大小
2、确认X轴方向有多少条横线
3、确认Y轴方向有多少条竖线
4、遍历画出来
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <style> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas = document.querySelector("canvas"); var ctx = myCanvas.getContext("2d"); // 确认网格的大小 var grid = 10; // x轴方向画多少条横线 var canvasHeight = ctx.canvas.height; var xLineTotal = Math.floor(canvasHeight / grid); // y轴方向画多少条竖线 var canvasWidth = ctx.canvas.width; var yLineTotal = Math.floor(canvasWidth / grid); // 遍历 // 遍历横线 for(var i = 0; i <= xLineTotal; i++){ ctx.beginPath(); ctx.moveTo(0, i * grid - 0.5); ctx.lineTo(canvasWidth, i * grid -0.5); ctx.strokeStyle = "#ddd"; ctx.stroke(); } // 遍历竖线 for(var i = 0; i <= yLineTotal; i++){ ctx.beginPath(); ctx.moveTo(i * grid, 0 - 0.5); ctx.lineTo(i * grid, canvasHeight - 0.5); ctx.strokeStyle = "#ddd"; ctx.stroke(); } </script> </body> </html>
三、坐标系
1、确定原点位置
2、确定两边的边距
3、确定箭头的长度,绘制等腰三角形
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <style> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas = document.querySelector("canvas"); var ctx = myCanvas.getContext("2d"); var canvasHeight = ctx.canvas.height; var canvasWidth = ctx.canvas.width; // 1、确认边距,和箭头大小 // 边距 var space = 20; // 箭头长 var arrowSize = 10; // 2、确定坐标原点 var x0 = space ; var y0 = canvasHeight - space; // 3、画出X轴和箭头 ctx.beginPath(); ctx.moveTo(x0, y0); ctx.lineTo(canvasWidth - space, y0); ctx.lineTo(canvasWidth - space - arrowSize, y0 + arrowSize / 2); ctx.lineTo(canvasWidth - space - arrowSize, y0 - arrowSize / 2); ctx.lineTo(canvasWidth - space, y0); ctx.fill(); ctx.strokeStyle = "#000"; ctx.stroke(); // 4、画出Y轴和箭头 ctx.beginPath(); ctx.moveTo(x0, y0); ctx.lineTo(space, space); ctx.lineTo(space - arrowSize / 2, space + arrowSize); ctx.lineTo(space + arrowSize / 2, space + arrowSize); ctx.lineTo(space, space); ctx.fill(); ctx.strokeStyle = "#000"; ctx.stroke(); </script> </body> </html>
四、绘制点
1、确定点的尺寸
2、以坐标中心绘制点
var Disc = function(x, y){ this.x = x; this.y = y; } var dicsAside = 6; var dics1 = new Disc(100, 100); ctx.beginPath(); ctx.moveTo(dics1.x - dicsAside / 2, dics1.y - dicsAside / 2); ctx.lineTo(dics1.x + dicsAside / 2, dics1.y - dicsAside / 2); ctx.lineTo(dics1.x + dicsAside / 2, dics1.y + dicsAside / 2); ctx.lineTo(dics1.x - dicsAside / 2, dics1.y + dicsAside / 2); ctx.closePath(); ctx.fill();
五、绘制折线图
注:网格,坐标系,点都能绘制出来了,下面就可以开始绘制折线图了
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <style> canvas{ border: 1px solid #333; } </style> </head> <body> <canvas id="my_canvas" width="600" height="400"></canvas> <script> var LineChart = function(canvas){ // 获取canvas this.canvas = document.querySelector("canvas"); // 获取上下文 this.ctx = this.canvas.getContext("2d"); // 获取画布的高 this.canvasHeight = this.ctx.canvas.height; // 获取画布的宽 this.canvasWidth = this.ctx.canvas.width; // 设置网格格子的大小 this.gridSize = 10; // 设置坐标系边距 this.space = 20; // 设置箭头的长 this.arrowSize = 10; // 设置点的大小 this.dottedSize = 6; } LineChart.prototype.init = function(data){ this.drawGrid(this.ctx, this.canvasHeight, this.canvasWidth, this.gridSize); this.drawCoord(this.ctx, this.space, this.arrowSize, this.canvasHeight, this.canvasWidth); this.drawDotted(data, this.ctx, this.canvasHeight, this.space, this.dottedSize); } // 绘制网格 LineChart.prototype.drawGrid = function(ctx,canvasHeight, canvasWidth, gridSize){ var xLineTotal = Math.floor(canvasHeight / gridSize); var yLineTotal = Math.floor(canvasWidth / gridSize); // 绘制横线 for(var i = 0; i < xLineTotal; i++){ ctx.beginPath(); ctx.moveTo(0, i * gridSize - .5); ctx.lineTo(canvasWidth, i * gridSize - .5); ctx.strokeStyle = "#ddd"; ctx.stroke(); } // 绘制竖线 for(var i = 0; i < yLineTotal; i++){ ctx.beginPath(); ctx.moveTo(i * gridSize - .5, 0 ); ctx.lineTo(i * gridSize - .5, canvasHeight); ctx.strokeStyle = "#ddd"; ctx.stroke(); } } //绘制坐标系 LineChart.prototype.drawCoord = function(ctx, space, arrowSize, canvasHeight, canvasWidth){ var x0 = space; var y0 = canvasHeight - space; // 绘制X轴 ctx.beginPath(); ctx.moveTo(x0, y0); ctx.lineTo(canvasWidth - space, y0); ctx.strokeStyle = "#000"; ctx.stroke(); ctx.lineTo(canvasWidth - space - arrowSize, y0 + arrowSize / 2); ctx.lineTo(canvasWidth - space - arrowSize, y0 - arrowSize / 2); ctx.lineTo(canvasWidth - space, y0); ctx.fill(); // 绘制Y轴 ctx.beginPath(); ctx.moveTo(x0, y0); ctx.lineTo(space, space); ctx.strokeStyle = "#000"; ctx.stroke(); ctx.lineTo(space + arrowSize / 2, space + arrowSize); ctx.lineTo(space - arrowSize / 2, space + arrowSize); ctx.lineTo(space, space); ctx.fill(); } // 绘制点并连线 LineChart.prototype.drawDotted = function(data,ctx,canvasHeight,space,dottedSize){ var x0 = space; var y0 = canvasHeight - space ; var prevCanvasX = 0; var prevCanvasY = 0; data.forEach(function(item,i){ var canvasX = x0 + item.x; var canvasY = y0 - item.y; ctx.beginPath(); ctx.moveTo(canvasX - dottedSize / 2, canvasY - dottedSize / 2); ctx.lineTo(canvasX + dottedSize / 2, canvasY - dottedSize / 2); ctx.lineTo(canvasX + dottedSize / 2, canvasY + dottedSize / 2); ctx.lineTo(canvasX - dottedSize / 2, canvasY + dottedSize / 2); ctx.closePath(); ctx.fill(); ctx.beginPath(); if(i == 0){ ctx.moveTo(x0, y0); ctx.lineTo(canvasX, canvasY); ctx.stroke(); }else{ // ctx.moveTo(x0+data[i-1].x, y0 - data[i-1].y); ctx.moveTo(prevCanvasX, prevCanvasY); ctx.lineTo(canvasX, canvasY); ctx.stroke(); } prevCanvasX = canvasX; prevCanvasY = canvasY; }); } var data = [ { x : 100, y : 100 }, { x : 200, y : 85 }, { x : 300, y : 125 }, { x : 400, y : 200, }, { x : 500, y : 330 } ]; var lineChart = new LineChart("my_canvas"); lineChart.init(data); </script> </body> </html>