annotate analyse.html @ 1961:bc31d1bc984c

Completed merge.
author Nicholas Jillings <nickjillings@users.noreply.github.com>
date Thu, 15 Oct 2015 10:32:15 +0100
parents f8a9b2466705
children 378726f0ac91 9da8a3e65a78
rev   line source
b@1479 1 <!DOCTYPE html>
b@1479 2 <html lang="en">
b@1479 3 <head>
b@1479 4 <meta charset="utf-8">
b@1479 5
b@1479 6 <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
b@1479 7 Remove this if you use the .htaccess -->
b@1479 8 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
b@1479 9
b@1479 10 <title>Analysis</title>
b@1479 11 <meta name="description" content="Show results from subjective evaluation">
b@1479 12 <meta name="author" content="Brecht De Man">
b@1479 13
b@1479 14 <script type="text/javascript" src="https://www.google.com/jsapi"></script>
b@1479 15 <script type="text/javascript">
b@1479 16 // To aid 'one-page set-up' all scripts and CSS must be included directly in this file!
b@1479 17
b@1479 18 google.load("visualization", "1", {packages:["corechart"]});
b@1479 19
b@1479 20 /*************
b@1479 21 * SETUP *
b@1479 22 *************/
b@1479 23 // folder where to find the XML files
b@1479 24 xmlFileFolder = "saves";
b@1479 25 // array of XML files
b@1479 26 var xmlFiles = ['McG-A-2014-03.xml','McG-B-2014-03.xml','McG-C-2014-03.xml'];
b@1479 27
b@1479 28 //TODO: make retrieval of file names automatic / drag files on here
b@1479 29
b@1479 30 /****************
b@1479 31 * VARIABLES *
b@1479 32 ****************/
b@1479 33
b@1479 34 // Counters
b@1479 35 // How many files, audioHolders, audioElementes and statements annotated (don't count current one)
b@1479 36 var numberOfFiles = -1;
b@1479 37 var numberOfaudioHolders = -1;
b@1479 38 var numberOfaudioElementes = -1;
b@1479 39 var numberOfStatements = -1;
b@1479 40 var numberOfSkippedComments = 0;
b@1479 41
b@1479 42 // Object arrays
b@1479 43 var fileNameArray = [];
b@1479 44 var subjectArray = [];
b@1479 45 var audioHolderArray = [];
b@1479 46 var audioElementArray = [];
b@1479 47
b@1479 48 // End of (file, audioholder, audioelement) flags
b@1479 49 var newFile = true;
b@1479 50 var newAudioHolder = true;
b@1479 51 var newAudioElement = true;
b@1479 52
b@1479 53 var fileCounter = 0; // file index
b@1479 54 var audioHolderCounter=0; // audioholder index (current XML file)
b@1479 55 var audioElementCounter=0; // audioelement index (current audioholder)
b@1479 56 var statementNumber=0; // total number of statements
b@1479 57
b@1479 58 var root; // root of XML file
b@1479 59 var commentInFull = ''; // full comment
b@1479 60
b@1479 61 var playAudio = true; // whether corresponding audio should be played back
b@1479 62
b@1479 63 // // Measuring time
b@1479 64 // var lastTimeMeasured = -1; //
b@1479 65 // var durationLastAnnotation = -1; // duration of last annotation
b@1479 66 // var timeArray = [];
b@1479 67 // var MIN_TIME = 1.0; // minimum time counted as significant
b@1479 68 // var measurementPaused = false; // whether time measurement is paused
b@1479 69 // var timeInBuffer = 0; //
b@1479 70
b@1479 71 var topLevel;
b@1479 72 window.onload = function() {
b@1479 73 // Initialise page
b@1479 74 topLevel = document.getElementById('topLevelBody');
b@1479 75 var setup = document.createElement('div');
b@1479 76 setup.id = 'setupTagDiv';
b@1479 77 loadAllFiles();
b@1479 78
b@1479 79 makePlots();
b@1479 80 // measure time at this point:
b@1479 81 lastTimeMeasured = new Date().getTime(); // in milliseconds
b@1479 82 };
b@1479 83
b@1479 84 // Assert function
b@1479 85 function assert(condition, message) {
b@1479 86 if (!condition) {
b@1479 87 message = message || "Assertion failed";
b@1479 88 if (typeof Error !== "undefined") {
b@1479 89 throw new Error(message);
b@1479 90 }
b@1479 91 throw message; // Fallback
b@1479 92 }
b@1479 93 }
b@1479 94
b@1479 95 function median(values) {
b@1479 96 values.sort( function(a,b) {return a - b;} );
b@1479 97 var half = Math.floor(values.length/2);
b@1479 98 if(values.length % 2)
b@1479 99 return values[half];
b@1479 100 else
b@1479 101 return (values[half-1] + values[half]) / 2.0;
b@1479 102 }
b@1479 103
b@1479 104 /***********************
b@1479 105 * TIME MEASUREMENT *
b@1479 106 ************************/
b@1479 107
b@1479 108 // measure time since last time this function was called
b@1479 109 function timeSinceLastCall() {
b@1479 110 // current time
b@1479 111 var currentTime = new Date().getTime();
b@1479 112 // calculate time difference
b@1479 113 var timeDifference = currentTime - lastTimeMeasured + timeInBuffer;
b@1479 114 // clear buffer (for pausing)
b@1479 115 timeInBuffer = 0;
b@1479 116 // remember last measured time
b@1479 117 lastTimeMeasured = currentTime;
b@1479 118 return timeDifference;
b@1479 119 }
b@1479 120
b@1479 121 // pause time measurement
b@1479 122 function pauseTimeMeasurement() {
b@1479 123 // UN-PAUSE
b@1479 124 if (measurementPaused) { // already paused
b@1479 125 // button shows 'pause' again
b@1479 126 document.getElementById('pauseButton').innerHTML = 'Pause';
b@1479 127 // toggle state
b@1479 128 measurementPaused = false;
b@1479 129 // resume time measurement
b@1479 130 lastTimeMeasured = new Date().getTime(); // reset time, discard time while paused
b@1479 131 } else { // PAUSE
b@1479 132 // button shows 'resume'
b@1479 133 document.getElementById('pauseButton').innerHTML = 'Resume';
b@1479 134 // toggle state
b@1479 135 measurementPaused = true;
b@1479 136 // pause time measurement
b@1479 137 timeInBuffer = timeSinceLastCall();
b@1479 138 }
b@1479 139 }
b@1479 140
b@1479 141 // show elapsed time on interface
b@1479 142 function showTimeElapsedInSeconds() {
b@1479 143 // if paused: un-pause
b@1479 144 if (measurementPaused) {
b@1479 145 pauseTimeMeasurement();
b@1479 146 }
b@1479 147
b@1479 148 // time of last annotation
b@1479 149 var lastAnnotationTime = timeSinceLastCall()/1000;
b@1479 150 document.getElementById('timeDisplay').innerHTML = lastAnnotationTime.toFixed(2);
b@1479 151 // average time over last ... annotations
b@1479 152 var avgAnnotationTime;
b@1479 153 var numberOfElementsToAverage =
b@1479 154 document.getElementById('numberOfTimeAverages').value;
b@1479 155 if (isPositiveInteger(numberOfElementsToAverage)) {
b@1479 156 avgAnnotationTime =
b@1479 157 calculateAverageTime(lastAnnotationTime,
b@1479 158 Number(numberOfElementsToAverage));
b@1479 159 } else {
b@1479 160 // change text field content to 'ALL'
b@1479 161 document.getElementById('numberOfTimeAverages').value = 'ALL';
b@1479 162 avgAnnotationTime = calculateAverageTime(lastAnnotationTime, -1);
b@1479 163 }
b@1479 164 document.getElementById('timeAverageDisplay').innerHTML = avgAnnotationTime.toFixed(2);
b@1479 165 }
b@1479 166
b@1479 167 // auxiliary function: is string a positive integer?
b@1479 168 // http://stackoverflow.com/questions/10834796/...
b@1479 169 // validate-that-a-string-is-a-positive-integer
b@1479 170 function isPositiveInteger(str) {
b@1479 171 var n = ~~Number(str);
b@1479 172 return String(n) === str && n >= 0;
b@1479 173 }
b@1479 174
b@1479 175 // calculate average time
b@1479 176 function calculateAverageTime(newTimeMeasurementInSeconds,numberOfPoints) {
b@1479 177 // append last measurement time to time array, if significant
b@1479 178 if (newTimeMeasurementInSeconds > MIN_TIME) {
b@1479 179 timeArray.push(newTimeMeasurementInSeconds);
b@1479 180 }
b@1479 181 // average over last N elements of this array
b@1479 182 if (numberOfPoints < 0 || numberOfPoints>=timeArray.length) { // calculate average over all
b@1479 183 var sum = 0;
b@1479 184 for (var i = 0; i < timeArray.length; i++) {
b@1479 185 sum += timeArray[i];
b@1479 186 }
b@1479 187 averageOfTimes = sum/timeArray.length;
b@1479 188 } else { // calculate average over specified number of times measured last
b@1479 189 var sum = 0;
b@1479 190 for (var i = timeArray.length-numberOfPoints; i < timeArray.length; i++) {
b@1479 191 sum += timeArray[i];
b@1479 192 }
b@1479 193 averageOfTimes = sum/numberOfPoints;
b@1479 194 }
b@1479 195 return averageOfTimes;
b@1479 196 }
b@1479 197
b@1479 198
b@1479 199 /********************************
b@1479 200 * PLAYBACK OF AUDIO *
b@1479 201 ********************************/
b@1479 202
b@1479 203 //PLAYaudioElement
b@1479 204 // Keep track of whether audio should be played
b@1479 205 function playFlagChanged(){
b@1479 206 playAudio = playFlag.checked; // global variable
b@1479 207
b@1479 208 if (!playAudio){ // if audio needs to stop
b@1479 209 audio.pause(); // stop audio - if anything is playing
b@1479 210 currently_playing = ''; // back to empty string so playaudioElement knows nothing's playing
b@1479 211 }
b@1479 212 }
b@1479 213
b@1479 214 // audioHolder that's currently playing
b@1479 215 var currently_playing_audioHolder = ''; // at first: empty string
b@1479 216 var currently_playing_audioElement = '';
b@1479 217 var audio;
b@1479 218
b@1479 219 // Play audioElement of audioHolder if available, from start or from same position
b@1479 220 function playaudioElement(audioHolderName, audioElementerName){
b@1479 221 if (playAudio) { // if enabled
b@1479 222 // get corresponding file from folder
b@1479 223 var file_location = 'audio/'+audioHolderName + '/' + audioElementerName + '.mp3'; // fixed path and file name format
b@1479 224
b@1479 225 // if not available, show error/warning message
b@1479 226 //TODO ...
b@1479 227
b@1479 228 // if nothing playing yet, start playing
b@1479 229 if (currently_playing_audioHolder == ''){ // signal that nothing is playing
b@1479 230 //playSound(audioBuffer);
b@1479 231 audio = new Audio(file_location);
b@1479 232 audio.loop = true; // loop when end is reached
b@1479 233 audio.play();
b@1479 234 currently_playing_audioHolder = audioHolderName;
b@1479 235 currently_playing_audioElement = audioElementerName;
b@1479 236 } else if (currently_playing_audioHolder != audioHolderName) {
b@1479 237 // if different audioHolder playing, stop that and start playing
b@1479 238 audio.pause(); // stop audio
b@1479 239 audio = new Audio(file_location); // load new file
b@1479 240 audio.loop = true; // loop when end is reached
b@1479 241 audio.play(); // play audio from the start
b@1479 242 currently_playing_audioHolder = audioHolderName;
b@1479 243 currently_playing_audioElement = audioElementerName;
b@1479 244 } else if (currently_playing_audioElement != audioElementerName) {
b@1479 245 // if same audioHolder playing, start playing from where it left off
b@1479 246 skipTime = audio.currentTime; // time to skip to
b@1479 247 audio.pause(); // stop audio
b@1479 248 audio = new Audio(file_location);
b@1479 249 audio.addEventListener('loadedmetadata', function() {
b@1479 250 this.currentTime = skipTime;
b@1479 251 console.log('Loaded '+audioHolderName+'-'+audioElementerName+', playing from '+skipTime);
b@1479 252 }, false); // skip to same time when audio is loaded!
b@1479 253 audio.loop = true; // loop when end is reached
b@1479 254 audio.play(); // play from that time
b@1479 255 audio.currentTime = skipTime;
b@1479 256 currently_playing_audioHolder = audioHolderName;
b@1479 257 currently_playing_audioElement = audioElementerName;
b@1479 258 }
b@1479 259 // if same audioElement playing: keep on playing (i.e. do nothing)
b@1479 260 }
b@1479 261 }
b@1479 262
b@1479 263 /********************
b@1479 264 * READING FILES *
b@1479 265 ********************/
b@1479 266
b@1479 267 // Read necessary data from XML file
b@1479 268 function readXML(xmlFileName){
b@1479 269 if (window.XMLHttpRequest)
b@1479 270 {// code for IE7+, Firefox, Chrome, Opera, Safari
b@1479 271 xmlhttp=new XMLHttpRequest();
b@1479 272 }
b@1479 273 else
b@1479 274 {// code for IE6, IE5
b@1479 275 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
b@1479 276 }
b@1479 277 xmlhttp.open("GET",xmlFileName,false);
b@1479 278 xmlhttp.send();
b@1479 279 return xmlhttp.responseXML;
b@1479 280 }
b@1479 281
b@1479 282 // go over all files and compute relevant statistics
b@1479 283 function loadAllFiles() {
b@1479 284 // retrieve information from XMLs
b@1479 285
b@1479 286 for (fileIndex = 0; fileIndex < xmlFiles.length; fileIndex++) {
b@1479 287 xmlFileName = xmlFileFolder+"/"+xmlFiles[fileIndex];
b@1479 288 xml = readXML(xmlFileName);
b@1479 289 if (xml != null) { // if file exists
b@1479 290 // append file name to array of file names
b@1479 291 fileNameArray.push(xmlFiles[fileIndex]);
b@1479 292
b@1479 293 // get root of XML file
b@1479 294 root = xml.getElementsByTagName('browserevaluationresult')[0];
b@1479 295
b@1479 296 // get subject ID, add to array if not already there
b@1479 297 pretest = root.getElementsByTagName('pretest')[0];
b@1479 298 subjectID = pretest.getElementsByTagName('comment')[0];
b@1479 299 if (subjectID.getAttribute('id')!='sessionId') { // warning in console when not available
b@1479 300 console.log(xmlFiles[fileIndex]+': no SessionID available');
b@1479 301 }
b@1479 302 if (subjectArray.indexOf(subjectID.textContent) == -1) { // if not already in array
b@1479 303 subjectArray.push(subjectID.textContent); // append to array
b@1479 304 }
b@1479 305
b@1479 306 // go over all audioHolders, add to array if not already there
b@1479 307 audioHolderNodes = root.getElementsByTagName('audioholder');
b@1479 308 // go over audioHolderNodes and append audioHolder name when not present yet
b@1479 309 for (audioHolderIndex = 0; audioHolderIndex < audioHolderNodes.length; audioHolderIndex++) {
b@1479 310 audioHolderName = audioHolderNodes[audioHolderIndex].getAttribute('id');
b@1479 311 if (audioHolderArray.indexOf(audioHolderName) == -1) { // if not already in array
b@1479 312 audioHolderArray.push(audioHolderName); // append to array
b@1479 313 }
b@1479 314 // within each audioHolder, go over all audioElement IDs, add to array if not already there
b@1479 315 audioElementNodes = audioHolderNodes[audioHolderIndex].getElementsByTagName('audioelement');
b@1479 316 for (audioElementIndex = 0; audioElementIndex < audioElementNodes.length; audioElementIndex++) {
b@1479 317 audioElementName = audioElementNodes[audioElementIndex].getAttribute('id');
b@1479 318 if (audioElementArray.indexOf(audioElementName) == -1) { // if not already in array
b@1479 319 audioElementArray.push(audioElementName); // append to array
b@1479 320 }
b@1479 321 }
b@1479 322 }
b@1479 323 // count occurrences of each audioHolder
b@1479 324 // ...
b@1479 325 }
b@1479 326 else {
b@1479 327 console.log('XML file '+xmlFileName+' not found.');
b@1479 328 }
b@1479 329 }
b@1479 330
b@1479 331 // sort alphabetically
b@1479 332 fileNameArray.sort();
b@1479 333 subjectArray.sort();
b@1479 334 audioHolderArray.sort();
b@1479 335 audioElementArray.sort();
b@1479 336
b@1479 337 // display all information in HTML
b@1479 338 // show XML file folder
b@1479 339 document.getElementById('xmlFileFolder_span').innerHTML = "\""+xmlFileFolder+"/\"";
b@1479 340 // show number of files
b@1479 341 document.getElementById('numberOfFiles_span').innerHTML = fileNameArray.length;
b@1479 342 // show list of subject names
b@1479 343 document.getElementById('subjectArray_span').innerHTML = subjectArray.toString();
b@1479 344 // show list of audioHolders
b@1479 345 document.getElementById('audioHolderArray_span').innerHTML = audioHolderArray.toString();
b@1479 346 // show list of audioElementes
b@1479 347 document.getElementById('audioElementArray_span').innerHTML = audioElementArray.toString();
b@1479 348 }
b@1479 349
b@1479 350 function makePlots() {
b@1479 351 // create value array
b@1479 352 var ratings = []; // 3D matrix of ratings (audioHolder, audioElement, subject)
b@1479 353 for (audioHolderIndex = 0; audioHolderIndex < audioHolderNodes.length; audioHolderIndex++) {
b@1479 354 ratings.push([]);
b@1479 355 for (audioElementIndex = 0; audioElementIndex < audioElementNodes.length; audioElementIndex++) {
b@1479 356 ratings[audioHolderIndex].push([]);
b@1479 357 }
b@1479 358 }
b@1479 359
b@1479 360 // go over all XML files
b@1479 361 for (fileIndex = 0; fileIndex < xmlFiles.length; fileIndex++) {
b@1479 362 xmlFileName = xmlFileFolder+"/"+xmlFiles[fileIndex];
b@1479 363 xml = readXML(xmlFileName);
b@1479 364 if (xml != null) { // if file exists
b@1479 365 // get root of XML file
b@1479 366 root = xml.getElementsByTagName('browserevaluationresult')[0];
b@1479 367 // go over all audioHolders
b@1479 368 audioHolderNodes = root.getElementsByTagName('audioholder');
b@1479 369 for (audioHolderIndex = 0; audioHolderIndex < audioHolderNodes.length; audioHolderIndex++) {
b@1479 370 audioHolderName = audioHolderNodes[audioHolderIndex].getAttribute('id');
b@1479 371 audioElementNodes = audioHolderNodes[audioHolderIndex].getElementsByTagName('audioelement');
b@1479 372 // go over all audioelements
b@1479 373 for (audioElementIndex = 0; audioElementIndex < audioElementNodes.length; audioElementIndex++) {
b@1479 374 audioElementName = audioElementNodes[audioElementIndex].getAttribute('id');
b@1479 375 // get value
b@1479 376 var value = audioElementNodes[audioElementIndex].getElementsByTagName("value")[0].textContent;
b@1479 377 if (value) { // if not empty, null, undefined...
b@1479 378 ratingValue = parseFloat(value);
b@1479 379 // add to matrix
b@1479 380 ratings[audioHolderIndex][audioElementIndex].push(ratingValue)
b@1479 381 }
b@1479 382 }
b@1479 383 }
b@1479 384
b@1479 385 // go over all audioHolders
b@1479 386
b@1479 387 // go over all audioElements within audioHolder, see if present in idMatrix, add if not
b@1479 388 // add corresponding rating to 'ratings', at position corresponding with position in idMatrix
b@1479 389 }
b@1479 390 }
b@1479 391
b@1479 392 for (audioHolderIndex = 0; audioHolderIndex < audioHolderArray.length; audioHolderIndex++) {
b@1479 393 audioHolderName = audioHolderArray[audioHolderIndex]; // for this song
b@1479 394 tickArray = []
b@1479 395 medianOfAudioElement = []
b@1479 396
b@1479 397 raw_data = [['SubjectID', 'Rating']];
b@1479 398 audioElIdx = 0;
b@1479 399 for (audioElementIndex = 0; audioElementIndex<ratings[audioHolderIndex].length; audioElementIndex++){
b@1479 400 if (ratings[audioHolderIndex][audioElementIndex].length>0) {
b@1479 401 audioElIdx++; // increase if not empty
b@1479 402 // make tick label
b@1479 403 tickArray.push({v:audioElIdx, f: audioElementArray[audioElementIndex]});
b@1479 404 // add median
b@1479 405 medianOfAudioElement.push(median(ratings[audioHolderIndex][audioElementIndex]));
b@1479 406 }
b@1479 407 for (subject = 0; subject<ratings[audioHolderIndex][audioElementIndex].length; subject++){
b@1479 408 // add subject-value pair for each subject
b@1479 409 raw_data.push([audioElIdx, ratings[audioHolderIndex][audioElementIndex][subject]]);
b@1479 410 }
b@1479 411 }
b@1479 412
b@1479 413 // create plot (one per song)
b@1479 414 var data = google.visualization.arrayToDataTable(raw_data);
b@1479 415
b@1479 416 var options = {
b@1479 417 title: audioHolderName,
b@1479 418 hAxis: {title: 'Subject', minValue: 0, maxValue: audioElIdx+1,
b@1479 419 ticks: tickArray},
b@1479 420 vAxis: {title: 'Rating', minValue: 0, maxValue: 1},
b@1479 421 seriesType: 'scatter',
b@1479 422 legend: 'none'
b@1479 423 };
b@1479 424 var div = document.createElement('div');
b@1479 425 document.body.appendChild(div);
b@1479 426 div.id = 'div_'+audioHolderName;
b@1479 427 div.style.width = '1100px';
b@1479 428 div.style.height = '350px';
b@1479 429 var chart = new google.visualization.ComboChart(document.getElementById('div_'+audioHolderName));
b@1479 430 chart.draw(data, options);
b@1479 431
b@1479 432 // box plots
b@1479 433 // function drawVisualization() {
b@1479 434 // // Create and populate the data table.
b@1479 435 // var data = google.visualization.arrayToDataTable([
b@1479 436 // ['ID', 'IQR', '', '', '', 'Median', 'Average'],
b@1479 437 // ['Serie1', 20, 28, 38, 45, 20, 25],
b@1479 438 // ['Serie2', 31, 38, 55, 66, 30, 35],
b@1479 439 // ['Serie3', 50, 55, 77, 80, 10, 15],
b@1479 440 // ['Serie4', 77, 77, 66, 50, 20, 25],
b@1479 441 // ['Serie5', 68, 66, 22, 15, 30, 35]
b@1479 442 // // Treat first row as data as well.
b@1479 443 // ]);
b@1479 444 // // Create and draw the visualization.
b@1479 445 // var ac = new google.visualization.ComboChart(document.getElementById('visualization'));
b@1479 446 // ac.draw(data, {
b@1479 447 // title : 'Box Plot with Median and Average',
b@1479 448 // width: 600,
b@1479 449 // height: 400,
b@1479 450 // vAxis: {title: "Value"},
b@1479 451 // hAxis: {title: "Serie ID"},
b@1479 452 // series: { 0: {type: "candlesticks"}, 1: {type: "line", pointSize: 10, lineWidth:
b@1479 453 // 0 }, 2: {type: "line", pointSize: 10, lineWidth: 0, color: 'black' } }
b@1479 454 // });
b@1479 455 // }
b@1479 456 }
b@1479 457 }
b@1479 458
b@1479 459 </script>
b@1479 460
b@1479 461
b@1479 462
b@1479 463 <style>
b@1479 464 div {
b@1479 465 padding: 2px;
b@1479 466 margin-top: 2px;
b@1479 467 margin-bottom: 2px;
b@1479 468 }
b@1479 469 div.head{
b@1479 470 margin-left: 10px;
b@1479 471 border: black;
b@1479 472 border-width: 2px;
b@1479 473 border-style: solid;
b@1479 474 }
b@1479 475 div.attrib{
b@1479 476 margin-left:25px;
b@1479 477 border: black;
b@1479 478 border-width: 2px;
b@1479 479 border-style: dashed;
b@1479 480 margin-bottom: 10px;
b@1479 481 }
b@1479 482 div#headerMatter{
b@1479 483 background-color: #FFFFCC;
b@1479 484 }
b@1479 485 div#currentStatement{
b@1479 486 font-size:3.0em;
b@1479 487 font-weight: bold;
b@1479 488
b@1479 489 }
b@1479 490 div#debugDisplay {
b@1479 491 color: #CCCCCC;
b@1479 492 font-size:0.3em;
b@1479 493 }
b@1479 494 span#scoreDisplay {
b@1479 495 font-weight: bold;
b@1479 496 }
b@1479 497 div#wrapper {
b@1479 498 width: 780px;
b@1479 499 border: 1px solid black;
b@1479 500 overflow: hidden; /* add this to contain floated children */
b@1479 501 }
b@1479 502 div#instrumentSection {
b@1479 503 width: 250px;
b@1479 504 border: 1px solid red;
b@1479 505 display: inline-block;
b@1479 506 }
b@1479 507 div#featureSection {
b@1479 508 width: 250px;
b@1479 509 border: 1px solid green;
b@1479 510 display: inline-block;
b@1479 511 }
b@1479 512 div#valenceSection {
b@1479 513 width: 250px;
b@1479 514 border: 1px solid blue;
b@1479 515 display: inline-block;
b@1479 516 }
b@1479 517 button#previousComment{
b@1479 518 width: 120px;
b@1479 519 height: 150px;
b@1479 520 font-size:1.5em;
b@1479 521 }
b@1479 522 button#nextComment{
b@1479 523 width: 666px;
b@1479 524 height: 150px;
b@1479 525 font-size:1.5em;
b@1479 526 }
b@1479 527 ul
b@1479 528 {
b@1479 529 list-style-type: none; /* no bullet points */
b@1479 530 margin-left: -20px; /* less indent */
b@1479 531 margin-top: 0px;
b@1479 532 margin-bottom: 5px;
b@1479 533 }
b@1479 534 </style>
b@1479 535
b@1479 536 </head>
b@1479 537
b@1479 538 <body>
b@1479 539 <h1>Subjective evaluation results</h1>
b@1479 540
b@1479 541 <div id="debugDisplay">
b@1479 542 XML file folder: <span id="xmlFileFolder_span"></span>
b@1479 543 </div>
b@1479 544
b@1479 545 <div id="headerMatter">
b@1479 546 <div>
b@1479 547 <strong>Result XML files:</strong> <span id="numberOfFiles_span"></span>
b@1479 548 </div>
b@1479 549 <div>
b@1479 550 <strong>Audioholders in dataset:</strong> <span id="audioHolderArray_span"></span>
b@1479 551 </div>
b@1479 552 <div>
b@1479 553 <strong>Subjects in dataset:</strong> <span id="subjectArray_span"></span>
b@1479 554 </div>
b@1479 555 <div>
b@1479 556 <strong>Audioelements in dataset:</strong> <span id="audioElementArray_span"></span>
b@1479 557 </div>
b@1479 558 <br>
b@1479 559 </div>
b@1479 560 <br>
b@1479 561
b@1479 562 <!-- Show time elapsed
b@1479 563 The last annotation took <strong><span id="timeDisplay">(N/A)</span></strong> seconds.
b@1479 564 <br>-->
b@1479 565
b@1479 566 </body>
b@1479 567 </html>