├── src ├── postcss.config.js ├── entry.js ├── bootstrap.config.less ├── bootstrap.config.js ├── distributionbuilder.css ├── demo.js ├── distributionbuilder.js └── distributionbuilder.ts ├── dependencies ├── mousehold.d.ts └── mousehold.js ├── .gitignore ├── docs ├── images │ ├── hr.gif │ ├── bullet.png │ ├── background.png │ ├── octocat-logo.png │ └── body-background.png ├── fonts │ ├── copse-regular-webfont.eot │ ├── copse-regular-webfont.ttf │ ├── copse-regular-webfont.woff │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ ├── glyphicons-halflings-regular.woff2 │ ├── quattrocentosans-bold-webfont.eot │ ├── quattrocentosans-bold-webfont.ttf │ ├── quattrocentosans-bold-webfont.woff │ ├── quattrocentosans-italic-webfont.eot │ ├── quattrocentosans-italic-webfont.ttf │ ├── quattrocentosans-italic-webfont.woff │ ├── quattrocentosans-regular-webfont.eot │ ├── quattrocentosans-regular-webfont.ttf │ ├── quattrocentosans-bolditalic-webfont.eot │ ├── quattrocentosans-bolditalic-webfont.ttf │ ├── quattrocentosans-regular-webfont.woff │ ├── quattrocentosans-bolditalic-webfont.woff │ └── quattrocentosans-bold-webfont.svg ├── javascripts │ └── main.js ├── stylesheets │ ├── github-dark.css │ ├── normalize.css │ └── styles.css └── index.html ├── distributionbuilder.zip ├── reference.bib ├── tsconfig.json ├── LICENSE ├── package.json ├── distributionbuilder.css ├── README.md ├── lib ├── distributionbuilder.d.ts └── distributionbuilder.css ├── webpack.config.js └── QualtricsExample.qsf /src/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = {}; -------------------------------------------------------------------------------- /dependencies/mousehold.d.ts: -------------------------------------------------------------------------------- 1 | export default function MouseHold($:any): any; -------------------------------------------------------------------------------- /src/entry.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./distributionbuilder.ts').default; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .idea/ 3 | yarn.lock 4 | test.html 5 | yarn-error.log 6 | -------------------------------------------------------------------------------- /docs/images/hr.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/images/hr.gif -------------------------------------------------------------------------------- /src/bootstrap.config.less: -------------------------------------------------------------------------------- 1 | @btn-default-color: #444; 2 | @btn-default-bg: #eee; -------------------------------------------------------------------------------- /docs/images/bullet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/images/bullet.png -------------------------------------------------------------------------------- /distributionbuilder.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/distributionbuilder.zip -------------------------------------------------------------------------------- /docs/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/images/background.png -------------------------------------------------------------------------------- /docs/images/octocat-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/images/octocat-logo.png -------------------------------------------------------------------------------- /docs/images/body-background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/images/body-background.png -------------------------------------------------------------------------------- /docs/fonts/copse-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/copse-regular-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/copse-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/copse-regular-webfont.ttf -------------------------------------------------------------------------------- /docs/fonts/copse-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/copse-regular-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /docs/fonts/quattrocentosans-bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/quattrocentosans-bold-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/quattrocentosans-bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/quattrocentosans-bold-webfont.ttf -------------------------------------------------------------------------------- /docs/fonts/quattrocentosans-bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/quattrocentosans-bold-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/quattrocentosans-italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/quattrocentosans-italic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/quattrocentosans-italic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/quattrocentosans-italic-webfont.ttf -------------------------------------------------------------------------------- /docs/fonts/quattrocentosans-italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/quattrocentosans-italic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/quattrocentosans-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/quattrocentosans-regular-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/quattrocentosans-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/quattrocentosans-regular-webfont.ttf -------------------------------------------------------------------------------- /docs/fonts/quattrocentosans-bolditalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/quattrocentosans-bolditalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/quattrocentosans-bolditalic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/quattrocentosans-bolditalic-webfont.ttf -------------------------------------------------------------------------------- /docs/fonts/quattrocentosans-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/quattrocentosans-regular-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/quattrocentosans-bolditalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuentinAndre/DistributionBuilder/HEAD/docs/fonts/quattrocentosans-bolditalic-webfont.woff -------------------------------------------------------------------------------- /reference.bib: -------------------------------------------------------------------------------- 1 | @misc{, 2 | title = {{distBuilder} ({Version} 1.4.1) [{Computer} {Software}]}, 3 | url = {https://quentinandre.github.io/DistributionBuilder/}, 4 | abstract = {A Javascript library adding distribution builders to your experiments.}, 5 | author = {André, Quentin}, 6 | year = {2016} 7 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "lib": ["dom", "es6"], 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "noEmitOnError": true, 8 | "noUnusedLocals": true, 9 | "outDir": "./lib", 10 | "target": "es6", 11 | "strict": true, 12 | "strictNullChecks": false, 13 | "suppressImplicitAnyIndexErrors": true, 14 | "types": [] 15 | }, 16 | "include": ["src/*"] 17 | } 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Quentin André. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /src/bootstrap.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | scripts: { 3 | 'transition': false, 4 | 'alert': false, 5 | 'button': true, 6 | 'carousel': false, 7 | 'collapse': false, 8 | 'dropdown': false, 9 | 'modal': false, 10 | 'tooltip': false, 11 | 'popover': false, 12 | 'scrollspy': false, 13 | 'tab': false, 14 | 'affix': false 15 | }, 16 | styles: { 17 | "mixins": true, 18 | 19 | "normalize": true, 20 | "print": true, 21 | 22 | "scaffolding": false, 23 | "type": false, 24 | "code": false, 25 | "grid": false, 26 | "tables": false, 27 | "forms": false, 28 | "buttons": true, 29 | 30 | "component-animations": false, 31 | "glyphicons": true, 32 | "dropdowns": false, 33 | "button-groups": false, 34 | "input-groups": false, 35 | "navs": false, 36 | "navbar": false, 37 | "breadcrumbs": false, 38 | "pagination": false, 39 | "pager": false, 40 | "labels": false, 41 | "badges": false, 42 | "jumbotron": false, 43 | "thumbnails": false, 44 | "alerts": false, 45 | "progress-bars": false, 46 | "media": false, 47 | "list-group": false, 48 | "panels": false, 49 | "wells": false, 50 | "close": false, 51 | 52 | "modals": false, 53 | "tooltip": false, 54 | "popovers": false, 55 | "carousel": false, 56 | 57 | "utilities": false, 58 | "responsive-utilities": false 59 | } 60 | }; 61 | 62 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "distbuilder", 3 | "version": "1.4.1", 4 | "description": "A distribution builder for economic and psychology experiments. Based on Goldstein and Rothschild's 2014 paper 'Lay understanding of probability distributions'.", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "build": "webpack --progress --color", 8 | "start": "webpack-dev-server" 9 | }, 10 | "author": "Quentin ANDRE", 11 | "license": "ISC", 12 | "dependencies": { 13 | "bootstrap": "3", 14 | "expose-loader": "^0.7.5", 15 | "jquery": "^3.3.1" 16 | }, 17 | "devDependencies": { 18 | "@types/jquery": "^3.3.6", 19 | "autoprefixer": "^8.6.3", 20 | "babel-core": "^6.26.3", 21 | "babel-loader": "^7.1.4", 22 | "babel-preset-env": "^1.7.0", 23 | "bootstrap-webpack": "^0.0.6", 24 | "clean-webpack-plugin": "^0.1.19", 25 | "css-loader": "^0.28.11", 26 | "exports-loader": "^0.7.0", 27 | "extract-text-webpack-plugin": "^4.0.0-beta.0", 28 | "file-loader": "^1.1.11", 29 | "image-webpack-loader": "^4.3.1", 30 | "imports-loader": "^0.8.0", 31 | "less": "^3.8.1", 32 | "less-loader": "^4.1.0", 33 | "mini-css-extract-plugin": "^0.4.0", 34 | "node-sass": "^4.9.0", 35 | "postcss-loader": "^2.1.5", 36 | "sass-loader": "^7.0.3", 37 | "style-loader": "^0.21.0", 38 | "ts-loader": "^5.1.0", 39 | "typescript": "^3.0.3", 40 | "url-loader": "^1.1.1", 41 | "webpack": "^4.12.0", 42 | "webpack-cli": "^4.5.0", 43 | "webpack-dev-server": "^3.1.4", 44 | "webpack-md5-hash": "^0.0.6" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /distributionbuilder.css: -------------------------------------------------------------------------------- 1 | /* Distbuilder */ 2 | 3 | .distbuilder { 4 | border-width: 2px; 5 | border-color: grey; 6 | border-style: solid; 7 | padding: 2px; 8 | } 9 | 10 | /* Grid */ 11 | 12 | .distbuilder > .grid { 13 | background-color: lightsteelblue; 14 | width: 100%; 15 | padding-bottom: 2px; 16 | padding-top: 5px; 17 | } 18 | 19 | .distbuilder > .grid > .distrow { 20 | display: flex; 21 | } 22 | 23 | .distbuilder > .grid > .distrow > .cell { 24 | flex: 1; 25 | display: flex; 26 | justify-content: center; 27 | } 28 | 29 | .distbuilder > .grid > .distrow > .cell > .ball { 30 | margin-bottom: 1px; 31 | height: 10px; 32 | width: 10px; 33 | border: 1px solid white; 34 | border-radius: 50%; 35 | align-self: center; 36 | } 37 | 38 | .distbuilder > .grid > .distrow > .filled > .ball { 39 | background-color: #FF4500; 40 | } 41 | 42 | /* Labels */ 43 | 44 | .distbuilder > .labels { 45 | background-color: steelblue; 46 | width: 100%; 47 | } 48 | 49 | .distbuilder > .labels > .distrow { 50 | display: flex; 51 | width: 100%; 52 | } 53 | 54 | .distbuilder > .labels > .distrow > .label { 55 | color: white; 56 | float: left; 57 | text-align: center; 58 | font-size: 0.8em; 59 | flex: 1; 60 | } 61 | 62 | /* Buttons */ 63 | 64 | .distbuilder > .buttons { 65 | background-color: steelblue; 66 | width: 100%; 67 | } 68 | 69 | .distbuilder > .buttons > .distrow { 70 | display: flex; 71 | width: 100%; 72 | } 73 | 74 | .distbuilder > .buttons > .distrow > .buttongroup { 75 | text-align: center; 76 | flex: 1; 77 | padding-bottom: 5px; 78 | } 79 | 80 | .distbuilder > .buttons > .distrow > .buttongroup > .distbutton { 81 | border-radius: 10%; 82 | width: 60%; 83 | margin: 0 auto !important; 84 | padding: 0 !important; 85 | line-height: 1 !important; 86 | background-color: lightgrey; 87 | } 88 | 89 | -------------------------------------------------------------------------------- /docs/javascripts/main.js: -------------------------------------------------------------------------------- 1 | var sectionHeight = function() { 2 | var total = $j(window).height(), 3 | $jsection = $j('section').css('height','auto'); 4 | 5 | if ($jsection.outerHeight(true) < total) { 6 | var margin = $jsection.outerHeight(true) - $jsection.height(); 7 | $jsection.height(total - margin - 20); 8 | } else { 9 | $jsection.css('height','auto'); 10 | } 11 | }; 12 | 13 | $j(window).resize(sectionHeight); 14 | 15 | $j(document).ready(function(){ 16 | $j("section h1, section h2").each(function(){ 17 | $j("nav ul").append("
A Javascript library adding distribution builders to your experiments.
22 |In their paper 'Lay 52 | understanding of probability distributions' (2014), published in 2014, Daniel Goldstein and 53 | David Rothschild have highlighted the benefits of using graphical interfaces called distribution 54 | builders to study subjective probabilities, perceptions of frequency, and confidence 55 | judgements. This tool was first developed by Sharpe, Goldstein and Blythe (2000), and was 57 | featured later in Goldstein, Johnson and Sharpe (2008) and Delavande and Rhowedder (2008). 61 | However, the implementation of such distribution builders in online studies is not straightforward, as most 62 | survey platforms do not implement this type of question.
63 |The distBuilder library was created to address this issue, and make the implementation of 64 | distribution builders easy and accessible to researchers. The library is user-friendly, and requires very 65 | little programming knowledge to be used.
66 |You can cite distBuilder using its Digital Object Identifier 68 | (DOI).
69 |This library is developed by Quentin André, an assistant professor of Marketing at 71 | the Leeds School of Business, University of Colorado Boulder. If you have any comment, feedback 72 | or suggestion regarding this library or its documentation, 73 | please let me know at quentin.andre@colorado.edu or use GitHub issues.
74 | 75 |To add the library to your projects and start using distBuilder, just follow the instructions 77 | below.
78 |If you are hosting your experiment on a separate website, here is how to add the script:
80 |Add the Javascript file distributionbuilder.min.js and the CSS file distributionbuilder.css
85 | to your html code:
<link rel="stylesheet" href="distributionbuilder.css">
87 | <script src="distributionbuilder.min.js"></script>
88 | $j alias.
92 | Instead of typing $('#Hello'), type $j('#Hello').
93 | If you prefer starting from a minimal working example and tweaking it, you can find 98 | a fully functional integration to Qualtrics here in the form of a .qsf file, that you can import in 99 | Qualtrics.
100 |If you prefer detailed instructions, just follow these simple steps:
101 |<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/QuentinAndre/DistributionBuilder@master/lib/distributionbuilder.css">
107 | <script src="https://cdn.jsdelivr.net/gh/QuentinAndre/DistributionBuilder@master/lib/distributionbuilder.min.js"></script>
108 | Qualtrics.SurveyEngine.addOnReady section.
112 | $j alias. Instead of typing $('#Hello'), type $j('#Hello').
114 | The library is extremely easy to use: it allows you to add fully functional distribution builders in a few 120 | lines of code.
121 |<div id="targetdiv"> to your HTML, and copy the code below between
123 | your two <script> tags.
124 | <div id="targetdiv"> to the HTML of your question, and copy the
126 | code below in the "Custom Javascript" section. See this link if you have never added Javascript to a Qualtrics question before.
129 | var distbuilder = new DistributionBuilder();
137 | distbuilder.render("targetdiv");
138 | distbuilder.labelize();
139 | In just three lines of code, you have created an interactive (try it!) Distribution Builder in the <div>
141 | section called “targetdiv”. It consists of three elements:
Each of these elements can be customized to your liking, both using the Javascript methods wrapped by the 149 | library and the CSS. Browse the sections below to discover how you can customize the appearance and 150 | functionalities of the distribution builder, access the results of your participants, and implement more 151 | complex logics in your studies.
152 | 153 |The complete creation of a Distribution Builder object is done in three phases:
155 |The first step in creating a Distribution Builder is to initialize the object:
162 |myDistBuilder = new DistributionBuilder({})
This function call initializes the internal state of the DistributionBuilder object, with a certain number of 164 | parameters that you can specify:
165 |nRows, (default: 10): The number of rows of the distribution builder (i.e. the
168 | maximum number of balls that can be allocated to a certain value).
169 | nBuckets, (default: 10): The number of buckets (columns) to which balls can be
172 | allocated.
173 | minVal, (default: 0): The value corresponding to the first bucket (the smallest
176 | value).
177 | maxVal, (default: 10): The value corresponding to the last bucket (the largest
180 | value)
181 | nBalls, (default: 10): The total number of balls to allocate.
184 | onTouch, (default: function () {}): A JavaScript function that will
187 | be called every time the user clicks a button of the distribution builder.
188 | onChange, (default: function () {}): A JavaScript function that will
190 | be called every time the user successfully changes the allocation of balls (i.e. when the add/remove
191 | action is performed on non-filled/non-empty bucket, and when there are still balls available to
192 | allocate).
193 | toggleGridClick, (default: false): Allow/disallow participants to click
195 | on the distBuilder to change the allocation of the balls.
196 | addTotals, (default: false): Add a row to the bottom of the distBuilder
198 | summarizing how many balls are in each bucket.
199 | var distbuilder = new DistributionBuilder({
206 | nRows: 20,
207 | nBuckets: 20,
208 | minVal: 0,
209 | maxVal: 100,
210 | nBalls: 20,
211 | onTouch: function () {
212 | console.log("Distbuilder was touched!")
213 | },
214 | onChange: function () {
215 | console.log("Distbuilder was updated!")
216 | },
217 | toggleGridClick: true,
218 | addTotals: true
219 | });
220 | distbuilder.render("targetdiv");
221 | distbuilder.labelize();
222 | After the DistributionBuilder object is initialized, you must call another method to indicate where you want 225 | to see it displayed on the page:
226 |DistributionBuilder.render()
This method requires the argument target, and you can optionally supply the order
228 | argument to further tweak the appearance of the Distribution Builder.
target, required argument: The html id attribute of the element in
232 | which the distribution builder should be displayed. For best results, this element should be a div with
233 | a fixed width.
234 | order, (default: ‘grid-labels-buttons’): The order in which the elements of the
237 | Distribution Builder should be rendered. For instance, if you want to labels to appear above the grid,
238 | you should specify ‘labels-grid-buttons’.
239 | var distbuilder = new DistributionBuilder({
247 | nRows: 10,
248 | nBuckets: 20,
249 | minVal: 0,
250 | maxVal: 100,
251 | nBalls: 10,
252 | onTouch: function () {
253 | console.log("Distbuilder was touched!")
254 | },
255 | onChange: function () {
256 | console.log("Distbuilder was updated!")
257 | }
258 | });
259 | distbuilder.render("targetdiv", "labels-grid-buttons");
260 | distbuilder.labelize();
261 |
262 | You generally want to add some labels to the buckets of your distribution builder:
265 |DistributionBuilder.labelize()
By default, the Distribution Builder automatically creates evenly spaced labels, using the distance between 267 | the minimum and maximum value and the number of buckets using the following code:
268 |269 |
step = (maxValue - minValue)/nBuckets;
270 | labels = [minValue + step/2 + step*0, minValue + step/2 + step*1, ..., minValue + step/2 +step*(nBuckets-1)]
271 | Calling the method DistributionBuilder.labelize() without arguments will display those
272 | labels. However, you are free to customize the labels using the following arguments:
labels, an array of length nBucketscode>. Supplying this argument will
275 | override the default labels.
276 | prefix, a string (e.g. ‘$’) which you would like to see prepended to all the labels.
278 | suffix, a string (e.g. ‘€’) which you would like to see appended to all the labels.
280 | The prefix and suffix arguments are always applied, whether or not you specify
283 | custom labels using the label argument.
var distbuilder = new DistributionBuilder({
289 | nRows: 10,
290 | nBuckets: 20,
291 | minVal: 0,
292 | maxVal: 100,
293 | nBalls: 10,
294 | onTouch: function () {
295 | console.log("Distbuilder was touched!")
296 | },
297 | onChange: function () {
298 | console.log("Distbuilder was updated!")
299 | }
300 | });
301 | distbuilder.render();
302 | distbuilder.labelize({
303 | prefix: '~',
304 | suffix: '€'
305 | });
306 |
307 | By default, respondents will start from an empty distribution (i.e. zero balls in all buckets).
310 |However, you might want to specify a different starting distribution, or change the current distribution 311 | to a specific value. To do so, you can use the method:
312 |DistributionBuilder.setDistribution(dist)
Here is an example:
314 |var distbuilder = new DistributionBuilder({
316 | nRows: 10,
317 | nBuckets: 10,
318 | minVal: 0,
319 | maxVal: 100,
320 | nBalls: 60
321 | });
322 | distbuilder.render();
323 | distbuilder.labelize(});
324 | var dist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
325 | distbuilder.setDistribution(dist);
326 |
327 | After setting up the Distribution Builder, its internal state can be conveniently accessed through three 335 | methods:
336 |DistributionBuilder.getDistribution() returns the current allocation of balls in the
339 | form of an array of length nBuckets. If there are four buckets, and the user has allocated two balls
340 | to the first bucket, one to the third one, and zero to the second and fourth, the method will return
341 | [2, 0, 1, 0].
DistributionBuilder.getRemainingBalls() returns the number of balls that have not been
345 | allocated yet.
DistributionBuilder.isComplete() returns true is the user has allocated all
349 | the balls, and false otherwise.
The two examples below demonstrate how those three methods can be used in your experiments and studies.
353 |This can be achieved by creating two <div>s called “BallsLeft” and “BallsAllocated”, and
355 | assigning a function updating those <div>s to the onChange argument of the
356 | Distribution Builder initialization function.
var n_balls = 10;
366 | $j('#BallsLeft').text("You have " + n_balls + " balls left.");
367 | $j('#BallsAllocated').text("You have allocated " + 0 + " balls.");
368 | var distbuilder = new DistributionBuilder({
369 | minVal: 0,
370 | maxVal: 100,
371 | nRows: 10,
372 | nBuckets: 20,
373 | nBalls: n_balls,
374 | onChange: function () {
375 | var remainingballs = this.getRemainingBalls();
376 | var ballsallocated = n_balls - this.getRemainingBalls();
377 | $j('#BallsLeft').text("You have " + remainingballs + " balls left.");
378 | $j('#BallsAllocated').text("You have allocated " + ballsallocated + " balls.");
379 | }
380 | });
381 | distbuilder.render("targetdiv");
382 | distbuilder.labelize();
383 | You probably want the participants to your studies to allocate all the balls before being able to validate 386 | their distribution. Fortunately, it is easy to add a button, and only enable it when all the balls have been 387 | allocated:
388 |button called “SubmitDistribution” with disabled=true. When clicked,
391 | this button will for now display "Distribution Validated!".
392 | onChange argument of the
395 | DistributionBuilder object. This is done by using the value returned by the DistributionBuilder.isComplete()
396 | method.
397 | Together, those two steps are ensuring that the distribution is fully specified before the user can click the 400 | button.
401 |var distbuilder = new DistributionBuilder({
410 | minVal: 0,
411 | maxVal: 100,
412 | nRows: 10,
413 | nBuckets: 20,
414 | nBalls: 10,
415 | onChange: function () {
416 | if (this.isComplete()) {
417 | $j("#SubmitDistribution").attr("disabled", false)
418 | } else {
419 | $j("#SubmitDistribution").attr("disabled", true)
420 | }
421 | }
422 | });
423 | $j("#SubmitDistribution").click(function() {alert("Distribution Validated!")});
424 | distbuilder.render("targetdiv");
425 | distbuilder.labelize({});
426 | We would now like to see in which buckets the balls have been allocated when the user validates the 429 | distribution by clicking on the button.
430 |Building upon the previous example, we can change the message "Distribution Validated!" to display the actual
431 | distribution that the user has specified. by using the method
432 | DistributionBuilder.getDistribution().
var distbuilder = new DistributionBuilder({
442 | minVal: 0,
443 | maxVal: 100,
444 | nRows: 10,
445 | nBuckets: 20,
446 | nBalls: 10,
447 | onChange: function () {
448 | if (this.isComplete()) {
449 | $j("#SubmitDistribution").attr("disabled", false)
450 | } else {
451 | $j("#SubmitDistribution").attr("disabled", true)
452 | }
453 | }
454 | });
455 | $j("#SubmitDistribution").click(function() {
456 | var message = "The distribution specified by the user is: " + distbuilder.getDistribution();
457 | alert(message)
458 | });
459 | distbuilder.render("targetdiv");
460 | distbuilder.labelize({});
461 | You will often want the Distribution Builder to be part of larger survey on Qualtrics, and you will want to 464 | store the resulting distribution in a variable. This result can be achieved in the following way:
465 |"MyDistributionResult", or any other name that you want to use. Leave
468 | the value empty: this is where we are going to store the results.
469 | Qualtrics.SurveyEngine.setEmbeddedData() function provided by Qualtrics
472 | to store a value in the "MyDistributionResult" variable. The syntax is: Qualtrics.SurveyEngine.setEmbeddedData("MyDistributionResult",
473 | "TheStringYouWantToStoreHere")
474 | DistributionBuilder.getDistribution() does not return a string: it returns an array. You
477 | must therefore convert this array into a string first. To do so, simply use DistributionBuilder.getDistribution().join().
478 | This will join the elements of the array by commas, and you will be able to store it in Qualtrics.
479 | Adding the code to the previous example:
482 |var distbuilder = new DistributionBuilder({
491 | minVal: 0,
492 | maxVal: 100,
493 | nRows: 10,
494 | nBuckets: 20,
495 | nBalls: 10,
496 | onChange: function () {
497 | if (this.isComplete()) {
498 | $j("#SubmitDistribution").attr("disabled", false)
499 | } else {
500 | $j("#SubmitDistribution").attr("disabled", true)
501 | }
502 | }
503 | });
504 | distbuilder.render("targetdiv");
505 | distbuilder.labelize({});
506 | $j("#SubmitDistribution").click(function () {
507 | var results = distbuilder.getDistribution().join()
508 | Qualtrics.SurveyEngine.setEmbeddedData("MyDistributionResult", results);
509 | var message = 'The function "Qualtrics.SurveyEngine.setEmbeddedData("MyDistributionResult", ';
510 | message += results + ') was called. Your data would have been stored in Qualtrics!';
511 | alert(message)
512 | });
513 | If you want to customize the appearance of the distribution builder, the full list of classes defined by the
517 | stylesheet can be found in the distributionbuilder.css file.
The following CSS tree will help you understand the mapping between the CSS classes and the way the 519 | Distribution Builder object is rendered on screen.
520 |<div id="MyContainer" class="distbuilder">
521 | <div class="grid">
522 | <div class="distrow row2">
523 | <div class="cell col0">
524 | <div class="ball col0"></div> // Present in all "cells"
525 | </div>
526 | <div class="cell col1"></div>
527 | <div class="cell col2"></div>
528 | </div>
529 | <div class="distrow row1">
530 | <div class="cell col0 filled"></div>
531 | <div class="cell col1"></div>
532 | <div class="cell col2"></div>
533 | </div>
534 | <div class="distrow row0">
535 | <div class="cell col0 filled"></div>
536 | <div class="cell col1"></div>
537 | <div class="cell col2"></div>
538 | </div>
539 | </div>
540 | <div class="buttons">
541 | <div class="distrow">
542 | <div class="buttongroup">
543 | <a class="btn btn-default distbutton glyphicon glyphicon-plus"></a>
544 | <a class="btn btn-default distbutton glyphicon glyphicon-minus"></a>
545 | </div>
546 | <div class="buttongroup">
547 | <a class="btn btn-default distbutton glyphicon glyphicon-plus"></a>
548 | <a class="btn btn-default distbutton glyphicon glyphicon-minus"></a>
549 | </div>
550 | <div class="buttongroup">
551 | <a class="btn btn-default distbutton glyphicon glyphicon-plus"></a>
552 | <a class="btn btn-default distbutton glyphicon glyphicon-minus"></a>
553 | </div>
554 | </div>
555 | </div>
556 | <div class="labels">
557 | <div class="distrow">
558 | <div class="label col0">~1€</div>
559 | <div class="label col1">~2€</div>
560 | <div class="label col2">~3€</div>
561 | </div>
562 | </div>
563 | </div class="totals"> // Only present if argument `addTotals` is `true`.
564 | <div class="distrow">
565 | <div class="total col0">2</div>
566 | <div class="total col1">0</div>
567 | <div class="total col2">0</div>
568 | </div>
569 | </div>
570 | </div>
571 | distBuilder is published under the MIT 574 | license. The code is written in Typescript, and is transpiled in legacy code 575 | for cross-browsers compatibility. It is developed upon the jQuery 576 | library, and uses some elements of Bootstrap 577 | for styling.
578 |I am grateful for the financial support of ADL Partner and INSEAD, the comments of Nicholas Reinholtz and Bart de Langhe on previous 581 | versions of the Distribution Builder, and Dan Goldstein's 582 | references on the history of the distribution builder. I would also like to thank Ignazio Ziano for uncovering a bug 584 | when trying to use the library.
585 |This page is hosted on GitHub Pages. Theme by mattgraham
586 |