浏览器中实现可视化的方式有哪几种?带你盘点一下

前言

 📫 大家好,我是南木元元,热衷分享有趣实用的文章,希望大家多多支持,一起进步!

 🍅 个人主页:南木元元


目录

可视化的含义

浏览器中实现可视化的4种方式

1. HTML+CSS

2. SVG

3. Canvas2D

4. WebGL

技术选型

总结


可视化的含义

说到数据可视化,在很多人的印象里,可视化就等同于制作下面这些美丽的图表。

但其实数据可视化远不止于此。让我们来问问ChatGPT,看看它怎么说。

总结一下,可视化就是:借助于图形化手段,将数据信息组织起来,清晰有效的传达与沟通信息。像我们熟知的图形、图表以及地图等都属于数据可视化的范畴。 在Web上,图形通常是通过浏览器绘制的,本文就来盘点一下在浏览器中渲染绘制图形的几种方式。

浏览器中实现可视化的4种方式

在现代浏览器中实现可视化的绘制技术主要有4种:HTML+CSS、Canvas2D、SVG、WebGL。

1. HTML+CSS

HTML+CSS这种方式通常用来呈现普通的 Web 网页,在可视化中使用的相对较少,但也可以用来实现常见的柱状图、饼图等图表。比如,要实现一个柱状图,其实也很简单,代码如下:

  • HTML代码

<div class="bar" style="height: 50px;"></div>
<div class="bar" style="height: 80px;"></div>
<div class="bar" style="height: 120px;"></div>
<div class="bar" style="height: 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就是更合适的技术了。

此外,使用HTML+CSS实现可视化有2个缺点:

  1. 在绘制复杂图形时,使用HTML+CSS的能力有限
  2. 图形发生变化时重绘的性能开销比较大

第一点其实很好理解,HTML和CSS主要还是为网页布局而创造的,使用它们虽然能绘制可视化图表,但是绘制的方式并不简洁。上面实现的柱状图和折线图都是最基础版,如果要实现稍微复杂一点的效果其实就没那么容易了。

第二点,HTML和CSS作为浏览器渲染引擎的一部分,为了完成页面渲染的工作,除了绘制图形外,还要做很多额外的工作。如下是浏览器的渲染过程:

  1. 解析HTML,生成DOM树,解析CSS,生成CSSOM树
  2. 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
  3. Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小
  4. Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
  5. Display:将像素发送给GPU,展示在页面上。

上述过程中,当图形发生变化时,会触发回流和重绘,渲染树中或大或小的部分需要重新计算,这样其实性能开销是很大的。而Canvas2D和WebGL相比而言,它们的绘图API能够直接操作绘图上下文,在重绘图像时,不会发生重新解析文档和构建结构的过程,开销要小很多。

2. SVG

现代浏览器支持SVG(Scalable Vector Graphics,可缩放矢量图),SVG是一种基于XML语法的图像格式,可以用图片(img元素)的src属性加载。而且,浏览器还可以内嵌SVG标签,并且像操作普通的HTML元素一样,利用DOM API 操作SVG元素。下面是使用SVG实现与前面相同的柱状图效果的代码:

<svg width="200" height="200">
    <rect x="0" y="80" width="30" height="50" fill="red" />
    <rect x="50" y="50" width="30" height="80" fill="red" />
    <rect x="100" y="10" width="30" height="120" fill="red" />
    <rect x="150" y="70" width="30" height="60" fill="red" />
</svg>

 

在上述SVG代码中,rect表示绘制一个矩形元素。除了rect外,SVG还提供了丰富的图形元素,可以绘制矩形、圆弧、椭圆、多边形和贝塞尔曲线等等。现在,想要绘制一个饼图,只需使用SVG内置的circle标签,通过stroke-dasharray属性(定义轮廓为虚线)来调整stroke-width(轮廓宽度)就可以实现饼图,代码如下:

<svg viewBox="0 0 32 32" width="100" height="100" style="border-radius: 50%;">
        <circle cx="16" cy="16" r="16" stroke-width="32" stroke-dasharray="20 100" fill="yellow" stroke="red"></circle>
        <circle cx="16" cy="16" r="16" stroke-width="32" stroke-dasharray="40 100" stroke-dashoffset="-20" fill="transparent" stroke="blue"></circle>
</svg>

 实现的饼图效果:

SVG和传统的HTML+CSS的绘图方式差别不大,只不过,HTML元素在绘制矢量图形方面的能力有些不足,而SVG运用了一些SVG支持的特殊属性,恰好弥补了这方面的缺陷。因此,用SVG绘图比用HTML和CSS要方便很多。

