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

tech2024-05-20  65

目录

一、canvas1.1 canvas 绘图的流程1.2 入门案例:绘制点、矩形、直线和圆形1.3 进阶案例:图片压缩 二、svg2.1 svg 绘图的流程2.2 入门案例:绘制点、矩形、直线和圆形 三、WebGL3.1 WebGL 案例3.2 WebGL 绘制点 四、zrender(echarts底层渲染方式)4.1 zrender 绘图的流程4.2 入门案例:绘制点、矩形、直线和圆形 五、D35.1 入门案例:数据绑定5.2 进阶案例:思维导图 六、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 案例
案例1:3D魔方案例2:化学模型案例3:3D地球案例4:3D大脑
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>
最新回复(0)