Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JavaScript 3D 图表

JavaScript 3D 图表

作者头像
四火
发布于 2022-07-15 13:46:10
发布于 2022-07-15 13:46:10
1K00
代码可运行
举报
文章被收录于专栏:四火的唠叨四火的唠叨
运行总次数:0
代码可运行

在说 3D 图表以前,首先要明确两个概念,一个是数据的维度,一个是呈现数据载体的维度。对于数据的维度,一维的数据呈现,但是呈现的载体是二维的平面图,比如饼图:

已经能够很清晰地观察到数据的分布情况。数据如果增加一个维度,变成二维,呈现载体依然是二维的平面图:

数据表达依然是清晰的。但是,倘若再增加一维,这个时候就面临了两个问题:

  1. 数据的维度增加,复杂性也增大了;
  2. 计算机发展到现在,绝大多数情况下数据载体依然是二维的平面图,如何展示三维的数据呢?

这两个问题中,第一个问题从本质上说,无法解决。数据的维度越大,理解起来理所当然地,也越来越困难。

但是第二个问题,我们至少有两种解决办法。一种,在当前二维图表的基础上,通过颜色、图形、数值的不同等等,来表示第三个维度的数据。例如,利用颜色不同来表示第三个维度的热图:

在两个维度经度和维度的情况下,第三个维度温度通过颜色的不同来展示了。

另一种,就是绘制 3D 的图形,把第三个维度展示出来。需要注意的是,绘制 3D 的图形仅仅是技术上的一种呈现形式,并不意味着它的易懂性要好于上面一种方式。实际上,我们还是需要看看具体的问题是什么。

明确了这些概念以后,我再来介绍两则 JavaScript 的 3D 图表,它们都是为了呈现三维的数据,而不仅仅是看起来 3D 而已,大部分 JavaScript 的 3D 图表库都是基于 Canvas 的,如果你对 Canvas 不了解请移步参阅这篇文章;其中一些则是支持 WebGL 的。WebGL 是一种 3D 的绘图标准,有了它,JavaScript 就可以实现 OpenGL 标准能做的事情了,在 HTML5 Canvas 基础上,WebGL 允许硬件 3D 加速。

webgl-surface-plot

主页点此。特性列表:

  • 纯 JavaScript 实现,不需要 Flash;
  • 鼠标左键拖拽可以翻转图像;
  • 按住 Shift 键可以缩放;
  • Web GL 不可用的时候,可以直接使用 Canvas 绘制;
  • 自定义坐标轴名称;
  • 自定义颜色梯度和渐变;
  • 包装为 Google Visualization API 的一部分。

在 IE 下,借助 excanvas 可以在 VML 下得到一样的效果。

对于这个例子,简单过一下重点代码,首先这部分是着色器的代码(片段着色器和顶点着色器),包括坐标轴和纹理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        <script id="shader-fs" type="x-shader/x-fragment">
            #ifdef GL_ES
            precision highp float;
            #endif
            varying vec4 vColor;
            varying vec3 vLightWeighting;
            void main(void)
            {
            gl_FragColor = vec4(vColor.rgb * vLightWeighting, vColor.a);
            }
        </script>
        <script id="shader-vs" type="x-shader/x-vertex">
            attribute vec3 aVertexPosition;
            attribute vec3 aVertexNormal;
            attribute vec4 aVertexColor;
            uniform mat4 uMVMatrix;
            uniform mat4 uPMatrix;
            uniform mat3 uNMatrix;
            varying vec4 vColor;
            uniform vec3 uAmbientColor;
            uniform vec3 uLightingDirection;
            uniform vec3 uDirectionalColor;
            varying vec3 vLightWeighting;
            void main(void)
            {
            gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
            vec3 transformedNormal = uNMatrix * aVertexNormal;
            float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
            vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting;
            vColor = aVertexColor;
            }
        </script>
        <script id="axes-shader-fs" type="x-shader/x-fragment">
            precision mediump float;
            varying vec4 vColor;
            void main(void)
            {
            gl_FragColor = vColor;
            }
        </script>
        <script id="axes-shader-vs" type="x-shader/x-vertex">
            attribute vec3 aVertexPosition;
            attribute vec4 aVertexColor;
            uniform mat4 uMVMatrix;
            uniform mat4 uPMatrix;
            varying vec4 vColor;
            uniform vec3 uAxesColour;
            void main(void)
            {
            gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
            vColor =  vec4(uAxesColour, 1.0);
            }
        </script>
        <script id="texture-shader-fs" type="x-shader/x-fragment">
            #ifdef GL_ES
            precision highp float;
            #endif
            varying vec2 vTextureCoord;
            uniform sampler2D uSampler;
            void main(void)
            {
            gl_FragColor = texture2D(uSampler, vTextureCoord);
            }
        </script>
        <script id="texture-shader-vs" type="x-shader/x-vertex">
            attribute vec3 aVertexPosition;
            attribute vec2 aTextureCoord;
            varying vec2 vTextureCoord;
            uniform mat4 uMVMatrix;
            uniform mat4 uPMatrix;
            void main(void)
            {
            gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
            vTextureCoord = aTextureCoord;
            }
        </script>