但是,SVG图表也有缺点,它HTML元素一样,在输出图形前都需要经过引擎的解析、布局计算和渲染树生成。如果要绘制的图形很复杂,需要大量的SVG元素,就会大大增加DOM树渲染和重绘所需要的时间,对性能开销非常大,所以SVG只适合应用于元素较少的简单可视化场景。

3. Canvas2D

Canvas2D上下文来绘制可视化图表也很方便,它是一种指令式的绘图系统,我们调用一些绘图指令,就可以在画布上绘制图形。而上面的HTML+CSS、SVG其实都属于声明式绘图系统,也就是我们根据数据创建各种不同的图形元素(或者CSS规则),然后利用浏览器渲染引擎解析它们并渲染出来。

我们接下来就继续通过绘制一个上述的柱状图来看看Canvas2D的使用方式,代码如下:

<canvas id="myCanvas" width="200" height="200"></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比HTML+CSS、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种方式,不同的方式有各自的优缺点,实际应用中,也应该根据具体的场景来选择合适的方案实现可视化,以达到最佳效果。

🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论支持一下博主~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/191999.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java小游戏 王者荣耀

GameFrame类 所需图片&#xff1a; package 王者荣耀;import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayLis…

霍夫丁不等式(Hoeffding‘s inequality)

参考资料&#xff1a;Hoeffdings inequality | encyclopedia article by TheFreeDictionary 霍夫丁不等式&#xff08;Hoeffdings inequality&#xff09;描述了随机变量的和、与和的期望之差的上限&#xff1b;或者表述为&#xff1a;随机变量的均值、与均值的期望之差的上限。…

Node.js与npm的准备与操作

1.下载 Node.js官网&#xff1a;Node.jsNode.js is a JavaScript runtime built on Chromes V8 JavaScript engine.https://nodejs.org/en 打开后的界面如下&#xff1a; LTS&#xff08;Long Term Support&#xff09;&#xff1a;长期支持版&#xff0c;稳定版 Current&am…

IDEA出现cannot download sources解决方案

IDEA出现cannot download sources解决方案 问题描述 当我想看第三方库的源码的注释时需要下载源码。 点击Dodnload Sources后可能会出现cannot download sources的问题。 解决方案 这时我们只需在根目录下打开Terminal后执行下面一行代码 mvn dependency:resolve -Dclassi…

【element优化经验】el-dialog修改title样式

目录 前言 解决之路 1.把默认的这个图标隐藏&#xff0c;官方的api有这个属性&#xff1a;showClose值设置false. 2.title插槽定制&#xff1a;左边定制标题&#xff0c;右边定制按钮区域。 3.背景颜色修改&#xff1a;默认title是有padding的需要把它重写调&#xff0c;然…

QQ录屏保存到哪了?教你快速找到保存位置

qq录屏是许多用户常用的屏幕录制工具&#xff0c;可是一旦录制结束&#xff0c;许多人不清楚如何找到和管理录制的视频文件。那么&#xff0c;您知道qq录屏保存到哪了吗&#xff1f;本文将深入研究qq录制视频功能&#xff0c;以帮助您了解如何存储和管理这些重要的录制视频文件…

网络爬虫(Python:Selenium、Scrapy框架;爬虫与反爬虫笔记)

网络爬虫&#xff08;Python&#xff1a;Selenium、Scrapy框架&#xff1b;爬虫与反爬虫笔记&#xff09; SeleniumWebDriver 对象提供的相关方法定位元素ActionChains的基本使用selenium显示等待和隐式等待显示等待隐式等待 Scrapy&#xff08;异步网络爬虫框架&#xff09;Sc…

AIGC|LangChain新手入门指南,5分钟速读版!

如果你用大语言模型来构建AI应用&#xff0c;那你一定不可能绕过LangChain,LangChain是现在最热门的AI应用框架之一&#xff0c;去年年底才刚刚发布&#xff0c;它在github上已经有了4.6万颗星的点赞了&#xff0c;在github社区上&#xff0c;每天都有众多大佬&#xff0c;用它…

数据结构 | 堆排序

数据结构 | 堆排序 文章目录 数据结构 | 堆排序建立大堆排序结果以及全部代码 如果没有看过堆的实现的话可以先看前面的一章堆的实现&#xff0c;然后再来看这个堆排序&#xff0c;都是比较简单的~~ 这里堆排序首先建堆&#xff0c;建堆是要建小堆还是大堆呢&#xff1f; 在堆排…

HT97226 免输出电容立体声耳机放大器的应用与曲线

