数据可视化记一基础学习(canvas、svg、WebGL、zrender、D3、Three.js)

一、canvas

canvas 是 HTML5 的新特性,它允许我们使用 canvas 元素在网页上通过 JavaScript 绘制图像。
canvas 参考手册

1.1 canvas 绘图的流程
	 1. 编写 canvas 标签(注意指定宽高)
	 2. 获取 canvas DOM 对象
	 3. 获取 Canvas 对象
	 4. 设置绘图属性
	 5. 调用绘图 API
1.2 入门案例:绘制点、矩形、直线和圆形

在这里插入图片描述

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <canvas id="canvas" width="800" height="800"></canvas>
    <script>
      const canvas = document.getElementById('canvas'); // 获取 DOM 对象
      const ctx = canvas.getContext('2d'); // 获取 Canvas 对象
      ctx.fillStyle = 'red'; // 填充为红色
      ctx.fillRect(0, 0, 50, 50); // 绘制矩形

      ctx.beginPath(); // 开始绘制路径
      ctx.lineWidth = 1; // 线条宽度
      ctx.strokeStyle = 'blue'; // 线条填充色
      ctx.moveTo(100, 100); // 起点坐标
      ctx.lineTo(250, 75); // 中间点坐标
      // 改变线宽
      // ctx.stroke(); // 绘制线段
      // ctx.lineWidth = 2; // 修改线条宽度
      ctx.lineTo(300, 100); // 终点坐标
      ctx.stroke(); // 绘制线段

      ctx.beginPath();
      ctx.lineWidth = 2;
      ctx.strokeStyle = 'green'; // 圆形边框色
      ctx.fillStyle = 'red'; // 圆形填充色
      ctx.arc(200, 200, 50, 0, 2 * Math.PI); // 圆心x坐标,圆心y坐标,半径,开始角度,结束角度绘制圆形
      ctx.stroke(); // 绘制圆形的边框
      ctx.fill(); // 绘制圆形的填充色

      ctx.beginPath();
      ctx.lineWidth = 1;
      ctx.strokeStyle = 'red';
      ctx.moveTo(300, 300);
      ctx.lineTo(301, 301); // 绘制一个点
      ctx.stroke();
    </script>
  </body>
</html>
1.3 进阶案例:图片压缩

在线演示
在这里插入图片描述

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <input type="file" id="upload">
    <script>
      const ACCEPT = ['image/jpg', 'image/png', 'image/jpeg']; // 限定图片文件类型
      const MAXSIZE = 1024 * 1024 * 3; // 限定图片最大容量
      const MAXSIZE_STR = '3MB';
      function convertImageToBase64(file, cb) {
        let reader = new FileReader();
        reader.addEventListener('load', function(e) {
          const base64Image = e.target.result; // 获取文件内容,等同于 reader.result
          cb(base64Image);
          reader = null;
        });
        reader.readAsDataURL(file); // 读取 file 对象中的内容
      }
      function compress(base64Image, cb) {
        let maxW = 1024;
        let maxH = 1024;

        const image = new Image();
        image.addEventListener('load', function() {
          let ratio; // 压缩比
          let needCompress = false; // 是否需要压缩
          if (maxW < image.naturalWidth) {
            needCompress = true;
            ratio = image.naturalWidth / maxW;
            maxH = image.naturalHeight / ratio;
          }
          if (maxH < image.naturalHeight) {
            needCompress = true;
            ratio = image.naturalHeight / maxH;
            maxW = image.naturalWidth / ratio;
          }
          if (!needCompress) {
            maxW = image.naturalWidth;
            maxH = image.naturalHeight;
          }
          const canvas = document.createElement('canvas');
          canvas.setAttribute('id', '__compress__');
          canvas.width = maxW;
          canvas.height = maxH;
          canvas.style.visibility = 'hidden';
          document.body.append(canvas);

          const ctx = canvas.getContext('2d');
          ctx.clearRect(0, 0, maxW, maxH);
          ctx.drawImage(image, 0, 0, maxW, maxH); // 渲染图片
          const compressImage = canvas.toDataURL('image/jpeg', 0.9); // 压缩图片
          cb(compressImage);
          const _image = new Image();
          _image.src = compressImage; // 设置图片地址
          document.body.appendChild(_image); // 渲染图片
          canvas.remove(); // 移除 canvas
        });
        image.src = base64Image; // 将图片设置到 image 的 src 属性中
        document.body.appendChild(image);
      }
      function uploadImage(compressImage) {
        console.log('upload image to server...', compressImage);
      }
	  
	  // 获取dom元素
      const upload = document.getElementById('upload');
      // 事件监听
      upload.addEventListener('change', function(e) {
        // 下面为ES6写法,等价 const file = e.target.files[0];
        const [file] = e.target.files;
        console.log(file);
        // 没有文件,直接return
        if (!file) {
          return;
        }
        const { type: fileType, size: fileSize } = file;
        // 图片类型检查
        if (!ACCEPT.includes(fileType)) {
          alert('不支持上传该格式文件!');
          upload.value = '';
          return;
        }
        // 图片大小检查
        if (fileSize > MAXSIZE) {
          alert('文件超出' + MAXSIZE_STR + '!');
          upload.value = '';
          return;
        }
        // 压缩文件
        convertImageToBase64(file, (base64Image) => compress(base64Image, uploadImage));
      });
    </script>
  </body>
