vojtam commited on
Commit
8e7c9f6
·
verified ·
1 Parent(s): 7c52e86

Upload 18 files

Browse files
app/js/index.js CHANGED
@@ -1,3 +1,25 @@
1
  export function maximizeBox() {
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  }
 
1
  export function maximizeBox() {
2
 
3
+ }
4
+
5
+
6
+ export function create_legend(titles, colors) {
7
+ let legend_div = document.getElementById('legend');
8
+
9
+ let legend_item = document.createElement('div');
10
+ let col_circle = document.createElement('div');
11
+ let legend_span = document.createElement('span');
12
+
13
+ legend_item.classList.add('legend-item');
14
+ col_circle.classList.add('legend-col-circle');
15
+ legend_span.classList.add('legend-span');
16
+
17
+ col_circle.style.backgroundColor = color;
18
+ legend_span.textContent = title;
19
+
20
+ legend_item.append(col_circle);
21
+ legend_item.append(legend_span);
22
+
23
+ legend_div.append(legend_item);
24
+
25
  }
app/logic/create_sankey.R CHANGED
@@ -2,7 +2,7 @@
2
  box::use(
3
  data.table[...],
4
  stats[na.omit],
5
- plotly[plot_ly, layout],
6
  )
7
 
8
  #' sankey_preprare_data
