需求

上一篇章介绍了如何使用Canvas绘制坐标系,那么本篇章来看看怎么简单绘制坐标系中的点。

示例图如下:


Canvas 绘制坐标系中的点以及折线_折线图


可以看到这里绘画的坐标点比较大,为了更好看一些。其实不管大小,基本的绘制步骤如下:

  1. 设置坐标点的中心圆点位置(x0,y0)
  2. 设置坐标点的大小 dotSize
  3. 计算坐标点的上下左右四角的点坐标

条件1和2可以直接通过设置获取,而坐标点上下左右四角坐标看看下面的计算示意图。

计算坐标点的上下左右四角的点坐标


Canvas 绘制坐标系中的点以及折线_2d_02


从上图可以看到要绘制一个正方形坐标点的上下左右四角点坐标的计算方式。
下面来具体示例代码。

绘制坐标系中的点

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
canvas{
border: 1px solid #cccccc;
margin-top: 100px;
margin-left: 100px;
}
</style>
<script type="text/javascript">
window.onload = function () {
/*获取元素*/
var myCanvas = document.querySelector('#myCanvas');
/*获取绘图工具*/
var ctx = myCanvas.getContext('2d');

/*
1. 设置坐标点的中心圆点位置(x0,y0)
2. 设置坐标点的大小 dotSize
3. 计算坐标点的上下左右四角的点坐标
*/

// 1. 设置坐标点的中心圆点位置(x0,y0)
var x0 = 100;
var y0 = 200;

// 2. 获取Canvas的width、height
var CanvasWidth = ctx.canvas.width;
var CanvasHeight = ctx.canvas.height;

// 3.设置坐标点的大小 dotSize
var dotSize = 10;

// 4.计算坐标点的上下左右四角的点坐标: 左上(x1,y1) 左下(x2,y2) 右上(x3,y3) 右下(x4,y4)

var x1 = Math.floor(x0 - dotSize/2);
var y1 = Math.floor(y0 - dotSize/2);

var x2 = Math.floor(x0 - dotSize/2);
var y2 = Math.floor(y0 + dotSize/2);

var x3 = Math.floor(x0 + dotSize/2);
var y3 = Math.floor(y0 - dotSize/2);

var x4 = Math.floor(x0 + dotSize/2);
var y4 = Math.floor(y0 + dotSize/2);

// 5.绘画坐标点
ctx.beginPath();
ctx.moveTo(x1,y1); // 左上点
ctx.lineTo(x2,y2); // 左下点
ctx.lineTo(x4,y4); // 右下点
ctx.lineTo(x3,y3); // 右上点
ctx.closePath();

// 6.填充以及描边y轴
ctx.fill();

}
</script>
</head>
<body>
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>

浏览器显示如下:


Canvas 绘制坐标系中的点以及折线_折线图_03


这样来看,就绘画好了单个坐标系中的点了,下面来增加复杂度,因为一般坐标系的点不会只单一画一个,一般都是后台返回多个点的坐标,然后一起绘画。

那么下面将绘制点的过程写成一个方法,然后定义多个点的坐标,进行多点绘制。

多点绘制

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
canvas{
border: 1px solid #cccccc;
margin-top: 100px;
margin-left: 100px;
}
</style>
<script type="text/javascript">
window.onload = function () {

function drawPoints(data) {

/*获取元素*/
var myCanvas = document.querySelector('#myCanvas');
/*获取绘图工具*/
var ctx = myCanvas.getContext('2d');

/*
1. 设置坐标点的中心圆点位置(x0,y0)
2. 设置坐标点的大小 dotSize
3. 计算坐标点的上下左右四角的点坐标
*/

// 设置坐标点的大小 dotSize
var dotSize = 10;

// 4.遍历点的坐标,以及绘画点
data.forEach(function (item,i) {
console.log("i = " + i + ", x = " + item.x + ", y = " + item.y);

// 1. 设置坐标点的中心圆点位置(x0,y0)
var x0 = item.x;
var y0 = item.y;

// 2.计算坐标点的上下左右四角的点坐标: 左上(x1,y1) 左下(x2,y2) 右上(x3,y3) 右下(x4,y4)

var x1 = Math.floor(x0 - dotSize/2);
var y1 = Math.floor(y0 - dotSize/2);

var x2 = Math.floor(x0 - dotSize/2);
var y2 = Math.floor(y0 + dotSize/2);

var x3 = Math.floor(x0 + dotSize/2);
var y3 = Math.floor(y0 - dotSize/2);

var x4 = Math.floor(x0 + dotSize/2);
var y4 = Math.floor(y0 + dotSize/2);

// 3.绘画坐标点
ctx.beginPath();
ctx.moveTo(x1,y1); // 左上点
ctx.lineTo(x2,y2); // 左下点
ctx.lineTo(x4,y4); // 右下点
ctx.lineTo(x3,y3); // 右上点
ctx.closePath();

// 4.填充以及描边y轴
ctx.fill();
});

}

// 定义需要绘制的点坐标
var points = [
{
x: 20,
y: 80,
},
{
x: 40,
y: 120,
},
{
x: 100,
y: 200,
},
{
x: 150,
y: 300,
},
{
x: 250,
y: 100,
},
{
x: 300,
y: 400,
},
{
x: 350,
y: 50,
}
];

drawPoints(points)

}
</script>
</head>
<body>
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>

