Note: this document is meant to be a high-level overview of constructing a dashboard using flexdashboard, plotly and crosstalk. This is not a definitive guide to each package nor is this the only approach to constructing a dashboard using R. Please refer to the links provided for more details on how to use the packages highlighted here.
Source: https://plotly-r.com
---
title: "flexdashboard + plotly + crosstalk"
output: flexdashboard::flex_dashboard
---
```{r setup, include=FALSE}
library(plotly)
library(crosstalk)
lw <- read.csv("length-weight_data.csv")
shared_lw <- SharedData$new(lw)
```
Column {.tabset}
-------------------------------------
### Length-Weight relationship
```{r}
plot_ly(data = shared_lw) %>%
add_markers(x = ~length, y = ~weight, name = "Observed") %>%
add_lines(x = ~length, y = ~exp(fit), name = "Predicted")
```
### Residuals vs. fitted values
```{r}
plot_ly(data = shared_lw) %>%
add_markers(x = ~fit, y = ~res)
```
This will generate a simple flexdashboard with two interactive figures (duplicated to the right)
2. Open skeleton.Rmd
in Rstudio
3. Install packages:
install.packages(c("flexdashboard", "plotly", "crosstalk"))
4. Knit file by typing Ctrl+Shift+K
or
use the button
This skeleton is a verbatim copy of an R markdown file
(`<a href="data:text/x-markdown;base64,LS0tDQp0aXRsZTogImZsZXhkYXNoYm9hcmQgKyBwbG90bHkgKyBjcm9zc3RhbGsiDQpvdXRwdXQ6IGZsZXhkYXNoYm9hcmQ6OmZsZXhfZGFzaGJvYXJkDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoY3Jvc3N0YWxrKQ0KbHcgPC0gcmVhZC5jc3YoImxlbmd0aC13ZWlnaHRfZGF0YS5jc3YiKQ0Kc2hhcmVkX2x3IDwtIFNoYXJlZERhdGEkbmV3KGx3KQ0KYGBgDQoNCkNvbHVtbiB7LnRhYnNldH0NCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMjIExlbmd0aC1XZWlnaHQgcmVsYXRpb25zaGlwDQoNCmBgYHtyfQ0KcGxvdF9seShkYXRhID0gc2hhcmVkX2x3KSAlPiUgDQogICAgYWRkX21hcmtlcnMoeCA9IH5sZW5ndGgsIHkgPSB+d2VpZ2h0LCBuYW1lID0gIk9ic2VydmVkIikgJT4lIA0KICAgIGFkZF9saW5lcyh4ID0gfmxlbmd0aCwgeSA9IH5leHAoZml0KSwgbmFtZSA9ICJQcmVkaWN0ZWQiKQ0KYGBgDQoNCiMjIyBSZXNpZHVhbHMgdnMuIGZpdHRlZCB2YWx1ZXMNCg0KYGBge3J9DQpwbG90X2x5KGRhdGEgPSBzaGFyZWRfbHcpICU+JSANCiAgICBhZGRfbWFya2Vycyh4ID0gfmZpdCwgeSA9IH5yZXMpDQpgYGANCg0K" download="skeleton.Rmd">skeleton.Rmd</a>`{=html}
)
set-up to produce a simple flexdashboard
with interactive
plotly
visuals connected by crosstalk
. Like
most R markdown files, it includes three types of content:
----
markdown
formatting```
The YAML header includes the metadata for the file, such as the document title and output format:
---
title: "flexdashboard + plotly + crosstalk"
output: flexdashboard::flex_dashboard
---
While only a title and format was specified in the skeleton, many other options are available (e.g. author, date).
The next section is a chunk of R code:
```{r setup, include=FALSE}
library(plotly)
library(crosstalk)
lw <- read.csv("length-weight_data.csv")
shared_lw <- SharedData$new(lw)
```
This is where the plotly
and crosstalk
packages are loaded along with some sample data
(`<a href="data:text/csv;base64,InJlY29yZCIsInllYXIiLCJtb250aCIsImRheSIsImxlbmd0aCIsIndlaWdodCIsImZpdCIsInJlcyINCjEsMTk4MCw1LDIyLDQxLDU4MCw2LjM5OSwtMC4wMzYNCjIsMTk4MCw1LDIyLDY1LDIyMTAsNy44NTEsLTAuMTUNCjMsMTk4MCw1LDI0LDIwLDUwLDQuMTM5LC0wLjIyNg0KNCwxOTgwLDExLDIzLDM4LDYzMCw2LjE2LDAuMjg2DQo1LDE5ODEsNCw3LDgxLDUyMTAsOC41NDQsMC4wMTQNCjYsMTk4MSwxMSwyMSw4NSw2ODAwLDguNjk2LDAuMTI5DQo3LDE5ODIsMywxNCw0OCwxMDMwLDYuODk2LDAuMDQxDQo4LDE5ODIsMywyMyw0Miw2MzAsNi40NzUsLTAuMDMNCjksMTk4Miw1LDcsNTQsMTQ1MCw3LjI2NywwLjAxMg0KMTAsMTk4MiwxMSw5LDkwLDY4ODAsOC44NzYsLTAuMDQNCjExLDE5ODIsMTEsMjIsOTIsNzYzMCw4Ljk0NSwtMC4wMDUNCjEyLDE5ODMsMywxOSw4Niw1NDEwLDguNzMzLC0wLjEzNw0KMTMsMTk4MywzLDI1LDcxLDM4MTAsOC4xMjksMC4xMTYNCjE0LDE5ODMsNywxMiwxMjQsMTY4MDAsOS44ODUsLTAuMTU2DQoxNSwxOTgzLDcsMjcsNTMsMTI0MCw3LjIwOCwtMC4wODUNCjE2LDE5ODMsNywyNyw0NSw4NDAsNi42OTMsMC4wNDENCjE3LDE5ODMsOCwxLDk2LDcyODAsOS4wNzksLTAuMTg2DQoxOCwxOTgzLDEwLDI1LDIwLDYwLDQuMTM5LC0wLjA0NA0KMTksMTk4MywxMSw1LDM0LDQwMCw1LjgxLDAuMTgyDQoyMCwxOTgzLDEyLDMsMjMsMTAwLDQuNTc5LDAuMDI2DQoyMSwxOTg0LDUsMTksMTAzLDEwMzMwLDkuMzAxLC0wLjA1OA0KMjIsMTk4NCw4LDEzLDg1LDQ1NTAsOC42OTYsLTAuMjczDQoyMywxOTg0LDgsMjAsOTcsOTU4MCw5LjExMiwwLjA1Ng0KMjQsMTk4NCwxMSwyNiw4OCw1OTcwLDguODA1LC0wLjExMQ0KMjUsMTk4NSwxLDE2LDM0LDM1MCw1LjgxLDAuMDQ4DQoyNiwxOTg1LDMsMjEsNzEsMzMwMCw4LjEyOSwtMC4wMjcNCjI3LDE5ODUsMywyMyw0Nyw4MDAsNi44MywtMC4xNDUNCjI4LDE5ODUsMywyMywzOCw0MzAsNi4xNiwtMC4wOTYNCjI5LDE5ODUsMywyMyw1OCwxODAwLDcuNDkyLDAuMDA0DQozMCwxOTg1LDgsMjAsNTUsMTUzMCw3LjMyNSwwLjAwOA0KMzEsMTk4NSwxMCwyNSw0OCwxMDYwLDYuODk2LDAuMDcNCjMyLDE5ODUsMTAsMjYsNTEsMTM1MCw3LjA4NywwLjEyMQ0KMzMsMTk4NSwxMCwyNiw0OSwxMTEwLDYuOTYxLDAuMDUxDQozNCwxOTg1LDEwLDI5LDQwLDYyMCw2LjMyMiwwLjEwOA0KMzUsMTk4NSwxMCwzMCwxMDcsMTEzOTAsOS40MjEsLTAuMDgNCjM2LDE5ODYsMSwxOCw3OSw0NzUwLDguNDY1LDAuMDAxDQozNywxOTg2LDEsMTgsNTksMTg3MCw3LjU0NiwtMC4wMTINCjM4LDE5ODYsMiwxMiwzMywyODAsNS43MTYsLTAuMDgxDQozOSwxOTg2LDIsMTYsNzMsMzQzMCw4LjIxNiwtMC4wNzYNCjQwLDE5ODYsOCwyNCwzNywzNzAsNi4wNzYsLTAuMTYzDQo0MSwxOTg2LDgsMjQsMzcsMzgwLDYuMDc2LC0wLjEzNg0KNDIsMTk4NiwxMSw1LDYzLDIyMTAsNy43NTIsLTAuMDUyDQo0MywxOTg2LDExLDE3LDc1LDM5NDAsOC4zMDIsLTAuMDIzDQo0NCwxOTg2LDExLDI5LDMzLDI4MCw1LjcxNiwtMC4wODENCjQ1LDE5ODcsMiwxMiw1NSwxNTYwLDcuMzI1LDAuMDI4DQo0NiwxOTg3LDYsMjAsNTYsMTM4MCw3LjM4MSwtMC4xNTINCjQ3LDE5ODcsNiwyMCwyMyw5MCw0LjU3OSwtMC4wNzkNCjQ4LDE5ODcsOCwzLDkyLDY2MDAsOC45NDUsLTAuMTUNCjQ5LDE5ODcsOCw1LDMyLDI4MCw1LjYxOSwwLjAxNg0KNTAsMTk4Nyw4LDUsNjYsMjcyMCw3Ljg5OSwwLjAwOQ0KNTEsMTk4NywxMCwyMCwzNyw0MDAsNi4wNzYsLTAuMDg1DQo1MiwxOTg3LDExLDEsNjEsMjA5MCw3LjY1MSwtMC4wMDYNCjUzLDE5ODcsMTEsMzAsMzYsNDUwLDUuOTksMC4xMTkNCjU0LDE5ODgsMiwxNiw0Miw2NDAsNi40NzUsLTAuMDE0DQo1NSwxOTg4LDIsMjAsNzEsMjkxMCw4LjEyOSwtMC4xNTMNCjU2LDE5ODgsMTAsMjcsNDUsNzIwLDYuNjkzLC0wLjExMw0KNTcsMTk4OCwxMCwyNyw2NSwyMjAwLDcuODUxLC0wLjE1NQ0KNTgsMTk4OCwxMSwxLDEwNiwxMzA1MCw5LjM5MSwwLjA4NQ0KNTksMTk4OCwxMSw2LDcwLDMyMDAsOC4wODQsLTAuMDEzDQo2MCwxOTg4LDExLDcsMzAsMjUwLDUuNDE2LDAuMTA2DQo2MSwxOTg4LDExLDIxLDQzLDc4MCw2LjU0OSwwLjExDQo2MiwxOTg4LDExLDI1LDQ0LDg2MCw2LjYyMiwwLjEzNQ0KNjMsMTk4OCwxMiwzLDg4LDY3MzAsOC44MDUsMC4wMDkNCjY0LDE5ODksMiwyMiw0Miw2MTAsNi40NzUsLTAuMDYyDQo2NSwxOTg5LDExLDIsNDAsNTYwLDYuMzIyLDAuMDA2DQo2NiwxOTg5LDExLDMsNjksMzY5MCw4LjAzOSwwLjE3NA0KNjcsMTk4OSwxMSwxMiw2NSwzMTgwLDcuODUxLDAuMjE0DQo2OCwxOTg5LDExLDE1LDI5LDIwMCw1LjMwOSwtMC4wMQ0KNjksMTk4OSwxMSwyNiwxNyw0MCwzLjYyNywwLjA2Mg0KNzAsMTk4OSwxMiw3LDQzLDYzMCw2LjU0OSwtMC4xMDQNCjcxLDE5ODksMTIsOSwyNywxODAsNS4wODQsMC4xMDkNCjcyLDE5OTAsMiwxMSw0Myw2NDAsNi41NDksLTAuMDg4DQo3MywxOTkwLDIsMTksNjYsMjM1MCw3Ljg5OSwtMC4xMzcNCjc0LDE5OTAsMyw0LDUzLDEyNTAsNy4yMDgsLTAuMDc3DQo3NSwxOTkwLDUsMTksNzgsNDQ4MCw4LjQyNSwtMC4wMTgNCjc2LDE5OTAsNSwxOSwyOCwxNjAsNS4xOTgsLTAuMTIzDQo3NywxOTkwLDUsMjQsNzcsNDgzMCw4LjM4NSwwLjA5OA0KNzgsMTk5MCw1LDI2LDY4LDMxMDAsNy45OTMsMC4wNDYNCjc5LDE5OTAsNSwyOCwzMywzMDAsNS43MTYsLTAuMDEyDQo4MCwxOTkwLDYsMiw3Niw0MzIwLDguMzQzLDAuMDI4DQo4MSwxOTkwLDgsMTAsMzAsMjIwLDUuNDE2LC0wLjAyMg0KODIsMTk5MCwxMCwxOSw0NSw3ODAsNi42OTMsLTAuMDMzDQo4MywxOTkwLDExLDcsNTYsMTU4MCw3LjM4MSwtMC4wMTYNCjg0LDE5OTAsMTEsMTEsMjksMjEwLDUuMzA5LDAuMDM4DQo4NSwxOTkwLDExLDE3LDM1LDM4MCw1LjkwMSwwLjAzOQ0KODYsMTk5MCwxMSwxNywyNywxNzAsNS4wODQsMC4wNTINCjg3LDE5OTAsMTEsMjMsNzAsMzc5MCw4LjA4NCwwLjE1Ng0KODgsMTk5MCwxMSwyNSwxOCw0MCwzLjgwNywtMC4xMTgNCjg5LDE5OTAsMTEsMjUsNjksMjczMCw4LjAzOSwtMC4xMjcNCjkwLDE5OTAsMTEsMjgsMjksMjEwLDUuMzA5LDAuMDM4DQo5MSwxOTkwLDExLDI5LDI3LDE3MCw1LjA4NCwwLjA1Mg0KOTIsMTk5MCwxMSwyOSw0MSw2MTAsNi4zOTksMC4wMTQNCjkzLDE5OTAsMTEsMzAsNTUsMTY4MCw3LjMyNSwwLjEwMg0KOTQsMTk5MCwxMiwxLDcyLDM5MzAsOC4xNzMsMC4xMDMNCjk1LDE5OTAsMTIsNyw0Nyw5NzAsNi44MywwLjA0OA0KOTYsMTk5MCwxMiw3LDQzLDc3MCw2LjU0OSwwLjA5Nw0KOTcsMTk5MSwyLDgsMzIsMjcwLDUuNjE5LC0wLjAyDQo5OCwxOTkxLDIsMjIsNzAsMjczMCw4LjA4NCwtMC4xNzINCjk5LDE5OTEsMiwyMiw2NiwyNDcwLDcuODk5LC0wLjA4Nw0KMTAwLDE5OTEsMywxNiw0Miw1ODAsNi40NzUsLTAuMTEyDQoxMDEsMTk5MSwzLDE2LDQ3LDkwMCw2LjgzLC0wLjAyNw0KMTAyLDE5OTEsMywyNSw0Miw1NzAsNi40NzUsLTAuMTMNCjEwMywxOTkxLDMsMjUsNzIsMzEwMCw4LjE3MywtMC4xMzQNCjEwNCwxOTkxLDMsMjUsNDEsNTIwLDYuMzk5LC0wLjE0Ng0KMTA1LDE5OTEsMywyNSwzNyw0NDAsNi4wNzYsMC4wMTENCjEwNiwxOTkxLDUsMjAsMTksNTAsMy45NzcsLTAuMDY1DQoxMDcsMTk5MSw1LDIyLDM2LDM5MCw1Ljk5LC0wLjAyNA0KMTA4LDE5OTEsNSwyNCw1MSwxMDUwLDcuMDg3LC0wLjEzDQoxMDksMTk5MSw4LDYsMzQsMzMwLDUuODEsLTAuMDExDQoxMTAsMTk5MSwxMSwxMSw0Miw3NjAsNi40NzUsMC4xNTgNCjExMSwxOTkxLDExLDEyLDQxLDU5MCw2LjM5OSwtMC4wMTkNCjExMiwxOTkxLDExLDE2LDI2LDEzMCw0Ljk2NSwtMC4wOTcNCjExMywxOTkxLDExLDE2LDQ1LDY4MCw2LjY5MywtMC4xNzENCjExNCwxOTkxLDExLDE4LDQ5LDExMDAsNi45NjEsMC4wNDINCjExNSwxOTkxLDExLDE4LDQ0LDc5MCw2LjYyMiwwLjA1DQoxMTYsMTk5MSwxMSwyMCw0OSwxMDgwLDYuOTYxLDAuMDI0DQoxMTcsMTk5MSwxMSwyNiw0NSw4MjAsNi42OTMsMC4wMTcNCjExOCwxOTkxLDExLDI4LDQyLDYwMCw2LjQ3NSwtMC4wNzgNCjExOSwxOTkxLDEyLDExLDQ1LDc5MCw2LjY5MywtMC4wMjENCjEyMCwxOTkxLDEyLDEzLDU4LDE4NDAsNy40OTIsMC4wMjYNCjEyMSwxOTkyLDMsMSw1OCwxNjUwLDcuNDkyLC0wLjA4Mw0KMTIyLDE5OTIsNCwxNSwzNyw0MjAsNi4wNzYsLTAuMDM2DQoxMjMsMTk5Miw0LDIzLDM1LDM1MCw1LjkwMSwtMC4wNDMNCjEyNCwxOTkyLDUsMzEsNTIsMTE1MCw3LjE0OCwtMC4xMDENCjEyNSwxOTkyLDExLDcsNDUsOTcwLDYuNjkzLDAuMTg1DQoxMjYsMTk5MiwxMSw5LDQ5LDEyMjAsNi45NjEsMC4xNDYNCjEyNywxOTkyLDExLDEwLDYyLDI4NjAsNy43MDIsMC4yNTcNCjEyOCwxOTkyLDExLDExLDQwLDUzMCw2LjMyMiwtMC4wNDkNCjEyOSwxOTkyLDExLDI2LDQ3LDEwNTAsNi44MywwLjEyNw0KMTMwLDE5OTIsMTIsMyw1MCw5MDAsNy4wMjUsLTAuMjIyDQoxMzEsMTk5MywyLDIzLDMxLDI2MCw1LjUxOSwwLjA0Mg0KMTMyLDE5OTMsMiwyOCw1OCwxNzQwLDcuNDkyLC0wLjAzDQoxMzMsMTk5Myw2LDMsNDAsNDQwLDYuMzIyLC0wLjIzNQ0KMTM0LDE5OTMsNiw0LDQyLDUyMCw2LjQ3NSwtMC4yMjINCjEzNSwxOTkzLDYsNCw1NiwxMTAwLDcuMzgxLC0wLjM3OA0KMTM2LDE5OTMsOCwxMSw2MSwxODEwLDcuNjUxLC0wLjE1DQoxMzcsMTk5MywxMSw1LDM0LDI4MCw1LjgxLC0wLjE3NQ0KMTM4LDE5OTMsMTEsMjMsMzMsMzEwLDUuNzE2LDAuMDIxDQoxMzksMTk5MywxMiwxLDU0LDE2MjAsNy4yNjcsMC4xMjMNCjE0MCwxOTk0LDIsMjgsNDIsNTYwLDYuNDc1LC0wLjE0Nw0KMTQxLDE5OTQsMiwyOCw0MCw1NzAsNi4zMjIsMC4wMjQNCjE0MiwxOTk0LDMsMywzNCwzMjAsNS44MSwtMC4wNDENCjE0MywxOTk0LDUsMjksMjYsMTQwLDQuOTY1LC0wLjAyMw0KMTQ0LDE5OTQsNiw1LDQwLDUwMCw2LjMyMiwtMC4xMDcNCjE0NSwxOTk1LDEsMTEsMzksNjAwLDYuMjQyLDAuMTU1DQoxNDYsMTk5NSwyLDIsMjIsODAsNC40MzksLTAuMDU3DQoxNDcsMTk5NSw3LDE0LDQxLDYxMCw2LjM5OSwwLjAxNA0KMTQ4LDE5OTUsOCwxNSw1OCwxNjMwLDcuNDkyLC0wLjA5Ng0KMTQ5LDE5OTUsOCwyOSw2MywyMjYwLDcuNzUyLC0wLjAyOQ0KMTUwLDE5OTUsMTIsNSwzMCwyNzAsNS40MTYsMC4xODMNCjE1MSwxOTk1LDEyLDYsNDAsNjAsNi4zMjIsLTIuMjI3DQoxNTIsMTk5NSwxMiw2LDI3LDE3MCw1LjA4NCwwLjA1Mg0KMTUzLDE5OTUsMTIsMTYsMTUsMzAsMy4yMzIsMC4xNjkNCjE1NCwxOTk2LDYsOCw1MywxMzQwLDcuMjA4LC0wLjAwOA0KMTU1LDE5OTYsNiwyMCw0OCw5NjAsNi44OTYsLTAuMDI5DQoxNTYsMTk5Niw3LDE2LDYzLDI2NTAsNy43NTIsMC4xMw0KMTU3LDE5OTYsNywzMSw3Nyw0NzQwLDguMzg1LDAuMDc5DQoxNTgsMTk5Niw4LDYsNjIsMjg5MCw3LjcwMiwwLjI2Nw0KMTU5LDE5OTYsOCwxNCw1NywyMDUwLDcuNDM3LDAuMTg4DQoxNjAsMTk5Niw4LDIwLDY3LDMwOTAsNy45NDYsMC4wOQ0KMTYxLDE5OTYsOSwxOCw0MCw2NTAsNi4zMjIsMC4xNTUNCjE2MiwxOTk2LDksMTgsNDIsNzMwLDYuNDc1LDAuMTE4DQoxNjMsMTk5NiwxMCwzMSwyNSwxNDAsNC44NDEsMC4xDQoxNjQsMTk5NiwxMSw5LDQ3LDkzMCw2LjgzLDAuMDA2DQoxNjUsMTk5NiwxMSwxMCwzNyw0NDAsNi4wNzYsMC4wMTENCjE2NiwxOTk2LDExLDEwLDIwLDYwLDQuMTM5LC0wLjA0NA0KMTY3LDE5OTYsMTEsMTAsMTYsMzAsMy40MzYsLTAuMDM0DQoxNjgsMTk5NiwxMSwxMSwzMiwyODAsNS42MTksMC4wMTYNCjE2OSwxOTk2LDExLDE1LDM2LDM4MCw1Ljk5LC0wLjA1DQoxNzAsMTk5NiwxMSwxNSwyOCwyMjAsNS4xOTgsMC4xOTUNCjE3MSwxOTk2LDExLDE2LDI1LDEzMCw0Ljg0MSwwLjAyNg0KMTcyLDE5OTcsMSwyNSwzMywzMDAsNS43MTYsLTAuMDEyDQoxNzMsMTk5Nyw3LDEwLDU2LDE0NDAsNy4zODEsLTAuMTA5DQoxNzQsMTk5Nyw3LDIzLDU4LDIwNzAsNy40OTIsMC4xNDMNCjE3NSwxOTk3LDcsMjksMzMsNDkwLDUuNzE2LDAuNDc5DQoxNzYsMTk5Nyw4LDIxLDUwLDEwODAsNy4wMjUsLTAuMDQNCjE3NywxOTk3LDgsMjMsNjIsMjE3MCw3LjcwMiwtMC4wMg0KMTc4LDE5OTcsOCwyNyw2MywyNjYwLDcuNzUyLDAuMTM0DQoxNzksMTk5Nyw5LDgsNzMsMzUyMCw4LjIxNiwtMC4wNQ0KMTgwLDE5OTcsOSwyNyw2MywyNDcwLDcuNzUyLDAuMDYNCjE4MSwxOTk3LDEwLDcsOTEsNzY2MCw4LjkxMSwwLjAzMw0KMTgyLDE5OTcsMTAsNywzOCw0NjAsNi4xNiwtMC4wMjkNCjE4MywxOTk3LDExLDEwLDQ3LDg2MCw2LjgzLC0wLjA3Mw0KMTg0LDE5OTcsMTEsMTEsMzQsMzMwLDUuODEsLTAuMDExDQoxODUsMTk5NywxMSwxMiwzOSw2MDAsNi4yNDIsMC4xNTUNCjE4NiwxOTk3LDExLDE0LDQ4LDgzMCw2Ljg5NiwtMC4xNzUNCjE4NywxOTk3LDEyLDksMzgsNDgwLDYuMTYsMC4wMTQNCjE4OCwxOTk4LDYsMzAsNjQsMjAzMCw3LjgwMiwtMC4xODYNCjE4OSwxOTk4LDcsMjIsNDQsODEwLDYuNjIyLDAuMDc1DQoxOTAsMTk5OCw3LDI4LDczLDQyODAsOC4yMTYsMC4xNDUNCjE5MSwxOTk4LDgsMjYsNjksMzUzMCw4LjAzOSwwLjEzDQoxOTIsMTk5OCw4LDI3LDYzLDIzMDAsNy43NTIsLTAuMDEyDQoxOTMsMTk5OCwxMCwyMCwyMiw4MCw0LjQzOSwtMC4wNTcNCjE5NCwxOTk4LDEwLDIyLDM4LDUyMCw2LjE2LDAuMDk0DQoxOTUsMTk5OCwxMCwzMSw0Myw2NzAsNi41NDksLTAuMDQyDQoxOTYsMTk5OCwxMSw0LDUwLDEyMTAsNy4wMjUsMC4wNzQNCjE5NywxOTk4LDExLDUsMjIsMTAwLDQuNDM5LDAuMTY2DQoxOTgsMTk5OCwxMSwyNSw0Myw2NzAsNi41NDksLTAuMDQyDQoxOTksMTk5OSw2LDE2LDU1LDE1NDAsNy4zMjUsMC4wMTUNCjIwMCwxOTk5LDYsMTcsODUsNjE1MCw4LjY5NiwwLjAyOA0KMjAxLDE5OTksNiwyMCw2OSwzMTAwLDguMDM5LDANCjIwMiwxOTk5LDYsMjgsMzEsMjUwLDUuNTE5LDAuMDAzDQoyMDMsMTk5OSw2LDI4LDMyLDI5MCw1LjYxOSwwLjA1MQ0KMjA0LDE5OTksNiwyOCw2NywyMjgwLDcuOTQ2LC0wLjIxNA0KMjA1LDE5OTksNiwyOSw2MywyMTQwLDcuNzUyLC0wLjA4NA0KMjA2LDE5OTksNywxMyw1OSwyMjUwLDcuNTQ2LDAuMTczDQoyMDcsMTk5OSw3LDIyLDcxLDI2OTAsOC4xMjksLTAuMjMyDQoyMDgsMTk5OSwxMSwyMiwxNCwyMCwzLjAxNSwtMC4wMTkNCjIwOSwxOTk5LDExLDIzLDI5LDIwMCw1LjMwOSwtMC4wMQ0KMjEwLDE5OTksMTIsNyw0NCw3MjAsNi42MjIsLTAuMDQzDQoyMTEsMjAwMCw2LDksNDQsNjQwLDYuNjIyLC0wLjE2DQoyMTIsMjAwMCw2LDI3LDY0LDI1MTAsNy44MDIsMC4wMjYNCjIxMywyMDAwLDcsMTMsNDQsNjYwLDYuNjIyLC0wLjEzDQoyMTQsMjAwMCw4LDE1LDcwLDM1NjAsOC4wODQsMC4wOTMNCjIxNSwyMDAwLDgsMjIsNjEsMjE2MCw3LjY1MSwwLjAyNw0KMjE2LDIwMDAsOCwyNCw1NywxNzgwLDcuNDM3LDAuMDQ3DQoyMTcsMjAwMCw4LDI0LDU2LDIwNDAsNy4zODEsMC4yMzkNCjIxOCwyMDAwLDgsMzEsNjAsMjQ3MCw3LjU5OSwwLjIxMw0KMjE5LDIwMDAsMTEsMiw0NCw2OTAsNi42MjIsLTAuMDg1DQoyMjAsMjAwMCwxMSwxMiw0Nyw4MTAsNi44MywtMC4xMzMNCjIyMSwyMDAwLDExLDE5LDE5LDYwLDMuOTc3LDAuMTE3DQoyMjIsMjAwMCwxMSwyMiwyNCwxMzAsNC43MTMsMC4xNTUNCjIyMywyMDAwLDExLDIzLDYwLDE4MDAsNy41OTksLTAuMTAzDQoyMjQsMjAwMCwxMSwzMCw0MSw1NzAsNi4zOTksLTAuMDU0DQoyMjUsMjAwMCwxMiw2LDMxLDI1MCw1LjUxOSwwLjAwMw0KMjI2LDIwMDAsMTIsOSwxMiwxMCwyLjUzLC0wLjIyNw0KMjI3LDIwMDAsMTIsMTAsMjEsNjAsNC4yOTIsLTAuMTk4DQoyMjgsMjAwMSw2LDE4LDI5LDE5MCw1LjMwOSwtMC4wNjINCjIyOSwyMDAxLDYsMTksMjMsOTAsNC41NzksLTAuMDc5DQoyMzAsMjAwMSw3LDQsNDUsOTQwLDYuNjkzLDAuMTUzDQoyMzEsMjAwMSw3LDEwLDU3LDE4NzAsNy40MzcsMC4wOTYNCjIzMiwyMDAxLDcsMzEsNzksNDM1MCw4LjQ2NSwtMC4wODcNCjIzMywyMDAxLDgsMSw2MiwxOTEwLDcuNzAyLC0wLjE0Nw0KMjM0LDIwMDEsOSw1LDY3LDI2NTAsNy45NDYsLTAuMDY0DQoyMzUsMjAwMSwxMSwyNSwzNiwzNzAsNS45OSwtMC4wNzYNCjIzNiwyMDAxLDExLDI2LDQxLDYyMCw2LjM5OSwwLjAzDQoyMzcsMjAwMSwxMiwxLDMzLDM1MCw1LjcxNiwwLjE0Mg0KMjM4LDIwMDEsMTIsMSwzNyw0ODAsNi4wNzYsMC4wOTgNCjIzOSwyMDAxLDEyLDIsMzksNTIwLDYuMjQyLDAuMDEyDQoyNDAsMjAwMSwxMiw0LDQ3LDk2MCw2LjgzLDAuMDM3DQoyNDEsMjAwMSwxMiw2LDE4LDQwLDMuODA3LC0wLjExOA0KMjQyLDIwMDEsMTIsNywyOSwyMDAsNS4zMDksLTAuMDENCjI0MywyMDAxLDEyLDcsMzgsNDQwLDYuMTYsLTAuMDczDQoyNDQsMjAwMSwxMiw3LDUzLDExNjAsNy4yMDgsLTAuMTUyDQoyNDUsMjAwMSwxMiwxMSwzMiwyNjAsNS42MTksLTAuMDU4DQoyNDYsMjAwMSwxMiwxMywxNiwzMCwzLjQzNiwtMC4wMzQNCjI0NywyMDAyLDMsMjAsNzgsNDYzMCw4LjQyNSwwLjAxNQ0KMjQ4LDIwMDIsNSwyMyw2NiwyNTUwLDcuODk5LC0wLjA1NQ0KMjQ5LDIwMDIsNiw3LDQxLDU1MCw2LjM5OSwtMC4wOQ0KMjUwLDIwMDIsNiw3LDI4LDE2MCw1LjE5OCwtMC4xMjMNCjI1MSwyMDAyLDcsMzEsNjUsMjc4MCw3Ljg1MSwwLjA3OQ0KMjUyLDIwMDIsOCw2LDY4LDI5ODAsNy45OTMsMC4wMDcNCjI1MywyMDAyLDgsNyw3NSwzODgwLDguMzAyLC0wLjAzOA0KMjU0LDIwMDIsOCw3LDY2LDIxOTAsNy44OTksLTAuMjA3DQoyNTUsMjAwMiw4LDI3LDU4LDIxMjAsNy40OTIsMC4xNjcNCjI1NiwyMDAyLDgsMjgsNzAsMzA3MCw4LjA4NCwtMC4wNTUNCjI1NywyMDAyLDksMTEsNzYsNDUyMCw4LjM0MywwLjA3Mw0KMjU4LDIwMDIsMTAsMzAsNDcsOTYwLDYuODMsMC4wMzcNCjI1OSwyMDAyLDExLDIsNTcsMTc2MCw3LjQzNywwLjAzNg0KMjYwLDIwMDIsMTEsMTcsMTcsNDAsMy42MjcsMC4wNjINCjI2MSwyMDAyLDEyLDIsMzUsMzQwLDUuOTAxLC0wLjA3Mg0KMjYyLDIwMDIsMTIsMiwzOCw0ODAsNi4xNiwwLjAxNA0KMjYzLDIwMDMsMSw1LDM1LDQwMCw1LjkwMSwwLjA5DQoyNjQsMjAwMywxLDYsNTUsMTM5MCw3LjMyNSwtMC4wODgNCjI2NSwyMDAzLDEsNywzMywzMjAsNS43MTYsMC4wNTMNCjI2NiwyMDAzLDQsMTAsNzcsNDkxMCw4LjM4NSwwLjExNQ0KMjY3LDIwMDMsNCwxMCw2MSwyMDAwLDcuNjUxLC0wLjA1DQoyNjgsMjAwMyw1LDIsNjcsMjk1MCw3Ljk0NiwwLjA0Mw0KMjY5LDIwMDMsNiw4LDUxLDEwODAsNy4wODcsLTAuMTAyDQoyNzAsMjAwMyw3LDI0LDg2LDU2MTAsOC43MzMsLTAuMQ0KMjcxLDIwMDMsOCwyNyw2NCwyNTcwLDcuODAyLDAuMDUNCjI3MiwyMDAzLDgsMjksNjAsMjIwMCw3LjU5OSwwLjA5Nw0KMjczLDIwMDMsOSw5LDQ1LDg3MCw2LjY5MywwLjA3Ng0KMjc0LDIwMDMsOSw5LDQ1LDcyMCw2LjY5MywtMC4xMTMNCjI3NSwyMDAzLDksMTcsNjIsMjU1MCw3LjcwMiwwLjE0Mg0KMjc2LDIwMDMsMTEsMjcsNDYsODkwLDYuNzYyLDAuMDI5DQoyNzcsMjAwMywxMiw5LDM5LDUwMCw2LjI0MiwtMC4wMjcNCjI3OCwyMDAzLDEyLDExLDE4LDQwLDMuODA3LC0wLjExOA0KMjc5LDIwMDMsMTIsMTYsNDEsNjIwLDYuMzk5LDAuMDMNCjI4MCwyMDA0LDEsMTEsMTQsMjAsMy4wMTUsLTAuMDE5DQoyODEsMjAwNCwxLDEzLDM3LDQ0MCw2LjA3NiwwLjAxMQ0KMjgyLDIwMDQsMSwyNCwxNiwzMCwzLjQzNiwtMC4wMzQNCjI4MywyMDA0LDEsMjksNDAsNDgwLDYuMzIyLC0wLjE0OA0KMjg0LDIwMDQsNiwxMywxOSw1MCwzLjk3NywtMC4wNjUNCjI4NSwyMDA0LDYsMjIsNjEsMjQyMCw3LjY1MSwwLjE0MQ0KMjg2LDIwMDQsNywyOCw1OCwyMDAwLDcuNDkyLDAuMTA5DQoyODcsMjAwNCw4LDQsNjEsMjI1MCw3LjY1MSwwLjA2OA0KMjg4LDIwMDQsOCwxNyw1OSwyMzYwLDcuNTQ2LDAuMjIxDQoyODksMjAwNCwxMCwyOCwyNCwxNDAsNC43MTMsMC4yMjkNCjI5MCwyMDA0LDExLDExLDMzLDMyMCw1LjcxNiwwLjA1Mw0KMjkxLDIwMDQsMTEsMTcsNDcsMTA3MCw2LjgzLDAuMTQ2DQoyOTIsMjAwNCwxMiw3LDE3LDQwLDMuNjI3LDAuMDYyDQoyOTMsMjAwNCwxMiw5LDM2LDQ0MCw1Ljk5LDAuMDk3DQoyOTQsMjAwNCwxMiwxMiwxOSw1MCwzLjk3NywtMC4wNjUNCjI5NSwyMDA0LDEyLDEzLDM2LDQzMCw1Ljk5LDAuMDc0DQoyOTYsMjAwNSw2LDIzLDI0LDEyMCw0LjcxMywwLjA3NQ0KMjk3LDIwMDUsNiwyOCwyNiwxNjAsNC45NjUsMC4xMQ0KMjk4LDIwMDUsNywyLDYxLDE4ODAsNy42NTEsLTAuMTEyDQoyOTksMjAwNSw3LDQsNzEsMzQ2MCw4LjEyOSwwLjAyDQozMDAsMjAwNSw3LDIwLDM2LDUxMCw1Ljk5LDAuMjQ1DQozMDEsMjAwNSw3LDIwLDM3LDQ3MCw2LjA3NiwwLjA3Nw0KMzAyLDIwMDUsNywyNyw3NSwzNDEwLDguMzAyLC0wLjE2Nw0KMzAzLDIwMDUsMTEsMywzOCw1NjAsNi4xNiwwLjE2OA0KMzA0LDIwMDUsMTEsOSwyNiwxNTAsNC45NjUsMC4wNDYNCjMwNSwyMDA1LDExLDI0LDM1LDM4MCw1LjkwMSwwLjAzOQ0KMzA2LDIwMDUsMTEsMjcsNDMsNzgwLDYuNTQ5LDAuMTENCjMwNywyMDA1LDExLDI5LDI2LDE1MCw0Ljk2NSwwLjA0Ng0KMzA4LDIwMDUsMTIsMTQsMTUsMzAsMy4yMzIsMC4xNjkNCjMwOSwyMDA2LDEsOCw0Niw5MzAsNi43NjIsMC4wNzMNCjMxMCwyMDA2LDUsMjYsNDYsODAwLDYuNzYyLC0wLjA3Nw0KMzExLDIwMDYsNiwyMiwxMywxMCwyLjc4MiwtMC40NzkNCjMxMiwyMDA2LDYsMjIsMjcsMTgwLDUuMDg0LDAuMTA5DQozMTMsMjAwNiw3LDExLDY4LDI5MjAsNy45OTMsLTAuMDE0DQozMTQsMjAwNiw3LDIwLDU5LDIwODAsNy41NDYsMC4wOTQNCjMxNSwyMDA2LDgsMiw1NSwxODQwLDcuMzI1LDAuMTkzDQozMTYsMjAwNiw4LDcsNjAsMjA5MCw3LjU5OSwwLjA0Ng0KMzE3LDIwMDYsOCw5LDQ4LDk2MCw2Ljg5NiwtMC4wMjkNCjMxOCwyMDA2LDgsMjEsNTQsMTQ1MCw3LjI2NywwLjAxMg0KMzE5LDIwMDYsOSw2LDM4LDU3MCw2LjE2LDAuMTg1DQozMjAsMjAwNiw5LDEzLDQ5LDExNDAsNi45NjEsMC4wNzgNCjMyMSwyMDA2LDExLDYsMjksMjEwLDUuMzA5LDAuMDM4DQozMjIsMjAwNiwxMSw5LDQ0LDY2MCw2LjYyMiwtMC4xMw0KMzIzLDIwMDYsMTEsMTUsNTYsMTUxMCw3LjM4MSwtMC4wNjINCjMyNCwyMDA2LDExLDE3LDUwLDExNDAsNy4wMjUsMC4wMTQNCjMyNSwyMDA2LDEyLDMsMTUsMjAsMy4yMzIsLTAuMjM3DQozMjYsMjAwNiwxMiw5LDE1LDMwLDMuMjMyLDAuMTY5DQozMjcsMjAwNywzLDIsNTQsMTYwMCw3LjI2NywwLjExMQ0KMzI4LDIwMDcsNywxMyw1NiwxODUwLDcuMzgxLDAuMTQxDQozMjksMjAwNyw3LDEzLDU0LDE1OTAsNy4yNjcsMC4xMDUNCjMzMCwyMDA3LDcsMjMsNDUsNjgwLDYuNjkzLC0wLjE3MQ0KMzMxLDIwMDcsNywyMyw1NywxODcwLDcuNDM3LDAuMDk2DQozMzIsMjAwNywxMSwzLDE5LDUwLDMuOTc3LC0wLjA2NQ0KMzMzLDIwMDcsMTEsMTgsMjksMjMwLDUuMzA5LDAuMTI5DQozMzQsMjAwNywxMSwyMywyMCw3MCw0LjEzOSwwLjExDQozMzUsMjAwNywxMSwyOCw4MCw0OTEwLDguNTA1LC0wLjAwNg0KMzM2LDIwMDcsMTEsMzAsMTksNjAsMy45NzcsMC4xMTcNCjMzNywyMDA3LDExLDMwLDI1LDE0MCw0Ljg0MSwwLjENCjMzOCwyMDA3LDExLDMwLDIyLDkwLDQuNDM5LDAuMDYxDQozMzksMjAwNywxMiw4LDU0LDE0NDAsNy4yNjcsMC4wMDUNCjM0MCwyMDA3LDEyLDgsNDEsNjAwLDYuMzk5LC0wLjAwMw0KMzQxLDIwMDcsMTIsOCw0NywxMDMwLDYuODMsMC4xMDgNCjM0MiwyMDA3LDEyLDExLDUzLDE0MjAsNy4yMDgsMC4wNQ0KMzQzLDIwMDcsMTIsMTUsNjMsMjQzMCw3Ljc1MiwwLjA0Mw0KMzQ0LDIwMDcsMTIsMTYsNjQsMjc0MCw3LjgwMiwwLjExNA0KMzQ1LDIwMDcsMTIsMTYsMzcsNDQwLDYuMDc2LDAuMDExDQozNDYsMjAwOCwzLDEsMzIsMzAwLDUuNjE5LDAuMDg1DQozNDcsMjAwOCwzLDMsNTIsMTI2MCw3LjE0OCwtMC4wMDkNCjM0OCwyMDA4LDMsMyw0MCw2MDAsNi4zMjIsMC4wNzUNCjM0OSwyMDA4LDMsNiw0Miw2MzAsNi40NzUsLTAuMDMNCjM1MCwyMDA4LDYsNCwyNiwxNTAsNC45NjUsMC4wNDYNCjM1MSwyMDA4LDcsMiw1OCwxODIwLDcuNDkyLDAuMDE1DQozNTIsMjAwOCw3LDEwLDU4LDIwMzAsNy40OTIsMC4xMjQNCjM1MywyMDA4LDcsMTAsNTYsMTY1MCw3LjM4MSwwLjAyNw0KMzU0LDIwMDgsNywyOCw3OCw0NjAwLDguNDI1LDAuMDA5DQozNTUsMjAwOCw3LDI5LDY2LDI2NDAsNy44OTksLTAuMDINCjM1NiwyMDA4LDExLDExLDE3LDMwLDMuNjI3LC0wLjIyNQ0KMzU3LDIwMDgsMTEsMjEsMjUsMTQwLDQuODQxLDAuMQ0KMzU4LDIwMDgsMTEsMjYsNzEsMzQ3MCw4LjEyOSwwLjAyMw0KMzU5LDIwMDgsMTIsNywyMywxMTAsNC41NzksMC4xMjINCjM2MCwyMDA5LDcsMTAsNzAsMjY2MCw4LjA4NCwtMC4xOTgNCjM2MSwyMDA5LDcsMjEsNjIsMjQwMCw3LjcwMiwwLjA4MQ0KMzYyLDIwMDksNywyMSw3OCwzNzkwLDguNDI1LC0wLjE4NQ0KMzYzLDIwMDksMTEsMjYsMjAsNjAsNC4xMzksLTAuMDQ0DQozNjQsMjAwOSwxMiwxMiw4NCw1NzkwLDguNjU5LDAuMDA1DQozNjUsMjAwOSwxMiwxMiw3MiwzMTEwLDguMTczLC0wLjEzMQ0KMzY2LDIwMTAsNiwxMSwzOCw0NDAsNi4xNiwtMC4wNzMNCjM2NywyMDEwLDYsMTcsMjUsMTUwLDQuODQxLDAuMTY5DQozNjgsMjAxMCw2LDIyLDI5LDE5MCw1LjMwOSwtMC4wNjINCjM2OSwyMDEwLDYsMjMsMjYsMTQwLDQuOTY1LC0wLjAyMw0KMzcwLDIwMTAsNywxMyw2NywyMjkwLDcuOTQ2LC0wLjIxDQozNzEsMjAxMCw3LDI4LDU1LDE2MzAsNy4zMjUsMC4wNzINCjM3MiwyMDEwLDgsMiw3NywzNTcwLDguMzg1LC0wLjIwNA0KMzczLDIwMTAsMTEsNiw1MiwxMTgwLDcuMTQ4LC0wLjA3NQ0KMzc0LDIwMTAsMTEsMTgsMzEsMjkwLDUuNTE5LDAuMTUxDQozNzUsMjAxMCwxMSwyMSwxOSw2MCwzLjk3NywwLjExNw0KMzc2LDIwMTAsMTEsMjUsMjgsMTkwLDUuMTk4LDAuMDQ5DQozNzcsMjAxMCwxMSwyNiw2MywyMjEwLDcuNzUyLC0wLjA1Mg0KMzc4LDIwMTAsMTEsMjgsNTAsMTE0MCw3LjAyNSwwLjAxNA0KMzc5LDIwMTAsMTEsMjgsNTYsMTY0MCw3LjM4MSwwLjAyMQ0KMzgwLDIwMTAsMTEsMjgsMzIsMzMwLDUuNjE5LDAuMTgNCjM4MSwyMDEwLDEyLDUsMzAsMjIwLDUuNDE2LC0wLjAyMg0KMzgyLDIwMTAsMTIsNSw3MywzMzgwLDguMjE2LC0wLjA5MQ0KMzgzLDIwMTAsMTIsNSw2MywyNzYwLDcuNzUyLDAuMTcxDQozODQsMjAxMCwxMiwxNiw0MSw1NzAsNi4zOTksLTAuMDU0DQozODUsMjAxMCwxMiwxOSwxOCw1MCwzLjgwNywwLjEwNQ0KMzg2LDIwMTEsNiw4LDQ4LDg5MCw2Ljg5NiwtMC4xMDUNCjM4NywyMDExLDYsOSwzMCwyMzAsNS40MTYsMC4wMjINCjM4OCwyMDExLDYsMjAsNjIsMTk4MCw3LjcwMiwtMC4xMTENCjM4OSwyMDExLDYsMjEsNDcsOTYwLDYuODMsMC4wMzcNCjM5MCwyMDExLDYsMjIsNDYsODgwLDYuNzYyLDAuMDE4DQozOTEsMjAxMSw3LDEyLDYwLDIxMDAsNy41OTksMC4wNTENCjM5MiwyMDExLDcsMTQsNzgsNDI3MCw4LjQyNSwtMC4wNjYNCjM5MywyMDExLDcsMjcsNjUsMjUwMCw3Ljg1MSwtMC4wMjcNCjM5NCwyMDExLDgsMTgsNzEsMzE3MCw4LjEyOSwtMC4wNjgNCjM5NSwyMDExLDksMTMsNjEsMjI2MCw3LjY1MSwwLjA3Mg0KMzk2LDIwMTEsMTEsMTgsNjgsMzIyMCw3Ljk5MywwLjA4NA0KMzk3LDIwMTEsMTIsOCwyNywxNzAsNS4wODQsMC4wNTINCjM5OCwyMDExLDEyLDExLDcwLDMzNTAsOC4wODQsMC4wMzINCjM5OSwyMDEyLDYsOCw0Niw4MzAsNi43NjIsLTAuMDQNCjQwMCwyMDEyLDYsMTYsMjUsMTYwLDQuODQxLDAuMjM0DQo0MDEsMjAxMiw3LDExLDU1LDEyNjAsNy4zMjUsLTAuMTg2DQo0MDIsMjAxMiw3LDI0LDUyLDE3MjAsNy4xNDgsMC4zMDINCjQwMywyMDEyLDExLDUsNDQsODQwLDYuNjIyLDAuMTExDQo0MDQsMjAxMiwxMSw2LDM3LDQ2MCw2LjA3NiwwLjA1NQ0KNDA1LDIwMTIsMTEsNywyMCw2MCw0LjEzOSwtMC4wNDQNCjQwNiwyMDEyLDExLDE3LDM2LDQzMCw1Ljk5LDAuMDc0DQo0MDcsMjAxMiwxMSwxOSwzNyw1MzAsNi4wNzYsMC4xOTcNCjQwOCwyMDEyLDExLDIyLDQ4LDEwMDAsNi44OTYsMC4wMTINCjQwOSwyMDEyLDExLDI2LDUyLDEyNzAsNy4xNDgsLTAuMDAxDQo0MTAsMjAxMiwxMSwyOSw0Nyw5ODAsNi44MywwLjA1OA0KNDExLDIwMTIsMTIsMiw1MywxNDAwLDcuMjA4LDAuMDM2DQo0MTIsMjAxMiwxMiwzLDk1LDk3OTAsOS4wNDYsMC4xNDMNCjQxMywyMDEyLDEyLDUsMjMsOTAsNC41NzksLTAuMDc5DQo0MTQsMjAxMiwxMiwxNSw2NCwyNTAwLDcuODAyLDAuMDIyDQo0MTUsMjAxMiwxMiwyMCw2NywzMTEwLDcuOTQ2LDAuMDk2DQo0MTYsMjAxMyw2LDE2LDE5LDUwLDMuOTc3LC0wLjA2NQ0KNDE3LDIwMTMsNiwxNyw1OCwxODAwLDcuNDkyLDAuMDA0DQo0MTgsMjAxMyw2LDE5LDQ3LDkyMCw2LjgzLC0wLjAwNQ0KNDE5LDIwMTMsNiwyMCw5Miw5MTYwLDguOTQ1LDAuMTc3DQo0MjAsMjAxMyw3LDIzLDU3LDE5MTAsNy40MzcsMC4xMTgNCjQyMSwyMDEzLDcsMzAsODcsNTQ2MCw4Ljc2OSwtMC4xNjQNCjQyMiwyMDEzLDgsMTYsNzQsNDM4MCw4LjI1OSwwLjEyNQ0KNDIzLDIwMTMsOCwxOSw2MCwyMDEwLDcuNTk5LDAuMDA3DQo0MjQsMjAxMywxMCwyMyw1NCwxNDIwLDcuMjY3LC0wLjAwOQ0KNDI1LDIwMTMsMTAsMjYsNDIsNjIwLDYuNDc1LC0wLjA0Ng0KNDI2LDIwMTMsMTEsMSw1OCwxNzcwLDcuNDkyLC0wLjAxMw0KNDI3LDIwMTMsMTEsMTEsNzMsMjk1MCw4LjIxNiwtMC4yMjcNCjQyOCwyMDEzLDExLDE4LDU4LDE3NTAsNy40OTIsLTAuMDI1DQo0MjksMjAxMywxMSwxOSw1NSwxNjgwLDcuMzI1LDAuMTAyDQo0MzAsMjAxMywxMSwyNSwxOCw0MCwzLjgwNywtMC4xMTgNCjQzMSwyMDEzLDExLDI3LDcyLDM0NTAsOC4xNzMsLTAuMDI3DQo0MzIsMjAxMywxMSwyNyw0NCw3NTAsNi42MjIsLTAuMDAyDQo0MzMsMjAxNCw2LDksMTgsNDAsMy44MDcsLTAuMTE4DQo0MzQsMjAxNCw2LDE4LDMwLDIyMCw1LjQxNiwtMC4wMjINCjQzNSwyMDE0LDcsMTQsNjcsMzI5MCw3Ljk0NiwwLjE1Mg0KNDM2LDIwMTQsNywxNiw2NywyNzEwLDcuOTQ2LC0wLjA0Mg0KNDM3LDIwMTQsOCwxNyw3OCwzNDUwLDguNDI1LC0wLjI3OQ0KNDM4LDIwMTQsOCwyMCw2MywyMjgwLDcuNzUyLC0wLjAyMQ0KNDM5LDIwMTQsOSw5LDY0LDI0NTAsNy44MDIsMC4wMDINCjQ0MCwyMDE0LDEwLDMwLDUxLDEyNjAsNy4wODcsMC4wNTINCjQ0MSwyMDE0LDExLDE0LDUwLDExNzAsNy4wMjUsMC4wNA0KNDQyLDIwMTQsMTEsMTUsNTIsMTQ2MCw3LjE0OCwwLjEzOA0KNDQzLDIwMTQsMTEsMjEsMTYsMzAsMy40MzYsLTAuMDM0DQo0NDQsMjAxNCwxMSwyOCw2MiwxOTcwLDcuNzAyLC0wLjExNg0KNDQ1LDIwMTQsMTEsMjksNzgsNTczMCw4LjQyNSwwLjIyOA0KNDQ2LDIwMTQsMTIsNyw1MiwxMTYwLDcuMTQ4LC0wLjA5Mg0KNDQ3LDIwMTUsMSw5LDQzLDcyMCw2LjU0OSwwLjAzDQo0NDgsMjAxNSwxMCwxMCwzNiw0NDAsNS45OSwwLjA5Nw0KNDQ5LDIwMTUsMTAsMzAsMzYsNDIwLDUuOTksMC4wNQ0KNDUwLDIwMTUsMTEsMiw2NCwyMzcwLDcuODAyLC0wLjAzMQ0KNDUxLDIwMTUsMTEsNSwyNywxNTAsNS4wODQsLTAuMDczDQo0NTIsMjAxNSwxMSw2LDQ4LDEwMjAsNi44OTYsMC4wMzINCjQ1MywyMDE1LDExLDEzLDk1LDk4NTAsOS4wNDYsMC4xNDkNCjQ1NCwyMDE1LDExLDEzLDMwLDIyMCw1LjQxNiwtMC4wMjINCjQ1NSwyMDE1LDExLDE3LDU4LDE5ODAsNy40OTIsMC4wOTkNCjQ1NiwyMDE1LDExLDE4LDc0LDQzNzAsOC4yNTksMC4xMjMNCjQ1NywyMDE1LDExLDIxLDMzLDMwMCw1LjcxNiwtMC4wMTINCjQ1OCwyMDE1LDExLDIzLDQ0LDY2MCw2LjYyMiwtMC4xMw0KNDU5LDIwMTUsMTEsMjgsMzIsMjMwLDUuNjE5LC0wLjE4MQ0KNDYwLDIwMTUsMTEsMzAsNzMsNDQzMCw4LjIxNiwwLjE4DQo0NjEsMjAxNSwxMiw5LDIzLDEwMCw0LjU3OSwwLjAyNg0KNDYyLDIwMTUsMTIsMTAsNjcsMjU2MCw3Ljk0NiwtMC4wOTkNCjQ2MywyMDE2LDUsOSwxMiwxMCwyLjUzLC0wLjIyNw0KNDY0LDIwMTYsNSwxOSwyMSw4MCw0LjI5MiwwLjA5DQo0NjUsMjAxNiw2LDQsMTYsMzAsMy40MzYsLTAuMDM0DQo0NjYsMjAxNiw2LDEwLDY0LDIyNjAsNy44MDIsLTAuMDc5DQo0NjcsMjAxNiw2LDExLDI4LDE3MCw1LjE5OCwtMC4wNjINCjQ2OCwyMDE2LDEwLDI4LDQ5LDk5MCw2Ljk2MSwtMC4wNjMNCjQ2OSwyMDE2LDExLDE0LDMwLDI5MCw1LjQxNiwwLjI1NA0KNDcwLDIwMTYsMTEsMTUsMTYsMzAsMy40MzYsLTAuMDM0DQo0NzEsMjAxNiwxMSwxOCwzNyw0NTAsNi4wNzYsMC4wMzMNCjQ3MiwyMDE2LDExLDIxLDQ2LDgwMCw2Ljc2MiwtMC4wNzcNCjQ3MywyMDE2LDExLDI2LDMzLDMxMCw1LjcxNiwwLjAyMQ0KNDc0LDIwMTYsMTEsMzAsNzIsMzU1MCw4LjE3MywwLjAwMg0KNDc1LDIwMTYsMTIsMiwzMSwyMTAsNS41MTksLTAuMTcyDQo0NzYsMjAxNiwxMiw1LDU4LDE5MDAsNy40OTIsMC4wNTgNCjQ3NywyMDE2LDEyLDExLDM3LDQyMCw2LjA3NiwtMC4wMzYNCjQ3OCwyMDE2LDEyLDE0LDgwLDQwOTAsOC41MDUsLTAuMTg5DQo0NzksMjAxNywxMCwyNywzNiw0NTAsNS45OSwwLjExOQ0KNDgwLDIwMTcsMTEsMiwzOSw1NTAsNi4yNDIsMC4wNjgNCjQ4MSwyMDE3LDExLDMsMzgsNDQwLDYuMTYsLTAuMDczDQo0ODIsMjAxNywxMSw5LDUwLDExMDAsNy4wMjUsLTAuMDIxDQo0ODMsMjAxNywxMSwxMCw1NSwxODAwLDcuMzI1LDAuMTcxDQo0ODQsMjAxNywxMSwxMCw1MiwxMzIwLDcuMTQ4LDAuMDM3DQo0ODUsMjAxNywxMSwxMiwxOSw2MCwzLjk3NywwLjExNw0KNDg2LDIwMTcsMTEsMTQsNTIsMTUxMCw3LjE0OCwwLjE3Mg0KNDg3LDIwMTcsMTEsMTQsNjUsMjc5MCw3Ljg1MSwwLjA4Mw0KNDg4LDIwMTcsMTEsMTQsNDQsODEwLDYuNjIyLDAuMDc1DQo0ODksMjAxNywxMSwxOCw2MywyMTMwLDcuNzUyLC0wLjA4OQ0KNDkwLDIwMTcsMTEsMjUsMjgsMTcwLDUuMTk4LC0wLjA2Mg0KNDkxLDIwMTcsMTEsMjUsNDAsNTYwLDYuMzIyLDAuMDA2DQo0OTIsMjAxOCwxMCw3LDQyLDg4MCw2LjQ3NSwwLjMwNQ0KNDkzLDIwMTgsMTAsMjksNDQsNzIwLDYuNjIyLC0wLjA0Mw0KNDk0LDIwMTgsMTEsMSwyMiw4MCw0LjQzOSwtMC4wNTcNCjQ5NSwyMDE4LDExLDMsNjMsMjI5MCw3Ljc1MiwtMC4wMTYNCjQ5NiwyMDE4LDExLDEwLDI1LDEzMCw0Ljg0MSwwLjAyNg0KNDk3LDIwMTgsMTIsMSw2MiwxODcwLDcuNzAyLC0wLjE2OA0KNDk4LDIwMTgsMTIsMTEsNTEsMTIyMCw3LjA4NywwLjAyDQo0OTksMjAxOCwxMiwxNSw0Nyw5MTAsNi44MywtMC4wMTYNCjUwMCwyMDE4LDEyLDE1LDY5LDMxODAsOC4wMzksMC4wMjYNCg==" download="length-weight_data.csv">length-weight_data.csv</a>`{=html}
).
The sample data includes length and weight data (columns
length
and weight
, respectively) along with
fitted values and residuals from a length-weight regression (columns
called fit
and res
, respectively). The
SharedData
function from crosstalk
package is
also used here to generate a data object that can be “shared” across
independent plots.
Following this chunk of R code is a level 2 markdown header that tells flexdashboard to introduce a column break and place the subsequent components into separate tabs:
Column {.tabset}
-------------------------------------
Following this break, independent tabs are defined using three
hashtags followed by an optional tab name (level 3 markdown header).
This header can be followed by either markdown text or R code. Here, two
tabs are generated with plotly
plots using shared data from
crosstalk
:
### Length-Weight relationship
```{r}
plot_ly(data = shared_lw) %>%
add_markers(x = ~length, y = ~weight, name = "Observed") %>%
add_lines(x = ~length, y = ~exp(fit), name = "Predicted")
```
### Residuals vs. fitted values
```{r}
plot_ly(data = shared_lw) %>%
add_markers(x = ~fit, y = ~res)
```
The native syntax of plotly
was inspired by the grammar
of graphics and, as such, its general structure will be familiar to
those who have used ggplot2
. The package has also been
structured to be pipe (%>%
) and dplyr
friendly, making the code more intuitive and efficient. Though the
script ends with the residual vs. fitted plot, the dashboard can easily
be extended to include other diagnostic plots, such as a histogram of
the residuals.
Once this script is “Knit” (Ctrl+Shift+K
in Rstudio), a
stand-alone html document will be produced with the plots rendered into
independent tabs (shown to the right). Clicking a specific point in one
plot will highlight the corresponding point in the other plot. In short,
flexdashboard
sets up the structure of the document,
plotly
produces the interactive figures and
crosstalk
connects the plots held in independent tabs.
Of course, this is only a rudimentary overview of what is possible
with flexdashboard
, plotly
and
crosstalk
. A wide range of layout options are possible
using flexdashboard
, plotly
can produce more
than just scatter and line plots and crosstalk
can connect
various widgets. See the links provided on the Background page for more details on each package.
The hope here is that this skeleton serves as a starting point from
which to build more elaborate dashboards tailored to specific needs.
The package rmarkdown
enables the writing of
markdown
text and R
code in the same document
(extension .Rmd
). Most R markdown files includes three
types of content:
----
markdown
formatting```
The first step in setting up an R markdown file is to define a YAML header. In the skeleton, it looks like this:
---
title: "flexdashboard + plotly + crosstalk"
output: flexdashboard::flex_dashboard
---
This is where the output type is defined along with other items such
as title, author, date, etc. A flex_dashboard
is requested
here. There are are growing number of output types supported by R
markdown (e.g. html_document
, pdf_document
,
word_document
).
Next, write plain text using markdown syntax to describe how to format the text in the final document.
Plain text
simply translates to Plain text in the
default font of the output document.*italic*
or _italic_
\(\rightarrow\) italic**bold**
or __bold__
\(\rightarrow\) bold**_bold-italic_**
\(\rightarrow\)
bold-italic$W = \alpha L ^{\beta}$
\(\rightarrow\) \(W
= \alpha L ^{\beta}\)1. ordered item 1
\(\rightarrow\) 1. ordered item 1- unordered item
\(\rightarrow\) • unordered item##### Header 5
\(\rightarrow\)
flexdashboard
Finally, mix in R
code by surrounding chunks of code
using one backtick for inline code (e.g.`r 1+1`
will print
2 in the output) or three backticks to run several lines of code and/or
display a table or plot. The chunk below will print the top three rows
of the cars
data-set:
```{r}
head_cars <- head(cars, 3)
head_cars
```
Resulting in the following output:
speed dist
1 4 2
2 4 10
3 7 4
The flexdashboard
package can be used to render groups
of related text, figures and tables into a dashboard. Using a
combination of markdown
syntax and R
code
(i.e. R markdown), this package facilitates a wide range of layout
options and each component can include output from packages such as
plotly
, leaflet
, ggplot2
, and so
on. The package also integrates nicely with shiny
and
crosstalk
, providing options for increasing the
interactivity of the dashboard. Some layout and component options are
highlighted below.
Individual charts are defined using markdown’s level 3 header
(### Chart title
) and they are, by default, stacked
vertically within columns defined using markdown’s level 2 header
(---------
). The code below will create a
flexdashboard
with two stacked columns and three
charts:
---
title: "Layout example 1"
output: flexdashboard::flex_dashboard
---
Column
-------------------------------------
### Chart 1
Column
-------------------------------------
### Chart 2
### Chart 3
The output from this example has been duplicated here.
Alternatively, charts can be organized by row by modifying the YAML header:
---
title: "Layout example 2"
output:
flexdashboard::flex_dashboard:
orientation: rows
---
Row
-------------------------------------
### Chart 1
Row
-------------------------------------
### Chart 2
### Chart 3
The output from this example has been duplicated here.
Also note that multiple pages can be generated using markdown’s level 1 header:
---
title: "Layout example 1"
output: flexdashboard::flex_dashboard
---
Page 1
====================================
Column
-------------------------------------
### Chart 1
Page 2
====================================
Column
-------------------------------------
### Chart 2
### Chart 3
The components of a dashboard can hold a wide range of outputs. The
code below generates a mixture of tabular and graphical output. The
table is generated following markdown
syntax with inline
R
code and the interactive plot is generated using
plotly
.
---
title: "Components example"
output: flexdashboard::flex_dashboard
---
Column {data-width=300}
-------------------------------------
### Table
Summary statistics of the `volcano` data-set
| Statistic | Elevation |
|:------------- |:--------------------------- |
| Min | `r min(volcano)` |
| Median | `r median(volcano)` |
| Mean | `r round(mean(volcano))` |
| Max | `r max(volcano)` |
Column {data-width=700}
-------------------------------------
### Plot
```{r}
plotly::plot_ly(z = volcano, type = "surface")
```
The output from this example has been duplicated here. Note the use of the
data-width
attribute to make the table chart relatively
narrow.
There are two ways to produce interactive graphics using
plotly
:
ggplotly
to convert plots from
ggplot
to plotly
objectsplotly
packageBoth options follow the layered grammar of graphics, which is a generic tool for concisely describing the components of a graphic, such as the:
Using the ggplotly
function, a user can construct a plot
using ggplot2
and supply the plot object to
ggplotly
to convert it to an interactive
plotly
graphic:
library(ggplot2)
<- ggplot(data = iris,
p mapping = aes(x = Sepal.Length,
y = Petal.Length,
color = Species)) +
geom_point() +
scale_color_manual(values = viridis::viridis(3))
::ggplotly(p) plotly
Here, the ggplot
function is used to set-up the base
layer of the plot as well as the aesthetics. That is, iris
data are supplied to the function and specific columns in the
iris
data-set are mapped to x
, y
and color
aesthetics.
Next points are added using the geom_point
function.
Many other geometries can be used to visually represent the data, such
as lines (geom_line
), bars (geom_bar
), text
(geom_text
).
Finally, colors were modified using scale_color_manual
.
While the colors are manually defined here, ggplot2
includes built in color scales such as scale_color_grey
.
Scales used for the x
and y
aesthetics can
also be modified using functions such as scale_x_log10
.
Using functions from the plotly
package,
plotly
plots can be directly created using syntax similar
to ggplot2
:
library(plotly)
plot_ly(data = iris,
x = ~Sepal.Length,
y = ~Petal.Length,
color = ~Species,
colors = viridis::viridis(3)) %>%
add_markers()
The plot_ly
function is analogous to the
ggplot
function from ggplot2
and, like
ggplot
, this function sets-up the base layer of the plot.
Again, the iris
data is supplied and specific columns are
mapped to x
, y
and color
aesthetics.
Under plotly
, geometries are added using functions with
the add_
prefix rather that the geom_
prefix
of used in ggplot2
. Points are added here using
add_markers
and, like ggplot2
, several other
geometries can be specified, such as lines (add_lines
),
bars (add_bars
), text (add_text
).
Unlike ggplot2
, scales are not modified using specific
functions with a scale_
prefix, rather, scales are
specified in the plot_ly
function call itself or via the
layout
function. Here, colors are specified using the
colors
argument in the plot_ly
function.
The crosstalk
package enables HTML widgets, such as
plotly
and leaflet
, to communicate with each
other without shiny
. As such, self-contained html files
with similar behaviour to shiny
applications can be built
using crosstalk
.
A first step to using crosstalk
is to set-up a shared
data-set using the SharedData
function:
library(crosstalk)
<- subset(quakes, stations %in% c(10, 20, 50, 100))
sub_quakes <- SharedData$new(sub_quakes) shared_quakes
The quakes
data is used for this example. As shown to
the right using leaflet
and plotly
, HTML
widgets using this shared data will be linked and selections in one plot
will affect the other plot.
The crosstalk
package also includes a series of
functions for filtering the shared data (filter_checkbox
,
filter_slider
and filter_select
). When used in
a flexdashboard
, and other interactive contexts, the
following lines of code will produce the check-box, slider and drop-down
filters shown below.
filter_checkbox("stations", "Stations", shared_quakes,
~stations, inline = TRUE)
filter_slider("depth", "Depth", shared_quakes, ~depth)
filter_select("mag", "Magnitude", shared_quakes,
~cut(mag, breaks = seq(1, 10, 0.5), right = FALSE))