最近做了一个canvas的折线图绘制的demo,用面向对象的思想封装了一下,把js部分提取一下差不多算是个小插件吧,输入x,y坐标,可以直接在页面中绘制相应的折线图。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
canvas {
margin: 0 auto;
background-color: #f0f0f0;
border: 1px solid #999999;
}
</style>
</head>
<body>
<form action="">
<input type="text" placeholder="请输入x值" id="valX"/>
<input type="text" placeholder="请输入y值" id="valY"/>
<input type="button" id="sub" value="PaintPoint"/>
</form>
<canvas width="600" height="600" id="cas"></canvas>
//以上为页面结构,接下来进行封装折线图函数
<script>
var cas = document.querySelector("#cas");
var ctx = cas.getContext("2d");
// 创建折线图对象,传入的参数为canvas的宽与高
(function (window) {
function LineChart(wid, hei) {
this.data = [];
this.wid = wid;
this.hei = hei;
// 页面初始化
this.cleanData(this.data);
this.drawCoor();
this.render(this.data)
}
LineChart.prototype = {
// 1、功能1,给页面添加坐标系
constructor:LineChart,
drawCoor: function () {
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(10, 10);
ctx.lineTo(10, this.hei - 10);
ctx.lineTo(this.wid - 10, this.hei - 10);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(5, 15);
ctx.lineTo(10, 10);
ctx.lineTo(15, 15);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(this.wid - 15, this.hei - 15);
ctx.lineTo(this.wid - 10, this.hei - 10);
ctx.lineTo(this.wid - 15, this.hei - 5);
ctx.stroke();
},
// 2、功能2,给页面输出折线图
render: function (data) {
if (this.data.length != 1) {
for (var i = 0; i < data.length - 1; i++) {
this.drawPoint(data[i].x, data[i].y);
this.drawPoint(data[i + 1].x, data[i + 1].y);
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(data[i].x, data[i].y);
ctx.lineTo(data[i + 1].x, data[i + 1].y);
ctx.stroke();
}
} else {
this.drawPoint(data[0].x, data[0].y);
}
},
// 3、功能3,每次输出一个点,都给这个点描出一个方格
drawPoint: function (x, y) {
ctx.beginPath();
ctx.lineWidth = 4;
ctx.moveTo(x - 2, y - 2);
ctx.lineTo(x + 2, y - 2);
ctx.lineTo(x + 2, y + 2);
ctx.lineTo(x - 2, y + 2);
ctx.closePath();
ctx.stroke();
},
// 4、功能4,给data数组添加元素
addEle: function (valX, valY) {
this.data.push({
// 用户输入的坐标值需要转换成canvas坐标
x: 10 + Number(valX),
y: this.hei - 10 - Number(valY)
});
},
// 5、整理数组,对数组进行排序
cleanData: function (data) {
if (this.data.length != 0) {
for (var i = 0; i < data.length - 1; i++) {
for (var j = 0; j < data.length - i -1; j++) {
if (data[j].x > data[j + 1].x) {
var temp = data[j + 1];
data[j + 1] = data[j];
data[j] = temp;
}
}
}
}else {
return;
}
}
}
// 最后,向外暴露接口
window.LineChart = window.Line = LineChart;
})(window);
var chart = new Line(600, 600);
var sub = document.getElementById("sub");
// 注册点击事件,当点击时给对象数组添加元素,元素为一个以x,y为属性的对象
sub.onclick = function () {
var valX = document.getElementById("valX").value;
var valY = document.getElementById("valY").value;
chart.drawPoint(10 + Number(valX), chart.hei - 10 - Number(valY));
chart.addEle(valX, valY);
chart.cleanData(chart.data);
ctx.clearRect(0, 0, chart.wid, chart.hei);
chart.drawCoor();
chart.render(chart.data);
}
</script>
</body>
</html>
效果: