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 = {// 绘制chartdrawChart: 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轴刻度 arrayvar 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>