- Project in github: https://github.com/ctmm-initiative/ctmmweb
- RStudio Cloud project: https://rstudio.cloud/project/196548
- Shinyapps.io app: https://tiny.cc/ctmmweb
- Video tutorials for various parts: https://ctmm-initiative.github.io/ctmmwebdoc/articles/demo.html
This is the easiest way to see how it works.
Some of the videos are created in early stage so there may be slightly differences with current version. - app help website built with pkgdown: https://ctmm-initiative.github.io/ctmmwebdoc/
Intro
ctmmweb is built upon ctmm, an R package for analyzing animal tracking data as a continuous-time stochastic processes. The web app provided a streamlined workflow so general users can upload their own data and get sophisticated analyses result in an interactive interface.
The app is also a package. With ctmmweb package installed, just run ctmmweb::app()
to start the app (you can do this in the RStudio Cloud workspace). Or access the shinyapps.io app.
Highlights on Design
- DT is used extensively for data and selection. Selecting rows in DT table often update plots dynamically.
- All scatter plots can zoom in/out. User can drag brush on histogram and highlight related points in scatter plots.
Please check this feature demo (turn on CC for narration) to see how interactions between DT, plots can facilitate an advanced outlier detection process. - The color theme is consistent across the app, in DT tables and plots.
- Online map can be created with terrain and satellite layers.
- All user actions can be recorded in log messages, and a html report will be compiled so user can reproduce the work.
- User can access Movebank website data directly within the app, using Movebank API.
- The app is also a package, easy to deploy and update.
Highlights on Technical Points
- It's tricky to use DT row selection to trigger updates in other parts, because the table redraw and rendering often make the row selection the slowest update in app, so the other parts often finished rendering before row selection is complete. And there are sometimes row selection become invalid. Extra care must be put in reactive control, additional approaches are used in different cases to prevent problems. These including
req
,freezeReactiveValue
, using reactive expression and value in different time, improve design to reduce problem in timing, etc.
I always wanted to write some blog posts to summarize the problem I met and how I solved them(the very first solution came from Joe Cheng's answer in google groups). - Parallel is used in model fitting, and it works on Mac, Linux and windows. I wrote some code to detect platform and use forked model or cluster accordingly.
- It's difficult to get the error message in hosted app if user need to report a problem. There is an option to turn on error capture in hosted app, then all error and warning message can be captured. Warnings can generate a pop up for user, asking user to check console messages in local mode, check captured message in hosted mode.
Capturing error/warning message seemed to be a difficult problem according to my search. I finally solved the problem. - I packed the app into a package, exposed many features as package functions, so user can use them directly.
- They can also load the app with data as parameter directly like
app(some_data)
. This require some careful design to make sure parameter was captured properly and safely. - In the earlier stages the app is just some R files in github, and user can run the app with
shiny::runGitHub
. I usedpacman
to load and install dependencies in first time. However deployment to shinyapps.io had difficulties to recognize them with pacman, because the underlying packrat only recognizelibrary
and full qualified calls. I forked on packrat (the PR was not taken into packrat) to solve this problem, in case if anybody has similar needs.
- They can also load the app with data as parameter directly like
- I recorded every meaningful user action with a log framework. It was shown in R console with ANSI color. In the end, these messages and all the plots, tables were compiled as RMarkdown then to a html report.
- Shiny modules were used for help button, which have same look in app, always open a markdown file.
Modules are also used in the fine tune UI (model selection page), where a whole sub page is built in pop up window. This feature is used in two stages so module have to be used. It took quite some work in design the abstract layers when module, pop up, my code and back end code have lots of interactions. - The UI are customized when needed.
- notification pop up was moved to center to get user attention.
- Link was disguised as button, by just using button class in css
- Whole page of UI are built inside a pop up window.