前言
使用HTML画折线和柱状图,效果图如下:
详细代码CanvasForHtml5已上传到Github
分析
<canvas id="a_canvas" width="950" height="290"></canvas>
<script type="text/javascript">
var a_canvas;
var a_context;
var b_canvas;
var b_context;
window.onload = function() {
a_canvas = document.getElementById('a_canvas');
if(a_canvas && a_canvas.getContext) {
a_context = a_canvas.getContext('2d');
}
b_canvas = document.getElementById('b_canvas');
if(b_canvas && b_canvas.getContext) {
b_context = b_canvas.getContext('2d');
}
var a_data = [7, 3, 5, 5, 14, 3, 27, 35, 26, 28, 27, 17, 20, 27, 19, 23, 26, 33, 22, 30, 25, 20, 17, 15];
var a_data1 = [4, 2, 4, 12, 8, 3, 27, 35, 26, 28, 27, 27, 20, 25, 19, 22, 24, 28, 22, 29, 25, 20, 16, 15];
drawChartWithAnimation(a_context,a_canvas,a_data1);
lineChart(a_context,a_canvas,a_data);
var b_data = [17, 3, 15, 5, 14, 3, 27, 15, 26, 28, 27, 17, 20, 7, 19, 23, 26, 13, 22, 30, 25, 20, 17, 15];
var b_data1 = [14, 2, 14, 12, 8, 3, 27, 15, 26, 28, 27, 27, 20, 5, 19, 22, 24, 18, 22, 29, 25, 20, 16, 15];
drawChartWithAnimation(b_context,b_canvas,b_data1);
lineChart(b_context,b_canvas,b_data);
}
function lineChart(context,canvas,data) {
var minDataValue = 100000000;
for(var i = 0; i < data.length; i++) {
var barVal = parseInt(data[i]);
if(parseInt(barVal) < parseInt(minDataValue))
minDataValue = barVal;
}
// 绘制背景
var gradient = context.createLinearGradient(0, 0, 0, 300);
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
// 描绘边框
var grid_cols = data.length + 1;
var grid_rows = 4;
var cell_height = canvas.height / grid_rows;
var cell_width = canvas.width / grid_cols;
context.lineWidth = 1;
context.strokeStyle = "#a0a0a0";
var max_v = 63;
for(var i = 0; i < data.length; i++) {
var d = 0;
if(data[i] < 0) {
d = d - data[i];
} else { d = data[i]; };
if(d > max_v) { max_v = d };
}
max_v = max_v * 1.0;
// 将数据换算为坐标
var points = [];
for(var i = 0; i < data.length; i++) {
var v = data[i];
var px = cell_width * (i + 1);
var py = canvas.height - canvas.height * (v / max_v);
points.push({ "x": px, "y": py });
}
context.beginPath();
context.fillStyle = "white";
context.font = "25px sans-serif";
context.fillText("0", canvas.width * 0.97, canvas.height);
// 绘制折现
context.beginPath();
context.moveTo(points[0].x, points[0].y);
for(var i = 1; i < points.length; i++) {
context.lineTo(points[i].x, points[i].y);
}
context.lineWidth = 4;
context.strokeStyle = "white";
context.stroke();
// 结束边框描绘
context.save();
context.beginPath();
context.setLineDash([6, 6]);
context.moveTo(0, canvas.height - canvas.height * (data[19] / max_v));
context.lineTo(canvas.width, canvas.height - canvas.height * (data[19] / max_v));
context.lineWidth = 1;
context.strokeStyle = "red";
context.stroke();
context.restore();
//绘制坐标图形
for(var i in points) {
if(i < 19) {
var p = points[i];
context.beginPath();
context.lineWidth = 4;
context.radius = 4;
context.strokeStyle = "white";
context.fillStyle = "#009CEF";
context.arc(p.x, p.y, (canvas.width / data.length - 20) / 2, 0, Math.PI * 2, false);
context.stroke();
context.fill();
context.closePath();
} else {
}
}
context.beginPath();
context.fillStyle = "red";
context.font = "25px sans-serif";
context.fillText(data[19], canvas.width - 50, canvas.height - canvas.height * (data[19] / max_v));
}
function drawChartWithAnimation(context,canvas,data1) {
// 描绘边框
var grid_cols = data1.length + 1;
var grid_rows = 4;
var cell_height = canvas.height / grid_rows;
var cell_width = canvas.width / grid_cols;
var max_v = 63;
for(var i = 0; i < data1.length; i++) {
var d = 0;
if(data1[i] < 0) {
d = d - data1[i];
} else { d = data1[i]; };
if(d > max_v) { max_v = d };
}
max_v = max_v * 1.0;
// 将数据换算为坐标
var points = [];
for(var i = 0; i < data1.length; i++) {
var v = data1[i];
var px = cell_width * (i + 1);
var py = canvas.height - canvas.height * (v / max_v);
points.push({ "x": px, "y": py });
}
for(var i in points) {
var p = points[i];
height = canvas.height - p.y;
width = canvas.width / data1.length - 20;
if(i < 19) {
drawRectangle(p.x - (canvas.width / data1.length - 20) / 2, p.y, width, height, context, true);
} else {
drawRectangle1(p.x - (canvas.width / data1.length - 20) / 2, p.y, width, height, context, true);
}
}
}
function drawRectangle(x, y, w, h, context,fill) {
context.beginPath();
context.rect(x, y, w, h);
drawRoundRect(x, y, w, h, w / 2,context);
context.closePath();
context.stroke();
if(fill) {
var gradient = context.createLinearGradient(0, 0, 0, 300);
gradient.addColorStop(0, '#40FEDD');
gradient.addColorStop(1, '#40FEDD');
context.fillStyle = gradient;
context.strokeStyle = gradient;
context.fill();
}
}
function drawRectangle1(x, y, w, h, context,fill) {
context.beginPath();
context.rect(x, y, w, h);
drawRoundRect(x, y, w, h, w / 2,context);
context.closePath();
context.stroke();
if(fill) {
var gradient = context.createLinearGradient(0, 0, 0, 300);
gradient.addColorStop(0, '#BDBDBD');
gradient.addColorStop(1, '#BDBDBD');
context.fillStyle = gradient;
context.strokeStyle = gradient;
context.fill();
}
}
function drawRoundRect(x, y, width, height, radius,context) {
var value = height - width;
if(value < 0) {
radius = height / 2;
}
context.beginPath();
context.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2);
context.lineTo(width - radius + x, y);
context.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2);
context.lineTo(width + x, height - radius + y);
context.arc(width - radius + x, height - radius + y, radius, 0, Math.PI * 1 / 2);
context.lineTo(radius + x, height + y);
context.arc(radius + x, height - radius + y, radius, Math.PI * 1 / 2, Math.PI);
context.closePath();
}
</script>
结语
博客旧版原文在CSDN上:https://blog.csdn.net/luochuanAD/article/details/73252241