JavaScript 3D图表

标签: Data Visualization 3D chart JavaScript 图表 | 发表时间:2013-08-24 19:27 | 作者:四火
出处:http://www.raychase.net

文章系本人原创,转载请保持完整性并注明出自 《四火的唠叨》

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

JavaScript 3D图表

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

JavaScript 3D图表

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

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

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

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

JavaScript 3D图表

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

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

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

webgl-surface-plot

JavaScript 3D图表

主页点此。特性列表:

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

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

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

        <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>

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

            function coordinateCharts(){
                // Link the two charts for rotation.
                
                plot1 = surfacePlot.getChart();
                plot2 = surfacePlot2.getChart();
                
                if (!plot1 || !plot2) 
                    return;
                
                plot1.otherPlots = [plot2];
                plot2.otherPlots = [plot1];
            }

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

surfacePlot.draw(data, options, basicPlotOptions, glOptions);
surfacePlot2.draw(data2, options, basicPlotOptions2, glOptions2);

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

            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真是太简单了,如果你需要这种风格的柱状图:

JavaScript 3D图表

demo的代码非常简单:

        //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即可。

文章系本人原创,转载请保持完整性并注明出自 《四火的唠叨》

分享到:
你可能也喜欢:

相关 [javascript 3d 图表] 推荐:

JavaScript 3D图表

- - 四火的唠叨
文章系本人原创,转载请保持完整性并注明出自 《四火的唠叨》. 在说3D图表以前,首先要明确两个概念,一个是数据的维度,一个是呈现数据载体的维度. 对于数据的维度,一维的数据呈现,但是呈现的载体是二维的平面图,比如饼图:. 已经能够很清晰地观察到数据的分布情况. 数据如果增加一个维度,变成二维,呈现载体依然是二维的平面图:.

ECharts 2.0.1 发布,JavaScript 图表库

- - 开源中国社区最新新闻
ECharts 2.0.1 发布,此版本是 bug 修复版本,更新内容如下:. [#] [gauge]min max非默认值时计算错误. [#] [map]图例开关无数据时图表没更新. [#] [map]选择切换图表类型时错误. [#] [markLine]过渡更新错误fix. [#] 无option时resize报错.

Javascript框架和jQuery应用情况的信息图表(Infographic)

- Will - ITeye资讯频道
我们总是想知道时下最流行的一些JavaScript框架和由于这些框架所开发的Web应用程序的比较情况. 下面就是一张体现这些比较数据的信息图表. 它包括了jQuery、Mootools、Prototype、YUI、Dojo、Extjs等这些框架的被使用情况. 从信息图表中你可以看出,比较有意思的一点就是1.3.2版本的jQuery是目前最流行的版本.

13个JavaScript图表图形绘制插件

- - HTML5研究小组
由于绘制矢量图的不同技术愈发成熟以及现代浏览器所具备的更强大的计算能力等原因,目前网上出现了越来越多免费 的JavaScript图表和图形绘制解决方案. 在本文中就将分享13个优秀实用的JavaScript图表和图形绘制插件,它们少数是独立的框架,大多 数支持条图、线图、饼图等基本图形,很多甚至支持更加复杂的图形,希望对你有所帮助.

用于展现图表的50种JavaScript库

- - 月光博客
  在很多项目中都会有在前端展现数据图表的需求,而在开发过程中,开发者往往会使用一些JavaScript库,从而更有效地达到想要的目标. 最近, TechSlide上的一篇文章总结了50种用于展现图表的JavaScript库,并对每种库做了简要的说明. 这对于想要选择合适JavaScript库的开发者很有参考意义.

10 个超赞的 JavaScript 图形图表绘制插件

- - 开源软件 - ITeye博客
Humble Finance是一个与Flash工具相似的HMTL5数据可视化工具. 该工具完全由JavaScript开发,使用Prototype与Flotr库. D3是最流行的可视化库之一,它被很多其他的表格插件所使用. 它允许绑定任意数据到DOM,然后将数据驱动转换应用到Document中. 你可以使用它用一个数组创建基本的HMTL表格,或是利用它的流体过度和交互,用相似的数据创建惊人的SVG条形图.

1021字节javascript写成的3D圣诞树

- RustingSword - hUrR DuRr
demo地址:http://js1k.com/2010-xmas/demo/856 (非Chrome浏览器会非常卡). 源码如下: . js1k里的东东让我觉得非常自卑. 更新1: blog.netoearth.com的同学,你好.

【译文】Top 10:HTML5、JavaScript 3D游戏引擎和框架

- - 淡忘~浅思
由于很多人都在用JavaScript、HTML5和WebGL技术创建基于浏览器的3D游戏,所有JavaScript 3D游戏引擎是一个人们主题. 基于浏览器的游戏最棒的地方是平台独立,它们能在iOS、Android、Windows或其他任何平台上运行. 有很多的JavaScript能够用于创建基于浏览器、使用HTML5和WebGL的3D游戏.

Javascript诞生记

- Milido - 阮一峰的网络日志
二周前,我谈了一点Javascript的历史. 今天把这部分补全,从历史的角度,说明Javascript到底是如何设计出来的. 只有了解这段历史,才能明白Javascript为什么是现在的样子. 我依据的资料,主要是Brendan Eich的自述. "1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.

JavaScript,你懂的

- dylan - keakon的涂鸦馆
经常有人问我,JavaScript应该怎么学. 先学基本语法,如果曾学过C等语言,应该1小时内就能掌握了. 再去使用内置的函数、方法和DOM API,熟悉它能干什么;而在学习DOM API的过程中,你还不得不与HTML和CSS打交道. 然后弄懂匿名函数和闭包,学会至少一个常用的JavaScript库(例如jQuery).