HT97226应用&#xff1a; ・耳机 ・多媒体音频接口 ・机顶盒 ・ 蓝光/DVD播放器 ・LCD电视 ・音频消费电子产品 HT97226应用图于曲线&#xff1a; HT97226是一款差分输入/单端输入、可直接输出驱动的耳机放大器。5V供…

在vue页面中添加组件到底有多方便

修改vue写的前端页面到底有多方便&#xff1f;如果熟练的话&#xff0c;出乎你想象的快。 原来的页面&#xff1a;/admin/stock 原来的文件地址&#xff1a;src\views\admin\stock\Stock.vue 另一个页面有个入库功能&#xff0c;需要转移到上面的页面中&#xff1a; 路径&…

MindStudio学习记录三:推理应用开发 acl mindx sdk

1.推理应用流程 1.1.创建工程 1.2.模型转换 1.3代码开发 1.3.1ACL代码 1.3.2MindX SDK开发 可视化模块化设计 中间的图片与处理 是基于AIPP的可视化处理 1.5.编译 交叉编译 1.6.运行与调试 1.7 调优工具 profiling性能分析 2.开发举例 resnet-50 2.1 准备工程 2.2.准备模型…

C#-基础及扩展合集(持续更新)

一、基础 Ⅰ 关键字 1、record record&#xff08;记录&#xff09;&#xff0c;编译器会在后台创建一个类。支持类似于结构的值定义&#xff0c;但被实现为一个类&#xff0c;方便创建不可变类型&#xff0c;成员在初始化后不能再被改变 &#xff08;C#9新增&#xff09; …

MT6893_天玑 1200芯片规格参数介绍_datasheet规格书

天玑 1200(MT6893)是一款专为旗舰级全新5G芯片&#xff0c;它融合了先进的AI、相机和多媒体技术&#xff0c;为用户带来令人惊叹的体验。采用先进的6纳米制程设计&#xff0c;内置各种先进技术。该芯片采用旗舰级的八核CPU架构设计&#xff0c;支持16GB强大的四通道内存以及双通…

西门子PLC与组态王无线通讯中如何设置从站

本方案主要详述了在多台西门子300PLC与组态王之间Modbus无线通讯中如何设置从站。方案中所用到的无线通讯终端是DTD434MC——欧美系PLC专用无线通讯终端。 一、方案概述 无线Modbus网络组成如下&#xff1a; 二、测试背景 ● PC端组态软件版本&#xff1a;组态王6.55 ● 默…

CRM的智能招投标对企业有什么意义?

如今CRM系统的生态系统越来越壮大&#xff0c;这些工具的集成极大地丰富了CRM系统的应用场景&#xff0c;例如CRM系统集成企业微信等社交媒体为获客提供便利&#xff1b;再比如CRM集成ChatGPT提高邮件内容质量&#xff0c;对于经常接触招投标项目的业务人员来说&#xff0c;在C…

在NAS上部署.NET版本的WOL远程开机服务

在本文中&#xff0c;我们将以部署基于.NET的WOL远程开机服务为例&#xff0c;详细介绍如何利用Docker技术在群辉部署ASP.NET服务。同时&#xff0c;我们还将展示如何对原有的控制台WOL进行改造&#xff0c;以及如何使用SignAuthorization简易URL验签类库。文章相关的代码开源地…

在PostGIS中进行点数据的等值线提取

说明 介绍在PostGIS中从点数据提取等值线。 关键字&#xff1a; raster、point、PostGIS、等值线 环境准备 Postgresql版本&#xff1a;PostgreSQL 14.0, 64-bitPostGIS版本&#xff1a;POSTGIS"3.3.2"QGIS版本&#xff1a;3.28.3-Firenze&#xff08;验证用&…

Windows系统下更新后自带的画图软件出现马赛克bug

一.bug的样子&#x1f357; 在使用橡皮后&#xff0c;原来写的内容会变成马赛克。而我们希望它是纯白色的。 二.解决方法&#x1f357; 第一步 第二步 第三步 三. 解决后的效果&#x1f357; 用橡皮擦随便擦都不会出现马赛克了。 更新过后&#xff0c;想用win自带的画图软件会出…

免杀原理(php)

免杀原理 0x01 前言 何为免杀&#xff0c;免杀就是一种逃脱杀毒软件查杀的方法&#xff0c;免杀的目的就是绕过“墙”&#xff0c;去执行危险的操作。那么如何绕过这堵“墙”&#xff0c;就是免杀的本质。有句俗话说得好“知己知彼&#xff0c;百战不殆”&#xff0c;想要用好…