Browse Source

added module filters and modes variation.

Signed-off-by: Nicholas Jerome <nicholas.jerome@kit.edu>
Nicholas Jerome 7 years ago
parent
commit
f80b805492
3 changed files with 845 additions and 16 deletions
  1. 1 1
      config.yaml
  2. 342 15
      index.html
  3. 502 0
      static/Lut.js

+ 1 - 1
config.yaml

@@ -1,6 +1,6 @@
 background: cps_02.png
 password: PCE_D4t3nb4nk!
-polling: '120'
+polling: '30'
 port: '9567'
 pw_designer: ipe-test
 script: services/getdata.php

+ 342 - 15
index.html

@@ -41,12 +41,37 @@
         </div>
         <div class="bar-settings">
             <div class="bar-wrapper">
+                <div class="bar-setup">
+		    
+		    <span class="bl bar-hl">Select modes</span>
+                    <span class="br bar-info">
+		        <input type="radio" name="moduleMode" value="0" checked>On/Off<br>
+                        <input type="radio" name="moduleMode" value="1">Gradient
+                    </span>
+                </div>
+                
                 <div class="bar-setup">
 		    
 		    <span class="bl bar-hl">Show module number</span>
                     <span class="br bar-info">
 		        <input type="checkbox" id="mylabel">
                     </span>
+                </div>
+                <div class="bar-setup">
+                    <span class="bl bar-hl">Show module type</span>
+                    <span class="br bar-info">
+		        <input type="checkbox" id="myType">
+                    </span>
+
+                </div>
+                <div class="bar-setup">
+                    <span class="bl bar-hl"></span>
+                    <span class="br bar-info">
+		        <input type="radio" name="moduleType" value="A">A<br>
+                        <input type="radio" name="moduleType" value="B">B<br>
+                        <input type="radio" name="moduleType" value="C">C<br>
+                        <input type="radio" name="moduleType" value="D">D
+                    </span>
 		    
                 </div>
             </div>
@@ -87,6 +112,7 @@
     <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
     <script src="{{ static_url("scripts.js") }}"></script>
     <script src="{{ static_url("three.min.js") }}"></script>
+    <script src="{{ static_url("Lut.js") }}"></script>
     <script src="{{ static_url("OrbitControls.js") }}"></script>
     <script>
         // Global variable
@@ -158,7 +184,9 @@
         
         
     </script>
+    <!--
     <script src="https://dl.dropboxusercontent.com/u/3587259/Code/Threejs/CSS3DRenderer.js"></script>
+    -->
     <script>
         var camera, scene, renderer;
         var container;
@@ -178,6 +206,8 @@
 	    }
         });
         
+
+
 	function onMouseMove( event ) {
 	    // calculate mouse position in normalized device coordinates
 	    // (-1 to +1) for both components
@@ -3346,6 +3376,39 @@ scene.add(pv101a);
 
             //scene.fog = new THREE.FogExp2( 0x000000, 0.0128 );
             //renderer.setClearColor( scene.fog.color, 1 );
+
+
+	    lut = new THREE.Lut( 'rainbow', 512 );
+            lut.setMax( 2000 );
+            lut.setMin( 0 );
+
+            legend = lut.setLegendOn();
+            legend.name = "legend";
+            createLabel("legend_title");
+            createLabel("legend_low");
+            createLabel("legend_mid");
+            createLabel("legend_high");
+
+            $("#textlegend_title").css("fontSize", "16px");
+            $("#textlegend_title").text("Pca [W]");
+
+            $("#textlegend_mid").css("fontSize", "16px");
+            $("#textlegend_mid").css("color", "black");
+            $("#textlegend_mid").css("background-color", "transparent");
+            $("#textlegend_mid").text("5.0");
+
+            $("#textlegend_low").css("fontSize", "16px");
+            $("#textlegend_low").css("color", "black");
+            $("#textlegend_low").css("background-color", "transparent");
+            $("#textlegend_low").text("< 0.0");
+	    
+            $("#textlegend_high").css("fontSize", "16px");
+            $("#textlegend_high").css("color", "black");
+            $("#textlegend_high").css("background-color", "transparent");
+            $("#textlegend_high").text("> 10.0");
+
+            scene.add ( legend );
+
             render();
         }
             
