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>