这个方法用于保持两图步调一致:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
            function coordinateCharts(){
                // Link the two charts for rotation.
                
                plot1 = surfacePlot.getChart();
                plot2 = surfacePlot2.getChart();
                
                if (!plot1 || !plot2) 
                    return;
                
                plot1.otherPlots = [plot2];
                plot2.otherPlots = [plot1];
            }

每发生变化需要重绘的时候,调用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
surfacePlot.draw(data, options, basicPlotOptions, glOptions);
surfacePlot2.draw(data2, options, basicPlotOptions2, glOptions2);

Demoparse 主要用来根据用户输入的公式 f(x,y) 计算 z 的值:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
            function Demoparse(ID_result, ID_code, valueArray, toolTips){
                var el, expr;
                el = document.getElementById(ID_result)
                expr = document.getElementById(ID_code).value;
                expr = Parser.parse(expr);
                var result;
                var idx = 0;
                var d = 360 / numRows;
                
                for (var x = 0; x < numRows; x++) {
                
                    valueArray[x] = new Array();
                    
                    for (var y = 0; y < numCols; y++) {
                    
                        result = expr.simplify({
                            x: x * d,
                            y: y * d
                        });
                        
                        result = result.evaluate();
                        
                        valueArray[x][y] = result / 4.0 + 0.25;
                        
                        toolTips[idx] = "x:" + x + ", y:" + y + " = " + result;
                        idx++;
                        
                    }
                    
                }
                
            }

Canvas 3D Graph

相比前者,Canvas 3D Graph 真是太简单了,如果你需要这种风格的柱状图:

demo 的代码非常简单:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        //Initialise Graph  
        var g = new canvasGraph('graph');  
                  
        //define some data  
        gData=new Array();  
                  
        gData[0]={x:500,y:500,z:500};  
        gData[1]={x:500,y:400,z:600};  
        gData[2]={x:500,y:300,z:700};  
        gData[3]={x:500,y:200,z:800};  
        gData[4]={x:500,y:100,z:900};  
  
        // sort data - draw farest elements first         
        gData.sort(sortNumByZ);  
                  
        //draw graph   
        g.drawGraph(gData); 

PS:如果你遇到无法显示 WebGL 图形的问题——它不仅对浏览器,还对硬件有要求。如果你使用 Opera 浏览器,在地址栏输入 about:gpu,以查看你的显卡是否被支持。如果是 FireFox,地址栏输入 about:config,寻找 webgl.force-enabled,双击,将该值改为 true 即可。

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

