canvas 简单的实现柱状图

效果如何,先看下图

既然看到图片的效果了,那么下面我们进行代码分析

1.封装一个函数来绘画柱形条

// 在 canvas 画一个柱形条
function draw(opts) {
  // 获得 2d 上下文对象
  let ctx = opts.ctx
  let oPoint = opts.oPoint
  let lPoint = opts.lPoint
  ctx.beginPath();
  // 路径的起始点坐标
  ctx.moveTo(oPoint.x, oPoint.y);
  // 线条绘制的坐标
  lPoint.forEach((val, idx) => {
    ctx.lineTo(val.x, val.y);
  });
  // 填充的颜色
  ctx.fillStyle = opts.fillStyle;
  ctx.closePath();
  ctx.fill();
}

2.这里的柱形条所用的颜色我通过下面这个随机函数进行获取

// 随机产生十六进制颜色值
function randomColor() {
  let str = '#'
  for (let i = 0; i < 3; i++) {
    let num = parseInt(256 * Math.random());
    if (num.toString(16).length === 1) {
      str += '0' + num.toString(16)
    } else {
      str += num.toString(16)
    }
  }
  return str
}

3.接下来是 canvas 的核心代码实现:

由于这里我设置的 canvas 的宽度是 400px
所以这里限制产生的柱形条的多少就根据宽度进行匹配
间距为 10px ,这里是 i 的值

let canvas = document.getElementById('myCanvas');
let ctx = canvas.getContext('2d');
// 判断是否支持 canvas
if (ctx) {
  // 随机产生出宽度
  let w = parseInt(30 * Math.random()) + 10
  // 坐标位置
  let i = 10;
  let k = 0;
  for (; i < 400 - w;) {
    // 随机产生出高度
    let h = parseInt(320 * Math.random()) + 50
    draw({
      ctx,
      oPoint: { x: i, y: 400 },
      lPoint: [
        {
          x: i,      // 坐标位置
          y: 400 - h // 画布坐标左上角是(0,0) 往下是 y 值, 往右是 x 值 
        },
        {
          x: i + w,
          y: 400 - h
        },
        {
          x: i + w,
          y: 400
        }
      ],
      fillStyle: randomColor()
    })
    // 间距加上宽度再加上上一个位置坐标
    i += w + 10
    k++;
  }
} else {
  alert('浏览器不支持canvas');
}

分析完了,最后来一个完整的代码展示

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>canvas</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    .chart {
      position: relative;
      margin: 50px;
    }

    .canvas {
      background: #e0e0e0;
    }

    .x-line,
    .y-line {
      position: absolute;
    }

    .x-line {
      left: -48px;
      width: 100px;
      box-sizing: border-box;
      bottom: 4px;
      height: 400px;
    }

    .y-line {
      left: -1px;
      display: flex;
      width: 400px;
      bottom: -96px;
    }

    .x-line-point {
      margin: 0 20px;
    }

    .x-line-point * {
      display: inline-block;
      vertical-align: top;
    }

    .x-line-point span {
      margin: -3px;
    }

    .x-axis {
      width: 1px;
      height: 100px;
      background: #333;
    }

    .y-axios-box {
      position: relative;
      width: 400px;
      height: 100px;
    }

    .y-axis {
      height: 1px;
      background: #333;
    }

    .top1,
    .top2,
    .top3,
    .top4 {
      position: absolute;
      width: 1px;
      background: #333;
      height: 6px;
      top: -6px;
    }

    .top1 {
      left: 99px;
    }

    .top2 {
      left: 198px;
    }

    .top3 {
      left: 297px;
    }

    .top4 {
      left: 396px;
    }

    .bottom1,
    .bottom2,
    .bottom3,
    .bottom4 {
      position: absolute;
      top: 0px;
    }

    .bottom1 {
      left: 86px;
    }

    .bottom2 {
      left: 186px;
    }

    .bottom3 {
      left: 286px;
    }

    .bottom4 {
      left: 386px;
    }
  </style>
</head>

<body>
  <div class="chart">
    <div class="x-line">
      <div class="x-line-point">
        <span>400</span>
        <i class="x-axis"></i>
        <span>-</span>
      </div>
      <div class="x-line-point">
        <span>300</span>
        <i class="x-axis"></i>
        <span>-</span>
      </div>
      <div class="x-line-point">
        <span>200</span>
        <i class="x-axis"></i>
        <span>-</span>
      </div>
      <div class="x-line-point">
        <span>100</span>
        <i class="x-axis"></i>
        <span>-</span>
      </div>
    </div>
    <canvas id="myCanvas" class="canvas" width="400" height="400"></canvas>
    <div class="y-line">
      <div class="y-axios-box">
        <span class="top1"></span>
        <span class="top2"></span>
        <span class="top3"></span>
        <span class="top4"></span>
        <p class="y-axis"></p>
        <span class="bottom1">100</span>
        <span class="bottom2">200</span>
        <span class="bottom3">300</span>
        <span class="bottom4">400</span>
      </div>
    </div>
  </div>

  <script>
    // 在 canvas 画一个柱形条
    function draw(opts) {
      // 获得 2d 上下文对象
      let ctx = opts.ctx
      let oPoint = opts.oPoint
      let lPoint = opts.lPoint
      ctx.beginPath();
      // 路径的起始点坐标
      ctx.moveTo(oPoint.x, oPoint.y);
      // 线条绘制的坐标
      lPoint.forEach((val, idx) => {
        ctx.lineTo(val.x, val.y);
      });
      // 填充的颜色
      ctx.fillStyle = opts.fillStyle;
      ctx.closePath();
      ctx.fill();
    }
    // 随机产生十六进制颜色值
    function randomColor() {
      let str = '#'
      for (let i = 0; i < 3; i++) {
        let num = parseInt(256 * Math.random());
        if (num.toString(16).length === 1) {
          str += '0' + num.toString(16)
        } else {
          str += num.toString(16)
        }
      }
      return str
    }
    let canvas = document.getElementById('myCanvas');
    let ctx = canvas.getContext('2d');
    // 判断是否支持 canvas
    if (ctx) {
      // 随机产生出宽度
      let w = parseInt(30 * Math.random()) + 10
      // 坐标位置
      let i = 10;
      let k = 0;
      for (; i < 400 - w;) {
        // 随机产生出高度
        let h = parseInt(320 * Math.random()) + 50
        draw({
          ctx,
          oPoint: { x: i, y: 400 },
          lPoint: [
            {
              x: i,      // 坐标位置
              y: 400 - h // 画布坐标左上角是(0,0) 往下是 y 值, 往右是 x 值 
            },
            {
              x: i + w,
              y: 400 - h
            },
            {
              x: i + w,
              y: 400
            }
          ],
          fillStyle: randomColor()
        })
        // 间距加上宽度再加上上一个位置坐标
        i += w + 10
        k++;
      }
    } else {
      alert('浏览器不支持canvas');
    }
  </script>
</body>

</html>

猜你喜欢

转载自www.cnblogs.com/webBlog-gqs/p/11284329.html
今日推荐