David Catuhe 7 سال پیش
والد
کامیت
a3c6cf9a23

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 13496 - 13496
dist/preview release/babylon.d.ts


+ 9 - 13
dist/preview release/gui/babylon.gui.d.ts

@@ -2426,6 +2426,8 @@ declare module BABYLON.GUI {
             };
             protected _scene: BABYLON.Scene;
             protected _blockRefresh: boolean;
+            protected _elementWidth: number;
+            protected _defaultMaterial: BABYLON.Nullable<BABYLON.Material>;
             /** BABYLON.Observable raised when a refresh was done */
             onRefreshObservable: BABYLON.Observable<Chart>;
             /** BABYLON.Observable raised when a new element is created */
@@ -2444,6 +2446,8 @@ declare module BABYLON.GUI {
             onElementOutObservable: BABYLON.Observable<BABYLON.AbstractMesh>;
             /** User defined callback used to create labels */
             labelCreationFunction: BABYLON.Nullable<(label: string, width: number, includeBackground: boolean) => BABYLON.Mesh>;
+            /** Gets or sets the width of each element */
+            elementWidth: number;
             /** Gets or sets the rotation of the entire chart */
             rotation: BABYLON.Vector3;
             /** Gets or sets the position of the entire chart */
@@ -2460,6 +2464,10 @@ declare module BABYLON.GUI {
             readonly rootNode: BABYLON.TransformNode;
             /** Gets or sets a value indicating if refresh function should be executed (useful when multiple changes will happen and you want to run refresh only at the end) */
             blockRefresh: boolean;
+            /** Gets or sets the material used by element meshes */
+            defaultMaterial: BABYLON.Nullable<BABYLON.Material>;
+            /** Gets or sets a boolean indicating if glow should be used to highlight element hovering */
+            glowHover: boolean;
             /** Gets or sets the name of the graph */
             name: string;
             /**
@@ -2468,6 +2476,7 @@ declare module BABYLON.GUI {
                 * @param scene defines the hosting scene
                 */
             constructor(name: string, scene?: BABYLON.Nullable<BABYLON.Scene>);
+            protected _createDefaultMaterial(scene: BABYLON.Scene): BABYLON.Material;
             /**
                 * Function called by the chart objects when they need a label. Could be user defined if you set this.labelCreationFunction to a custom callback
                 * @param label defines the text of the label
@@ -2499,28 +2508,22 @@ declare module BABYLON.GUI {
         * @see http://doc.babylonjs.com/how_to/chart3d#bargraph
         */
     export class BarGraph extends Chart {
-            protected _ownDefaultMaterial: boolean;
             /** Gets or sets a boolean indicating if the background must be displayed */
             displayBackground: boolean;
             /** Gets or sets a boolean indicating if labels must be displayed */
             displayLabels: boolean;
             /** Gets or sets the margin between bars */
             margin: number;
-            /** Gets or sets the width of each bar */
-            barWidth: number;
             /** Gets or sets the maximum height of a bar */
             maxBarHeight: number;
             /** Gets or sets the dimension used for the labels */
             labelDimension: string;
-            /** Gets or sets the material used by bar meshes */
-            defaultMaterial: BABYLON.Nullable<BABYLON.Material>;
             /**
                 * Creates a new BarGraph
                 * @param name defines the name of the graph
                 * @param scene defines the hosting scene
                 */
             constructor(name: string, scene?: BABYLON.Nullable<BABYLON.Scene>);
-            protected _createDefaultMaterial(scene: BABYLON.Scene): BABYLON.Material;
             /**
                 * Children class can override this function to provide a new mesh (as long as it stays inside a 1x1x1 box)
                 * @param name defines the mesh name
@@ -2533,8 +2536,6 @@ declare module BABYLON.GUI {
                 * @returns the current BarGraph
              */
             refresh(): BarGraph;
-            /** Clean associated resources */
-            dispose(): void;
             protected _clean(): void;
     }
 }
@@ -2544,8 +2545,6 @@ declare module BABYLON.GUI {
         * @see http://doc.babylonjs.com/how_to/chart3d#mapgraph
         */
     export class MapGraph extends Chart {
-            /** Gets or sets the radius of each cylinder */
-            cylinderRadius: number;
             /** Gets or sets the size of the world map (this will define the width) */
             worldMapSize: number;
             /**
@@ -2555,10 +2554,7 @@ declare module BABYLON.GUI {
                 */
             constructor(name: string, mapUrl: string, scene?: BABYLON.Nullable<BABYLON.Scene>);
             protected _createCylinderMesh(name: string, scene: BABYLON.Scene): BABYLON.Mesh;
-            protected _createDefaultMaterial(scene: BABYLON.Scene): BABYLON.Material;
             refresh(): MapGraph;
             protected _clean(): void;
-            /** Clean associated resources */
-            dispose(): void;
     }
 }

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
dist/preview release/gui/babylon.gui.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js.map


+ 21 - 29
dist/preview release/gui/babylon.gui.module.d.ts

@@ -2628,7 +2628,7 @@ declare module 'babylonjs-gui/3D/charting/dataSeries' {
 }
 
 declare module 'babylonjs-gui/3D/charting/chart' {
-    import { Nullable, TransformNode, Scene, Vector3, Observable, Mesh, AbstractMesh } from "babylonjs";
+    import { Nullable, TransformNode, Scene, Vector3, Observable, Mesh, AbstractMesh, Material } from "babylonjs";
     import { DataSeries } from "babylonjs-gui/3D/charting";
     /**
         * Base class for all chart controls
@@ -2642,6 +2642,8 @@ declare module 'babylonjs-gui/3D/charting/chart' {
             };
             protected _scene: Scene;
             protected _blockRefresh: boolean;
+            protected _elementWidth: number;
+            protected _defaultMaterial: Nullable<Material>;
             /** Observable raised when a refresh was done */
             onRefreshObservable: Observable<Chart>;
             /** Observable raised when a new element is created */
@@ -2660,6 +2662,8 @@ declare module 'babylonjs-gui/3D/charting/chart' {
             onElementOutObservable: Observable<AbstractMesh>;
             /** User defined callback used to create labels */
             labelCreationFunction: Nullable<(label: string, width: number, includeBackground: boolean) => Mesh>;
+            /** Gets or sets the width of each element */
+            elementWidth: number;
             /** Gets or sets the rotation of the entire chart */
             rotation: Vector3;
             /** Gets or sets the position of the entire chart */
@@ -2676,6 +2680,10 @@ declare module 'babylonjs-gui/3D/charting/chart' {
             readonly rootNode: TransformNode;
             /** Gets or sets a value indicating if refresh function should be executed (useful when multiple changes will happen and you want to run refresh only at the end) */
             blockRefresh: boolean;
+            /** Gets or sets the material used by element meshes */
+            defaultMaterial: Nullable<Material>;
+            /** Gets or sets a boolean indicating if glow should be used to highlight element hovering */
+            glowHover: boolean;
             /** Gets or sets the name of the graph */
             name: string;
             /**
@@ -2684,6 +2692,7 @@ declare module 'babylonjs-gui/3D/charting/chart' {
                 * @param scene defines the hosting scene
                 */
             constructor(name: string, scene?: Nullable<Scene>);
+            protected _createDefaultMaterial(scene: Scene): Material;
             /**
                 * Function called by the chart objects when they need a label. Could be user defined if you set this.labelCreationFunction to a custom callback
                 * @param label defines the text of the label
@@ -2711,35 +2720,29 @@ declare module 'babylonjs-gui/3D/charting/chart' {
 }
 
 declare module 'babylonjs-gui/3D/charting/barGraph' {
-    import { Nullable, Scene, Mesh, Material } from "babylonjs";
+    import { Nullable, Scene, Mesh } from "babylonjs";
     import { Chart } from "babylonjs-gui/3D/charting";
     /**
         * Class used to render bar graphs
         * @see http://doc.babylonjs.com/how_to/chart3d#bargraph
         */
     export class BarGraph extends Chart {
-            protected _ownDefaultMaterial: boolean;
             /** Gets or sets a boolean indicating if the background must be displayed */
             displayBackground: boolean;
             /** Gets or sets a boolean indicating if labels must be displayed */
             displayLabels: boolean;
             /** Gets or sets the margin between bars */
             margin: number;
-            /** Gets or sets the width of each bar */
-            barWidth: number;
             /** Gets or sets the maximum height of a bar */
             maxBarHeight: number;
             /** Gets or sets the dimension used for the labels */
             labelDimension: string;
-            /** Gets or sets the material used by bar meshes */
-            defaultMaterial: Nullable<Material>;
             /**
                 * Creates a new BarGraph
                 * @param name defines the name of the graph
                 * @param scene defines the hosting scene
                 */
             constructor(name: string, scene?: Nullable<Scene>);
-            protected _createDefaultMaterial(scene: Scene): Material;
             /**
                 * Children class can override this function to provide a new mesh (as long as it stays inside a 1x1x1 box)
                 * @param name defines the mesh name
@@ -2752,22 +2755,18 @@ declare module 'babylonjs-gui/3D/charting/barGraph' {
                 * @returns the current BarGraph
              */
             refresh(): BarGraph;
-            /** Clean associated resources */
-            dispose(): void;
             protected _clean(): void;
     }
 }
 
 declare module 'babylonjs-gui/3D/charting/mapGraph' {
     import { Chart } from "babylonjs-gui/3D/charting";
-    import { Scene, Nullable, Mesh, Material } from "babylonjs";
+    import { Scene, Nullable, Mesh } from "babylonjs";
     /**
         * Class used to render bar graphs
         * @see http://doc.babylonjs.com/how_to/chart3d#mapgraph
         */
     export class MapGraph extends Chart {
-            /** Gets or sets the radius of each cylinder */
-            cylinderRadius: number;
             /** Gets or sets the size of the world map (this will define the width) */
             worldMapSize: number;
             /**
@@ -2777,11 +2776,8 @@ declare module 'babylonjs-gui/3D/charting/mapGraph' {
                 */
             constructor(name: string, mapUrl: string, scene?: Nullable<Scene>);
             protected _createCylinderMesh(name: string, scene: Scene): Mesh;
-            protected _createDefaultMaterial(scene: Scene): Material;
             refresh(): MapGraph;
             protected _clean(): void;
-            /** Clean associated resources */
-            dispose(): void;
     }
 }
 
@@ -5214,6 +5210,8 @@ declare module BABYLON.GUI {
             };
             protected _scene: BABYLON.Scene;
             protected _blockRefresh: boolean;
+            protected _elementWidth: number;
+            protected _defaultMaterial: BABYLON.Nullable<BABYLON.Material>;
             /** BABYLON.Observable raised when a refresh was done */
             onRefreshObservable: BABYLON.Observable<Chart>;
             /** BABYLON.Observable raised when a new element is created */
@@ -5232,6 +5230,8 @@ declare module BABYLON.GUI {
             onElementOutObservable: BABYLON.Observable<BABYLON.AbstractMesh>;
             /** User defined callback used to create labels */
             labelCreationFunction: BABYLON.Nullable<(label: string, width: number, includeBackground: boolean) => BABYLON.Mesh>;
+            /** Gets or sets the width of each element */
+            elementWidth: number;
             /** Gets or sets the rotation of the entire chart */
             rotation: BABYLON.Vector3;
             /** Gets or sets the position of the entire chart */
@@ -5248,6 +5248,10 @@ declare module BABYLON.GUI {
             readonly rootNode: BABYLON.TransformNode;
             /** Gets or sets a value indicating if refresh function should be executed (useful when multiple changes will happen and you want to run refresh only at the end) */
             blockRefresh: boolean;
+            /** Gets or sets the material used by element meshes */
+            defaultMaterial: BABYLON.Nullable<BABYLON.Material>;
+            /** Gets or sets a boolean indicating if glow should be used to highlight element hovering */
+            glowHover: boolean;
             /** Gets or sets the name of the graph */
             name: string;
             /**
@@ -5256,6 +5260,7 @@ declare module BABYLON.GUI {
                 * @param scene defines the hosting scene
                 */
             constructor(name: string, scene?: BABYLON.Nullable<BABYLON.Scene>);
+            protected _createDefaultMaterial(scene: BABYLON.Scene): BABYLON.Material;
             /**
                 * Function called by the chart objects when they need a label. Could be user defined if you set this.labelCreationFunction to a custom callback
                 * @param label defines the text of the label
@@ -5287,28 +5292,22 @@ declare module BABYLON.GUI {
         * @see http://doc.babylonjs.com/how_to/chart3d#bargraph
         */
     export class BarGraph extends Chart {
-            protected _ownDefaultMaterial: boolean;
             /** Gets or sets a boolean indicating if the background must be displayed */
             displayBackground: boolean;
             /** Gets or sets a boolean indicating if labels must be displayed */
             displayLabels: boolean;
             /** Gets or sets the margin between bars */
             margin: number;
-            /** Gets or sets the width of each bar */
-            barWidth: number;
             /** Gets or sets the maximum height of a bar */
             maxBarHeight: number;
             /** Gets or sets the dimension used for the labels */
             labelDimension: string;
-            /** Gets or sets the material used by bar meshes */
-            defaultMaterial: BABYLON.Nullable<BABYLON.Material>;
             /**
                 * Creates a new BarGraph
                 * @param name defines the name of the graph
                 * @param scene defines the hosting scene
                 */
             constructor(name: string, scene?: BABYLON.Nullable<BABYLON.Scene>);
-            protected _createDefaultMaterial(scene: BABYLON.Scene): BABYLON.Material;
             /**
                 * Children class can override this function to provide a new mesh (as long as it stays inside a 1x1x1 box)
                 * @param name defines the mesh name
@@ -5321,8 +5320,6 @@ declare module BABYLON.GUI {
                 * @returns the current BarGraph
              */
             refresh(): BarGraph;
-            /** Clean associated resources */
-            dispose(): void;
             protected _clean(): void;
     }
 }
@@ -5332,8 +5329,6 @@ declare module BABYLON.GUI {
         * @see http://doc.babylonjs.com/how_to/chart3d#mapgraph
         */
     export class MapGraph extends Chart {
-            /** Gets or sets the radius of each cylinder */
-            cylinderRadius: number;
             /** Gets or sets the size of the world map (this will define the width) */
             worldMapSize: number;
             /**
@@ -5343,10 +5338,7 @@ declare module BABYLON.GUI {
                 */
             constructor(name: string, mapUrl: string, scene?: BABYLON.Nullable<BABYLON.Scene>);
             protected _createCylinderMesh(name: string, scene: BABYLON.Scene): BABYLON.Mesh;
-            protected _createDefaultMaterial(scene: BABYLON.Scene): BABYLON.Material;
             refresh(): MapGraph;
             protected _clean(): void;
-            /** Clean associated resources */
-            dispose(): void;
     }
 }

+ 11 - 128
gui/src/3D/charting/barGraph.ts

@@ -1,7 +1,6 @@
-import { Nullable, Scene, Mesh, StandardMaterial, Material, Animation, Observer, Vector3, GlowLayer, Engine, AbstractMesh, Matrix } from "babylonjs";
+import { Nullable, Scene, Mesh, StandardMaterial, Animation, Engine, Matrix } from "babylonjs";
 import { Chart } from ".";
 import { AdvancedDynamicTexture, DisplayGrid } from "../../2D";
-import { FluentMaterial } from "../materials";
 
 /** 
  * Class used to render bar graphs 
@@ -9,20 +8,10 @@ import { FluentMaterial } from "../materials";
  */
 export class BarGraph extends Chart {
     private _margin = 1;
-    private _barWidth = 2
     private _maxBarHeight = 10;
-    private _defaultMaterial: Nullable<Material>;
-    protected _ownDefaultMaterial = false;
     private _barMeshes: Nullable<Array<Mesh>>;
     private _backgroundMesh: Nullable<Mesh>;
     private _backgroundADT : Nullable<AdvancedDynamicTexture>;
-
-    private _pickedPointObserver: Nullable<Observer<Vector3>>;
-
-    private _glowLayer: GlowLayer;
-    
-    private _onElementEnterObserver: Nullable<Observer<AbstractMesh>>;
-    private _onElementOutObserver: Nullable<Observer<AbstractMesh>>;
     
     private _labelDimension: string;
     private _displayLabels = true;
@@ -30,8 +19,6 @@ export class BarGraph extends Chart {
     private _backgroundResolution = 512;
     private _backgroundTickCount = 5;
 
-    private _hoverLabel: Nullable<Mesh>;
-
     /** Gets or sets a boolean indicating if the background must be displayed */
     public get displayBackground(): boolean {
         return this._displayBackground;
@@ -77,21 +64,6 @@ export class BarGraph extends Chart {
         this.refresh();
     }
 
-    /** Gets or sets the width 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;
@@ -122,21 +94,6 @@ export class BarGraph extends Chart {
         this.refresh();
     }
 
-    /** Gets or sets the material used by bar meshes */
-    public get defaultMaterial(): Nullable<Material> {
-        return this._defaultMaterial;
-    }
-
-    public set defaultMaterial(value: Nullable<Material>) {
-        if (this._defaultMaterial === value) {
-            return;
-        }
-
-        this._defaultMaterial = value;
-
-        this.refresh();
-    }
-
     /**
      * Creates a new BarGraph
      * @param name defines the name of the graph
@@ -144,56 +101,6 @@ export class BarGraph extends Chart {
      */
     constructor(name: string, scene: Nullable<Scene> = Engine.LastCreatedScene) {
         super(name, scene);
-
-        this._glowLayer = new GlowLayer("glow", scene!);
-
-        let activeBar: Nullable<Mesh>;
-        this._onElementEnterObserver = this.onElementEnterObservable.add(mesh => {
-            activeBar = <Mesh>mesh;
-
-            this._hoverLabel = this._addLabel(activeBar.metadata.value.toString(), this._barWidth);
-
-            this._hoverLabel.position = activeBar.position.clone();
-            this._hoverLabel.position.y = activeBar.scaling.y + 0.5;
-            this._hoverLabel.scaling.x = this.barWidth;            
-        });
-
-        this._onElementOutObserver = this.onElementOutObservable.add(mesh => {
-            activeBar = null;
-
-            if (this._hoverLabel) {
-                this._removeLabel(this._hoverLabel);
-                this._hoverLabel = null;
-            }
-        });
-
-        this._glowLayer.customEmissiveColorSelector = (mesh, subMesh, material, result) => {
-            if (mesh === activeBar) {
-                let chartColor = this._dataSource!.color.scale(0.75);
-                result.set(chartColor.r, chartColor.g, chartColor.b, 1.0);
-            } else {
-                result.set(0, 0, 0, 0);
-            }
-        }
-    }
-
-    protected _createDefaultMaterial(scene: Scene): Material {
-        var result = new FluentMaterial("fluent", scene);
-        result.albedoColor = this._dataSource!.color.scale(0.5);
-        result.innerGlowColorIntensity = 0.6;
-        result.renderHoverLight = true;
-        result.hoverRadius = 5;
-
-        this._pickedPointObserver = this.onPickedPointChangedObservable.add(pickedPoint => {
-            if (pickedPoint) {
-                result.hoverPosition = pickedPoint;
-                result.hoverColor.a = 1.0;
-            } else {
-                result.hoverColor.a = 0;
-            }
-        });
-
-        return result;
     }
 
     /**
@@ -250,7 +157,7 @@ export class BarGraph extends Chart {
         let ratio = this._maxBarHeight / (max - min);
 
         let createMesh = false;
-        let left = -(data.length / 2) * (this.barWidth + this.margin) + 1.5 * this._margin;
+        let left = -(data.length / 2) * (this._elementWidth + this.margin) + 1.5 * this._margin;
 
         // Do we need to create new graph or animate the current one
         if (!this._barMeshes || this._barMeshes.length !== data.length) {
@@ -285,16 +192,16 @@ export class BarGraph extends Chart {
 
             (<StandardMaterial>this._backgroundMesh.material!).opacityTexture = null;
 
-            this._backgroundMesh.position.z = this.barWidth;
-            this._backgroundMesh.scaling.x = (this.barWidth + this.margin) * data.length;
+            this._backgroundMesh.position.z = this._elementWidth;
+            this._backgroundMesh.scaling.x = (this._elementWidth + this.margin) * data.length;
             this._backgroundMesh.scaling.y = this._maxBarHeight; 
 
             for (var tickIndex = 0; tickIndex <= this._backgroundTickCount; tickIndex++) {
                 var label = (max / this._backgroundTickCount) * tickIndex + "";
-                var ticklabel = this._addLabel(label, this._barWidth, false);
-                ticklabel.position.x = left - this._barWidth;
+                var ticklabel = this._addLabel(label, this._elementWidth, false);
+                ticklabel.position.x = left - this._elementWidth;
                 ticklabel.position.y = (this.maxBarHeight * tickIndex) / this._backgroundTickCount;
-                ticklabel.position.z = this._barWidth;
+                ticklabel.position.z = this._elementWidth;
             }
         }
 
@@ -315,7 +222,7 @@ export class BarGraph extends Chart {
             barMesh.parent = this._rootNode;
             barMesh.position.x = left;
             let currentScalingYState = barMesh.scaling.y;
-            barMesh.scaling.set(this.barWidth, 0, this._barWidth);
+            barMesh.scaling.set(this._elementWidth, 0, this._elementWidth);
 
             var easing = new BABYLON.CircleEase();
             Animation.CreateAndStartAnimation("entryScale", barMesh, "scaling.y", 30, 30, currentScalingYState, entry.value * ratio, 0, easing);
@@ -324,16 +231,16 @@ export class BarGraph extends Chart {
 
             this.onElementCreatedObservable.notifyObservers(barMesh);
 
-            left += this._barWidth + this.margin;
+            left += this._elementWidth + this.margin;
 
             // Label
             if (!this._labelDimension || !this._displayLabels) {
                 return;
             }
 
-            let label = this._addLabel(entry[this._labelDimension], this.barWidth);
+            let label = this._addLabel(entry[this._labelDimension], this._elementWidth);
             label.position = barMesh.position.clone();
-            label.position.z -= this.barWidth;
+            label.position.z -= this._elementWidth;
         });
 
         this.onRefreshObservable.notifyObservers(this);
@@ -341,30 +248,6 @@ export class BarGraph extends Chart {
         return this;
     }
 
-    /** Clean associated resources */
-    public dispose() {
-        super.dispose();
-        if (this._ownDefaultMaterial && this._defaultMaterial) {
-            this._defaultMaterial.dispose();
-            this._defaultMaterial = null;
-        }
-
-        if (this._pickedPointObserver) {
-            this.onPickedPointChangedObservable.remove(this._pickedPointObserver);
-            this._pickedPointObserver = null;
-        }
-
-        if (this._onElementEnterObserver) {
-            this.onElementEnterObservable.remove(this._onElementEnterObserver);
-            this._onElementEnterObserver = null;
-        }
-
-        if (this._onElementOutObserver) {
-            this.onElementOutObservable.remove(this._onElementOutObserver);
-            this._onElementOutObserver = null;
-        }
-    }
-
     protected _clean(): void {
         super._clean();
         this._barMeshes = null;

+ 128 - 2
gui/src/3D/charting/chart.ts

@@ -1,6 +1,7 @@
-import { Nullable, TransformNode, Scene, Vector3, Engine, Observer, PointerInfo, Observable, Mesh, AbstractMesh } from "babylonjs";
+import { Nullable, TransformNode, Scene, Vector3, Engine, Observer, PointerInfo, Observable, Mesh, AbstractMesh, GlowLayer, Material } from "babylonjs";
 import { DataSeries } from ".";
 import { AdvancedDynamicTexture, TextBlock, Rectangle, TextWrapping } from "../../2D";
+import { FluentMaterial } from "../materials";
 
 /** 
  * Base class for all chart controls
@@ -14,7 +15,16 @@ export abstract class Chart {
     protected _scene: Scene;
     private _lastElementOver: Nullable<AbstractMesh>;
     private _labelMeshes = new Array<Mesh>();
-    protected _blockRefresh = false;
+    protected _blockRefresh = false;    
+    protected _elementWidth = 2;    
+    private _pickedPointObserver: Nullable<Observer<Vector3>>;      
+    protected _defaultMaterial: Nullable<Material>; 
+
+    private _glowLayer: Nullable<GlowLayer>;
+    private _onElementEnterObserver: Nullable<Observer<AbstractMesh>>;
+    private _onElementOutObserver: Nullable<Observer<AbstractMesh>>;
+    
+    private _hoverLabel: Nullable<Mesh>;
 
     /** Observable raised when a refresh was done */
     public onRefreshObservable  = new Observable<Chart>();
@@ -40,6 +50,21 @@ export abstract class Chart {
     /** User defined callback used to create labels */
     public labelCreationFunction: Nullable<(label: string, width: number, includeBackground: boolean) => Mesh>;
 
+    /** Gets or sets the width of each element */
+    public get elementWidth(): number {
+        return this._elementWidth;
+    }
+
+    public set elementWidth(value: number) {
+        if (this._elementWidth === value) {
+            return;
+        }
+
+        this._elementWidth = value;
+
+        this.refresh();
+    }    
+
     /** Gets or sets the rotation of the entire chart */
     public set rotation(value: Vector3) {
         this._rootNode.rotation = value;
@@ -115,6 +140,79 @@ export abstract class Chart {
         }
     }
 
+    /** Gets or sets the material used by element meshes */
+    public get defaultMaterial(): Nullable<Material> {
+        return this._defaultMaterial;
+    }
+
+    public set defaultMaterial(value: Nullable<Material>) {
+        if (this._defaultMaterial === value) {
+            return;
+        }
+
+        this._defaultMaterial = value;
+
+        this.refresh();
+    }
+
+    /** Gets or sets a boolean indicating if glow should be used to highlight element hovering */
+    public get glowHover(): boolean {
+        return this._glowLayer !== undefined && this._glowLayer !== null;
+    }
+
+    public set glowHover(value: boolean) {
+        if (this.glowHover === value) {
+            return;
+        }
+
+        if (this._glowLayer) {
+            if (this._onElementEnterObserver) {
+                this.onElementEnterObservable.remove(this._onElementEnterObserver);
+                this._onElementEnterObserver = null;
+            }
+    
+            if (this._onElementOutObserver) {
+                this.onElementOutObservable.remove(this._onElementOutObserver);
+                this._onElementOutObserver = null;
+            } 
+
+            this._glowLayer.dispose();
+            this._glowLayer = null;
+            return;
+        }
+
+        this._glowLayer = new GlowLayer("glow", this._scene);
+
+        let activeBar: Nullable<Mesh>;
+        this._onElementEnterObserver = this.onElementEnterObservable.add(mesh => {
+            activeBar = <Mesh>mesh;
+
+            this._hoverLabel = this._addLabel(activeBar.metadata.value.toString(), this._elementWidth);
+
+            this._hoverLabel.position = activeBar.position.clone();
+            this._hoverLabel.position.y = activeBar.scaling.y + 0.5;
+            this._hoverLabel.scaling.x = this._elementWidth;            
+        });
+
+        this._onElementOutObserver = this.onElementOutObservable.add(mesh => {
+            activeBar = null;
+
+            if (this._hoverLabel) {
+                this._removeLabel(this._hoverLabel);
+                this._hoverLabel = null;
+            }
+        });
+
+        this._glowLayer.customEmissiveColorSelector = (mesh, subMesh, material, result) => {
+            if (mesh === activeBar) {
+                let chartColor = this._dataSource!.color.scale(0.75);
+                result.set(chartColor.r, chartColor.g, chartColor.b, 1.0);
+            } else {
+                result.set(0, 0, 0, 0);
+            }
+        }     
+    }
+
     /** Gets or sets the name of the graph */
     public name: string; 
 
@@ -159,6 +257,27 @@ export abstract class Chart {
 
             this.onPickedPointChangedObservable.notifyObservers(pi.pickInfo.pickedPoint);
         });
+
+        this.glowHover = true;
+    }
+
+    protected _createDefaultMaterial(scene: Scene): Material {
+        var result = new FluentMaterial("fluent", scene);
+        result.albedoColor = this._dataSource!.color.scale(0.5);
+        result.innerGlowColorIntensity = 0.6;
+        result.renderHoverLight = true;
+        result.hoverRadius = 5;
+
+        this._pickedPointObserver = this.onPickedPointChangedObservable.add(pickedPoint => {
+            if (pickedPoint) {
+                result.hoverPosition = pickedPoint;
+                result.hoverColor.a = 1.0;
+            } else {
+                result.hoverColor.a = 0;
+            }
+        });
+
+        return result;
     }
 
     /**
@@ -252,6 +371,13 @@ export abstract class Chart {
             this._pointerObserver = null;
         }
 
+        this.glowHover = false;
+
+        if (this._pickedPointObserver) {
+            this.onPickedPointChangedObservable.remove(this._pickedPointObserver);
+            this._pickedPointObserver = null;
+        }
+
         this._rootNode.dispose();
     }
 

+ 2 - 48
gui/src/3D/charting/mapGraph.ts

@@ -1,6 +1,5 @@
 import { Chart } from ".";
-import { Engine, Scene, Nullable, Mesh, Animation, StandardMaterial, Texture, Matrix, Material, Observer, Vector3 } from "babylonjs";
-import { FluentMaterial } from "../materials";
+import { Engine, Scene, Nullable, Mesh, Animation, StandardMaterial, Texture, Matrix } from "babylonjs";
 
 /** 
  * Class used to render bar graphs 
@@ -9,28 +8,11 @@ import { FluentMaterial } from "../materials";
 export class MapGraph extends Chart {
 
     private _cylinderMeshes: Nullable<Array<Mesh>>;
-    private _cylinderRadius = 0.5;    
     private _maxCylinderHeight = 10;
     private _worldMap: Nullable<Mesh>;
     private _mercatorMaterial: Nullable<StandardMaterial>;
     private _worldMapSize = 40;   
-    private _pickedPointObserver: Nullable<Observer<Vector3>>;    
-    private _defaultMaterial: Nullable<Material>;
 
-    /** Gets or sets the radius of each cylinder */
-    public get cylinderRadius(): number {
-        return this._cylinderRadius;
-    }
-
-    public set cylinderRadius(value: number) {
-        if (this._cylinderRadius === value) {
-            return;
-        }
-
-        this._cylinderRadius = value;
-
-        this.refresh();
-    }
     
     /** Gets or sets the size of the world map (this will define the width) */
     public get worldMapSize(): number {
@@ -70,25 +52,6 @@ export class MapGraph extends Chart {
         return cylinder;
     }
 
-    protected _createDefaultMaterial(scene: Scene): Material {
-        var result = new FluentMaterial("fluent", scene);
-        result.albedoColor = this._dataSource!.color.scale(0.5);
-        result.innerGlowColorIntensity = 0.6;
-        result.renderHoverLight = true;
-        result.hoverRadius = 5;
-
-        this._pickedPointObserver = this.onPickedPointChangedObservable.add(pickedPoint => {
-            if (pickedPoint) {
-                result.hoverPosition = pickedPoint;
-                result.hoverColor.a = 1.0;
-            } else {
-                result.hoverColor.a = 0;
-            }
-        });
-
-        return result;
-    }
-
     public refresh(): MapGraph {
         if (this._blockRefresh || !this._mercatorMaterial || !this._mercatorMaterial.emissiveTexture!.isReady()) {
             return this;
@@ -161,7 +124,7 @@ export class MapGraph extends Chart {
             cylinderMesh.metadata = entry;
             cylinderMesh.parent = this._rootNode;
             let currentScalingYState = cylinderMesh.scaling.y;
-            cylinderMesh.scaling.set(this._cylinderRadius, 0, this._cylinderRadius);
+            cylinderMesh.scaling.set(this._elementWidth / 2, 0, this._elementWidth / 2);
 
             // Lat/long convertion
             const latitude: number = entry.latitude;
@@ -188,13 +151,4 @@ export class MapGraph extends Chart {
         this._worldMap = null;
         this._cylinderMeshes = null;
     }
-    
-    /** Clean associated resources */
-    public dispose() {
-        super.dispose();
-        if (this._pickedPointObserver) {
-            this.onPickedPointChangedObservable.remove(this._pickedPointObserver);
-            this._pickedPointObserver = null;
-        }
-    }
 }