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.
- package/.eslintrc.yml +4 -4
- package/.github/workflows/node.js.yml +35 -0
- package/README.md +1 -1
- package/database/README.md +218 -97
- package/database/constants.py +42 -0
- package/database/filter_update.py +168 -0
- package/database/grnsettings-database/README.md +52 -0
- package/database/grnsettings-database/schema.sql +4 -0
- package/database/loader.py +30 -0
- package/database/loader_update.py +36 -0
- package/database/network-database/scripts/generate_network.py +15 -23
- package/database/network-database/scripts/generate_new_network_version.py +17 -24
- package/database/protein-protein-database/README.md +71 -0
- package/database/protein-protein-database/schema.sql +37 -0
- package/database/protein-protein-database/scripts/generate_protein_network.py +227 -0
- package/database/protein-protein-database/scripts/remove_duplicates.sh +4 -0
- package/database/utils.py +418 -0
- package/package.json +3 -2
- package/server/app.js +2 -0
- package/server/config/config.js +4 -4
- package/server/controllers/additional-sheet-parser.js +2 -1
- package/server/controllers/constants.js +5 -0
- package/server/controllers/custom-workbook-controller.js +4 -3
- package/server/controllers/demo-workbooks.js +1462 -6
- package/server/controllers/export-constants.js +3 -2
- package/server/controllers/exporters/sif.js +6 -1
- package/server/controllers/exporters/xlsx.js +8 -3
- package/server/controllers/expression-sheet-parser.js +0 -6
- package/server/controllers/grnsettings-database-controller.js +17 -0
- package/server/controllers/importers/sif.js +30 -11
- package/server/controllers/network-database-controller.js +2 -2
- package/server/controllers/network-sheet-parser.js +54 -12
- package/server/controllers/protein-database-controller.js +18 -0
- package/server/controllers/sif-constants.js +11 -4
- package/server/controllers/spreadsheet-controller.js +44 -1
- package/server/controllers/workbook-constants.js +21 -4
- package/server/dals/expression-dal.js +4 -4
- package/server/dals/grnsetting-dal.js +49 -0
- package/server/dals/network-dal.js +14 -15
- package/server/dals/protein-dal.js +106 -0
- package/test/additional-sheet-parser-tests.js +1 -1
- package/test/export-tests.js +136 -9
- package/test/import-sif-tests.js +67 -13
- package/test/test.js +1 -1
- package/test-files/additional-sheet-test-files/optimization-parameters-default.xlsx +0 -0
- package/test-files/demo-files/18_proteins_81_edges_PPI.xlsx +0 -0
- package/test-files/expression-data-test-sheets/expression_sheet_missing_data_ok_export_exact.xlsx +0 -0
- package/web-client/config/config.js +4 -4
- package/web-client/public/js/api/grnsight-api.js +18 -3
- package/web-client/public/js/constants.js +27 -12
- package/web-client/public/js/generateNetwork.js +170 -72
- package/web-client/public/js/graph.js +424 -161
- package/web-client/public/js/grnsight.js +25 -4
- package/web-client/public/js/grnstate.js +4 -1
- package/web-client/public/js/iframe-coordination.js +3 -3
- package/web-client/public/js/setup-handlers.js +76 -61
- package/web-client/public/js/setup-load-and-import-handlers.js +32 -7
- package/web-client/public/js/update-app.js +119 -28
- package/web-client/public/js/upload.js +142 -85
- package/web-client/public/js/warnings.js +25 -0
- package/web-client/public/lib/bootstrap.file-input/bootstrap.file-input.js +0 -1
- package/web-client/public/stylesheets/grnsight.styl +40 -16
- package/web-client/views/components/demo.pug +7 -5
- package/web-client/views/upload.pug +64 -50
- package/database/network-database/scripts/filter_genes.py +0 -76
- package/database/network-database/scripts/loader.py +0 -79
- package/database/network-database/scripts/loader_updates.py +0 -99
|
@@ -1,13 +1,34 @@
|
|
|
1
|
+
/* eslint-disable func-style */
|
|
1
2
|
import { displayStatistics } from "./graph-statistics"; // eslint-disable-line no-unused-vars
|
|
2
3
|
import { upload } from "./upload";
|
|
3
4
|
import { generateNetwork } from "./generateNetwork";
|
|
4
5
|
|
|
5
6
|
import { grnState } from "./grnstate";
|
|
7
|
+
import { queryDefaultDataset } from "./api/grnsight-api.js";
|
|
6
8
|
import { updateApp } from "./update-app";
|
|
7
9
|
import { setupHandlers } from "./setup-handlers";
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
async function updateDefaultDataset () {
|
|
12
|
+
try {
|
|
13
|
+
const response = await queryDefaultDataset({type:"DefaultDataset"});
|
|
14
|
+
grnState.database = response;
|
|
15
|
+
return response.defaultDataset.join();
|
|
16
|
+
} catch (error) {
|
|
17
|
+
console.log(error.stack);
|
|
18
|
+
console.log(error.name);
|
|
19
|
+
console.log(error.message);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
11
22
|
|
|
12
|
-
|
|
13
|
-
|
|
23
|
+
async function initializeGrnsight () {
|
|
24
|
+
const defaultDataset = await updateDefaultDataset();
|
|
25
|
+
grnState.defaultDataset = defaultDataset;
|
|
26
|
+
|
|
27
|
+
setupHandlers(grnState);
|
|
28
|
+
updateApp(grnState);
|
|
29
|
+
|
|
30
|
+
upload();
|
|
31
|
+
generateNetwork();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
initializeGrnsight();
|
|
@@ -10,7 +10,8 @@ import {
|
|
|
10
10
|
DEFAULT_MAX_LOG_FOLD_CHANGE,
|
|
11
11
|
DEFAULT_ZOOM_VALUE,
|
|
12
12
|
FORCE_GRAPH,
|
|
13
|
-
VIEWPORT_INIT
|
|
13
|
+
VIEWPORT_INIT,
|
|
14
|
+
NETWORK_GRN_MODE
|
|
14
15
|
} from "./constants";
|
|
15
16
|
let currentWorkbook = null;
|
|
16
17
|
|
|
@@ -41,6 +42,7 @@ const annotateLinks = workbook => {
|
|
|
41
42
|
};
|
|
42
43
|
|
|
43
44
|
export const grnState = {
|
|
45
|
+
mode: NETWORK_GRN_MODE, // GRNsight will display GRN view unless specified
|
|
44
46
|
name: null,
|
|
45
47
|
simulation: undefined,
|
|
46
48
|
newWorkbook: false,
|
|
@@ -83,6 +85,7 @@ export const grnState = {
|
|
|
83
85
|
lastDataset: null,
|
|
84
86
|
bottomDataSameAsTop: true,
|
|
85
87
|
nodeColoringOptions: [],
|
|
88
|
+
ppiNodeColorWarningDisplayed: false,
|
|
86
89
|
},
|
|
87
90
|
|
|
88
91
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* loaded into the web browser when this script executes.
|
|
12
12
|
*/
|
|
13
13
|
iFrameResize({
|
|
14
|
-
checkOrigin: ["https://dondi.github.io", "https://grnsight.
|
|
14
|
+
checkOrigin: ["https://dondi.github.io", "https://grnsight.lmucs.org"],
|
|
15
15
|
widthCalculationMethod: "taggedElement",
|
|
16
16
|
heightCalculationMethod: "taggedElement",
|
|
17
17
|
sizeWidth: true,
|
|
@@ -40,7 +40,7 @@ const sendDimensions = (destination, origin) => {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
window.addEventListener("message", event => {
|
|
43
|
-
if (event.origin.indexOf("https://grnsight.
|
|
43
|
+
if (event.origin.indexOf("https://grnsight.lmucs.org") !== 0) {
|
|
44
44
|
// Ignore any message that did not originate from the GRNsight web client server.
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
@@ -51,5 +51,5 @@ window.addEventListener("message", event => {
|
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
window.addEventListener("resize", () => sendDimensions(
|
|
54
|
-
document.querySelector("iframe.embedded-demo").contentWindow, "https://grnsight.
|
|
54
|
+
document.querySelector("iframe.embedded-demo").contentWindow, "https://grnsight.lmucs.org"
|
|
55
55
|
));
|
|
@@ -94,13 +94,11 @@ export const setupHandlers = grnState => {
|
|
|
94
94
|
window.document.body.appendChild(emptySvg);
|
|
95
95
|
var emptySvgDeclarationComputed = getComputedStyle(emptySvg);
|
|
96
96
|
|
|
97
|
-
const traverse =
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (node && node.hasChildNodes()) {
|
|
103
|
-
var child = node.firstChild;
|
|
97
|
+
const traverse = (node) => {
|
|
98
|
+
const tree = [];
|
|
99
|
+
const visit = (currentNode) => {
|
|
100
|
+
if (currentNode && currentNode.hasChildNodes()) {
|
|
101
|
+
let child = currentNode.firstChild;
|
|
104
102
|
while (child) {
|
|
105
103
|
if (child.nodeType === 1 && child.nodeName !== "SCRIPT") {
|
|
106
104
|
tree.push(child);
|
|
@@ -110,38 +108,39 @@ export const setupHandlers = grnState => {
|
|
|
110
108
|
}
|
|
111
109
|
}
|
|
112
110
|
};
|
|
113
|
-
visit(
|
|
111
|
+
visit(node);
|
|
114
112
|
return tree;
|
|
115
113
|
};
|
|
116
114
|
|
|
117
115
|
const explicitlySetStyle = element => {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
let
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
for (i = 0, len = cSSStyleDeclarationComputed.length; i < len; i++) {
|
|
126
|
-
key = cSSStyleDeclarationComputed[i];
|
|
127
|
-
value = cSSStyleDeclarationComputed.getPropertyValue(key);
|
|
116
|
+
const cssStyleDeclarationComputed = window.getComputedStyle(element);
|
|
117
|
+
const computedStyleObj = {};
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
for (let i = 0; i < cssStyleDeclarationComputed.length; i++) {
|
|
121
|
+
const key = cssStyleDeclarationComputed[i];
|
|
122
|
+
const value = cssStyleDeclarationComputed.getPropertyValue(key);
|
|
128
123
|
if (value !== emptySvgDeclarationComputed.getPropertyValue(key)) {
|
|
129
124
|
// Don't set computed style of width and height. Makes SVG elmements disappear.
|
|
130
125
|
if ((key !== "height") && (key !== "width")) {
|
|
131
|
-
|
|
126
|
+
computedStyleObj[key] = value;
|
|
132
127
|
}
|
|
133
128
|
|
|
134
129
|
}
|
|
135
130
|
}
|
|
136
|
-
|
|
131
|
+
|
|
132
|
+
if (element.classList.contains("weight")) {
|
|
133
|
+
computedStyleObj["visibility"] = "hidden";
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (computedStyleObj) {
|
|
137
|
+
Object.assign(element.style, computedStyleObj);
|
|
138
|
+
}
|
|
137
139
|
};
|
|
138
140
|
|
|
139
141
|
// hardcode computed css styles inside svg
|
|
140
142
|
var allElements = traverse(svg);
|
|
141
|
-
|
|
142
|
-
while (i--) {
|
|
143
|
-
explicitlySetStyle(allElements[i]);
|
|
144
|
-
}
|
|
143
|
+
allElements.forEach(explicitlySetStyle);
|
|
145
144
|
};
|
|
146
145
|
|
|
147
146
|
const sourceAttributeSetter = (svg) => {
|
|
@@ -160,7 +159,7 @@ export const setupHandlers = grnState => {
|
|
|
160
159
|
};
|
|
161
160
|
|
|
162
161
|
const exportSVG = (svgElement, name) => {
|
|
163
|
-
let source = svgElement;
|
|
162
|
+
let source = svgElement.cloneNode(true);
|
|
164
163
|
|
|
165
164
|
sourceAttributeSetter(source);
|
|
166
165
|
setInlineStyles(source);
|
|
@@ -185,10 +184,30 @@ export const setupHandlers = grnState => {
|
|
|
185
184
|
const imgData = canvas.toDataURL("image/png");
|
|
186
185
|
|
|
187
186
|
const pdf = new jsPDF("l", "mm", "letter");
|
|
188
|
-
const
|
|
189
|
-
const
|
|
187
|
+
const pdfWidth = pdf.internal.pageSize.getWidth();
|
|
188
|
+
const pdfHeight = pdf.internal.pageSize.getHeight();
|
|
190
189
|
|
|
191
|
-
|
|
190
|
+
const svgWidth = canvas.width;
|
|
191
|
+
const svgHeight = canvas.height;
|
|
192
|
+
|
|
193
|
+
const aspectRatio = svgWidth / svgHeight;
|
|
194
|
+
let scaledWidth = pdfWidth;
|
|
195
|
+
// ratio = width/height --> height = width/ratio
|
|
196
|
+
let scaledHeight = scaledWidth / aspectRatio;
|
|
197
|
+
|
|
198
|
+
if (scaledHeight > pdfHeight) {
|
|
199
|
+
scaledHeight = pdfHeight;
|
|
200
|
+
scaledWidth = pdfHeight * aspectRatio;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
pdf.addImage(
|
|
204
|
+
imgData,
|
|
205
|
+
"PNG",
|
|
206
|
+
(pdfWidth - scaledWidth) / 2,
|
|
207
|
+
(pdfHeight - scaledHeight) / 2,
|
|
208
|
+
scaledWidth,
|
|
209
|
+
scaledHeight
|
|
210
|
+
);
|
|
192
211
|
pdf.save(name);
|
|
193
212
|
};
|
|
194
213
|
|
|
@@ -209,7 +228,7 @@ export const setupHandlers = grnState => {
|
|
|
209
228
|
$(EXPORT_TO_PNG).click(() => {
|
|
210
229
|
var svgContainer = document.getElementById("exportContainer");
|
|
211
230
|
var editedName = grnState.name.replace(determineFileType(grnState.name), "") + ".png";
|
|
212
|
-
saveSvgAsPng(svgContainer, editedName);
|
|
231
|
+
saveSvgAsPng(svgContainer, editedName, { backgroundColor: "white"});
|
|
213
232
|
});
|
|
214
233
|
|
|
215
234
|
$(EXPORT_TO_SVG).click(() => {
|
|
@@ -225,29 +244,40 @@ export const setupHandlers = grnState => {
|
|
|
225
244
|
});
|
|
226
245
|
|
|
227
246
|
// Node Coloring
|
|
228
|
-
|
|
229
|
-
grnState.nodeColoring.nodeColoringEnabled = !grnState.nodeColoring.nodeColoringEnabled;
|
|
230
|
-
updateApp(grnState);
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
$(TOP_DATASET_SELECTION_SIDEBAR).change(() => {
|
|
234
|
-
var selection = $(TOP_DATASET_SELECTION_SIDEBAR).find(":selected").attr("value");
|
|
247
|
+
const updateTopDatasetSelection = (selection) => {
|
|
235
248
|
grnState.nodeColoring.topDataset = selection;
|
|
236
249
|
if (grnState.nodeColoring.bottomDataSameAsTop) {
|
|
237
250
|
grnState.nodeColoring.bottomDataset = selection;
|
|
238
251
|
}
|
|
239
252
|
updateApp(grnState);
|
|
240
|
-
}
|
|
253
|
+
};
|
|
241
254
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
255
|
+
const updateBottomDatasetSelection = (selection) => {
|
|
256
|
+
grnState.nodeColoring.bottomDataset = selection;
|
|
257
|
+
if (selection === "Same as Top Dataset") {
|
|
258
|
+
grnState.nodeColoring.bottomDataset = grnState.nodeColoring.topDataset;
|
|
259
|
+
grnState.nodeColoring.bottomDataSameAsTop = true;
|
|
260
|
+
} else {
|
|
261
|
+
grnState.nodeColoring.bottomDataSameAsTop = false;
|
|
246
262
|
grnState.nodeColoring.bottomDataset = selection;
|
|
247
263
|
}
|
|
248
264
|
updateApp(grnState);
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
$(NODE_COLORING_TOGGLE_CLASS).click(() => {
|
|
268
|
+
grnState.nodeColoring.nodeColoringEnabled = !grnState.nodeColoring.nodeColoringEnabled;
|
|
269
|
+
updateApp(grnState);
|
|
249
270
|
});
|
|
250
271
|
|
|
272
|
+
$(TOP_DATASET_SELECTION_SIDEBAR).change(() => {
|
|
273
|
+
const selection = $(TOP_DATASET_SELECTION_SIDEBAR).find(":selected").attr("value");
|
|
274
|
+
updateTopDatasetSelection(selection);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
$(TOP_DATASET_SELECTION_MENU).click((event) => {
|
|
278
|
+
const selection = event.target.dataset.expression;
|
|
279
|
+
updateTopDatasetSelection(selection);
|
|
280
|
+
});
|
|
251
281
|
$(AVG_REPLICATE_VALS_TOP_SIDEBAR).change(() => {
|
|
252
282
|
grnState.nodeColoring.averageTopDataset = !grnState.nodeColoring.averageTopDataset;
|
|
253
283
|
updateApp(grnState);
|
|
@@ -259,28 +289,13 @@ export const setupHandlers = grnState => {
|
|
|
259
289
|
});
|
|
260
290
|
|
|
261
291
|
$(BOTTOM_DATASET_SELECTION_SIDEBAR).change(() => {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if (grnState.nodeColoring.bottomDataset === "Same as Top Dataset") {
|
|
265
|
-
grnState.nodeColoring.bottomDataset = grnState.nodeColoring.topDataset;
|
|
266
|
-
grnState.nodeColoring.bottomDataSameAsTop = true;
|
|
267
|
-
} else {
|
|
268
|
-
grnState.nodeColoring.bottomDataSameAsTop = false;
|
|
269
|
-
}
|
|
270
|
-
updateApp(grnState);
|
|
292
|
+
const selection = $(BOTTOM_DATASET_SELECTION_SIDEBAR).find(":selected").attr("value");
|
|
293
|
+
updateBottomDatasetSelection(selection);
|
|
271
294
|
});
|
|
272
295
|
|
|
273
|
-
$(BOTTOM_DATASET_SELECTION_MENU).click(() => {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
if (selection === "Same as Top Dataset") {
|
|
277
|
-
grnState.nodeColoring.bottomDataset = grnState.nodeColoring.topDataset;
|
|
278
|
-
grnState.nodeColoring.bottomDataSameAsTop = true;
|
|
279
|
-
} else {
|
|
280
|
-
grnState.nodeColoring.bottomDataSameAsTop = false;
|
|
281
|
-
grnState.nodeColoring.bottomDataset = selection;
|
|
282
|
-
}
|
|
283
|
-
updateApp(grnState);
|
|
296
|
+
$(BOTTOM_DATASET_SELECTION_MENU).click((event) => {
|
|
297
|
+
const selection = event.target.dataset.expression;
|
|
298
|
+
updateBottomDatasetSelection(selection);
|
|
284
299
|
});
|
|
285
300
|
|
|
286
301
|
$(AVG_REPLICATE_VALS_BOTTOM_SIDEBAR).change(() => {
|
|
@@ -10,6 +10,11 @@ import {
|
|
|
10
10
|
UNWEIGHTED_DEMO_NAME,
|
|
11
11
|
SCHADE_INPUT_NAME,
|
|
12
12
|
SCHADE_OUTPUT_NAME,
|
|
13
|
+
PPI_DEMO_PATH,
|
|
14
|
+
PPI_DEMO_NAME,
|
|
15
|
+
FORCE_GRAPH,
|
|
16
|
+
NETWORK_PPI_MODE,
|
|
17
|
+
NETWORK_GRN_MODE
|
|
13
18
|
} from "./constants";
|
|
14
19
|
import { getWorkbookFromForm, getWorkbookFromUrl } from "./api/grnsight-api";
|
|
15
20
|
|
|
@@ -19,6 +24,7 @@ const demoFiles = [
|
|
|
19
24
|
WEIGHTED_DEMO_PATH,
|
|
20
25
|
SCHADE_INPUT_PATH,
|
|
21
26
|
SCHADE_OUTPUT_PATH,
|
|
27
|
+
PPI_DEMO_PATH
|
|
22
28
|
];
|
|
23
29
|
|
|
24
30
|
const submittedFilename = ($upload) => {
|
|
@@ -133,9 +139,21 @@ export const setupLoadAndImportHandlers = (grnState) => {
|
|
|
133
139
|
break;
|
|
134
140
|
case SCHADE_OUTPUT_PATH:
|
|
135
141
|
grnState.name = SCHADE_OUTPUT_NAME;
|
|
142
|
+
break;
|
|
143
|
+
case PPI_DEMO_PATH:
|
|
144
|
+
grnState.name = PPI_DEMO_NAME;
|
|
145
|
+
break;
|
|
136
146
|
}
|
|
137
147
|
}
|
|
138
148
|
grnState.workbook = workbook;
|
|
149
|
+
|
|
150
|
+
if (grnState.name.includes(".sif")) {
|
|
151
|
+
grnState.mode = workbook.workbookType;
|
|
152
|
+
} else if (grnState.name.includes(".graphml")) {
|
|
153
|
+
grnState.mode = NETWORK_GRN_MODE;
|
|
154
|
+
} else {
|
|
155
|
+
grnState.mode = workbook.meta.data.workbookType;
|
|
156
|
+
}
|
|
139
157
|
grnState.workbook.expressionNames = Object.keys(workbook.expression);
|
|
140
158
|
if (uploadRoute !== "upload") {
|
|
141
159
|
grnState.annotateLinks();
|
|
@@ -153,8 +171,8 @@ export const setupLoadAndImportHandlers = (grnState) => {
|
|
|
153
171
|
* for helping to resolve this.
|
|
154
172
|
*/
|
|
155
173
|
|
|
156
|
-
// $(".upload").change(uploadHandler(loadGrn));
|
|
157
174
|
$("body").on("change", ".upload", uploadHandler(loadGrn));
|
|
175
|
+
|
|
158
176
|
const loadDemo = (url, value) => {
|
|
159
177
|
$("#demoSourceDropdown option[value='" + value.substring(1) + "']").prop(
|
|
160
178
|
"selected",
|
|
@@ -162,14 +180,16 @@ export const setupLoadAndImportHandlers = (grnState) => {
|
|
|
162
180
|
);
|
|
163
181
|
loadGrn(url);
|
|
164
182
|
reloader = () => loadGrn(url);
|
|
165
|
-
|
|
183
|
+
grnState.graphLayout = FORCE_GRAPH;
|
|
166
184
|
$("a.upload > input[type=file]").val("");
|
|
167
185
|
};
|
|
168
186
|
|
|
169
187
|
const initializeDemoFile = (demoClass, demoPath, demoName) => {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
188
|
+
$(".dropdown-menu li a").on("click", (event) => {
|
|
189
|
+
const selected = event.target.dataset.expression;
|
|
190
|
+
if (`.${selected}` === demoClass) {
|
|
191
|
+
loadDemo(demoPath, demoClass, demoName);
|
|
192
|
+
}
|
|
173
193
|
});
|
|
174
194
|
$("#demoSourceDropdown").on("change", () => {
|
|
175
195
|
const selected = `.${$("#demoSourceDropdown").val()}`;
|
|
@@ -200,11 +220,16 @@ export const setupLoadAndImportHandlers = (grnState) => {
|
|
|
200
220
|
export const responseCustomWorkbookData = (grnState, queryURL, name) => {
|
|
201
221
|
const uploadRoute = queryURL;
|
|
202
222
|
getWorkbookFromUrl(uploadRoute).done((workbook) => {
|
|
223
|
+
if (workbook.meta.data.workbookType === NETWORK_PPI_MODE) {
|
|
224
|
+
grnState.mode = workbook.meta.data.workbookType;
|
|
225
|
+
} else {
|
|
226
|
+
grnState.mode = NETWORK_GRN_MODE;
|
|
227
|
+
}
|
|
203
228
|
grnState.name = name;
|
|
204
229
|
grnState.workbook = workbook;
|
|
205
230
|
// Reset the node coloring dataset selection
|
|
206
|
-
grnState.nodeColoring.topDataset =
|
|
207
|
-
grnState.nodeColoring.bottomDataset =
|
|
231
|
+
grnState.nodeColoring.topDataset = grnState.defaultDataset;
|
|
232
|
+
grnState.nodeColoring.bottomDataset = grnState.defaultDataset;
|
|
208
233
|
grnState.annotateLinks();
|
|
209
234
|
disableUpload(false);
|
|
210
235
|
updateApp(grnState);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { drawGraph, updaters } from "./graph";
|
|
2
2
|
import { uploadState } from "./upload";
|
|
3
|
-
import { displayWarnings } from "./warnings";
|
|
3
|
+
import { displayWarnings, displayPPINodeColorWarning } from "./warnings";
|
|
4
4
|
import { max } from "d3-array";
|
|
5
5
|
import { grnState } from "./grnstate";
|
|
6
6
|
|
|
@@ -45,12 +45,11 @@ import {
|
|
|
45
45
|
CHARGE_SLIDER_SIDEBAR,
|
|
46
46
|
CHARGE_MENU,
|
|
47
47
|
CHARGE_VALUE,
|
|
48
|
-
GRID_LAYOUT_MENU,
|
|
49
|
-
FORCE_GRAPH_MENU,
|
|
50
48
|
LAYOUT_SIDEBAR_PANEL,
|
|
51
49
|
NODE_COLORING_MENU,
|
|
52
50
|
NODE_COLORING_TOGGLE_MENU,
|
|
53
51
|
NODE_COLORING_MENU_CLASS,
|
|
52
|
+
NODE_COLORING_NAVBAR_OPTIONS,
|
|
54
53
|
NODE_COLORING_SIDEBAR_BODY,
|
|
55
54
|
NODE_COLORING_SIDEBAR_PANEL,
|
|
56
55
|
NODE_COLORING_SIDEBAR_HEADER_LINK,
|
|
@@ -104,6 +103,13 @@ import {
|
|
|
104
103
|
VIEWPORT_SIZE_L_SIDEBAR,
|
|
105
104
|
VIEWPORT_SIZE_FIT_SIDEBAR,
|
|
106
105
|
VIEWPORT_INIT,
|
|
106
|
+
NETWORK_MODE_DROPDOWN,
|
|
107
|
+
NETWORK_MODE_CLASS,
|
|
108
|
+
NETWORK_MODE_PROTEIN_PHYS,
|
|
109
|
+
NETWORK_MODE_GRN,
|
|
110
|
+
EXPORT_TO_UNWEIGHTED_GML_MENU,
|
|
111
|
+
NETWORK_GRN_MODE,
|
|
112
|
+
NETWORK_PPI_MODE,
|
|
107
113
|
// EXPRESSION_SOURCE,
|
|
108
114
|
} from "./constants";
|
|
109
115
|
|
|
@@ -128,7 +134,6 @@ const refreshApp = () => {
|
|
|
128
134
|
|
|
129
135
|
const displayworkbook = (workbook, name) => {
|
|
130
136
|
uploadState.currentWorkbook = workbook;
|
|
131
|
-
// console.log("workbook: ", workbook); // Display the workbook in the console
|
|
132
137
|
$("#graph-metadata").html(workbook.genes.length + " nodes<br>" + workbook.links.length + " edges");
|
|
133
138
|
|
|
134
139
|
if (workbook.warnings.length > 0) {
|
|
@@ -379,6 +384,14 @@ const enableNodeColoringUI = function () {
|
|
|
379
384
|
$(LOG_FOLD_CHANGE_MAX_VALUE_HEADER).removeClass("hidden");
|
|
380
385
|
};
|
|
381
386
|
|
|
387
|
+
const adjustGeneNameForExpression = function (gene) {
|
|
388
|
+
const geneName = gene.name;
|
|
389
|
+
return grnState.workbook.meta.data.workbookType === NETWORK_PPI_MODE &&
|
|
390
|
+
geneName.endsWith("p")
|
|
391
|
+
? geneName.slice(0, -1)
|
|
392
|
+
: geneName;
|
|
393
|
+
};
|
|
394
|
+
|
|
382
395
|
const loadExpressionDatabase = function (isTopDataset) {
|
|
383
396
|
const dataset = isTopDataset ? grnState.nodeColoring.topDataset : grnState.nodeColoring.bottomDataset;
|
|
384
397
|
startLoadingIcon();
|
|
@@ -389,7 +402,9 @@ const loadExpressionDatabase = function (isTopDataset) {
|
|
|
389
402
|
queryExpressionDatabase({
|
|
390
403
|
type:"ExpressionData",
|
|
391
404
|
dataset,
|
|
392
|
-
genes
|
|
405
|
+
genes: grnState.workbook.genes
|
|
406
|
+
.map(adjustGeneNameForExpression)
|
|
407
|
+
.join(","),
|
|
393
408
|
timepoints: timepointsResponse[dataset]
|
|
394
409
|
}).then(function (response) {
|
|
395
410
|
if (isTopDataset) {
|
|
@@ -417,13 +432,11 @@ const loadExpressionDatabase = function (isTopDataset) {
|
|
|
417
432
|
const updateSliderState = slidersLocked => {
|
|
418
433
|
const forceGraphDisabled = grnState.graphLayout === GRID_LAYOUT || slidersLocked;
|
|
419
434
|
if (forceGraphDisabled) {
|
|
420
|
-
$(`${LOCK_SLIDERS_MENU} span`).removeClass("invisible").addClass("glyphicon-ok");
|
|
421
435
|
$(RESET_SLIDERS_MENU).parent().addClass("disabled");
|
|
422
436
|
$(UNDO_SLIDERS_RESET_MENU).parent().addClass("disabled");
|
|
423
437
|
$(LINK_DIST_CLASS).parent().addClass("disabled");
|
|
424
438
|
$(CHARGE_CLASS).parent().addClass("disabled");
|
|
425
439
|
} else {
|
|
426
|
-
$(`${LOCK_SLIDERS_MENU} span`).removeClass("glyphicon-ok").addClass("invisible");
|
|
427
440
|
$(RESET_SLIDERS_MENU).parent().removeClass("disabled");
|
|
428
441
|
$(UNDO_SLIDERS_RESET_MENU).parent().removeClass("disabled");
|
|
429
442
|
$(LINK_DIST_CLASS).parent().removeClass("disabled");
|
|
@@ -433,6 +446,17 @@ const updateSliderState = slidersLocked => {
|
|
|
433
446
|
$(LINK_DIST_SLIDER_SIDEBAR).prop("disabled", forceGraphDisabled);
|
|
434
447
|
$(CHARGE_SLIDER_SIDEBAR).prop("disabled", forceGraphDisabled);
|
|
435
448
|
$(RESET_SLIDERS_SIDEBAR).prop("disabled", forceGraphDisabled);
|
|
449
|
+
|
|
450
|
+
if (slidersLocked) {
|
|
451
|
+
$(`${LOCK_SLIDERS_MENU} span`)
|
|
452
|
+
.removeClass("invisible")
|
|
453
|
+
.addClass("glyphicon-ok");
|
|
454
|
+
} else {
|
|
455
|
+
$(`${LOCK_SLIDERS_MENU} span`)
|
|
456
|
+
.removeClass("glyphicon-ok")
|
|
457
|
+
.addClass("invisible");
|
|
458
|
+
}
|
|
459
|
+
|
|
436
460
|
$(LOCK_SLIDERS_BUTTON).prop("checked", slidersLocked);
|
|
437
461
|
|
|
438
462
|
if (!grnState.showUndoReset) {
|
|
@@ -488,15 +512,13 @@ const toggleLayout = (on, off) => {
|
|
|
488
512
|
}
|
|
489
513
|
};
|
|
490
514
|
|
|
491
|
-
const
|
|
492
|
-
|
|
493
|
-
toggleLayout(FORCE_GRAPH_MENU, GRID_LAYOUT_MENU);
|
|
515
|
+
export const hasExpressionData = (sheets) => {
|
|
516
|
+
return Object.keys(sheets).some(property => property.match(ENDS_IN_EXPRESSION_REGEXP));
|
|
494
517
|
};
|
|
495
518
|
|
|
496
|
-
const
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
};
|
|
519
|
+
const updatetoForceGraph = () => {};
|
|
520
|
+
|
|
521
|
+
const updatetoGridLayout = () => {};
|
|
500
522
|
|
|
501
523
|
// Node Coloring Functions
|
|
502
524
|
const showNodeColoringMenus = () => {
|
|
@@ -510,8 +532,8 @@ const showNodeColoringMenus = () => {
|
|
|
510
532
|
const disableNodeColoringMenus = () => {
|
|
511
533
|
$(NODE_COLORING_SIDEBAR_PANEL).addClass("disabled");
|
|
512
534
|
$(NODE_COLORING_SIDEBAR_PANEL).removeClass("in");
|
|
513
|
-
$(NODE_COLORING_MENU).addClass("disabled");
|
|
514
535
|
$(NODE_COLORING_MENU_CLASS).addClass("disabled");
|
|
536
|
+
$(NODE_COLORING_MENU).addClass("disabled");
|
|
515
537
|
$(NODE_COLORING_SIDEBAR_HEADER_LINK).attr("data-toggle", "");
|
|
516
538
|
};
|
|
517
539
|
|
|
@@ -519,18 +541,67 @@ const isNewWorkbook = (name) => {
|
|
|
519
541
|
return grnState.nodeColoring.lastDataset === null || grnState.nodeColoring.lastDataset !== name;
|
|
520
542
|
};
|
|
521
543
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
544
|
+
// Workbook Mode Functions
|
|
545
|
+
const updateModeViews = () =>{
|
|
546
|
+
// Select correct dropdown item
|
|
547
|
+
$(`${NETWORK_MODE_DROPDOWN} option`).removeAttr("selected");
|
|
548
|
+
$(`${NETWORK_MODE_DROPDOWN} option[value="${grnState.mode}"]`).prop("selected", true);
|
|
549
|
+
// Select the correct menu items
|
|
550
|
+
$(`${NETWORK_MODE_CLASS} option`).removeAttr("checked");
|
|
551
|
+
if (grnState.mode === NETWORK_GRN_MODE) {
|
|
552
|
+
toggleLayout(NETWORK_MODE_GRN, NETWORK_MODE_PROTEIN_PHYS);
|
|
553
|
+
} else if (grnState.mode === NETWORK_PPI_MODE) {
|
|
554
|
+
toggleLayout(NETWORK_MODE_PROTEIN_PHYS, NETWORK_MODE_GRN);
|
|
555
|
+
}
|
|
525
556
|
};
|
|
526
557
|
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
558
|
+
const checkWorkbookModeSettings = () => {
|
|
559
|
+
const hasExpression = hasExpressionData(grnState.workbook.expression);
|
|
560
|
+
|
|
561
|
+
if (grnState.mode === NETWORK_PPI_MODE || !hasExpression) {
|
|
562
|
+
grnState.nodeColoring.nodeColoringEnabled = false;
|
|
563
|
+
grnState.nodeColoring.showMenu = true;
|
|
564
|
+
grnState.colorOptimal = false;
|
|
565
|
+
showNodeColoringMenus();
|
|
566
|
+
hideEdgeWeightOptions();
|
|
567
|
+
updateModeViews();
|
|
568
|
+
} else if (grnState.mode === NETWORK_GRN_MODE) {
|
|
569
|
+
grnState.nodeColoring.nodeColoringEnabled = true;
|
|
570
|
+
grnState.nodeColoring.showMenu = true;
|
|
571
|
+
grnState.colorOptimal = true;
|
|
572
|
+
showNodeColoringMenus();
|
|
573
|
+
showEdgeWeightOptions();
|
|
574
|
+
updateModeViews();
|
|
532
575
|
}
|
|
533
|
-
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
$("body").on("click", () => {
|
|
579
|
+
if (grnState.mode === NETWORK_PPI_MODE) {
|
|
580
|
+
$(EXPORT_TO_UNWEIGHTED_GML_MENU).addClass("disabled");
|
|
581
|
+
} else if (grnState.mode === NETWORK_GRN_MODE) {
|
|
582
|
+
$(EXPORT_TO_UNWEIGHTED_GML_MENU).removeClass("disabled");
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
$(NETWORK_MODE_DROPDOWN).on("change", () => {
|
|
587
|
+
grnState.mode = $(NETWORK_MODE_DROPDOWN).val();
|
|
588
|
+
checkWorkbookModeSettings();
|
|
589
|
+
refreshApp();
|
|
590
|
+
});
|
|
591
|
+
$(NETWORK_MODE_PROTEIN_PHYS).on("click", () => {
|
|
592
|
+
grnState.mode = NETWORK_PPI_MODE;
|
|
593
|
+
checkWorkbookModeSettings();
|
|
594
|
+
refreshApp();
|
|
595
|
+
});
|
|
596
|
+
$(NETWORK_MODE_GRN).on("click", () => {
|
|
597
|
+
grnState.mode = NETWORK_GRN_MODE;
|
|
598
|
+
checkWorkbookModeSettings();
|
|
599
|
+
refreshApp();
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
const shortenExpressionSheetName = (name) => {
|
|
603
|
+
return (name.length > MAX_NUM_CHARACTERS_DROPDOWN) ?
|
|
604
|
+
(name.slice(0, MAX_NUM_CHARACTERS_DROPDOWN) + "...") : name;
|
|
534
605
|
};
|
|
535
606
|
|
|
536
607
|
const updateSpeciesMenu = () => {
|
|
@@ -628,7 +699,7 @@ const resetDatasetDropdownMenus = (workbook) => {
|
|
|
628
699
|
var createHTMLforDataset = function (name) {
|
|
629
700
|
return `
|
|
630
701
|
<li class=\"dataset-option node-coloring-menu\" value=\"${name}\">
|
|
631
|
-
<a>
|
|
702
|
+
<a data-expression=\"${name}\">
|
|
632
703
|
<span class=\"glyphicon\"></span>
|
|
633
704
|
${name}
|
|
634
705
|
</a>
|
|
@@ -716,7 +787,7 @@ if (!grnState.genePageData.identified) {
|
|
|
716
787
|
|
|
717
788
|
export const updateApp = grnState => {
|
|
718
789
|
if (grnState.newWorkbook) {
|
|
719
|
-
|
|
790
|
+
checkWorkbookModeSettings();
|
|
720
791
|
grnState.normalizationMax = max(grnState.workbook.positiveWeights.concat(grnState.workbook.negativeWeights));
|
|
721
792
|
displayworkbook(grnState.workbook, grnState.name);
|
|
722
793
|
expandLayoutSidebar();
|
|
@@ -813,6 +884,12 @@ export const updateApp = grnState => {
|
|
|
813
884
|
$(NODE_COLORING_TOGGLE_SIDEBAR).prop("checked", true);
|
|
814
885
|
$(LOG_FOLD_CHANGE_MAX_VALUE_CLASS).val(DEFAULT_MAX_LOG_FOLD_CHANGE);
|
|
815
886
|
$(NODE_COLORING_SIDEBAR_BODY).removeClass("hidden");
|
|
887
|
+
$(NODE_COLORING_MENU).removeClass("hidden");
|
|
888
|
+
$(NODE_COLORING_NAVBAR_OPTIONS).removeClass("hidden");
|
|
889
|
+
if (grnState.mode === NETWORK_PPI_MODE) {
|
|
890
|
+
displayPPINodeColorWarning(grnState.ppiNodeColorWarningDisplayed);
|
|
891
|
+
grnState.ppiNodeColorWarningDisplayed = true;
|
|
892
|
+
}
|
|
816
893
|
if (grnState.database.expressionDatasets.includes(grnState.nodeColoring.topDataset) &&
|
|
817
894
|
grnState.workbook.expression[grnState.nodeColoring.topDataset] === undefined) {
|
|
818
895
|
if ($(NODE_COLORING_TOGGLE_SIDEBAR).prop("checked")) {
|
|
@@ -840,6 +917,12 @@ export const updateApp = grnState => {
|
|
|
840
917
|
grnState.nodeColoring.topDataset : "Dahlquist_2018_wt";
|
|
841
918
|
grnState.nodeColoring.bottomDataset = grnState.nodeColoring.bottomDataset ?
|
|
842
919
|
grnState.nodeColoring.bottomDataset : "Dahlquist_2018_wt";
|
|
920
|
+
$(NODE_COLORING_TOGGLE_SIDEBAR).prop("checked", true);
|
|
921
|
+
$(`${NODE_COLORING_TOGGLE_MENU} span`).addClass("glyphicon-ok");
|
|
922
|
+
$(NODE_COLORING_SIDEBAR_BODY).removeClass("hidden");
|
|
923
|
+
$(NODE_COLORING_MENU).removeClass("hidden");
|
|
924
|
+
$(NODE_COLORING_NAVBAR_OPTIONS).removeClass("hidden");
|
|
925
|
+
$(LOG_FOLD_CHANGE_MAX_VALUE_CLASS).val(DEFAULT_MAX_LOG_FOLD_CHANGE);
|
|
843
926
|
$(LOG_FOLD_CHANGE_MAX_VALUE_CLASS).addClass("hidden");
|
|
844
927
|
$(LOG_FOLD_CHANGE_MAX_VALUE_SIDEBAR_BUTTON).addClass("hidden");
|
|
845
928
|
$(LOG_FOLD_CHANGE_MAX_VALUE_HEADER).addClass("hidden");
|
|
@@ -866,13 +949,21 @@ export const updateApp = grnState => {
|
|
|
866
949
|
// Investigate why a timeout is required in order for node coloring to take place
|
|
867
950
|
// successfully in this case.
|
|
868
951
|
setTimeout(() => updaters.renderNodeColoring(), 250);
|
|
869
|
-
|
|
952
|
+
}
|
|
953
|
+
if (grnState.mode === NETWORK_PPI_MODE) {
|
|
954
|
+
displayPPINodeColorWarning(grnState.ppiNodeColorWarningDisplayed);
|
|
955
|
+
grnState.ppiNodeColorWarningDisplayed = true;
|
|
870
956
|
}
|
|
871
957
|
}
|
|
872
958
|
} else if (grnState.workbook !== null && !grnState.nodeColoring.nodeColoringEnabled) {
|
|
873
959
|
$(NODE_COLORING_SIDEBAR_BODY).addClass("hidden");
|
|
960
|
+
$(NODE_COLORING_MENU).addClass("disabled");
|
|
961
|
+
$(NODE_COLORING_NAVBAR_OPTIONS).addClass("hidden");
|
|
874
962
|
$(`${NODE_COLORING_TOGGLE_MENU} span`).removeClass("glyphicon-ok");
|
|
875
963
|
$(NODE_COLORING_TOGGLE_SIDEBAR).prop("checked", false);
|
|
964
|
+
if (grnState.mode === NETWORK_PPI_MODE) {
|
|
965
|
+
grnState.ppiNodeColorWarningDisplayed = false;
|
|
966
|
+
}
|
|
876
967
|
}
|
|
877
968
|
|
|
878
969
|
if (grnState.workbook !== null && grnState.workbook.sheetType === "weighted") {
|
|
@@ -943,4 +1034,4 @@ export const updateApp = grnState => {
|
|
|
943
1034
|
};
|
|
944
1035
|
|
|
945
1036
|
|
|
946
|
-
export { stopLoadingIcon, startLoadingIcon};
|
|
1037
|
+
export { stopLoadingIcon, startLoadingIcon, adjustGeneNameForExpression};
|