Public
Edited
Apr 23
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
networkTesting.data
Insert cell
Insert cell
networkTesting.tasks
Insert cell
Insert cell
Insert cell
nodeLinkViewer = new NodeLinkViewer(400,400)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
basicStudyDesign = ([
{
type : "eval",
viewers : [nodeLinkViewer,
matrixViewer],
data : [networkTesting.data.lesMis,
networkTesting.data.ingredients],
tasks : [networkTesting.tasks.compareDegrees,
networkTesting.tasks.findPath],
design : {
type : "factorial",
viewers : testingStrategy.viewer,
data : testingStrategy.data,
tasks : testingStrategy.task,
blocking : testingStrategy.blocking
}
}
])
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
delivery = visUnit.compileDesign(basicStudyDesign)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
<div id = "simplestudy"> Study goes here </div>
Insert cell
Insert cell
visUnit.deliverCondition(document.getElementById("simplestudy"), // a div where the study gets displayed
delivery[participantGroup], //one of the study sequences
saveParticipantResponses); //callback to store results (see below)

Insert cell
Insert cell
Insert cell
Insert cell
//a demonstrator method for saving participant responses
saveParticipantResponses = (b,i) => {
//responses to the demo study shown above are store into simpleResults
//in real deployment, this method would send responses to a database
let a = mutable simpleResults;
a.push(b);
mutable simpleResults = a;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
visUnit.deliverCondition(document.getElementById("complex_study"), // a div where the study gets displayed
complexDelivery[participantGroup], //one of the study sequences
(b,i) => {}); //no response saving
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
complexDesign = ([

//the design is made up of multiple "activities";
//while they are listed and compiled sequentially, their
//trials sequenced together according to placement rules
//(i.e. trials from subsequent activities can be inserted
// between those from earlier activities)
//1. the main - "evaluation" - part of the study
{
type : "eval",

//we are evaluating two visualisations on two datasets
//and two tasks
viewers : [nodeLinkViewer2, matrixViewer2],
data : [networkTesting.data.lesMis, networkTesting.data.ingredients],
tasks : [networkTesting.tasks.compareDegrees,
networkTesting.tasks.findPath],

//using a factorial design; whether factors are tested
//between or within participants and blocking order can
//be selected via drop down boxes further down
design : {
type : "factorial",
viewers : complexTestingStrategy.viewer,
data : complexTestingStrategy.data,
tasks : complexTestingStrategy.task,
blocking : complexTestingStrategy.blocking
},

//trial delivery lets us customise how each trial in this activity
//is delivered (depending on what combination of viewer x data x task
//the trial shows)
trialDelivery : (v,d,t) => ({
repeats : {
//evaluate 3 repeats of compareDegrees and 1 repeat of findPath
number : t == networkTesting.tasks.compareDegrees ? 3 : 1,
//pick repeats at random from available task x data instances
selection : 'random',
//a participant will not be exposed to the same repeat twice
unique : true
},
//we estimate findPath tasks will take longer than compareDegrees
//(we could extend this further and make it dataset dependent)
estimatedDuration : (d == networkTesting.tasks.findPath ? 60 : 15),

//enforceTiming lets us make tasks timed; here we make
//the compareDegrees task timed at 10sec (but leave findPath untimed)
... (t == networkTesting.tasks.compareDegrees &&
{ enforceTiming : {
maxTime : 10,
onTimeout : "hideViewer blockResponses" //default
}})
})
},

//2. task training
{
type : "train",

//we will train whatever viewer x task combination comes next
//(see placement below)
viewer : "inherit next",
task : "inherit next",
//but feed it the demoNetwork for training
data : networkTesting.data.demoNetwork,
trialDelivery : {
//mark trials as training: participants will be able to check answers
train : true,
estimatedDuration : 30,
repeats : 2 //two training repeats
},

//we insert training trials in front of the first showing of
//every distinct viewer x task combination
placement : {
positioning : "before first",
selector : {viewer : ['*'],
task : ['*'],
activity : "eval"}
}
},

//3. color blind testing
{
type : "color testing",
viewer : colorBlindTesting.viewer, //shows images
data : colorBlindTesting.dataset, //of colour-test number swatches and
task : colorBlindTesting.task, //and ask participants to identify shown numbers

trialDelivery : {
//we'll do two such trials (i.e., show 2 color swatches)
repeats : 2,
//and enforce a minimum accuracy threshold
enforceAccuracy : {
threshold : 0.5, //at least half of the readings must be correct
jumpTo : (b,i,s) => i == s.length-1 //or welse we jump to the end of the study
},
estimatedDuration : 10 //we estimate each colour test repeat to take about 10sec
},

//we put this activity at start of study assembled so far
placement : "before",
},

//4. we'll ask a few demographic questions (all questions we have
//in a demographicQuestions suite)
{
type : "demographics",
tasks : Object.values(demographicQuestions),
placement : "before"
},

//5. we show a consent form to start with
{
type : "consent",

//we are showing a "consent page" in a
//study information "dataset" (using an html "viewer")
task : studyInformation.askConsent,
data : studyInformation.data,
viewer : studyInformation.viewer,

trialDelivery : {
enforceAccuracy : { //and require participants to consent
threshold : 1, //(i.e., "answer correctly")
jumpTo : (b,i,s) => i == s.length -1 //or we end the study
}
},
placement : "before"
},

//6. and say goodbye at the end (without any other visuals)
{
type : "exit",
task : {
name : "thankyou",
question : "That would be all, thank you for participating!"
}
},

//7. additionally, we show a few introductory and transition messages
//(e.g., introducing activities, flagging changes etc.)
{
type : "transition",
task : {
name : "intro coltest",
question : "Before we continue, there will be a quick color perception check to ensure the rest of the study is accessible for you.",
},
trialDelivery : {estimatedDuration : 10},
placement : {positioning : "before first", selector : {activity : "color testing"}}
},
{
type : "transition",
task : {
name : "intro demographics",
question : "We will now ask you a few questions about yourself.",
},
trialDelivery : {estimatedDuration : 10},
placement : {positioning : "before first",selector : {activity : "demographics"}}
},
{
type : "transition",
task : {
name : "intro eval",
question : "You will now start the main part of the study. You will see visualisations of data and be asked to answer a series of questions about the data. Each time a new type of question or a new visualisation is introduced, you will get a chance to practice that question and check the correctness of your answers.",
},
trialDelivery : {estimatedDuration : 10},
placement : {positioning : "before first",selector : {activity : "train"}}
},
{
type : "transition",
task : {
name : "new train",
question : "Here's a new kind of question. Let's train it first.",
},
trialDelivery : {estimatedDuration : 10},
placement : {positioning : "before each",selector : {activity : "train"}}
},
{
type : "transition",
task : {
name : "for real",
question : "Now lets answer a few such questions for real. But note that the task is timed - you have 10seconds to provide an answer",
},
trialDelivery : {estimatedDuration : 10},
placement : {positioning : "after each",
selector : {
task : [networkTesting.tasks.compareDegrees],
activity : "train"
}
}
},
{
type : "transition",
task : {
name : "for real",
question : "Now lets answer a few such questions for real (these questions are not timed)"
},
trialDelivery : {estimatedDuration : 10},
placement : {positioning : "after each",
selector : {
task : [networkTesting.tasks.findPath],
activity : "train"
}
}
},

])
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
complexDelivery = visUnit.compileDesign(complexDesign)
Insert cell
mutable viewer2 = null
Insert cell
Insert cell
Insert cell
Insert cell
mutable updateViewer2 = false
Insert cell
mutable updateStudyViewer = false;
Insert cell
mutable updateViewer1 = false
Insert cell
mutable viewer = null
Insert cell
import {visUnit} from "@rdjianu/visunit"
Insert cell
import {NodeLinkViewer,MatrixViewer} from "@rdjianu/network-test-suite"
Insert cell
import {colorBlindTesting} from "@rdjianu/color-blind-testing"
Insert cell
import {studyInformation} from "@rdjianu/study-information"
Insert cell
import {demographicQuestions} from "@rdjianu/demographics"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more