grnsight 6.0.7 → 7.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/.eslintrc.yml +4 -4
  2. package/.github/workflows/node.js.yml +35 -0
  3. package/README.md +1 -1
  4. package/database/README.md +218 -97
  5. package/database/constants.py +42 -0
  6. package/database/filter_update.py +168 -0
  7. package/database/grnsettings-database/README.md +52 -0
  8. package/database/grnsettings-database/schema.sql +4 -0
  9. package/database/loader.py +30 -0
  10. package/database/loader_update.py +36 -0
  11. package/database/network-database/scripts/generate_network.py +15 -23
  12. package/database/network-database/scripts/generate_new_network_version.py +17 -24
  13. package/database/protein-protein-database/README.md +71 -0
  14. package/database/protein-protein-database/schema.sql +37 -0
  15. package/database/protein-protein-database/scripts/generate_protein_network.py +227 -0
  16. package/database/protein-protein-database/scripts/remove_duplicates.sh +4 -0
  17. package/database/utils.py +418 -0
  18. package/package.json +3 -2
  19. package/server/app.js +2 -0
  20. package/server/config/config.js +4 -4
  21. package/server/controllers/additional-sheet-parser.js +2 -1
  22. package/server/controllers/constants.js +5 -0
  23. package/server/controllers/custom-workbook-controller.js +4 -3
  24. package/server/controllers/demo-workbooks.js +1462 -6
  25. package/server/controllers/export-constants.js +3 -2
  26. package/server/controllers/exporters/sif.js +6 -1
  27. package/server/controllers/exporters/xlsx.js +8 -3
  28. package/server/controllers/expression-sheet-parser.js +0 -6
  29. package/server/controllers/grnsettings-database-controller.js +17 -0
  30. package/server/controllers/importers/sif.js +30 -11
  31. package/server/controllers/network-database-controller.js +2 -2
  32. package/server/controllers/network-sheet-parser.js +54 -12
  33. package/server/controllers/protein-database-controller.js +18 -0
  34. package/server/controllers/sif-constants.js +11 -4
  35. package/server/controllers/spreadsheet-controller.js +44 -1
  36. package/server/controllers/workbook-constants.js +21 -4
  37. package/server/dals/expression-dal.js +4 -4
  38. package/server/dals/grnsetting-dal.js +49 -0
  39. package/server/dals/network-dal.js +14 -15
  40. package/server/dals/protein-dal.js +106 -0
  41. package/test/additional-sheet-parser-tests.js +1 -1
  42. package/test/export-tests.js +136 -9
  43. package/test/import-sif-tests.js +67 -13
  44. package/test/test.js +1 -1
  45. package/test-files/additional-sheet-test-files/optimization-parameters-default.xlsx +0 -0
  46. package/test-files/demo-files/18_proteins_81_edges_PPI.xlsx +0 -0
  47. package/test-files/expression-data-test-sheets/expression_sheet_missing_data_ok_export_exact.xlsx +0 -0
  48. package/web-client/config/config.js +4 -4
  49. package/web-client/public/js/api/grnsight-api.js +18 -3
  50. package/web-client/public/js/constants.js +27 -12
  51. package/web-client/public/js/generateNetwork.js +170 -72
  52. package/web-client/public/js/graph.js +424 -161
  53. package/web-client/public/js/grnsight.js +25 -4
  54. package/web-client/public/js/grnstate.js +4 -1
  55. package/web-client/public/js/iframe-coordination.js +3 -3
  56. package/web-client/public/js/setup-handlers.js +76 -61
  57. package/web-client/public/js/setup-load-and-import-handlers.js +32 -7
  58. package/web-client/public/js/update-app.js +119 -28
  59. package/web-client/public/js/upload.js +142 -85
  60. package/web-client/public/js/warnings.js +25 -0
  61. package/web-client/public/lib/bootstrap.file-input/bootstrap.file-input.js +0 -1
  62. package/web-client/public/stylesheets/grnsight.styl +40 -16
  63. package/web-client/views/components/demo.pug +7 -5
  64. package/web-client/views/upload.pug +64 -50
  65. package/database/network-database/scripts/filter_genes.py +0 -76
  66. package/database/network-database/scripts/loader.py +0 -79
  67. package/database/network-database/scripts/loader_updates.py +0 -99