×Scan to share with WeChat

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
HTML制作3D樱花漫天飞舞及浪漫信封
作者主页:海拥 作者简介:CSDN全栈领域优质创作者、HDZ核心组成员、蝉联C站周榜前十 HTML5制作3D樱花漫天飞舞及浪漫信封 💕浪漫信封:http://haiyong.site/eluvletter 💌3D樱花漫天飞舞:http://haiyong.site/yinghua 💕 浪漫信封 HTML 内容 <div id="jsi-cherry-container"></div> <section class="container" id="contact" > <form clas
海拥
2021/12/20
1K0
HTML制作3D樱花漫天飞舞及浪漫信封
WebGL基础教程:第一部分
WebGL是一种基于OpenGL的浏览器内置3D渲染器,它可以让你在HTML5页面中直接显示3维内容。 在本教程中,我会介绍你使用此框架所需的所有基础内容。
前端达人
2019/01/12
2.9K0
WebGL基础教程:第一部分
three.js 粒子效果(分别基于 CPU & GPU 实现)
前段时间做了一个基于 CPU 和 GPU 对比的粒子效果丢在学习 WebGL 的 RTX 群里,技术上没有多作讲解,有同学反馈看不太懂 GPU 版本,干脆开一篇文章,重点讲解基于 GPU 开发的版本。
万技师
2017/07/17
10.5K3
three.js 粒子效果(分别基于 CPU & GPU 实现)
PhiloGL学习(1)——场景创建及方块欲露还羞出水面
前言 上一篇文章中介绍了我认识PhiloGL框架的机缘以及初步的探讨(见JS前端三维地球渲染——中国各城市航空路线展示),在此文中仅仅对此框架进行了简单介绍并初步介绍了一些该框架的知识。首先三维这个东西本身涉及的技术和知识点就非常多,我也基本属于初次接触;其次学习也需要过程,需要一点点积累,不积跬步无以至千里。 这几天天天加班,但是也利用空闲时间学习了些此框架的基础知识,本文为大家介绍如何创建一个简单的二维场景。 一、 HTML部分 PhiloGL采用canvas来加载三维模型,所以只有在支持HTML5的浏
魏守峰
2018/04/28
9930
【愚公系列】2023年08月 WEBGL专题-3D特效-雾化
在3D图形渲染中,雾化是一种用于创建深度感的技术。它模拟了真实世界中的雾气效果,使远距离的物体看起来模糊不清,并且与背景融合在一起,从而增强了场景的真实感。
愚公搬代码
2025/05/28
1110
【愚公系列】2023年08月 WEBGL专题-3D特效-雾化
WebGL,真正进入三维的世界
一、在此之前 在之前的文章中,我想大家已经对WebGL有了一个大体的了解,不过为了凑字数,我在这篇文章的开头再稍微回顾一下,如果我们需要使用WebGL来绘制图像需要走完以下这五步: 1、从canvas
周明礼
2017/05/17
9K2
WebGL,真正进入三维的世界
漫天花雨HTML特效+3D相册
HTML特效是指在网页中使用各种技术和代码来实现动态效果的一种方式。这些效果可以是动画、过渡、交互和其他视觉效果。HTML特效可以在不影响网页性能的同时增强用户体验。
淼学派对
2023/10/14
7240
漫天花雨HTML特效+3D相册
【愚公系列】2022年09月 微信小程序-WebGL动画的使用
在现实中webgl的用途很多,比如医院运维网站,地铁运维网站,海绵城市,可以以三维网页形式展示出现实状态。
愚公搬代码
2022/09/28
1.2K0
【愚公系列】2022年09月 微信小程序-WebGL动画的使用
PixiJS 源码解读:绘制矩形的渲染过程讲解
之前写了一篇 PixiJS 绘制矩形,简单说了一下 PixiJS 是怎么绘制矩形的。
前端西瓜哥
2023/09/11
6930
PixiJS 源码解读:绘制矩形的渲染过程讲解
PhiloGL学习(6)——深情奉献:快乐的一家
 前言 话说上一篇文章结尾讲到这一篇要做一个地球自转以及月球公转的三维动画,提笔,不对,是提键盘开始写的时候脑海中突然出现了几年前春晚风靡的那首歌:蒙古族小丫头唱的快乐的一家。闲言莫提,进入正题。  一、 原理分析 场景涉及两个对象,一个是地球、一个是月球,当然这基本是废话,不过还可以再添加一个对象,月球的公转轨迹。地球和月球都可以用一个球来模拟(Sphere),稍微困难的是公转轨迹,公转轨迹是一个圆,PhiloGL貌似没有直接提供圆的封装,但是有画线段的API,细细想来,什么是圆?祖冲之早就告诉我们了,所
