You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Docs/development/r-analyses-guide.md
+69-11Lines changed: 69 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -105,11 +105,38 @@ It is recommended to **only** use `.vf()` for display purposes. Using it to crea
105
105
106
106
JASP accepts images as SVGs encoded as base64 data URIs. The following functions are useful for creating images in this format.
107
107
108
-
`.beginSaveImage(width, height)`
109
-
`.endSaveImage(descriptor)`
110
-
111
-
`.beginSaveImage()` starts the image capturing process, and returns a descriptor. Once the analysis has performed all the rendering it needs, it should call `.endSaveImage()`, passing in the descriptor provided by `.beginSaveImage()`. `.endSaveImage()` returns a descriptor which can be assigned to the image object described below.
108
+
Recently, we moved to a new system for writing images, to support the saveImage functionality (saving JASP images to a file). Here is the quick overview:
112
109
110
+
1. Create a `ggplot2` plot in your code. If you're working with (deprecated) base-r plots, wrap your plotting routine in a function (don't choose this option):
111
+
```r
112
+
p<-ggplot2::ggplot(...)
113
+
```
114
+
__OR__
115
+
```r
116
+
.plotFunc() <-function() {
117
+
# add plotting routine here
118
+
plot(plotData, plotParameters)
119
+
}
120
+
```
121
+
2. Write the image to an object using the function `.writeImage()`:
122
+
```r
123
+
imgObj<- .writeImage(width=options$plotWidth,
124
+
height=options$plotHeight,
125
+
plot=p)
126
+
```
127
+
__OR__
128
+
```r
129
+
imgObj<- .writeImage(width=options$plotWidth,
130
+
height=options$plotHeight,
131
+
plot=.plotFunc)
132
+
```
133
+
3. Extract the necessary information from the image object to your plot object that will go into the output:
134
+
```r
135
+
plot[["data"]] <-imgObj[["png"]]
136
+
plot[["obj"]] <-imgObj[["obj"]]
137
+
plot[["convertible"]] <-TRUE
138
+
plot[["status"]] <-"complete"
139
+
```
113
140
114
141
### Cleaning data
115
142
@@ -200,7 +227,7 @@ An example of a results bundle might be:
200
227
-`results` : a results object, descriped below
201
228
-`status` : the status, this can be either `"inited"` (typically to be returned when `perform == "init"`) or `"complete"` (typically returned when `perform == "run"`)
202
229
-`state` : arbitrary data that can be retrieved in a subsequent call of this analysis with a call to `.retrieveState()`, explained below
203
-
-`keep` : a list of file descriptors (from `.endSaveImage()`). This instructs the temporary file system to keep these files, and not delete them.
230
+
-`keep` : a list of file descriptors (from `.writeImage()`). This instructs the temporary file system to keep these files, and not delete them.
204
231
205
232
### Results
206
233
@@ -449,7 +476,40 @@ It will return a named list with TRUE/FALSE values indicating which options have
449
476
450
477
# otherwise continue
451
478
452
-
### State
479
+
Progress bar
480
+
------------
481
+
482
+
If an analysis is going to run for a long time it's nice to give the user some reassurance that something is actually happening. Of course we have the spinner, but this provides no actual progress indication. To this purpose the `.newProgressbar` function can be used. The function takes the following arguments:
483
+
484
+
-`ticks`: integer specifying the number of times the progress bar needs to be updated to reach completion.
485
+
-`callback`: callback function which is supplied to each analysis and described above.
486
+
-`skim`: integer specifying the percentage that should be "skimmed" from the total 100%. The progress bar generally captures only some portion of an analysis. If the remainder might also take some time we can reserve a portion of the progress bar. Default percentage is `5`.
487
+
-`response`: boolean, should the progressbar return the response of the callback? Default is `FALSE`.
488
+
489
+
Note that `.newProgressbar` itself returns a function. This function takes the optional arguments:
490
+
491
+
-`results`: results list. See above to read more about the results list structure.
492
+
-`complete`: boolean specifying if the progress bar should be forced to immediate (premature) completion.
493
+
494
+
### Example:
495
+
496
+
A typical analysis that takes a while is the Bayesian ANOVA.
497
+
Now, there are parts of this analysis that go quite quick; calculating descriptives or effects takes no time.
498
+
The model calculation is slow, however, in this part of the code a progress indicator makes a lot sense.
499
+
Say we have the number of models we will calculate stored in `nModels`. Before the first model is calculated we then run
If we want to make the analysis responsive to user changes we can set `response` to `TRUE` and check the callback output as described above.
510
+
511
+
State
512
+
-----
453
513
454
514
The state is a storage system. This storage can be used to transfer useful data between different calls to an analysis.
455
515
The main goal of the state is to prevent recalculating things that were already calculated once (and thus make analyses quicker). Let's use the Bayesian ANOVA as an example of its practical relevance. This analysis may take up to several minutes to fully calculate its result -- which is not that unusual for a Bayesian analysis. Now if a user decides he would also like to see descriptive statistics the analysis will be run again. If we had no storage system in place it would take several minutes to give an additional table with descriptive statistics because the ANOVA has to be calculated all over again -- eventhough we already did this. With the state system it becomes possible to store the outcome of the ANOVA and then re-use it. Asking for additional output such as a descriptives table will now result in a very short calculation because the ANOVA calculation can be avoided. It may be clear that it is not always possible to re-use output from an earlier call to the analysis. For example, if the dependent variable of the ANOVA is swapped for a different one, the old results become unusable.
Now if the analysis is called again and e.g. `sampleMode` changes, only the plot will be returned.
476
-
If there are state items you would like to keep indefinitely -- regardless of the options a user changes -- you may also specify this in the state, e.g.:
477
-
```
478
-
attr(state, "keep") <- c("model", "options")
479
-
```
536
+
If there are state items you would like to keep indefinitely -- regardless of the options a user changes -- you must omit these in the stateKey.
0 commit comments