1 | define(["dojo/_base/array", "dojo/dom","dojo/_base/declare", "dojo/_base/html", "dojox/gfx", "dojox/gfx3d"], |
---|
2 | function(arr, dom, declare, html, gfx, gfx3d){ |
---|
3 | // module: |
---|
4 | // dojox/charting/Chart3D |
---|
5 | // summary: |
---|
6 | // This module provides basic 3d charting capablities (using 2d vector graphics to simulate 3d. |
---|
7 | |
---|
8 | /*===== |
---|
9 | dojox.charting.__Chart3DCtorArgs = function(node, lights, camera, theme){ |
---|
10 | // summary: |
---|
11 | // The keyword arguments that can be passed in a Chart constructor. |
---|
12 | // |
---|
13 | // node: Node |
---|
14 | // The DOM node to construct the chart on. |
---|
15 | // lights: |
---|
16 | // Lighting properties for the 3d scene |
---|
17 | // camera: Object |
---|
18 | // Camera properties describing the viewing camera position. |
---|
19 | // theme: Object |
---|
20 | // Charting theme to use for coloring chart elements. |
---|
21 | } |
---|
22 | =====*/ |
---|
23 | var observerVector = {x: 0, y: 0, z: 1}, v = gfx3d.vector, n = gfx.normalizedLength; |
---|
24 | |
---|
25 | return declare("dojox.charting.Chart3D", null, { |
---|
26 | constructor: function(node, lights, camera, theme){ |
---|
27 | // setup a view |
---|
28 | this.node = dom.byId(node); |
---|
29 | this.surface = gfx.createSurface(this.node, n(this.node.style.width), n(this.node.style.height)); |
---|
30 | this.view = this.surface.createViewport(); |
---|
31 | this.view.setLights(lights.lights, lights.ambient, lights.specular); |
---|
32 | this.view.setCameraTransform(camera); |
---|
33 | this.theme = theme; |
---|
34 | |
---|
35 | // initialize internal variables |
---|
36 | this.walls = []; |
---|
37 | this.plots = []; |
---|
38 | }, |
---|
39 | |
---|
40 | // public API |
---|
41 | generate: function(){ |
---|
42 | return this._generateWalls()._generatePlots(); |
---|
43 | }, |
---|
44 | invalidate: function(){ |
---|
45 | this.view.invalidate(); |
---|
46 | return this; |
---|
47 | }, |
---|
48 | render: function(){ |
---|
49 | this.view.render(); |
---|
50 | return this; |
---|
51 | }, |
---|
52 | addPlot: function(plot){ |
---|
53 | return this._add(this.plots, plot); |
---|
54 | }, |
---|
55 | removePlot: function(plot){ |
---|
56 | return this._remove(this.plots, plot); |
---|
57 | }, |
---|
58 | addWall: function(wall){ |
---|
59 | return this._add(this.walls, wall); |
---|
60 | }, |
---|
61 | removeWall: function(wall){ |
---|
62 | return this._remove(this.walls, wall); |
---|
63 | }, |
---|
64 | |
---|
65 | // internal API |
---|
66 | _add: function(array, item){ |
---|
67 | if(!arr.some(array, function(i){ return i == item; })){ |
---|
68 | array.push(item); |
---|
69 | this.view.invalidate(); |
---|
70 | } |
---|
71 | return this; |
---|
72 | }, |
---|
73 | _remove: function(array, item){ |
---|
74 | var a = arr.filter(array, function(i){ return i != item; }); |
---|
75 | return a.length < array.length ? (array = a, this.invalidate()) : this; |
---|
76 | }, |
---|
77 | _generateWalls: function(){ |
---|
78 | for(var i = 0; i < this.walls.length; ++i){ |
---|
79 | if(v.dotProduct(observerVector, this.walls[i].normal) > 0){ |
---|
80 | this.walls[i].generate(this); |
---|
81 | } |
---|
82 | } |
---|
83 | return this; |
---|
84 | }, |
---|
85 | _generatePlots: function(){ |
---|
86 | var depth = 0, m = gfx3d.matrix, i = 0; |
---|
87 | for(; i < this.plots.length; ++i){ |
---|
88 | depth += this.plots[i].getDepth(); |
---|
89 | } |
---|
90 | for(--i; i >= 0; --i){ |
---|
91 | var scene = this.view.createScene(); |
---|
92 | scene.setTransform(m.translate(0, 0, -depth)); |
---|
93 | this.plots[i].generate(this, scene); |
---|
94 | depth -= this.plots[i].getDepth(); |
---|
95 | } |
---|
96 | return this; |
---|
97 | } |
---|
98 | }); |
---|
99 | }); |
---|