diff --git a/scenarios/WeissHapticSensorsUnitTest/tactile.html b/scenarios/WeissHapticSensorsUnitTest/tactile.html
index c86869f07d90536b40b3fe4cc11f11685b3ea78e..a0a5d1a8775ddc377e8c0f07f52f3aa7f0dcf9cb 100755
--- a/scenarios/WeissHapticSensorsUnitTest/tactile.html
+++ b/scenarios/WeissHapticSensorsUnitTest/tactile.html
@@ -3,8 +3,8 @@
 <head>
 <meta charset="utf-8">    
 <title>Tactile Sensor Data Explorer</title>
-<link rel="stylesheet" type="text/css" href="svg-export.css"/>
-<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
+<script type="text/javascript" src="jquery.sparkline.js"></script>
 <script>
 sensors = [];
 </script>
@@ -15,13 +15,56 @@ sensors = [];
 	font-size: 10px;
 	font-family: Verdana, sans;
 }
+div.sensor {
+	float: left;
+	padding: 10px;
+}
+body {
+	font-family: Verdana, sans;
+}
 </style>
 </head>
 <body>
+<div id="test"></div>
 <div id="buttons"></div>
 <div id="out"></div>
+<div id="graphs" style="clear:both; position:relative;"></div>
 <script>
 
+var getColor = function(x) {
+	var colors = ['000000', '0000ff', '00ffff', '00ff00', 'ffff00', 'ff0000'];
+	var f = x * (colors.length - 1);
+	if(f < 0) return '#' + colors[0];
+	if(f > colors.length - 1) return '#' + colors[colors.length - 1];
+	var i = Math.floor(f);
+	f = f - i;
+	var r1 = parseInt(colors[i].substr(0, 2), 16);
+	var g1 = parseInt(colors[i].substr(2, 2), 16);
+	var b1 = parseInt(colors[i].substr(4, 2), 16);
+	var r2 = parseInt(colors[i + 1].substr(0, 2), 16);
+	var g2 = parseInt(colors[i + 1].substr(2, 2), 16);
+	var b2 = parseInt(colors[i + 1].substr(4, 2), 16);
+	var r = Math.round(r1 * (1 - f) + r2 * f);
+	var g = Math.round(g1 * (1 - f) + g2 * f);
+	var b = Math.round(b1 * (1 - f) + b2 * f);
+	return '#' + ("000000" + (r * 256 * 256 + g * 256 + b).toString(16)).slice(-6);
+};
+/*for(var n = 0; n <= 1; n+=0.01) {
+	$("#test").append(n.toFixed(2) + " " + getColor(n)+"<br />");
+}*/
+
+var binarySearch = function(sensorData, timestamp)
+{
+	var low = 0, high = sensorData.length - 1, i, comparison;
+	while (low <= high) {
+		i = Math.floor((low + high) / 2);
+		if (sensorData[i][0] < timestamp) { low = i + 1; continue; };
+		if (sensorData[i][0] > timestamp) { high = i - 1; continue; };
+		return i;
+	}
+	return ~i;
+};
+
 var displayData = function(data) {
 	var s = 40;
 	var str = '<div style="position: relative; width:' + (data[0].length * s) + 'px; height:' + (data.length * s) + 'px;">';
@@ -29,25 +72,117 @@ var displayData = function(data) {
 		var row = data[y];
 		
 		for(var x = 0; x < row.length; x++) {
-			str += '<div style="top:' + (y * s) + 'px; left:' + (x * s) + 'px; width: '+s+'px; height: '+s+'px; position: absolute; text-align:center; line-height:'+s+'px; ">' + row[x] + '</div>';
+			str += '<div style="top:' + (y * s) + 'px; left:' + (x * s) + 'px; width: '+s+'px; height: '+s+'px; position: absolute; text-align:center; line-height:'+s+'px; background:' + getColor(row[x] / 4096) + '; color: #777;">' + row[x] + '</div>';
 		}
 	}
 	str += '</div>';
 	return str;
 };
 
-var pos = 0;
-var sensor = sensors[0];
 var formatDate = function(date) {
-	return date.getYear() + "-" + ("00" + date.getMonth()).slice(-2) + "-" + ("00" + date.getDate()).slice(-2) + " " + ("00" + date.getHours()).slice(-2) + ":" + ("00" + date.getMinutes()).slice(-2) + ":" + ("00" + date.getSeconds()).slice(-2) + "." + ("000" + date.getMilliseconds()).slice(-3);
+	return (date.getYear() + 1900) + "-" + ("00" + (date.getMonth() + 1)).slice(-2) + "-" + ("00" + date.getDate()).slice(-2) + " " + ("00" + date.getHours()).slice(-2) + ":" + ("00" + date.getMinutes()).slice(-2) + ":" + ("00" + date.getSeconds()).slice(-2) + "." + ("000" + date.getMilliseconds()).slice(-3);
 };
