canvas可以画柱状图,如下就是一个例子,主要用到了lineWidth,beginPath,lineCap等知识点。
效果图
源代码
<!DOCTYPE Html>
<html>
<head>
<title>Line Chart Demo</title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
</head>
<body>
<header>预约挂号人数(<span id="hosUnitDiv"></span>)</header>
<canvas id="canvas2">您的浏览器不支持canvas,请换高版本的浏览器!</canvas>
<script type="text/javascript" >
/*进度条图*/
var progressChart = {
// 绘制chart
drawChart: function(canvas2, data, padding, marginRight, ygap, bgLineColor, scaleColor) {
this.canID2 = document.getElementById("canvas2");
this.content2 = this.canID2.getContext("2d");
// this.canID2.width = 400;
var canRealWidth = this.canID2.width - marginRight; // 图像真实的宽度 (距离右边canvas有一定的距离
var dataMax = this.getArrayMax(data); // 数据中最大的值
var unit = this.getUnitByDataMax(dataMax); // 单位
var xlimt = this.getXLimtByNewData(dataMax / (unit.number)); // x轴刻度 array
var xgap = (canRealWidth - padding) / (xlimt.length - 1); // x轴刻度间距
var newData = this.getNewDataByUnit(data, unit.number);
var ymove = 5; // 整图y轴,向下移动 解决0的时候,显示不全问题
this.canID2.height = ygap * (data.length) + ymove * 4;
// 绘制x轴刻度
for(var i=0; i<xlimt.length; i++) {
// console.log(i*xgap + padding);
this.content2.fillStyle = scaleColor;
// this.content2.textAlign = "left";
// if语句解决最后一个刻度,靠图像右端对齐问题
if(i === xlimt.length -1) {
this.content2.fillText(xlimt[i],i*xgap + padding - 16, ygap*data.length + ygap);
} else {
this.content2.fillText(xlimt[i],i*xgap + padding, ygap*data.length + ygap);
}
}
for(var i=0; i<data.length; i++) {
// 画横线
this.content2.lineWidth=8;
this.content2.strokeStyle=bgLineColor;// 笔触颜色
this.content2.beginPath();
this.content2.moveTo(padding, ygap*i + ymove);
this.content2.lineTo(canRealWidth, ygap*i + ymove);
this.content2.lineCap = 'round';
this.content2.stroke();
this.content2.closePath();
// y轴刻度
this.content2.fillStyle = scaleColor;
this.content2.textAlign = "left";//y轴文字靠右写
// this.content2.textBaseline = "middle";//文字的中心线的调整
this.content2.font = '12px PingFang HK';
this.content2.fillText(data[i].y, 0, ygap*i + 10);
// 画真实数据线
/* 画有渐变色线 */
this.content2.beginPath();
var linear_gradient = this.content2.createLinearGradient(0,0, canRealWidth,50);
linear_gradient.addColorStop(0, '#5c80cd');
linear_gradient.addColorStop(1, '#ac92d3');
this.content2.strokeStyle = linear_gradient;
this.content2.lineJoin = 'round';
this.content2.lineWidth = 8;
this.content2.strokeRect(padding, ygap*i + ymove, newData[i].x * (canRealWidth - padding) / xlimt[xlimt.length - 1], 0);
}
return unit;
},
// 根据x轴最大的数据 判断单位 params: 原始数据中最大的值
getUnitByDataMax: function(maxData) {
if(maxData > 1000 && maxData <= 10000) {
return unit = {text: '百人', number: 100};
} else if(maxData > 10000) {
return unit = {text: '千人', number: 1000};
}
},
// 获取x轴刻度 params:原始数据通过单位处理后的数据 的最大值
getXLimtByNewData: function(handleByUnitNewdataMax) {
if (handleByUnitNewdataMax > 0 && handleByUnitNewdataMax <= 50) {
return xlimt = [0, 10, 20, 30, 40, 50];
} else {
return xlimt = [0, 20, 40, 60 ,80, 100];
}
},
// 根据单位处理原始数据,获取到新的数据
getNewDataByUnit: function(data, unit) {
var canvas2NewData = [];
// var canvas2NewData = canvas2Data.map(function(item) {
// item.x = item.x /unit;
// }); ??? 为什么map不可以
for (var i = 0; i < canvas2Data.length; i++) {
canvas2NewData[i] = {y: canvas2Data[i].y, x:canvas2Data[i].x / unit};
};
return canvas2NewData;
},
// 获取x轴 最大值
getArrayMax: function(array) {
return array.reduce(function(prev, next) {
if (prev.x > next.x) { return prev.x;} else {return next.x};
});
}
}
</script>
<script>
/*进度条图*/
var canvas2Data = [
{x:520, y:'1月'},
{x:1000, y:'2月'},
{x:600, y:'3月'},
{x:2100, y:'4月'},
{x:3400, y:'5月'},
{x:3600, y:'6月'},
{x:4000, y:'7月'},
{x:6000, y:'8月'},
{x:7000, y:'9月'},
{x:9000, y:'10月'}
];
var hosUnit = progressChart.drawChart(canvas2, canvas2Data, 30, 10, 13, '#bcc0c7', '#fff');
document.getElementById('hosUnitDiv').innerText = hosUnit.text;
</script>
</body>
</html>