diff options
author | Naeem Model <me@nmode.ca> | 2024-05-09 20:22:45 +0000 |
---|---|---|
committer | Naeem Model <me@nmode.ca> | 2024-05-09 20:22:45 +0000 |
commit | dce01ac19a0298388089ce4297a44ef2aa2c4c46 (patch) | |
tree | 1dbc74e9f7e9139f14a517b33a0e3c82c6e04dd0 /inst/app/templates/content | |
parent | e06a56581d43cb3c59d51b9b39e6d0fb36efe31c (diff) |
Revamp Shiny app
Diffstat (limited to 'inst/app/templates/content')
23 files changed, 352 insertions, 0 deletions
diff --git a/inst/app/templates/content/about.html b/inst/app/templates/content/about.html new file mode 100644 index 0000000..aa806d5 --- /dev/null +++ b/inst/app/templates/content/about.html @@ -0,0 +1,27 @@ +<h1>Welcome to the Rnaught web application!</h1> +<p> + Rnaught is an R package and web application for estimating the + <a href="https://en.wikipedia.org/wiki/Basic_reproduction_number" target="_blank">basic reproduction number</a> + of infectious diseases. For information about using this application, view the + <span class="fw-bold text-primary">Help <span class="glyphicon glyphicon-question-sign"></span></span> tab. + To learn more about the package, visit the online + <a href="https://MI2YorkU.github.io/Rnaught" target="_blank">documentation</a> or + <a href="https://github.com/MI2YorkU/Rnaught" target="_blank">GitHub</a> repository. + Technical details about the estimators featured in this project can be found in the reference + <a href="https://doi.org/10.1371/journal.pone.0269306" target="_blank">article</a>. +</p> + +<h4>What is the basic reproduction number?</h4> +<p> + The basic reproduction number, denoted <em>R<sub>0</sub></em>, describes the expected number of infections caused by a + single infectious individual. It assumes that all individuals in a given population are susceptible to the disease, + and that no preventive measures (such as lockdowns or vaccinations) have been enforced. As such, it is a useful + indicator of the transmissibility of a disease during the early stages of its detection. +</p> +<p> + If <em>R<sub>0</sub></em> < 1, then the disease will eventually die out. On the other hand, if + <em>R<sub>0</sub></em> > 1, the rate at which the disease spreads is exponential. Typically, it is difficult to + determine <em>R<sub>0</sub></em> precisely, due to uncertainty in information relating to the spread of the disease. + Therefore, many estimation methods exist, each based on their own models and yielding different estimates. It is the + responsibility of public health officials to employ the most appropriate estimator given the situation at hand. +</p> diff --git a/inst/app/templates/content/data.html b/inst/app/templates/content/data.html new file mode 100644 index 0000000..eaae571 --- /dev/null +++ b/inst/app/templates/content/data.html @@ -0,0 +1,13 @@ +<nav class="nav nav-tabs"> + <a class="nav-link active" data-bs-toggle="tab" href="#enter-data">Enter data</a> + <a class="nav-link" data-bs-toggle="tab" href="#view-data">View data</a> +</nav> + +<div class="container-fluid tab-content"> + <div id="enter-data" class="pt-3 tab-pane fade show active"> + {{ htmlTemplate("templates/content/data/enter-data.html") }} + </div> + <div id="view-data" class="pt-3 tab-pane fade"> + {{ htmlTemplate("templates/content/data/view-data.html") }} + </div> +</div> diff --git a/inst/app/templates/content/data/enter-data.html b/inst/app/templates/content/data/enter-data.html new file mode 100644 index 0000000..621c785 --- /dev/null +++ b/inst/app/templates/content/data/enter-data.html @@ -0,0 +1,13 @@ +<div class="row mb-5"> + <form class="col-md"> + {{ htmlTemplate("templates/content/data/enter-data/single-entry.html") }} + </form> + <div class="col-md mt-5 mt-md-0 d-flex flex-column align-items-center"> + <h5>Data plot</h5> + {{ plotOutput(outputId = "data_plot") }} + </div> +</div> +<hr> +<form> + {{ htmlTemplate("templates/content/data/enter-data/bulk-entry.html") }} +</form> diff --git a/inst/app/templates/content/data/enter-data/bulk-entry.html b/inst/app/templates/content/data/enter-data/bulk-entry.html new file mode 100644 index 0000000..82a3ccf --- /dev/null +++ b/inst/app/templates/content/data/enter-data/bulk-entry.html @@ -0,0 +1,37 @@ +<h4 class="mb-3">Bulk entry</h4> +<!-- Button to toggle help text. --> +<button type="button" class="btn btn-outline-primary btn-sm" id="bulk-help-toggle" + data-bs-toggle="collapse" data-bs-target="#bulk-help"> + Show required format +</button> +<!-- Help text for bulk input format. --> +<div class="collapse mt-2" id="bulk-help"> + <div class="card card-body border-primary"> + <p>Enter one or more rows in the following format:</p> + <p class="overflow-x-scroll text-nowrap font-monospace"> + <u>Dataset name</u>,<u>Time units</u>,<u>Case counts</u> + </p> + <p> + <u class="font-monospace">Time units</u> must be one of + <u class="font-monospace">Days</u> or + <u class="font-monospace">Weeks</u>, and + <u class="font-monospace">Case counts</u> + must be a comma-separated list of one or more non-negative integers. + </p> + <p>Example:</p> + <p class="overflow-x-scroll text-nowrap font-monospace lh-sm"> + Montreal,Days,1,2,3,4,5,6,7,8,9,19<br> + Ottawa,Weeks,1,2,3,4,5,6,7,8,9,19<br> + Toronto,Days,1,2,3,4,5,6,7,8,9,19 + </p> + </div> +</div> +<!-- Data input area. --> +<div> + <textarea id="data_area" class="form-control shiny-input-textarea my-3" rows="3" wrap="off"></textarea> + <small id="data_area_warn" class="form-text text-primary shiny-html-output"></small> +</div> +<!-- Submit data. --> +<button id="data_bulk" type="button" class="btn btn-outline-primary btn-sm action-button"> + <span class="glyphicon glyphicon-plus"></span> Add +</button> diff --git a/inst/app/templates/content/data/enter-data/single-entry.html b/inst/app/templates/content/data/enter-data/single-entry.html new file mode 100644 index 0000000..9f249d9 --- /dev/null +++ b/inst/app/templates/content/data/enter-data/single-entry.html @@ -0,0 +1,39 @@ +<h4>Single entry</h4> +<!-- Dataset name. --> +<div class="my-3"> + <label class="form-label" for="data_name">Dataset name</label> + <input name="data_name" class="form-control" type="text"> + <small id="data_name_warn" class="form-text text-primary shiny-text-output"></small> +</div> +<!-- Case counts. --> +<div class="mb-3"> + <label class="form-label" for="data_counts"> + Case counts + <sup data-bs-toggle="tooltip" data-bs-placement="right" + data-bs-title="Enter as a comma-separated list of non-negative integers (example: 0,1,1,2,3,5,8,13)."> + [?] + </sup> + </label> + <input name="data_counts" class="form-control" type="text"> + <small id="data_counts_warn" class="form-text text-primary shiny-text-output"></small> +</div> +<!-- Time units. --> +<div class="mb-3"> + <label class="form-label" for="data_units">Time units</label> + <div class="shiny-input-radiogroup" id="data_units"> + <div class="form-check form-check-inline"> + <label class="form-check-label"> + <input type="radio" class="form-check-input me-2" name="data_units" value="Days">Days + </label> + </div> + <div class="form-check form-check-inline"> + <label class="form-check-label"> + <input type="radio" class="form-check-input me-2" name="data_units" value="Weeks" checked>Weeks + </label> + </div> + </div> +</div> +<!-- Submit data. --> +<button id="data_single" type="button" class="btn btn-outline-primary btn-sm action-button"> + <span class="glyphicon glyphicon-plus"></span> Add +</button> diff --git a/inst/app/templates/content/data/view-data.html b/inst/app/templates/content/data/view-data.html new file mode 100644 index 0000000..52f1e85 --- /dev/null +++ b/inst/app/templates/content/data/view-data.html @@ -0,0 +1,19 @@ +<h4>Data table</h4> +<!-- Data table. --> +<div class="my-3"> + {{ DT::dataTableOutput(outputId = "data_table") }} +</div> +<!-- Display inactive delete button when no rows are selected. --> +<button type="button" class="btn btn-primary btn-sm text-white" disabled + data-display-if="'data_table_rows_selected' in input && input.data_table_rows_selected.length == 0"> + <span class="glyphicon glyphicon-remove"></span> Delete row(s) +</button> +<!-- Display active delete button when at least one row is selected. --> +<button id="data_delete" type="button" class="btn btn-primary btn-sm action-button text-white" + data-display-if="'data_table_rows_selected' in input && input.data_table_rows_selected.length != 0"> + <span class="glyphicon glyphicon-remove"></span> Delete row(s) +</button> +<!-- Button to export data table as a CSV file. --> +<a id="data_export" type="button" class="btn btn-outline-primary btn-sm shiny-download-link"> + <span class="glyphicon glyphicon-download-alt"></span> Export table +</a> diff --git a/inst/app/templates/content/estimators.html b/inst/app/templates/content/estimators.html new file mode 100644 index 0000000..e664ad2 --- /dev/null +++ b/inst/app/templates/content/estimators.html @@ -0,0 +1,13 @@ +<nav class="nav nav-tabs"> + <a class="nav-link active" data-bs-toggle="tab" href="#add-estimators">Add estimators</a> + <a class="nav-link" data-bs-toggle="tab" href="#view-estimates">View estimates</a> +</nav> + +<div class="container-fluid tab-content"> + <div id="add-estimators" class="pt-3 tab-pane fade show active"> + {{ htmlTemplate("templates/content/estimators/add-estimators.html") }} + </div> + <div id="view-estimates" class="pt-3 tab-pane fade"> + {{ htmlTemplate("templates/content/estimators/view-estimates.html") }} + </div> +</div> diff --git a/inst/app/templates/content/estimators/add-estimators.html b/inst/app/templates/content/estimators/add-estimators.html new file mode 100644 index 0000000..dce2dae --- /dev/null +++ b/inst/app/templates/content/estimators/add-estimators.html @@ -0,0 +1,34 @@ +<div class="accordion accordion-flush" id="estimators-accordion"> + {{ + htmlTemplate("templates/content/estimators/add-estimators/components/panel.html", + id = "id", + header = "Incidence Decay (ID)", + reference_label = "Fisman et al. (PloS One, 2013)", + reference_url = "https://doi.org/10.1371/journal.pone.0083622" + ) + }} + {{ + htmlTemplate("templates/content/estimators/add-estimators/components/panel.html", + id = "idea", + header = "Incidence Decay and Exponential Adjustment (IDEA)", + reference_label = "Fisman et al. (PloS One, 2013)", + reference_url = "https://doi.org/10.1371/journal.pone.0083622" + ) + }} + {{ + htmlTemplate("templates/content/estimators/add-estimators/components/panel.html", + id = "seq_bayes", + header = "Sequential Bayes (seqB)", + reference_label = "Bettencourt and Riberio (PloS One, 2008)", + reference_url = "https://doi.org/10.1371/journal.pone.0002185" + ) + }} + {{ + htmlTemplate("templates/content/estimators/add-estimators/components/panel.html", + id = "wp", + header = "White and Pagano (WP)", + reference_label = "White and Pagano (Statistics in Medicine, 2008)", + reference_url = "https://doi.org/10.1002/sim.3136" + ) + }} +</div> diff --git a/inst/app/templates/content/estimators/add-estimators/components/mu.html b/inst/app/templates/content/estimators/add-estimators/components/mu.html new file mode 100644 index 0000000..f25a1c8 --- /dev/null +++ b/inst/app/templates/content/estimators/add-estimators/components/mu.html @@ -0,0 +1,20 @@ +<!-- Serial interval label and help tooltip. --> +<label class="form-label" for="mu_{{ id }}"> + Serial interval (μ) + <sup data-bs-toggle="tooltip" data-bs-placement="right" + data-bs-title="The serial interval is the time between when an infected individual (the infector) becomes + symptomatic, to when another individual (who is infected by the infector) becomes symptomatic."> + [?] + </sup> +</label> +<div class="input-group"> + <!-- Serial interval input field. --> + <input name="mu_{{ id }}" class="form-control" type="text"> + <!-- Days/weeks dropdown. --> + <select name="mu_{{ id }}_units" class="form-select"> + <option value="Days" selected>Days</option> + <option value="Weeks">Weeks</option> + </select> +</div> +<!-- Warning text for incorrect values. --> +<small id="mu_{{ id }}_warn" class="form-text text-primary shiny-text-output"></small> diff --git a/inst/app/templates/content/estimators/add-estimators/components/panel.html b/inst/app/templates/content/estimators/add-estimators/components/panel.html new file mode 100644 index 0000000..b1e0378 --- /dev/null +++ b/inst/app/templates/content/estimators/add-estimators/components/panel.html @@ -0,0 +1,21 @@ +<div class="accordion-item"> + <h2 class="accordion-header"> + <button class="accordion-button collapsed" type="button" + data-bs-toggle="collapse" data-bs-target="#{{ id }}"> + <h4>{{ header }}</h4> + </button> + </h2> + <div id="{{ id }}" class="accordion-collapse collapse" data-bs-parent="#estimators-accordion"> + <div class="accordion-body"> + <p>Reference: <a href="{{ reference_url }}" target="_blank"><em>{{ reference_label }}</em></a></p> + <p>{{ htmlTemplate(paste0("templates/content/estimators/add-estimators/descriptions/", id, ".html")) }}</p> + <h5>Parameters</h5> + <form class="my-3"> + {{ htmlTemplate(paste0("templates/content/estimators/add-estimators/parameters/", id, ".html")) }} + </form> + <button id="add_{{ id }}" type="button" class="btn btn-outline-primary btn-sm action-button"> + <span class="glyphicon glyphicon-plus"></span> Add + </button> + </div> + </div> +</div> diff --git a/inst/app/templates/content/estimators/add-estimators/descriptions/id.html b/inst/app/templates/content/estimators/add-estimators/descriptions/id.html new file mode 100644 index 0000000..b182ae5 --- /dev/null +++ b/inst/app/templates/content/estimators/add-estimators/descriptions/id.html @@ -0,0 +1 @@ +This is a short description of the ID method. diff --git a/inst/app/templates/content/estimators/add-estimators/descriptions/idea.html b/inst/app/templates/content/estimators/add-estimators/descriptions/idea.html new file mode 100644 index 0000000..edfbb79 --- /dev/null +++ b/inst/app/templates/content/estimators/add-estimators/descriptions/idea.html @@ -0,0 +1 @@ +This is a short description of the IDEA method. diff --git a/inst/app/templates/content/estimators/add-estimators/descriptions/seq_bayes.html b/inst/app/templates/content/estimators/add-estimators/descriptions/seq_bayes.html new file mode 100644 index 0000000..f6df3ee --- /dev/null +++ b/inst/app/templates/content/estimators/add-estimators/descriptions/seq_bayes.html @@ -0,0 +1 @@ +This is a short description of the seqB method. diff --git a/inst/app/templates/content/estimators/add-estimators/descriptions/wp.html b/inst/app/templates/content/estimators/add-estimators/descriptions/wp.html new file mode 100644 index 0000000..640b44d --- /dev/null +++ b/inst/app/templates/content/estimators/add-estimators/descriptions/wp.html @@ -0,0 +1 @@ +This is a short description of the WP method. diff --git a/inst/app/templates/content/estimators/add-estimators/parameters/id.html b/inst/app/templates/content/estimators/add-estimators/parameters/id.html new file mode 100644 index 0000000..a3159ca --- /dev/null +++ b/inst/app/templates/content/estimators/add-estimators/parameters/id.html @@ -0,0 +1 @@ +{{ htmlTemplate("templates/content/estimators/add-estimators/components/mu.html", id = "id") }} diff --git a/inst/app/templates/content/estimators/add-estimators/parameters/idea.html b/inst/app/templates/content/estimators/add-estimators/parameters/idea.html new file mode 100644 index 0000000..379be84 --- /dev/null +++ b/inst/app/templates/content/estimators/add-estimators/parameters/idea.html @@ -0,0 +1 @@ +{{ htmlTemplate("templates/content/estimators/add-estimators/components/mu.html", id = "idea") }} diff --git a/inst/app/templates/content/estimators/add-estimators/parameters/seq_bayes.html b/inst/app/templates/content/estimators/add-estimators/parameters/seq_bayes.html new file mode 100644 index 0000000..bcc82b7 --- /dev/null +++ b/inst/app/templates/content/estimators/add-estimators/parameters/seq_bayes.html @@ -0,0 +1,22 @@ +<div class="row"> + <!-- Serial interval (mu). --> + <div class="col-md"> + {{ htmlTemplate("templates/content/estimators/add-estimators/components/mu.html", id = "seq_bayes") }} + </div> + <!-- Maximum value of the uniform prior (kappa). --> + <div class="col-md mt-2 mt-md-0"> + <!-- Label and help tooltip. --> + <label class="form-label" for="kappa"> + Maximum prior (κ) + <sup data-bs-toggle="tooltip" data-bs-placement="right" data-bs-html="true" + data-bs-title="The initial maximum belief of <em>R<sub>0</sub></em>. The higher this value, the higher + <em>R<sub>0</sub></em> is believed to be prior to the estimation."> + [?] + </sup> + </label> + <!-- Input field. --> + <input name="kappa" class="form-control" type="text" placeholder="Default: 20"> + <!-- Warning text for incorrect values. --> + <small id="kappa_warn" class="form-text text-primary shiny-text-output"></small> + </div> +</div> diff --git a/inst/app/templates/content/estimators/add-estimators/parameters/wp.html b/inst/app/templates/content/estimators/add-estimators/parameters/wp.html new file mode 100644 index 0000000..b789a23 --- /dev/null +++ b/inst/app/templates/content/estimators/add-estimators/parameters/wp.html @@ -0,0 +1,39 @@ +<!-- Radio buttons to specify whether the serial interval is known. --> +<label class="form-label" for="wp_mu_known">Is the serial interval known?</label> +<div class="shiny-input-radiogroup" id="wp_mu_known"> + <div class="form-check form-check-inline"> + <label class="form-check-label"> + <input type="radio" class="form-check-input me-2" name="wp_mu_known" value="Yes" checked>Yes + </label> + </div> + <div class="form-check form-check-inline"> + <label class="form-check-label"> + <input type="radio" class="form-check-input me-2" name="wp_mu_known" value="No">No + </label> + </div> +</div> +<!-- Show the input field for the serial interval if it is known. --> +<div data-display-if="input.wp_mu_known == 'Yes'" class="mt-2 mt-md-0"> + {{ htmlTemplate("templates/content/estimators/add-estimators/components/mu.html", id = "wp") }} +</div> +<!-- Show the input fields for the grid search parameters if the serial interval is unknown. --> +<div data-display-if="input.wp_mu_known == 'No'" class="row"> + <!-- Grid length. --> + <div class="col-md mt-2 mt-md-0"> + <label class="form-label" for="grid_length">Grid length</label> + <input name="grid_length" class="form-control" type="text" placeholder="Default: 100"> + <small id="grid_length_warn" class="form-text text-primary shiny-text-output"></small> + </div> + <!-- Maximum shape. --> + <div class="col-md mt-2 mt-md-0"> + <label class="form-label" for="max_shape">Maximum shape</label> + <input name="max_shape" class="form-control" type="text" placeholder="Default: 10"> + <small id="max_shape_warn" class="form-text text-primary shiny-text-output"></small> + </div> + <!-- Grid length. --> + <div class="col-md mt-2 mt-md-0"> + <label class="form-label" for="max_scale">Maximum scale</label> + <input name="max_scale" class="form-control" type="text" placeholder="Default: 10"> + <small id="max_scale_warn" class="form-text text-primary shiny-text-output"></small> + </div> +</div> diff --git a/inst/app/templates/content/estimators/view-estimates.html b/inst/app/templates/content/estimators/view-estimates.html new file mode 100644 index 0000000..e81fff6 --- /dev/null +++ b/inst/app/templates/content/estimators/view-estimates.html @@ -0,0 +1,21 @@ +<h4>Estimates table</h4> +<!-- Estimates table. --> +<div class="my-3"> + {{ DT::dataTableOutput(outputId = "estimates_table") }} +</div> +<!-- Display inactive delete button when no columns are selected. --> +<button type="button" class="btn btn-primary btn-sm text-white" disabled + data-display-if="'estimates_table_columns_selected' in input && + input.estimates_table_columns_selected.length == 0"> + <span class="glyphicon glyphicon-remove"></span> Delete column(s) +</button> +<!-- Display active delete button when at least one column is selected. --> +<button id="estimators_delete" type="button" class="btn btn-primary btn-sm action-button text-white" + data-display-if="'estimates_table_columns_selected' in input && + input.estimates_table_columns_selected.length != 0"> + <span class="glyphicon glyphicon-remove"></span> Delete column(s) +</button> +<!-- Button to export estimates table as a CSV file. --> +<a id="estimates_export" type="button" class="btn btn-outline-primary btn-sm shiny-download-link"> + <span class="glyphicon glyphicon-download-alt"></span> Export table +</a> diff --git a/inst/app/templates/content/help.html b/inst/app/templates/content/help.html new file mode 100644 index 0000000..388afb1 --- /dev/null +++ b/inst/app/templates/content/help.html @@ -0,0 +1,14 @@ +<div class="accordion accordion-flush" id="help-accordion"> + {{ + htmlTemplate("templates/content/help/panel.html", + id = "example-help-1", + header = "Example help 1" + ) + }} + {{ + htmlTemplate("templates/content/help/panel.html", + id = "example-help-2", + header = "Example help 2" + ) + }} +</div> diff --git a/inst/app/templates/content/help/example-help-1.html b/inst/app/templates/content/help/example-help-1.html new file mode 100644 index 0000000..245b9b6 --- /dev/null +++ b/inst/app/templates/content/help/example-help-1.html @@ -0,0 +1 @@ +Example help 1 diff --git a/inst/app/templates/content/help/example-help-2.html b/inst/app/templates/content/help/example-help-2.html new file mode 100644 index 0000000..a4817b5 --- /dev/null +++ b/inst/app/templates/content/help/example-help-2.html @@ -0,0 +1 @@ +Example help 2 diff --git a/inst/app/templates/content/help/panel.html b/inst/app/templates/content/help/panel.html new file mode 100644 index 0000000..9eb6e2e --- /dev/null +++ b/inst/app/templates/content/help/panel.html @@ -0,0 +1,12 @@ +<div class="accordion-item"> + <h2 class="accordion-header"> + <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#{{ id }}"> + {{ header }} + </button> + </h2> + <div id="{{ id }}" class="accordion-collapse collapse" data-bs-parent="#help-accordion"> + <div class="accordion-body"> + {{ htmlTemplate(paste0("templates/content/help/", id, ".html")) }} + </div> + </div> +</div> |