@@ -12,6 +12,7 @@ import {
12
12
  } from "./update-app";
13
13
 
14
14
  import { queryExpressionDatabase } from "./api/grnsight-api.js";
15
+ import { NETWORK_PPI_MODE, NETWORK_GRN_MODE } from "./constants.js";
15
16
 
16
17
 
17
18
  const EXPRESSION_SHEET_SUFFIXES = ["_expression", "_optimized_expression", "_sigmas"];
@@ -118,8 +119,8 @@ export const upload = function () {
118
119
 
119
120
  const updateOptimizationParameters = (finalExportSheets) => {
120
121
  let optimizationParameters = {
121
- data: {
122
- alpha: 0.002,
122
+ data: grnState.mode === NETWORK_GRN_MODE ? {
123
+ alpha: 0.02,
123
124
  "kk_max": 1,
124
125
  MaxIter: 100000000,
125
126
  TolFun: 0.000001,
@@ -131,29 +132,69 @@ export const upload = function () {
131
132
  "make_graphs": 1,
132
133
  "fix_P": 0,
133
134
  "fix_b": 0,
135
+ species: "Saccharomyces cerevisiae",
136
+ "taxon_id":559292,
137
+ workbookType: NETWORK_GRN_MODE
138
+ } : {
139
+ species: "Saccharomyces cerevisiae",
140
+ "taxon_id":559292,
141
+ workbookType: NETWORK_PPI_MODE
134
142
  }
135
143
  };
136
- const expression = Object.keys(finalExportSheets.expression);
137
- let expTimepoints = expression.length > 0 ? finalExportSheets.expression[expression[0]].timePoints : null;
138
- expTimepoints = expTimepoints ? [...(new Set(expTimepoints))].sort(function (a, b) {
139
- return a - b;
140
- }) : null;
141
- const simTimepoints = expTimepoints ? Array.from(Array(expTimepoints[expTimepoints.length - 1] + 1).keys()).filter(x => x % 5 === 0) : null;
142
- const strain = expression.length > 0 ? expression.map(x => removeExpressionSuffix(x)) : null;
143
- if (expTimepoints) {
144
- optimizationParameters.data["expression_timepoints"] = expTimepoints;
145
- }
146
- if (strain) {
147
- optimizationParameters.data.Strain = strain;
148
- }
149
- if (simTimepoints) {
150
- optimizationParameters.data["simulation_timepoints"] = simTimepoints;
144
+ if (grnState.mode === NETWORK_GRN_MODE) {
145
+ const expression = Object.keys(finalExportSheets.expression);
146
+ let expTimepoints = expression.length > 0 ? finalExportSheets.expression[expression[0]].timePoints : null;
147
+ expTimepoints = expTimepoints ? [...(new Set(expTimepoints))].sort(function (a, b) {
148
+ return a - b;
149
+ }) : null;
150
+ const simTimepoints = expTimepoints ? Array.from(Array(expTimepoints[expTimepoints.length - 1] + 1).keys()).filter(x => x % 5 === 0) : null;
151
+ const strain = expression.length > 0 ? expression.map(x => removeExpressionSuffix(x)) : null;
152
+ if (expTimepoints) {
153
+ optimizationParameters.data["expression_timepoints"] = expTimepoints;
154
+ }
155
+ if (strain) {
156
+ optimizationParameters.data.Strain = strain;
157
+ }
158
+ if (simTimepoints) {
159
+ optimizationParameters.data["simulation_timepoints"] = simTimepoints;
160
+ }
151
161
  }
152
- optimizationParameters.data.species = "Saccharomyces cerevisiae";
153
- optimizationParameters.data["taxon_id"] = 559292;
154
162
  return optimizationParameters;
155
163
  };
156
164
 
165
+ // helper method for handleExpressionDataAndExport to reduce indentation
166
+ const expressionDataHandler = (expressionData, sheet, route, extension, sheetType, finalExportSheets) => {
167
+ finalExportSheets.expression[sheet] = expressionData;
168
+ if (finalExportSheets.expression[sheet]) {
169
+ stopLoadingIcon();
170
+ if (!Object.values(finalExportSheets.expression).includes(null)) {
171
+ // we have all of the expression sheets so lets initilize the export process
172
+ Object.keys(finalExportSheets.expression).forEach((sheet) => {
173
+ // make sure that the sheets we queried are populated with the correct data
174
+ if (!(finalExportSheets.expression[sheet].data && finalExportSheets.expression[sheet].timePoints)) {
175
+ // if the resulting query doesn't contains both the timePoint data and
176
+ // the gene data then don't export it. If not don't :)
177
+ finalExportSheets.expression[sheet] = null;
178
+ }
179
+ });
180
+ if (finalExportSheets["optimization_parameters"] === null) {
181
+ finalExportSheets[
182
+ "optimization_parameters"
183
+ ] = updateOptimizationParameters(finalExportSheets);
184
+ }
185
+ grnState.workbook.exportSheets = finalExportSheets;
186
+ exportExcel(route, extension, sheetType);
187
+ }
188
+ }
189
+ };
190
+
191
+ // helper method for handleExpressionDataAndExport and handleExportExcelButtonExport to avoid redundant code
192
+ const expressionExportErrorHandler = (error) => {
193
+ console.log(error.stack);
194
+ console.log(error.name);
195
+ console.log(error.message);
196
+ };
197
+
157
198
  const handleExpressionDataAndExport = (route, extension, sheetType, source, finalExportSheets) => {
158
199
  if (source === "userInput" && grnState.workbook.expression) {
159
200
  // make sure that the optimization parameters sheet is actually properly formatted
@@ -178,42 +219,13 @@ export const upload = function () {
178
219
  return x.name;
179
220
  }).join(","),
180
221
  timepoints: timepointsResponse[dataset]
181
- }).then(function (response) {
182
- finalExportSheets.expression[sheet] = response;
183
- if (finalExportSheets.expression[sheet]) {
184
- stopLoadingIcon();
185
- if (!Object.values(finalExportSheets.expression).includes(null)) {
186
- // we have all of the expression sheets so lets initilize the export process
187
- Object.keys(finalExportSheets.expression).forEach((sheet) => {
188
- // make sure that the sheets we queried are populated with the correct data
189
- if (!(finalExportSheets.expression[sheet].data && finalExportSheets.expression[sheet].timePoints)) {
190
- // if the resulting query doesn't contains both the timePoint data and
191
- // the gene data then don't export it. If not don't :)
192
- finalExportSheets.expression[sheet] = null;
193
- }
194
- });
195
- if (finalExportSheets["optimization_parameters"] === null) {
196
- finalExportSheets["optimization_parameters"] = updateOptimizationParameters(finalExportSheets);
197
- }
198
- grnState.workbook.exportSheets = finalExportSheets;
199
- exportExcel(route, extension, sheetType);
200
- }
201
- }
202
- }).catch(function (error) {
203
- console.log(error.stack);
204
- console.log(error.name);
205
- console.log(error.message);
206
- });
207
- }).catch(function (error) {
208
- console.log(error.stack);
209
- console.log(error.name);
210
- console.log(error.message);
211
- });
222
+ }).then((expressionData) => expressionDataHandler(expressionData, sheet, route, extension, sheetType, finalExportSheets))
223
+ .catch((error) => expressionExportErrorHandler(error));
224
+ }).catch((error) => expressionExportErrorHandler(error));
212
225
  }
