From 12118247b1b49aeee2bc7c20571caeff9fb4ff10 Mon Sep 17 00:00:00 2001 From: Josh de Leeuw Date: Wed, 10 Sep 2014 10:15:13 -0400 Subject: [PATCH] add progress bar option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Can now pass ‘show_progress_bar: true’ to init method to display a progress bar throughout the experiment. * default styling has been added to jspsych.css for the progress bar * bug fixes to jspsych.progress method to support this change (bug was related to getting progress after experiment had ended) * improved logic for when on_finish_trial callback function will trigger --- css/jspsych.css | 39 +++++++++++++++++++++++ jspsych.js | 82 ++++++++++++++++++++++--------------------------- 2 files changed, 76 insertions(+), 45 deletions(-) diff --git a/css/jspsych.css b/css/jspsych.css index 4f25ea6f..9c66cedd 100644 --- a/css/jspsych.css +++ b/css/jspsych.css @@ -20,6 +20,11 @@ html { line-height: 1.6em; } +body { + margin: 0; + padding: 0; +} + p { clear:both; } @@ -95,6 +100,40 @@ button:hover { margin: 50px auto 50px auto; } +/* + * + * jsPsych progress bar + * + */ + +#jspsych-progressbar-container { + color: #777; + border-bottom: 2px solid #dedede; + background-color: #f3f3f3; + margin-bottom: 1em; + text-align: center; + padding: 10px 0px; +} + +#jspsych-progressbar-container s { + +} + +#jspsych-progressbar-outer { + background-color: #dedede; + border-radius: 5px; + padding: 1px; + width: 800px; + margin: auto; +} + +#jspsych-progressbar-inner { + background-color: #aaa; /* #3EB3D7; */ + width: 0%; + height: 1em; + border-radius: 5px; +} + /* * * PLUGIN: jspsych-animation diff --git a/jspsych.js b/jspsych.js index b901af03..e3f38c2b 100755 --- a/jspsych.js +++ b/jspsych.js @@ -8,13 +8,10 @@ (function($) { jsPsych = (function() { - // - // public object - // var core = {}; // - // private class variables + // private variables // // options @@ -34,13 +31,6 @@ // public methods // - // core.init creates the experiment and starts running it - // display_element is an HTML element (usually a
) that will display jsPsych content - // options is an object: { - // "experiment_structure": an array of blocks specifying the experiment - // "finish": function to execute when the experiment ends - // } - // core.init = function(options) { // reset the key variables @@ -69,7 +59,8 @@ }, 'on_data_update': function(data) { return undefined; - } + }, + 'show_progress_bar': false }; // import options @@ -84,11 +75,6 @@ run(); }; - // core.data returns all of the data objects for each block as an array - // where core.data[0] = data object from block 0, etc... - // if flatten is true, then the hierarchical structure of the data - // is removed and each array entry will be a single trial. - core.data = function() { var all_data = []; @@ -99,17 +85,6 @@ return all_data; }; - - - // core.progress returns an object with the following properties - // total_blocks: the number of total blocks in the experiment - // total_trials: the number of total trials in the experiment - // current_trial_global: the current trial number in global terms - // i.e. if each block has 20 trials and the experiment is - // currently in block 2 trial 10, this has a value of 30. - // current_trial_local: the current trial number within the block. - // current_block: the current block number. - core.progress = function() { var total_trials = 0; @@ -118,41 +93,34 @@ } var current_trial_global = 0; + var current_trial_local = -1; for (var i = 0; i < curr_block; i++) { current_trial_global += exp_blocks[i].num_trials; } - current_trial_global += exp_blocks[curr_block].trial_idx; + if(current_trial_global < total_trials) { + current_trial_global += exp_blocks[curr_block].trial_idx; + current_trial_local = exp_blocks[curr_block].trial_idx; + } var obj = { "total_blocks": exp_blocks.length, "total_trials": total_trials, "current_trial_global": current_trial_global, - "current_trial_local": exp_blocks[curr_block].trial_idx, + "current_trial_local": current_trial_local, "current_block": curr_block }; return obj; }; - // core.startTime() returns the Date object which represents the time that the experiment started. - core.startTime = function() { return exp_start_time; }; - // core.totalTime() returns the length of time in ms since the experiment began - core.totalTime = function() { return (new Date()).getTime() - exp_start_time.getTime(); }; - // core.preloadImage will load images into the browser cache so that they appear quickly when - // used during a trial. - // images: array of paths to images - // callback_complete: a function with no arguments that calls when loading is complete - // callback_load: a function with a single argument that calls whenever an image is loaded - // argument is the number of images currently loaded. - core.preloadImages = function(images, callback_complete, callback_load) { // flatten the images array @@ -185,10 +153,11 @@ // private functions // // function run() { - // take the experiment structure and dynamically create a set of blocks + + // take the experiment structure and create a set of blocks exp_blocks = new Array(opts.experiment_structure.length); - // iterate through block list to create trials + // iterate through list to create trials for (var i = 0; i < exp_blocks.length; i++) { // check to make sure plugin is loaded @@ -201,6 +170,11 @@ exp_blocks[i] = createBlock(trials); } + + // show progress bar if requested + if(opts.show_progress_bar === true) { + drawProgressBar(); + } // record the start time exp_start_time = new Date(); @@ -232,8 +206,14 @@ // call on_trial_finish() // if not very first trial // and not the last call in this block (no trial due to advance in block) - if (typeof this.trials[this.trial_idx + 1] != "undefined" && (curr_block != 0 || this.trial_idx > -1)) { - opts.on_trial_finish(); + //if (typeof this.trials[this.trial_idx + 1] != "undefined" && (curr_block != 0 || this.trial_idx > -1)) { + if(this.trial_idx > -1){ + opts.on_trial_finish(); + + // update progress bar if shown + if(opts.show_progress_bar === true) { + updateProgressBar(); + } }; this.trial_idx = this.trial_idx + 1; @@ -285,6 +265,18 @@ // execute trial method jsPsych[trial.type]["trial"].call(this, DOM_target, block, trial, 1); } + + function drawProgressBar(){ + $('body').prepend($('
Completion Progress
')); + } + + function updateProgressBar(){ + var progress = jsPsych.progress(); + + var percentComplete = 100 * ( (progress.current_trial_global+1) / progress.total_trials); + + $('#jspsych-progressbar-inner').css('width', percentComplete+"%"); + } return core; })();