-var update = function() {
-	$("#out").html(sensor.device + ", tag=" + sensor.tag + "<br />Frame " + pos + "/" + (sensor.data.length - 1) + " t= " + formatDate(new Date(sensor.data[pos][0]/1000)) + displayData(sensor.data[pos][1]));
+var update = function(timestamp) {
+	for(var n = 0; n < sensors.length; n++) {
+		var html = "";
+		var sensor = sensors[n];
+		var pos = binarySearch(sensor.data, timestamp);
+		if (pos < 0) pos = ~pos;
+		sensor.pos = pos;
+		//html += '<div class="sensor">' + sensor.device + ", tag=" + sensor.tag;
+		html += sensor.device + ", tag=" + sensor.tag;
+		if (sensor == primarySensor) {
+			html += " (Primary)";
+		}
+		html += "<br />Frame " + pos + "/" + (sensor.data.length - 1) + " t=" + formatDate(new Date(sensor.data[pos][0]/1000)) + displayData(sensor.data[pos][1]);// + '</div>';
+		//html += '<div class="sensor">' + sensor.device + ", tag=" + sensor.tag + "<br />Frame " + pos + "/" + (sensor.data.length - 1) + " t= " + (new Date(sensor.data[pos][0]/1000)) + displayData(sensor.data[pos][1]) + '</div>';
+		sensor.div.html(html);
+	}
+	updatePositionDiv();
 }
-var changeFrameGen = function(delta) { return function() { pos = Math.max(0, Math.min(sensor.data.length - 1, pos + delta)); update(); }; };
+for (var n = 0; n < sensors.length; n++) {
+	var sensor = sensors[n];
+	sensor.pos = 0;
+	sensor.div = $('<div class="sensor"></div>');
+	$("#out").append(sensor.div);
+	sensor.div.data('sensor', sensor);
+	sensor.div.click(function() { primarySensor = $(this).data('sensor'); update(primarySensor.data[primarySensor.pos][0]); });
+}
+var primarySensor = sensors[0];
+
+var getPosByTimestamp = function(timestamp) { var pos = binarySearch(primarySensor.data, timestamp); if (pos < 0) pos = ~pos; return pos; };
+var selectFrameByTimestamp = function(timestamp) { primarySensor.pos = getPosByTimestamp(timestamp); changeFrame(0); };
+var changeFrame = function(delta) { primarySensor.pos = Math.max(0, Math.min(primarySensor.data.length - 1, primarySensor.pos + delta)); update(primarySensor.data[primarySensor.pos][0]); };
+var changeFrameGen = function(delta) { return function() { changeFrame(delta) }; };
 var buttonGen = function(text, delta) { return $("<button>"+text+"</button>").click(changeFrameGen(delta)); };
 $("#buttons").append("navigate: ").append(buttonGen("-100", -100)).append(buttonGen("-10", -10)).append(buttonGen("-1", -1)).append(buttonGen("+1", +1)).append(buttonGen("+10", +10)).append(buttonGen("+100", +100));
-update();
+
+
+$(document).keydown(function(e) {
+    switch(e.which) {
+        case 37: // left
+			changeFrame(e.ctrlKey ? -10 : -1);
+			break;
+
+        case 38: // up
+			break;
+
+        case 39: // right
+			changeFrame(e.ctrlKey ? 10 : 1);
+			break;
+
+        case 40: // down
+			break;
+
+        default: return; // exit this handler for other keys
+    }
+    e.preventDefault(); // prevent the default action (scroll / move caret)
+});
+
+var matrixMax = function(data) {
+	var max = data[0][0];
+	for(var y = 0; y < data.length; y++) {
+		var row = data[y];
+		for(var x = 0; x < row.length; x++) {
+			max = Math.max(max, row[x]);
+		}
+	}
+	return max;
+}
+
+//var $positionDiv = $('<div style="width:500px; height:20px;"></div>');
+var $positionDivInner = $('<div style="border-right: 1px solid #00A000; height: ' + (sensors.length * 50) + 'px; position: absolute; left: 0px; top: 0px; z-index:-10;"></div>');
+var updatePositionDiv = function() {
+	$positionDivInner.css('width', (primarySensor.pos / primarySensor.data.length * 500) + "px");
+};
+$("#graphs").append($positionDivInner);
+
+for(var n = 0; n < sensors.length; n++) {
+	var sensor = sensors[n];
+	var $div = $('<div style="line-height: 50px;"></div>');
+	$("#graphs").append($div);
+	var xvalues = [];
+	var yvalues = [];
+	for(var i = 0; i < sensor.data.length; i++) {
+		xvalues.push(sensor.data[i][0]);
+		yvalues.push(matrixMax(sensor.data[i][1]));
+	}
+	
+	$div.sparkline(yvalues, {"width":"500px", "height":"50px", "xvalues":xvalues, "spotColor":false, "minSpotColor":false, "maxSpotColor":false, 'fillColor': 'rgba(0,0,255,0.2)'});
+	$div.data('sensor', sensor);
+	$div.bind('sparklineClick', function(ev) {
+		var sparkline = ev.sparklines[0];
+		var sensor = $(this).data('sensor');
+        var region = sparkline.getCurrentRegionFields();
+		//alert("Clicked on x="+region.x+" y="+region.y);
+		primarySensor = sensor;
+		selectFrameByTimestamp(region.x);
+	});
+	$div.append(sensor.tag);
+}
+
+
+update(primarySensor.data[primarySensor.pos][0]);
 
 </script>
 </body>