David Catuhe hace 7 años
padre
commit
cc173f9711

+ 19 - 0
gui/src/3D/charting/IGraph.ts

@@ -0,0 +1,19 @@
+import { DataSeries } from "./dataSeries";
+import { TransformNode } from "babylonjs";
+
+export interface IGraph {
+    /** Gets the root node associated with this graph */
+    rootNode: TransformNode;
+
+    /** Gets or sets the data source used by the graph */
+    dataSource: DataSeries;
+
+    /** Gets or sets the name of the graph */
+    name: string;
+
+    /** 
+     * Force the graph to redraw itself
+     * @returns the current graph 
+     */
+    refresh(): IGraph;
+}

+ 163 - 0
gui/src/3D/charting/barGraph.ts

@@ -0,0 +1,163 @@
+import { DataSeries } from "./dataSeries";
+import { Nullable, TransformNode, Scene, Mesh, Observable, PBRMaterial, CubeTexture } from "babylonjs";
+
+/** Class used to render bar graphs */
+export class BarGraph {
+    private _dataSource: Nullable<DataSeries>;
+    private _rootNode: TransformNode;
+    private _margin = 1;
+    private _barWidth = 2
+    private _maxBarHeight = 10;
+    private _defaultMaterial: PBRMaterial;
+
+    public onElementCreated = new Observable<Mesh>();
+
+    /** Gets or sets the data source used by the graph */
+    public get dataSource(): Nullable<DataSeries> {
+        return this._dataSource;
+    }
+
+    public set dataSource(value: Nullable<DataSeries>) {
+        if (this._dataSource === value) {
+            return;
+        }
+
+        this._dataSource = value;
+
+        this.refresh();
+    }
+
+    /** Gets the root node associated with this graph */
+    public get rootNode(): TransformNode {
+        return this._rootNode;
+    }
+
+    /** Gets or sets the name of the graph */
+    public name: string; 
+
+    /** Gets or sets the margin between bars */
+    public get margin(): number {
+        return this._margin;
+    }
+
+    public set margin(value: number) {
+        if (this._margin === value) {
+            return;
+        }
+
+        this._margin = value;
+
+        this.refresh();
+    }
+
+    /** Gets or sets the with of each bar */
+    public get barWidth(): number {
+        return this._barWidth;
+    }
+
+    public set barWidth(value: number) {
+        if (this._barWidth === value) {
+            return;
+        }
+
+        this._barWidth = value;
+
+        this.refresh();
+    }
+
+    /** Gets or sets the maximum height of a bar */
+    public get maxBarHeight(): number {
+        return this._maxBarHeight;
+    }
+
+    public set maxBarHeight(value: number) {
+        if (this._maxBarHeight === value) {
+            return;
+        }
+
+        this._maxBarHeight = value;
+
+        this.refresh();
+    }
+
+    /** Gets or sets the material used by bar meshes */
+    public get defaultMaterial(): PBRMaterial {
+        return this._defaultMaterial;
+    }
+
+    public set defaultMaterial(value: PBRMaterial) {
+        if (this._defaultMaterial === value) {
+            return;
+        }
+
+        this._defaultMaterial = value;
+
+        this.refresh();
+    }
+
+    /**
+     * Creates a new BarGraph
+     * @param name defines the name of the graph
+     */
+    constructor(name: string, scene?: Scene) {
+        this.name = name;
+        this._rootNode = new TransformNode(name, scene);
+    }
+
+    /** Force the graph to redraw itself */
+    public refresh(): BarGraph {
+        // TODO: clean current meshes
+
+        if (!this._dataSource) {
+            return this;
+        }
+
+        let scene = this._rootNode.getScene();
+
+        // Default material
+        if (!this._defaultMaterial) {
+            this._defaultMaterial = new BABYLON.PBRMaterial("plastic", scene);
+            this._defaultMaterial.microSurface = 0.96;
+            this._defaultMaterial.alpha = 0.8;
+            this._defaultMaterial.albedoColor = this._dataSource.color;
+            this._defaultMaterial.reflectivityColor = new BABYLON.Color3(0.003, 0.003, 0.003);
+        }
+
+        // Scan data
+        let min = Number.MAX_VALUE;
+        let max = Number.MIN_VALUE;
+        this._dataSource.data.forEach(entry => {
+            if (min > entry.value) {
+                min = entry.value;
+            }
+
+            if (max < entry.value) {
+                max = entry.value;
+            }
+        });
+
+        let ratio = this.maxBarHeight / (max - min);
+
+        // We will generate one bar per entry
+        let left = -(this._dataSource.data.length / 2) * (this.barWidth + this.margin) + 1.5 * this._margin;
+        let index = 0;
+        this._dataSource.data.forEach(entry => {
+
+            var box = Mesh.CreateBox(this.name + "_box_" + index++, 1, scene);
+            box.setPivotPoint(new BABYLON.Vector3(0, -0.5, 0));
+
+            box.parent = this._rootNode;
+            box.position.x += left;
+            box.scaling.set(this.barWidth, entry.value * ratio, this._barWidth);
+
+            box.material = this._defaultMaterial;
+
+            this.onElementCreated.notifyObservers(box);
+
+            left += this.barWidth + this.margin;
+        });
+
+
+        return this;
+    }
+}

+ 57 - 5
gui/src/3D/charting/dataSeries.ts

@@ -1,17 +1,69 @@
 import { Color3 } from "babylonjs";
 
+/** Class used to store data to display */
 export class DataSeries {
     /** Gets or sets the label of the series */
     public label: string;
 
-    /** Gets or sets the color associated with the series*/
+    /** Gets or sets the color associated with the series */
     public color: Color3;
 
     /** Gets or sets the list of dimensions (used to filter data) */
     public dimensions: Array<string>;
 
-    /**
-     * Gets or sets the list of values (data to display)
-     */
-    public values: Array<string>;
+    /** Gets or sets the list of values (data to display) */
+    public data: Array<any>;  
+
+    public static CreateFakeData(): DataSeries {
+        var series = new DataSeries();
+        series.label = "Product #1";
+        series.color = Color3.Red();
+
+        series.dimensions = ["Year", "Country"];
+
+        series.data = [
+            {
+                "Year": 2014,
+                "Country": "France",
+                "value": 10
+            }, 
+            {
+                "Year": 2014,
+                "Country": "USA",
+                "value": 200
+            }, 
+            {
+                "Year": 2014,
+                "Country": "India",
+                "value": 400
+            }, 
+            {
+                "Year": 2014,
+                "Country": "UK",
+                "value": 180
+            },
+            {
+                "Year": 2015,
+                "Country": "France",
+                "value": 12
+            }, 
+            {
+                "Year": 2015,
+                "Country": "USA",
+                "value": 120
+            }, 
+            {
+                "Year": 2015,
+                "Country": "India",
+                "value": 480
+            }, 
+            {
+                "Year": 2015,
+                "Country": "UK",
+                "value": 10
+            }
+        ];
+        
+        return series;
+    }
 }

+ 3 - 1
gui/src/3D/charting/index.ts

@@ -1 +1,3 @@
-export * from "./dataSeries";
+export * from "./dataSeries";
+export * from "./IGraph";
+export * from "./barGraph";