Explorar el Código

Add labels for Chart3D
Associated with #3738 (for AddCheckboxWithHeader)

David Catuhe hace 7 años
padre
commit
033afa503c

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 9003 - 8819
Playground/babylon.d.txt


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 8871 - 8855
dist/preview release/babylon.d.ts


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/babylon.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 56 - 14
dist/preview release/babylon.max.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 56 - 14
dist/preview release/babylon.no-module.max.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/babylon.worker.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 56 - 14
dist/preview release/es6.js


+ 170 - 2
dist/preview release/gui/babylon.gui.d.ts

@@ -180,9 +180,10 @@ declare module BABYLON.GUI {
                 * @param width defines the texture width (1024 by default)
                 * @param height defines the texture height (1024 by default)
                 * @param supportPointerMove defines a boolean indicating if the texture must capture move events (true by default)
+                * @param onlyAlphaTesting defines a boolean indicating that alpha blending will not be used (only alpha testing) (false by default)
                 * @returns a new AdvancedDynamicTexture
                 */
-            static CreateForMesh(mesh: BABYLON.AbstractMesh, width?: number, height?: number, supportPointerMove?: boolean): AdvancedDynamicTexture;
+            static CreateForMesh(mesh: BABYLON.AbstractMesh, width?: number, height?: number, supportPointerMove?: boolean, onlyAlphaTesting?: boolean): AdvancedDynamicTexture;
             /**
                 * Creates a new AdvancedDynamicTexture in fullscreen mode.
                 * In this mode the texture will rely on a layer for its rendering.
@@ -484,6 +485,8 @@ declare module BABYLON.GUI {
 declare module BABYLON.GUI {
 }
 declare module BABYLON.GUI {
+}
+declare module BABYLON.GUI {
     /**
         * Class used to manage 3D user interface
         * @see http://doc.babylonjs.com/how_to/gui3d
@@ -659,6 +662,13 @@ declare module BABYLON.GUI {
             _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
             /** @hidden */
             _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number): boolean;
