#' Generates a pie plot (donut) that visualizes the relation between actually received and targeted number of submissions.
#'
#' The pie plot this function creates is generated by comparing the number of received submissions with the number of targeted submissions.
#' The target is calculated by multiplying the number-of-submissions goal per day times the number of days the data collection has been ongoing.
#' The number of days are determined using the function \code{\link{collection_period}}
#' If the targeted number of submissions has been exceeded the plot is all green and additionally provides the info by how many submissions the target number was exceeded.
#' Please note, that one and only one of the three data arguments (df, csv, svc) must be specified.
#'
#' @param df Data frame containing the ODK data that is to be used. Optional, defaults to NULL.
#' @param csv Character that specifies the path to the csv file that is to be read. Optional, defaults to NULL.
#' @param svc Logical that indicates whether the data shall be parsed using ruODK's \code{\link[ruODK]{odata_submission_get}}. Optional, defaults to FALSE.
#' @param daily_submission_goal Integer or float that reflects the targeted number of daily submissions.
#' @param date_col String that specifies the date or time stamp column in the data which is to be examined.
#' @param exclude_wday Integer (for one day) or integer vector (for multiple days) containing the day(s) of the week that shall not be included when generating the plot, defaults to NULL. Specify the days as following: 1 = Sun, 2 = Mon, ..., 7 = Sun.
#'
#' @return Plotly html-widget
#'
#' @import plotly lubridate
#' @export
#'
#' @examples
#' \dontrun{
#' # 1. with SVC
#' # ruODK needs to be set up for this function to work
#' repvisforODK::setup_ruODK(svc = 'example/svc.svc', un = 'exampleusername', pw = 'examplepassword', tz = 'Europe/Berlin', verbose = TRUE)
#'
#' submission_goal_donut(svc = TRUE, daily_submission_goal = 4, date_col = 'start', exclude_wday = c(1, 7))
#'
#' # 2. with data frame
#' submission_goal_donut(df = df_odk_data, daily_submission_goal = 4, date_col = 'start', exclude_wday = c(1, 7))
#'
#' # 3. with csv
#' submission_goal_donut(csv = 'example/file/odk_data.csv', daily_submission_goal = 4, date_col = 'start', exclude_wday = c(1, 7))
#' }
submission_goal_donut <- function(df = NULL, csv = NULL, svc = FALSE, daily_submission_goal, date_col, exclude_wday = NULL){
# loading and manipulating data-------------------------------------------------------------------------------------------------------------------------------
df <- repvisforODK::check_data_args(df, csv, svc)
# stop if daily submission goal is negative
if (daily_submission_goal < 0) {
stop("The argument daily_submission_goal has to be defined as a positive integer or float.")
}
if (daily_submission_goal == 0) {
warning("The argument daily_submission_goal is set to 0.")
}
# finding min and max date of the collection period
date_limits = repvisforODK::collection_period(df = df, date_col = date_col)
# calculating number of days of data collection period
all_wdays_in_period <- lubridate::wday(seq.Date(date_limits[[1]], date_limits[[2]], 'days'), abbr = TRUE)
# first w/o excluded wdays
if (!is.null(exclude_wday)) {
# get all dates of data collection period
all_wdays_in_period <- all_wdays_in_period[!all_wdays_in_period %in% exclude_wday]
df$wday <- lubridate::wday(df[[date_col]], abbr = T)
}
submission_goal_total = length(all_wdays_in_period)*daily_submission_goal
submissions_total = nrow(df[!df$wday %in% exclude_wday, ])
submission_goal_deviation = submission_goal_total - submissions_total
# plotting----------------------------------------------------------------------------------------------------------------------------------------------------
# plot used when sub goal is > 0
if (submission_goal_deviation > 0){
fig <- plotly::plot_ly(type='pie',
labels=c('Received', 'Missing'),
values=c(submissions_total, submission_goal_deviation),
textinfo='label+percent',
marker=list(colors=c(repvisforODK::set_color('green'), repvisforODK::set_color('red'))),
hole=0.4)
fig <- fig %>% plotly::layout(xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE, title='Test'),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
# plot used when sub goal is <= 0
} else{
fig <- plotly::plot_ly(type='pie',
labels=c('Received'),
values=c(submissions_total),
textinfo='label+percent',
marker=list(colors=c(repvisforODK::set_color('green'), repvisforODK::set_color('red'))),
hole=0.4)
fig <- fig %>% plotly::layout(xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE, title='Test'),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
annotations=list(x=0.66, y=0.5,
xanchor='right',
showarrow=F,
font=list(color = repvisforODK::set_color('yellow')),
text=paste0('Target exceeded by: <br>',
round(abs(submission_goal_deviation), 0),
' submissions (',
round(abs(submission_goal_deviation)/submission_goal_total*100, 1),
' %)')))
}
# adding title to the html widget
title <- paste0('Total number of submissions: Received vs. Missing to Target (', date_limits[[2]], ')')
fig <- repvisforODK::add_html_title_tag(fig, title)
return(fig)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.