Canvas初探--实现一个柱状图

笔者之所以想要深入了解 Canvas,是因为最近几次的实习部门都属于 Data 这个门类下面,所以用echarts之类的图标库会很多很多,那么当然要好好学一下其间的底层原理了。

那么让我们好好聊聊,如何实现一个柱状图

如何实现一个柱状图?

Step1

首先创建一个叫做barchart.html的新文件,并且在其中写入如下代码:

js 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <canvas width="500" height="500" id="canvas"></canvas>
  </body>
  <script>
    var data = [16, 68, 20, 30, 54];
  </script>
</html>
  • Tips 我们知道canvas可以使用fillRect来实现一个矩形。

fillRect(x, y, xWidth, yHeight)

fillRect有四个参数,分别是x的坐标,y的坐标,宽度与高度。

Step2

我们创建文件包含了 canvasscript 元素,对canvas来说,我们标注了他的宽高,它类似于DOM中的DIV元素,我们可以为其添加样式和移动位置。

data变量呢则是一系列的数据集,我们将用这些变量来画柱状图。

接下来我们将获取canvas元素,并且绘制一个底层色(灰色)

js 复制代码
//get a reference to the canvas 
var canvas = document.getElementById('canvas');  
//get a reference to the drawing context 
var c = canvas.getContext('2d');  
//draw c.fillStyle = "gray"; 
c.fillRect(0,0,500,500); 

Step3

在我们的基本条件都具备了之后,我们可以添加数据了,这里采用一个循环来添加。

js 复制代码
//draw data 
c.fillStyle = "blue"; 
for(var i=0; i<data.length; i++) {     
    var dp = data[i];
    c.fillRect(25 + i*100, 30, 50, dp*5);
} 

效果如下:

但是这里有一个问题,我们的柱状图,反了!怎么让他正起来呢?

Step4

我们知道,fillRect的前两个参数是我们的起点x和y的坐标,那么为了实现"正"的效果,我们可以移动起点的位置。

js 复制代码
//draw data 
c.fillStyle = "blue"; 
for(var i=0; i<data.length; i++) {     
    var dp = data[i];
    c.fillRect(25 + i*100, 500-dp*5 - 30 , 50, dp*5);
} 

效果如下:

是不是看起来很舒服啦?

但是现在还有一个问题,我们的坐标轴去哪了???

Step5

现在,让我们一起来画一个坐标轴

  1. 首先需要画x轴和y
js 复制代码
//draw axis lines 
c.fillStyle = "black"; 
c.lineWidth = 2.0; 
c.beginPath(); 
c.moveTo(30,10); 
c.lineTo(30,460); 
c.lineTo(490,460); 
c.stroke(); 
  1. 然后我们要新增y轴标记点和文本
js 复制代码
//draw text and vertical lines 
c.fillStyle = "black"; 
for(var i=0; i<6; i++) {
    c.fillText((5-i)*20 + "",4, i*80+60);
    c.beginPath();
    c.moveTo(25,i*80+60);
    c.lineTo(30,i*80+60);
    c.stroke(); 
} 
  1. 最后新增x轴文本
js 复制代码
var labels = ["JAN","FEB","MAR","APR","MAY"]; 
//draw horiz text 
for(var i=0; i<5; i++) {     
    c.fillText(labels[i], 50+ i*100, 475);
} 

效果如下:

看起来有部分问题,让我们再来做一些调整!

Step6

将背景色改成白色 & 把起点做一下变更。

ini 复制代码
//draw background 
c.fillStyle = "white"; 
c.fillRect(0,0,500,500);  
//draw data 
c.fillStyle = "blue"; 
for(var i=0; i<data.length; i++) {    
    var dp = data[i];     
    c.fillRect(40 + i*100, 460-dp*5 , 50, dp*5); 
} 

噔噔噔噔,我们的柱状图就这样写好啦~

相关推荐
benbenAItalk5 小时前
数字人口播视频的批量生产实践:素材规范、任务编排与质量验收
java·前端·音视频
2601_962885725 小时前
如何用 Python 扫描 A 股跳空缺口并统计缺口回补概率?
java·前端·python
西瓜太郎12346 小时前
Claude Code、Codex CLI、Gemini CLI 能否共用一枚 Key?先看协议选择矩阵
前端·api 网关·claude code·gemini cli·codex cli
多加点辣也没关系6 小时前
JavaScript|第31章:表单与控件
开发语言·javascript·ecmascript
怕浪猫6 小时前
长会话不崩盘:DeepSeek Harness 的上下文压缩与目标管理策略
面试·github·agent
ocean21036 小时前
2025-2026年Python面试高频知识点洞察
开发语言·python·面试·python八股文
陈随易7 小时前
在Finch用了62亿词元,我认为这是新一代Agent工具之神
前端·人工智能·后端
letisgo58 小时前
JAVA 高级进阶07篇《@Transactional失效的8个场景:代理机制到传播行为》
java·面试·transactional·spring事务·aop动态代理
水域安全老周8 小时前
水趣钓鱼救生衣专利拆解:两级锁紧如何解决落水人衣分离
java·前端·网络
计算机魔术师8 小时前
Anthropic CEO突然喊踩刹车,OpenAI罕见力挺:AI这辆车不能只踩油门了
前端