写点什么

canvas- 绘制一个柱状图

  • 2023-04-25
    广东
  • 本文字数:1784 字

    阅读完需:约 6 分钟

canvas-绘制一个柱状图

前言

最近也是在学习 canvas,跟着绘制了一个最基本柱状图,canvas 是一个基于 HTML5 的绘图标准,提供了一系列的 API 可以用来绘制图形,包括直线、矩形、圆形、文本等等。我介绍如何使用 canvas 绘制简单的柱状图,并优化技巧,使得代码更加高效



绘制柱状图

在上图的柱状图里有什么?


  • 坐标轴:横轴和纵轴,横轴用来表示数据的分类或者时间,纵轴用来表示数据的大小或者数量

  • 柱子:柱状图的每一个数据点通常用一个矩形或者条形来表示,其高度表示该数据的大小或数量

绘制坐标轴

首先来对画布进行一个初始化,获取 canvas 元素并获取其 2D 上下文对象的,对 canvas 元素的尺寸进行缩放,将 canvas 元素的 CSS 宽高设置为它在 HTML 中设置的宽度和高度,确保 canvas 在页面中显示的大小不会改变,然后根据设备像素比扩大画布的像素,提高图像的清晰度,防止模糊发虚


<canvas id="canvas" width="600" height="500"></canvas><script>  const canvas = document.getElementById("canvas");  const ctx = canvas.getContext("2d");  canvas.style.width = canvas.width + "px";  canvas.style.height = canvas.height + "px";  canvas.width = canvas.width * 1.5;  canvas.height = canvas.height * 1.5;</script>
复制代码


然后定义一些相关的属性,在绘制的过程中以备使用


const ht = canvas.clientHeight; //画布高度const wd = canvas.clientWidth; //画布宽度const pad = 20; //边距const bottomPad = 20; //底部边距const step = 100; //坐标轴刻度间距
复制代码


首先要把坐标轴的那条直角画出来,设置 lineWidth 线宽为 2,strokeStyle 笔画颜色为'lightblue',绘制的起点为定义好的常量 pad 为 20,一直绘制到最底部然后再往右边绘制


// 绘制坐标轴ctx.beginPath();ctx.lineWidth = 2;ctx.strokeStyle = "lightblue";ctx.moveTo(pad, pad);ctx.lineTo(pad, ht * 1.5 - bottomPad);ctx.lineTo(wd * 1.5 - pad, ht * 1.5 - bottomPad);ctx.stroke();ctx.closePath();
复制代码



然后循环绘制 x 轴方向刻度,起点 x 轴固定不变为 pad,y 轴坐标为画布高度 * 1.5 - bottomPad - i * 坐标轴刻度间距,终点 x 轴为 pad + 10,y 轴和起点 y 轴一致


循环 y 轴方向刻度也是同理,只不过是反过来了


// 绘制x轴方向刻度ctx.beginPath();ctx.lineWidth = 1;ctx.strokeStyle = "#666";for (let i = 1; i < Math.floor((ht * 1.5) / step); i++) {ctx.moveTo(pad, ht * 1.5 - bottomPad - i * step);ctx.lineTo(pad + 10, ht * 1.5 - bottomPad - i * step);}ctx.stroke();ctx.closePath();
// 绘制y轴方向刻度ctx.beginPath();ctx.lineWidth = 1;ctx.strokeStyle = "#666";for (let i = 1; i < Math.floor((wd * 1.5) / step); i++) {ctx.moveTo(pad + i * step, ht * 1.5 - bottomPad);ctx.lineTo(pad + i * step, ht * 1.5 - bottomPad + 10);}ctx.stroke();ctx.closePath();
复制代码



绘制柱子

柱子实际上就是一个矩形,绘制矩形分三种,有描边有填充,无描边有填充,有描边无填充


有描边有填充通过rect方法绘制出一个矩形的路径,但不会实际绘制矩形,还需要通过stroke方法和fill方法来绘制描边和填充


无描边有填充通过fillRect方法绘制一个填充的矩形,有描边无填充通过strokeRect方法绘制一个边框矩形


无论是rect方法,fillRect方法还是strokeRect方法都要传入四个参数:x 轴坐标,y 轴坐标,宽度,高度


// 绘制矩形填充ctx.beginPath();ctx.lineWidth = 5; //线条宽度ctx.strokeStyle = "orange"; //笔画颜色ctx.fillStyle = "hotpink"; //填充颜色ctx.rect(100, 100, 300, 200); //绘制矩形路径ctx.stroke(); //绘制描边ctx.fill(); //填充ctx.closePath();
ctx.beginPath();ctx.lineWidth = 4;ctx.strokeStyle = "blue";ctx.strokeRect(100, 310, 300, 200); //绘制矩形(无填充)ctx.closePath();
ctx.beginPath();ctx.fillStyle = "skyblue";ctx.fillRect(410, 310, 300, 200); //绘制矩形(填充)ctx.closePath();
复制代码



知道如何绘制矩形然后就可以绘制出柱子了,只需要绘制有填充五描边的矩形就行了,于是循环调用fillRect方法绘制


ctx.beginPath();for (let i = 1; i < Math.floor((wd * 1.5) / step); i++) {    const height = Math.random() * 500 + 50;    ctx.fillStyle = "#5470C6";    ctx.fillRect(i * step, ht * 1.5 - bottomPad, 40, -height);}ctx.closePath();
复制代码



发布于: 刚刚阅读数: 3
用户头像

你若毁我天堂,我必戳你脊梁 2022-11-01 加入

还未添加个人简介

评论

发布
暂无评论
canvas-绘制一个柱状图_CSS_格斗家不爱在外太空沉思_InfoQ写作社区