From c584f19dbc0b539da503c5683504d32f35d0f787 Mon Sep 17 00:00:00 2001 From: Colin Diesh Date: Thu, 13 Jul 2023 17:28:33 -0400 Subject: [PATCH] Deploy demos to shinyapps.io (#24) * Move files around * Consolidate some demos --- README.Rmd | 38 ++- README.md | 83 ++++-- example_apps/.gitignore | 1 + example_apps/README.md | 21 ++ example_apps/app.R | 15 - .../app.R} | 9 +- example_apps/bookmark_app.R | 54 ---- example_apps/bookmarks_demo/README.md | 16 ++ example_apps/bookmarks_demo/app.R | 270 ++++++++++++++++++ example_apps/custom_app.R | 70 ----- .../{json_app.R => load_config_json/app.R} | 3 + .../{ => load_config_json}/config.json | 0 .../{df_app.R => load_data_frame/app.R} | 3 + .../app.R} | 3 + 14 files changed, 417 insertions(+), 169 deletions(-) create mode 100644 example_apps/.gitignore create mode 100644 example_apps/README.md delete mode 100644 example_apps/app.R rename example_apps/{hg38_index_app.R => basic_usage_with_text_index/app.R} (76%) delete mode 100644 example_apps/bookmark_app.R create mode 100644 example_apps/bookmarks_demo/README.md create mode 100644 example_apps/bookmarks_demo/app.R delete mode 100644 example_apps/custom_app.R rename example_apps/{json_app.R => load_config_json/app.R} (75%) rename example_apps/{ => load_config_json}/config.json (100%) rename example_apps/{df_app.R => load_data_frame/app.R} (89%) rename example_apps/{skbr3_fusions.R => skbr3_gene_fusions/app.R} (92%) diff --git a/README.Rmd b/README.Rmd index f0c1760..3e41135 100644 --- a/README.Rmd +++ b/README.Rmd @@ -27,7 +27,6 @@ Using JBrowseR, you can: - Deploy a genome browser directly from the R console to view your data - Customize your genome browser to display your own data -With this functionality, you can deploy a first-class genome browser with your data in just a few lines of R code! ## Installation @@ -49,8 +48,7 @@ This line of code can be used to launch a genome browser from your R console: ```{r example, eval=FALSE} library(JBrowseR) -JBrowseR("ViewHg19", - location = "10:29,838,737..29,838,819") +JBrowseR("ViewHg19", location = "10:29,838,737..29,838,819") ``` @@ -64,6 +62,40 @@ In order to get started with JBrowseR, please refer to the vignette that best su - [JSON configuration tutorial](https://gmod.github.io/JBrowseR/articles/json-tutorial.html) - [Creating URLS](https://gmod.github.io/JBrowseR/articles/creating-urls.html) +## Live demos + + +### Basic usage including text search index + +Allows you to search by gene name + +https://gmod.shinyapps.io/basic_usage_with_text_index + +### Multi purpose demo app + +Shows a "bookmark" type feature, loading data from data frame, and buttons to navigate to genes of interest + +https://gmod.shinyapps.io/bookmarks_demo + +### Load config.json file + +Shows loading a config.json file + +https://gmod.shinyapps.io/load_config_json + +### Load data frame + +Simple example showing a data frame as a track + +https://gmod.shinyapps.io/load_data_frame + +### Gene fusion example + +Shows putative gene fusions in the SKBR3 breast cancer cell line + +https://gmod.shinyapps.io/skbr3_gene_fusions + + ## Citation If you use JBrowseR in your research, please cite the following publication: diff --git a/README.md b/README.md index c0552e8..87cf148 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,94 @@ +--- +output: github_document +--- + + + # JBrowseR - [![R-CMD-check](https://github.com/GMOD/JBrowseR/workflows/R-CMD-check/badge.svg)](https://github.com/gmod/JBrowseR/actions) -[![CRAN -status](https://www.r-pkg.org/badges/version/JBrowseR)](https://CRAN.R-project.org/package=JBrowseR) - +[![CRAN status](https://www.r-pkg.org/badges/version/JBrowseR)](https://CRAN.R-project.org/package=JBrowseR) -JBrowseR is an R package that provides a simple and clean interface to -[JBrowse 2](https://jbrowse.org/jb2/) for R users. Using JBrowseR, you can: +JBrowseR is an R package that provides a simple and clean interface to [JBrowse 2](https://jbrowse.org/jb2/) for R users. +Using JBrowseR, you can: -- Embed the JBrowse 2 genome browser in **R Markdown** documents and **Shiny - applications** +- Embed the JBrowse 2 genome browser in **R Markdown** documents and **Shiny applications** - Deploy a genome browser directly from the R console to view your data - Customize your genome browser to display your own data -With this functionality, you can deploy a first-class genome browser with your -data in just a few lines of R code! ## Installation -You can install the released version of JBrowseR from -[CRAN](https://CRAN.R-project.org) with: +You can install the released version of JBrowseR from [CRAN](https://CRAN.R-project.org) with: -```r +``` r install.packages("JBrowseR") ``` And the development version from [GitHub](https://github.com/) with: -```r +``` r # install.packages("devtools") devtools::install_github("gmod/JBrowseR") ``` - ## Example This line of code can be used to launch a genome browser from your R console: + ```r library(JBrowseR) -JBrowseR("ViewHg19", - location = "10:29,838,737..29,838,819") +JBrowseR("ViewHg19", location = "10:29,838,737..29,838,819") ``` ## Getting started -In order to get started with JBrowseR, please refer to the vignette that best -suits your needs: +In order to get started with JBrowseR, please refer to the vignette that best suits your needs: - [Introduction](https://gmod.github.io/JBrowseR/articles/JBrowseR.html) - [Custom browser tutorial](https://gmod.github.io/JBrowseR/articles/custom-browser-tutorial.html) - [JSON configuration tutorial](https://gmod.github.io/JBrowseR/articles/json-tutorial.html) -- [Creating URLs](https://gmod.github.io/JBrowseR/articles/creating-urls.html) +- [Creating URLS](https://gmod.github.io/JBrowseR/articles/creating-urls.html) + +## Live demos + + +### Basic usage including text search index + +Allows you to search by gene name + +https://gmod.shinyapps.io/basic_usage_with_text_index + +### Multi purpose demo app + +Shows a "bookmark" type feature, loading data from data frame, and buttons to navigate to genes of interest + +https://gmod.shinyapps.io/bookmarks_demo + +### Load config.json file + +Shows loading a config.json file + +https://gmod.shinyapps.io/load_config_json + +### Load data frame + +Simple example showing a data frame as a track + +https://gmod.shinyapps.io/load_data_frame + +### Gene fusion example + +Shows putative gene fusions in the SKBR3 breast cancer cell line + +https://gmod.shinyapps.io/skbr3_gene_fusions + ## Citation @@ -65,8 +96,10 @@ If you use JBrowseR in your research, please cite the following publication: [Hershberg et al., 2021. JBrowseR: An R Interface to the JBrowse 2 Genome Browser](https://doi.org/10.1093/bioinformatics/btab459) - @article{hershberg2021jbrowser, - title={JBrowseR: An R Interface to the JBrowse 2 Genome Browser}, - author={Hershberg, Elliot A and Stevens, Garrett and Diesh, Colin and Xie, Peter and De Jesus Martinez, Teresa and Buels, Robert and Stein, Lincoln and Holmes, Ian}, - journal={Bioinformatics} - } +``` +@article{hershberg2021jbrowser, + title={JBrowseR: An R Interface to the JBrowse 2 Genome Browser}, + author={Hershberg, Elliot A and Stevens, Garrett and Diesh, Colin and Xie, Peter and De Jesus Martinez, Teresa and Buels, Robert and Stein, Lincoln and Holmes, Ian}, + journal={Bioinformatics} +} +``` diff --git a/example_apps/.gitignore b/example_apps/.gitignore new file mode 100644 index 0000000..ae1b5cf --- /dev/null +++ b/example_apps/.gitignore @@ -0,0 +1 @@ +*.dcf diff --git a/example_apps/README.md b/example_apps/README.md new file mode 100644 index 0000000..edfba1c --- /dev/null +++ b/example_apps/README.md @@ -0,0 +1,21 @@ +## Install deps + +```R + +install.packages(c('JBrowseR','crosstalk','DT')) +``` + +### Deploy + +```R +deployApp('example_apps/basic_usage_with_text_index',account='gmod') +deployApp('example_apps/bookmarks_demo',account='gmod') +deployApp('example_apps/load_config_json',account='gmod') +deployApp('example_apps/load_data_frame',account='gmod') +deployApp('example_apps/skbr3_gene_fusions',account='gmod') + +``` + +Regex to generate above list of commands + +'<,'>s/^\(.\*\)/deployApp('example_apps\/\1',account='gmod') diff --git a/example_apps/app.R b/example_apps/app.R deleted file mode 100644 index a676d53..0000000 --- a/example_apps/app.R +++ /dev/null @@ -1,15 +0,0 @@ -library(shiny) -library(JBrowseR) - -ui <- fluidPage( - titlePanel("JBrowseR Example"), - JBrowseROutput("widgetOutput") -) - -server <- function(input, output, session) { - output$widgetOutput <- renderJBrowseR(JBrowseR("ViewHg19", - location = "10:29,838,737..29,838,819" - )) -} - -shinyApp(ui, server) diff --git a/example_apps/hg38_index_app.R b/example_apps/basic_usage_with_text_index/app.R similarity index 76% rename from example_apps/hg38_index_app.R rename to example_apps/basic_usage_with_text_index/app.R index abb8a65..37fcb0c 100644 --- a/example_apps/hg38_index_app.R +++ b/example_apps/basic_usage_with_text_index/app.R @@ -1,8 +1,13 @@ library(shiny) library(JBrowseR) +library(bslib) -ui <- fluidPage(titlePanel("JBrowseR Example"), - JBrowseROutput("widgetOutput")) +ui <- fluidPage( + # Overriding the default bootstrap theme is needed to get proper font size + theme = bs_theme(version = 5), + titlePanel("JBrowseR Example"), + JBrowseROutput("widgetOutput") +) server <- function(input, output, session) { hg38 <- assembly( diff --git a/example_apps/bookmark_app.R b/example_apps/bookmark_app.R deleted file mode 100644 index e5f450c..0000000 --- a/example_apps/bookmark_app.R +++ /dev/null @@ -1,54 +0,0 @@ -library(shiny) -library(tibble) -library(DT) -library(dplyr) -library(JBrowseR) - -ui <- fluidPage( - titlePanel("JBrowseR Bookmark App"), - JBrowseROutput("browserOutput"), - tags$br(), - actionButton("delete", label = "delete selected table rows", icon = icon('trash')), - tags$br(), - tags$br(), - dataTableOutput("bookmarks") -) - -server <- function(input, output, session) { - output$browserOutput <- renderJBrowseR( - JBrowseR("ViewHg38", location = "10:32,311,572..32,478,205") - ) - - # set up reactive df of bookmarks - values <- reactiveValues() - - values$bookmark_df <- tibble::tibble( - chrom = character(), - start = numeric(), - end = numeric(), - name = character() - ) - - # add clicked region - observeEvent(input$selectedFeature, { - values$bookmark_df <- values$bookmark_df %>% - add_row( - chrom = input$selectedFeature$refName, - start = input$selectedFeature$start, - end = input$selectedFeature$end, - name = input$selectedFeature$name - ) - }) - - # delete selected table rows - observeEvent(input$delete, { - if (!is.null(input$bookmarks_rows_selected)) { - values$bookmark_df <- values$bookmark_df %>% - slice(-input$bookmarks_rows_selected) - } - }) - - output$bookmarks <- DT::renderDT(values$bookmark_df) -} - -shinyApp(ui, server) diff --git a/example_apps/bookmarks_demo/README.md b/example_apps/bookmarks_demo/README.md new file mode 100644 index 0000000..2cc8fb2 --- /dev/null +++ b/example_apps/bookmarks_demo/README.md @@ -0,0 +1,16 @@ +# JBrowse R Demo (with Shiny) + +See this app running at https://cbridge.shinyapps.io/jbrowse-r-shiny/ + +This demo is originally by +[Caroline Bridge](https://github.com/carolinebridge-oicr) with components by +[Elliot Hershberg](https://github.com/elliothershberg). + +Download this directory from the monorepo using +https://download-directory.github.io/?url=https://github.com/GMOD/jbrowse-components/tree/main/embedded_demos/jbrowse-r-shiny + +## Usage + +On the command line: + +`Rscript app.R` diff --git a/example_apps/bookmarks_demo/app.R b/example_apps/bookmarks_demo/app.R new file mode 100644 index 0000000..7fed837 --- /dev/null +++ b/example_apps/bookmarks_demo/app.R @@ -0,0 +1,270 @@ +# Load packages --- +library(shiny) +library(JBrowseR) +library(bslib) +library(tibble) +library(DT) +library(dplyr) + +ui <- fluidPage( + # Overriding the default bootstrap theme is needed to get proper font size + theme = bs_theme(version = 5), + titlePanel("JBrowseR Demo (with Shiny)"), + tags$head( + tags$style( + "#text { + border: '1px black', + height: '50px' + }" + ) + ), + sidebarLayout( + sidebarPanel( + h4("Control the view"), + span("This is an example of controlling the view from other elements + on the page. Clicking on a button below will navigate to the location of + that gene:"), + br(), + actionButton("cyp", "CYP2C19"), + actionButton("brc", "BRCA2"), + h4("Using dataframes"), + h5("Add a track"), + span("You can use dataframes to render tracks in JBrowse R. + Click the button below to add the track data represented in + the table below to a new track in JBrowse R."), + br(), + actionButton( + "add", + label = "Add track", + icon = icon("plus") + ), + tableOutput("tracks"), + h5("Add or remove bookmarks"), + span("You can use dataframes to add or remove bookmarks in JBrowse R.\n + Click on a feature on a JBrowse track to add a bookmark.\n + Select a row and click the delete button to remove a bookmark.\n + Select a row and click the navigate button to navigate to a bookmark."), + br(), + actionButton( + "delete", + label = "Delete selected table rows", + icon = icon("trash") + ), + actionButton( + "navigate", + label = "Navigate to selected bookmark", + icon = icon("arrow-right") + ), + br(), + dataTableOutput("bookmarks"), + h4("See the state"), + span("The button below will show you the current 'session', which + includes things like what region the view is showing and which + tracks are open. This 'session' object can be used in the"), + code("JBrowseR"), + span("slot of"), + code("renderJBrowseR"), + br(), + actionButton("session", "Show session"), + verbatimTextOutput("text"), + h4("Docs"), + span("Full documentation for JBrowse R is available at "), + a( + href = "https://gmod.github.io/JBrowseR/", + "https://gmod.github.io/JBrowseR/" + ), + h4("Code"), + span("The code for this app is available at"), + a( + href = "https://github.com/GMOD/jbrowse-components/tree/main/demos/jbrowse-r-shiny", # nolint + "https://github.com/GMOD/jbrowse-components/tree/main/demos/jbrowse-r-shiny" # nolint + ), + h4("Citation"), + span("JBrowse R was developed by "), + a(href = "https://orcid.org/0000-0003-2068-3366", "Elliot Hershberg"), + span(" and the "), + a(href = "https://github.com/gmod/jbrowse-components", "JBrowse 2 Team"), + br(), + span("Please cite where appropriate:"), + br(), + a( + href = "https://doi.org/10.1093/bioinformatics/btab459", + "Hershberg et al., 2021. + JBrowseR: An R Interface to the JBrowse 2 Genome Browser" + ) + ), + mainPanel( + JBrowseROutput("browserOutput"), + ) + ) +) + +server <- function(input, output, session) { + assembly <- assembly( + "https://jbrowse.org/genomes/GRCh38/fasta/hg38.prefix.fa.gz", + bgzip = TRUE, + aliases = ("hg38"), + refname_aliases = + "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/hg38_aliases.txt" + ) + + # JB2 track configuration + annotations <- track_feature( + "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/ncbi_refseq/GCA_000001405.15_GRCh38_full_analysis_set.refseq_annotation.sorted.gff.gz", # nolint + assembly + ) + + alignments <- track_alignments( + "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/alignments/NA12878/NA12878.alt_bwamem_GRCh38DH.20150826.CEU.exome.cram", # nolint + assembly + ) + + wiggles <- track_wiggle( + "https://hgdownload.cse.ucsc.edu/goldenpath/hg38/phyloP100way/hg38.phyloP100way.bw", # nolint + assembly + ) + + variants <- track_variant( + "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/variants/ALL.wgs.shapeit2_integrated_snvindels_v2a.GRCh38.27022019.sites.vcf.gz", # nolint + assembly + ) + + text_index <- text_index( + "https://jbrowse.org/genomes/GRCh38/ncbi_refseq/trix/GCA_000001405.15_GRCh38_full_analysis_set.refseq_annotation.sorted.gff.gz.ix", # nolint + "https://jbrowse.org/genomes/GRCh38/ncbi_refseq/trix/GCA_000001405.15_GRCh38_full_analysis_set.refseq_annotation.sorted.gff.gz.ixx", # nolint + "https://jbrowse.org/genomes/GRCh38/ncbi_refseq/trix/GCA_000001405.15_GRCh38_full_analysis_set.refseq_annotation.sorted.gff.gz_meta.json", # nolint + "hg38" + ) + + tracks <- tracks( + annotations, + variants, + alignments, + wiggles + ) + + # set up the default session for the browser + default_session <- default_session( + assembly, + c(alignments, wiggles, variants), + ) + + # some reactive values that our UI can change + loc <- reactiveValues(val = "10:29,838,565..29,838,860") + shown_tracks <- reactiveValues(val = c(alignments, wiggles, variants)) + + # link the UI with the browser widget + output$browserOutput <- renderJBrowseR( + JBrowseR( + "View", + assembly = assembly, + tracks = tracks, + location = loc$val, + text_index = text_index, + defaultSession = default_session + ) + ) + + # buttons to nav to specific locations + observeEvent(input$cyp, { + loc$val <- "10:94762681..94855547" + }) + + observeEvent(input$brc, { + loc$val <- "13:32315086..32400266" + }) + + # could use prettify from jsonlite here, but it makes the out vertically large + observeEvent(input$session, { + output$text <- renderText({ + paste( + "JBrowseR( + \"View\", + assembly = + assembly(\n", + assembly, + "\n\t ),\n\ttracks = + tracks(\n", + tracks, + "\n\t ),\n", + "\tlocation = ", + loc$val, + "\n)" + ) + }) + }) + + # add or remove bookmark logic + values <- reactiveValues() + + values$bookmark_df <- tibble::tibble( + chrom = character(), + start = numeric(), + end = numeric(), + name = character() + ) + + observeEvent(input$selectedFeature, { + values$bookmark_df <- values$bookmark_df %>% + add_row( + chrom = input$selectedFeature$refName, + start = input$selectedFeature$start, + end = input$selectedFeature$end, + name = input$selectedFeature$name + ) + }) + + observeEvent(input$delete, { + if (!is.null(input$bookmarks_rows_selected)) { + values$bookmark_df <- values$bookmark_df %>% + slice(-input$bookmarks_rows_selected) + } + }) + + output$bookmarks <- DT::renderDT(values$bookmark_df) + + # navigate to bookmark logic + observeEvent(input$navigate, { + if (!is.null(input$bookmarks_rows_selected)) { + loc$val <- paste0( + values$bookmark_df[input$bookmarks_rows_selected, "chrom"], + ":", + values$bookmark_df[input$bookmarks_rows_selected, "start"], + "..", + values$bookmark_df[input$bookmarks_rows_selected, "end"] + ) + } + }) + + # logic for adding sample track df to JBrowse R + values$tracks_df <- data.frame( + chrom = c("10", "10", "13"), + start = c(94780000, 29838600, 32330000), + end = c(94810000, 29838760, 32370000), + name = c("feature1", "feature2", "feature3") + ) + + output$tracks <- renderTable(values$tracks_df) + + observeEvent(input$add, { + df_track <- track_data_frame(values$tracks_df, "new_track", assembly) + shown_tracks$val <- append(shown_tracks$val, df_track) + + output$browserOutput <- renderJBrowseR( + JBrowseR( + "View", + assembly = assembly, + tracks = tracks(wiggles, annotations, alignments, variants, df_track), + location = loc$val, + text_index = text_index, + defaultSession = default_session( + assembly, + shown_tracks$val, + ) + ) + ) + }) +} + +# Run --- +shinyApp(ui, server) diff --git a/example_apps/custom_app.R b/example_apps/custom_app.R deleted file mode 100644 index 4b8b16e..0000000 --- a/example_apps/custom_app.R +++ /dev/null @@ -1,70 +0,0 @@ -library(shiny) -library(JBrowseR) - -ui <- fluidPage( - tags$head( - tags$style(HTML( - "html { font-size: 14px }" - )) - ), - titlePanel("JBrowseR Example"), - JBrowseROutput("widgetOutput") -) - -server <- function(input, output, session) { - # create the assembly configuration - assembly <- assembly( - "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz", - bgzip = TRUE, - aliases = c("GRCh37"), - refname_aliases = "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/hg19_aliases.txt" - ) - - # create alignments, variant, feature, and wiggle tracks - alignments <- track_alignments( - "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/ultra-long-ont_hs37d5_phased.cram", - assembly - ) - variant <- track_variant( - "https://ftp.ncbi.nlm.nih.gov/pub/clinvar/vcf_GRCh37/clinvar.vcf.gz", - assembly - ) - feature <- track_feature( - "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/ncbi_refseq/GRCh37_latest_genomic.sort.gff.gz", - assembly - ) - wiggle <- track_wiggle( - "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/reads_lr_skbr3.fa_ngmlr-0.2.3_mapped.bam.regions.bw", - assembly - ) - - # set up the final tracks object to be used - tracks <- tracks( - alignments, - variant, - feature, - wiggle - ) - - # determine what the browser displays by default - default_session <- default_session( - assembly, - c(variant, wiggle, feature), - display_assembly = FALSE - ) - - # create a custom color palette theme for the browser - theme <- theme("#311b92", "#0097a7", "#f57c00", "#d50000") - - output$widgetOutput <- renderJBrowseR( - JBrowseR("View", - assembly = assembly, - tracks = tracks, - location = "10:31,419,497..33,370,375", - defaultSession = default_session, - theme = theme - ) - ) -} - -shinyApp(ui, server) diff --git a/example_apps/json_app.R b/example_apps/load_config_json/app.R similarity index 75% rename from example_apps/json_app.R rename to example_apps/load_config_json/app.R index 5b0c579..40bc848 100644 --- a/example_apps/json_app.R +++ b/example_apps/load_config_json/app.R @@ -1,7 +1,10 @@ library(shiny) library(JBrowseR) +library(bslib) ui <- fluidPage( + # Overriding the default bootstrap theme is needed to get proper font size + theme = bs_theme(version = 5), titlePanel("JSON JBrowseR Example"), JBrowseROutput("widgetOutput") ) diff --git a/example_apps/config.json b/example_apps/load_config_json/config.json similarity index 100% rename from example_apps/config.json rename to example_apps/load_config_json/config.json diff --git a/example_apps/df_app.R b/example_apps/load_data_frame/app.R similarity index 89% rename from example_apps/df_app.R rename to example_apps/load_data_frame/app.R index 1aabdb7..e296467 100644 --- a/example_apps/df_app.R +++ b/example_apps/load_data_frame/app.R @@ -1,7 +1,10 @@ library(shiny) library(JBrowseR) +library(bslib) ui <- fluidPage( + # Overriding the default bootstrap theme is needed to get proper font size + theme = bs_theme(version = 5), titlePanel("JBrowseR Example"), JBrowseROutput("widgetOutput") ) diff --git a/example_apps/skbr3_fusions.R b/example_apps/skbr3_gene_fusions/app.R similarity index 92% rename from example_apps/skbr3_fusions.R rename to example_apps/skbr3_gene_fusions/app.R index a503b06..fa9b7fb 100644 --- a/example_apps/skbr3_fusions.R +++ b/example_apps/skbr3_gene_fusions/app.R @@ -1,8 +1,11 @@ library(shiny) library(tibble) library(JBrowseR) +library(bslib) ui <- fluidPage( + # Overriding the default bootstrap theme is needed to get proper font size + theme = bs_theme(version = 5), titlePanel("SKBR3 Gene Fusions"), dataTableOutput("gene_fusions"), JBrowseROutput("browserOutput")