1
- import { AfterViewInit , Component , effect , inject , model , resource , ResourceRef , viewChild } from '@angular/core' ;
2
- import { Gene , GOTerm } from "../../interfaces" ;
3
- import { MAT_DIALOG_DATA , MatDialog , MatDialogModule } from "@angular/material/dialog" ;
4
- import { MatButtonModule } from "@angular/material/button" ;
5
- import { VersionsService } from "../../services/versions.service" ;
6
- import { BackendService } from "../../services/backend.service" ;
7
- import { MatTabsModule } from "@angular/material/tabs" ;
8
- import { MatExpansionModule } from "@angular/material/expansion" ;
9
- import { MatTableDataSource , MatTableModule } from "@angular/material/table" ;
10
- import { MatPaginator , MatPaginatorModule } from "@angular/material/paginator" ;
11
- import { MatFormFieldModule } from "@angular/material/form-field" ;
12
- import { MatInputModule } from "@angular/material/input" ;
13
- import { FormsModule } from "@angular/forms" ;
14
- import { MatChip , MatChipSet } from "@angular/material/chips" ;
15
- import { MatProgressSpinner } from "@angular/material/progress-spinner" ;
16
- import { TranscriptModalComponent } from "../transcript-modal/transcript-modal.component" ;
17
- import { AS_DESCRIPTIONS } from "../../constants" ;
18
- import { MatTooltip } from "@angular/material/tooltip" ;
1
+ import {
2
+ AfterViewInit ,
3
+ Component ,
4
+ computed ,
5
+ effect ,
6
+ inject ,
7
+ model ,
8
+ resource ,
9
+ ResourceRef ,
10
+ Signal ,
11
+ viewChild ,
12
+ } from '@angular/core' ;
13
+ import { Gene , GOTerm } from '../../interfaces' ;
14
+ import { MAT_DIALOG_DATA , MatDialogModule } from '@angular/material/dialog' ;
15
+ import { MatButtonModule } from '@angular/material/button' ;
16
+ import { VersionsService } from '../../services/versions.service' ;
17
+ import { BackendService } from '../../services/backend.service' ;
18
+ import { MatTabsModule } from '@angular/material/tabs' ;
19
+ import { MatExpansionModule } from '@angular/material/expansion' ;
20
+ import { MatTableDataSource , MatTableModule } from '@angular/material/table' ;
21
+ import { MatPaginator , MatPaginatorModule } from '@angular/material/paginator' ;
22
+ import { MatFormFieldModule } from '@angular/material/form-field' ;
23
+ import { MatInputModule } from '@angular/material/input' ;
24
+ import { FormsModule } from '@angular/forms' ;
25
+ import { MatChip , MatChipSet } from '@angular/material/chips' ;
26
+ import { MatProgressSpinner } from '@angular/material/progress-spinner' ;
27
+ import { AS_DESCRIPTIONS , IGV_REFGENOME } from '../../constants' ;
28
+ import { MatTooltip } from '@angular/material/tooltip' ;
29
+ import { Igv , Location , Track } from '@visa-ge/ng-igv' ;
30
+ import { ModalsService } from '../modals-service/modals.service' ;
31
+ import { BrowseService } from '../../services/browse.service' ;
19
32
20
33
interface ASEntry {
21
34
enst : string ;
@@ -37,69 +50,151 @@ interface ASEntry {
37
50
MatChipSet ,
38
51
MatChip ,
39
52
MatProgressSpinner ,
40
- MatTooltip
53
+ MatTooltip ,
54
+ Igv ,
41
55
] ,
42
56
templateUrl : './gene-modal.component.html' ,
43
- styleUrl : './gene-modal.component.scss'
57
+ styleUrl : './gene-modal.component.scss' ,
44
58
} )
45
59
export class GeneModalComponent implements AfterViewInit {
46
60
goPaginator = viewChild . required < MatPaginator > ( 'goPaginator' ) ;
47
61
asPaginator = viewChild . required < MatPaginator > ( 'asPaginator' ) ;
48
- goColumns = [ 'symbol' , 'description' ]
49
- asColumns = [ 'enst' , 'events' ]
50
- goFilter = model < string > ( '' )
51
- dialog = inject ( MatDialog ) ;
52
- readonly asDescriptions = AS_DESCRIPTIONS
62
+ goColumns = [ 'symbol' , 'description' ] ;
63
+ asColumns = [ 'enst' , 'events' ] ;
64
+ goFilter = model < string > ( '' ) ;
65
+ readonly asDescriptions = AS_DESCRIPTIONS ;
66
+ modalsService = inject ( ModalsService ) ;
53
67
68
+ browseService = inject ( BrowseService ) ;
69
+ readonly disease$ = this . browseService . disease$ ;
54
70
readonly gene = inject < Gene > ( MAT_DIALOG_DATA ) ;
55
71
readonly versionsService = inject ( VersionsService ) ;
56
72
readonly backend = inject ( BackendService ) ;
57
73
readonly version$ = this . versionsService . versionReadOnly ( ) ;
58
74
readonly isOpeningTranscript = model < boolean > ( false ) ;
75
+ readonly activeTab$ = model < number > ( 0 ) ;
59
76
60
77
goDatasource = new MatTableDataSource < GOTerm > ( ) ;
61
78
asDatasource = new MatTableDataSource < ASEntry > ( ) ;
62
79
80
+ edges$ = this . browseService . getEdgesForNode ( this . gene ) ;
81
+ miRNAs$ = resource ( {
82
+ request : computed ( ( ) => {
83
+ return {
84
+ edges : this . edges$ ( ) ,
85
+ disease : this . disease$ ( ) ,
86
+ version : this . version$ ( ) ,
87
+ } ;
88
+ } ) ,
89
+ loader : async ( param ) => {
90
+ const edges = param . request . edges ;
91
+ const disease = param . request . disease ;
92
+ const version = param . request . version ;
93
+ if ( ! disease ) {
94
+ return Promise . resolve ( [ ] ) ;
95
+ }
96
+ const miRNAs$ = edges . map ( ( edge ) =>
97
+ this . backend
98
+ . getMiRNAs (
99
+ version ,
100
+ disease ,
101
+ BrowseService . getInteractionIDs ( edge ) ,
102
+ 'gene' ,
103
+ )
104
+ . then ( ( res ) => res . map ( ( mirna ) => mirna . mirna . hs_nr ) ) ,
105
+ ) ;
106
+ return ( await Promise . all ( miRNAs$ ) )
107
+ . flat ( )
108
+ . filter ( ( miRNA , i , arr ) => arr . indexOf ( miRNA ) === i ) ;
109
+ } ,
110
+ } ) ;
111
+
112
+ miRNAtracks$ = computed ( ( ) : Track [ ] => {
113
+ const miRNAs = this . miRNAs$ . value ( ) ;
114
+ if ( ! miRNAs ) {
115
+ return [ ] ;
116
+ }
117
+ return miRNAs . map ( ( miRNA ) => {
118
+ return {
119
+ name : miRNA ,
120
+ url : `https://exbio.wzw.tum.de/sponge-files/miRNA_bed_files/${ miRNA } .bed.gz` ,
121
+ format : 'bed' ,
122
+ type : 'annotation' ,
123
+ height : 30 ,
124
+ displayMode : 'SQUISHED' ,
125
+ indexed : false ,
126
+ } ;
127
+ } ) ;
128
+ } ) ;
129
+
63
130
readonly geneInfo$ = resource ( {
64
131
request : this . version$ ,
65
- loader : async ( version ) => this . backend . getGeneInfo ( version . request , this . gene . ensg_number ) . then ( info => info [ 0 ] )
66
- } )
132
+ loader : async ( version ) =>
133
+ this . backend
134
+ . getGeneInfo ( version . request , this . gene . ensg_number )
135
+ . then ( ( info ) => info [ 0 ] ) ,
136
+ } ) ;
67
137
68
138
readonly goTerms$ = resource ( {
69
139
request : this . version$ ,
70
- loader : async ( version ) => this . backend . getGOterms ( version . request , this . gene . gene_symbol )
71
- } )
140
+ loader : async ( version ) =>
141
+ this . backend . getGOterms ( version . request , this . gene . gene_symbol ) ,
142
+ } ) ;
72
143
73
144
readonly hallmarks$ = resource ( {
74
145
request : this . version$ ,
75
- loader : async ( version ) => this . backend . getHallmark ( version . request , this . gene . gene_symbol )
76
- } )
146
+ loader : async ( version ) =>
147
+ this . backend . getHallmark ( version . request , this . gene . gene_symbol ) ,
148
+ } ) ;
77
149
78
150
readonly wikipathways$ = resource ( {
79
151
request : this . version$ ,
80
- loader : async ( version ) => this . backend . getWikiPathways ( version . request , this . gene . gene_symbol )
81
- } )
152
+ loader : async ( version ) =>
153
+ this . backend . getWikiPathways ( version . request , this . gene . gene_symbol ) ,
154
+ } ) ;
82
155
83
156
readonly transcripts$ : ResourceRef < ASEntry [ ] > = resource ( {
84
157
request : this . version$ ,
85
158
loader : async ( version ) => {
86
- const transcripts = await this . backend . getGeneTranscripts ( version . request , this . gene . ensg_number ) ;
87
- const asEvents = await this . backend . getAlternativeSplicingEvents ( transcripts ) ;
159
+ const transcripts = await this . backend . getGeneTranscripts (
160
+ version . request ,
161
+ this . gene . ensg_number ,
162
+ ) ;
163
+ const asEvents =
164
+ await this . backend . getAlternativeSplicingEvents ( transcripts ) ;
88
165
const transcriptEvents = asEvents . reduce ( ( acc , event ) => {
89
166
const enst = event . transcript . enst_number ;
90
167
if ( ! acc . has ( enst ) ) {
91
168
acc . set ( enst , new Set < string > ( ) ) ;
92
169
}
93
170
acc . get ( enst ) ! . add ( event . event_type ) ;
94
171
return acc ;
95
- } , new Map < string , Set < string > > ( ) )
172
+ } , new Map < string , Set < string > > ( ) ) ;
96
173
97
- return transcripts . map ( t => ( {
174
+ return transcripts . map ( ( t ) => ( {
98
175
enst : t ,
99
- events : Array . from ( transcriptEvents . get ( t ) ?? [ ] )
176
+ events : Array . from ( transcriptEvents . get ( t ) ?? [ ] ) ,
100
177
} ) ) ;
178
+ } ,
179
+ } ) ;
180
+
181
+ readonly location$ : Signal < Location > = computed ( ( ) => {
182
+ const geneInfo = this . geneInfo$ . value ( ) ;
183
+ if ( ! geneInfo ) {
184
+ return {
185
+ chr : 'all' ,
186
+ } ;
187
+ } else {
188
+ return {
189
+ chr : geneInfo . chromosome_name ,
190
+ range : {
191
+ start : geneInfo . start_pos ,
192
+ end : geneInfo . end_pos ,
193
+ } ,
194
+ } ;
101
195
}
102
- } )
196
+ } ) ;
197
+ protected readonly IGV_REFGENOME = IGV_REFGENOME ;
103
198
104
199
constructor ( ) {
105
200
effect ( ( ) => {
@@ -112,7 +207,7 @@ export class GeneModalComponent implements AfterViewInit {
112
207
113
208
effect ( ( ) => {
114
209
this . asDatasource . data = this . transcripts$ . value ( ) ?? [ ] ;
115
- } )
210
+ } ) ;
116
211
}
117
212
118
213
ngAfterViewInit ( ) : void {
@@ -123,10 +218,10 @@ export class GeneModalComponent implements AfterViewInit {
123
218
async openTranscript ( enst : string ) {
124
219
if ( this . isOpeningTranscript ( ) ) return ;
125
220
this . isOpeningTranscript . set ( true ) ;
126
- const transcript = ( await this . backend . getTranscriptInfo ( this . version$ ( ) , enst ) ) [ 0 ] ;
127
- this . dialog . open ( TranscriptModalComponent , {
128
- data : transcript
129
- } ) ;
221
+ const transcript = (
222
+ await this . backend . getTranscriptInfo ( this . version$ ( ) , enst )
223
+ ) [ 0 ] ;
224
+ this . modalsService . openNodeDialog ( transcript ) ;
130
225
this . isOpeningTranscript . set ( false ) ;
131
226
}
132
227
}
0 commit comments