@@ -3368,14 +3431,69 @@ scene.add(pv101a);
 
             render();
         }
-        
-        var vector;    
+
+        var vector;
+        var legend;
+        var width, height;
+        var widthHalf, heightHalf;
+        var pos_title, pos_high, pos_low, pos_mid;
+
         function render() {
             //console.log(camera.position);
             // if camera.position.y more than 90 then show module number
             scene.traverse( function( node ) {
                 if (node.name != "") {
                     //console.log(node.name);
+
+                    if (node.name == "legend") {
+			legend = scene.getObjectByName( "legend" );
+                        width = window.innerWidth;
+                        height = window.innerHeight;
+                        widthHalf = width / 2.0;
+                        heightHalf = height / 2.0;
+                        pos_title = legend.position.clone();
+                        
+                        pos_title.y = pos_title.y + 9;
+                        pos_title.x = pos_title.x - 1;
+                        pos_title.project(camera);
+                        pos_title.x = ( pos_title.x * widthHalf ) + widthHalf;
+                        pos_title.y = - ( pos_title.y * heightHalf ) + heightHalf;
+			$("#textlegend_title").show();
+                        $("#textlegend_title").css("top", (pos_title.y) + 'px');
+                        $("#textlegend_title").css("left", (pos_title.x) + 'px');
+                        
+                        pos_mid = legend.position.clone();
+                        pos_mid.y = pos_mid.y + 0;
+                        pos_mid.x = pos_mid.x + 2;
+                        pos_mid.project(camera);
+                        pos_mid.x = ( pos_mid.x * widthHalf ) + widthHalf;
+                        pos_mid.y = - ( pos_mid.y * heightHalf ) + heightHalf;
+			$("#textlegend_mid").show();
+                        $("#textlegend_mid").css("top", (pos_mid.y) + 'px');
+                        $("#textlegend_mid").css("left", (pos_mid.x) + 'px');
+                        
+                        pos_low = legend.position.clone();
+                        pos_low.y = pos_low.y - 5;
+                        pos_low.x = pos_low.x + 2;
+                        pos_low.project(camera);
+                        pos_low.x = ( pos_low.x * widthHalf ) + widthHalf;
+                        pos_low.y = - ( pos_low.y * heightHalf ) + heightHalf;
+			$("#textlegend_low").show();
+                        $("#textlegend_low").css("top", (pos_low.y) + 'px');
+                        $("#textlegend_low").css("left", (pos_low.x) + 'px');
+                        
+                        pos_high = legend.position.clone();
+                        pos_high.y = pos_high.y + 6;
+                        pos_high.x = pos_high.x + 2;
+                        pos_high.project(camera);
+                        pos_high.x = ( pos_high.x * widthHalf ) + widthHalf;
+                        pos_high.y = - ( pos_high.y * heightHalf ) + heightHalf;
+			$("#textlegend_high").show();
+                        $("#textlegend_high").css("top", (pos_high.y) + 'px');
+                        $("#textlegend_high").css("left", (pos_high.x) + 'px');
+
+                    }
+
                     var _id = node.name;
                     _id = _id.split("_")[3];
                     //console.log(_id2[3]);
@@ -3399,9 +3517,38 @@ scene.add(pv101a);
                     } else {
                         $(_id).hide();
                     }
+
+
+
                 }
             });
 
+            var mode = $('input[type=radio][name=moduleMode]:checked').val();
+            if (mode == "0") {
+		$("#textlegend_title").hide();
+		$("#textlegend_high").hide();
+		$("#textlegend_mid").hide();
+		$("#textlegend_low").hide();
+		legend_object = scene.getObjectByName( "legend" );
+                if (legend_object) {
+                    scene.remove(legend_object);
+                }
+                        
+            } else if (mode == "1") {
+		$("#textlegend_title").show();
+		$("#textlegend_high").show();
+		$("#textlegend_mid").show();
+		$("#textlegend_low").show();
+                legend_object = scene.getObjectByName( "legend", true );
+                if (!legend_object) {
+		    lut = new THREE.Lut( 'rainbow', 512 );
+		    lut.setMax( 2000 );
+		    lut.setMin( 0 );
+		    legend = lut.setLegendOn();
+		    legend.name = "legend";
+		    scene.add(legend);
+                }
+            }
  
             // update the picking ray with the camera and mouse position	
 	        raycaster.setFromCamera( mouse, camera );	
@@ -3411,12 +3558,10 @@ scene.add(pv101a);
                 //console.log("Check intersection");
                 //console.log(intersects);
 	        for ( var i = 0; i < intersects.length; i++ ) {
-		        //intersects[ i ].object.material.color.set( 0xff0000 );
-                //$("#obj-tooltip").text(intersects[ i ].object.name); 
-                if (intersects[ i ].object.name != "") {
-                    $("#obj-tooltip").text("Module: " + intersects[ i ].object.name);
-                    $("#val-tooltip").text("Value: " + data[ intersects[ i ].object.name ]);
-                }
+                    if (intersects[ i ].object.name != "" && intersects[ i ].object.name != "legend") {
+                        $("#obj-tooltip").text("Module: " + intersects[ i ].object.name);
+                        $("#val-tooltip").text("Value: " + data[ intersects[ i ].object.name ]);
+                    }
             }
             
             renderer.render(scene, camera);
@@ -3469,9 +3614,166 @@ scene.add(pv101a);
 <script>
 jQuery(window).load(function () {
 
+    var typeFlag, typeValue;
+    
+    $('input[type=radio][name=moduleType]').change(function() {
+        typeValue = this.value;
+        for (var prop in data) {
+            value = data[prop];
+
+            if (prop != "time") {
+                current_type = prop.split("_")[0][1];
+
+                if (current_type != typeValue) {
+                    colour = "0xaaaaaa";
+                } else {
+                    colour = mycm["jet"][parseInt(Math.floor( (value / 10.0) * 71.0 ))];     
+                    colour = "0x" + colour.substring(1);
+                }
+                object = scene.getObjectByName( prop, true );
+                if (object) {
+                    object.material.color.setHex( colour );
+                }
+            }
+        }
+    });
+  
+    
+    $("#myType").change(function() {
+	    if(this.checked) {
+	        typeFlag = true;
+                var radios = $('input:radio[name=moduleType]');
+                if(radios.is(':checked') === false) {
+                    radios.filter('[value=A]').prop('checked', true);
+                }
+                typeValue = "A";
+
+                for (var prop in data) {
+                    value = data[prop];
+
+                    if (prop != "time") {
+                        current_type = prop.split("_")[0][1];
+
+                        if (current_type != typeValue) {
+                            colour = "0xaaaaaa";
+                        } else {
+                            colour = mycm["jet"][parseInt(Math.floor( (value / 10.0) * 71.0 ))];     
+                            colour = "0x" + colour.substring(1);
+                        }
+                        object = scene.getObjectByName( prop, true );
+                        if (object) {
+                            object.material.color.setHex( colour );
+                        }
+                    }
+                }
+                //updateColour("A");
+            } else {
+	        typeFlag = false;
+                var radios = $('input:radio[name=moduleType]');
+                if(radios.is(':checked') === true) {
+                    radios.filter('[value=A]').prop('checked', false);
+                    radios.filter('[value=B]').prop('checked', false);
+                    radios.filter('[value=C]').prop('checked', false);
+                    radios.filter('[value=D]').prop('checked', false);
+                }
+                for (var prop in data) {
+                    value = data[prop];
+
+                    if (prop != "time") {
+                        colour = mycm["jet"][parseInt(Math.floor( (value / 10.0) * 71.0 ))];     
+                        colour = "0x" + colour.substring(1);
+                        object = scene.getObjectByName( prop, true );
+                        if (object) {
+                            object.material.color.setHex( colour );
+                        }
+                    }
+                }
+	    }
+        });
+
+
 myTimer();
 var myVar = setInterval(myTimer, 10000);
 
+var mycm = {
+    jet: ['#000080',
+ '#00008d',
+ '#00009f',
+ '#0000ad',
+ '#0000bf',
+ '#0000d1',
+ '#0000df',
+ '#0000f1',
+ '#0000ff',
+ '#0000ff',
+ '#0010ff',
+ '#001cff',
+ '#002cff',
+ '#0038ff',
+ '#0048ff',
+ '#0058ff',
+ '#0064ff',
+ '#0074ff',
+ '#0080ff',
+ '#0090ff',
+ '#00a0ff',
+ '#00acff',
+ '#00bcff',
+ '#00c8ff',
+ '#00d8ff',
+ '#02e8f4',
+ '#0cf4eb',
+ '#19ffde',
+ '#23ffd4',
+ '#30ffc7',
+ '#3cffba',
+ '#46ffb1',
+ '#53ffa4',
+ '#5dff9a',
+ '#6aff8d',
+ '#77ff80',
+ '#80ff77',
+ '#8dff6a',
+ '#9aff5d',
+ '#a4ff53',
+ '#b1ff46',
+ '#baff3c',
+ '#c7ff30',
+ '#d4ff23',
+ '#deff19',
+ '#ebff0c',
+ '#f4f802',
+ '#ffea00',
+ '#ffdb00',
+ '#ffd000',
+ '#ffc100',
+ '#ffb600',
+ '#ffa700',
+ '#ff9800',
+ '#ff8d00',
+ '#ff7e00',
+ '#ff7300',
+ '#ff6400',
+ '#ff5500',
+ '#ff4a00',
+ '#ff3b00',
+ '#ff3000',
+ '#ff2200',
+ '#ff1300',
+ '#f10800',
+ '#df0000',
+ '#d10000',
+ '#bf0000',
+ '#ad0000',
+ '#9f0000',
+ '#8d0000',
+ '#800000']
+}
+
+var min_pac = 0;
+var max_pac = 10.0;
+
+
 function myTimer() {
     var dataToSend = {};
     var object;
@@ -3492,14 +3794,39 @@ function myTimer() {
                 if (prop == "time") {
                     $("#slider-tooltip").text(value);
                 } else {
-                    // 0 = red
-                    // 1 = green
-                    if (value <= 0) {
-                        colour = "0xff0000";
-                    } else {
-                        colour = "0x242b72";
+                    var mode = $('input[type=radio][name=moduleMode]:checked').val();
+                    current_type = prop.split("_")[0][1];
+
+                    if (mode == "0") {
+                        legend_object = scene.getObjectByName( "legend", true );
+                        if (legend_object) {
+                            scene.remove(legend_object);
+                        }
+                        //animate();
+                        if (value <= 0) {
+                            colour = "0xff0000";
+                        } else {
+                            colour = "0x242b72";
+                        }
+                    } else if (mode == "1") {
+                        legend_object = scene.getObjectByName( "legend", true );
+                        if (!legend_object) {
+	                    lut = new THREE.Lut( 'rainbow', 512 );
+                            lut.setMax( 2000 );
+                            lut.setMin( 0 );
+                            legend = lut.setLegendOn();
+                            legend.name = "legend";
+                            scene.add(legend);
+                        }
+                        
+                        colour = mycm["jet"][parseInt(Math.floor( (value / 10.0) * 71.0 ))];     
+                        colour = "0x" + colour.substring(1);
+
+                        if (typeFlag == true && current_type != typeValue) {
+                            colour = "0xaaaaaa";
+                        }
+ 
                     }
-                
                     object = scene.getObjectByName( prop, true );
                     if (object) {
                         object.material.color.setHex( colour );

+ 502 - 0
static/Lut.js

@@ -0,0 +1,502 @@
+/**
+ * @author daron1337 / http://daron1337.github.io/
+ */
+
+THREE.Lut = function ( colormap, numberofcolors ) {
+
+	this.lut = [];
+	this.map = THREE.ColorMapKeywords[ colormap ];
+	this.n = numberofcolors;
+	this.mapname = colormap;
+
+	var step = 1.0 / this.n;
+
+	for ( var i = 0; i <= 1; i += step ) {
+
+		for ( var j = 0; j < this.map.length - 1; j ++ ) {
+
+			if ( i >= this.map[ j ][ 0 ] && i < this.map[ j + 1 ][ 0 ] ) {
+
+				var min = this.map[ j ][ 0 ];
+				var max = this.map[ j + 1 ][ 0 ];
+
+				var color = new THREE.Color( 0xffffff );
+				var minColor = new THREE.Color( 0xffffff ).setHex( this.map[ j ][ 1 ] );
+				var maxColor = new THREE.Color( 0xffffff ).setHex( this.map[ j + 1 ][ 1 ] );
+
+				color = minColor.lerp( maxColor, ( i - min ) / ( max - min ) );
+
+				this.lut.push( color );
+
+			}
+
+		}
+
+	}
+
+	return this.set( this );
+
+};
+
+THREE.Lut.prototype = {
+
+	constructor: THREE.Lut,
+
+	lut: [], map: [], mapname: 'rainbow', n: 256, minV: 0, maxV: 1, legend: null,
+
+	set: function ( value ) {
+
+		if ( value instanceof THREE.Lut ) {
+
+			this.copy( value );
+
+		}
+
+		return this;
+
+	},
+
+	setMin: function ( min ) {
+
+		this.minV = min;
+
+		return this;
+
+	},
+
+	setMax: function ( max ) {
+
+		this.maxV = max;
+
+		return this;
+
+	},
+
+	changeNumberOfColors: function ( numberofcolors ) {
+
+		this.n = numberofcolors;
+
+		return new THREE.Lut( this.mapname, this.n );
+
+	},
+
+	changeColorMap: function ( colormap ) {
+
+		this.mapname = colormap;
+
+		return new THREE.Lut( this.mapname, this.n );
+
+	},
+
+	copy: function ( lut ) {
+
+		this.lut = lut.lut;
+		this.mapname = lut.mapname;
+		this.map = lut.map;
+		this.n = lut.n;
+		this.minV = lut.minV;
+		this.maxV = lut.maxV;
+
+		return this;
+
+	},
+
+	getColor: function ( alpha ) {
+
+		if ( alpha <= this.minV ) {
+
+			alpha = this.minV;
+
+		} else if ( alpha >= this.maxV ) {
+
+			alpha = this.maxV;
+
+		}
+
+		alpha = ( alpha - this.minV ) / ( this.maxV - this.minV );
+
+		var colorPosition = Math.round ( alpha * this.n );
+		colorPosition == this.n ? colorPosition -= 1 : colorPosition;
+
+		return this.lut[ colorPosition ];
+
+	},
+
+	addColorMap: function ( colormapName, arrayOfColors ) {
+
+		THREE.ColorMapKeywords[ colormapName ] = arrayOfColors;
+
+	},
+
+	setLegendOn: function ( parameters ) {
+
+		if ( parameters === undefined ) {
+
+			parameters = {};
+
+		}
+
+		this.legend = {};
+
+		this.legend.layout = parameters.hasOwnProperty( 'layout' ) ? parameters[ 'layout' ] : 'vertical';
+
+		this.legend.position = parameters.hasOwnProperty( 'position' ) ? parameters[ 'position' ] : { 'x': 50.0, 'y': 8, 'z': 0 };
+
+		//this.legend.dimensions = parameters.hasOwnProperty( 'dimensions' ) ? parameters[ 'dimensions' ] : { 'width': 0.5, 'height': 3 };
+		this.legend.dimensions = parameters.hasOwnProperty( 'dimensions' ) ? parameters[ 'dimensions' ] : { 'width': 2, 'height': 12 };
+
+		this.legend.canvas = document.createElement( 'canvas' );
+
+		this.legend.canvas.setAttribute( 'id', 'legend' );
+		this.legend.canvas.setAttribute( 'hidden', true );
+
+		document.body.appendChild( this.legend.canvas );
+
+		this.legend.ctx = this.legend.canvas.getContext( '2d' );
+
+		this.legend.canvas.setAttribute( 'width',  1 );
+		this.legend.canvas.setAttribute( 'height', this.n );
+
+		this.legend.texture = new THREE.Texture( this.legend.canvas );
+
+		imageData = this.legend.ctx.getImageData( 0, 0, 1, this.n );
+
+		data = imageData.data;
+		len = data.length;
+
+		this.map = THREE.ColorMapKeywords[ this.mapname ];
+
+		var k = 0;
+
+		var step = 1.0 / this.n;
+
+		for ( var i = 1; i >= 0; i -= step ) {
+
+			for ( var j = this.map.length - 1; j >= 0; j -- ) {
+
+				if ( i < this.map[ j ][ 0 ] && i >= this.map[ j - 1 ][ 0 ]  ) {
+
+					var min = this.map[ j - 1 ][ 0 ];
+					var max = this.map[ j ][ 0 ];
+					var color = new THREE.Color( 0xffffff );
+					var minColor = new THREE.Color( 0xffffff ).setHex( this.map[ j - 1 ][ 1 ] );
+					var maxColor = new THREE.Color( 0xffffff ).setHex( this.map[ j ][ 1 ] );
+					color = minColor.lerp( maxColor, ( i - min ) / ( max - min ) );
+
+					data[ k * 4 ] = Math.round( color.r * 255 );
+					data[ k * 4 + 1 ] = Math.round( color.g * 255 );
+					data[ k * 4 + 2 ] = Math.round( color.b * 255 );
+					data[ k * 4 + 3 ] = 255;
+
+					k += 1;
+
+				}
+
+			}
+
+		}
+
+		this.legend.ctx.putImageData( imageData, 0, 0 );
+		this.legend.texture.needsUpdate = true;
+
+		this.legend.legendGeometry = new THREE.PlaneBufferGeometry( this.legend.dimensions.width, this.legend.dimensions.height );
+		this.legend.legendMaterial = new THREE.MeshBasicMaterial( { map : this.legend.texture, side : THREE.DoubleSide } );
+
+		this.legend.mesh = new THREE.Mesh( this.legend.legendGeometry, this.legend.legendMaterial );
+
+		if ( this.legend.layout == 'horizontal' ) {
+
+			this.legend.mesh.rotation.z = - 90 * ( Math.PI / 180 );
+
+		}
+
+		this.legend.mesh.position.copy( this.legend.position );
+
+		return this.legend.mesh;
+
+	},
+
+	setLegendOff: function () {
+
+		this.legend = null;
+
+		return this.legend;
+
+	},
+
+	setLegendLayout: function ( layout ) {
+
+		if ( ! this.legend ) {
+
+			return false;
+
+		}
+
+		if ( this.legend.layout == layout ) {
+
+			return false;
+
+		}
+
+		if ( layout != 'horizontal' && layout != 'vertical' ) {
+
+			return false;
+
+		}
+
+		this.layout = layout;
+
+		if ( layout == 'horizontal' ) {
+
+			this.legend.mesh.rotation.z = 90 * ( Math.PI / 180 );
+
+		}
+
+		if ( layout == 'vertical' ) {
+
+			this.legend.mesh.rotation.z = - 90 * ( Math.PI / 180 );
+
+		}
+
+		return this.legend.mesh;
+
+	},
+
+	setLegendPosition: function ( position ) {
+
+		this.legend.position = new THREE.Vector3( position.x, position.y, position.z );
+
+		return this.legend;
+
+	},
+
+	setLegendLabels: function ( parameters, callback ) {
+
+		if ( ! this.legend ) {
+
+			return false;
+
+		}
+
+		if ( typeof parameters === 'function' ) {
+
+			callback = parameters;
+
+		}
+
+		if ( parameters === undefined ) {
+
+			parameters = {};
+
+		}
+
+		this.legend.labels = {};
+
+		this.legend.labels.fontsize = parameters.hasOwnProperty( 'fontsize' ) ? parameters[ 'fontsize' ] : 128;
+
+		this.legend.labels.fontface = parameters.hasOwnProperty( 'fontface' ) ? parameters[ 'fontface' ] : 'Arial';
+
+		this.legend.labels.title = parameters.hasOwnProperty( 'title' ) ? parameters[ 'title' ] : '';
+
+		this.legend.labels.um = parameters.hasOwnProperty( 'um' ) ? ' [ ' + parameters[ 'um' ] + ' ]' : '';
+
+		this.legend.labels.ticks = parameters.hasOwnProperty( 'ticks' ) ? parameters[ 'ticks' ] : 0;
+
+		this.legend.labels.decimal = parameters.hasOwnProperty( 'decimal' ) ? parameters[ 'decimal' ] : 2;
+
+		this.legend.labels.notation = parameters.hasOwnProperty( 'notation' ) ? parameters[ 'notation' ] : 'standard';
+
+		var backgroundColor = { r: 255, g: 100, b: 100, a: 0.8 };
+		var borderColor =  { r: 255, g: 0, b: 0, a: 1.0 };
+		var borderThickness = 4;
+
+		var canvasTitle = document.createElement( 'canvas' );
+		var contextTitle = canvasTitle.getContext( '2d' );
+
+		contextTitle.font = 'Normal ' + this.legend.labels.fontsize + 'px ' + this.legend.labels.fontface;
+
+		var metrics = contextTitle.measureText( this.legend.labels.title.toString() + this.legend.labels.um.toString() );
+		var textWidth = metrics.width * 3.0;
+
+		contextTitle.fillStyle   = 'rgba(' + backgroundColor.r + ',' + backgroundColor.g + ',' + backgroundColor.b + ',' + backgroundColor.a + ')';
+
+		contextTitle.strokeStyle = 'rgba(' + borderColor.r + ',' + borderColor.g + ',' + borderColor.b + ',' + borderColor.a + ')';
+
+		contextTitle.lineWidth = borderThickness;
+
+		contextTitle.fillStyle = 'rgba( 0, 0, 0, 1.0 )';
+
+		contextTitle.fillText( this.legend.labels.title.toString() + this.legend.labels.um.toString(), borderThickness, this.legend.labels.fontsize + borderThickness );
+
+		var txtTitle = new THREE.CanvasTexture( canvasTitle );
+		txtTitle.minFilter = THREE.LinearFilter;
+
+		var spriteMaterialTitle = new THREE.SpriteMaterial( { map: txtTitle } );
+
+		var spriteTitle = new THREE.Sprite( spriteMaterialTitle );
+
+		spriteTitle.scale.set( 1.5, 1, 1.0 );
+
+		if ( this.legend.layout == 'vertical' ) {
+
+			spriteTitle.position.set( this.legend.position.x + this.legend.dimensions.width, this.legend.position.y + ( this.legend.dimensions.height * 0.6 ), this.legend.position.z );
+
+		}
+
+		if ( this.legend.layout == 'horizontal' ) {
+
+			spriteTitle.position.set( this.legend.position.x * 1.015, this.legend.position.y + ( this.legend.dimensions.height * 0.03 ), this.legend.position.z );
+
+		}
+
+		if ( this.legend.labels.ticks > 0 ) {
+
+			var ticks = {};
+			var lines = {};
+
+			if ( this.legend.layout == 'vertical' ) {
+
+				var topPositionY = this.legend.position.y + ( this.legend.dimensions.height * 0.36 );
+				var bottomPositionY = this.legend.position.y - ( this.legend.dimensions.height * 0.61 );
+
+			}
+
+			if ( this.legend.layout == 'horizontal' ) {
+
+				var topPositionX = this.legend.position.x + ( this.legend.dimensions.height * 0.75 );
+				var bottomPositionX = this.legend.position.x - ( this.legend.dimensions.width * 1.2  ) ;
+
+			}
+
+			for ( var i = 0; i < this.legend.labels.ticks; i ++ ) {
+
+				var value = ( this.maxV - this.minV ) / ( this.legend.labels.ticks - 1  ) * i + this.minV;
+
+				if ( callback ) {
+
+					value = callback ( value );
+
+				} else {
+
+					if ( this.legend.labels.notation == 'scientific' ) {
+
+						value = value.toExponential( this.legend.labels.decimal );
+
+					} else {
+
+						value = value.toFixed( this.legend.labels.decimal );
+
+					}
+
+				}
+
+				var canvasTick = document.createElement( 'canvas' );
+				var contextTick = canvasTick.getContext( '2d' );
+
+				contextTick.font = 'Normal ' + this.legend.labels.fontsize + 'px ' + this.legend.labels.fontface;
+
+				var metrics = contextTick.measureText( value.toString() );
+				var textWidth = metrics.width;
+
+				contextTick.fillStyle   = 'rgba(' + backgroundColor.r + ',' + backgroundColor.g + ',' + backgroundColor.b + ',' + backgroundColor.a + ')';
+
+				contextTick.strokeStyle = 'rgba(' + borderColor.r + ',' + borderColor.g + ',' + borderColor.b + ',' + borderColor.a + ')';
+
+				contextTick.lineWidth = borderThickness;
+
+				contextTick.fillStyle = 'rgba( 0, 0, 0, 1.0 )';
+
+				contextTick.fillText( value.toString(), borderThickness, this.legend.labels.fontsize + borderThickness );
+
+				var txtTick = new THREE.CanvasTexture( canvasTick );
+				txtTick.minFilter = THREE.LinearFilter;
+
+				var spriteMaterialTick = new THREE.SpriteMaterial( { map: txtTick } );
+
+				var spriteTick = new THREE.Sprite( spriteMaterialTick );
+
+				spriteTick.scale.set( 2, 1, 1.0 );
+
+				if ( this.legend.layout == 'vertical' ) {
+
+					var position = bottomPositionY + ( topPositionY - bottomPositionY ) * ( ( value - this.minV ) / ( this.maxV - this.minV ) );
+
+					spriteTick.position.set( this.legend.position.x + ( this.legend.dimensions.width * 2.7 ), position, this.legend.position.z );
+
+				}
+
+				if ( this.legend.layout == 'horizontal' ) {
+
+					var position = bottomPositionX + ( topPositionX - bottomPositionX ) * ( ( value - this.minV ) / ( this.maxV - this.minV ) );
+
+					if ( this.legend.labels.ticks > 5 ) {
+
+						if ( i % 2 === 0 ) {
+
+							var offset = 1.7;
+
+						} else {
+
+							var offset = 2.1;
+
+						}
+
+					} else {
+
+						var offset = 1.7;
+
+					}
+
+					spriteTick.position.set( position, this.legend.position.y - this.legend.dimensions.width * offset, this.legend.position.z );
+
+				}
+
+				var material = new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 2 } );
+
+				var geometry = new THREE.Geometry();
+
+
+				if ( this.legend.layout == 'vertical' ) {
+
+					var linePosition = ( this.legend.position.y - ( this.legend.dimensions.height * 0.5 ) + 0.01 ) + ( this.legend.dimensions.height ) * ( ( value - this.minV ) / ( this.maxV - this.minV ) * 0.99 );
+
+					geometry.vertices.push( new THREE.Vector3( this.legend.position.x + this.legend.dimensions.width * 0.55, linePosition, this.legend.position.z  ) );
+
+					geometry.vertices.push( new THREE.Vector3( this.legend.position.x + this.legend.dimensions.width * 0.7, linePosition, this.legend.position.z  ) );
+
+				}
+
+				if ( this.legend.layout == 'horizontal' ) {
+
+					var linePosition = ( this.legend.position.x - ( this.legend.dimensions.height * 0.5 ) + 0.01 ) + ( this.legend.dimensions.height ) * ( ( value - this.minV ) / ( this.maxV - this.minV ) * 0.99 );
+
+					geometry.vertices.push( new THREE.Vector3( linePosition, this.legend.position.y - this.legend.dimensions.width * 0.55, this.legend.position.z  ) );
+
+					geometry.vertices.push( new THREE.Vector3( linePosition, this.legend.position.y - this.legend.dimensions.width * 0.7, this.legend.position.z  ) );
+
+				}
+
+				var line = new THREE.Line( geometry, material );
+
+				lines[ i ] = line;
+				ticks[ i ] = spriteTick;
+
+			}
+
+		}
+
+		return { 'title': spriteTitle,  'ticks': ticks, 'lines': lines };
+
+	}
+
+};
+
+
+THREE.ColorMapKeywords = {
+
+	"rainbow":    [ [ 0.0, '0x0000FF' ], [ 0.2, '0x00FFFF' ], [ 0.5, '0x00FF00' ], [ 0.8, '0xFFFF00' ],  [ 1.0, '0xFF0000' ] ],
+	"cooltowarm": [ [ 0.0, '0x3C4EC2' ], [ 0.2, '0x9BBCFF' ], [ 0.5, '0xDCDCDC' ], [ 0.8, '0xF6A385' ],  [ 1.0, '0xB40426' ] ],
+	"blackbody" : [ [ 0.0, '0x000000' ], [ 0.2, '0x780000' ], [ 0.5, '0xE63200' ], [ 0.8, '0xFFFF00' ],  [ 1.0, '0xFFFFFF' ] ],
+	"grayscale" : [ [ 0.0, '0x000000' ], [ 0.2, '0x404040' ], [ 0.5, '0x7F7F80' ], [ 0.8, '0xBFBFBF' ],  [ 1.0, '0xFFFFFF' ] ]
+
+};