213
226
  }
214
227
  };
215
228
 
216
-
217
229
  const handleExportExcelButtonExport = (route, extension, sheetType, source) => {
218
230
  grnState.workbook.exportNetworkType = sheetType;
219
231
  const workbookSheets = $("input[name=workbookSheets]:checked");
@@ -249,7 +261,7 @@ export const upload = function () {
249
261
  } else if (sheet === "network") {
250
262
  finalExportSheets.networks[sheet] = grnState.workbook.network;
251
263
  } else if (sheet === "network_weights") {
252
- finalExportSheets.networks[sheet] = grnState.workbook.networkWeights;
264
+ finalExportSheets.networks[sheet] = grnState.workbook.network; // network_weights is identical to network
253
265
  } else if (sheet === "optimization_diagnostics") { // Get the additional Sheets
254
266
  finalExportSheets[sheet] = grnState.workbook.meta2;
255
267
  } else if (sheet === "optimization_parameters") {
@@ -296,23 +308,27 @@ export const upload = function () {
296
308
 
297
309
  queryExpressionDatabase({
298
310
  type: twoColumnSheetType[sheet],
299
- genes: grnState.workbook.genes.map(x => {
311
+ genes: grnState.workbook.genes
312
+ .map((x) => {
300
313
  return x.name;
301
- }).join(",")
302
- }).then(function (response) {
314
+ })
315
+ .join(","),
316
+ })
317
+ .then(function (response) {
303
318
  result.data = response;
304
319
  finalExportSheets.two_column_sheets[sheet] = result;
305
- if (!Object.values(finalExportSheets.two_column_sheets).includes(null)) {
320
+ if (!Object.values( finalExportSheets.two_column_sheets).includes(null)) {
306
321
  // if we got all of the two column sheets, then proceed with export
307
- handleExpressionDataAndExport(route, extension, sheetType, source, finalExportSheets);
322
+ handleExpressionDataAndExport(
323
+ route,
324
+ extension,
325
+ sheetType,
326
+ source,
327
+ finalExportSheets
328
+ );
308
329
  }
309
-
310
- }).catch(function (error) {
311
- console.log(error.stack);
312
- console.log(error.name);
313
- console.log(error.message);
314
- });
315
-
330
+ })
331
+ .catch(error => expressionExportErrorHandler(error));
316
332
  }
317
333
  }
