@@ -62,8 +62,8 @@
- Min. MScore
-
+ Min. mscor
+
diff --git a/src/app/routes/browse/form/form.component.ts b/src/app/routes/browse/form/form.component.ts
index 9fc77f87..9716e692 100644
--- a/src/app/routes/browse/form/form.component.ts
+++ b/src/app/routes/browse/form/form.component.ts
@@ -1,16 +1,30 @@
-import {Component, computed, effect, inject, linkedSignal, signal} from '@angular/core';
-import {MatFormFieldModule} from "@angular/material/form-field";
-import {MatSelectModule} from "@angular/material/select";
-import {MatExpansionModule} from "@angular/material/expansion";
-import {FormControl, FormGroup, ReactiveFormsModule} from "@angular/forms";
-import {MatInputModule} from "@angular/material/input";
-import {BrowseQuery, GeneSorting, InteractionSorting} from "../../../interfaces";
-import {BrowseService} from "../../../services/browse.service";
-import {VersionsService} from "../../../services/versions.service";
-import _ from "lodash";
-import {MatButtonToggle, MatButtonToggleGroup} from "@angular/material/button-toggle";
-import {MatCheckbox} from "@angular/material/checkbox";
-import {DiseaseSelectorComponent} from "../../../components/disease-selector/disease-selector.component";
+import {
+ Component,
+ computed,
+ effect,
+ inject,
+ linkedSignal,
+ signal,
+} from '@angular/core';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatSelectModule } from '@angular/material/select';
+import { MatExpansionModule } from '@angular/material/expansion';
+import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
+import { MatInputModule } from '@angular/material/input';
+import {
+ BrowseQuery,
+ GeneSorting,
+ InteractionSorting,
+} from '../../../interfaces';
+import { BrowseService } from '../../../services/browse.service';
+import { VersionsService } from '../../../services/versions.service';
+import _ from 'lodash';
+import {
+ MatButtonToggle,
+ MatButtonToggleGroup,
+} from '@angular/material/button-toggle';
+import { MatCheckbox } from '@angular/material/checkbox';
+import { DiseaseSelectorComponent } from '../../../components/disease-selector/disease-selector.component';
@Component({
selector: 'app-form',
@@ -26,14 +40,14 @@ import {DiseaseSelectorComponent} from "../../../components/disease-selector/dis
DiseaseSelectorComponent,
],
templateUrl: './form.component.html',
- styleUrl: './form.component.scss'
+ styleUrl: './form.component.scss',
})
export class FormComponent {
versionsService = inject(VersionsService);
browseService = inject(BrowseService);
version = this.versionsService.versionReadOnly();
- diseases$ = computed(() => this.versionsService.diseases$().value() ?? [])
- activeDataset = linkedSignal(() => this.diseases$()[0])
+ diseases$ = computed(() => this.versionsService.diseases$().value() ?? []);
+ activeDataset = linkedSignal(() => this.diseases$()[0]);
geneSortings = GeneSorting;
interactionSortings = InteractionSorting;
formGroup = new FormGroup({
@@ -44,17 +58,19 @@ export class FormComponent {
minDegree: new FormControl
(1),
minBetweenness: new FormControl(0.05),
minEigen: new FormControl(0.1),
- interactionSorting: new FormControl(this.interactionSortings.pAdj),
+ interactionSorting: new FormControl(
+ this.interactionSortings.pAdj,
+ ),
maxInteractions: new FormControl(100),
maxPValue: new FormControl(0.05),
- minMScore: new FormControl(0.1),
- })
+ minMscor: new FormControl(0.1),
+ });
protected readonly capitalize = _.capitalize;
constructor() {
const formSignal = signal(this.formGroup.value);
- this.formGroup.valueChanges.subscribe(val => formSignal.set(val))
+ this.formGroup.valueChanges.subscribe((val) => formSignal.set(val));
effect(() => {
const config = formSignal();
@@ -62,7 +78,7 @@ export class FormComponent {
if (dataset === undefined) return;
this.browseService.runQuery({
...config,
- dataset
+ dataset,
} as BrowseQuery);
});
}
diff --git a/src/app/routes/browse/nodes/nodes.component.ts b/src/app/routes/browse/nodes/nodes.component.ts
index e4032c83..e49a96bb 100644
--- a/src/app/routes/browse/nodes/nodes.component.ts
+++ b/src/app/routes/browse/nodes/nodes.component.ts
@@ -11,10 +11,9 @@ import { MatPaginator } from '@angular/material/paginator';
import { MatSort, MatSortHeader } from '@angular/material/sort';
import { MatButton } from '@angular/material/button';
import { MatDialog } from '@angular/material/dialog';
-import { GeneModalComponent } from '../../../components/gene-modal/gene-modal.component';
import { MatTooltip } from '@angular/material/tooltip';
-import { TranscriptModalComponent } from '../../../components/transcript-modal/transcript-modal.component';
import { InfoComponent } from '../../../components/info/info.component';
+import { ModalsService } from '../../../components/modals-service/modals.service';
@Component({
selector: 'app-nodes',
@@ -33,6 +32,7 @@ import { InfoComponent } from '../../../components/info/info.component';
export class NodesComponent implements AfterViewInit {
@ViewChild(MatPaginator) paginator!: MatPaginator;
@ViewChild(MatSort) sort!: MatSort;
+ modalsService = inject(ModalsService);
columns = ['identifier', 'betweenness', 'eigenvector', 'node_degree'];
dataSource: MatTableDataSource;
readonly dialog = inject(MatDialog);
@@ -57,14 +57,6 @@ export class NodesComponent implements AfterViewInit {
}
openDialog(entity: Gene | Transcript) {
- if ('ensg_number' in entity) {
- this.dialog.open(GeneModalComponent, {
- data: entity,
- });
- } else {
- this.dialog.open(TranscriptModalComponent, {
- data: entity,
- });
- }
+ this.modalsService.openNodeDialog(entity);
}
}
diff --git a/src/app/routes/documentation/browse-functionalities/browse-functionalities.component.html b/src/app/routes/documentation/browse-functionalities/browse-functionalities.component.html
index 3a5dcd98..194ba8bb 100644
--- a/src/app/routes/documentation/browse-functionalities/browse-functionalities.component.html
+++ b/src/app/routes/documentation/browse-functionalities/browse-functionalities.component.html
@@ -1,6 +1,6 @@
Browse functionalities
On the browse site you can create different interaction networks and investigate which genes/miRNAs affect each
- other. The node sizes and edge thicknes is corresponding to the Mscore and node degree. When loading a new cancer set,
+ other. The node sizes and edge thickness is corresponding to the mscor and node degree. When loading a new cancer set,
also a expression heatmap will be produced.
Network-Features:
diff --git a/src/app/routes/documentation/browse-functionalities/browse-functionalities.component.ts b/src/app/routes/documentation/browse-functionalities/browse-functionalities.component.ts
index a0d25ac4..22fae786 100644
--- a/src/app/routes/documentation/browse-functionalities/browse-functionalities.component.ts
+++ b/src/app/routes/documentation/browse-functionalities/browse-functionalities.component.ts
@@ -1,48 +1,51 @@
-import {Component} from '@angular/core';
-import {MatTableModule} from "@angular/material/table";
+import { Component } from '@angular/core';
+import { MatTableModule } from '@angular/material/table';
@Component({
selector: 'app-browse-functionalities',
- imports: [
- MatTableModule
- ],
+ imports: [MatTableModule],
templateUrl: './browse-functionalities.component.html',
- styleUrl: './browse-functionalities.component.scss'
+ styleUrl: './browse-functionalities.component.scss',
})
export class BrowseFunctionalitiesComponent {
- columns = ["name", "description"];
+ columns = ['name', 'description'];
features = [
{
- "name": "Title Banner Select",
- "description": "Select one of the cancer sets, which should be used for a network."
+ name: 'Title Banner Select',
+ description:
+ 'Select one of the cancer sets, which should be used for a network.',
},
{
- "name": "Click on a Node",
- "description": "Survival Analysis (Kaplan-Meier Plot) will be displayed for the Node."
+ name: 'Click on a Node',
+ description:
+ 'Survival Analysis (Kaplan-Meier Plot) will be displayed for the Node.',
},
{
- "name": "Hover over Node/Edge",
- "description": "Values such as Mscore, p-value, betweenness, correlation, and gene IDs will be displayed in a side table."
+ name: 'Hover over Node/Edge',
+ description:
+ 'Values such as mscor, p-value, betweenness, correlation, and gene IDs will be displayed in a side table.',
},
{
- "name": "Search under network",
- "description": "Select a ENSG number or interaction of interest (number), and it will be colored and focused on in the network."
+ name: 'Search under network',
+ description:
+ 'Select a ENSG number or interaction of interest (number), and it will be colored and focused on in the network.',
},
{
- "name": "Save as",
- "description": "You can save and download the plot as .jpg or .png."
+ name: 'Save as',
+ description: 'You can save and download the plot as .jpg or .png.',
},
{
- "name": "Reset camera",
- "description": "Reset the viewpoint of the network after zooming or focusing on a node."
+ name: 'Reset camera',
+ description:
+ 'Reset the viewpoint of the network after zooming or focusing on a node.',
},
{
- "name": "Force atlas 2/start layout",
- "description": "Start a layout for a better visualization of the network."
+ name: 'Force atlas 2/start layout',
+ description: 'Start a layout for a better visualization of the network.',
},
{
- "name": "Reset Colors",
- "description": "Deselect clicked nodes."
- }
- ]
+ name: 'Reset Colors',
+ description: 'Deselect clicked nodes.',
+ },
+ ];
}
diff --git a/src/app/routes/documentation/example-script/example-script.component.ts b/src/app/routes/documentation/example-script/example-script.component.ts
index ed8fd5d2..d4060a7f 100644
--- a/src/app/routes/documentation/example-script/example-script.component.ts
+++ b/src/app/routes/documentation/example-script/example-script.component.ts
@@ -18,10 +18,6 @@ export class ExampleScriptComponent {
content$ = this.http.getHtmlRequest('./example.py');
- constructor() {
- this.content$.then(console.log);
- }
-
async download() {
const content = await this.content$;
const file = new File([content], 'example.py');
diff --git a/src/app/routes/documentation/home-search-bar/home-search-bar.component.ts b/src/app/routes/documentation/home-search-bar/home-search-bar.component.ts
index 5c27d681..60bd490d 100644
--- a/src/app/routes/documentation/home-search-bar/home-search-bar.component.ts
+++ b/src/app/routes/documentation/home-search-bar/home-search-bar.component.ts
@@ -1,52 +1,57 @@
-import {Component} from '@angular/core';
-import {MatTableModule} from "@angular/material/table";
+import { Component } from '@angular/core';
+import { MatTableModule } from '@angular/material/table';
@Component({
selector: 'app-home-search-bar',
- imports: [
- MatTableModule
- ],
+ imports: [MatTableModule],
templateUrl: './home-search-bar.component.html',
- styleUrl: './home-search-bar.component.scss'
+ styleUrl: './home-search-bar.component.scss',
})
export class HomeSearchBarComponent {
- columns = ["name", "description"];
+ columns = ['name', 'description'];
features = [
{
- "name": "Search Box",
- "description": "Search for a ENSG number or Gene Symbol. Check the box to only obtain significant results."
+ name: 'Search Box',
+ description:
+ 'Search for a ENSG number or Gene Symbol. Check the box to only obtain significant results.',
},
{
- "name": "Result Boxes",
- "description": "Lists the cancer datasets, which contain interactions with the searched value. The tables visualize values such as mscore, p-value, correlation, and IDs."
+ name: 'Result Boxes',
+ description:
+ 'Lists the cancer datasets, which contain interactions with the searched value. The tables visualize values such as mscore, p-value, correlation, and IDs.',
},
{
- "name": "Options Button",
- "description": "Set a range for the mscore or adjusted p-value. You don't have to submit your entry; it will be applied automatically."
+ name: 'Options Button',
+ description:
+ "Set a range for the mscor or adjusted p-value. You don't have to submit your entry; it will be applied automatically.",
},
{
- "name": "Hallmarks",
- "description": "Associated cancer hallmarks."
+ name: 'Hallmarks',
+ description: 'Associated cancer hallmarks.',
},
{
- "name": "Show as Network Button",
- "description": "Exports selected table entries or default ones to create an interaction network."
+ name: 'Show as Network Button',
+ description:
+ 'Exports selected table entries or default ones to create an interaction network.',
},
{
- "name": "Gene Enrichment Button",
- "description": "If no gene is selected, all genes will be used for gene enrichment analysis. Otherwise, the selected entries will be used for a default query on g:Profiler."
+ name: 'Gene Enrichment Button',
+ description:
+ 'If no gene is selected, all genes will be used for gene enrichment analysis. Otherwise, the selected entries will be used for a default query on g:Profiler.',
},
{
- "name": "WikiPathways",
- "description": "Brings you to a pathway visualization on WikiPathways."
+ name: 'WikiPathways',
+ description: 'Brings you to a pathway visualization on WikiPathways.',
},
{
- "name": "GeneCard",
- "description": "Displays further information about the gene with the help of GeneCards."
+ name: 'GeneCard',
+ description:
+ 'Displays further information about the gene with the help of GeneCards.',
},
{
- "name": "Gene Ontology",
- "description": "All associating GO numbers will be displayed for the gene and link to their entry on QuickGO."
- }
- ]
+ name: 'Gene Ontology',
+ description:
+ 'All associating GO numbers will be displayed for the gene and link to their entry on QuickGO.',
+ },
+ ];
}
diff --git a/src/app/routes/spongeffects/predict/prediction-results/prediction-results.component.ts b/src/app/routes/spongeffects/predict/prediction-results/prediction-results.component.ts
index bb9e05a4..2cbd686e 100644
--- a/src/app/routes/spongeffects/predict/prediction-results/prediction-results.component.ts
+++ b/src/app/routes/spongeffects/predict/prediction-results/prediction-results.component.ts
@@ -8,24 +8,20 @@ import {
resource,
viewChild,
} from '@angular/core';
-import { PlotlyData, PredictCancerType } from '../../../../interfaces';
+import { PlotlyData } from '../../../../interfaces';
import { ClassPerformancePlotComponent } from '../../explore/plots/class-performance-plot/class-performance-plot.component';
import { PredictFormComponent } from '../form/predict-form.component';
import { PredictService } from '../service/predict.service';
import { MatProgressSpinner } from '@angular/material/progress-spinner';
import { CommonModule } from '@angular/common';
-
declare var Plotly: any;
@Component({
selector: 'app-prediction-results',
standalone: true,
providers: [ClassPerformancePlotComponent, PredictFormComponent],
- imports: [
- MatProgressSpinner,
- CommonModule,
- ],
+ imports: [MatProgressSpinner, CommonModule],
templateUrl: './prediction-results.component.html',
styleUrls: ['./prediction-results.component.scss'],
})
@@ -33,10 +29,10 @@ export class PredictionResultsComponent {
predictService = inject(PredictService);
prediction$ = this.predictService.prediction$;
predictionResource = this.predictService._prediction$;
- typePredictPiePlot = viewChild.required>('typePredictPiePlot');
+ typePredictPiePlot =
+ viewChild.required>('typePredictPiePlot');
refreshSignal$ = input();
- doneLoading = false
-
+ doneLoading = false;
predictionMeta$ = computed(() => this.prediction$()?.meta);
predictionData$ = computed(() => this.prediction$()?.data);
@@ -59,13 +55,10 @@ export class PredictionResultsComponent {
loader: async (param) => {
const data = param.request.data;
if (data === undefined) return;
- console.log('resource')
- console.log(this.plotTypePredictPieResource.isLoading())
- console.log(this.plotTypePredictPieResource.value())
const plot_data = this.extractPredictions(data);
return await this.plotPredictions(plot_data);
},
- })
+ });
async plotPredictions(plotlyData: PlotlyData): Promise {
return Plotly.newPlot(
@@ -76,11 +69,9 @@ export class PredictionResultsComponent {
);
}
-
extractPredictions(responseJson: any): PlotlyData {
const typeGroups: Map = new Map();
// group predictions by type
- console.log(responseJson);
responseJson.data.forEach(
(entry: { typePrediction: string; subtypePrediction: string }) => {
if (typeGroups.has(entry.typePrediction)) {
@@ -109,7 +100,6 @@ export class PredictionResultsComponent {
(d: { name: string }) => d.name == 'modules',
);
const oneMeasure = classPerformanceData[0];
- console.log(oneMeasure);
// create map to value
const classToMeasure: Map = new Map();
for (let i = 0; i < oneMeasure.x.length; i++) {
@@ -174,7 +164,12 @@ export class PredictionResultsComponent {
responsive: true,
};
const plot_data = { data: data, layout: layout, config: config };
- Plotly.newPlot(this.typePredictPiePlot().nativeElement, data, layout, config);
+ Plotly.newPlot(
+ this.typePredictPiePlot().nativeElement,
+ data,
+ layout,
+ config,
+ );
this.doneLoading = true;
return plot_data;
}
@@ -206,6 +201,4 @@ export class PredictionResultsComponent {
// // Additional content validation can be added here
// return true;
// }
-
-
}
diff --git a/src/app/services/backend.service.ts b/src/app/services/backend.service.ts
index c23c3e7c..30f8a4de 100644
--- a/src/app/services/backend.service.ts
+++ b/src/app/services/backend.service.ts
@@ -1,5 +1,5 @@
-import {Injectable} from '@angular/core';
-import {HttpService} from "./http.service";
+import { Injectable } from '@angular/core';
+import { HttpService } from './http.service';
import {
AlternativeSplicingEvent,
BrowseQuery,
@@ -18,6 +18,7 @@ import {
GOTerm,
GseaResult,
Hallmark,
+ Network,
NetworkResult,
OverallCounts,
PredictCancerType,
@@ -36,27 +37,25 @@ import {
TranscriptInteraction,
TranscriptMiRNA,
TranscriptNode,
- WikiPathway
-} from "../interfaces";
-import {API_BASE} from "../constants";
+ WikiPathway,
+} from '../interfaces';
+import { API_BASE } from '../constants';
interface Query {
[key: string]: any;
}
@Injectable({
- providedIn: 'root'
+ providedIn: 'root',
})
export class BackendService {
-
- constructor(private http: HttpService) {
- }
+ constructor(private http: HttpService) {}
async getDatasets(version: number, diseaseName?: string): Promise {
const route = 'datasets';
const query: Query = {
- sponge_db_version: version
+ sponge_db_version: version,
};
if (diseaseName) {
@@ -68,21 +67,56 @@ export class BackendService {
getDatasetInfo(version: number, diseaseName: string): Promise {
const route = 'dataset/spongeRunInformation';
- const query: Query = {sponge_db_version: version, disease_name: diseaseName};
+ const query: Query = {
+ sponge_db_version: version,
+ disease_name: diseaseName,
+ };
return this.http.getRequest(this.getRequestURL(route, query));
}
getOverallCounts(version: number): Promise {
const route = 'getOverallCounts';
- const query: Query = {sponge_db_version: version};
- return this.http.getRequest(this.getRequestURL(route, query));
+ const query: Query = { sponge_db_version: version };
+ return this.http.getRequest(
+ this.getRequestURL(route, query),
+ );
+ }
+
+ getNetwork(version: number, query: BrowseQuery): Promise {
+ const level = query.level;
+ const route =
+ level == 'gene'
+ ? 'ceRNAInteraction/getGeneNetwork'
+ : 'ceRNAInteraction/getTranscriptNetwork';
+
+ const _query: Query = {
+ sponge_db_version: version,
+ dataset_ID: query.dataset.dataset_ID,
+ minBetweenness: query.minBetweenness,
+ minNodeDegree: query.minDegree,
+ minEigenvector: query.minEigen,
+ maxPValue: query.maxPValue,
+ minMscor: query.minMscor,
+ edgeSorting: query.interactionSorting,
+ nodeSorting: query.geneSorting,
+ maxNodes: query.maxNodes,
+ maxEdges: query.maxInteractions,
+ };
+
+ return this.http.getRequest(this.getRequestURL(route, _query));
}
- getNodes(version: number, query: BrowseQuery): Promise<(GeneNode | TranscriptNode)[]> {
+ getNodes(
+ version: number,
+ query: BrowseQuery,
+ ): Promise<(GeneNode | TranscriptNode)[]> {
const level = query.level;
const route = level == 'gene' ? 'findceRNA' : 'findceRNATranscripts';
- if (version != query.dataset.sponge_db_version || (version < 2 && level == 'transcript')) {
+ if (
+ version != query.dataset.sponge_db_version ||
+ (version < 2 && level == 'transcript')
+ ) {
return Promise.resolve([]);
}
@@ -95,16 +129,27 @@ export class BackendService {
minEigenvector: query.minEigen,
sorting: query.geneSorting,
descending: true,
- limit: query.maxNodes
+ limit: query.maxNodes,
};
- return this.http.getRequest<(GeneNode | TranscriptNode)[]>(this.getRequestURL(route, internalQuery));
+ return this.http.getRequest<(GeneNode | TranscriptNode)[]>(
+ this.getRequestURL(route, internalQuery),
+ );
}
- async getGeneInteractionsAll(version: number, disease: Dataset | undefined, maxPValue: number, ensgs: string[]): Promise {
+ async getGeneInteractionsAll(
+ version: number,
+ disease: Dataset | undefined,
+ maxPValue: number,
+ ensgs: string[],
+ ): Promise {
const route = 'ceRNAInteraction/findAll';
- if (ensgs.length === 0 || !disease || version != disease.sponge_db_version) {
+ if (
+ ensgs.length === 0 ||
+ !disease ||
+ version != disease.sponge_db_version
+ ) {
return Promise.resolve([]);
}
@@ -113,21 +158,23 @@ export class BackendService {
disease_name: disease.disease_name,
dataset_ID: disease.dataset_ID,
ensg_number: ensgs.join(','),
- pValue: maxPValue
- }
+ pValue: maxPValue,
+ };
- const results: GeneInteraction[] = []
+ const results: GeneInteraction[] = [];
const limit = 1000;
let offset = 0;
let data: GeneInteraction[];
do {
- data = await this.http.getRequest(this.getRequestURL(route, {
- ...query,
- limit,
- offset
- }));
+ data = await this.http.getRequest(
+ this.getRequestURL(route, {
+ ...query,
+ limit,
+ offset,
+ }),
+ );
results.push(...data);
offset += limit;
} while (data.length === limit);
@@ -135,8 +182,17 @@ export class BackendService {
return results;
}
- getInteractionsSpecific(version: number, disease: Dataset, maxPValue: number, identifiers: string[], level: 'gene' | 'transcript'): Promise<(GeneInteraction | TranscriptInteraction)[]> {
- const route = level == 'gene' ? 'ceRNAInteraction/findSpecific' : 'ceRNAInteraction/findSpecificTranscripts';
+ getInteractionsSpecific(
+ version: number,
+ disease: Dataset,
+ maxPValue: number,
+ identifiers: string[],
+ level: 'gene' | 'transcript',
+ ): Promise<(GeneInteraction | TranscriptInteraction)[]> {
+ const route =
+ level == 'gene'
+ ? 'ceRNAInteraction/findSpecific'
+ : 'ceRNAInteraction/findSpecificTranscripts';
if (identifiers.length === 0) {
return Promise.resolve([]);
@@ -146,8 +202,8 @@ export class BackendService {
sponge_db_version: version,
disease_name: disease.disease_name,
dataset_ID: disease.dataset_ID,
- pValue: maxPValue
- }
+ pValue: maxPValue,
+ };
if (level == 'gene') {
query['ensg_number'] = identifiers.join(',');
@@ -155,11 +211,19 @@ export class BackendService {
query['enst_number'] = identifiers.join(',');
}
- return this.http.getRequest<(GeneInteraction | TranscriptInteraction)[]>(this.getRequestURL(route, query));
+ return this.http.getRequest<(GeneInteraction | TranscriptInteraction)[]>(
+ this.getRequestURL(route, query),
+ );
}
- async getExpression(version: number, identifiers: string[], disease: Dataset, level: 'gene' | 'transcript'): Promise<(GeneExpression | TranscriptExpression)[]> {
- const route = level == 'gene' ? 'exprValue/getceRNA' : 'exprValue/getTranscriptExpr';
+ async getExpression(
+ version: number,
+ identifiers: string[],
+ disease: Dataset,
+ level: 'gene' | 'transcript',
+ ): Promise<(GeneExpression | TranscriptExpression)[]> {
+ const route =
+ level == 'gene' ? 'exprValue/getceRNA' : 'exprValue/getTranscriptExpr';
if (identifiers.length === 0) {
return Promise.resolve([]);
@@ -169,7 +233,7 @@ export class BackendService {
sponge_db_version: version,
dataset_ID: disease.dataset_ID,
disease_name: disease.disease_name,
- }
+ };
if (level == 'gene') {
query['ensg_number'] = identifiers.join(',');
@@ -177,22 +241,29 @@ export class BackendService {
query['enst_number'] = identifiers.join(',');
}
- return await this.http.getRequest<(GeneExpression | TranscriptExpression)[]>(this.getRequestURL(route, query));
+ return await this.http.getRequest<
+ (GeneExpression | TranscriptExpression)[]
+ >(this.getRequestURL(route, query));
}
- getSurvivalRates(version: number, ensgs: string[], disease: Dataset): Promise {
+ getSurvivalRates(
+ version: number,
+ ensgs: string[],
+ disease: Dataset,
+ ): Promise {
const route = 'survivalAnalysis/getRates';
const query: Query = {
sponge_db_version: version,
disease_name: disease.disease_name,
dataset_ID: disease.dataset_ID,
- ensg_number: ensgs.join(',')
- }
+ ensg_number: ensgs.join(','),
+ };
- return this.http.getRequest(this.getRequestURL(route, query));
+ return this.http.getRequest(
+ this.getRequestURL(route, query),
+ );
}
-
getAutocomplete(version: number, query: string): Promise {
if (query.length < 2) {
return Promise.resolve([]);
@@ -201,8 +272,8 @@ export class BackendService {
const route = 'stringSearch';
const queryObj: Query = {
sponge_db_version: version,
- searchString: query
- }
+ searchString: query,
+ };
try {
return this.http.getRequest(this.getRequestURL(route, queryObj));
} catch (e) {
@@ -214,17 +285,19 @@ export class BackendService {
const route = 'getTranscriptInformation';
const query: Query = {
sponge_db_version: version,
- enst_number: enst
- }
- return this.http.getRequest(this.getRequestURL(route, query));
+ enst_number: enst,
+ };
+ return this.http.getRequest(
+ this.getRequestURL(route, query),
+ );
}
getGeneInfo(version: number, ensg: string): Promise {
const route = 'getGeneInformation';
const query: Query = {
sponge_db_version: version,
- ensg_number: ensg
- }
+ ensg_number: ensg,
+ };
return this.http.getRequest(this.getRequestURL(route, query));
}
@@ -237,12 +310,15 @@ export class BackendService {
const query: Query = {
sponge_db_version: version,
- gene_symbol: symbol
- }
+ gene_symbol: symbol,
+ };
return this.http.getRequest(this.getRequestURL(route, query));
}
- async getHallmark(version: number, symbol: string | undefined): Promise {
+ async getHallmark(
+ version: number,
+ symbol: string | undefined,
+ ): Promise {
const route = 'getHallmark';
if (!symbol) {
@@ -251,16 +327,21 @@ export class BackendService {
const query: Query = {
sponge_db_version: version,
- gene_symbol: symbol
- }
- const hallmarks = await this.http.getRequest(this.getRequestURL(route, query));
+ gene_symbol: symbol,
+ };
+ const hallmarks = await this.http.getRequest(
+ this.getRequestURL(route, query),
+ );
if (!Array.isArray(hallmarks)) {
return [];
}
return hallmarks;
}
- async getWikiPathways(version: number, symbol: string | undefined): Promise {
+ async getWikiPathways(
+ version: number,
+ symbol: string | undefined,
+ ): Promise {
const route = 'getWikipathway';
if (!symbol) {
@@ -269,9 +350,11 @@ export class BackendService {
const query: Query = {
sponge_db_version: version,
- gene_symbol: symbol
- }
- const wikipathways = await this.http.getRequest(this.getRequestURL(route, query));
+ gene_symbol: symbol,
+ };
+ const wikipathways = await this.http.getRequest(
+ this.getRequestURL(route, query),
+ );
if (!Array.isArray(wikipathways)) {
return [];
@@ -279,7 +362,11 @@ export class BackendService {
return wikipathways;
}
- getGeneCount(version: number, ensgs: string[], onlySignificant: boolean): Promise {
+ getGeneCount(
+ version: number,
+ ensgs: string[],
+ onlySignificant: boolean,
+ ): Promise {
if (ensgs.length === 0) {
return Promise.resolve([]);
}
@@ -287,7 +374,7 @@ export class BackendService {
const query: Query = {
sponge_db_version: version,
ensg_number: ensgs.join(','),
- }
+ };
if (onlySignificant) {
query['minCountSign'] = 1;
}
@@ -298,41 +385,64 @@ export class BackendService {
const route = 'getGeneTranscripts';
const query: Query = {
sponge_db_version: version,
- ensg_number: ensg
- }
- return this.http.getRequest(this.getRequestURL(route, query));
- }
-
- async getMiRNAs(version: number, disease: Dataset, identifiers: [string, string], level: 'gene' | 'transcript') {
- const route = level == 'gene' ? 'miRNAInteraction/findceRNA' : 'miRNAInteraction/findceRNATranscripts';
+ ensg_number: ensg,
+ };
+ return (
+ await this.http.getRequest(this.getRequestURL(route, query))
+ )[0];
+ }
+
+ async getMiRNAs(
+ version: number,
+ disease: Dataset,
+ identifiers: [string, string],
+ level: 'gene' | 'transcript',
+ ) {
+ const route =
+ level == 'gene'
+ ? 'miRNAInteraction/findceRNA'
+ : 'miRNAInteraction/findceRNATranscripts';
const query: Query = {
sponge_db_version: version,
dataset_ID: disease.dataset_ID,
- between: true
- }
+ between: true,
+ };
if (level == 'gene') {
query['ensg_number'] = identifiers.join(',');
} else {
query['enst_number'] = identifiers.join(',');
}
- return this.http.getRequest(this.getRequestURL(route, query));
+ return this.http.getRequest(
+ this.getRequestURL(route, query),
+ );
}
- async getAlternativeSplicingEvents(ensts: string[]): Promise {
+ async getAlternativeSplicingEvents(
+ ensts: string[],
+ ): Promise {
const route = 'alternativeSplicing/getTranscriptEvents';
const query: Query = {
- enst_number: ensts.join(',')
- }
+ enst_number: ensts.join(','),
+ };
- const resp = await this.http.getRequest(this.getRequestURL(route, query));
+ const resp = await this.http.getRequest(
+ this.getRequestURL(route, query),
+ );
return 'detail' in resp ? [] : resp;
}
- getCeRNAInteractionsAll(disease: string, maxPValue: number, ensgs: string[], limit?: number, offset?: number): Promise {
- let request = API_BASE + '/ceRNAInteraction/findAll?disease_name=' + disease;
+ getCeRNAInteractionsAll(
+ disease: string,
+ maxPValue: number,
+ ensgs: string[],
+ limit?: number,
+ offset?: number,
+ ): Promise {
+ let request =
+ API_BASE + '/ceRNAInteraction/findAll?disease_name=' + disease;
request += `&ensg_number=${ensgs.join(',')}`;
request += `&pValue=${maxPValue}`;
@@ -346,15 +456,19 @@ export class BackendService {
return this.http.getRequest(request);
}
- getCeRNAInteractionsSpecific(disease: string, maxPValue: number, ensgs: string[]): Promise {
- let request = API_BASE + '/ceRNAInteraction/findSpecific?disease_name=' + disease;
+ getCeRNAInteractionsSpecific(
+ disease: string,
+ maxPValue: number,
+ ensgs: string[],
+ ): Promise {
+ let request =
+ API_BASE + '/ceRNAInteraction/findSpecific?disease_name=' + disease;
request += `&ensg_number=${ensgs.join(',')}`;
request += `&pValue=${maxPValue}`;
return this.http.getRequest(request);
}
-
// getCeRNA(query: CeRNAQuery): Promise {
// const sponge_db_version = this.versionService.getCurrentVersion();
// let request = BackendService.API_BASE + '/findceRNA?disease_name=' + query.disease.disease_name + `?sponge_db_version=${sponge_db_version}`;
@@ -369,65 +483,114 @@ export class BackendService {
// return this.http.getRequest(request);
// }
- getCeRNAExpression(ensgs: string[], diseaseName: string): Promise {
+ getCeRNAExpression(
+ ensgs: string[],
+ diseaseName: string,
+ ): Promise {
let request = API_BASE + '/exprValue/getceRNA?disease_name=' + diseaseName;
request += `&ensg_number=${ensgs.join(',')}`;
return this.http.getRequest(request);
}
- getTranscriptExpression(ensts: string[], disease_name?: string): Promise {
- let request = API_BASE + `/exprValue/getTranscript?disease_name=${disease_name}`;
+ getTranscriptExpression(
+ ensts: string[],
+ disease_name?: string,
+ ): Promise {
+ let request =
+ API_BASE + `/exprValue/getTranscript?disease_name=${disease_name}`;
request += `&enst_number=${ensts.join(',')}`;
return this.http.getRequest(request);
}
- async getSurvivalPValues(version: number, ensgs: string[], disease: Dataset): Promise {
+ async getSurvivalPValues(
+ version: number,
+ ensgs: string[],
+ disease: Dataset,
+ ): Promise {
const route = 'survivalAnalysis/getPValues';
const query: Query = {
sponge_db_version: version,
disease_name: disease.disease_name,
dataset_ID: disease.dataset_ID,
- ensg_number: ensgs.join(',')
- }
-
- return (await this.http.getRequest(this.getRequestURL(route, query))) ?? [];
- }
+ ensg_number: ensgs.join(','),
+ };
- getSpongEffectsRuns(version: number, dataset_ID?: number, diseaseName?: string): Promise {
- const request = `${API_BASE}/spongEffects/getSpongEffectsRuns?`
- + (dataset_ID ? `?dataset_ID=${dataset_ID}` : '')
- + (diseaseName ? `&disease_name=${diseaseName}` : '')
- + `&sponge_db_version=${version}`
+ return (
+ (await this.http.getRequest(
+ this.getRequestURL(route, query),
+ )) ?? []
+ );
+ }
+
+ getSpongEffectsRuns(
+ version: number,
+ dataset_ID?: number,
+ diseaseName?: string,
+ ): Promise {
+ const request =
+ `${API_BASE}/spongEffects/getSpongEffectsRuns?` +
+ (dataset_ID ? `?dataset_ID=${dataset_ID}` : '') +
+ (diseaseName ? `&disease_name=${diseaseName}` : '') +
+ `&sponge_db_version=${version}`;
return this.http.getRequest(request);
}
- getRunPerformance(version: number, diseaseName: string, level: string): Promise {
- const request = API_BASE + '/spongEffects/getRunPerformance' + `?disease_name=${diseaseName}` + `&level=${level}` + `&sponge_db_version=${version}`;
+ getRunPerformance(
+ version: number,
+ diseaseName: string,
+ level: string,
+ ): Promise {
+ const request =
+ API_BASE +
+ '/spongEffects/getRunPerformance' +
+ `?disease_name=${diseaseName}` +
+ `&level=${level}` +
+ `&sponge_db_version=${version}`;
return this.http.getRequest(request);
}
+ // spongEffects services:
-// spongEffects services:
-
- getRunClassPerformance(version: number, diseaseName: string, level: string): Promise {
- const request = API_BASE + '/spongEffects/getRunClassPerformance' + `?disease_name=${diseaseName}` + `&level=${level}` + `&sponge_db_version=${version}`;
+ getRunClassPerformance(
+ version: number,
+ diseaseName: string,
+ level: string,
+ ): Promise {
+ const request =
+ API_BASE +
+ '/spongEffects/getRunClassPerformance' +
+ `?disease_name=${diseaseName}` +
+ `&level=${level}` +
+ `&sponge_db_version=${version}`;
return this.http.getRequest(request);
}
- getEnrichmentScoreDistributions(version: number, diseaseName: string, level: string): Promise {
+ getEnrichmentScoreDistributions(
+ version: number,
+ diseaseName: string,
+ level: string,
+ ): Promise {
const request = `${API_BASE}/spongEffects/enrichmentScoreDistributions?disease_name=${diseaseName}&level=${level}&sponge_db_version=${version}`;
return this.http.getRequest(request);
}
- getSpongEffectsGeneModules(version: number, diseaseName: string): Promise {
+ getSpongEffectsGeneModules(
+ version: number,
+ diseaseName: string,
+ ): Promise {
const request = `${API_BASE}/spongEffects/getSpongEffectsGeneModules?disease_name=${diseaseName}&sponge_db_version=${version}`;
return this.http.getRequest(request);
}
- getSpongEffectsGeneModuleMembers(version: number, diseaseName: string, ensgNumber?: string, geneSymbol?: string): Promise {
+ getSpongEffectsGeneModuleMembers(
+ version: number,
+ diseaseName: string,
+ ensgNumber?: string,
+ geneSymbol?: string,
+ ): Promise {
let request = `${API_BASE}/spongEffects/getSpongEffectsGeneModuleMembers?disease_name=${diseaseName}&sponge_db_version=${version}`;
if (ensgNumber) {
request += `&ensg_number=${ensgNumber}`;
@@ -438,12 +601,19 @@ export class BackendService {
return this.http.getRequest(request);
}
- getSpongEffectsTranscriptModules(version: number, diseaseName: string): Promise {
+ getSpongEffectsTranscriptModules(
+ version: number,
+ diseaseName: string,
+ ): Promise {
const request = `${API_BASE}/spongEffects/getSpongEffectsTranscriptModules?disease_name=${diseaseName}&sponge_db_version=${version}`;
return this.http.getRequest(request);
}
- getSpongEffectsTranscriptModuleMembers(version: number, diseaseName: string, enstNumber?: string): Promise {
+ getSpongEffectsTranscriptModuleMembers(
+ version: number,
+ diseaseName: string,
+ enstNumber?: string,
+ ): Promise {
let request = `${API_BASE}/spongEffects/getSpongEffectsTranscriptModuleMembers?disease_name=${diseaseName}&sponge_db_version=${version}`;
if (enstNumber) {
request += `&enst_number=${enstNumber}`;
@@ -451,7 +621,18 @@ export class BackendService {
return this.http.getRequest(request);
}
- predictCancerType(version: number, file: Blob, subtypes: boolean, log: boolean, mscor: number, fdr: number, minSize: number, maxSize: number, minExpr: number, method: string): Promise {
+ predictCancerType(
+ version: number,
+ file: Blob,
+ subtypes: boolean,
+ log: boolean,
+ mscor: number,
+ fdr: number,
+ minSize: number,
+ maxSize: number,
+ minExpr: number,
+ method: string,
+ ): Promise {
const formData = new FormData();
formData.append('file', file);
formData.append('subtypes', subtypes.toString());
@@ -470,13 +651,19 @@ export class BackendService {
const route = 'comparison';
const query: Query = {
- sponge_db_version: version
- }
+ sponge_db_version: version,
+ };
return this.http.getRequest(this.getRequestURL(route, query));
}
- async getGeneSets(version: number, disease1: Dataset | undefined, condition1: string, disease2: Dataset | undefined, condition2: string) {
+ async getGeneSets(
+ version: number,
+ disease1: Dataset | undefined,
+ condition1: string,
+ disease2: Dataset | undefined,
+ condition2: string,
+ ) {
const route = 'gseaSets';
if (!disease1 || !disease2) {
@@ -489,13 +676,18 @@ export class BackendService {
dataset_ID_2: disease2.dataset_ID,
condition_1: condition1,
condition_2: condition2,
- }
+ };
- const res = await this.http.getRequest<{ gene_set: string }[]>(this.getRequestURL(route, query));
- return res.map(e => e.gene_set).sort();
+ const res = await this.http.getRequest<{ gene_set: string }[]>(
+ this.getRequestURL(route, query),
+ );
+ return res.map((e) => e.gene_set).sort();
}
- async getNetworkResults(version: number, level: 'gene' | 'transcript' | undefined) {
+ async getNetworkResults(
+ version: number,
+ level: 'gene' | 'transcript' | undefined,
+ ) {
const route = 'networkResults';
if (!level || version < 2) {
@@ -504,10 +696,12 @@ export class BackendService {
const query: Query = {
sponge_db_version: version,
- level
- }
+ level,
+ };
- const resp = await this.http.getRequest(this.getRequestURL(route, query));
+ const resp = await this.http.getRequest(
+ this.getRequestURL(route, query),
+ );
return 'type' in resp ? resp : undefined;
}
@@ -516,13 +710,20 @@ export class BackendService {
const query: Query = {
alternative_splicing_event_transcripts_ID: asEventID,
- enst_number: enst
- }
+ enst_number: enst,
+ };
return this.http.getRequest(this.getRequestURL(route, query));
}
- async getGSEAterms(version: number, disease1: Dataset | undefined, condition1: string, disease2: Dataset | undefined, condition2: string, geneSet: string | undefined) {
+ async getGSEAterms(
+ version: number,
+ disease1: Dataset | undefined,
+ condition1: string,
+ disease2: Dataset | undefined,
+ condition2: string,
+ geneSet: string | undefined,
+ ) {
const route = 'gseaTerms';
if (!disease1 || !disease2 || !geneSet) {
@@ -534,14 +735,23 @@ export class BackendService {
dataset_ID_2: disease2.dataset_ID,
condition_1: condition1,
condition_2: condition2,
- gene_set: geneSet
- }
+ gene_set: geneSet,
+ };
- const res = await this.http.getRequest<{ term: string }[]>(this.getRequestURL(route, query));
- return res.map(e => e.term).sort();
+ const res = await this.http.getRequest<{ term: string }[]>(
+ this.getRequestURL(route, query),
+ );
+ return res.map((e) => e.term).sort();
}
- getGSEAresults(version: number, disease1: Dataset | undefined, condition1: string, disease2: Dataset | undefined, condition2: string, geneSet: string | undefined) {
+ getGSEAresults(
+ version: number,
+ disease1: Dataset | undefined,
+ condition1: string,
+ disease2: Dataset | undefined,
+ condition2: string,
+ geneSet: string | undefined,
+ ) {
const route = 'gseaResults';
if (!disease1 || !disease2 || !geneSet) {
@@ -553,14 +763,16 @@ export class BackendService {
dataset_ID_2: disease2.dataset_ID,
condition_1: condition1,
condition_2: condition2,
- gene_set: geneSet
- }
+ gene_set: geneSet,
+ };
return this.http.getRequest(this.getRequestURL(route, query));
}
private stringify(query: Query): string {
- return Object.keys(query).map(key => key + '=' + query[key]).join('&');
+ return Object.keys(query)
+ .map((key) => key + '=' + query[key])
+ .join('&');
}
private getRequestURL(route: string, query: Query): string {
diff --git a/src/app/services/browse.service.ts b/src/app/services/browse.service.ts
index 5762405a..f4b7ac38 100644
--- a/src/app/services/browse.service.ts
+++ b/src/app/services/browse.service.ts
@@ -1,26 +1,33 @@
-import {computed, effect, Injectable, resource, ResourceRef, Signal, signal} from '@angular/core';
+import {
+ computed,
+ effect,
+ Injectable,
+ resource,
+ ResourceRef,
+ Signal,
+ signal,
+} from '@angular/core';
import {
BrowseQuery,
Dataset,
Gene,
GeneInteraction,
GeneNode,
- InteractionSorting,
NetworkResult,
Transcript,
TranscriptInteraction,
- TranscriptNode
-} from "../interfaces";
-import {BackendService} from "./backend.service";
-import Graph from "graphology";
-import {VersionsService} from "./versions.service";
-import ForceSupervisor from "graphology-layout-force/worker";
-import {isEqual} from "lodash";
+ TranscriptNode,
+} from '../interfaces';
+import { BackendService } from './backend.service';
+import Graph from 'graphology';
+import { VersionsService } from './versions.service';
+import ForceSupervisor from 'graphology-layout-force/worker';
+import { isEqual } from 'lodash';
export enum State {
Default,
Hover,
- Active
+ Active,
}
export interface EntityState {
@@ -29,35 +36,40 @@ export interface EntityState {
}
interface NetworkData {
- nodes: (GeneNode | TranscriptNode)[],
- inverseNodes: (GeneNode | TranscriptNode)[],
- interactions: (GeneInteraction | TranscriptInteraction)[],
- disease: Dataset | undefined
+ nodes: (GeneNode | TranscriptNode)[];
+ inverseNodes: (GeneNode | TranscriptNode)[];
+ edges: (GeneInteraction | TranscriptInteraction)[];
+ disease: Dataset | undefined;
}
@Injectable({
- providedIn: 'root'
+ providedIn: 'root',
})
export class BrowseService {
readonly physicsEnabled$ = signal(true);
- readonly graph$ = computed(() => this.createGraph(this.nodes$(), this.interactions$(), this.inverseNodes$()));
- layout = computed(() => new ForceSupervisor(this.graph$(), {
- isNodeFixed: (_, attr) => attr['highlighted'],
- settings: {
- repulsion: 0.001,
- attraction: 0.01,
- gravity: 0.001,
- }
- }))
+ readonly graph$ = computed(() =>
+ this.createGraph(this.nodes$(), this.interactions$(), this.inverseNodes$()),
+ );
+ layout = computed(
+ () =>
+ new ForceSupervisor(this.graph$(), {
+ isNodeFixed: (_, attr) => attr['highlighted'],
+ settings: {
+ repulsion: 0.001,
+ attraction: 0.01,
+ gravity: 0.001,
+ },
+ }),
+ );
private readonly _query$ = signal(undefined);
private readonly _version$: Signal;
private readonly _comparisons$ = resource({
request: computed(() => {
- return this._version$()
+ return this._version$();
}),
loader: (param) => {
return this.backend.getComparisons(param.request);
- }
+ },
});
private readonly _currentData$: ResourceRef;
readonly disease$ = computed(() => this._currentData$.value()?.disease);
@@ -66,52 +78,85 @@ export class BrowseService {
const comparisons = this._comparisons$.value();
if (disease === undefined || comparisons === undefined) return [];
return comparisons
- .filter(c => c.gene_transcript == this.level$())
- .filter(c => c.dataset_1.dataset_ID === disease.dataset_ID || c.dataset_2.dataset_ID === disease.dataset_ID);
- })
+ .filter((c) => c.gene_transcript == this.level$())
+ .filter(
+ (c) =>
+ c.dataset_1.dataset_ID === disease.dataset_ID ||
+ c.dataset_2.dataset_ID === disease.dataset_ID,
+ );
+ });
readonly nodes$ = computed(() => this._currentData$.value()?.nodes || []);
- readonly inverseNodes$ = computed(() => this._currentData$.value()?.inverseNodes || []);
- readonly interactions$ = computed(() => this._currentData$.value()?.interactions || []);
+ readonly inverseNodes$ = computed(
+ () => this._currentData$.value()?.inverseNodes || [],
+ );
+ readonly interactions$ = computed(
+ () => this._currentData$.value()?.edges || [],
+ );
private readonly _nodeStates$ = signal>({});
activeNodes$ = computed(() => {
- const activeNodeIDs = Object.entries(this._nodeStates$()).filter(([_, state]) => state[State.Active]).map(([node, _]) => node);
- return this.nodes$().filter(node => activeNodeIDs.includes(BrowseService.getNodeID(node)));
+ const activeNodeIDs = Object.entries(this._nodeStates$())
+ .filter(([_, state]) => state[State.Active])
+ .map(([node, _]) => node);
+ return this.nodes$().filter((node) =>
+ activeNodeIDs.includes(BrowseService.getNodeID(node)),
+ );
});
private readonly _edgeStates$ = signal>({});
activeInteractions$ = computed(() => {
- const activeEdgeIDs = Object.entries(this._edgeStates$()).filter(([_, state]) => state[State.Active]).map(([edge, _]) => edge);
- return activeEdgeIDs.map(edgeID => this.getInteractionForEdge(edgeID, this.interactions$(), this.graph$())).flat().filter(interaction => interaction !== undefined);
- })
+ const activeEdgeIDs = Object.entries(this._edgeStates$())
+ .filter(([_, state]) => state[State.Active])
+ .map(([edge, _]) => edge);
+ return activeEdgeIDs
+ .map((edgeID) =>
+ this.getInteractionForEdge(edgeID, this.interactions$(), this.graph$()),
+ )
+ .flat()
+ .filter((interaction) => interaction !== undefined);
+ });
private readonly _networkResults$ = resource({
request: computed(() => {
return {
version: this._version$(),
- level: this.level$()
- }
+ level: this.level$(),
+ };
}),
loader: (param) => {
- return this.backend.getNetworkResults(param.request.version, param.request.level);
- }
+ return this.backend.getNetworkResults(
+ param.request.version,
+ param.request.level,
+ );
+ },
});
- constructor(private backend: BackendService, versionsService: VersionsService) {
+ constructor(
+ private backend: BackendService,
+ versionsService: VersionsService,
+ ) {
this._version$ = versionsService.versionReadOnly();
this._currentData$ = resource({
request: computed(() => {
return {
version: this._version$(),
- config: this._query$()
- }
+ config: this._query$(),
+ };
}),
- loader: (param) => this.fetchData(param.request.version, param.request.config),
- })
+ loader: (param) =>
+ this.fetchData(param.request.version, param.request.config),
+ });
effect(() => {
const graph = this.graph$();
- const initialState: EntityState = {[State.Hover]: false, [State.Active]: false};
- this._nodeStates$.set(Object.fromEntries(graph.nodes().map(node => [node, initialState])));
- this._edgeStates$.set(Object.fromEntries(graph.edges().map(edge => [edge, initialState])));
+ const initialState: EntityState = {
+ [State.Hover]: false,
+ [State.Active]: false,
+ };
+ this._nodeStates$.set(
+ Object.fromEntries(graph.nodes().map((node) => [node, initialState])),
+ );
+ this._edgeStates$.set(
+ Object.fromEntries(graph.edges().map((edge) => [edge, initialState])),
+ );
});
effect(() => {
@@ -157,29 +202,39 @@ export class BrowseService {
return BrowseService.getFullName(BrowseService.getNodeObject(node));
}
- public static getNodeObject(node: GeneNode | TranscriptNode): Gene | Transcript {
+ public static getNodeObject(
+ node: GeneNode | TranscriptNode,
+ ): Gene | Transcript {
return 'gene' in node ? node.gene : node.transcript;
}
- public static getInteractionIDs(interaction: GeneInteraction | TranscriptInteraction): [string, string] {
+ public static getInteractionIDs(
+ interaction: GeneInteraction | TranscriptInteraction,
+ ): [string, string] {
const objects = BrowseService.getInteractionObjects(interaction);
return objects.map(BrowseService.getID) as [string, string];
}
- public static getInteractionFullNames(interaction: GeneInteraction | TranscriptInteraction): [string, string] {
+ public static getInteractionFullNames(
+ interaction: GeneInteraction | TranscriptInteraction,
+ ): [string, string] {
const objects = BrowseService.getInteractionObjects(interaction);
return objects.map(BrowseService.getFullName) as [string, string];
}
- public static getInteractionGeneNames(interaction: GeneInteraction | TranscriptInteraction): [string, string] {
+ public static getInteractionGeneNames(
+ interaction: GeneInteraction | TranscriptInteraction,
+ ): [string, string] {
const objects = BrowseService.getInteractionObjects(interaction);
return objects.map(BrowseService.getGeneName) as [string, string];
}
- public static getInteractionObjects(interaction: GeneInteraction | TranscriptInteraction): [Gene, Gene] | [Transcript, Transcript] {
- return 'gene1' in interaction ?
- [interaction.gene1, interaction.gene2] :
- [interaction.transcript_1, interaction.transcript_2];
+ public static getInteractionObjects(
+ interaction: GeneInteraction | TranscriptInteraction,
+ ): [Gene, Gene] | [Transcript, Transcript] {
+ return 'gene1' in interaction
+ ? [interaction.gene1, interaction.gene2]
+ : [interaction.transcript_1, interaction.transcript_2];
}
public static getFullName(node: Gene | Transcript): string {
@@ -190,14 +245,18 @@ export class BrowseService {
}
}
- public static getGProfilerUrlForNodes(nodes: (GeneNode | TranscriptNode)[]): string {
- const genes = nodes.map(node => {
- if ('gene' in node) {
- return node.gene;
- } else {
- return node.transcript.gene;
- }
- }).map(gene => gene.gene_symbol || gene.ensg_number);
+ public static getGProfilerUrlForNodes(
+ nodes: (GeneNode | TranscriptNode)[],
+ ): string {
+ const genes = nodes
+ .map((node) => {
+ if ('gene' in node) {
+ return node.gene;
+ } else {
+ return node.transcript.gene;
+ }
+ })
+ .map((gene) => gene.gene_symbol || gene.ensg_number);
return `https://biit.cs.ut.ee/gprofiler/gost?organism=hsapiens&query=${genes.join(' ')}`;
}
@@ -207,7 +266,9 @@ export class BrowseService {
}
private static getGeneName(node: Gene | Transcript): string {
- return 'ensg_number' in node ? node.gene_symbol || node.ensg_number : node.gene.gene_symbol || node.gene.ensg_number;
+ return 'ensg_number' in node
+ ? node.gene_symbol || node.ensg_number
+ : node.gene.gene_symbol || node.gene.ensg_number;
}
runQuery(query: BrowseQuery) {
@@ -218,112 +279,140 @@ export class BrowseService {
return computed(() => this._query$()?.dataset?.download_url);
}
- async fetchData(version: number, config: BrowseQuery | undefined): Promise {
+ getEdgesForNode(node: Gene | Transcript) {
+ const nodeId = BrowseService.getID(node);
+ return computed(() => {
+ return this.interactions$().filter((interaction) => {
+ return BrowseService.getInteractionIDs(interaction).some(
+ (interactionID) => interactionID == nodeId,
+ );
+ });
+ });
+ }
+
+ async fetchData(
+ version: number,
+ config: BrowseQuery | undefined,
+ ): Promise {
if (config === undefined) {
return {
nodes: [],
inverseNodes: [],
- interactions: [],
- disease: undefined
- }
+ edges: [],
+ disease: undefined,
+ };
}
const inverseConfig = {
...config,
- level: config.level === 'gene' ? 'transcript' : 'gene' as 'gene' | 'transcript'
- }
-
- const inverseNodes$ = this.backend.getNodes(version, inverseConfig);
- let nodes = await this.backend.getNodes(version, config);
- // Get gene IDs or transcript IDs respectively
- const identifiers = nodes.map(node => 'gene' in node ? node.gene.ensg_number : node.transcript.enst_number);
- let interactions =
- await this.backend.getInteractionsSpecific(version, config.dataset, config.maxPValue, identifiers, config.level);
+ level:
+ config.level === 'gene'
+ ? 'transcript'
+ : ('gene' as 'gene' | 'transcript'),
+ };
+
+ const inverseNodes$ = this.backend
+ .getNetwork(version, inverseConfig)
+ .then((network) => network.nodes);
+ let { nodes, edges } = await this.backend.getNetwork(version, config);
const inverseNodes = await inverseNodes$;
- interactions = interactions.filter(interaction => interaction.mscor >= config.minMScore && interaction.p_value <= config.maxPValue);
- interactions = interactions.sort((a, b) => {
- switch (config.interactionSorting) {
- case InteractionSorting.pAdj:
- return a.p_value - b.p_value;
- case InteractionSorting.mScor:
- return a.mscor - b.mscor;
- case InteractionSorting.Correlation:
- return a.correlation - b.correlation;
- }
- });
- interactions = interactions.slice(0, config.maxInteractions);
-
if (!config.showOrphans) {
- const interactionNodes = interactions
- .map(interaction => BrowseService.getInteractionIDs(interaction)).flat();
- nodes = nodes.filter(node => {
+ const interactionNodes = edges
+ .map((interaction) => BrowseService.getInteractionIDs(interaction))
+ .flat();
+ nodes = nodes.filter((node) => {
const nodeObject = BrowseService.getNodeID(node);
- return interactionNodes.some(interactionObject => isEqual(interactionObject, nodeObject));
+ return interactionNodes.some((interactionObject) =>
+ isEqual(interactionObject, nodeObject),
+ );
});
}
return {
nodes,
inverseNodes,
- interactions,
- disease: config.dataset
- }
+ edges,
+ disease: config.dataset,
+ };
}
- toggleState(id: string, entityType: "node" | "edge", state: State.Active | State.Hover) {
- const states = entityType === "node" ? this._nodeStates$ : this._edgeStates$;
- states.update(entityStates => {
+ toggleState(
+ id: string,
+ entityType: 'node' | 'edge',
+ state: State.Active | State.Hover,
+ ) {
+ const states =
+ entityType === 'node' ? this._nodeStates$ : this._edgeStates$;
+ states.update((entityStates) => {
return {
...entityStates,
[id]: {
...entityStates[id],
- [state]: !entityStates[id][state]
- }
- }
+ [state]: !entityStates[id][state],
+ },
+ };
});
}
- setState(id: string, entityType: "node" | "edge", state: State, value: boolean) {
- const states = entityType === "node" ? this._nodeStates$ : this._edgeStates$;
- states.update(entityStates => {
+ setState(
+ id: string,
+ entityType: 'node' | 'edge',
+ state: State,
+ value: boolean,
+ ) {
+ const states =
+ entityType === 'node' ? this._nodeStates$ : this._edgeStates$;
+ states.update((entityStates) => {
return {
...entityStates,
[id]: {
...entityStates[id],
- [state]: value
- }
- }
+ [state]: value,
+ },
+ };
});
}
- getInteractionForEdge(edgeID: string, interactions: (GeneInteraction | TranscriptInteraction)[], graph: Graph): (GeneInteraction | TranscriptInteraction)[] {
+ getInteractionForEdge(
+ edgeID: string,
+ interactions: (GeneInteraction | TranscriptInteraction)[],
+ graph: Graph,
+ ): (GeneInteraction | TranscriptInteraction)[] {
const source = graph.source(edgeID);
const target = graph.target(edgeID);
- return interactions.filter(interaction => {
+ return interactions.filter((interaction) => {
const ids = BrowseService.getInteractionIDs(interaction);
- return (ids[0] === source && ids[1] === target) ||
- (ids[0] === target && ids[1] === source);
+ return (
+ (ids[0] === source && ids[1] === target) ||
+ (ids[0] === target && ids[1] === source)
+ );
});
}
- private createGraph(nodes: (GeneNode | TranscriptNode)[], interactions: (GeneInteraction | TranscriptInteraction)[], inverseNodes: (GeneNode | TranscriptNode)[]): Graph {
+ private createGraph(
+ nodes: (GeneNode | TranscriptNode)[],
+ interactions: (GeneInteraction | TranscriptInteraction)[],
+ inverseNodes: (GeneNode | TranscriptNode)[],
+ ): Graph {
const graph = new Graph();
- nodes.forEach(node => {
+ nodes.forEach((node) => {
const gene = BrowseService.getNodeGeneName(node);
- const hasInverse = inverseNodes.some(inverseNode => BrowseService.getNodeGeneName(inverseNode) === gene);
+ const hasInverse = inverseNodes.some(
+ (inverseNode) => BrowseService.getNodeGeneName(inverseNode) === gene,
+ );
graph.addNode(BrowseService.getNodeID(node), {
label: BrowseService.getNodeFullName(node),
x: Math.random(), // Coordinates will be overridden by the layout algorithm
y: Math.random(),
size: Math.log(node.node_degree),
forceLabel: true,
- type: hasInverse ? 'circle' : 'square'
+ type: hasInverse ? 'circle' : 'square',
});
});
- interactions.forEach(interaction => {
+ interactions.forEach((interaction) => {
const ids = BrowseService.getInteractionIDs(interaction);
if (graph.hasEdge(ids[0], ids[1])) {
return;
diff --git a/src/index.html b/src/index.html
index b03df550..74817ad9 100644
--- a/src/index.html
+++ b/src/index.html
@@ -11,6 +11,7 @@
+