-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathiii-package-devel.Rmd
More file actions
95 lines (72 loc) · 4.53 KB
/
iii-package-devel.Rmd
File metadata and controls
95 lines (72 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
---
title: "`SpaDES.shiny` package development"
author: "Damian Rodziewicz & Alex Chubaty"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{03-package-devel}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
## Introduction
This document is intended for contributors to the development of the `SpaDES.shiny` package.
For users looking to get started building basic `SpaDES.shiny` apps, see the introductory vignettes.
Please review the [Contributor Guidelines](https://github.com/PredictiveEcology/SpaDES.shiny/blob/master/CONTRIBUTING.md).
## Package structure
The `SpaDES.shiny` package consists of a set of shiny modules, an app generator and templates.
The generator takes application metadata and uses templates to build a standalone application.
Modules implement reusable parts of application that can be used to speed up the implementation process.
### App generator
App generator builds new application in a chosen directory based on application metadata.
In the directory there is a `ui.R` and `server.R` created together with all needed files.
Generator uses templates (described in next section) to generate the code.
Entry point of generator is `newApp` function.
Application metadata is passed to other functions to build different parts of the app.
Generated applications use `shinydashboard`, where each menu item is a `shiny` module.
### App templates
Application templates are located `inst/templates`.
Any static parts of application that are generated by the generator should be put here.
Generator uses the [`whisker`](https://cran.r-project.org/package=whisker) package to generate files from templates.
In order to add a new UI/server component, create a new file in `inst/templates/` directory with the `.template` extension.
Inside the template write code that you'd like to have generated.
Put variables in "mustache" form (`{{variable}}`).
By default whisker applies html escaping on the generated text.
To prevent this use `{{{variable}}}` (triple) in stead of `{{variable}}` (double).
### Shiny modules
Shiny modules in this package are generic components that can be used to bootstrap the application.
The module should have a generic purpose and the main aim of developer should be to make this module reusable in different applications.
When building a new shiny module try to extract as much code as possible to separate modules that can be reused in other use cases.
For example if you are building a shiny module that consists of a table, plot and a slider divide it into three modules each representing separate logic that can be reusable - a table view of a data.frame, a plot and a slider.
First always check if there already exists a module that does the job.
Take a look at `rastersOverTime` module. The aim of this module is to display a map with rasters that change over time.
We want to be able to also change underlying polygons that are displayed and show histogram of raster values.
We can divide this module into smaller independent components. `rastersOverTime` module actually consists of a:
- map
- slider that allows user to choose raster to display
- slider that allows user to choose polygons to display
- raster updater that draws a chosen raster on a map
- polygon updater that draws chosen set of polygons on a map
- summary popup that shows pop ups on map for selected polygons and raster
- histogram for a raster
This division gives us 7 independent generic components (actually 6 components - slider is used twice) that can be used in any combination.
In the end your code may look as follows:
```r
rasterIndexValue <- callModule(slider, "rastersSlider")
polygonIndexValue <- callModule(slider, "polygonsSlider")
...
callModule(tilesUpdater, "tilesUpdater", mapProxy, urlTemplate, session$ns("tiles"),
addTilesParameters = addTilesParameters, addLayersControlParameters = NULL)
callModule(summaryPopups, "popups", mapProxy, click, raster, polygons)
callModule(polygonsUpdater, "polygonsUpdater", mapProxy, polygons, weight = 0.2)
callModule(histogramForRaster, "histogram", sampledRaster, histogramBreaks = breaks,
scale = rasterScale, addAxisParams = addAxisParams,
width = 1, space = 0)
```
What is more - if someone wants to create a map with raster selection and popups - they can just take a map, slider, raster updater and summary popup.
A user can decide to implement different way of selecting the raster - they'll just use another module instead of the slider.