JavaScript 3D圖表
在說3D圖表以前,首先要明確兩個概念,一個是資料的維度,一個是呈現資料載體的維度。對於資料的維度,一維的資料呈現,但是呈現的載體是二維的平面圖,比如餅圖:
已經能夠很清晰地觀察到資料的分佈情況。資料如果增加一個維度,變成二維,呈現載體依然是二維的平面圖:
資料表達依然是清晰的。但是,倘若再增加一維,這個時候就面臨了兩個問題:
- 資料的維度增加,複雜性也增大了;
- 計算機發展到現在,絕大多數情況下資料載體依然是二維的平面圖,如何展示三維的資料呢?
這兩個問題中,第一個問題從本質上說,無法解決。資料的維度越大,理解起來理所當然地,也越來越困難。
但是第二個問題,我們至少有兩種解決辦法。一種,在當前二維圖表的基礎上,通過顏色、圖形、數值的不同等等,來表示第三個維度的資料。例如,利用顏色不同來表示第三個維度的熱圖:
在兩個維度經度和維度的情況下,第三個維度溫度通過顏色的不同來展示了。
另一種,就是繪製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下得到一樣的效果。
對於這個例子,簡單過一下重點程式碼,首先這部分是著色器的程式碼(片段著色器和頂點著色器),包括座標軸和紋理:
<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真是太簡單了,如果你需要這種風格的柱狀圖:
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圖表元件dhtmlxChartJavaScript元件HTML
- 基於 WebGL 的 3D Chart 圖表Web3D
- 13個JavaScript圖表(JS圖表)圖形繪製外掛JavaScriptJS
- HTML-JavaScript-計算圖表HTMLJavaScript
- 幾款實用的 JavaScript 圖形圖表庫JavaScript
- Excel表格中的3D圖表簡介和圖表資料系列的處理方法Excel3D
- 給開發者提供的 35 款 JavaScript 圖形圖表庫JavaScript
- 給開發者提供的35 款JavaScript 圖形圖表庫JavaScript
- Origin圖表技巧之繪製帶輔助面的3D折線圖3D
- 將拓撲圖和圖表繪製在 3D 六面體上3D
- 4個頂級開源JavaScript圖表庫JavaScript
- 最好的 3 個開源 JavaScript 圖表庫JavaScript
- 前端開發者常用的9個JavaScript圖表庫前端JavaScript
- JavaScript視覺化圖表庫MetricsGraphics.jsJavaScript視覺化JS
- 基於HTML5 Canvas的3D動態Chart圖表HTMLCanvas3D
- JavaScript視覺化圖表庫D3.jsJavaScript視覺化JS
- xCharts:基於D3的JavaScript圖表庫JavaScript
- 21 個最棒最有用的 JavaScript 圖表庫JavaScript
- 用於展現圖表的50種JavaScript庫JavaScript
- 11 個用來建立圖形和圖表的 JavaScript 工具包JavaScript
- js 3d圖形JS3D
- 深圳3D地圖3D地圖
- 強大的JavaScript響應式圖表Chartist.jsJavaScriptJS
- ECharts:基於HTML5 Canvas的JavaScript圖表庫EchartsHTMLCanvasJavaScript
- 向 Web 開發人員推薦35款 JavaScript 圖形圖表庫WebJavaScript
- javascript 3D旋轉滾動效果JavaScript3D
- 如何使用畫圖 3D3D
- 3D地圖折射功能3D地圖
- echarts 3D圓柱圖Echarts3D
- 九、柱狀圖和3D柱狀圖3D
- 3D繪圖:18個WebGL開源引擎框架及Web 3D圖形庫3D繪圖Web框架
- JavaScript 3D球形標籤雲程式碼JavaScript3D
- 在同一頁面顯示多個JavaScript統計圖表JavaScript
- 3D圖形:透視投影3D
- javascript操作表單JavaScript
- javascript提交表單JavaScript
- 基於HTML5 WebGL 將拓撲圖和圖表繪製在 3D 六面體上HTMLWeb3D
- 分享一個開源的JavaScript統計圖表庫,40行程式碼實現專業統計圖表JavaScript行程