中国建设质量网官方网站,自己怎样建立网站,百度风云榜小说排行榜历届榜单,hao爱做网站前言 #x1f4eb; 大家好#xff0c;我是南木元元#xff0c;热衷分享有趣实用的文章#xff0c;希望大家多多支持#xff0c;一起进步#xff01; #x1f345; 个人主页#xff1a;南木元元 目录
可视化的含义
浏览器中实现可视化的4种方式
1. HTMLCSS
2. SVG
…前言 大家好我是南木元元热衷分享有趣实用的文章希望大家多多支持一起进步 个人主页南木元元 目录
可视化的含义
浏览器中实现可视化的4种方式
1. HTMLCSS
2. SVG
3. Canvas2D
4. WebGL
技术选型
总结 可视化的含义
说到数据可视化在很多人的印象里可视化就等同于制作下面这些美丽的图表。 但其实数据可视化远不止于此。让我们来问问ChatGPT看看它怎么说。 总结一下可视化就是借助于图形化手段将数据信息组织起来清晰有效的传达与沟通信息。像我们熟知的图形、图表以及地图等都属于数据可视化的范畴。 在Web上图形通常是通过浏览器绘制的本文就来盘点一下在浏览器中渲染绘制图形的几种方式。
浏览器中实现可视化的4种方式
在现代浏览器中实现可视化的绘制技术主要有4种HTMLCSS、Canvas2D、SVG、WebGL。
1. HTMLCSS
HTMLCSS这种方式通常用来呈现普通的 Web 网页在可视化中使用的相对较少但也可以用来实现常见的柱状图、饼图等图表。比如要实现一个柱状图其实也很简单代码如下
HTML代码 div classbar styleheight: 50px;/div
div classbar styleheight: 80px;/div
div classbar styleheight: 120px;/div
div classbar styleheight: 60px;/div CSS代码
.bar {width: 30px;background-color: red;display: inline-block;margin-right: 20px;
}
实现的柱状图效果 再来看看如何实现一个饼图代码如下
.pie {width: 250px;height: 250px;border-radius: 50%;background: conic-gradient(red 6deg, orange 6deg 18deg, yellow 18deg 45deg, green 45deg 110deg, blue 110deg 200deg, purple 200deg);
}
直接使用conic-gradient方法创建一个锥形渐变即可实现。 通过上面的例子可以发现一些常见的可视化图表都可以使用HTML和CSS来实现并且不需要引入额外的第三方库但为什么在可视化领域很少直接用HTML和CSS来绘制图表呢这是因为Web开发以呈现块状内容为主而可视化开发因为需要呈现各种各样的形状结构所以形状更丰富的SVG以及更底层的Canvas2D和WebGL就是更合适的技术了。 此外使用HTMLCSS实现可视化有2个缺点
在绘制复杂图形时使用HTMLCSS的能力有限图形发生变化时重绘的性能开销比较大
第一点其实很好理解HTML和CSS主要还是为网页布局而创造的使用它们虽然能绘制可视化图表但是绘制的方式并不简洁。上面实现的柱状图和折线图都是最基础版如果要实现稍微复杂一点的效果其实就没那么容易了。
第二点HTML和CSS作为浏览器渲染引擎的一部分为了完成页面渲染的工作除了绘制图形外还要做很多额外的工作。如下是浏览器的渲染过程 解析HTML生成DOM树解析CSS生成CSSOM树将DOM树和CSSOM树结合生成渲染树(Render Tree)Layout(回流)根据生成的渲染树进行回流(Layout)得到节点的几何信息位置大小Painting(重绘)根据渲染树以及回流得到的几何信息得到节点的绝对像素Display将像素发送给GPU展示在页面上。
上述过程中当图形发生变化时会触发回流和重绘渲染树中或大或小的部分需要重新计算这样其实性能开销是很大的。而Canvas2D和WebGL相比而言它们的绘图API能够直接操作绘图上下文在重绘图像时不会发生重新解析文档和构建结构的过程开销要小很多。
2. SVG
现代浏览器支持SVGScalable Vector Graphics可缩放矢量图SVG是一种基于XML语法的图像格式可以用图片img元素的src属性加载。而且浏览器还可以内嵌SVG标签并且像操作普通的HTML元素一样利用DOM API 操作SVG元素。下面是使用SVG实现与前面相同的柱状图效果的代码
svg width200 height200rect x0 y80 width30 height50 fillred /rect x50 y50 width30 height80 fillred /rect x100 y10 width30 height120 fillred /rect x150 y70 width30 height60 fillred /
/svg 在上述SVG代码中rect表示绘制一个矩形元素。除了rect外SVG还提供了丰富的图形元素可以绘制矩形、圆弧、椭圆、多边形和贝塞尔曲线等等。现在想要绘制一个饼图只需使用SVG内置的circle标签通过stroke-dasharray属性定义轮廓为虚线来调整stroke-width轮廓宽度就可以实现饼图代码如下
svg viewBox0 0 32 32 width100 height100 styleborder-radius: 50%;circle cx16 cy16 r16 stroke-width32 stroke-dasharray20 100 fillyellow strokered/circlecircle cx16 cy16 r16 stroke-width32 stroke-dasharray40 100 stroke-dashoffset-20 filltransparent strokeblue/circle
/svg 实现的饼图效果 SVG和传统的HTMLCSS的绘图方式差别不大只不过HTML元素在绘制矢量图形方面的能力有些不足而SVG运用了一些SVG支持的特殊属性恰好弥补了这方面的缺陷。因此用SVG绘图比用HTML和CSS要方便很多。
但是SVG图表也有缺点它HTML元素一样在输出图形前都需要经过引擎的解析、布局计算和渲染树生成。如果要绘制的图形很复杂需要大量的SVG元素就会大大增加DOM树渲染和重绘所需要的时间对性能开销非常大所以SVG只适合应用于元素较少的简单可视化场景。
3. Canvas2D
Canvas2D上下文来绘制可视化图表也很方便它是一种指令式的绘图系统我们调用一些绘图指令就可以在画布上绘制图形。而上面的HTMLCSS、SVG其实都属于声明式绘图系统也就是我们根据数据创建各种不同的图形元素或者CSS规则然后利用浏览器渲染引擎解析它们并渲染出来。
我们接下来就继续通过绘制一个上述的柱状图来看看Canvas2D的使用方式代码如下
canvas idmyCanvas width200 height200/canvas
script// 获取canvas元素const canvas document.getElementById(myCanvas);// 获取二维渲染上下文const ctx canvas.getContext(2d);// 设置填充颜色ctx.fillStyle red;// 使用fillRect()绘制填充的矩形ctx.fillRect(0, 80, 30, 50);ctx.fillRect(50, 50, 30, 80);ctx.fillRect(100, 10, 30, 120);ctx.fillRect(150, 70, 30, 60);
/script
其实很简单就是创建一个画布获取渲染上下文然后设置填充颜色最后使用fillRect()绘制相应的填充矩形即可实现简单柱状图 想要更进一步学习的话也可以去看我的这篇文章 。
Canvas的优点是能够直接操作绘图上下文不需要经过HTML、CSS解析、构建渲染树、布局等一系列操作。因此单纯绘图的话Canvas比HTMLCSS、SVG要快得多绘制性能较优。
Canvas的缺点是处理事件交互的时候没有HTML和SVG方便 在HTML和SVG中一个元素对应一个基本图形所以我们可以很方便地操作它们比如在柱状图的某个柱子上注册点击事件相比来说Canvas实现交互就比较麻烦需要手动去计算图形的坐标位置来获取图形。并且如果要绘制的图形太多或者处理大量的像素计算时Canvas2D依然会遇到性能瓶颈。
所以可以总结一下SVG和Canvas2D分别的使用场景当数据量不大且侧重交互的情况用SVG比较合适当数据量较大的时候用Canvas比较合适。
4. WebGL
WebGL是浏览器提供的功能强大的绘图系统它是基于OpenGL ES 规范的浏览器实现的API相对更底层让我们来看看使用WebGL绘制上述的柱状图的代码
const canvas document.getElementById(canvas);
//获取WebGL绘图上下文
const gl canvas.getContext(webgl);
//顶点着色器
const vertexShaderSource attribute vec2 a_position;void main() {gl_Position vec4(a_position, 0.0, 1.0);};//片元着色器
const fragmentShaderSource precision mediump float;void main() {gl_FragColor vec4(1.0, 0.0, 0.0, 1.0);};//创建着色器
const vertexShader gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
const fragmentShader gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
//创建程序对象
const program gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);//获取attribute变量位置
const a_Position gl.getAttribLocation(program, a_position);
//向缓冲区对象写入的数据
const vertices new Float32Array([-1, -1,-0.7, -1,-0.7, -0.5,-0.7, -0.5,-1, -0.5,-1, -1,-0.5, -1,-0.2, -1,-0.2, -0.2,-0.2, -0.2,-0.5, -0.2,-0.5, -1,0, -1,0.3, -1,0.3, 0.2,0.3, 0.2,0, 0.2,0, -1,0.5, -1,0.8, -1,0.8, -0.4,0.8, -0.4,0.5, -0.4,0.5, -1,
])
const vertexBuffer gl.createBuffer();//创建缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);// 绑定缓冲区对象
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);// 将数据写入缓冲区对象
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0); // 调用顶点缓冲
gl.enableVertexAttribArray(a_Position);// 激活a_Position使用缓冲数组
//绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 2);
实现的效果 可以看到使用WebGL绘制一个简单的柱状图它的代码相比上面三种方式就已经复杂了很多需要手写大量的GLSL代码学习成本较高上手比较困难想要了解更多的可以去看我的这两篇文章WebGL简介和快速上手WebGL。
那什么时候需要用到WebGL呢
要绘制的图形数量非常多或要计算的像素点数量非常的多一般是数十万甚至上百万数量级的的时候即使Canvas2D也会达到性能瓶颈这时就需要用WebGL来绘制充分利用GPU并行计算的能力来快速、精准地操作图像的像素实现超高性能绘制。绘制3D物体。WebGL内置了对 3D 物体的投影、深度检测等处理所以用它来渲染 3D 物体就不需要我们自己对坐标做底层的处理了。
技术选型
上述四种方式都有各自的优缺点实际应用中的技术选型可以参考下图 总结
本文主要介绍了在浏览器中实现可视化的4种方式不同的方式有各自的优缺点实际应用中也应该根据具体的场景来选择合适的方案实现可视化以达到最佳效果。
如果此文对你有帮助的话欢迎关注、点赞、⭐收藏、✍️评论支持一下博主~