diff --git a/src/ui/parcellationRegion/region.base.ts b/src/ui/parcellationRegion/region.base.ts index 9f382991a4d07440f9141bda6ce12055b7a6ed7c..d889899d67bf9204052c0e47961b7781b453a8d1 100644 --- a/src/ui/parcellationRegion/region.base.ts +++ b/src/ui/parcellationRegion/region.base.ts @@ -1,5 +1,5 @@ import {EventEmitter, Input, Output} from "@angular/core"; -import { Store } from "@ngrx/store"; +import {select, Store} from "@ngrx/store"; import {SET_CONNECTIVITY_REGION} from "src/services/state/viewerState.store"; import { EXPAND_SIDE_PANEL_CURRENT_VIEW, @@ -7,6 +7,8 @@ import { SHOW_SIDE_PANEL_CONNECTIVITY, } from "src/services/stateStore.service"; import { VIEWERSTATE_CONTROLLER_ACTION_TYPES } from "../viewerStateController/viewerState.base"; +import {distinctUntilChanged, shareReplay} from "rxjs/operators"; +import {Observable} from "rxjs"; export class RegionBase { @@ -20,10 +22,40 @@ export class RegionBase { @Output() public closeRegionMenu: EventEmitter<boolean> = new EventEmitter() + public loadedTemplate$: Observable<any[]> + public templateSelected$: Observable<any[]> + public parcellationSelected$: Observable<any[]> + + protected loadedTemplates: any[] + protected selectedTemplate: any + protected selectedParcellation: any + protected sameRegionTemplate: any[] = [] + + private parcellationRegions: any[] = [] + constructor( private store$: Store<IavRootStoreInterface>, ) { + const viewerState$ = this.store$.pipe( + select('viewerState'), + shareReplay(1), + ) + + this.loadedTemplate$ = viewerState$.pipe( + select('fetchedTemplates'), + distinctUntilChanged() + ) + + this.templateSelected$ = viewerState$.pipe( + select('templateSelected'), + distinctUntilChanged(), + ) + + this.parcellationSelected$ = viewerState$.pipe( + select('parcellationSelected'), + distinctUntilChanged(), + ) } public navigateToRegion() { @@ -56,4 +88,71 @@ export class RegionBase { connectivityRegion: regionName, }) } + + getSameParcellationTemplates = () => { + // Get All the templates which includes parcellation equal to selected parcellation + // (E.g. if MNI 152 ICBM Jubrain is selected method returns MNI Colin 27) + this.loadedTemplates.forEach(template => { + if (this.selectedTemplate.name !== template.name + && template.parcellations.map(p => p.name).includes(this.selectedParcellation.name)) { + this.sameRegionTemplate.push(template.name) + } + }) + return null + } + + bigBrainJubrainSwitch = () => { + // If Jubrain or bigbrain is selected and clicked region is included in both of them + // push template name to sameRegionTemplate to change template from menu + this.loadedTemplates.forEach(template => { + if(this.selectedTemplate.name === 'Big Brain (Histology)' + && template.parcellations.map( p => p.name).includes('JuBrain Cytoarchitectonic Atlas')) { + + this.parcellationRegions = [] + + this.getAllRegionsFromParcellation(template.parcellations.filter(p => p.name === 'JuBrain Cytoarchitectonic Atlas')[0].regions) + this.parcellationRegions.forEach(pr => { + if (!pr.name.includes(' - left hemisphere')) { + if (pr.name.includes(' - right hemisphere')) pr.name = pr.name.replace(' - right hemisphere','') + if (!this.sameRegionTemplate.includes(template.name)) this.sameRegionTemplate.push(template.name) + } + }) + } + else if(this.selectedParcellation.name === 'JuBrain Cytoarchitectonic Atlas' + && template.name === 'Big Brain (Histology)') { + let exploreRegion = this.region.name + if (exploreRegion.includes(' - right hemisphere')) exploreRegion = exploreRegion.replace(' - right hemisphere','') + if (exploreRegion.includes(' - left hemisphere')) exploreRegion = exploreRegion.replace(' - left hemisphere','') + this.getAllRegionsFromParcellation(template.parcellations.filter(p => p.name === 'Cytoarchitectonic Maps')[0].regions) + if (this.parcellationRegions.map(pr => pr.name).includes(exploreRegion)) this.sameRegionTemplate.push(template.name) + } + }) + } + + selectTemplate(templateName) { + this.closeRegionMenu.emit() + this.store$.dispatch({ + type: VIEWERSTATE_CONTROLLER_ACTION_TYPES.SELECT_TEMPLATE_WITH_NAME, + payload: { + name: templateName, + }, + }) + } + + + public getAllRegionsFromParcellation = (regions) => { + for (const region of regions) { + if (region.children && region.children.length) { + this.getAllRegionsFromParcellation(region.children) + } else { + this.parcellationRegions.push(region) + } + } + } + + + + + + } diff --git a/src/ui/parcellationRegion/regionMenu/regionMenu.component.ts b/src/ui/parcellationRegion/regionMenu/regionMenu.component.ts index d6b84425c69210634101345df9b6d7cc802bed43..dd91ee1d228b24a8b970df66010106153e6da74e 100644 --- a/src/ui/parcellationRegion/regionMenu/regionMenu.component.ts +++ b/src/ui/parcellationRegion/regionMenu/regionMenu.component.ts @@ -1,19 +1,48 @@ -import { Component } from "@angular/core"; +import {AfterViewInit, Component, ElementRef, OnDestroy, OnInit, ViewChild} from "@angular/core"; import { Store } from "@ngrx/store"; +import {MatMenuTrigger} from "@angular/material/menu"; +import {Subscription} from "rxjs"; import { IavRootStoreInterface } from "src/services/stateStore.service"; import { RegionBase } from '../region.base' +import {VIEWERSTATE_CONTROLLER_ACTION_TYPES} from "src/ui/viewerStateController/viewerState.base"; @Component({ selector: 'region-menu', templateUrl: './regionMenu.template.html', styleUrls: ['./regionMenu.style.css'], }) -export class RegionMenuComponent extends RegionBase { +export class RegionMenuComponent extends RegionBase implements OnInit, OnDestroy { + + @ViewChild('additionalActionsMenuButton', {read: MatMenuTrigger}) actionsMenuTriggerButton: MatMenuTrigger + @ViewChild('additionalActionsPanel', {read: ElementRef}) additionalActionsPanelElement: ElementRef + + private subscriptions: Subscription[] = [] constructor( store$: Store<IavRootStoreInterface>, ) { super(store$) } + + ngOnInit(): void { + this.subscriptions.push( + this.templateSelected$.subscribe(template => { + this.selectedTemplate = template + }), + this.parcellationSelected$.subscribe(parcellation => { + this.selectedParcellation = parcellation + }), + this.loadedTemplate$.subscribe(templates => { + this.loadedTemplates = templates + this.bigBrainJubrainSwitch() + this.getSameParcellationTemplates() + }), + ) + } + + ngOnDestroy(): void { + this.subscriptions.forEach(s => s.unsubscribe()) + } + } diff --git a/src/ui/parcellationRegion/regionMenu/regionMenu.template.html b/src/ui/parcellationRegion/regionMenu/regionMenu.template.html index 1d7e78a1ad5484f51b35145ac258fcc73f278e04..d9cf765f799b52eff3fd174bef9db82c0012c0b6 100644 --- a/src/ui/parcellationRegion/regionMenu/regionMenu.template.html +++ b/src/ui/parcellationRegion/regionMenu/regionMenu.template.html @@ -5,7 +5,7 @@ <mat-card-content> {{ region.description }} </mat-card-content> - <mat-card-actions class="d-flex flex-row flex-wrap"> + <div class="d-flex flex-row flex-wrap" #actionCard> <button mat-button (click)="toggleRegionSelected()" [color]="isSelected ? 'primary': 'basic'"> @@ -20,11 +20,34 @@ Navigate </span> </button> + <button *ngIf="hasConnectivity" mat-button (click)="showConnectivity(region.name)"> <i class="fab fa-connectdevelop"></i> <span> - Connectivity - </span> + Connectivity + </span> </button> - </mat-card-actions> + + <!-- Menu to navigate between template spaces to explore same region --> + <div #additionalActions> + <button mat-icon-button + *ngIf="sameRegionTemplate.length" + [matMenuTriggerFor]="additionalActions" + #additionalActionsMenuButton="matMenuTrigger" + (mouseenter)="$event.stopPropagation(); actionsMenuTriggerButton.openMenu()"> + <i class="fas fa-angle-right"></i> + </button> + </div> + + <mat-menu #additionalActions="matMenu" xPosition="before" (click)="$event.stopPropagation()" hasBackdrop="false"> + <div> + <button mat-menu-item *ngFor="let templateName of sameRegionTemplate" (click)="selectTemplate(templateName)"> + <span> + Explore in {{templateName}} + </span> + </button> + </div> + </mat-menu> + + </div> </mat-card> \ No newline at end of file