魏守峰
2018/04/28
8720
PhiloGL学习(6)——深情奉献:快乐的一家
从关键概念开始,万字带你轻松入门 WebGL
只要理解了 WebGL 背后的概念,学习 WebGL 并没有那么难。很多 WebGL 入门文章并没有介绍这些重要的概念,直接使用 WebGL 复杂的 API 开始渲染图形,很轻松就把入坑文变成了劝退文。这篇文章将会着重讲解这些概念,并一步步探究 WebGL 是如何渲染图片到屏幕的,理解这些重要的概念,将会大大降低学习曲线。
羽月
2022/10/08
2.3K0
从关键概念开始,万字带你轻松入门 WebGL
WebGL基础教程:第三部分
欢迎回到第三部分,也是我们的迷你WebGL教程系列的最后一部分。在此课程中,我们会会介绍光照和添加2D对象到场景中。新的内容很多,我们还是直接开始吧。
前端达人
2019/01/12
2.8K0
WebGL基础教程:第三部分
【愚公系列】2022年09月 微信小程序-WebGL画渐变色正方形
在现实中webgl的用途很多,比如医院运维网站,地铁运维网站,海绵城市,可以以三维网页形式展示出现实状态。
愚公搬代码
2022/09/30
6350
【愚公系列】2022年09月 微信小程序-WebGL画渐变色正方形
一起来玩玩WebGL
上一篇文章说到我从客户端转前端的历程,短短一年的时间就打开了前端世界的大门,简直就是有无穷多的东西可玩,以前酷爱Java的我终于见识到什么都可以写的JavaScript的厉害了,不仅仅可以写Web,客户端,后端,系统应用,还可以在神经网络、物联网,甚至嵌入式都可以,简直就是一个万能的语言,可以说能编程的地方理论上都可以用JS来写!
ConardLi
2020/06/29
1.2K0
一起来玩玩WebGL
【愚公系列】2023年08月 WEBGL专题-3D特效-半透明
半透明物体是指在光线透过时,可以看到模糊的影像,但不完全透明的物体。这种物体通常具有一定的透明性,但不完全透明,仍然存在某种程度上的不透明性。
愚公搬代码
2025/05/28
770
【愚公系列】2023年08月 WEBGL专题-3D特效-半透明
【愚公系列】2023年08月 WEBGL专题-canvas和webgl的区别 | 技术创作特训营第一期
本文是专题类文章,主要是针对数字孪生和WEB 3D可视化展开,下面是数字孪生相关概念。
愚公搬代码
2023/08/27
8620
几个简单的小例子手把手带你入门webgl
各位同学们大家好,又到了周末写文章的时间,之前群里有粉丝提问, 就是shader不是很理解。然后今天他就来了, 废话不多说,读完今天的这篇文章你可以学到以下几点:
coder_koala
2021/09/18
1.6K0
几个简单的小例子手把手带你入门webgl
【前端er入门Shader系列】04—MVP矩阵与纹理映射
我们生活在三维的由各种色彩构成的大千世界里,包含了复杂的细节纹理,而纹理采样作为重要的图形学技术,能够在渲染物体表面时,使用一张图片来提供颜色信息,从而增强物体的细节和真实感。本章将结合少量数学知识,介绍如何使用MVP矩阵将三维场景投射到二维屏幕,最终执行纹理采样的过程。
CS逍遥剑仙
2025/01/13
4060
CG实验6 交互与动画
(1) 示范代码1为交互实例:在鼠标点击的位置上绘制出点;示范代码2为动画实例:三角形按照恒定的速度(45度/秒)旋转。结合示范代码,学习理解交互与动画的基本思想与实现; (2) 结合示范代码1,将示范代码2改为根据鼠标来控制三角形的旋转;
步行者08
2018/10/09
6430
实用 WebGL 图像处理入门
技术社区里有种很有意思的现象,那就是不少人们口耳相传中的强大技术,往往因为上手难度高而显得曲高和寡。从这个角度看来,WebGL 和函数式编程有些类似,都属于优势已被论证了多年,却一直较为不温不火的技术。但是,一旦这些技术的易用性跨越了某个临界点,它们其实并没有那么遥不可及。这次我们就将以 WebGL 为例,尝试降低它的入门门槛,讲解它在前端图像处理领域的应用入门。
ConardLi
2020/02/23
3.3K0
相关推荐
HTML制作3D樱花漫天飞舞及浪漫信封
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验