<!DOCTYPE html><html lang="utf-8"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><head> ????<title>库存曲线</title> ???</head> ????<body onload="draw()"> ???????<canvas id="myCanvus" width="840px" height="240px" style="border:1px dashed black;"> ???????????出现文字表示你的浏览器不支持HTML5 ???????</canvas> ????</body></html><script type="text/javascript"><!-- ???function draw(){ ???????var canvas=document.getElementById("myCanvus"); ???????var canvasWidth=840; ???????var canvasHeight=240; ???????var context=canvas.getContext("2d"); ???????????????context.fillStyle = "white"; ???????context.fillRect(0, 0, canvasWidth, canvasHeight); ???????context.strokeStyle = "black"; ???????context.fillStyle = "black"; ???????context.save(); ???????????????// 进行坐标变换:把原点放在左下角,东方为X轴正向,北方为Y轴正向 ???????var offset=20;// 偏移值,用来画坐标轴 ???????context.save(); ???????context.translate(0+offset,canvasHeight-offset); ???????context.rotate(getRad(180)); ???????context.scale(-1,1); ???????????????drawAxisX(context); ???????drawAxisY(context); ???????var actualStock=100; ???????var inbounds=[50,0,50,0,50,0,50,0,50,0,90,0,90,0,90,0,90,0,]; ???????var outbounds=[0,70,0,70,0,70,0,70,0,70,0,70,0,70,0,70,0,70,]; ???????drawStockCurve(context,actualStock,inbounds,outbounds); ???????drawBounds(context); ???????context.restore(); ???????context.fillText("每日库存变化折线",400,50); ???????context.fillText("库存",10,20); ???????context.fillText("日期",800,235); ???} ???function drawBounds(ctx){ ???????ctx.save(); ???????????????ctx.lineWidth=0.5; ???????ctx.strokeStyle=‘red‘; ???????// 画underage ???????ctx.beginPath(); ???????ctx.moveTo(0, 25); ???????ctx.lineTo(800, 25); ???????ctx.stroke(); ???????ctx.closePath(); ???????ctx.save(); ???????ctx.translate(-10,25); ???????ctx.rotate(getRad(180)); ???????ctx.scale(-1,1); ???????ctx.fillText("告罄",0,0); ???????ctx.restore(); ???????ctx.restore(); ???????ctx.save(); ???????????????ctx.lineWidth=0.5; ???????ctx.strokeStyle=‘red‘; ???????// 画underage ???????ctx.beginPath(); ???????ctx.moveTo(0, 125); ???????ctx.lineTo(800, 125); ???????ctx.stroke(); ???????ctx.closePath(); ???????ctx.save(); ???????ctx.translate(-10,125); ???????ctx.rotate(getRad(180)); ???????ctx.scale(-1,1); ???????ctx.fillText("超储",0,0); ???????ctx.restore(); ???????ctx.restore(); ???} ???function drawStockCurve(ctx,actualStock,inbounds,outbounds){ ???????ctx.save(); ???????????????ctx.lineWidth=1; ???????ctx.strokeStyle=‘black‘; ???????ctx.fillStyle=‘black‘; ???????var y=actualStock; ???????var x; ???????ctx.beginPath(); ???????for(var i=0;i<inbounds.length;i++){ ???????????y=y+inbounds[i]-outbounds[i]; ???????????x=i*50; ???????????ctx.lineTo(x, y); ???????????ctx.save(); ???????????// 因坐标变换会导致文字错位,故采用位移+旋转+缩放的方式恢复 ???????????ctx.translate(x,y); ???????????ctx.rotate(getRad(180)); ???????????ctx.scale(-1,1); ???????????ctx.fillText("("+i+","+y+")",0,0); ???????????ctx.restore(); ???????} ???????ctx.stroke(); ???????ctx.closePath(); ???????ctx.restore(); ???} ???function drawAxisX(ctx){ ???????ctx.save(); ???????????????ctx.lineWidth=0.5; ???????ctx.strokeStyle=‘navy‘; ???????ctx.fillStyle=‘navy‘; ???????// 画轴 ???????ctx.beginPath(); ???????ctx.moveTo(0, 0); ???????ctx.lineTo(800, 0); ???????ctx.stroke(); ???????ctx.closePath(); ???????ctx.beginPath(); ???????ctx.moveTo(800-Math.cos(getRad(15))*10, Math.sin(getRad(15))*10); ???????ctx.lineTo(800, 0); ???????ctx.lineTo(800-Math.cos(getRad(15))*10, -Math.sin(getRad(15))*10); ???????ctx.stroke(); ???????ctx.closePath(); ???????????????// 画刻度 ???????var x,y; ???????y=5; ???????for(x=50;x<800;x+=50){ ???????????ctx.beginPath(); ???????????ctx.moveTo(x, 0); ???????????ctx.lineTo(x, y); ???????????????????????ctx.stroke(); ???????????ctx.closePath(); ???????} ???????// 写文字 ???????var i=0; ???????for(x=0;x<800;x+=50){ ???????????ctx.save(); ???????????ctx.scale(1,-1); ???????????ctx.fillText(i,x,y+10); ???????????ctx.restore(); ???????????i++; ???????} ???????ctx.restore(); ???} ???function drawAxisY(ctx){ ???????ctx.save(); ???????????????ctx.lineWidth=0.5; ???????ctx.strokeStyle=‘navy‘; ???????ctx.fillStyle=‘navy‘; ???????// 画轴 ???????ctx.beginPath(); ???????ctx.moveTo(0, 0); ???????ctx.lineTo(0, 200); ???????ctx.stroke(); ???????ctx.closePath(); ???????ctx.beginPath(); ???????ctx.moveTo(Math.sin(getRad(15))*10, 200-Math.cos(getRad(15))*10); ???????ctx.lineTo(0, 200); ???????ctx.lineTo(-Math.sin(getRad(15))*10, 200-Math.cos(getRad(15))*10); ???????ctx.stroke(); ???????ctx.closePath(); ???????????????// 画刻度 ???????var x,y; ???????x=5; ???????for(y=50;y<200;y+=50){ ???????????ctx.beginPath(); ???????????ctx.moveTo(x, y); ???????????ctx.lineTo(0, y); ???????????????????????ctx.stroke(); ???????????ctx.closePath(); ???????} ???????// 写文字 ???????x=-19; ???????for(y=50;y<200;y+=50){ ???????????ctx.save(); ???????????????????????ctx.scale(1,-1); ???????????ctx.translate(0,-200); ???????????ctx.fillText(200-y,x,y); ???????????ctx.restore(); ???????} ???????ctx.restore(); ???} ???function getRad(degree){ ???????return degree/180*Math.PI; ???}//--></script>
HTML5 Canvas 绘制库存变化折线 增加超储告罄线
原文地址:http://www.cnblogs.com/xiandedanteng/p/7594559.html