zoukankan      html  css  js  c++  java
  • 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;
           100px;
          box-sizing: border-box;
          bottom: 4px;
          height: 400px;
        }
    
        .y-line {
          left: -1px;
          display: flex;
           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 {
           1px;
          height: 100px;
          background: #333;
        }
    
        .y-axios-box {
          position: relative;
           400px;
          height: 100px;
        }
    
        .y-axis {
          height: 1px;
          background: #333;
        }
    
        .top1,
        .top2,
        .top3,
        .top4 {
          position: absolute;
           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>
  • 相关阅读:
    python 包管理工具 pip 的配置
    Python 变量作用域 LEGB (下)—— Enclosing function locals
    Python 变量作用域 LEGB (上)—— Local,Global,Builtin
    2020 Java 面试题 小结 (答案慢慢补上,有错误请指出)
    mysql 根据日期(date)做年,月,日分组统计查询
    jvm指令
    正则表达式 分割地址 获取省市区详细地址
    .Net 异常记录
    WCF设计服务协议(一)
    plsql ORA-01789:查询块具有不正确的结果列数
  • 原文地址:https://www.cnblogs.com/webBlog-gqs/p/11284329.html
Copyright © 2011-2022 走看看