【Canvas】绘制直方图例子
放一个Canvas绘制直方图的例子在这里,以备日后不时之需。
先上图:

代码:
<!DOCTYPE html>
<html lang="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<head>
<title>直方图绘制</title>
<style type="text/css">
.centerlize{
margin:0 auto;
border:0px solid red;
width:1200px;height:600px;
}
</style>
</head>
<body onload="draw();">
<div class="centerlize">
<canvas id="myCanvas" width="1200px" height="600px" style="border:1px dashed black;">
出现文字表示您的浏览器尚不支持HTML5 Canvas
</canvas>
</div>
</body>
</html>
<script type="text/javascript">
<!--
// 画布宽度
const WIDTH=1200;
// 画布高度
const HEIGHT=600;
// 中心固定圆半径
const RADIUS=200;
// 画图前初始化
function draw(){
var canvas=document.getElementById('myCanvas');
canvas.width=WIDTH;
canvas.height=HEIGHT;
context=canvas.getContext('2d');
// 进行屏幕坐标系到笛卡尔坐标系的变换,原点移动到画布中央,右方为X正向,上方为Y的正向
context.translate(0,HEIGHT-50);
context.rotate(getRad(180));
context.scale(-1,1);
slot=new Slot();
animate();
};
//-------------------------------
// 画图
//-------------------------------
function animate(){
let datas=[{text:'勇气',count:80},{text:'毅力',count:120},{text:'果敢',count:450},
{text:'机敏',count:32},{text:'决心',count:360},{text:'明智',count:230}];
slot.update(datas);
slot.paintBg(context);
slot.paint(context);
}
//-------------------------------
// Slot对象定义处
//-------------------------------
function Slot(){
var obj=new Object;
// 画直方图的数据
obj.datas=[];
// 传入参数更新内部数据
obj.update=function(datas){
this.datas=datas;
};
// 画背景
obj.paintBg=function(ctx){
// 清屏
ctx.clearRect(0,-50,WIDTH,HEIGHT);
// 画轴线
//drawAxisX(ctx,0,WIDTH,100);
// drawAxisY(ctx,-50,HEIGHT-50,100);
drawText(ctx,"绘制:逆火狂飙",1150,-35);
};
// 画前景
obj.paint=function(ctx){
const YMAX=450;
let n=this.datas.length;
// --往下是竖向网格线
const stepx=WIDTH/n;
const CW=stepx/3;// CW:Column Width
ctx.lineWidth=0.5;
ctx.strokeStyle='gray';
for(var i=0;i<n;i++){
let x=i*stepx;
let y=YMAX;
// 恢复实线
ctx.setLineDash([]);
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, y);
ctx.stroke();
ctx.closePath();
// 画虚线
ctx.setLineDash([5,2]);
ctx.lineDashOffset=1;
ctx.beginPath();
ctx.moveTo(x+CW, 0);
ctx.lineTo(x+CW, y);
ctx.moveTo(x+2*CW, 0);
ctx.lineTo(x+2*CW, y);
ctx.stroke();
ctx.closePath();
}
// --往下是画横向网格线
const stepy=YMAX/n;
const GH=stepy/3;// GH:Grid Width
for(var i=0;i<=n;i++){
let y=i*stepy;
// 恢复实线
ctx.setLineDash([]);
ctx.beginPath();
ctx.moveTo(0, y);
ctx.lineTo(WIDTH, y);
ctx.stroke();
ctx.closePath();
if(i>0){
// 画虚线
ctx.setLineDash([5,2]);
ctx.lineDashOffset=1;
ctx.beginPath();
ctx.moveTo(0,y-GH);
ctx.lineTo(WIDTH, y-GH);
ctx.moveTo(0,y-2*GH);
ctx.lineTo(WIDTH, y-2*GH);
ctx.stroke();
ctx.closePath();
}
}
// 以最高点定比例
let maxCnt=-1;
for(var i=0;i<n;i++){
var data=this.datas[i];
if(data.count>maxCnt){
maxCnt=data.count;
}
}
const ratio=YMAX/maxCnt;
// --往下是画柱状图
for(var i=0;i<n;i++){
var data=this.datas[i];
var x=i*stepx+(CW);
var y=0;
var w=CW;
var h=data.count*ratio;
// 阴影设置
ctx.shadowOffsetX=3;
ctx.shadowOffsetY=-2;
ctx.shadowBlur=1;
ctx.shadowColor='rgba(0,0,0,0.5)';
// 画柱子
ctx.fillStyle=getColor(i);
ctx.fillRect(x,y,w,h);
// 取消阴影设置
ctx.shadowOffsetX=0;
ctx.shadowOffsetY=0;
// 在柱子顶写文字
ctx.fillStyle="black";
drawText(ctx,data.text+"="+data.count,x+CW/2,h+5);
}
// 书写标题
ctx.fillStyle="navy";
ctx.font="30px 仿宋";
drawText(ctx,"Canvas绘制直方图例子",WIDTH/2,HEIGHT-100);
};
return obj;
}
// 连点成线画曲线
function paintCurve(ctx,color,cds){
var SU=1;// Scale Unit
ctx.strokeStyle = color;
ctx.beginPath();
for(var i=0; i<cds.length; i++){
ctx.lineTo(cds[i].x*SU,cds[i].y*SU);
}
ctx.stroke();
ctx.closePath();
}
//-----------------------------------------------
// 画横轴
// ctx:画布环境
// startx:起始点横坐标
// endx:结束点横坐标
// step:画刻度的步长,注意画刻度处是步长的整倍数
//-----------------------------------------------
function drawAxisX(ctx,startx,endx,step){
ctx.save();
ctx.lineWidth=0.5;
ctx.strokeStyle='navy';
ctx.fillStyle='navy';
// 画轴
ctx.beginPath();
ctx.moveTo(startx, 0);
ctx.lineTo(endx, 0);
ctx.stroke();
ctx.closePath();
// 画箭头
ctx.beginPath();
ctx.moveTo(endx-Math.cos(getRad(15))*10, Math.sin(getRad(15))*10);
ctx.lineTo(endx, 0);
ctx.lineTo(endx-Math.cos(getRad(15))*10, -Math.sin(getRad(15))*10);
ctx.stroke();
ctx.closePath();
// 画刻度
var x,y;
y=5;
for(x=startx;x<endx;x++){
if((x % step)==0){
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, y);
ctx.stroke();
ctx.closePath();
drawText(ctx,x+"",x,y-20);
}
}
ctx.restore();
}
//-----------------------------------------------
// 画纵轴
// ctx:画布环境
// starty:起始点纵坐标
// endy:结束点纵坐标
// step:画刻度的步长,注意画刻度处是步长的整倍数
//-----------------------------------------------
function drawAxisY(ctx,starty,endy,step){
ctx.save();
ctx.lineWidth=0.5;
ctx.strokeStyle='navy';
ctx.fillStyle='navy';
// 画轴
ctx.beginPath();
ctx.moveTo(0, starty);
ctx.lineTo(0, endy);
ctx.stroke();
ctx.closePath();
// 画箭头
ctx.beginPath();
ctx.moveTo(Math.sin(getRad(15))*10, endy-Math.cos(getRad(15))*10);
ctx.lineTo(0, endy);
ctx.lineTo(-Math.sin(getRad(15))*10, endy-Math.cos(getRad(15))*10);
ctx.stroke();
ctx.closePath();
// 画刻度
var x,y;
x=5;
for(y=starty;y<endy;y+=1){
if((y % step)==0){
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(0, y);
drawText(ctx,y+"",x-15,y);
ctx.stroke();
ctx.closePath();
}
}
}
//-------------------------------
// 角度得到弧度
//-------------------------------
function getRad(degree){
return degree/180*Math.PI;
}
//-------------------------------
// 得到颜色
//-------------------------------
function getColor(index){
var arr=["red","purple","blue","green","skyblue","yellow","#aa0000",
"orange","maroon","navy",
"lime","teal","fuchsia",
"aqua","black"];
if(index>arr.length){
index=index % arr.length;
}
return arr[index];
}
//-------------------------------
// 在笛卡尔坐标系中绘制文字
//-------------------------------
function drawText(ctx,text,x,y){
ctx.save();
ctx.translate(x,y)
ctx.rotate(getRad(180))
ctx.scale(-1,1)
ctx.textBaseline="bottom";
ctx.textAlign="center";
ctx.fillText(text,0,0);
ctx.restore();
}
//-->
</script>
END

浙公网安备 33010602011771号