浏览器显示如下:


Canvas 绘制坐标系中的点以及折线_折线图_04


那么如果是折线图的话,那就还需要将这些多点连接起来,形成一个折线图。

连接多点,形成折线图

如果要连接多点,形成一点直线,那么每一条连接的线段都需要知道起点和终点。
对于第一个点,那么起点就是坐标原点。
对于第二个点开始,起点就是上一个点的坐标,自身坐标就是终点。

那么在这里关键就是要定义好坐标系的原点,作为第一个点的起点,后续的点只要将上一个点的坐标进行记录,然后将线条绘制起来,就可以形成折线图了。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
canvas{
border: 1px solid #cccccc;
margin-top: 100px;
margin-left: 100px;
}
</style>
<script type="text/javascript">
window.onload = function () {

function drawPoints(data) {

/*获取元素*/
var myCanvas = document.querySelector('#myCanvas');
/*获取绘图工具*/
var ctx = myCanvas.getContext('2d');

/*
1. 设置坐标点的中心圆点位置(x0,y0)
2. 设置坐标点的大小 dotSize
3. 计算坐标点的上下左右四角的点坐标
*/

// 设置坐标点的大小 dotSize
var dotSize = 10;

// 4.遍历点的坐标,以及绘画点
data.forEach(function (item,i) {
// console.log("i = " + i + ", x = " + item.x + ", y = " + item.y);

// 1. 设置坐标点的中心圆点位置(x0,y0)
var x0 = item.x;
var y0 = item.y;

// 2.计算坐标点的上下左右四角的点坐标: 左上(x1,y1) 左下(x2,y2) 右上(x3,y3) 右下(x4,y4)

var x1 = Math.floor(x0 - dotSize/2);
var y1 = Math.floor(y0 - dotSize/2);

var x2 = Math.floor(x0 - dotSize/2);
var y2 = Math.floor(y0 + dotSize/2);

var x3 = Math.floor(x0 + dotSize/2);
var y3 = Math.floor(y0 - dotSize/2);

var x4 = Math.floor(x0 + dotSize/2);
var y4 = Math.floor(y0 + dotSize/2);

// 3.绘画坐标点
ctx.beginPath();
ctx.moveTo(x1,y1); // 左上点
ctx.lineTo(x2,y2); // 左下点
ctx.lineTo(x4,y4); // 右下点
ctx.lineTo(x3,y3); // 右上点
ctx.closePath();

// 4.填充以及描边y轴
ctx.fill();
});

}

function drawLine(data) {
/*获取元素*/
var myCanvas = document.querySelector('#myCanvas');
/*获取绘图工具*/
var ctx = myCanvas.getContext('2d');

// 设置坐标系与边界的间隙大小
var space = 20;

// 2. 获取Canvas的width、height
var canvasWidth = ctx.canvas.width;
var canvasHeight = ctx.canvas.height;

// 3.计算坐标系的原点坐标(x0,y0)
var x0 = space;
var y0 = canvasHeight - space;

/*
遍历绘画多点连接的折线
1. 第一个点与坐标系原点连成一条线
2. 从第二个点开始与上一个点连成一条线,所以需要记录上一个点的坐标
*/

// 记录上一个点坐标
var prev_point_x = null;
var prev_point_y = null;

data.forEach(function (item,i) {
console.log("绘制折线: i = " + i + ", x = " + item.x + ", y = " + item.y);

if (i===0){
console.log("坐标系的原点坐标:x0 = " + x0 + ", y0 = " + y0);
console.log("第一个点的坐标: x = " + item.x + ", y = " + item.y);

// 第一个点与坐标系原点连成一条线
ctx.beginPath();
ctx.moveTo(x0,y0); // 坐标系原点
ctx.lineTo(item.x,item.y); // 第一个点
ctx.stroke();

// 记录当前的点为下一个点的坐标的出发点坐标
prev_point_x = item.x;
prev_point_y = item.y;

}else{ // 从第二个点开始与上一个点连成一条线,所以需要记录上一个点的坐标

ctx.beginPath();
ctx.moveTo(prev_point_x,prev_point_y); // 设置上一个点的坐标为出发点
ctx.lineTo(item.x, item.y); // 设置当前点为终点
ctx.stroke();

// 记录当前的点为下一个点的坐标的出发点坐标
prev_point_x = item.x;
prev_point_y = item.y;

}

})

}

// 定义需要绘制的点坐标
var points = [
{
x: 20,
y: 80,
},
{
x: 40,
y: 120,
},
{
x: 100,
y: 200,
},
{
x: 150,
y: 300,
},
{
x: 250,
y: 100,
},
{
x: 300,
y: 400,
},
{
x: 350,
y: 50,
}
];

drawPoints(points);
drawLine(points);

}
</script>
</head>
<body>
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>

浏览器显示效果如下:


Canvas 绘制坐标系中的点以及折线_2d_05

Canvas 绘制坐标系中的点以及折线_2d_06