@@ -37,14 +37,15 @@ box::use(
37
  sankey_prepare_data <- function(dataset, selected_pathways, selected_genes, is_pathway) {
38
  # filter the selected_pathways -> | gene_name | kegg_paths_name |
39
  if (!is_pathway) {
40
- sankey_data <- dataset[gene_name %in% selected_genes$gene_name, .(gene_name, kegg_paths_name, var_name)]
41
  } else {
42
- sankey_data <- dataset[kegg_paths_name %in% selected_pathways$pathway, .(gene_name, kegg_paths_name, var_name)]
43
  }
44
 
45
  setorder(sankey_data, kegg_paths_name, gene_name)
46
  labels_all <- data.table(
47
  label = c(sankey_data$kegg_paths_name, sankey_data$gene_name, sankey_data$var_name)
 
48
  )
49
  # get all labels their id
50
  labels_all[, id := match(labels_all$label, unique(labels_all$label))]
@@ -57,6 +58,7 @@ sankey_prepare_data <- function(dataset, selected_pathways, selected_genes, is_p
57
  full <- unique(na.omit(with_source))
58
  path_gene <- unique(full[, .(kegg_paths_name, gene_name, first, second)])
59
  scores <- c(rle(rleid(c(full$first + full$second)))$lengths, rep(1, nrow(full)))
 
60
  return(list(labels, full, scores))
61
  }
62
 
@@ -71,17 +73,21 @@ sankey_prepare_data <- function(dataset, selected_pathways, selected_genes, is_p
71
  #' @export
72
  #'
73
  #' @examples
74
- create_sankey <- function(labels, path_gene, gene_variant, scores) {
 
 
 
75
  fig <- plot_ly(
76
  type = "sankey",
77
  orientation = "h",
78
  selectedpoints = c(0:10),
79
  node = list(
80
- label = labels$label,
81
- #x = c(rep(0, length(unique(path_gene$kegg_paths_name))), rep(1, length(unique(gene_variant$gene_name))), rep(2, length(unique(gene_variant$var_name)))),
82
  y = seq(0, nrow(labels), by = 1),
83
  color = "black",
84
  pad = 30,
 
 
85
  thickness = 30,
86
  line = list(
87
  color = "black",
@@ -91,13 +97,30 @@ create_sankey <- function(labels, path_gene, gene_variant, scores) {
91
  link = list(
92
  source = c(path_gene$first, gene_variant$second) - 1,
93
  target = c(path_gene$second, gene_variant$third) - 1,
94
- value = scores
 
95
  )
96
  )
 
 
 
 
 
 
97
 
98
  fig <- fig |> layout(
99
  font = list(
100
  size = 14
 
 
 
 
 
 
 
 
 
 
101
  )
102
  )
103
  fig
 
2
  box::use(
3
  data.table[...],
4
  stats[na.omit],
5
+ plotly[plot_ly, layout, add_annotations],
6
  )
7
 
8
  #' sankey_preprare_data
 
37
  sankey_prepare_data <- function(dataset, selected_pathways, selected_genes, is_pathway) {
38
  # filter the selected_pathways -> | gene_name | kegg_paths_name |
39
  if (!is_pathway) {
40
+ sankey_data <- dataset[gene_name %in% selected_genes$gene_name, .(gene_name, kegg_paths_name, var_name, col)]
41
  } else {
42
+ sankey_data <- dataset[kegg_paths_name %in% selected_pathways$pathway, .(gene_name, kegg_paths_name, var_name, col)]
43
  }
44
 
45
  setorder(sankey_data, kegg_paths_name, gene_name)
46
  labels_all <- data.table(
47
  label = c(sankey_data$kegg_paths_name, sankey_data$gene_name, sankey_data$var_name)
48
+
49
  )
50
  # get all labels their id
51
  labels_all[, id := match(labels_all$label, unique(labels_all$label))]
 
58
  full <- unique(na.omit(with_source))
59
  path_gene <- unique(full[, .(kegg_paths_name, gene_name, first, second)])
60
  scores <- c(rle(rleid(c(full$first + full$second)))$lengths, rep(1, nrow(full)))
61
+ scores <- rep(1, length(scores))
62
  return(list(labels, full, scores))
63
  }
64
 
 
73
  #' @export
74
  #'
75
  #' @examples
76
+ create_sankey <- function(labels, path_gene, gene_variant, scores, colors) {
77
+ path_gene_labels <- labels
78
+ path_gene_labels[(nrow(labels) - length(unique(gene_variant$var_name)) + 1):nrow(labels)]$label <- ""
79
+
80
  fig <- plot_ly(
81
  type = "sankey",
82
  orientation = "h",
83
  selectedpoints = c(0:10),
84
  node = list(
85
+ label = path_gene_labels$label,
 
86
  y = seq(0, nrow(labels), by = 1),
87
  color = "black",
88
  pad = 30,
89
+ customdata = labels$label,
90
+ hovertemplate = paste("%{customdata}"),
91
  thickness = 30,
92
  line = list(
93
  color = "black",
 
97
  link = list(
98
  source = c(path_gene$first, gene_variant$second) - 1,
99
  target = c(path_gene$second, gene_variant$third) - 1,
100
+ value = scores,
101
+ color = colors
102
  )
103
  )
104
+
105
+
106
+
107
+ fig <- fig |> add_annotations(x = 0, y = -0.1, showarrow = FALSE, font = list(size = 17), xref = "x", yref = "paper", text = "Pathway")
108
+ fig <- fig |> add_annotations(x = 1, y = -0.1, showarrow = FALSE, font = list(size = 17), xref = "x", yref = "paper", text = "Gene")
109
+ fig <- fig |> add_annotations(x = 2, y = -0.1, showarrow = FALSE, font = list(size = 17), xref = "x", yref = "paper", text = "Variant")
110
 
111
  fig <- fig |> layout(
112
  font = list(
113
  size = 14
114
+ ),
115
+ xaxis = list(
116
+ showgrid = FALSE,
117
+ zeroline = FALSE,
118
+ visible = FALSE
119
+ ),
120
+ yaxis = list(
121
+ showgrid = FALSE,
122
+ zeroline = FALSE,
123
+ visible = FALSE
124
  )
125
  )
126
  fig
app/logic/data_preprocessor.R CHANGED
@@ -1,7 +1,8 @@
1
 
2
  box::use(
3
  data.table[...],
4
- stats[na.omit]
 
5
  )
6
 
7
 
@@ -61,11 +62,17 @@ preprocess_maf_data <- function() {
61
  new = c("ensembl_id", "gene_name", "Allele")
62
  )
63
 
 
64
  variants_tab <- na.omit(variants_tab)
65
- genes_sample <- sample(variants_tab$gene_name, 2000)
 
66
  variants_tab <- variants_tab[gene_name %in% genes_sample]
67
  variants_tab[, var_name := paste0(Chromosome, "_", Start_Position, "_", Reference_Allele, "/", Allele)]
68
  tab <- variants_tab[kegg_tab, on = "ensembl_id", nomatch = 0, allow.cartesian = TRUE]
 
 
 
 
69
  return(tab)
70
 
71
  }
 
1
 
2
  box::use(
3
  data.table[...],
4
+ stats[na.omit],
5
+ RColorBrewer[brewer.pal]
6
  )
7
 
8
 
 
62
  new = c("ensembl_id", "gene_name", "Allele")
63
  )
64
 
65
+
66
  variants_tab <- na.omit(variants_tab)
67
+ genes_sample <- variants_tab$gene_name
68
+
69
  variants_tab <- variants_tab[gene_name %in% genes_sample]
70
  variants_tab[, var_name := paste0(Chromosome, "_", Start_Position, "_", Reference_Allele, "/", Allele)]
71
  tab <- variants_tab[kegg_tab, on = "ensembl_id", nomatch = 0, allow.cartesian = TRUE]
72
+
73
+ variant_types <-unique(tab$Variant_Type)
74
+ colors_tab <- data.table(col = brewer.pal(length(variant_types), "Set2"), Variant_Type = variant_types)
75
+ tab <- tab[colors_tab, on = "Variant_Type"]
76
  return(tab)
77
 
78
  }
app/main.R CHANGED
@@ -1,13 +1,14 @@
1
  box::use(
2
- shiny[bootstrapPage, div, icon, moduleServer, fluidRow, NS, renderUI, tags, uiOutput],
3
  bs4Dash[box, dashboardPage, tabItems, tabItem, sidebarMenu, menuItem, dashboardHeader, column, dashboardBrand, dashboardSidebar, dashboardBody],
4
  thematic[thematic_shiny],
5
  shinyjs[useShinyjs, runjs],
6
- gargoyle[init]
 
7
  )
 
8
 
9
  library(g3viz)
10
-
11
  box::use(
12
  app/logic/data_preprocessor[preprocess_data],
13
  app/logic/data_preprocessor[preprocess_maf_data]
@@ -17,7 +18,8 @@ box::use(
17
  app/view/table,
18
  app/view/sankey,
19
  app/view/lollipop,
20
- app/view/browser
 
21
  )
22
 
23
  thematic_shiny()
@@ -72,6 +74,7 @@ ui <- function(id) {
72
  fluidRow(
73
  column(
74
  width = 9,
 
75
  sankey$ui(ns("sankey")),
76
  lollipop$ui(ns("lollipop"))
77
  ),
@@ -99,17 +102,32 @@ ui <- function(id) {
99
  )
100
  }
101
 
 
 
 
102
  #' @export
103
  server <- function(id) {
104
  moduleServer(id, function(input, output, session) {
105
  init("reset_sankey")
106
- shiny::devmode()
107
-
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  # data <- preprocess_data()
109
- data <- preprocess_maf_data()
110
- print(data)
111
- browser$server("browser", data)
112
- selected_features <- table$server("table", data)
113
  selected_gene_rval <- sankey$server("sankey", data, selected_features()[[1]], selected_features()[[2]], selected_features()[[3]])
114
  lollipop$server("lollipop", data, selected_gene_rval)
115
  })
 
1
  box::use(
2
+ shiny[...],
3
  bs4Dash[box, dashboardPage, tabItems, tabItem, sidebarMenu, menuItem, dashboardHeader, column, dashboardBrand, dashboardSidebar, dashboardBody],
4
  thematic[thematic_shiny],
5
  shinyjs[useShinyjs, runjs],
6
+ gargoyle[init],
7
+ utils[globalVariables]
8
  )
9
+ globalVariables(c("mutation.table.df", "hgnc2pfam.df"))
10
 
11
  library(g3viz)
 
12
  box::use(
13
  app/logic/data_preprocessor[preprocess_data],
14
  app/logic/data_preprocessor[preprocess_maf_data]
 
18
  app/view/table,
19
  app/view/sankey,
20
  app/view/lollipop,
21
+ app/view/browser,
22
+ app/view/plot_options
23
  )
24
 
25
  thematic_shiny()
 
74
  fluidRow(
75
  column(
76
  width = 9,
77
+ plot_options$ui(ns("plot_options")),
78
  sankey$ui(ns("sankey")),
79
  lollipop$ui(ns("lollipop"))
80
  ),
 
102
  )
103
  }
104
 
105
+
106
+ whole_dataset <- preprocess_maf_data()
107
+
108
  #' @export
109
  server <- function(id) {
110
  moduleServer(id, function(input, output, session) {
111
  init("reset_sankey")
112
+
113
+ ns <- NS(id)
114
+ data <- reactiveVal(whole_dataset)
115
+ options <- plot_options$server("plot_options", unique(data()$Variant_Type), unique(data()$Consequence))
116
+ observeEvent(options(), {
117
+ req((length(options()[[1]]) > 0 || length(options()[[2]] > 0)))
118
+
119
+ selected_var_types <- options()[[1]]
120
+ selected_consequences <- options()[[2]]
121
+
122
+ tab <- whole_dataset[Variant_Type %in% selected_var_types]
123
+ data(tab[Consequence %in% selected_consequences])
124
+
125
+ })
126
+
127
  # data <- preprocess_data()
128
+ browser$server("browser", data())
129
+
130
+ selected_features <- table$server("table", data())
 
131
  selected_gene_rval <- sankey$server("sankey", data, selected_features()[[1]], selected_features()[[2]], selected_features()[[3]])
132
  lollipop$server("lollipop", data, selected_gene_rval)
133
  })
app/static/css/app.min.css CHANGED
@@ -1 +1 @@
1
- .toggle-switch{position:relative;display:inline-block;width:40px;height:24px;margin:10px}.toggle-switch .toggle-input{display:none}.toggle-switch .toggle-label{position:absolute;top:0;left:0;width:40px;height:24px;background-color:#ccc;border-radius:34px;cursor:pointer;transition:background-color .3s}.toggle-switch .toggle-label::before{content:"";position:absolute;width:20px;height:20px;border-radius:50%;top:2px;left:2px;background-color:#fff;box-shadow:0px 2px 5px 0px rgba(0,0,0,.3);transition:transform .3s}.toggle-switch .toggle-input:checked+.toggle-label{background-color:#2196f3}.toggle-switch .toggle-input:checked+.toggle-label::before{transform:translateX(16px)}.toggle-switch.light .toggle-label{background-color:#bebebe}.toggle-switch.light .toggle-input:checked+.toggle-label{background-color:#9b9b9b}.toggle-switch.light .toggle-input:checked+.toggle-label::before{transform:translateX(6px)}.toggle-switch.dark .toggle-label{background-color:#4b4b4b}.toggle-switch.dark .toggle-input:checked+.toggle-label{background-color:#717171}.toggle-switch.dark .toggle-input:checked+.toggle-label::before{transform:translateX(16px)}.feat-radio-container{display:flex;justify-content:center;align-items:center}.feat-radio-container>h4{margin-top:6px}.toggle-switch-feat{position:relative;display:inline-block;width:40px;height:24px;margin:10px}.toggle-switch-feat .toggle-input-feat{display:none}.toggle-switch-feat .toggle-label-feat{position:absolute;top:0;left:0;width:40px;height:24px;background-color:#bbb;border-radius:34px;cursor:pointer;transition:background-color .3s}.toggle-switch-feat .toggle-label-feat::before{content:"";position:absolute;width:20px;height:20px;border-radius:50%;top:2px;left:2px;background-color:#fff;box-shadow:0px 2px 5px 0px rgba(0,0,0,.3);transition:transform .3s}.toggle-switch-feat .toggle-input-feat:checked+.toggle-label-feat{background-color:#bbb}.toggle-switch-feat .toggle-input-feat:checked+.toggle-label-feat::before{transform:translateX(16px)}.toggle-switch-feat.light .toggle-label-feat{background-color:#bebebe}.toggle-switch-feat.light .toggle-input-feat:checked+.toggle-label-feat{background-color:#9b9b9b}.toggle-switch-feat.light .toggle-input-feat:checked+.toggle-label-feat::before{transform:translateX(6px)}.toggle-switch-feat.dark .toggle-label-feat{background-color:#4b4b4b}.toggle-switch-feat.dark .toggle-input:checked+.toggle-label-feat{background-color:#717171}.toggle-switch-feat.dark .toggle-input-feat:checked+.toggle-label-feat::before{transform:translateX(16px)}.header-btns{width:100%;display:flex;justify-content:space-between}.shiny-output-error-validation{color:#000046;font-size:22px}
 
1
+ .toggle-switch{position:relative;display:inline-block;width:40px;height:24px;margin:10px}.toggle-switch .toggle-input{display:none}.toggle-switch .toggle-label{position:absolute;top:0;left:0;width:40px;height:24px;background-color:#ccc;border-radius:34px;cursor:pointer;transition:background-color .3s}.toggle-switch .toggle-label::before{content:"";position:absolute;width:20px;height:20px;border-radius:50%;top:2px;left:2px;background-color:#fff;box-shadow:0px 2px 5px 0px rgba(0,0,0,.3);transition:transform .3s}.toggle-switch .toggle-input:checked+.toggle-label{background-color:#2196f3}.toggle-switch .toggle-input:checked+.toggle-label::before{transform:translateX(16px)}.toggle-switch.light .toggle-label{background-color:#bebebe}.toggle-switch.light .toggle-input:checked+.toggle-label{background-color:#9b9b9b}.toggle-switch.light .toggle-input:checked+.toggle-label::before{transform:translateX(6px)}.toggle-switch.dark .toggle-label{background-color:#4b4b4b}.toggle-switch.dark .toggle-input:checked+.toggle-label{background-color:#717171}.toggle-switch.dark .toggle-input:checked+.toggle-label::before{transform:translateX(16px)}.feat-radio-container{display:flex;justify-content:center;align-items:center}.feat-radio-container>h4{margin-top:6px}.toggle-switch-feat{position:relative;display:inline-block;width:40px;height:24px;margin:10px}.toggle-switch-feat .toggle-input-feat{display:none}.toggle-switch-feat .toggle-label-feat{position:absolute;top:0;left:0;width:40px;height:24px;background-color:#bbb;border-radius:34px;cursor:pointer;transition:background-color .3s}.toggle-switch-feat .toggle-label-feat::before{content:"";position:absolute;width:20px;height:20px;border-radius:50%;top:2px;left:2px;background-color:#fff;box-shadow:0px 2px 5px 0px rgba(0,0,0,.3);transition:transform .3s}.toggle-switch-feat .toggle-input-feat:checked+.toggle-label-feat{background-color:#bbb}.toggle-switch-feat .toggle-input-feat:checked+.toggle-label-feat::before{transform:translateX(16px)}.toggle-switch-feat.light .toggle-label-feat{background-color:#bebebe}.toggle-switch-feat.light .toggle-input-feat:checked+.toggle-label-feat{background-color:#9b9b9b}.toggle-switch-feat.light .toggle-input-feat:checked+.toggle-label-feat::before{transform:translateX(6px)}.toggle-switch-feat.dark .toggle-label-feat{background-color:#4b4b4b}.toggle-switch-feat.dark .toggle-input:checked+.toggle-label-feat{background-color:#717171}.toggle-switch-feat.dark .toggle-input-feat:checked+.toggle-label-feat::before{transform:translateX(16px)}.header-btns{width:100%;display:flex;justify-content:space-between}.shiny-output-error-validation{color:#000046;font-size:22px}.flex-centered{display:flex;align-items:center;justify-content:center}.awesome-checkbox{margin-left:15px !important;margin-right:15px !important}.flex-col{flex-direction:column}.control-label{font-size:18px}#legend{height:30px;display:flex;flex-direction:row;justify-content:center;align-items:center}.legend-span{padding:10px}.legend-item{display:flex;justify-content:center;align-items:center}.legend-col-circle{width:15px;height:15px;border-radius:50%}
app/styles/misc.scss CHANGED
@@ -14,4 +14,53 @@ $light-red: #dc3545;
14
  .shiny-output-error-validation {
15
  color: $dark-blue;
16
  font-size: 22px;
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  .shiny-output-error-validation {
15
  color: $dark-blue;
16
  font-size: 22px;
17
+ }
18
+
19
+
20
+ .flex-centered {
21
+ display: flex;
22
+ align-items: center;
23
+ justify-content: center;
24
+ }
25
+
26
+ .awesome-checkbox {
27
+ margin-left: 15px !important;
28
+ margin-right: 15px !important ;
29
+ }
30
+
31
+ .flex-col {
32
+ flex-direction: column;
33
+ }
34
+
35
+
36
+ .control-label {
37
+ font-size: 18px;
38
+ }
39
+
40
+
41
+
42
+
43
+ #legend {
44
+ height: 30px;
45
+ display: flex;
46
+ flex-direction: row;
47
+ justify-content: center;
48
+ align-items: center;
49
+ }
50
+
51
+ .legend-span {
52
+ padding: 10px;
53
+ }
54
+
55
+ .legend-item {
56
+ display: flex;
57
+ justify-content: center;
58
+ align-items: center;
59
+ }
60
+
61
+
62
+ .legend-col-circle {
63
+ width: 15px;
64
+ height: 15px;
65
+ border-radius: 50%;
66
+ }
app/view/lollipop.R CHANGED
@@ -27,8 +27,7 @@ server <- function(id, data, selected_gene_rval) {
27
 
28
  output$lollipop_plot <- renderG3Lollipop({
29
  req(selected_gene_rval())
30
- print(selected_gene_rval())
31
- filter_tab <- data[gene_name == selected_gene_rval()]
32
  plot.options <- g3Lollipop.theme(theme.name = "cbioportal",
33
  title.text = selected_gene_rval(),
34
  y.axis.label = "# of Mutations")
 
27
 
28
  output$lollipop_plot <- renderG3Lollipop({
29
  req(selected_gene_rval())
30
+ filter_tab <- data()[gene_name == selected_gene_rval()]
 
31
  plot.options <- g3Lollipop.theme(theme.name = "cbioportal",
32
  title.text = selected_gene_rval(),
33
  y.axis.label = "# of Mutations")
app/view/plot_options.R ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ box::use(
2
+ shiny[moduleServer, NS, div, observeEvent, req, reactive, textOutput, renderText, uiOutput, renderUI],
3
+ shinyWidgets[awesomeCheckboxGroup, pickerInput, pickerOptions],
4
+ bs4Dash[box]
5
+
6
+ )
7
+
8
+ #' @export
9
+ ui <- function(id) {
10
+ ns <- NS(id)
11
+ box(
12
+ width = 12,
13
+ title = "Plot options",
14
+ status = "navy",
15
+ maximizable = TRUE,
16
+ solidHeader = TRUE,
17
+ div(
18
+ class = "flex-centered, flex-col",
19
+ uiOutput(ns("filter_var_type_UI")),
20
+ uiOutput(ns("filter_consequence_UI"))
21
+ )
22
+ )
23
+ }
24
+
25
+ #' @export
26
+ server <- function(id, var_types, conseq_types) {
27
+ moduleServer(id, function(input, output, session) {
28
+
29
+ ns <- session$ns # so that we put the renderui inputs in the same namespace as the session
30
+
31
+ output$filter_var_type_UI <- renderUI({
32
+ awesomeCheckboxGroup(
33
+ inputId = ns("pick_var_type"),
34
+ label = "Filter variant type",
35
+ choices = var_types,
36
+ selected = var_types,
37
+ inline = TRUE
38
+ )
39
+ })
40
+
41
+ output$filter_consequence_UI <- renderUI({
42
+ labels <- gsub(",", ", ", gsub("_", " ", conseq_types))
43
+ names(conseq_types) <- labels
44
+ pickerInput(
45
+ inputId = ns("pick_consequence"),
46
+ label = "Select consequence types",
47
+ choices = conseq_types,
48
+ selected = conseq_types,
49
+ multiple = TRUE,
50
+ options = pickerOptions(container = "body",
51
+ actionsBox = TRUE),
52
+ width = "100%"
53
+ )
54
+ })
55
+
56
+
57
+ return(reactive(list(input$pick_var_type, input$pick_consequence)))
58
+ })
59
+ }
app/view/sankey.R CHANGED
@@ -1,8 +1,10 @@
1
  box::use(
2
- shiny[moduleServer, verbatimTextOutput, renderPrint, isolate, NS, req, validate, need, tagList, renderPlot, plotOutput, observeEvent, reactiveVal, reactiveValues],
3
  plotly[plot_ly, event_data, plotlyOutput, renderPlotly, plotlyProxy, plotlyProxyInvoke],
4
  data.table[...],
 
5
  bs4Dash[box],
 
6
  stats[na.omit],
7
  shinyjs[...],
8
  gargoyle[...]
@@ -16,17 +18,17 @@ box::use(
16
  ui <- function(id) {
17
  ns <- NS(id)
18
  tagList(
19
-
20
  box(
21
  width = 12,
22
- height = "50vh",
23
  title = "Sankey Diagram",
24
  status = "navy",
25
  maximizable = TRUE,
26
  solidHeader = TRUE,
27
  id = ns("sankey_box"),
 
28
  plotlyOutput(ns("sankey_plt"), height = "50vh")
29
-
30
  )
31
  )
32
  }
@@ -36,7 +38,6 @@ server <- function(id, dataset, selected_pathways_react, selected_genes_react, i
36
  moduleServer(id, function(input, output, session) {
37
  ns <- NS(id)
38
  # reactive value holding the sankey plot
39
-
40
 
41
  # reactiveVal initialization ----------------------------------------------
42
 
@@ -52,11 +53,17 @@ server <- function(id, dataset, selected_pathways_react, selected_genes_react, i
52
  # Render ------------------------------------------------------------------
53
 
54
  output$sankey_plt <- renderPlotly({
 
55
  validate(
56
  need(!((is.null(selected_pathways_react()) || nrow(selected_pathways_react()) == 0)
57
  && (is.null(selected_genes_react()) || nrow(selected_genes_react()) == 0)),
58
  "select the features (pathways / genes) that you want to visualize from the table on the right")
59
  )
 
 
 
 
 
60
  # output the contents of the sankey_plot reactive value
61
  if (is_path_tab_active()) {
62
  sankey_pathway_plot()
@@ -66,6 +73,7 @@ server <- function(id, dataset, selected_pathways_react, selected_genes_react, i
66
  })
67
 
68
 
 
69
 
70
  # Events ------------------------------------------------------------------
71
 
@@ -79,36 +87,41 @@ server <- function(id, dataset, selected_pathways_react, selected_genes_react, i
79
  })
80
 
81
  # data is passed into module -> create sankey
82
- observeEvent(selected_pathways_react(), {
83
- req(selected_pathways_react())
84
-
85
- data <- sankey_prepare_data(dataset, selected_pathways_react(), selected_genes_react(), TRUE)
 
 
 
 
 
 
86
  labels(data[[1]])
87
  path_gene <- unique(data[[2]][, .(kegg_paths_name, gene_name, first, second)])
88
- gene_variant <- unique(data[[2]][, .(gene_name, var_name, second, third)])
89
  setorder(path_gene, first)
90
  setorder(gene_variant, second)
91
  path_gene_tab(path_gene)
92
  gene_variant_tab(gene_variant)
93
 
94
- plot <- create_sankey(labels(), path_gene, gene_variant, data[[3]])
95
- sankey_pathway_plot(plot)
 
 
 
 
 
 
 
 
 
 
 
 
96
  })
97
 
98
- observeEvent(selected_genes_react(), {
99
- req(selected_genes_react())
100
- print(selected_genes_react())
101
- data <- sankey_prepare_data(dataset, selected_pathways_react(), selected_genes_react(), FALSE)
102
- labels(data[[1]])
103
- path_gene <- unique(data[[2]][, .(kegg_paths_name, gene_name, first, second)])
104
- gene_variant <- unique(data[[2]][, .(gene_name, var_name, second, third)])
105
- setorder(path_gene, first)
106
- setorder(gene_variant, second)
107
- path_gene_tab(path_gene)
108
- gene_variant_tab(gene_variant)
109
- plot <- create_sankey(labels(), path_gene, gene_variant, data[[3]])
110
- sankey_gene_plot(plot)
111
- })
112
 
113
 
114
  observeEvent(event_data("plotly_click", priority = "event"), {
@@ -122,7 +135,7 @@ server <- function(id, dataset, selected_pathways_react, selected_genes_react, i
122
 
123
  link_colors <- rep("lightgray", nrow(labels()))
124
  link_colors[link_ids] <- "red"
125
-
126
  proxy <- plotlyProxy("sankey_plt", session)
127
  plotlyProxyInvoke(proxy, "restyle",
128
  list(link.color = list(link_colors)))
@@ -130,6 +143,9 @@ server <- function(id, dataset, selected_pathways_react, selected_genes_react, i
130
  })
131
 
132
 
 
 
 
133
  observeEvent(input$sankey_box$maximized, {
134
  plot_height <- if (input$sankey_box$maximized) {
135
  "100%"
@@ -224,4 +240,39 @@ second_level_link_selection <- function(clicked_link, path_gene_tab, gene_varian
224
  return(list(link_ids, select_gene_name))
225
  }
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  box::use(
2
+ shiny[moduleServer, observe, reactive, br, div, verbatimTextOutput, renderPrint, isolate, NS, req, validate, need, tagList, renderPlot, plotOutput, observeEvent, reactiveVal, reactiveValues],
3
  plotly[plot_ly, event_data, plotlyOutput, renderPlotly, plotlyProxy, plotlyProxyInvoke],
4
  data.table[...],
5
+ purrr[map2],
6
  bs4Dash[box],
7
+ graphics[legend, mtext],
8
  stats[na.omit],
9
  shinyjs[...],
10
  gargoyle[...]
 
18
  ui <- function(id) {
19
  ns <- NS(id)
20
  tagList(
 
21
  box(
22
  width = 12,
23
+ height = "54vh",
24
  title = "Sankey Diagram",
25
  status = "navy",
26
  maximizable = TRUE,
27
  solidHeader = TRUE,
28
  id = ns("sankey_box"),
29
+ div(id = "legend"),
30
  plotlyOutput(ns("sankey_plt"), height = "50vh")
31
+ #plotOutput(ns("sankey_legend"))
32
  )
33
  )
34
  }
 
38
  moduleServer(id, function(input, output, session) {
39
  ns <- NS(id)
40
  # reactive value holding the sankey plot
 
41
 
42
  # reactiveVal initialization ----------------------------------------------
43
 
 
53
  # Render ------------------------------------------------------------------
54
 
55
  output$sankey_plt <- renderPlotly({
56
+
57
  validate(
58
  need(!((is.null(selected_pathways_react()) || nrow(selected_pathways_react()) == 0)
59
  && (is.null(selected_genes_react()) || nrow(selected_genes_react()) == 0)),
60
  "select the features (pathways / genes) that you want to visualize from the table on the right")
61
  )
62
+
63
+ legend_tab <- unique(dataset()[, .(Variant_Type, col)])
64
+ prepare_legend_r()
65
+ map2(.x = legend_tab$Variant_Type, .y = legend_tab$col, \(title, color) add_to_legend_r(title, color))
66
+
67
  # output the contents of the sankey_plot reactive value
68
  if (is_path_tab_active()) {
69
  sankey_pathway_plot()
 
73
  })
74
 
75
 
76
+
77
 
78
  # Events ------------------------------------------------------------------
79
 
 
87
  })
88
 
89
  # data is passed into module -> create sankey
90
+ observe({
91
+
92
+ if (is_path_tab_active()) {
93
+ req(selected_pathways_react())
94
+ }
95
+ else {
96
+ req(selected_genes_react())
97
+ }
98
+
99
+ data <- sankey_prepare_data(dataset(), selected_pathways_react(), selected_genes_react(), is_path_tab_active())
100
  labels(data[[1]])
101
  path_gene <- unique(data[[2]][, .(kegg_paths_name, gene_name, first, second)])
102
+ gene_variant <- unique(data[[2]][, .(gene_name, var_name, col, second, third)])
103
  setorder(path_gene, first)
104
  setorder(gene_variant, second)
105
  path_gene_tab(path_gene)
106
  gene_variant_tab(gene_variant)
107
 
108
+
109
+ colors <- NULL
110
+ if (nrow(labels()) > 0) {
111
+ colors <- c(rep("lightgray", nrow(path_gene)), gene_variant$col)
112
+
113
+ }
114
+ plot <- create_sankey(labels(), path_gene, gene_variant, data[[3]], colors)
115
+
116
+ if (is_path_tab_active()) {
117
+ sankey_pathway_plot(plot)
118
+ }
119
+ else {
120
+ sankey_gene_plot(plot)
121
+ }
122
  })
123
 
124
+
 
 
 
 
 
 
 
 
 
 
 
 
 
125
 
126
 
127
  observeEvent(event_data("plotly_click", priority = "event"), {
 
135
 
136
  link_colors <- rep("lightgray", nrow(labels()))
137
  link_colors[link_ids] <- "red"
138
+
139
  proxy <- plotlyProxy("sankey_plt", session)
140
  plotlyProxyInvoke(proxy, "restyle",
141
  list(link.color = list(link_colors)))
 
143
  })
144
 
145
 
146
+
147
+
148
+
149
  observeEvent(input$sankey_box$maximized, {
150
  plot_height <- if (input$sankey_box$maximized) {
151
  "100%"
 
240
  return(list(link_ids, select_gene_name))
241
  }
242
 
243
+ prepare_legend_r <- function() {
244
+ js_call <- "
245
+ let legend_div = document.getElementById('legend');
246
+ legend_div.textContent = '';
247
+ "
248
+ shinyjs::runjs(js_call)
249
+ }
250
+
251
+ add_to_legend_r <- function(title, color) {
252
+ js_call <- sprintf(
253
+ "
254
+
255
+ let legend_div = document.getElementById('legend');
256
+
257
+ let legend_item = document.createElement('div');
258
+ let col_circle = document.createElement('div');
259
+ let legend_span = document.createElement('span');
260
+
261
+ legend_item.classList.add('legend-item');
262
+ col_circle.classList.add('legend-col-circle');
263
+ legend_span.classList.add('legend-span');
264
 
265
+ legend_span.textContent = '%s';
266
+ col_circle.style.backgroundColor = '%s';
267
+
268
+ legend_item.append(col_circle);
269
+ legend_item.append(legend_span);
270
+
271
+ legend_div.append(legend_item);
272
+
273
+
274
+ console.log('DONE');
275
+ "
276
+ , title, color)
277
+ shinyjs::runjs(js_call)
278
+ }
app/view/table.R CHANGED
@@ -27,12 +27,12 @@ ui <- function(id) {
27
  HTML(
28
  '
29
  <div id="feat-radio" style="margin-left: 15px" class="feat-radio-container">
30
- <h4>Pathway</h4>
31
  <div class="toggle-switch-feat">
32
  <input name="checkbox-feature" class="toggle-input-feat" id="toggle-feat" type="checkbox">
33
  <label class="toggle-label-feat" for="toggle-feat"></label>
34
  </div>
35
- <h4>Gene</h4>
36
  </div>
37
 
38
  <script>
@@ -40,9 +40,9 @@ ui <- function(id) {
40
  var checkbox = document.querySelector("input[name=checkbox-feature]");
41
  checkbox.addEventListener("change", function() {
42
  if (this.checked) {
43
- Shiny.setInputValue("app-table-feature_radio", "gene", {priority: "event"});
44
- } else {
45
  Shiny.setInputValue("app-table-feature_radio", "pathway", {priority: "event"});
 
 
46
  }
47
  });
48
 
@@ -64,7 +64,7 @@ ui <- function(id) {
64
  server <- function(id, data) {
65
 
66
  moduleServer(id, function(input, output, session) {
67
- is_path_tab_active <- reactiveVal(TRUE)
68
  selected_pathways <- reactiveVal(NULL)
69
  selected_genes <- reactiveVal(NULL)
70
 
@@ -78,11 +78,11 @@ server <- function(id, data) {
78
  unique(data[, .(gene_name)])
79
  })
80
 
81
- observeEvent(pathways_tab(),{
82
- req(pathways_tab())
83
- output$table <- render_pathways_table(
84
- pathways_tab(),
85
- selected_pathways()
86
  )
87
  })
88
 
@@ -137,7 +137,6 @@ server <- function(id, data) {
137
  row <- input$table_cell_clicked[["row"]]
138
  req(gene)
139
  if (is.null(row)) {
140
- print("it is null")
141
  return(NULL)
142
  }
143
 
@@ -151,7 +150,6 @@ server <- function(id, data) {
151
  features[, row_i := rows]
152
  selected_genes(features)
153
  }
154
- print(selected_pathways())
155
  })
156
 
157
  return(reactiveVal(list(selected_pathways, selected_genes, is_path_tab_active)))
 
27
  HTML(
28
  '
29
  <div id="feat-radio" style="margin-left: 15px" class="feat-radio-container">
30
+ <h4>Gene</h4>
31
  <div class="toggle-switch-feat">
32
  <input name="checkbox-feature" class="toggle-input-feat" id="toggle-feat" type="checkbox">
33
  <label class="toggle-label-feat" for="toggle-feat"></label>
34
  </div>
35
+ <h4>Pathway</h4>
36
  </div>
37
 
38
  <script>
 
40
  var checkbox = document.querySelector("input[name=checkbox-feature]");
41
  checkbox.addEventListener("change", function() {
42
  if (this.checked) {
 
 
43
  Shiny.setInputValue("app-table-feature_radio", "pathway", {priority: "event"});
44
+ } else {
45
+ Shiny.setInputValue("app-table-feature_radio", "gene", {priority: "event"});
46
  }
47
  });
48
 
 
64
  server <- function(id, data) {
65
 
66
  moduleServer(id, function(input, output, session) {
67
+ is_path_tab_active <- reactiveVal(FALSE)
68
  selected_pathways <- reactiveVal(NULL)
69
  selected_genes <- reactiveVal(NULL)
70
 
 
78
  unique(data[, .(gene_name)])
79
  })
80
 
81
+ observeEvent(genes_tab(),{
82
+ req(genes_tab())
83
+ output$table <- render_genes_table(
84
+ genes_tab(),
85
+ selected_genes()
86
  )
87
  })
88
 
 
137
  row <- input$table_cell_clicked[["row"]]
138
  req(gene)
139
  if (is.null(row)) {
 
140
  return(NULL)
141
  }
142
 
 
150
  features[, row_i := rows]
151
  selected_genes(features)
152
  }
 
153
  })
154
 
155
  return(reactiveVal(list(selected_pathways, selected_genes, is_path_tab_active)))