A Protobi project is specified by a JSON (JavaScript Object Notation) syntax which defines what elements exist and how they should be displayed. The beauty is that you can see and edit the actual code that defines your Protobi project.
JSON editor
For any element or group, press the circle or square icon and select "Edit JSON...." to edit element properties. JSON syntax is pretty simple, and the existing examples should help you figure out the logic.
The general pattern is {"key":"value"}
pairs separated by commas. The key is always contained in quotes and the value may be a string, number, null, an array in square brackets or even another JSON object in curly braces.
All of the above attributes have default values, and can be set to null or "". Below is a list of allowable values. You can also download the Protobi JSON Reference.pdf.
"Elements" in project settings
For any Protobi project you can see and edit the complete JSON specification by selecting the "Elements" tab under project settings. The primary document is an array containing one JSON object for each element. This is for advanced users only, so be very careful if editing this directly. Below is an example of how JSON syntax can be used in "Elements" to define variables.
Expand example
Define variables in "Elements"
In the simple example below, there are two elements, "Q1" representing a question in the survey, and "$root" representing the top of the survey document.
Here, "Q1"
has an optional "format"
attribute which specifies how raw values are to be formatted for display to the user, as an optional string title attribute.
[ { "key": "Q1", "title": "Q1. What is your primary specialty?", "color": "#9B6", "format": { "1": "Primary care", "2": "Allergy", "3": "Pulmonology", "4": "Otolaryngologist" } }, { "key": "$root", "children": ["Q1"], } ]
We can extend the example to include a tab "profile"
to be displayed to the user with a few defined admin variables:
[ { "key": "Q1", "title": "Q1. What is your primary specialty?", "color": "#9B6", "format": { "1": "Primary care", "2": "Allergy", "3": "Pulmonology", "4": "Otolaryngologist" } }, { "key": "profile", "displayKey": "Profile", "children": [ "country", "source", "status"] }, { "key": "status", "format": { "1": "Eligible", "2": "Invited", "3": "In progress", "4": "Terminated", "7": "Complete" }, { "key": "$root", "children": ["profile", "Q1" ], } ]
Here, "country"
is listed in the children of element "$root"
. Just naming a child is enough to define and create a default element. The attribute "country"
defines constituent elements. But there is no entry defined with a key "country"
, so Protobi will create a default element {"key": "country"}
. That element will in turn look in the data for a column named "country"
. If it finds such a column, it will display the values directly. Conversely, there is an entry with key "status"
so Protobi will use that format to display the value in a human-readable format.
Attributes
key
Each element has a unique key
that identifies it. Multiple groups can refer to the same key
as a child element, and each group will point to the same element with the same properties. By default, the key appears in the element's header.
displayKey
Specifies a different string to display in the element's header. This might be handy if the survey define a column with key s0 but you would prefer the user to see Specialty instead. In this case you might have:
{ "key": "s0", "displayKey": "Specialty" }
title
(string)
Longer text that appears below the element header. For instance, the element specialty might have the title
{ "key": "s0", "displayKey": "Specialty", "title": "Doctor, what is your primary specialty?" }
color
heritable
The color of the element icon. It may be any CSS named color (e.g. "color": "gold"
) or hexadecimal color code (e.g."color": "#FA0"
)
{ "key": "s0", "displayKey": "Specialty", "color": "#FA0", "color": "gold" }
format
heritable (object)
Translates raw values to human-readable strings for display. Underlying value is unchanged. Formats are directly comparable to SPSS value labels. Formats are specified as objects with the raw value as the key and the formatted string as the value, e.g.:
{ "format": { "AD": "Andora", "AI": "Anguila", "AG": "Antigua", "AR": "Argentina", ... } }
If no format is defined, then all raw values that appear in the data are displayed directly in the distribution. If a format is defined, then all formatted values appear in the distribution, whether or not they have data values. Values that exist in the data but are not defined in the format will appear under "Other".
You can toggle formatted value vs. raw value using the Format
button.
display
Specify how the element should be displayed. Accepted values are:
"independent"
"checkbox"
"compact"
maxValue
(number)
Reference value to calculate length of bars when numeric values are compacted to mean or median.
hidden
(boolean)
Hides the entire element! To unhide the element, use the tree on the left to select the element, then press the "Advanced" button from the toolbar and select "Hide/unhide." You can also use the keyboard shortcut, Shift + D.
width
(number)
Specify width in pixels.
height
(number)
Specify height in pixels.
color
(string)
Color code for element. Any CSS color string, such as "purple"
or "#B69"
.
colors
("ascending"|"descending"|object)
Color scheme for element.
A special value like "descending"
or "ascending"
indicates the values are ordinal and code from shades of blue to green.
You can specify a hash of color codes for specific values, e.g.:
{ "colors": { "1": "red", "2": "orange", "3": "yellow" } }
Data
field
By default, Protobi assumes that each element key refers to a data column with the same name. For instance, the element with key "s0"
will look for a data column "s0"
.
You can override this using the field
attribute. For instance the following defines an element "s0"
which looks to the data column "spec"
for its data:
{ "key": "s0", "field": "spec" }
element
Instead of using the field
attribute, you can also override the data reference using the element
attribute. This attribute looks to the calculated element for its data. These calculation could be due to either transform or reformat. For instance, the following element "s0_clone"
would look for calculated data in "s0"
.
{ "key": "s0_clone", "element": "s0" }
type
Specify the data type for the element. Accepted values are:
null
""
"string"
"number"
"date"
"empty"
If "type"
is "number"
, the default is to sort by value, show means and auto-bin into ranges.
If "type"
is "string"
, the default is to sort by frequency, not show means, and show a search bar if more than 10 values.
If "type"
is "date"
, Protobi parses the values as Date values. Protobi will recognize any date format recognized by the browser. If you have a special date format, you can set the dateFormat
attribute. See the Dates and times tutorial
If "type"
is "empty"
, Protobi will not show data for this element at all. This is appropriate for groups of elements that have children but do not correspond to a data element themselves.
If "type"
is ""
or null
, Protobi will make its best guess based on the available data.
dateFormat
(string)
Specify a date format so that Protobi can parse the string values as dates. You can enter any format recognized moment.js, see this link for a complete syntax.
For instance, if your date looks like "Monday April 9, 2018" you can specify "dateFormat": "dddd MMM D, YYYY"
split
(string|"word"|"letter")
Specifies a delimiter to split each responses into an array of values. You can enter a specific delimiter, such as a comma (","
), semicolon (";"
) or pipe ("|"
).
For instance, each response may be a list of the respondent's favorite pizza toppings separated by commas.
{ "toppings": "s0", "split": "," }
You can also enter a special values like "word"
which will intelligently break at all word and sentence boundaries, like spaces, periods, semicolons, and line breaks and drop some punctuation marks like "?" and "!". This is particularly useful when creating Word clouds
Setting "split": "letter"
will split the string into individual characters. Not that you would but you could.
roundby
(number|string|array) heritable
Specify bin size for grouping numeric values for analysis. Acceptable values are:
-
0
no binning at all -
number
specify linear bin size, e.g.10
-
array
specify linear bin size, e.g.[1,5,10,25,50,100]
-
"auto"
auto-guess bin size based on distribution -
"log"
logarithmic bins based on powers of 10
weight
heritable
Specific a weight value for this element. Accepted values are:
- String name of a data field with weight values, e.g.
"sales"
- String key of an element which calculates a weight, e.g.
"s0"
- Numeric constant to use as a weight, e.g.
1000
- Default indicating no weight
null
denominator
(string) heritable
Divides response values by another data column or element. This is useful for transforming count responses into percentages. e.g.:
{ "key": "s5a", "denominator": "s4" }
Note that when denominator
is set, Protobi automatically calculates the mean as a ratio average rather than a simple average, see the Ratios tutorial
transform
(string)
If the element is a group, standard transforms calculates a summary value from children:
-
"sum"
returns sum of children -
"mean"
returns mean of children -
"median"
returns median of children -
"min"
returns minimum of children -
"max"
returns maximum of children -
"stdev"
returns standard deviation of children -
"squish"
condenses multiple string values a single multi-value response -
"compact"
transforms multiple binary elements into a single multi-value response
There are a number of additional transforms for Date values (i.e. "type": "date"
):
-
"minute"
returns value to nearest minute -
"hour"
returns value to nearest hour -
"day"
returns value to nearest day -
"month"
returns value to nearest month -
"year"
returns value to nearest year -
"dayofweek"
returns name of day -
"monthofyear"
returns name of month
For groups, it is possible to "squish" responses from multiple columns into one multiple-response element. This is useful for questions like "List up to three reasons". It de-duplicates responses for each individual.
It is also possible to insert arbitrary JS code. The transform defines a function which is passed two objects, row
represents the data row, and this
represents the element itself. For instance:
{ "key": "x-sqrt", "transform": "return Math.sqrt(row.x)" }
string
("toLower"|"toUpper"|"titleCase"|"trim"|"deburr")
Specify any lodash.js string functions, including:
-
"toUpper"
converts to upper case -
"toLower"
converts to lower case -
"capitalize"
converts first character to upper case and rest to lower case. -
"deburr"
converts to Latin characters and removes accent marks -
"trim"
removes leading and trailing spaces
reformat
heritable (object)
An object mapping raw values to new values, { "raw": "new", ...}
.
It works a lot like format except it actually transforms the values before analysis, and you can appy "format"
to the results.
Reformat can be used to convert values like 99
into missing values:
{ "reformat": { "99": "" } }
Conversely, reformats can be useful to zero-fill missing values, e.g.
{ "reformat": { "": 0 } }
Reformats are also used to recode verbatim responses. For instance, if a survey elicits respondent sex as a text open-ends, values might e recoded as :
{ "reformat":{ "Man": "M", "Male": "M", "male": "M", "Female": "F", "female": "F", "Woman": "F" } }
The raw value is on the left, and is always written as a string. The new value on the right can be a number, boolean, null or string value.
Note that reformat is applied before format is applied and can be used in conjunction with other transformations.
ceiling
heritable (number)
Bounds the distribution to this value or smaller. Useful for Winsorizing data.
floor
heritable (number)
Bounds the distribution to this value or greater. Useful for Winsorizing data.
filter
heritable (object)
A query expression that filters out all other values. This is useful for including only valid responses. Filter objects operate on the entire row, so the field name has to be specified. Constraints are specified in MongoDB query syntax.
A few examples:
-
{"QA5a": {"$in": [1,2,3,4,5]}}
accepts rows where QA5a is in [1,2,3,4, 5] -
{"QA5a": {"$nin": [-9, 98, 99]}}
rejects rows where QA5a is -9, 98 or 99 -
{"QS4": {"$gte":0, "$lt": 100}}
accepts rows where QA5a is 0 up to 99
Statistics
showMean
(boolean) heritable
showSum
(boolean) heritable
showMedian
(boolean) heritable
showBasis
(boolean) heritable
showMin
(boolean) heritable
showMax
(boolean) heritable
denominator
(boolean) heritable
Groups
children
(array)
list all sub-elements for the group. can use to create a shell for a new element. (advance use)
hideChildren
(boolean)
When transform or compactto is used, children are usually hidden for display purpose. Use to hide/unhide children
compactto
(number|string|array|null) heritable
Control how group is summarized in compact form:
- A specific value, e.g.
1
for a top-box percentage. - An array, e.g.
[1,2]
for a top-N box percentage. -
"$mean"
for a summary of means. -
"$sum"
for a summary of sums. -
"$min"
for a summary of sums. -
"$max"
for a summary of sums. -
"$median"
for a summary of sums. -
null
for no summary.
compactto
can also be specified for an independent element to display a single summarized value.
unique
(boolean)
When transform to squished is used, "unique": false would count each value separately instead of collapse like items into a single value.
Heritable properties
Changes to these heritable properties propagate down to child elements within a group (and to their children...):
- format,
- reformat,
- maxValue,
- color,
- weight,
- showSum,
- showMean,
- showMedian,
- showMin,
- showMax,
- showBasis,
- denominator
Below is a partial list of attributes recognized by Protobi with their allowable values and a brief description:
Attribute | Type | Example | Description |
---|---|---|---|
key |
string | "s1" | Unique identifier for element. Required and immutable. |
displayKey |
string | "S1" | Override key for display. |
title |
string | "Primary specialty" | Additional description text. |
field |
string | "s1x" | Specify another data column as data source (default is "key") |
element |
key | "s1x" | Specify another element as data source, a |
children |
array | ["s1a","s1b","s1c"] | List child elements. If not null, element is a group. |
format |
hash | {"1":"PCP","2":"Neuro"} | Format values for display after analysis. |
reformat |
object | {"99":"", "7":0} | Recode values prior to analysis. |
color |
string | "gold"|"#FA0" | CSS color for element. |
colors |
object | {"1":"red","2":"yellow"} | CSS colors for values. Can be "ascending" or "descending". |
type |
string | "string"|"number"|"empty" | Whether element values are numbers, string, or not applicable. |
compactto |
value or array | 1 | One or more summary values for top/bottom box percentages. |
roundby |
value or name | 0|10|"auto"|"log" | Bin range for numeric values. |
transform |
name | "squish"|"sum"|"mean"|(fn) | Specify standard transform function or code a custom function |
split |
string | "," | Split values at delimiter into a multiple response value |
weight |
number or key | "ptwt"|1000 | Weight frequencies by value of a data column or constant. |
scale |
number or key | "s4"|100 | Multiply values by a data column or constant. |
denominator |
number or key | "s3"|100 | Divide values by a data column or constant. |
display |
name | null|"checkbox"|"compact" | Specify how to display element as expanded, compact or group |
hidden |
boolean | TRUE | Hide element from tab |
hideChildren |
boolean | TRUE | Hide children (useful for groups with transform specified) |
showBody |
boolean | FALSE | Hide distribution (useful to show just summary stats) |
heritable |
boolean | FALSE | Whether changes to heritable properties propagate to children |
showMissing |
boolean | FALSE | Whether to include NA values in distribution percentages |
chartType |
name | "VennDiagram" | Specify alternative chart type (default is "BaselineBarChart") |
chartOptions |
boolean | {"width":"480px"} | Specify options specific to selected chartType |
showStats |
array of values or objects | [[1,2],{label:"net",value:[6,7]} | Additional custom statistics to show |
follow |
hash | {"q1":["chartOptions.width"} | Specify which elements and which attributes of them to follow |