318
334
  } else {
@@ -366,7 +382,7 @@ export const upload = function () {
366
382
  };
367
383
  };
368
384
 
369
- const createHTMLforForm = () => {
385
+ const createHTMLforGRNForm = () => {
370
386
  const sources = [...new Set(grnState.database.expressionDatasets.map(s => s.slice(0, s.lastIndexOf("_"))))];
371
387
  let result = `
372
388
  <form id=\'exportExcelForm\'>
@@ -414,7 +430,7 @@ export const upload = function () {
414
430
  let networks = [
415
431
  [grnState.workbook.network !== undefined, "network"],
416
432
  [grnState.workbook.networkOptimizedWeights !== undefined, "network_optimized_weights"],
417
- [grnState.workbook.networkWeights !== undefined, "network_weights"]];
433
+ [grnState.workbook.network !== undefined, "network_weights"]]; // network_weights is always available if network is available
418
434
  // networks = networks.filter(x => x !== false);
419
435
  let additionalsheets = grnState.workbook.twoColumnSheets ? [
420
436
  ...Object.keys(grnState.workbook.twoColumnSheets),
@@ -422,7 +438,7 @@ export const upload = function () {
422
438
  ] : [
423
439
  (grnState.workbook.meta2 !== undefined && "optimization_diagnostics")
424
440
  ];
425
- additionalsheets = additionalsheets.filter(x => (x !== false && -1 !== optionalAdditionalSheets.indexOf(x)));
441
+ additionalsheets = additionalsheets.filter(sheet => (sheet && -1 !== optionalAdditionalSheets.indexOf(sheet)));
426
442
  additionalsheets = [...optionalAdditionalSheets, ...additionalsheets].sort();
427
443
  additionalsheets = [...(new Set(additionalsheets))];
428
444
  for (let n of networks) {
@@ -506,6 +522,34 @@ export const upload = function () {
506
522
  `;
507
523
  };
508
524
 
525
+ const createHTMLforProteinProteinPhysicalInteractionForm = () => {
526
+ $(".export-excel-workbook-sheet-option").remove();
527
+ // check if user updated data is selected
528
+ let result = `
529
+ <form id=\'exportExcelForm\'>
530
+ <div class=\'form-group export-form-group\'>
531
+ <p id=\'exportExcelWorkbookSheets\'></p>
532
+ <ul class=\'exportExcelWorkbookSheets\' id=\'export-excel-workbook-sheet-list\' style=\"list-style-type:none;\">
533
+ <p class=\'export-excel-workbook-sheet-option-subheader\'> Network Sheets </p>
534
+ <li class=\'export-excel-workbook-sheet-option\'>
535
+ <input type=\'checkbox\' name=\'workbookSheets\' checked=\"true\" value=\"network\" id=\'exportExcelWorkbookSheet-network\' class=\'export-checkbox\'/>
536
+ <label for=\'exportExcelWorkbookSheet-network\' id=\'exportExcelWorkbookSheet-network-label\' class=\'export-checkbox-label\' >
537
+ network
538
+ </label>
539
+ </li>
540
+ <p class=\'export-excel-workbook-sheet-option-subheader\'> Additional Sheets </p>
541
+ <li class=\'export-excel-workbook-sheet-option\'>
542
+ <input type=\'checkbox\' name=\'workbookSheets\' checked=\"true\" value=\"optimization_parameters\" id=\'exportExcelWorkbookSheet-optimization_parameters\' class=\'export-checkbox\' />
543
+ <label for=\'exportExcelWorkbookSheet-optimization_parameters\' id=\'exportExcelWorkbookSheet-optimization_parameters-label\' class=\'export-checkbox-label\' >
544
+ optimization_parameters
545
+ </label>
546
+ </li>
547
+ </ul>
548
+ </div>
549
+ </form>`;
550
+ return result;
551
+ };
552
+
509
553
 
510
554
  var handleWorkbookSheetCheckboxBehaviour = () => {
511
555
  $("input[name=workbookSheets]").not($("#exportExcelWorkbookSheet-All")).on("click", () => {
@@ -538,24 +582,37 @@ export const upload = function () {
538
582
  $("#Export-Excel-Button").on("click", performExport("export-to-excel", "xlsx", null, source));
539
583
  };
540
584
  const handleExportExcelModal = function () {
541
- $("#exportExcelForm").remove();
542
- $("#exportExcelFooter").remove();
543
- $("#exportExcelQuestions-containter").append(createHTMLforForm);
544
- $("#exportExcelFooter-container").append(createHTMLforModalButtons());
545
- $("#Export-Excel-Button").prop("value", "Export Workbook");
546
- $("#exportExcelExpressionSources").html("Select the Expression Data Source:");
547
- $("#exportExcelExpressionSource-userInput").html(grnState.name);
548
- $("#exportExcelWorkbookSheets").html("Select Workbook Sheets to Export:");
549
- let source = $("input[name=expressionSource]:checked")[0].value;
550
- $("#exportExcelForm").on("change", function () {
551
- const selectedValue = $("input[name=expressionSource]:checked")[0].value;
552
- if (selectedValue !== source) {
553
- source = selectedValue;
554
- $(".export-excel-workbook-sheet-option-subheader").remove();
555
- handleExpressionSheetsFromSource(source);
556
- }
557
- });
558
- handleExpressionSheetsFromSource(source);
585
+ if (grnState.mode === NETWORK_GRN_MODE) {
586
+ $("#exportExcelForm").remove();
587
+ $("#exportExcelFooter").remove();
588
+ $("#exportExcelQuestions-containter").append(createHTMLforGRNForm);
589
+ $("#exportExcelFooter-container").append(createHTMLforModalButtons());
590
+ $("#Export-Excel-Button").prop("value", "Export Workbook");
591
+ $("#exportExcelExpressionSources").html("Select the Expression Data Source:");
592
+ $("#exportExcelExpressionSource-userInput").html(grnState.name);
593
+ $("#exportExcelWorkbookSheets").html("Select Workbook Sheets to Export:");
594
+ let source = $("input[name=expressionSource]:checked")[0].value;
595
+ $("#exportExcelForm").on("change", function () {
596
+ const selectedValue = $("input[name=expressionSource]:checked")[0].value;
597
+ if (selectedValue !== source) {
598
+ source = selectedValue;
599
+ $(".export-excel-workbook-sheet-option-subheader").remove();
600
+ handleExpressionSheetsFromSource(source);
601
+ }
602
+ });
603
+ handleExpressionSheetsFromSource(source);
604
+ } else if (grnState.mode === NETWORK_PPI_MODE) {
605
+ const source = "userInput";
606
+ $("#exportExcelForm").remove();
607
+ $("#exportExcelFooter").remove();
608
+ $("#exportExcelQuestions-containter").append(createHTMLforProteinProteinPhysicalInteractionForm);
609
+ $("#exportExcelFooter-container").append(createHTMLforModalButtons());
610
+ $("#Export-Excel-Button").prop("value", "Export Workbook");
611
+ $("#exportExcelWorkbookSheets").html("Select Workbook Sheets to Export:");
612
+ handleWorkbookSheetCheckboxBehaviour();
613
+ $("#Export-Excel-Button").on("click", performExport("export-to-excel", "xlsx", null, source));
614
+
615
+ }
559
616
  };
560
617
 
561
618
 
@@ -58,3 +58,28 @@ export var displayWarnings = function (warnings) {
58
58
 
59
59
  $("#warningsModal").modal("show");
60
60
  };
61
+
62
+ export var displayPPINodeColorWarning = function (warningDisplayed) {
63
+ if (warningDisplayed) {
64
+ return;
65
+ }
66
+
67
+ $("#warningIntro").html("Protein-protein interaction node coloring warning.");
68
+ $("#warningsList").html(
69
+ ["You are displaying mRNA-level expression data on a protein-protein interaction network.",
70
+ "Please note that this may not be the most appropriate representation of the data."].join(" ")
71
+ );
72
+
73
+ var screenHeight = $(window).height();
74
+ var MIN_SCREEN_HEIGHT = 600;
75
+ var BORDER = 425;
76
+ var setPanel = screenHeight - BORDER + "px";
77
+ var minPanel = MIN_SCREEN_HEIGHT - BORDER + "px";
78
+ if (screenHeight > MIN_SCREEN_HEIGHT) {
79
+ $("#list-frame").css({ height: setPanel });
80
+ } else {
81
+ $("#list-frame").css({ height: minPanel });
82
+ }
83
+
84
+ $("#warningsModal").modal("show");
85
+ };
@@ -84,7 +84,6 @@ $.fn.bootstrapFileInput = function() {
84
84
  });
85
85
 
86
86
  $('body').on('change', '.file-input-wrapper input[type=file]', function(){
87
-
88
87
  var fileName;
89
88
  fileName = $(this).val();
90
89
 
@@ -100,12 +100,6 @@ form label, form span
100
100
  top: 1px
101
101
  margin-right: auto
102
102
  margin-bottom: 10px
103
-
104
- .glyphicon
105
- min-width: 22px
106
-
107
- .glyphicon-searchbar
108
- margin-left: -22px
109
103
 
110
104
  .dropdown-menu > li > a.upload
111
105
  padding-top: 7px
@@ -169,8 +163,9 @@ nav.navbar.navbar-default
169
163
  font-size: 12px
170
164
  display: inline-block
171
165
 
172
- .dropdown-menu > li > a:hover
166
+ .dropdown-menu > li > a:hover, .dropdown-menu > #node-coloring-navbar-options > li > a:hover
173
167
  background-color: #dfebe5
168
+ text-decoration: none;
174
169
 
175
170
  #undoResetButton
176
171
  margin-top: 5px
@@ -252,7 +247,7 @@ nav.navbar.navbar-default
252
247
  .dropdown-submenu
253
248
  position:relative
254
249
 
255
- .dropdown-submenu>.dropdown-menu
250
+ .dropdown-submenu>.dropdown-menu, .dropdown-menu > #node-coloring-navbar-options dropdown-submenu
256
251
  top:0
257
252
  left:100%
258
253
  margin-top:-6px
@@ -261,9 +256,12 @@ nav.navbar.navbar-default
261
256
  -moz-border-radius:0 6px 6px 6px
262
257
  border-radius:0 6px 6px 6px
263
258
 
264
- .dropdown-submenu:hover>.dropdown-menu
259
+ .dropdown-submenu:hover>.dropdown-menu, #node-coloring-navbar-options .dropdown-submenu:hover>.dropdown-menu
265
260
  display:block
266
261
 
262
+ #node-coloring-navbar-options .disabled:hover>.dropdown-menu
263
+ display:none
264
+
267
265
  .dropdown-submenu>a:after
268
266
  display:block
269
267
  content:" "
@@ -280,22 +278,43 @@ nav.navbar.navbar-default
280
278
  .dropdown-submenu:hover>a:after
281
279
  border-left-color:#ffffff
282
280
 
283
- .dropdown-submenu.pull-left
281
+ #node-coloring-navbar-options>li>a
282
+ display: block;
283
+ padding: 3px 20px;
284
+ clear: both;
285
+ font-weight: 400;
286
+ line-height: 1.42857143;
287
+ color: #333;
288
+ white-space: nowrap;
289
+
290
+ #node-coloring-navbar-options>.disabled>a, #node-coloring-navbar-options
291
+ color: #999;
292
+ cursor: not-allowed;
293
+ text-decoration: none;
294
+ aria-disabled: true;
295
+
296
+ .dropdown-menu > #node-coloring-navbar-options > .disabled > a:hover
297
+ background-color: #FFFFFF;
298
+
299
+ .dropdown-submenu.pull-left, #node-coloring-navbar-options .dropdown-submenu.pull-left
284
300
  float:none
285
301
 
286
- .dropdown-submenu.pull-left>.dropdown-menu
302
+ #node-coloring-navbar-options
303
+ cursor: pointer
304
+
305
+ .dropdown-submenu.pull-left>.dropdown-menu, .dropdown-submenu.pull-left, .dropdown-menu #node-coloring-navbar-options .dropdown-submenu.pull-left
287
306
  left:-100%
288
307
  margin-left:10px
289
308
  -webkit-border-radius:6px 0 6px 6px
290
309
  -moz-border-radius:6px 0 6px 6px
291
310
  border-radius:6px 0 6px 6px
292
311
 
293
- .dropdown a.with-input
312
+ .dropdown a.with-input, #node-coloring-navbar-options a.with-input
294
313
  display:flex
295
314
  align-items:center
296
315
  user-select:none
297
316
 
298
- .dropdown a.with-input>*:last-child
317
+ .dropdown a.with-input>*:last-child, #node-coloring-navbar-options a.with-input > *:last-child
299
318
  margin-left:auto
300
319
 
301
320
  // Graph statistics styling is due to absolute position and size of grnsight-container
@@ -471,7 +490,8 @@ path.mousezone
471
490
 
472
491
  #Saccharomyces-cerevisiae
473
492
  color: #AAA
474
- margin-left: 30px
493
+ margin-left: 20px
494
+
475
495
 
476
496
  .create-network-label
477
497
  font-weight: normal
@@ -522,7 +542,8 @@ path.mousezone
522
542
  background-color: #81ecec
523
543
  border: 2px solid #00cec9
524
544
 
525
-
545
+ .glyphicon
546
+ min-width: 22px
526
547
 
527
548
  .sidebar-glyphicon
528
549
  margin-right: 0px
@@ -536,6 +557,7 @@ path.mousezone
536
557
  #enter-search
537
558
  margin-left: 0px
538
559
  height: 100%
560
+ margin-bottom: 2px
539
561
  padding: 0
540
562
  border-color:#aeaeae
541
563
 
@@ -603,10 +625,12 @@ path.mousezone
603
625
  # demoSourceDropdown > option {
604
626
  direction: ltr;
605
627
  }
628
+ # networkModeDropdown > option {
629
+ font-size: 14px
630
+ }
606
631
 
607
632
  .panelDropdownContainer > select {
608
633
  right: auto;
609
- padding: 13px 45px 15px 0px;
610
634
  direction: ltr;
611
635
  }
612
636
 
@@ -1,10 +1,12 @@
1
- ul(class='dropdown-menu' role='menu')
1
+ ul(class='dropdown-menu' role='menu' id="demo-dropdown")
2
2
  li
3
- a(href='#' class='unweighted') Demo #1: Unweighted GRN (15 genes, 28 edges, Dahlquist Lab unpublished data)
3
+ a(href='#' class='unweighted' data-expression="unweighted") Demo #1: Unweighted GRN (15 genes, 28 edges, Dahlquist Lab unpublished data)
4
4
  li
5
- a(href='#' class='weighted') Demo #2: Weighted GRN (15 genes, 28 edges, Dahlquist Lab unpublished data)
5
+ a(href='#' class='weighted' data-expression="weighted") Demo #2: Weighted GRN (15 genes, 28 edges, Dahlquist Lab unpublished data)
6
6
  li
7
- a(href='#' class='schadeInput') Demo #3: Unweighted GRN (21 genes, 31 edges)
7
+ a(href='#' class='schadeInput' data-expression="schadeInput") Demo #3: Unweighted GRN (21 genes, 31 edges)
8
8
  li
9
- a(href='#' class='schadeOutput') Demo #4: Weighted GRN (21 genes, 31 edges, Schade et al. 2004 data)
9
+ a(href='#' class='schadeOutput' data-expression="schadeOutput") Demo #4: Weighted GRN (21 genes, 31 edges, Schade et al. 2004 data)
10
+ li
11
+ a(href='#' class='ppi' data-expression="ppi") Demo #5: PPI (18 proteins, 81 edges)
10
12