</html>
二、svg

SVG是一种基于 XML 的图像文件格式,它的英文全称为Scalable Vector Graphics,意思为可缩放的矢量图形
svg 参考手册

2.1 svg 绘图的流程
	1、编写 svg 标签,指定宽高
	2、编写 svg 绘图标签
	3、编写绘图属性和样式
2.2 入门案例:绘制点、矩形、直线和圆形
<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
  	// 创建svg画布
    <svg width="800" height="800">
    // 绘制矩形 fill:填充色 stroke-width:边框宽度 stroke:边框颜色
      <rect
        width="50"
        height="50"
        style="fill:red;stroke-width:0;stroke:rgb(0,0,0);"
      />
      // 绘制线
      <line 
        x1="100" 
        y1="100" 
        x2="250" 
        y2="75"
        style="stroke:blue;stroke-width:1"
      />
      <line 
        x1="250" 
        y1="75" 
        x2="300" 
        y2="100"
        style="stroke:blue;stroke-width:1"
      />
      // 绘制圆
      <circle 
        cx="200" 
        cy="200" 
        r="50" 
        stroke="green"
        stroke-width="2" 
        fill="red"
      />
      // 绘制点
      <line 
        x1="300" 
        y1="300" 
        x2="301" 
        y2="301"
        style="stroke:red;stroke-width:1"
      />
    </svg>
  </body>
</html>
三、WebGL

WebGL(Web Graphics Library)是一种 3D 绘图协议,WebGL可以为 HTML5 Canvas 提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示 3D 场景和模型了,还能创建复杂的导航和数据视觉化

3.1 WebGL 案例
3.2 WebGL 绘制点
<html>
  <body>
    <canvas id="canvas" width="200px" height="200px"></canvas>
    <script>
    window.onload = function () {
      //顶点着色器程序
      var VSHADER_SOURCE =
          "void main() {" +
              //设置坐标
          "gl_Position = vec4(0.0, 0.0, 0.0, 1.0); " +
              //设置尺寸
          "gl_PointSize = 10.0; " +
          "} ";
    
      //片元着色器
      var FSHADER_SOURCE =
          "void main() {" +
              //设置颜色
          "gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);" +
          "}";
      //获取canvas元素
      var canvas = document.getElementById('canvas');
      //获取绘制二维上下文
      var gl = canvas.getContext('webgl');
      if (!gl) {
          console.log("Failed");
          return;
      }
      //编译着色器
      var vertShader = gl.createShader(gl.VERTEX_SHADER);
      gl.shaderSource(vertShader, VSHADER_SOURCE);
      gl.compileShader(vertShader);
    
      var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
      gl.shaderSource(fragShader, FSHADER_SOURCE);
      gl.compileShader(fragShader);
      //合并程序
      var shaderProgram = gl.createProgram();
      gl.attachShader(shaderProgram, vertShader);
      gl.attachShader(shaderProgram, fragShader);
      gl.linkProgram(shaderProgram);
      gl.useProgram(shaderProgram);
    
      //绘制一个点
      gl.drawArrays(gl.POINTS, 0, 1);
    }
    </script>
</body>
</html>
四、zrender(echarts底层渲染方式)