+            /**
+                * Utility function to easily create a checkbox with a header
+                * @param title defines the label to use for the header
+                * @param onValueChanged defines the callback to call when value changes
+                * @returns a StackPanel containing the checkbox and a textBlock
+                */
+            static AddCheckBoxWithHeader(title: string, onValueChanged: (value: boolean) => void): StackPanel;
     }
 }
 declare module BABYLON.GUI {
@@ -747,6 +757,11 @@ declare module BABYLON.GUI {
                 */
             addControl(control: BABYLON.Nullable<Control>): Container;
             /**
+                * Removes all controls from the current container
+                * @returns the current container
+                */
+            clearControls(): Container;
+            /**
                 * Removes a control from the current container
                 * @param control defines the control to remove
                 * @returns the current container
@@ -1809,6 +1824,10 @@ declare module BABYLON.GUI {
     /** Class used to render a grid  */
     export class DisplayGrid extends Control {
             name?: string | undefined;
+            /** Gets or sets a boolean indicating if minor lines must be rendered (true by default)) */
+            displayMinorLines: boolean;
+            /** Gets or sets a boolean indicating if major lines must be rendered (true by default)) */
+            displayMajorLines: boolean;
             /** Gets or sets background color (Black by default) */
             background: string;
             /** Gets or sets the width of each cell (20 by default) */
@@ -2323,7 +2342,7 @@ declare module BABYLON.GUI {
                 */
             renderHoverLight: boolean;
             /**
-                * Gets or sets the radius used to render the hover light (default is 0.15)
+                * Gets or sets the radius used to render the hover light (default is 1.0)
                 */
             hoverRadius: number;
             /**
@@ -2353,4 +2372,153 @@ declare module BABYLON.GUI {
             getClassName(): string;
             static Parse(source: any, scene: BABYLON.Scene, rootUrl: string): FluentMaterial;
     }
+}
+declare module BABYLON.GUI {
+    /** Class used to store data to display */
+    export class DataSeries {
+            /** Gets or sets the label of the series */
+            label: string;
+            /** Gets or sets the color associated with the series */
+            color: BABYLON.Color3;
+            /** Gets or sets the list of dimensions (used to filter data) */
+            dimensions: Array<string>;
+            /** Gets or sets the list of values (data to display) */
+            data: Array<any>;
+            /**
+                * Apply a list of filters to the data and return a list
+                * @param filters defines the filters to apply
+                * @returns an array containing the filtered data
+                */
+            getFilteredData(filters: {
+                    [key: string]: string;
+            }): Array<any>;
+            /**
+                * Get the different values of a dimension
+                * @param key defines the dimension name
+                * @returns An array of values
+                */
+            getDimensionValues(key: string): Array<any>;
+            /**
+                * Create a new DataSeries containing testing values
+                * @returns the new DataSeries
+                */
+            static CreateFakeData(): DataSeries;
+    }
+}
+declare module BABYLON.GUI {
+    /** base class for all chart controls*/
+    export abstract class Chart {
+            protected _dataSource: BABYLON.Nullable<DataSeries>;
+            protected _rootNode: BABYLON.TransformNode;
+            protected _dataFilters: {
+                    [key: string]: string;
+            };
+            protected _scene: BABYLON.Scene;
+            protected _blockRefresh: boolean;
+            /** BABYLON.Observable raised when a new element is created */
+            onElementCreated: BABYLON.Observable<BABYLON.Mesh>;
+            /** User defined callback used to create labels */
+            labelCreationFunction: (label: string, width: number, includeBackground: boolean) => BABYLON.Mesh;
+            /**
+                * BABYLON.Observable raised when the point picked by the pointer events changed
+                */
+            onPickedPointChangedObservable: BABYLON.Observable<BABYLON.Nullable<BABYLON.Vector3>>;
+            /**
+                * BABYLON.Observable raised when the pointer enters an element of the chart
+             */
+            onElementEnterObservable: BABYLON.Observable<BABYLON.AbstractMesh>;
+            /**
+                * BABYLON.Observable raised when the pointer leaves an element of the chart
+                */
+            onElementOutObservable: BABYLON.Observable<BABYLON.AbstractMesh>;
+            /** Gets or sets the rotation of the entire chart */
+            rotation: BABYLON.Vector3;
+            /** Gets or sets the position of the entire chart */
+            position: BABYLON.Vector3;
+            /** Gets or sets the scaling of the entire chart */
+            scaling: BABYLON.Vector3;
+            /** Gets or sets the data source used by the graph */
+            dataSource: BABYLON.Nullable<DataSeries>;
+            /** Gets the filters applied to data source */
+            dataFilters: {
+                    [key: string]: string;
+            };
+            /** Gets the root node associated with this graph */
+            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 name of the graph */
+            name: string;
+            /**
+                * Creates a new Chart
+                * @param name defines the name of the graph
+                * @param scene defines the hosting scene
+                */
+            constructor(name: string, scene?: BABYLON.Nullable<BABYLON.Scene>);
+            /**
+                * 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
+                * @param width defines the expected width (height is supposed to be 1)
+                * @param includeBackground defines if a background rectangle must be added (default is true)
+                * @returns a mesh used to host the label
+                */
+            addLabel(label: string, width: number, includeBackground?: boolean): BABYLON.Mesh;
+            /**
+                * Remove specific label mesh
+                * @param label defines the label mesh to remove
+                */
+            removeLabel(label: BABYLON.Mesh): void;
+            /** Remove all created labels */
+            removeLabels(): void;
+            /**
+                * Force the chart to redraw itself
+                * @returns the current chart
+             */
+            abstract refresh(): Chart;
+            /** Release all associated resources */
+            dispose(): void;
+            protected _clean(): void;
+    }
+}
+declare module BABYLON.GUI {
+    /** Class used to render bar graphs */
+    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 with 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
+                * @param scene defines the hosting scene
+                * @returns a new mesh used to represent the current bar
+                */
+            protected _createBarMesh(name: string, scene: BABYLON.Scene): BABYLON.Mesh;
+            /**
+                * Force the graph to redraw itself
+                * @returns the current BarGraph
+             */
+            refresh(): BarGraph;
+            /** Clean associated resources */
+            dispose(): void;
+            protected _clean(): void;
+    }
 }

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/gui/babylon.gui.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js.map


+ 354 - 4
dist/preview release/gui/babylon.gui.module.d.ts

@@ -20,6 +20,7 @@ declare module 'babylonjs-gui/2D' {
 declare module 'babylonjs-gui/3D' {
     export * from "babylonjs-gui/3D/controls";
     export * from "babylonjs-gui/3D/materials";
+    export * from "babylonjs-gui/3D/charting";
     export * from "babylonjs-gui/3D/gui3DManager";
     export * from "babylonjs-gui/3D/vector3WithInfo";
 }
@@ -222,9 +223,10 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
                 * @param width defines the texture width (1024 by default)
                 * @param height defines the texture height (1024 by default)
                 * @param supportPointerMove defines a boolean indicating if the texture must capture move events (true by default)
+                * @param onlyAlphaTesting defines a boolean indicating that alpha blending will not be used (only alpha testing) (false by default)
                 * @returns a new AdvancedDynamicTexture
                 */
-            static CreateForMesh(mesh: AbstractMesh, width?: number, height?: number, supportPointerMove?: boolean): AdvancedDynamicTexture;
+            static CreateForMesh(mesh: AbstractMesh, width?: number, height?: number, supportPointerMove?: boolean, onlyAlphaTesting?: boolean): AdvancedDynamicTexture;
             /**
                 * Creates a new AdvancedDynamicTexture in fullscreen mode.
                 * In this mode the texture will rely on a layer for its rendering.
@@ -554,6 +556,12 @@ declare module 'babylonjs-gui/3D/materials' {
     export * from "babylonjs-gui/3D/materials/fluentMaterial";
 }
 
+declare module 'babylonjs-gui/3D/charting' {
+    export * from "babylonjs-gui/3D/charting/dataSeries";
+    export * from "babylonjs-gui/3D/charting/chart";
+    export * from "babylonjs-gui/3D/charting/barGraph";
+}
+
 declare module 'babylonjs-gui/3D/gui3DManager' {
     import { IDisposable, Scene, Nullable, UtilityLayerRenderer, Observable, Vector3, Material } from "babylonjs";
     import { Container3D } from "babylonjs-gui/3D/controls/container3D";
@@ -716,6 +724,7 @@ declare module 'babylonjs-gui/2D/controls/checkbox' {
     import { Control } from "babylonjs-gui/2D/controls/control";
     import { Measure } from "babylonjs-gui/2D/measure";
     import { Observable, Vector2 } from "babylonjs";
+    import { StackPanel } from "babylonjs-gui/2D/controls/stackPanel";
     /**
         * Class used to represent a 2D checkbox
         */
@@ -743,6 +752,13 @@ declare module 'babylonjs-gui/2D/controls/checkbox' {
             _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
             /** @hidden */
             _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean;
+            /**
+                * Utility function to easily create a checkbox with a header
+                * @param title defines the label to use for the header
+                * @param onValueChanged defines the callback to call when value changes
+                * @returns a StackPanel containing the checkbox and a textBlock
+                */
+            static AddCheckBoxWithHeader(title: string, onValueChanged: (value: boolean) => void): StackPanel;
     }
 }
 
@@ -840,6 +856,11 @@ declare module 'babylonjs-gui/2D/controls/container' {
                 */
             addControl(control: Nullable<Control>): Container;
             /**
+                * Removes all controls from the current container
+                * @returns the current container
+                */
+            clearControls(): Container;
+            /**
                 * Removes a control from the current container
                 * @param control defines the control to remove
                 * @returns the current container
@@ -1963,6 +1984,10 @@ declare module 'babylonjs-gui/2D/controls/displayGrid' {
     /** Class used to render a grid  */
     export class DisplayGrid extends Control {
             name?: string | undefined;
+            /** Gets or sets a boolean indicating if minor lines must be rendered (true by default)) */
+            displayMinorLines: boolean;
+            /** Gets or sets a boolean indicating if major lines must be rendered (true by default)) */
+            displayMajorLines: boolean;
             /** Gets or sets background color (Black by default) */
             background: string;
             /** Gets or sets the width of each cell (20 by default) */
@@ -2527,7 +2552,7 @@ declare module 'babylonjs-gui/3D/materials/fluentMaterial' {
                 */
             renderHoverLight: boolean;
             /**
-                * Gets or sets the radius used to render the hover light (default is 0.15)
+                * Gets or sets the radius used to render the hover light (default is 1.0)
                 */
             hoverRadius: number;
             /**
@@ -2559,6 +2584,163 @@ declare module 'babylonjs-gui/3D/materials/fluentMaterial' {
     }
 }
 
+declare module 'babylonjs-gui/3D/charting/dataSeries' {
+    import { Color3 } from "babylonjs";
+    /** Class used to store data to display */
+    export class DataSeries {
+            /** Gets or sets the label of the series */
+            label: string;
+            /** Gets or sets the color associated with the series */
+            color: Color3;
+            /** Gets or sets the list of dimensions (used to filter data) */
+            dimensions: Array<string>;
+            /** Gets or sets the list of values (data to display) */
+            data: Array<any>;
+            /**
+                * Apply a list of filters to the data and return a list
+                * @param filters defines the filters to apply
+                * @returns an array containing the filtered data
+                */
+            getFilteredData(filters: {
+                    [key: string]: string;
+            }): Array<any>;
+            /**
+                * Get the different values of a dimension
+                * @param key defines the dimension name
+                * @returns An array of values
+                */
+            getDimensionValues(key: string): Array<any>;
+            /**
+                * Create a new DataSeries containing testing values
+                * @returns the new DataSeries
+                */
+            static CreateFakeData(): DataSeries;
+    }
+}
+
+declare module 'babylonjs-gui/3D/charting/chart' {
+    import { Nullable, TransformNode, Scene, Vector3, Observable, Mesh, AbstractMesh } from "babylonjs";
+    import { DataSeries } from "babylonjs-gui/3D/charting";
+    /** base class for all chart controls*/
+    export abstract class Chart {
+            protected _dataSource: Nullable<DataSeries>;
+            protected _rootNode: TransformNode;
+            protected _dataFilters: {
+                    [key: string]: string;
+            };
+            protected _scene: Scene;
+            protected _blockRefresh: boolean;
+            /** Observable raised when a new element is created */
+            onElementCreated: Observable<Mesh>;
+            /** User defined callback used to create labels */
+            labelCreationFunction: (label: string, width: number, includeBackground: boolean) => Mesh;
+            /**
+                * Observable raised when the point picked by the pointer events changed
+                */
+            onPickedPointChangedObservable: Observable<Nullable<Vector3>>;
+            /**
+                * Observable raised when the pointer enters an element of the chart
+             */
+            onElementEnterObservable: Observable<AbstractMesh>;
+            /**
+                * Observable raised when the pointer leaves an element of the chart
+                */
+            onElementOutObservable: Observable<AbstractMesh>;
+            /** Gets or sets the rotation of the entire chart */
+            rotation: Vector3;
+            /** Gets or sets the position of the entire chart */
+            position: Vector3;
+            /** Gets or sets the scaling of the entire chart */
+            scaling: Vector3;
+            /** Gets or sets the data source used by the graph */
+            dataSource: Nullable<DataSeries>;
+            /** Gets the filters applied to data source */
+            dataFilters: {
+                    [key: string]: string;
+            };
+            /** Gets the root node associated with this graph */
+            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 name of the graph */
+            name: string;
+            /**
+                * Creates a new Chart
+                * @param name defines the name of the graph
+                * @param scene defines the hosting scene
+                */
+            constructor(name: string, scene?: Nullable<Scene>);
+            /**
+                * 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
+                * @param width defines the expected width (height is supposed to be 1)
+                * @param includeBackground defines if a background rectangle must be added (default is true)
+                * @returns a mesh used to host the label
+                */
+            addLabel(label: string, width: number, includeBackground?: boolean): Mesh;
+            /**
+                * Remove specific label mesh
+                * @param label defines the label mesh to remove
+                */
+            removeLabel(label: Mesh): void;
+            /** Remove all created labels */
+            removeLabels(): void;
+            /**
+                * Force the chart to redraw itself
+                * @returns the current chart
+             */
+            abstract refresh(): Chart;
+            /** Release all associated resources */
+            dispose(): void;
+            protected _clean(): void;
+    }
+}
+
+declare module 'babylonjs-gui/3D/charting/barGraph' {
+    import { Nullable, Scene, Mesh, Material } from "babylonjs";
+    import { Chart } from "babylonjs-gui/3D/charting";
+    /** Class used to render bar graphs */
+    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 with 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
+                * @param scene defines the hosting scene
+                * @returns a new mesh used to represent the current bar
+                */
+            protected _createBarMesh(name: string, scene: Scene): Mesh;
+            /**
+                * Force the graph to redraw itself
+                * @returns the current BarGraph
+             */
+            refresh(): BarGraph;
+            /** Clean associated resources */
+            dispose(): void;
+            protected _clean(): void;
+    }
+}
+
 
 /*BabylonJS GUI*/
 // Dependencies for this module:
@@ -2742,9 +2924,10 @@ declare module BABYLON.GUI {
                 * @param width defines the texture width (1024 by default)
                 * @param height defines the texture height (1024 by default)
                 * @param supportPointerMove defines a boolean indicating if the texture must capture move events (true by default)
+                * @param onlyAlphaTesting defines a boolean indicating that alpha blending will not be used (only alpha testing) (false by default)
                 * @returns a new AdvancedDynamicTexture
                 */
-            static CreateForMesh(mesh: BABYLON.AbstractMesh, width?: number, height?: number, supportPointerMove?: boolean): AdvancedDynamicTexture;
+            static CreateForMesh(mesh: BABYLON.AbstractMesh, width?: number, height?: number, supportPointerMove?: boolean, onlyAlphaTesting?: boolean): AdvancedDynamicTexture;
             /**
                 * Creates a new AdvancedDynamicTexture in fullscreen mode.
                 * In this mode the texture will rely on a layer for its rendering.
@@ -3046,6 +3229,8 @@ declare module BABYLON.GUI {
 declare module BABYLON.GUI {
 }
 declare module BABYLON.GUI {
+}
+declare module BABYLON.GUI {
     /**
         * Class used to manage 3D user interface
         * @see http://doc.babylonjs.com/how_to/gui3d
@@ -3221,6 +3406,13 @@ declare module BABYLON.GUI {
             _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
             /** @hidden */
             _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number): boolean;
+            /**
+                * Utility function to easily create a checkbox with a header
+                * @param title defines the label to use for the header
+                * @param onValueChanged defines the callback to call when value changes
+                * @returns a StackPanel containing the checkbox and a textBlock
+                */
+            static AddCheckBoxWithHeader(title: string, onValueChanged: (value: boolean) => void): StackPanel;
     }
 }
 declare module BABYLON.GUI {
@@ -3309,6 +3501,11 @@ declare module BABYLON.GUI {
                 */
             addControl(control: BABYLON.Nullable<Control>): Container;
             /**
+                * Removes all controls from the current container
+                * @returns the current container
+                */
+            clearControls(): Container;
+            /**
                 * Removes a control from the current container
                 * @param control defines the control to remove
                 * @returns the current container
@@ -4371,6 +4568,10 @@ declare module BABYLON.GUI {
     /** Class used to render a grid  */
     export class DisplayGrid extends Control {
             name?: string | undefined;
+            /** Gets or sets a boolean indicating if minor lines must be rendered (true by default)) */
+            displayMinorLines: boolean;
+            /** Gets or sets a boolean indicating if major lines must be rendered (true by default)) */
+            displayMajorLines: boolean;
             /** Gets or sets background color (Black by default) */
             background: string;
             /** Gets or sets the width of each cell (20 by default) */
@@ -4885,7 +5086,7 @@ declare module BABYLON.GUI {
                 */
             renderHoverLight: boolean;
             /**
-                * Gets or sets the radius used to render the hover light (default is 0.15)
+                * Gets or sets the radius used to render the hover light (default is 1.0)
                 */
             hoverRadius: number;
             /**
@@ -4915,4 +5116,153 @@ declare module BABYLON.GUI {
             getClassName(): string;
             static Parse(source: any, scene: BABYLON.Scene, rootUrl: string): FluentMaterial;
     }
+}
+declare module BABYLON.GUI {
+    /** Class used to store data to display */
+    export class DataSeries {
+            /** Gets or sets the label of the series */
+            label: string;
+            /** Gets or sets the color associated with the series */
+            color: BABYLON.Color3;
+            /** Gets or sets the list of dimensions (used to filter data) */
+            dimensions: Array<string>;
+            /** Gets or sets the list of values (data to display) */
+            data: Array<any>;
+            /**
+                * Apply a list of filters to the data and return a list
+                * @param filters defines the filters to apply
+                * @returns an array containing the filtered data
+                */
+            getFilteredData(filters: {
+                    [key: string]: string;
+            }): Array<any>;
+            /**
+                * Get the different values of a dimension
+                * @param key defines the dimension name
+                * @returns An array of values
+                */
+            getDimensionValues(key: string): Array<any>;
+            /**
+                * Create a new DataSeries containing testing values
+                * @returns the new DataSeries
+                */
+            static CreateFakeData(): DataSeries;
+    }
+}
+declare module BABYLON.GUI {
+    /** base class for all chart controls*/
+    export abstract class Chart {
+            protected _dataSource: BABYLON.Nullable<DataSeries>;
+            protected _rootNode: BABYLON.TransformNode;
+            protected _dataFilters: {
+                    [key: string]: string;
+            };
+            protected _scene: BABYLON.Scene;
+            protected _blockRefresh: boolean;
+            /** BABYLON.Observable raised when a new element is created */
+            onElementCreated: BABYLON.Observable<BABYLON.Mesh>;
+            /** User defined callback used to create labels */
+            labelCreationFunction: (label: string, width: number, includeBackground: boolean) => BABYLON.Mesh;
+            /**
+                * BABYLON.Observable raised when the point picked by the pointer events changed
+                */
+            onPickedPointChangedObservable: BABYLON.Observable<BABYLON.Nullable<BABYLON.Vector3>>;
+            /**
+                * BABYLON.Observable raised when the pointer enters an element of the chart
+             */
+            onElementEnterObservable: BABYLON.Observable<BABYLON.AbstractMesh>;
+            /**
+                * BABYLON.Observable raised when the pointer leaves an element of the chart
+                */
+            onElementOutObservable: BABYLON.Observable<BABYLON.AbstractMesh>;
+            /** Gets or sets the rotation of the entire chart */
+            rotation: BABYLON.Vector3;
+            /** Gets or sets the position of the entire chart */
+            position: BABYLON.Vector3;
+            /** Gets or sets the scaling of the entire chart */
+            scaling: BABYLON.Vector3;
+            /** Gets or sets the data source used by the graph */
+            dataSource: BABYLON.Nullable<DataSeries>;
+            /** Gets the filters applied to data source */
+            dataFilters: {
+                    [key: string]: string;
+            };
+            /** Gets the root node associated with this graph */
+            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 name of the graph */
+            name: string;
+            /**
+                * Creates a new Chart
+                * @param name defines the name of the graph
+                * @param scene defines the hosting scene
+                */
+            constructor(name: string, scene?: BABYLON.Nullable<BABYLON.Scene>);
+            /**
+                * 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
+                * @param width defines the expected width (height is supposed to be 1)
+                * @param includeBackground defines if a background rectangle must be added (default is true)
+                * @returns a mesh used to host the label
+                */
+            addLabel(label: string, width: number, includeBackground?: boolean): BABYLON.Mesh;
+            /**
+                * Remove specific label mesh
+                * @param label defines the label mesh to remove
+                */
+            removeLabel(label: BABYLON.Mesh): void;
+            /** Remove all created labels */
+            removeLabels(): void;
+            /**
+                * Force the chart to redraw itself
+                * @returns the current chart
+             */
+            abstract refresh(): Chart;
+            /** Release all associated resources */
+            dispose(): void;
+            protected _clean(): void;
+    }
+}
+declare module BABYLON.GUI {
+    /** Class used to render bar graphs */
+    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 with 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
+                * @param scene defines the hosting scene
+                * @returns a new mesh used to represent the current bar
+                */
+            protected _createBarMesh(name: string, scene: BABYLON.Scene): BABYLON.Mesh;
+            /**
+                * Force the graph to redraw itself
+                * @returns the current BarGraph
+             */
+            refresh(): BarGraph;
+            /** Clean associated resources */
+            dispose(): void;
+            protected _clean(): void;
+    }
 }

+ 19 - 5
dist/preview release/viewer/babylon.viewer.d.ts

@@ -168,11 +168,11 @@ declare module BabylonViewer {
                 * Mainly used for help and errors
                 * @param subScreen the name of the subScreen. Those can be defined in the configuration object
                 */
-            showOverlayScreen(subScreen: string): Promise<string> | Promise<Template>;
+            showOverlayScreen(subScreen: string): Promise<Template> | Promise<string>;
             /**
                 * Hide the overlay screen.
                 */
-            hideOverlayScreen(): Promise<string> | Promise<Template>;
+            hideOverlayScreen(): Promise<Template> | Promise<string>;
             /**
                 * show the viewer (in case it was hidden)
                 *
@@ -189,11 +189,11 @@ declare module BabylonViewer {
                 * Show the loading screen.
                 * The loading screen can be configured using the configuration object
                 */
-            showLoadingScreen(): Promise<string> | Promise<Template>;
+            showLoadingScreen(): Promise<Template> | Promise<string>;
             /**
                 * Hide the loading screen
                 */
-            hideLoadingScreen(): Promise<string> | Promise<Template>;
+            hideLoadingScreen(): Promise<Template> | Promise<string>;
             dispose(): void;
             protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
     }
@@ -915,7 +915,7 @@ declare module BabylonViewer {
       * @param name the name of the custom optimizer configuration
       * @param upgrade set to true if you want to upgrade optimizer and false if you want to degrade
       */
-    export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
+    export function getCustomOptimizerByName(name: string, upgrade?: boolean): typeof extendedUpgrade;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
 }
 declare module BabylonViewer {
@@ -1541,6 +1541,20 @@ declare module BabylonViewer {
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
 }
 declare module BabylonViewer {
+    /**
+        * A custom upgrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedUpgrade(sceneManager: SceneManager): boolean;
+    /**
+        * A custom degrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedDegrade(sceneManager: SceneManager): boolean;
+}
+declare module BabylonViewer {
 }
 declare module BabylonViewer {
     export interface IEnvironmentMapConfiguration {

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 22 - 5
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -200,11 +200,11 @@ declare module 'babylonjs-viewer/viewer/defaultViewer' {
                 * Mainly used for help and errors
                 * @param subScreen the name of the subScreen. Those can be defined in the configuration object
                 */
-            showOverlayScreen(subScreen: string): Promise<string> | Promise<Template>;
+            showOverlayScreen(subScreen: string): Promise<Template> | Promise<string>;
             /**
                 * Hide the overlay screen.
                 */
-            hideOverlayScreen(): Promise<string> | Promise<Template>;
+            hideOverlayScreen(): Promise<Template> | Promise<string>;
             /**
                 * show the viewer (in case it was hidden)
                 *
@@ -221,11 +221,11 @@ declare module 'babylonjs-viewer/viewer/defaultViewer' {
                 * Show the loading screen.
                 * The loading screen can be configured using the configuration object
                 */
-            showLoadingScreen(): Promise<string> | Promise<Template>;
+            showLoadingScreen(): Promise<Template> | Promise<string>;
             /**
                 * Hide the loading screen
                 */
-            hideLoadingScreen(): Promise<string> | Promise<Template>;
+            hideLoadingScreen(): Promise<Template> | Promise<string>;
             dispose(): void;
             protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
     }
@@ -976,13 +976,14 @@ declare module 'babylonjs-viewer/templating/viewerTemplatePlugin' {
 }
 
 declare module 'babylonjs-viewer/optimizer/custom' {
+    import { extendedUpgrade } from "babylonjs-viewer/optimizer/custom/extended";
     import { SceneManager } from "babylonjs-viewer/managers/sceneManager";
     /**
       *
       * @param name the name of the custom optimizer configuration
       * @param upgrade set to true if you want to upgrade optimizer and false if you want to degrade
       */
-    export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
+    export function getCustomOptimizerByName(name: string, upgrade?: boolean): typeof extendedUpgrade;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
 }
 
@@ -1645,6 +1646,22 @@ declare module 'babylonjs-viewer/loader/plugins' {
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
 }
 
+declare module 'babylonjs-viewer/optimizer/custom/extended' {
+    import { SceneManager } from 'babylonjs-viewer/managers/sceneManager';
+    /**
+        * A custom upgrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedUpgrade(sceneManager: SceneManager): boolean;
+    /**
+        * A custom degrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedDegrade(sceneManager: SceneManager): boolean;
+}
+
 declare module 'babylonjs-viewer/configuration/interfaces' {
     export * from 'babylonjs-viewer/configuration/interfaces/cameraConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/colorGradingConfiguration';

+ 11 - 3
gui/src/2D/advancedDynamicTexture.ts

@@ -705,17 +705,25 @@ export class AdvancedDynamicTexture extends DynamicTexture {
      * @param width defines the texture width (1024 by default)
      * @param height defines the texture height (1024 by default)
      * @param supportPointerMove defines a boolean indicating if the texture must capture move events (true by default)
+     * @param onlyAlphaTesting defines a boolean indicating that alpha blending will not be used (only alpha testing) (false by default)
      * @returns a new AdvancedDynamicTexture
      */
-    public static CreateForMesh(mesh: AbstractMesh, width = 1024, height = 1024, supportPointerMove = true): AdvancedDynamicTexture {
+    public static CreateForMesh(mesh: AbstractMesh, width = 1024, height = 1024, supportPointerMove = true, onlyAlphaTesting = false): AdvancedDynamicTexture {
         var result = new AdvancedDynamicTexture(mesh.name + " AdvancedDynamicTexture", width, height, mesh.getScene(), true, Texture.TRILINEAR_SAMPLINGMODE);
 
         var material = new StandardMaterial("AdvancedDynamicTextureMaterial", mesh.getScene());
         material.backFaceCulling = false;
         material.diffuseColor = Color3.Black();
         material.specularColor = Color3.Black();
-        material.emissiveTexture = result;
-        material.opacityTexture = result;
+
+        if (onlyAlphaTesting) {
+            material.diffuseTexture = result;
+            material.emissiveTexture = result;
+            result.hasAlpha = true;    
+        } else {
+            material.emissiveTexture = result;
+            material.opacityTexture = result;   
+        }
 
         mesh.material = material;
 

+ 32 - 0
gui/src/2D/controls/checkbox.ts

@@ -1,6 +1,8 @@
 import { Control } from "./control";
 import { Measure } from "../measure";
 import { Observable, Vector2 } from "babylonjs";
+import { StackPanel } from "./stackPanel";
+import { TextBlock } from "./textBlock";
 
 /**
  * Class used to represent a 2D checkbox
@@ -142,4 +144,34 @@ export class Checkbox extends Control {
 
         return true;
     }
+
+    /**
+     * Utility function to easily create a checkbox with a header
+     * @param title defines the label to use for the header
+     * @param onValueChanged defines the callback to call when value changes
+     * @returns a StackPanel containing the checkbox and a textBlock
+     */
+    public static AddCheckBoxWithHeader(title: string, onValueChanged: (value: boolean) => void): StackPanel {
+        var panel = new StackPanel();
+        panel.isVertical = false;
+        panel.height = "30px";
+
+        var checkbox = new Checkbox();
+        checkbox.width = "20px";
+        checkbox.height = "20px";
+        checkbox.isChecked = true;
+        checkbox.color = "green";
+        checkbox.onIsCheckedChangedObservable.add(onValueChanged);
+        panel.addControl(checkbox);    
+    
+        var header = new TextBlock();
+        header.text = title;
+        header.width = "180px";
+        header.paddingLeft = "5px";
+        header.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+        header.color = "white";
+        panel.addControl(header); 
+
+        return panel;
+    }
 }   

+ 74 - 19
gui/src/3D/charting/barGraph.ts

@@ -22,6 +22,42 @@ export class BarGraph extends Chart {
     private _onElementOutObserver: Nullable<Observer<AbstractMesh>>;
     
     private _labelDimension: string;
+    private _displayLabels = true;
+    private _displayBackground = true;
+    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;
+    }
+
+    public set displayBackground(value: boolean) {
+        if (this._displayBackground === value) {
+            return;
+        }
+
+        this._displayBackground = value;
+
+        this.refresh();
+    }     
+
+    /** Gets or sets a boolean indicating if labels must be displayed */
+    public get displayLabels(): boolean {
+        return this._displayLabels;
+    }
+
+    public set displayLabels(value: boolean) {
+        if (this._displayLabels === value) {
+            return;
+        }
+
+        this._displayLabels = value;
+
+        this.refresh();
+    }    
 
     /** Gets or sets the margin between bars */
     public get margin(): number {
@@ -111,10 +147,22 @@ export class BarGraph extends Chart {
         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.z -= this.barWidth / 2;
+            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) => {
@@ -156,8 +204,6 @@ export class BarGraph extends Chart {
         var box = Mesh.CreateBox(name, 1, scene);
         box.setPivotPoint(new BABYLON.Vector3(0, -0.5, 0));
 
-        box.metadata = "chart";
-
         return box;
     }
 
@@ -202,6 +248,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;
 
         // Do we need to create new graph or animate the current one
         if (!this._barMeshes || this._barMeshes.length !== data.length) {
@@ -212,31 +259,44 @@ export class BarGraph extends Chart {
 
         this.removeLabels();
 
-        // Axis
-        if (!this._backgroundMesh) {
+        if (this._backgroundMesh) {
+            this._backgroundMesh.dispose(false, true);
+            this._backgroundMesh = null;
+        }
+
+        if (this._displayBackground) {
+            // Axis
             this._backgroundMesh = BABYLON.Mesh.CreatePlane("background", 1, scene);
             this._backgroundMesh.parent = this._rootNode;            
             this._backgroundMesh.setPivotPoint(new BABYLON.Vector3(0, -0.5, 0));
 
-            this._backgroundADT = AdvancedDynamicTexture.CreateForMesh(this._backgroundMesh, 512, 512, false);
+            this._backgroundADT = AdvancedDynamicTexture.CreateForMesh(this._backgroundMesh, this._backgroundResolution, this._backgroundResolution, false);
 
             let displayGrid = new DisplayGrid();
             displayGrid.displayMajorLines = false;
             displayGrid.minorLineColor = "White";
             displayGrid.minorLineTickness = 2;
-            displayGrid.cellWidth = 512 / data.length;
-            displayGrid.cellHeight = 512 / 5;
+            displayGrid.cellWidth = this._backgroundResolution / data.length;
+            displayGrid.cellHeight = this._backgroundResolution / this._backgroundTickCount;
 
             this._backgroundADT.addControl(displayGrid);
 
             (<StandardMaterial>this._backgroundMesh.material!).opacityTexture = null;
+
+            this._backgroundMesh.position.z = this.barWidth;
+            this._backgroundMesh.scaling.x = (this.barWidth + 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;
+                ticklabel.position.y = (this.maxBarHeight * (tickIndex - 0.25)) / this._backgroundTickCount;
+                ticklabel.position.z = this._barWidth;
+            }
         }
-        this._backgroundMesh.position.z = this.barWidth;
-        this._backgroundMesh.scaling.x = (this.barWidth + this.margin) * data.length;
-        this._backgroundMesh.scaling.y = this._maxBarHeight; 
 
         // We will generate one bar per entry
-        let left = -(data.length / 2) * (this.barWidth + this.margin) + 1.5 * this._margin;
         let index = 0;
         data.forEach(entry => {
 
@@ -249,6 +309,7 @@ export class BarGraph extends Chart {
                 barMesh = this._barMeshes![index++];
             }
 
+            barMesh.metadata = entry;
             barMesh.parent = this._rootNode;
             barMesh.position.x = left;
             let currentScalingYState = barMesh.scaling.y;
@@ -264,14 +325,13 @@ export class BarGraph extends Chart {
             left += this.barWidth + this.margin;
 
             // Label
-            if (!this._labelDimension) {
+            if (!this._labelDimension || !this._displayLabels) {
                 return;
             }
 
-            let label = this.addLabel(entry[this._labelDimension]);
+            let label = this.addLabel(entry[this._labelDimension], this.barWidth);
             label.position = barMesh.position.clone();
             label.position.z -= this.barWidth;
-            label.scaling.x = this.barWidth;
         });
 
         return this;
@@ -285,11 +345,6 @@ export class BarGraph extends Chart {
             this._defaultMaterial = null;
         }
 
-        if (this._backgroundADT) {
-            this._backgroundADT.dispose();
-            this._backgroundADT = null;
-        }
-
         if (this._pickedPointObserver) {
             this.onPickedPointChangedObservable.remove(this._pickedPointObserver);
             this._pickedPointObserver = null;

+ 68 - 11
gui/src/3D/charting/chart.ts

@@ -1,6 +1,6 @@
 import { Nullable, TransformNode, Scene, Vector3, Engine, Observer, PointerInfo, Observable, Mesh, AbstractMesh } from "babylonjs";
 import { DataSeries } from ".";
-import { AdvancedDynamicTexture, TextBlock } from "../../2D";
+import { AdvancedDynamicTexture, TextBlock, Rectangle, TextWrapping } from "../../2D";
 
 /** base class for all chart controls*/
 export abstract class Chart {
@@ -16,6 +16,9 @@ export abstract class Chart {
     /** Observable raised when a new element is created */
     public onElementCreated = new Observable<Mesh>();
 
+    /** User defined callback used to create labels */
+    public labelCreationFunction: (label: string, width: number, includeBackground: boolean) => Mesh;
+
     /**
      * Observable raised when the point picked by the pointer events changed
      */
@@ -131,38 +134,91 @@ export abstract class Chart {
                 return;
             }
 
-            if (pi.pickInfo.pickedMesh!.metadata === "chart") {
+            let metadata = pi.pickInfo.pickedMesh!.metadata;
+            if (metadata && metadata.value) {
                 if (this._lastElementOver !== pi.pickInfo.pickedMesh) {
+                    if (this._lastElementOver) {
+                        this.onElementOutObservable.notifyObservers(this._lastElementOver);
+                        this._lastElementOver = null;
+                    }
                     this._lastElementOver = pi.pickInfo.pickedMesh;
                     this.onElementEnterObservable.notifyObservers(this._lastElementOver!);
                 }
+            } else {
+                if (this._lastElementOver) {
+                    this.onElementOutObservable.notifyObservers(this._lastElementOver);
+                    this._lastElementOver = null;
+                }
             }
 
             this.onPickedPointChangedObservable.notifyObservers(pi.pickInfo.pickedPoint);
         });
     }
 
-    public addLabel(label: string): Mesh {
+    /**
+     * 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
+     * @param width defines the expected width (height is supposed to be 1)
+     * @param includeBackground defines if a background rectangle must be added (default is true)
+     * @returns a mesh used to host the label
+     */
+    public addLabel(label: string, width: number, includeBackground = true): Mesh {
+        if (this.labelCreationFunction) {
+            let labelMesh = this.labelCreationFunction(label, width, includeBackground);
+            labelMesh.parent = this._rootNode;
+
+            this._labelMeshes.push(labelMesh);
+
+            return labelMesh;
+        }
+
         let plane = Mesh.CreatePlane(label, 1, this._scene);
 
         this._labelMeshes.push(plane);
 
         plane.parent = this._rootNode;
         plane.billboardMode = Mesh.BILLBOARDMODE_ALL;
-        plane.renderingGroupId = 1;
+        plane.scaling.x = width;
 
-        let adt = AdvancedDynamicTexture.CreateForMesh(plane, 512, 128, false);
+        let resolution = 256;
+        let adt = AdvancedDynamicTexture.CreateForMesh(plane, resolution, resolution / width, false, true);
         let textBlock = new TextBlock(label, label);
         textBlock.color = "White";
+        textBlock.textWrapping = TextWrapping.Ellipsis;
         textBlock.fontWeight = "Bold";
-        textBlock.fontSize = 80;
-
-        adt.addControl(textBlock);
+        textBlock.fontSize = 50;
+
+        if (includeBackground) {
+            let rectangle = new Rectangle(label + "Border");
+            rectangle.thickness = 4;
+            rectangle.color = "White";
+            rectangle.background = "Black";
+            rectangle.addControl(textBlock);
+            adt.addControl(rectangle);
+        } else {
+            adt.addControl(textBlock);
+        }
 
         return plane;
     }
 
-    public removeLabels() {
+    /**
+     * Remove specific label mesh
+     * @param label defines the label mesh to remove
+     */
+    public removeLabel(label: Mesh): void {
+        let index = this._labelMeshes.indexOf(label);
+
+        if (index === -1) {
+            return;
+        }
+
+        this._labelMeshes.splice(index, 1);
+        label.dispose(false, true);
+    }
+
+    /** Remove all created labels */
+    public removeLabels(): void {
         this._labelMeshes.forEach(label => {
             label.dispose(false, true);
         });
@@ -171,11 +227,12 @@ export abstract class Chart {
     }
 
     /** 
-     * Force the graph to redraw itself 
-     * @returns the current BarGraph
+     * Force the chart to redraw itself 
+     * @returns the current chart
     */
     public abstract refresh(): Chart;
 
+    /** Release all associated resources */
     public dispose() {
         if (this._pointerObserver) {
             this._scene.onPointerObservable.remove(this._pointerObserver);