<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>面向對象的思惟繪製折線圖</title>
<style>
canvas {
border: 1px solid #dddddd;
display: block;
margin: 50px auto 0;
}
</style>
</head>
<body>
<canvas height="400" width="600"></canvas>
<script>
//構造函數
var LineChart = function (ctx) {
//獲取繪圖工具
this.ctx = ctx || document.querySelector('canvas').getContext('2d');
//獲取畫布大小
this.canvasWidth = this.ctx.canvas.width;
this.canvasHeight = this.ctx.canvas.height;
//網格大小
this.gridSzie = 10;
//座標系間距
this.space = 20;
//箭頭大小
this.arrowSize = 10;
//點大小
this.dottedSize = 6;
//座標系原點
this.x0 = this.space;
this.y0 = this.canvasHeight - this.space;
};
//添加原型方法
LineChart.prototype.init = function (data) {
this.drawGrid();
this.drawCoordinate();
this.drawDotted(data);
};
//繪製網格方法
LineChart.prototype.drawGrid = function () {
//開啓一個新的軌跡
this.ctx.beginPath();
this.ctx.strokeStyle = '#eee';
//X方向的線
var xLineTotal = this.canvasWidth / this.gridSzie;
for (var i = 0; i < xLineTotal; i++) {
this.ctx.moveTo(0, i * this.gridSzie - 0.5);
this.ctx.lineTo(this.canvasWidth, i * this.gridSzie - 0.5);
this.ctx.stroke();
}
//y方向的線
var yLineTotal = this.canvasHeight / this.gridSzie;
for (var i = 0; i < xLineTotal; i++) {
this.ctx.moveTo(i * this.gridSzie - 0.5, 0);
this.ctx.lineTo(i * this.gridSzie - 0.5, this.canvasHeight);
this.ctx.stroke();
}
};
//繪製座標系
LineChart.prototype.drawCoordinate = function () {
//繪製x軸座標系
this.ctx.beginPath();
this.ctx.strokeStyle = '#000';
this.ctx.moveTo(this.x0, this.y0);
this.ctx.lineTo(this.canvasWidth - this.space, this.y0);
this.ctx.lineTo(this.canvasWidth - this.space - this.arrowSize, this.y0 + this.arrowSize / 2);
this.ctx.lineTo(this.canvasWidth - this.space - this.arrowSize, this.y0 - this.arrowSize / 2);
this.ctx.lineTo(this.canvasWidth - this.space, this.y0);
this.ctx.stroke();
this.ctx.fill();
//繪製Y軸座標系
this.ctx.beginPath();
this.ctx.moveTo(this.x0, this.y0);
this.ctx.lineTo(this.space, this.space);
this.ctx.lineTo(this.space + this.arrowSize / 2, this.space + this.arrowSize);
this.ctx.lineTo(this.space - this.arrowSize / 2, this.space + this.arrowSize);
this.ctx.lineTo(this.space, this.space);
this.ctx.stroke();
this.ctx.fill();
};
//繪製多個點,連成折線圖
LineChart.prototype.drawDotted = function (data) {
// 將數據的座標須要轉換成canvas座標
var that = this;
var preCanvasX = 0;
var preCanvasY = 0;
//遍歷數組進行繪點
data.forEach(function (item, i) {
var canvasX = that.x0 + item.x;
var canvasY = that.y0 - item.y;
//繪製點
that.ctx.beginPath();
that.ctx.moveTo(canvasX - that.dottedSize / 2, canvasY - that.dottedSize / 2);
that.ctx.lineTo(canvasX + that.dottedSize / 2, canvasY - that.dottedSize / 2);
that.ctx.lineTo(canvasX + that.dottedSize / 2, canvasY + that.dottedSize / 2);
that.ctx.lineTo(canvasX - that.dottedSize / 2, canvasY + that.dottedSize / 2);
that.ctx.closePath();
that.ctx.fill();
//連線
if (i == 0) {
that.ctx.beginPath();
that.ctx.moveTo(that.x0, that.y0);
that.ctx.lineTo(canvasX, canvasY);
that.ctx.stroke();
} else {
that.ctx.beginPath();
that.ctx.moveTo(preCanvasX, preCanvasY);
that.ctx.lineTo(canvasX, canvasY);
that.ctx.stroke();
}
//將此次的canvasX 和canvasY保存起來,爲下次使用
preCanvasX = canvasX;
preCanvasY = canvasY;
});
};
//定義一個包含多個點的數據
var data = [
{
x: 100,
y: 100
},
{
x: 160,
y: 140
},
{
x: 250,
y: 40
},
{
x: 400,
y: 300
},
{
x: 500,
y: 80
}
];
//初始化對象
var lineChart = new LineChart();
lineChart.init(data);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>繪製扇形統計圖</title>
<style>
canvas {
border: solid 1px #dddddd;
display: block;
margin: auto;
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
/*繪製扇形統計圖(面向對象的思惟)
* 1.繪製扇形
* 2.繪製標題
*3. 繪製說明*/
var PieChart = function (ctx) {
//繪製工具
this.ctx = ctx || document.querySelector('canvas').getContext('2d');
//繪製餅圖的中心;
this.w = this.ctx.canvas.width;
this.h = this.ctx.canvas.height;
this.x0 = this.w / 2 + 60;
this.y0 = this.h / 2;
//餅圖半徑
this.radius = 150;
//標題伸出距離圓心的距離
this.outline = 15;
//說明矩形的寬和高
this.rectW = 30;
this.rectH = 16;
this.space = 20;
};
PieChart.prototype.init = function (data) {
this.drawPie(data);
};
PieChart.prototype.drawPie = function (data) {
var that = this;
//將角度轉化爲弧度
var newData = this.transFormData(data);
//繪製餅狀圖
var startAngle = 0;
newData.forEach(function (item, i) {
var endAngle = startAngle + item.angle;
that.ctx.beginPath();
that.ctx.moveTo(that.x0, that.y0);
that.ctx.arc(that.x0, that.y0, that.radius, startAngle, endAngle);
//添加隨機顏色
var color = that.ctx.fillStyle = that.getRandomColor();
that.ctx.fill();
//調用畫標題的方法.
that.drawTitle(startAngle, item.angle, color, item.title);
//調用畫說明的方法
that.drawDesc(i, item.title);
//將下一次的起始值設爲本次繪畫的結束值
startAngle = endAngle;
});
};
PieChart.prototype.drawTitle = function (startAngle, angle, color, text) {
/*須要先找到伸出點的座標
* 1.計算出斜邊相對於圓點的座標*/
var edge = this.radius + this.outline;
var edgeX = edge * Math.cos(startAngle + angle / 2);
var edgeY = edge * Math.sin(startAngle + angle / 2);
//伸出點的座標
var outX = this.x0 + edgeX;
var outY = this.y0 + edgeY;
//畫線
this.ctx.beginPath();
this.ctx.moveTo(this.x0, this.y0);
this.ctx.lineTo(outX, outY);
this.ctx.strokeStyle = color;
this.ctx.stroke();
//畫底部線;
//字體大小
this.ctx.font = "14px Microsoft YaHei";
this.ctx.textBaseline = "bottom";
var textWidth = this.ctx.measureText(text).width;
if (outX > this.x0) {
this.ctx.textAlign = 'left';
this.ctx.lineTo(outX + textWidth, outY);
} else {
this.ctx.textAlign = 'right';
this.ctx.lineTo(outX - textWidth, outY);
}
this.ctx.stroke();
//畫文字
this.ctx.fillText(text, outX, outY);
};
PieChart.prototype.drawDesc = function (index, title) {
/*畫說明矩形*/
this.ctx.fillRect(this.space, this.space + index * (this.space + 10), this.rectW, this.rectH);
/*畫說明內容*/
this.ctx.beginPath();
this.ctx.textAlign="left";
this.ctx.textBaseline='top';
this.ctx.fillText(title, this.space+this.rectW + 10, this.space + index * (this.space + 10));
};
//獲得一個隨機的顏色
PieChart.prototype.getRandomColor = function () {
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
return 'rgb(' + r + ',' + g + ',' + b + ')';
};
//將數據的須要統計的數據轉換成弧度,並返回該數據
PieChart.prototype.transFormData = function (data) {
var total = 0;
data.forEach(function (item, i) {
total += item.num;
});
//計算出角度並添加一個屬性記錄角度
data.forEach(function (item, i) {
var angle = item.num / total * Math.PI * 2;
item.angle = angle;
});
return data;
};
var data = [
{title: '數計學院', num: 432},
{title: '音樂學院', num: 200},
{title: '經法學院', num: 189},
{title: '體育學院', num: 385},
{title: '文旅學院', num: 199}
];
//實例化對象,並調用該對象的初始化方法
var pieChart = new PieChart();
pieChart.init(data);
</script>
</body>
</html>