You're about to take a test on LabintheWild. Your contribution to our research allows us to learn more about cognitive differences around the world. The results from your test will also tell you something about yourself!
" +
"
Please read the following information carefully before proceeding.
" +
"Why we are doing this research: We are trying to understand how people perceive and name colors in different languages.
" +
"
What you will have to do: You will be asked to do two different tasks. In one, you will be shown color tiles and be asked to enter the name of the color. In the other, you will be shown a line of color tiles and will be asked to sort them by hue.
" +
"
What you will get out of it: We will give you feedback on how you performed on the tasks. The final results from this experiment will be posted on our blog page. The experiment is not explicitly designed to benefit you, but you may enjoy it and enjoy comparing your results with those of other participants.
" +
"
Privacy and Data Collection: We will not ask you for your name. Any data that we collect will be securely stored on our servers.
" +
"
Duration: Approximately 12 minutes.
" +
"
Contact information: If you have questions about this research, you may contact Professor Katharina Reinecke, Paul G. Allen Center for Computer Science & Engineering, Box 352350, Seattle, WA 98195, reinecke@cs.washington.edu." +
"
If you have questions about your rights as a research participant, or wish to obtain information, ask questions or discuss any concerns about this study with someone other than the researcher(s), please contact the University of Washington Human Subjects Division at 206-543-0098 (for international calls include the US Calling Code: +1-206-543-0098)." +
"
";
$("#irb").html(html);
$.each(available_locales, function(locale, localeInfo){
var opt = document.createElement("option");
opt.innerHTML = localeInfo.name;
opt.value = locale;
if(locale == litw_locale){
opt.selected = true;
}
$("#locale_select_irb").append(opt);
});
$("body").css("direction", window.direction);
if(window.direction == "rtl"){
$("#locale_select_irb").removeClass("pull-right");
$("#locale_select_irb").addClass("pull-left");
//Mirror the nextButton box
//nevermind, informed it wasn't helpful to mirror it.
//$("#nextButton").css("transform", "rotateY(180deg)");
}
$("#locale_select_irb").change(function(){
var selectedLocale = $("#locale_select_irb").val();
if(selectedLocale != litw_locale){
window.location.replace("?locale=" + selectedLocale)
}
});
LE.showSlide("irb");
window.scrollTo(0, 0);
//in RTL languages, we mirror the next button box, so this is a hack to flip the inside back
var rtlStyleHack2 = "";
// nevermind, told it wasn't helpful to mirror next button
//if(window.direction == "rtl"){
// rtlStyleHack2 = "style='transform:rotateY(180deg); float:left;'"
//}
$("#nextButton").html(" You must check the box to continue.");
$("#agreeToStudy").on("click", function () {
if ($("#agreeToStudy").is(':checked')) {
LE.showNextButton(demographics);
} else {
$("#nextButton").html(" You must check the box to continue.");
}
});
}
// variable to keep track of lighting info given before more iquestion is clicked
var lighting = [];
function updateVal(val, name) {
var clampped = clamp(val);
if(name == 'surrBright'){
lighting[0] = clampped;
$("#surrBrightness")[0].value = clampped;
$("#surrBrightnessSlider")[0].value = clampped;
$("[for='surrBright'] span").html(clampped);
}
if(name == 'mBright'){
lighting[2] = clampped;
$("#mBrightness")[0].value = clampped;
$("#mBrightnessSlider")[0].value = clampped;
$("[for='mBright'] span").html(clampped);
}
function clamp(value){
if (isNaN(value)) { return -1; };
if (value < 0){
return 0;
} else if (value >100) {
return 100;
} else {
return value;
}
}
}
function updateCheck(name, box){
if(name == "mBright"){
$("#mBrightIDK")[0].value = box.checked;
}
if(name == "surrBright"){
$("#surrBrightIDK")[0].value = box.checked;
}
}
function demographics() {
var languages = {};
languages["Other"] = "Other";
$.each(languages_iso_639, function(i, d){
languages[d["Language name"]] = d["Language name"] + " ("+d["Native name"]+")";
});
var languageFluencyOptions = {
"fluently": "fluently",
"very well": "very well",
"well": "well",
"at beginner's level": "at beginner's level"
};
LE.newForm("demographics", {
requiredQuestions: ["retake", "multinational", "country0", "gender", "age", "education", "multilingual", "lang0", "colorReading"]
})
.add("retake")
.add("multinational")
.add("country0")
.add("lang0", {
name: "lang0",
style: "dropdown",
options: languages,
prompt: "What is your native language? If more than one native language, choose the language you would prefer to name colors in. ",
optionsAsNumbers: false,
expand: "langAOtherText0",
expansionTrigger: "Other"
})
.add("langAOtherText0", {
name: "langAOtherText0",
style: "shortFreeText",
prompt: "",
expansionPrompt: "",
expansionHeader: "Please fill in your native language",
hidden: true,
maxExpansions: 1
})
.add("lang1", {
name: "lang1",
style: "dropdown",
options: languages,
prompt: "List up to two other languages you know below: Language 2?",
optionsAsNumbers: false,
expand: "langBOtherText0",
expansionTrigger: "Other"
})
.add("langBOtherText0", {
name: "langBOtherText0",
style: "shortFreeText",
prompt: "",
expansionPrompt: "",
expansionHeader: "Please fill in your second language",
hidden: true,
maxExpansions: 1
})
.add("fluency1", {
name: "fluency1",
style: "dropdown",
options: languageFluencyOptions,
prompt: " Fluency in language 2?",
})
.add("lang2", {
name: "lang2",
style: "dropdown",
options: languages,
prompt: " Language 3?",
optionsAsNumbers: false,
expand: "langCOtherText0",
expansionTrigger: "Other"
})
.add("langCOtherText0", {
name: "langCOtherText0",
style: "shortFreeText",
prompt: "",
expansionPrompt: "",
expansionHeader: "Please fill in your third language",
hidden: true,
maxExpansions: 1
})
.add("fluency2", {
name: "fluency2",
style: "dropdown",
options: languageFluencyOptions,
prompt: " Fluency in language 3?",
})
.add("gender")
.add("age", {style: "numericalFreeText", prompt: "How old are you? (Please type a number between 6 and 99)" })
.add("education")
.add("colorReading", {
name: "colorReading",
style: "dropdown",
options: "yesNo",
prompt: "Have you recently looked in detail at any website comparing how colors are named in different languages?"
})
.add("colorWork", {
name: "colorWork",
style: "dropdown",
options: "yesNo",
prompt: "Do your work or studies require you to have a knowledge of different colors and their names that might be considered above average? (e.g. graphic designer, painter, make-up artist)?",
expand: "colorWorkText0",
expansionTrigger: "1",
optionsAsNumbers: true
})
.add("colorWorkText0", {
name: "colorWorkText0",
style: "freeText",
prompt: "",
expansionPrompt: "",
expansionHeader: "Please tell us what those work or studies are (in a word or a short sentance)?",
hidden: true,
maxExpansions: 1
})
.add("colorBlindness", {
name: "colorBlindness",
style: "dropdown",
options: {"none": "None",
"red-green": "Red-green",
"blue-yellow": "Blue-yellow",
"total": "Total Color Blindness",
"other": "Other"},
prompt: "If you have color vision deficiency, please select your type:",
expand: "colorBlindnessText0",
expansionTrigger: "other",
optionsAsNumbers: false
})
.add("colorBlindnessText0", {
name: "colorBlindnessText0",
style: "freeText",
prompt: "",
expansionPrompt: "",
expansionHeader: "If you are comfortable, please describe your color blindness (in a word or a short sentance):",
hidden: true,
maxExpansions: 1
})
//brightness options
.add("surrBrightIDK", {
name: "surrBrightIDK",
style: "freeText",
prompt: "",
hidden: true,
maxExpansions: 1
})
.add("mBrightIDK", {
name: "mBrightIDK",
style: "freeText",
prompt: "",
hidden: true,
maxExpansions: 1
})
.render(function(){
var lang_id = $("select#lang0").val();
if(lang_id == "Other"){
expData.nativeLanguage = $("#langAOtherText0").val();
}else{
expData.nativeLanguage = languages[lang_id];
}
//remove whitespace, which is causing some problems in comparisons
var languagesforfullrgb_no_white = window.languagesforfullrgb.map(function(s){return s.replace(/\s/g, '')});
if(languagesforfullrgb_no_white.indexOf(expData.nativeLanguage.replace(/\s/g, '')) >= 0){
//still collect line data 1 out of 10 times
// otherwise collect from the full data set
if(Math.floor(Math.random() * 10) != 0){
rgbSet = "full";
}
}
clearInterval(window.sortCountriesInterval);
nextPhase();
});
//in RTL languages, we want the text to be to the right of the sliders
var rtlStyleHack1 = "";
if(window.direction == "rtl"){
rtlStyleHack1 = "style='float:right;'"
}
//in LTR languages, we want the "don't know" text spaced over
var rtlStyleHack2 = "";
if(window.direction == "ltr"){
rtlStyleHack2 = "col-sm-offset-4"
}
//in RTL languages, we want extra space after the "don't know" text
var rtlStyleHack3 = "";
if(window.direction == "rtl"){
rtlStyleHack3 = ""
}
//allow number input in alternate numeral set by hiding the "age" input
// and creating another one whose input is then translated into arabic numerals in the "age" input
$("#age").hide();
$("#ageContainer").append("");
$("#ageInput").change(function(){
var rawAge = $("#ageInput").val();
var age = parseArabic(rawAge);
$("#age").val(age);
});
var brightness_html = "
";
}
function name_tiles(currentStep, totalSteps){
LE.showSlide("name_tiles");
var html = getStepTitle(currentStep, totalSteps) +
"
" +
" Please enter the name of the color in " + expData.nativeLanguage + ". You can use color names that are as specific or as general as you want." +
"
" +
" If there is more than one character set for " + expData.nativeLanguage + ", please enter the names in the most common character set." +
"
" +
" Is " + expData.nativeLanguage + " not your language? You can restart the experiment to tell us about your actual first language by using this link." +
"
" +
" Once you have finished naming the colors, press the blue arrow to continue." +
"
" +
""
$("#name_tiles").html(html);
LE.showNextButton(function(){
submit_color_names();
nextPhase();
}, { "loadingOverride": true });
if(expData.color_naming_sets){
fill_in_name_tiles();
}else{
if(rgbSet == "line"){
loadLineColorNamingSet(fill_in_name_tiles);
}else {
getRandomFullRGBColors(fill_in_name_tiles);
}
}
}
function loadLineColorNamingSet(callback){
$.getJSON( "data/naming_color_set.json", function( data ) {
var colorSet;
var binEndPoints = [];
var Nbin=36;
var NScreens = 3;
if(!expData.color_naming_sets){
colorSet = data;
var endPoint = colorSet[colorSet.length-1].cummulative_dist + colorSet[colorSet.length-1].neighbor_dist;
var bins = [];
for(var i = 0; i < Nbin; i++){
bins.push(i);
}
shuffle(bins);
expData.color_naming_sets = [];
for(var i = 0; i < NScreens; i ++){
var color_naming_set = [];
for(var j = 0; j < Nbin / NScreens; j++){
var binIndex = i * Nbin / NScreens + j;
var color_dist = (bins[binIndex] + Math.random()) * endPoint / Nbin;
color_naming_set.push(find_color_dist(colorSet, color_dist));
}
expData.color_naming_sets.push(color_naming_set);
}
callback();
}
});
}
function find_color_dist(colorSet, colorDist){
//binary search to find color_dist
var left = 0;
var right = colorSet.length - 1;
while(left <= right){
//chose midpoint (left)
var mid = Math.floor((left + right) / 2);
if(colorSet[mid].cummulative_dist <= colorDist &&
colorSet[mid].cummulative_dist + colorSet[mid].neighbor_dist >= colorDist){
return colorSet[mid];
} else if(colorSet[mid].cummulative_dist <= colorDist){
left = mid + 1;
} else{
right = mid - 1;
}
}
console.log("BINARY SEARCH FAILED");
}
// choose a set of random rgb colors
function getRandomFullRGBColors(callback){
var colorSet;
var binEndPoints = [];
var Nbin=36;
var NScreens = 3;
var allChosenColors = [];
if(!expData.color_naming_sets){
expData.color_naming_sets = [];
for(var i = 0; i < NScreens; i ++){
var color_naming_set = [];
for(var j = 0; j < Nbin / NScreens; j++){
//pick a random color
min_dist = 0;
var newColor;
do {
newColor = getRandomRGBColor();
var min_dist = 100000;
for(var k = 0; k < allChosenColors.length; k++){
var dist = labDist(newColor.lab, allChosenColors[k].lab);
if(dist < min_dist){
min_dist = dist;
}
}
} while(min_dist < 20); //while the current color is too similar to previously chosen colors
// Note: just noticable difference in LAB is about 2.3
color_naming_set.push(newColor);
allChosenColors.push(newColor);
}
expData.color_naming_sets.push(color_naming_set);
}
callback();
}
}
function labDist(lab1, lab2){
return Math.sqrt(
Math.pow(lab1.l - lab2.l, 2) +
Math.pow(lab1.a - lab2.a, 2) +
Math.pow(lab1.b - lab2.b, 2));
}
function labNeighborDist(color){
//find average distance in all 6 directions
var dist = 0;
var rgb = color.rgb;
//note the math works even for rgb values past the limits (eg, -1, 256), so we don't worry about that.
dist += labDist(color.lab, d3.lab(d3.rgb(rgb.r + 1, rgb.g, rgb.b)));
dist += labDist(color.lab, d3.lab(d3.rgb(rgb.r - 1, rgb.g, rgb.b)));
dist += labDist(color.lab, d3.lab(d3.rgb(rgb.r, rgb.g + 1, rgb.b)));
dist += labDist(color.lab, d3.lab(d3.rgb(rgb.r, rgb.g - 1, rgb.b)));
dist += labDist(color.lab, d3.lab(d3.rgb(rgb.r, rgb.g, rgb.b + 1)));
dist += labDist(color.lab, d3.lab(d3.rgb(rgb.r, rgb.g, rgb.b - 1)));
return dist / 6;
}
//choose a single random rgb color accounting for LAB space
function getRandomRGBColor(){
var max_neighbor_dist = 0.7555604179499573 // max_color rgb = 27 23 24
//pick color, find neighborhood distance, find fractional dist, rand number 0-1, if rand too high, try again
var foundColor = false;
var color;
while(!foundColor){
//pick random rgb values
var r = Math.round(Math.random()*255);
var g = Math.round(Math.random()*255);
var b = Math.round(Math.random()*255);
color = {};
color.rgb = d3.rgb(r, g, b);
color.lab = d3.lab(color.rgb);
//since rgb is not scaled perceptually, find the size of the LAB neighborhood of the color.
// use this size to randomly skip perceptually smaller colors proportionally
neighbor_dist = labNeighborDist(color);
var dist_ratio = neighbor_dist/max_neighbor_dist;
// decide if we get to keep the color based on the ratio and a random number;
if(dist_ratio > Math.random()){
foundColor = true;
}
}
return color;
}
function fill_in_name_tiles(){
var color_set = expData.color_naming_sets.shift();
$.each(color_set, function(index, color){
$('#naming-colors-set').append(create_color_tile_html(index, color.rgb));
});
$('input').on('keyup', name_tile_keyup);
}
function create_color_tile_html(index, color){
var $newColorColumn = $('');
var $newColorPatch = $('').css('background-color',d3.rgb(color.r, color.g, color.b).toString());
$newColorColumn.append($newColorPatch);
$newColorColumn.append($(""));
$newColorColumn.append($("
"));
return $newColorColumn;
}
function name_tile_keyup(){
var text = $(this).val();
var korean = new RegExp("[\u1100-\u11FF|\u3130-\u318F|\uA960-\uA97F|\uAC00-\uD7AF|\uD7B0-\uD7FF]");
var chinese = new RegExp("[\u4E00-\u9FFF|\u2FF0-\u2FFF|\u31C0-\u31EF|\u3200-\u9FBF|\uF900-\uFAFF]");
var langDetector = { "Korean": korean, "Chinese": chinese };
var nativeLang = expData.nativeLanguage.split("(")[0].trim();
if(langDetector[nativeLang])
{
if (!langDetector[nativeLang].test(text) && text !== "") {
$(this).css('border-color',"#AA0000");
$(this).siblings('.help-block').html('Please write in '+ expData.nativeLanguage+'.');
}
else{
$(this).css('border-color',"initial");
$(this).siblings('.help-block').html(' ');
}
}
}
function submit_color_names(){
var color_names = [];
$('#naming-colors-set .color-column').each(function(){
var rgb_string = $(this).find('.color-tile').css("background-color");
var rgb = d3.rgb(rgb_string);
var lab = d3.lab(rgb);
var name = $(this).find('input').val();
color_names.push({
r: rgb.r,
g: rgb.g,
b: rgb.b,
lab_l: lab.l,
lab_a: lab.a,
lab_b: lab.b,
name: name});
});
var result = {
participantId: LE.getParticipantId(),
phaseNum: LE.getPhaseNum(),
trialNum: LE.getTrialNum(),
color_names: color_names,
studyVersion: studyVersion,
rgbSet: rgbSet,
lang0: expData.nativeLanguage,
locale: litw_locale
};
LE.recordResult(result);
$.ajax({
type: "POST",
url: "include/name_data.php",
data: result
}).done(function(result) {
//console.log(result);
});
}
function sort_tiles(currentStep, totalSteps){
LE.showSlide("sort_tiles");
var html = getStepTitle(currentStep, totalSteps) +
"
" +
" Sort the colors by hue so that similar colors are near each other. They should form a continuum between the two fixed color tiles at the ends of each row." +
"
" +
" You can either click and drag the tiles using a mouse or you can drag them with your finger on a touch screen." +
"
" +
" Once you have finished sorting the colors, press the blue arrow to continue." +
"
" +
"
"
$("#sort_tiles").html(html);
LE.showNextButton(function(){
submit_sort_tiles();
nextPhase();
}, { "loadingOverride": true });
fill_in_sort_tiles();
}
function fill_in_sort_tiles(){
colorSets = [];
var colorSets = [];
for(var i = 0; i < 3; i++){
colorSets.push(expData.colorSets.shift());
$('#sorting-div').append(' ');
}
$('#sorting-div .sortable').each(function(index){
var $sortable = $(this);
var $itemDiv = $('');
var tempColorSet = colorSets.shift();
var colorSet = [];
for(i = 0; i < tempColorSet.length; i++){
colorSet.push({
rgb: tempColorSet[i].rgb(),
index: i
});
}
var width = 100 / (colorSet.length);
$itemDiv.css('width', width+'%');
$sortable.append($itemDiv.clone().addClass('static').append($('').css('background-color',colorSet.splice(0,1)[0].rgb.toString())));
var colorSetShuffle = expData.colorSetsShuffles.shift();
colorSet1Trimed = matchShuffle(colorSet.splice(0,colorSet.length-1), colorSetShuffle);
for (var i = 0; i < colorSet1Trimed.length; i++) {
$sortable.append(
$itemDiv.clone().addClass('moveable').attr("patch_id", colorSet1Trimed[i].index)
.append($('').css('background-color',colorSet1Trimed[i].rgb.toString())));
};
$sortable.append($itemDiv.clone().addClass('static').css("margin-bottom","10px").append($('').css('background-color',colorSet.splice(0,1)[0].rgb.toString())));
$sortable.data('drags',0);
$sortable.data('sTime',0);
$sortable.data('timerOn',false);
$sortable.data('totalTime',0);
$sortable.sortable({
revert: false,
placeholder: "color-patch-placeholder",
forcePlaceholderSize: false,
tolerance: "pointer",
items: '> div:not(.static)',
start: function(){
var clickedTime = Date.now();
$sortable.data('drags', $sortable.data('drags') +1 );
if( !$sortable.data('timerOn') ){
$sortable.data('timerOn',true);
$sortable.data('sTime', clickedTime);
}
$('.sortable').not($sortable).each(function(index, otherSortable){
if( $(otherSortable).data('timerOn') ){
var newTotalTime = $(otherSortable).data('totalTime') + clickedTime - $(otherSortable).data('sTime');
$(otherSortable).data('totalTime', newTotalTime);
$(otherSortable).data('timerOn',false);
}
})
$('.color-patch-placeholder').css('width',width+'%');
$('.static', this).each(function(){
var $this = $(this);
$this.data('pos', $( "div.color-patch", $sortable).index(this));
});
},
change: function(){
$sortable = $(this);
$statics = $('.static', this).detach();
// $statics.each(function(){
// $('').prependTo($sortable);
// })
$('').prependTo($sortable);
$sortable.append($(''));
$statics.each(function(){
var $this = $(this);
var target = $this.data('pos');
$this.insertAfter($('div.color-patch', $sortable).eq(target));
$('#sorting-div .static-helper').eq(0).remove();
});
}
});
$sortable.disableSelection();
});
}
function submit_sort_tiles(){
var sortingTilesOrder = [];
var sortingTilesDrags = [];
var sortingTilesTimes = [];
$('#sorting-div .sortable').each(function(index){
var $sortable = $(this);
var totalTime = $sortable.data('timerOn') ? Date.now() - $sortable.data('sTime') + $sortable.data('totalTime') : $sortable.data('totalTime');
var sortOrderRow = [];
$sortable.find(".color-patch.moveable").each(function(index){
var $color_patch = $(this);
var patch_id = parseInt($color_patch.attr("patch_id"));
sortOrderRow.push(patch_id);
});
sortingTilesOrder.push(sortOrderRow);
sortingTilesDrags.push($sortable.data('drags'));
sortingTilesTimes.push(totalTime);
expData.sortTileOrders.push(sortOrderRow);
});
var result = {
participantId: LE.getParticipantId(),
phaseNum: LE.getPhaseNum(),
trialNum: LE.getTrialNum(),
sortTilePage: expData.sortTilePage,
sortTiles1: sortingTilesOrder[0].toString(),
sortTiles2: sortingTilesOrder[1].toString(),
sortTiles3: sortingTilesOrder[2].toString(),
sortTiles1Drags: sortingTilesDrags[0],
sortTiles2Drags: sortingTilesDrags[1],
sortTiles3Drags: sortingTilesDrags[2],
sortTiles1Time: sortingTilesTimes[0],
sortTiles2Time: sortingTilesTimes[1],
sortTiles3Time: sortingTilesTimes[2]
};
LE.recordResult(result);
$.ajax({
type: "POST",
url: "include/sort_data.php",
data: result
}).done(function(result) {
//console.log(result);
});
expData.sortTilePage ++;
}
function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
function matchShuffle(arrayToShufle, shuffleToMatch){
newArray = []
for(var i = 0; i < shuffleToMatch.length; i++){
newArray[shuffleToMatch[i] - 1] = arrayToShufle[i];
}
return newArray;
}
function breakTime(){
LE.showSlide("break");
var html = "
" +
"Nice work so far!
Feel free to take a break and rest your eyes before finishing the last two stages." +
"
" +
" ";
$("#break").html(html);
LE.showNextButton(nextPhase, { "loadingOverride": true });
}
function nextPhase() {
var type = expData.progression.shift();
var totalSteps = 5;
LE.increaseTrialCounter();
//progression: ["name_tiles", "sort_tiles", "name_tiles", "break", "sort_tiles", "name_tiles"],
var numStepsLeft = expData.progression.length;
var currentStep = totalSteps - numStepsLeft;
//correct for break step which doesn't count
if(currentStep < 3){
currentStep++;
}
if(type == "name_tiles"){
LE.recordProgression("name_tiles");
name_tiles(currentStep, totalSteps);
} else if(type == "sort_tiles"){
LE.recordProgression("sort_tiles");
sort_tiles(currentStep, totalSteps);
} else if (type == "break") {
LE.recordProgression("mid-trial break");
breakTime();
} else {
comments();
}
window.scrollTo(0, 0);
}
function comments() {
if (!expData.commentsDone) {
LE.recordProgression("comments");
expData.commentsDone = true;
LE.showCommentsPage(results);
$('#comments h2.bolded-blue').text("Before we continue to your results...");
} else {
results();
}
}
function results() {
LE.recordProgression("results");
//var numberOfColorSets = 6;
//var colorsPerSet = labRing.length
var N = colorsPerSet // 15 (note in the actual set there are 17: two are the fixed start/end)
var setN = numberOfColorSets // 6
userResponses = expData.sortTileOrders;
//various fake datasets
//var userResponses = [];
/* // perfect data
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
*/
// one mistake data
/*userResponses.push([2,1,3,4,5,6,7,8,9,10,11,12,13,14,15]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
*/
/* // specific mistakes data
userResponses.push([2,1,3,4,5,6,7,8,9,10,11,12,13,14,15]);
userResponses.push([1,2,3,4,5,6,7,9,8,10,11,12,13,14,15]);
userResponses.push([8,2,3,4,5,6,7,1,9,10,11,12,13,14,15]);
userResponses.push([15,2,3,4,5,6,7,8,9,10,11,12,13,14,1]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
*/
/* // reversed data
userResponses.push([15,14,13,12,11,10,9,8,7,6,5,4,3,2,1]);
userResponses.push([15,14,13,12,11,10,9,8,7,6,5,4,3,2,1]);
userResponses.push([15,14,13,12,11,10,9,8,7,6,5,4,3,2,1]);
userResponses.push([15,14,13,12,11,10,9,8,7,6,5,4,3,2,1]);
userResponses.push([15,14,13,12,11,10,9,8,7,6,5,4,3,2,1]);
userResponses.push([15,14,13,12,11,10,9,8,7,6,5,4,3,2,1]);
*/
//Good data
/* userResponses.push([1,2,4,3,5,6,7,9,8,10,11,12,13,15,14]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,14,13,15]);
userResponses.push([1,5,3,4,2,6,7,12,9,11,10,8,13,15,14]);
userResponses.push([1,2,4,3,5,6,7,9,8,10,11,12,13,15,14]);
userResponses.push([1,2,4,3,5,6,7,9,8,10,11,12,13,15,14]);
userResponses.push([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
*/
/*//Random data
userResponses.push([12, 8, 5, 6, 13, 4, 1, 2, 15, 7, 10, 3, 11, 14, 9]);
userResponses.push([13, 1, 11, 14, 9, 2, 3, 12, 5, 7, 4, 8, 10, 15, 6]);
userResponses.push([4, 2, 6, 3, 10, 5, 8, 12, 9, 15, 14, 7, 1, 13, 11]);
userResponses.push([11, 4, 1, 15, 14, 9, 6, 2, 7, 8, 13, 10, 3, 5, 12]);
userResponses.push([9, 14, 4, 8, 11, 1, 10, 6, 2, 15, 12, 13, 5, 3, 7]);
userResponses.push([8, 15, 6, 5, 10, 7, 11, 3, 1, 13, 2, 9, 12, 14, 4]);
*/
var colorSets = expData.resultsColorSets;
var results = colorSets.reduce(function(prev, colorSet, setIndex){
var splicedColorSet = colorSet.slice(1, colorSet.length - 1);
prev = prev.concat(splicedColorSet.map(function(color, index, array){
return {
"error" : Math.abs(index - userResponses[setIndex][index] + 1),
"maxError": Math.max(index - 0, N - 1 - index),
"color" : color,
"index" : index + setIndex*N
};
}));
return prev;
},[]);
var avgUserResults = [];
for(var i = 0; i < results.length; i++){
avgUserResults[i] = {
"error" : window.averageTileErrors[i],
"maxError": results[i].maxError,
"color" : results[i].color,
"index" : results[i].index
}
}
// to compute max error for scores, reverse the list and see how bad it is (this should be close enough to correct)
var maxError = 0;
for(var i = 0; i < N; i++){
var currentPointError = Math.abs(i - (N - 1 - i));
maxError += Math.pow(currentPointError, 2);
}
maxError *= setN; // there are 6 sets
var score = 1 - results.reduce(function(prev,curr){
prev += Math.pow(curr.error, 2);
return prev;
}, 0) / maxError;
//to make scores (between 0 and 1) distributed better so not everyone scores 99+,
// and to keep the range between 0 and 1 and to particularly separate high scores
// do basically (1 - sqrt(1 - score)), but with a slighlty different exponent so one error rounds as 99
score = 1 - Math.pow(1 - score, .55);
// make all scores less than 35.2 be 0
score = Math.max(0, (score - 0.352) / (1 - 0.352));
var roundedScore = Math.round(score*100);
var roundedAvgScore = Math.round(window.average_score*100);
var bannerText = "";
if(roundedScore > 60){
bannerText = "Good job!";
}
LE.showSlide("results");
var html =
'
' +
'
Your color perception score is ...
' +
'
' +
'
' +
'
' +
'
' +
'
' +
' ???' +
'
' +
'
' +
'
' +
'
' +
' ' +
' ' +
'
' +
'
' +
'
' +
' '+bannerText+'' +
'
' +
'
' +
"
" +
"
" +
"
" +
"
" +
"
" +
" Your score indicates how close your tiles were to where they should go if they are sorted with 100% accuracy." +
"
" +
" " +
"
" +
" Color Perception on the Spectrum" +
"
" +
"
" +
" Which colors could you discriminate well or poorly?" +
"
" +
"
" +
" On the spectrum below you will see a chart showing how well you were at discriminating different colors." +
"
" +
"
" +
" Where the line is higher, you placed colors closer to their correct position. " +
"
" +
"
" +
" Where the line is lower, you placed colors further away from their correct position." +
"
" +
"
" +
" Your Spectrum " +
"
" +
"
" +
"
" +
" How did the average user do?" +
"
" +
"
" +
" On the spectrum below you will see a chart showing how well the average user was at discriminating different colors." +
"
" +
"
" +
" Average User Spectrum " +
"
" +
"
" +
" " +
"
Color Names" +
"
" +
"
" +
" Thank you for naming colors for us! Those names are not part of your color perception score. Instead, we will use them as part of a research study on how colors are named in different languages, which is why we could not give you examples color names or hints." +
"
" +
//"
" +
//" If you would like to see the results from the color naming task, enter your email below and we will email you when the study is finished. Your email address will be kept separately from the data you entered." +
//"