zrender 是二维绘图引擎,它提供 Canvas、SVG、VML 等多种渲染方式。ZRender 也是 ECharts 的渲染器。
参考文档官方案例官方案例源码

4.1 zrender 绘图的流程
	1、引入 zrender 库
	2、编写 div 容器
	3、初始化 zrender 对象
	4、初始化 zrender 绘图对象
	5、调用 zrender add 方法绘图
4.2 入门案例:绘制点、矩形、直线和圆形
<!DOCTYPE html>
<html>
  <head>
    // zrender引入文件 
    <script src="https://cdn.jsdelivr.net/npm/zrender@4.3.0/dist/zrender.js"></script>
  </head>
  <body>
    <div id="container" style="width: 800px;height: 800px;"></div>
    <script>
      var zr = zrender.init(document.getElementById('container')); // 初始化
      
      //  定义矩形
      var rect = new zrender.Rect({
        // 矩形的形状
        shape: {
          x: 0,
          y: 0,
          width: 50,
          height: 50
        },
        style: {
          fill: 'red', // 填充颜色
          lineWidth: 0 // 边框宽度
        }
      });
      
      // 定义线段
      var line = new zrender.Polyline({
        shape: {
          points:[
            [100, 100],
            [250, 75],
            [300, 100]
          ]
        },
        style: {
          stroke: 'blue',
          lineWidth: 1
        }
      });
      
      // 定义圆
      var circle = new zrender.Circle({
        shape: {
          cx: 200,
          cy: 200,
          r: 50
        },
        style: {
          fill: 'red',
          stroke: 'green',
          lineWidth: 2
        }
      });

	 // 定义点
      var point = new zrender.Polyline({
        shape: {
          points:[
            [300, 300],
            [301, 301]
          ]
        },
        style: {
          stroke: 'red',
          lineWidth: 1
        }
      });
      zr.add(rect); // 绘制矩形
      zr.add(line); // 绘制线段
      zr.add(circle); // 绘制原型
      zr.add(point);  // 绘制点
    </script>
  </body>
</html>
五、D3

D3(Data-Driven Documents) 是一个 Javascript 图形库,基于 Canvas、Svg 和 HTML。
官网地址D3案例D3.js 学习之路

5.1 入门案例:数据绑定

演示地址

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="https://d3js.org/d3.v5.js"></script>
  </head>
  <body>
    <p>Vue</p>
    <p>React</p>
    <p>Agular</p>
    <button id="datum">datum</button>
    <button id="data">data</button>
    <script>
      var body = d3.select("body");
      var p = body.selectAll("p");
      function doDatum() {
        // datum
        var str = "Framework";
        p.datum(str);
        p.text(function(d, i) {
          return `${d}-${i}`;
        });
      }
      function doData() {
        // data
        var dataset = ['Vue', 'React', 'Agular'];
        p.data(dataset)
          .text(function(d, i) {
            return `${d}-${i}`;
          });
      }
      document.getElementById('datum').addEventListener('click', function(e) {
        doDatum();
      });
      document.getElementById('data').addEventListener('click', function(e) {
        doData();
      });
    </script>
  </body>
</html>
5.2 进阶案例:思维导图

源码地址
在这里插入图片描述

六、Three.js

Three.js 是一个基于 WebGL 的 Javascript 3D 图形库
git地址官方案例

<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/three@0.116.1/build/three.js"></script>
  </head>
  <body>
    <script>
      var camera, scene, renderer;
      var geometry, material, mesh;

      init(); // 图形渲染
      animate(); // 图形动画

      function init() {
      	// 调整camera角度
        camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
        camera.position.z = 1;
        scene = new THREE.Scene(); // 初始化一个场景
        geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
        material = new THREE.MeshNormalMaterial();
        mesh = new THREE.Mesh( geometry, material );
        scene.add( mesh );
        renderer = new THREE.WebGLRenderer( { antialias: true } ); // 绘制
        renderer.setSize( window.innerWidth, window.innerHeight );
        document.body.appendChild( renderer.domElement );
      }

	  // 定义动画
      function animate() {
        requestAnimationFrame( animate );
        mesh.rotation.x += 0.01;
        mesh.rotation.y += 0.02;
        renderer.render( scene, camera );
      }
    </script>
  </body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值