diff --git a/src/ui/databrowserModule/singleDataset/sideNavView/sDsSideNavView.template.html b/src/ui/databrowserModule/singleDataset/sideNavView/sDsSideNavView.template.html index c9fceb2e755e665c77e3d3784d1eea2de7430992..e71d9cc744e8d596f258d4bd00a9a99e502a83ac 100644 --- a/src/ui/databrowserModule/singleDataset/sideNavView/sDsSideNavView.template.html +++ b/src/ui/databrowserModule/singleDataset/sideNavView/sDsSideNavView.template.html @@ -92,7 +92,8 @@ <ng-template matExpansionPanelContent> <feature-explorer [feature]="feature" - [region]="region$ | async"> + [region]="region$ | async" + (feature-explorer-is-loading)="detectChange()"> </feature-explorer> </ng-template> diff --git a/src/ui/regionalFeatures/featureExplorer/featureExplorer.component.ts b/src/ui/regionalFeatures/featureExplorer/featureExplorer.component.ts index fa75b061364ed658f11a9febcde1fb04275ac4e6..007a41c1acbe0b73e5845570c8bc15b87d005db5 100644 --- a/src/ui/regionalFeatures/featureExplorer/featureExplorer.component.ts +++ b/src/ui/regionalFeatures/featureExplorer/featureExplorer.component.ts @@ -1,6 +1,6 @@ -import { Component, Input, OnDestroy, OnInit } from "@angular/core"; -import { BehaviorSubject, forkJoin, Observable, Subject, Subscription } from "rxjs"; -import { shareReplay, switchMap, tap } from "rxjs/operators"; +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; +import { BehaviorSubject, forkJoin, merge, Observable, Subject, Subscription } from "rxjs"; +import { debounceTime, map, scan, shareReplay, switchMap, tap } from "rxjs/operators"; import { IHasId } from "src/util/interfaces"; import { IFeature, RegionalFeaturesService } from "../regionalFeature.service"; @@ -33,6 +33,9 @@ export class FeatureExplorer implements OnInit, OnDestroy{ public data$: Observable<IHasId[]> + @Output('feature-explorer-is-loading') + public dataIsLoadingEventEmitter: EventEmitter<boolean> = new EventEmitter() + constructor( private regionFeatureService: RegionalFeaturesService, ){ @@ -81,6 +84,25 @@ export class FeatureExplorer implements OnInit, OnDestroy{ this.onDestroyCb.push(() => { if (this.landmarksLoaded.length > 0) this.regionFeatureService.removeLandmarks(this.landmarksLoaded) }) + + this.sub.push( + this.openElectrodeId$.pipe( + debounceTime(200) + ).subscribe(arr => { + + if (this.landmarksLoaded.length > 0) { + this.regionFeatureService.removeLandmarks(this.landmarksLoaded) + this.regionFeatureService.addLandmarks(this.landmarksLoaded.map(lm => { + const selected = arr.some(id => id === lm['_']['electrodeId']) + return { + ...lm, + color: selected ? selectedColor : null, + showInSliceView: selected + } + })) + } + }) + ) } public dataIsLoading$ = new BehaviorSubject(false) @@ -89,6 +111,7 @@ export class FeatureExplorer implements OnInit, OnDestroy{ if (val === this._dataIsLoading) return this._dataIsLoading = val this.dataIsLoading$.next(val) + this.dataIsLoadingEventEmitter.next(val) } get dataIsLoading(){ return this._dataIsLoading @@ -103,23 +126,34 @@ export class FeatureExplorer implements OnInit, OnDestroy{ /** * TODO either debounce call here, or later down stream */ - if (this.landmarksLoaded.length > 0) this.regionFeatureService.removeLandmarks(this.landmarksLoaded) - if (this.landmarksLoaded.length > 0) { - this.regionFeatureService.addLandmarks(this.landmarksLoaded.map(lm => { - if (lm['_']['electrodeId'] === electrodeId) { - return { - ...lm, - color: open ? selectedColor : null, - showInSliceView: open - } - } else { - return lm - } - })) - } + if (open) this.exploreElectrode$.next(electrodeId) + else this.unExploreElectrode$.next(electrodeId) } - public exploreElectrode$ = new Subject() + private unExploreElectrode$ = new Subject<string>() + private exploreElectrode$ = new Subject<string>() + public openElectrodeId$ = merge( + this.unExploreElectrode$.pipe( + map(id => ({ + add: null, + remove: id + })) + ), + this.exploreElectrode$.pipe( + map(id => ({ + add: id, + remove: null + })) + ) + ).pipe( + scan((acc, curr) => { + const { add, remove } = curr + const set = new Set(acc) + if (add) set.add(add) + if (remove) set.delete(remove) + return Array.from(set) + }, []) + ) handleLandmarkClick(arg: { landmark: any, next: Function }) { const { landmark, next } = arg @@ -133,9 +167,9 @@ export class FeatureExplorer implements OnInit, OnDestroy{ }) if (isOne) { - this.exploreElectrode$.next(landmark) + this.exploreElectrode$.next(landmark['_']['electrodeId']) } else { next() } } -} \ No newline at end of file +} diff --git a/src/ui/regionalFeatures/featureExplorer/featureExplorer.template.html b/src/ui/regionalFeatures/featureExplorer/featureExplorer.template.html index 59d2d580504b33f5f7f5032b909f62a0e7600ae5..7c5f3cf3367c8ca0408a1279f2ec8046dc66819b 100644 --- a/src/ui/regionalFeatures/featureExplorer/featureExplorer.template.html +++ b/src/ui/regionalFeatures/featureExplorer/featureExplorer.template.html @@ -6,7 +6,7 @@ (rf-interact-onclick-3d-landmark)="handleLandmarkClick($event)" #interactDir="regionalFeatureInteractivity"> <mat-expansion-panel *ngFor="let datum of (data$ | async)" - [expanded]="(exploreElectrode$ | async | getProperty : '_' | getProperty : 'electrodeId') === datum['@id']" + [expanded]="openElectrodeId$ | async | arrayContains : datum['@id']" (opened)="handleDatumExpansion(datum['@id'], true)" (closed)="handleDatumExpansion(datum['@id'], false)" togglePosition="before"> diff --git a/src/util/pipes/arrayContains.pipe.ts b/src/util/pipes/arrayContains.pipe.ts new file mode 100644 index 0000000000000000000000000000000000000000..e36b1283d2b69dc11e6c2a1febdc5604ad204ec1 --- /dev/null +++ b/src/util/pipes/arrayContains.pipe.ts @@ -0,0 +1,12 @@ +import { Pipe, PipeTransform } from "@angular/core"; + +@Pipe({ + name: 'arrayContains', + pure: true +}) + +export class ArrayContainsPipe implements PipeTransform{ + public transform<T>(inputArray: T[], qualifier: T): boolean{ + return (inputArray || []).some(it => it === qualifier) + } +} diff --git a/src/util/util.module.ts b/src/util/util.module.ts index d03ee97f4efa39239d298b76cde710f8ba003fde..2259d3b71c8e6a4a035c846e413f0074dffc0040 100644 --- a/src/util/util.module.ts +++ b/src/util/util.module.ts @@ -22,6 +22,7 @@ import { GetUniquePipe } from "./pipes/getUnique.pipe"; import { GetPropertyPipe } from "./pipes/getProperty.pipe"; import { FilterArrayPipe } from "./pipes/filterArray.pipe"; import { FilterByPropertyPipe } from "./pipes/filterByProperty.pipe"; +import { ArrayContainsPipe } from "./pipes/arrayContains.pipe"; @NgModule({ imports:[ @@ -49,6 +50,7 @@ import { FilterByPropertyPipe } from "./pipes/filterByProperty.pipe"; GetPropertyPipe, FilterArrayPipe, FilterByPropertyPipe, + ArrayContainsPipe, ], exports: [ FilterNullPipe, @@ -72,6 +74,7 @@ import { FilterByPropertyPipe } from "./pipes/filterByProperty.pipe"; GetPropertyPipe, FilterArrayPipe, FilterByPropertyPipe, + ArrayContainsPipe, ] })