Skip to content

Commit

Permalink
Merge pull request #1310 from FZJ-INM1-BDA/staging
Browse files Browse the repository at this point in the history
v2.10.2
  • Loading branch information
xgui3783 authored May 2, 2023
2 parents dd1c5ed + fba47e5 commit 8ae9264
Show file tree
Hide file tree
Showing 20 changed files with 492 additions and 166 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<img align="right" src="https://raw.githubusercontent.com/FZJ-INM1-BDA/siibra-explorer/master/docs/images/siibra-explorer-square.jpeg" width="200">

[![DOI](https://zenodo.org/badge/109723444.svg)](https://zenodo.org/badge/latestdoi/109723444)
[![Documentation Status](https://readthedocs.org/projects/siibra-explorer/badge/?version=latest)](https://siibra-explorer.readthedocs.io/)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

Expand Down
11 changes: 11 additions & 0 deletions docs/releases/v2.10.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# v2.10.2

## Bugfix

- paginate feature requests to hopefully improve server performance
- bump siibra-api version
- fix ng layer control style pollution

## Behind the scenes

- added zenodo badge
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ nav:
- Fetching datasets: 'advanced/datasets.md'
- Display non-atlas volumes: 'advanced/otherVolumes.md'
- Release notes:
- v2.10.2: 'releases/v2.10.2.md'
- v2.10.1: 'releases/v2.10.1.md'
- v2.10.0: 'releases/v2.10.0.md'
- v2.9.1: 'releases/v2.9.1.md'
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "siibra-explorer",
"version": "2.10.1",
"version": "2.10.2",
"description": "siibra-explorer - explore brain atlases. Based on humanbrainproject/nehuba & google/neuroglancer. Built with angular",
"scripts": {
"lint": "eslint src --ext .ts",
Expand Down
2 changes: 1 addition & 1 deletion src/atlasComponents/sapi/sapi.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const useViewer = {
} as const

export const SIIBRA_API_VERSION_HEADER_KEY='x-siibra-api-version'
export const EXPECTED_SIIBRA_API_VERSION = '0.3.1'
export const EXPECTED_SIIBRA_API_VERSION = '0.3.2'

let BS_ENDPOINT_CACHED_VALUE: Observable<string> = null

Expand Down
2 changes: 1 addition & 1 deletion src/atlasComponents/sapi/translateV3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ class TranslateV3 {
}
}

async translateFeature(feat: PathReturn<"/feature/{feature_id}">): Promise<TabularFeature<number|string|number[]>|Feature> {
async translateFeature(feat: PathReturn<"/feature/{feature_id}">): Promise<TabularFeature<number|string|number[]>|VoiFeature|Feature> {
if (this.#isTabular(feat)) {
return await this.translateTabularFeature(feat)
}
Expand Down
154 changes: 108 additions & 46 deletions src/features/category-acc.directive.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { AfterContentInit, ContentChildren, Directive, OnDestroy, QueryList } from '@angular/core';
import { BehaviorSubject, combineLatest, Subscription } from 'rxjs';
import { map } from 'rxjs/operators';
import { Feature } from "src/atlasComponents/sapi/sxplrTypes"
import { ListDirective } from './list/list.directive';
import { AfterContentInit, ContentChildren, Directive, Input, OnDestroy, QueryList } from '@angular/core';
import { combineLatest, merge, of, Subject, Subscription } from 'rxjs';
import { distinctUntilChanged, map, scan, shareReplay, switchMap } from 'rxjs/operators';
import { ListDirective, TranslatedFeature } from './list/list.directive';
import { ParentDatasource, PulledDataSource } from 'src/util/pullable';
import { arrayEqual } from 'src/util/array';

export type GroupedFeature = {
features: Feature[]
export type FeatureMetadata = {
meta: {
displayName: string
total: number
}
}

Expand All @@ -16,57 +17,118 @@ export type GroupedFeature = {
exportAs: 'categoryAcc'
})
export class CategoryAccDirective implements AfterContentInit, OnDestroy {

#listCmps$ = new Subject<ListDirective[]>()

public isBusy$ = this.#listCmps$.pipe(
switchMap(cmps =>
combineLatest(
cmps.map(
cmp => cmp.isBusy$
)
).pipe(
map(isBusyState => isBusyState.some(state => state))
)
)
)
public total$ = this.#listCmps$.pipe(
switchMap(listCmps =>
combineLatest(
listCmps.map(cmp => cmp.total$)
).pipe(
map(totals => totals.reduce((acc, curr) => acc + curr)),
)
),
shareReplay(1)
)

public isBusy$ = new BehaviorSubject<boolean>(false)
public total$ = new BehaviorSubject<number>(0)
public groupedFeatures$ = new BehaviorSubject<GroupedFeature[]>([])
public features$ = this.groupedFeatures$.pipe(
map(arr => arr.flatMap(val => val.features))
public featureMetadata$ = this.#listCmps$.pipe(
switchMap(listcmps => {
if (listcmps.length === 0) {
return of([] as FeatureMetadata[])
}
return merge(
...listcmps.map(cmp =>
cmp.total$.pipe(
map(total => ({
[cmp.displayName]: total
}))
)
)
).pipe(
scan((acc, curr) => {
return {
...acc,
...curr
}
}, {} as Record<string, number>),
map(record => {
const returnVal: FeatureMetadata[] = []
for (const key in record) {
returnVal.push({
meta: {
displayName: key,
total: record[key]
}
})
}
return returnVal
})
)
})
)

@ContentChildren(ListDirective, { read: ListDirective, descendants: true })
listCmps: QueryList<ListDirective>

#changeSub: Subscription
ngAfterContentInit(): void {
this.#registerListCmps()
this.#changeSub = this.listCmps.changes.subscribe(() => this.#registerListCmps())
}

ngOnDestroy(): void {
this.#cleanup()
}
#unchecked$ = new Subject<FeatureMetadata[]>()
unchecked$ = this.#unchecked$.pipe(
distinctUntilChanged(
arrayEqual((o, n) => o.meta.displayName === n.meta.displayName && o.meta.total === n.meta.total)
)
)

#subscriptions: Subscription[] = []
#cleanup(){
if (this.#changeSub) this.#changeSub.unsubscribe()
while(this.#subscriptions.length > 0) this.#subscriptions.pop().unsubscribe()
@Input()
set unchecked(val: FeatureMetadata[]){
this.#unchecked$.next(val)
}
#registerListCmps(){
this.#cleanup()

const listCmp = Array.from(this.listCmps)

this.#subscriptions.push(
combineLatest(
listCmp.map(
listC => listC.features$.pipe(
map(features => ({ features, meta: { displayName: listC.displayName } }))
)
)
).subscribe(val => this.groupedFeatures$.next(val)),
public datasource$ = combineLatest([
this.unchecked$,
this.#listCmps$,
]).pipe(
switchMap(([ unchecked, listCmps ]) => {
const hideFeatureNames = unchecked.map(c => c.meta.displayName)
const filteredListCmps = listCmps.filter(cmp => !hideFeatureNames.includes(cmp.displayName))

combineLatest(
listCmp.map(listC => listC.features$)
if (filteredListCmps.length === 0) {
return of(
new ParentDatasource({
children: [] as PulledDataSource<TranslatedFeature>[]
})
)
}
return combineLatest(
filteredListCmps.map(cmp => cmp.datasource$)
).pipe(
map(features => features.reduce((acc, curr) => acc + curr.length, 0))
).subscribe(total => this.total$.next(total)),
map(dss => new ParentDatasource({ children: dss })),
)
})
)

combineLatest(
listCmp.map(listC => listC.state$)
).pipe(
map(states => states.some(state => state === "busy"))
).subscribe(flag => this.isBusy$.next(flag))
#changeSub: Subscription
ngAfterContentInit(): void {
this.#changeSub = this.listCmps.changes.subscribe(() => {
this.#listCmps$.next(
Array.from(this.listCmps)
)
})
this.#listCmps$.next(
Array.from(this.listCmps)
)
}

ngOnDestroy(): void {
if (this.#changeSub) this.#changeSub.unsubscribe()
}
}
23 changes: 14 additions & 9 deletions src/features/entry/entry.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as userInteraction from "src/state/userInteraction"
import { atlasSelection } from 'src/state';
import { CategoryAccDirective } from "../category-acc.directive"
import { BehaviorSubject, combineLatest, merge, of, Subscription } from 'rxjs';
import { IsAlreadyPulling, PulledDataSource } from 'src/util/pullable';

const categoryAcc = <T extends Record<string, unknown>>(categories: T[]) => {
const returnVal: Record<string, T[]> = {}
Expand Down Expand Up @@ -36,7 +37,6 @@ export class EntryComponent extends FeatureBase implements AfterViewInit, OnDest

public busyTallying$ = new BehaviorSubject<boolean>(false)
public totals$ = new BehaviorSubject<number>(null)
public features$ = new BehaviorSubject<Feature[]>([])

constructor(private sapi: SAPI, private store: Store) {
super()
Expand Down Expand Up @@ -77,13 +77,6 @@ export class EntryComponent extends FeatureBase implements AfterViewInit, OnDest
this.totals$.next(num)
}),
).subscribe(),

catAccDirs$.pipe(
switchMap(catArrDirs => combineLatest(
catArrDirs.map(dir => dir.features$)
)),
map(features => features.flatMap(f => f))
).subscribe(features => this.features$.next(features))
)
}

Expand Down Expand Up @@ -140,5 +133,17 @@ export class EntryComponent extends FeatureBase implements AfterViewInit, OnDest
})
)
}
}

async onScroll(datasource: PulledDataSource<unknown>, scrollIndex: number){
if ((datasource.currentValue.length - scrollIndex) < 30) {
try {
await datasource.pull()
} catch (e) {
if (e instanceof IsAlreadyPulling) {
return
}
throw e
}
}
}
}
Loading

0 comments on commit 8ae9264

Please sign in to comment.