Skip to content
Snippets Groups Projects
Unverified Commit e031bcbb authored by xgui3783's avatar xgui3783 Committed by GitHub
Browse files

Merge pull request #291 from HumanBrainProject/bugfix/userLandmarks

bugfix: adding and removing userlandmarks
parents 6f4d7e97 1eb04963
No related branches found
No related tags found
No related merge requests found
......@@ -42,6 +42,7 @@ import {HttpClientModule} from "@angular/common/http";
import { EffectsModule } from "@ngrx/effects";
import { UseEffects } from "./services/effect/effect";
import { MatDialogModule, MatTabsModule } from "@angular/material";
import { ViewerStateUseEffect } from "./services/state/viewerState.store";
@NgModule({
imports : [
......@@ -62,6 +63,7 @@ import { MatDialogModule, MatTabsModule } from "@angular/material";
TooltipModule.forRoot(),
TabsModule.forRoot(),
EffectsModule.forRoot([
ViewerStateUseEffect,
UseEffects
]),
StoreModule.forRoot({
......
import { Action } from '@ngrx/store'
import { Action, Store, select } from '@ngrx/store'
import { UserLandmark } from 'src/atlasViewer/atlasViewer.apiService.service';
import { NgLayerInterface } from 'src/atlasViewer/atlasViewer.component';
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { withLatestFrom, map, shareReplay, startWith, tap } from 'rxjs/operators';
import { Observable } from 'rxjs';
export interface ViewerStateInterface{
fetchedTemplates : any[]
......@@ -34,13 +38,16 @@ export interface AtlasAction extends Action{
deselectLandmarks : UserLandmark[]
navigation? : any
payload: any
}
export function viewerState(
state:Partial<ViewerStateInterface> = {
landmarksSelected : [],
fetchedTemplates : [],
loadedNgLayers: []
loadedNgLayers: [],
userLandmarks: []
},
action:AtlasAction
){
......@@ -174,3 +181,78 @@ export const DESELECT_LANDMARKS = `DESELECT_LANDMARKS`
export const USER_LANDMARKS = `USER_LANDMARKS`
export const NEHUBA_LAYER_CHANGED = `NEHUBA_LAYER_CHANGED`
@Injectable({
providedIn: 'root'
})
export class ViewerStateUseEffect{
constructor(
private actions$: Actions,
private store$: Store<any>
){
this.currentLandmarks$ = this.store$.pipe(
select('viewerState'),
select('userLandmarks'),
shareReplay(1),
)
this.removeUserLandmarks = this.actions$.pipe(
ofType(ACTION_TYPES.REMOVE_USER_LANDMARKS),
withLatestFrom(this.currentLandmarks$),
map(([action, currentLandmarks]) => {
const { landmarkIds } = (action as AtlasAction).payload
for ( const rmId of landmarkIds ){
const idx = currentLandmarks.findIndex(({ id }) => id === rmId)
if (idx < 0) console.warn(`remove userlandmark with id ${rmId} does not exist`)
}
const removeSet = new Set(landmarkIds)
return {
type: USER_LANDMARKS,
landmarks: currentLandmarks.filter(({ id }) => !removeSet.has(id))
}
})
)
this.addUserLandmarks$ = this.actions$.pipe(
ofType(ACTION_TYPES.ADD_USERLANDMARKS),
withLatestFrom(this.currentLandmarks$),
map(([action, currentLandmarks]) => {
const { landmarks } = action as AtlasAction
const landmarkMap = new Map()
for (const landmark of currentLandmarks) {
const { id } = landmark
landmarkMap.set(id, landmark)
}
for (const landmark of landmarks) {
const { id } = landmark
if (landmarkMap.has(id)) {
console.warn(`Attempting to add a landmark that already exists, id: ${id}`)
} else {
landmarkMap.set(id, landmark)
}
}
const userLandmarks = Array.from(landmarkMap).map(([id, landmark]) => landmark)
return {
type: USER_LANDMARKS,
landmarks: userLandmarks
}
})
)
}
private currentLandmarks$: Observable<any[]>
@Effect()
removeUserLandmarks: Observable<any>
@Effect()
addUserLandmarks$: Observable<any>
}
const ACTION_TYPES = {
ADD_USERLANDMARKS: `ADD_USERLANDMARKS`,
REMOVE_USER_LANDMARKS: 'REMOVE_USER_LANDMARKS'
}
export const VIEWERSTATE_ACTION_TYPES = ACTION_TYPES
\ No newline at end of file
......@@ -3,7 +3,7 @@ import { NehubaViewerUnit } from "./nehubaViewer/nehubaViewer.component";
import { Store, select } from "@ngrx/store";
import { ViewerStateInterface, safeFilter, CHANGE_NAVIGATION, isDefined, USER_LANDMARKS, ADD_NG_LAYER, REMOVE_NG_LAYER, NgViewerStateInterface, MOUSE_OVER_LANDMARK, SELECT_LANDMARKS, Landmark, PointLandmarkGeometry, PlaneLandmarkGeometry, OtherLandmarkGeometry, getNgIds, getMultiNgIdsRegionsLabelIndexMap, generateLabelIndexId } from "../../services/stateStore.service";
import { Observable, Subscription, fromEvent, combineLatest, merge } from "rxjs";
import { filter,map, take, scan, debounceTime, distinctUntilChanged, switchMap, skip, withLatestFrom, buffer, tap, throttleTime, bufferTime } from "rxjs/operators";
import { filter,map, take, scan, debounceTime, distinctUntilChanged, switchMap, skip, withLatestFrom, buffer, tap, throttleTime, bufferTime, startWith } from "rxjs/operators";
import { AtlasViewerAPIServices, UserLandmark } from "../../atlasViewer/atlasViewer.apiService.service";
import { timedValues } from "../../util/generator";
import { AtlasViewerConstantsServices } from "../../atlasViewer/atlasViewer.constantService.service";
......@@ -11,7 +11,7 @@ import { ViewerConfiguration } from "src/services/state/viewerConfig.store";
import { pipeFromArray } from "rxjs/internal/util/pipe";
import { NEHUBA_READY } from "src/services/state/ngViewerState.store";
import { MOUSE_OVER_SEGMENTS } from "src/services/state/uiState.store";
import { SELECT_REGIONS_WITH_ID, NEHUBA_LAYER_CHANGED } from "src/services/state/viewerState.store";
import { SELECT_REGIONS_WITH_ID, NEHUBA_LAYER_CHANGED, VIEWERSTATE_ACTION_TYPES } from "src/services/state/viewerState.store";
const getProxyUrl = (ngUrl) => `nifti://${BACKEND_URL}preview/file?fileUrl=${encodeURIComponent(ngUrl.replace(/^nifti:\/\//,''))}`
const getProxyOther = ({source}) => /AUTH_227176556f3c4bb38df9feea4b91200c/.test(source)
......@@ -135,8 +135,6 @@ export class NehubaContainer implements OnInit, OnDestroy{
private landmarksLabelIndexMap : Map<number, any> = new Map()
private landmarksNameMap : Map<string,number> = new Map()
private userLandmarks : UserLandmark[] = []
private subscriptions : Subscription[] = []
private nehubaViewerSubscriptions : Subscription[] = []
......@@ -220,13 +218,9 @@ export class NehubaContainer implements OnInit, OnDestroy{
)
this.userLandmarks$ = this.store.pipe(
/* TODO: distinct until changed */
select('viewerState'),
// filter(state => isDefined(state) && isDefined(state.userLandmarks)),
map(state => isDefined(state) && isDefined(state.userLandmarks)
? state.userLandmarks
: []),
distinctUntilChanged(userLmUnchanged)
select('userLandmarks'),
distinctUntilChanged()
)
this.onHoverSegments$ = this.store.pipe(
......@@ -454,10 +448,7 @@ export class NehubaContainer implements OnInit, OnDestroy{
)
this.subscriptions.push(
this.userLandmarks$.pipe(
// distinctUntilChanged((old,new) => )
).subscribe(landmarks => {
this.userLandmarks = landmarks
this.userLandmarks$.subscribe(landmarks => {
if(this.nehubaViewer){
this.nehubaViewer.updateUserLandmarks(landmarks)
}
......@@ -968,14 +959,16 @@ export class NehubaContainer implements OnInit, OnDestroy{
if(!landmarks.every(l => l.position.constructor === Array) || !landmarks.every(l => l.position.every(v => !isNaN(v))) || !landmarks.every(l => l.position.length == 3))
throw new Error('position needs to be a length 3 tuple of numbers ')
this.store.dispatch({
type: USER_LANDMARKS,
type: VIEWERSTATE_ACTION_TYPES.ADD_USERLANDMARKS,
landmarks : landmarks
})
},
remove3DLandmarks : ids => {
remove3DLandmarks : landmarkIds => {
this.store.dispatch({
type : USER_LANDMARKS,
landmarks : this.userLandmarks.filter(l => ids.findIndex(id => id === l.id) < 0)
type: VIEWERSTATE_ACTION_TYPES.REMOVE_USER_LANDMARKS,
payload: {
landmarkIds
}
})
},
hideSegment : (labelIndex) => {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment