diff --git a/client/package.json b/client/package.json index 7e7cad96734364427fdcc7fe3022f1e64f022190..587d474ebd838b8a7878554cdc2c2c9b05da7944 100644 --- a/client/package.json +++ b/client/package.json @@ -26,6 +26,7 @@ "@ngrx/store": "12.1.0", "@ngrx/store-devtools": "12.1.0", "bootstrap": "4.6", + "d3": "^5.15.1", "keycloak-angular": "^8.2.0", "keycloak-js": "^14.0.0", "ngx-bootstrap": "^7.0.0-rc.1", @@ -39,6 +40,7 @@ "@angular-devkit/build-angular": "~12.0.4", "@angular/cli": "~12.0.4", "@angular/compiler-cli": "~12.0.4", + "@types/d3": "^5.7.2", "@types/jasmine": "~3.6.0", "@types/node": "^12.11.1", "jasmine-core": "~3.7.0", diff --git a/client/src/app/instance/detail/components/default-object.component.html b/client/src/app/instance/detail/components/default/default-object.component.html similarity index 73% rename from client/src/app/instance/detail/components/default-object.component.html rename to client/src/app/instance/detail/components/default/default-object.component.html index de8546af4ec8d9dfa2bf3983755ae597798da1d2..bc6843ae7d94023d1cd8b39b9c9c57631d17822f 100644 --- a/client/src/app/instance/detail/components/default-object.component.html +++ b/client/src/app/instance/detail/components/default/default-object.component.html @@ -1,9 +1,9 @@ <div class="row justify-content-center"> <div class="col col-lg-10 col-xl-8 mt-4"> <app-object-data - [datasetName]="datasetName" + [datasetSelected]="datasetSelected" [outputFamilyList]="outputFamilyList" - [categoryList]="categoryList" + [outputCategoryList]="outputCategoryList" [attributeList]="attributeList" [object]="object"> </app-object-data> diff --git a/client/src/app/instance/detail/components/default-object.component.ts b/client/src/app/instance/detail/components/default/default-object.component.ts similarity index 89% rename from client/src/app/instance/detail/components/default-object.component.ts rename to client/src/app/instance/detail/components/default/default-object.component.ts index aed6a1481ef7dd4db11a611adb19f6c1b4c5624d..058a6eda84682117c638f3b96313f04f6ae192bb 100644 --- a/client/src/app/instance/detail/components/default-object.component.ts +++ b/client/src/app/instance/detail/components/default/default-object.component.ts @@ -21,9 +21,9 @@ import { Attribute, OutputFamily, OutputCategory } from 'src/app/metamodel/model * @classdesc Detail default object component. */ export class DefaultObjectComponent { - @Input() datasetName: string; + @Input() datasetSelected: string; @Input() outputFamilyList: OutputFamily[]; - @Input() categoryList: OutputCategory[]; + @Input() outputCategoryList: OutputCategory[]; @Input() attributeList: Attribute[]; @Input() object: any; } diff --git a/client/src/app/instance/detail/components/default/index.ts b/client/src/app/instance/detail/components/default/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..f36eed1181aaad1346a0f96e9b5375b1f68979b2 --- /dev/null +++ b/client/src/app/instance/detail/components/default/index.ts @@ -0,0 +1,5 @@ +import { DefaultObjectComponent } from './default-object.component'; + +export const defaultComponents = [ + DefaultObjectComponent +]; diff --git a/client/src/app/instance/detail/components/index.ts b/client/src/app/instance/detail/components/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..e0d32c36208a417c4ec089814d619e25f5a69c6b --- /dev/null +++ b/client/src/app/instance/detail/components/index.ts @@ -0,0 +1,9 @@ +import { defaultComponents } from './default'; +import { spectraComponents } from './spectra'; +import { ObjectDataComponent } from './object-data.component'; + +export const dummiesComponents = [ + defaultComponents, + spectraComponents, + ObjectDataComponent +]; diff --git a/client/src/app/instance/detail/components/object-data.component.ts b/client/src/app/instance/detail/components/object-data.component.ts index 6d33ca2f41c1d264d37e577885118dab18a855fc..d834874bede64081c6f7b45b6c5f4f0e5b9a1ad9 100644 --- a/client/src/app/instance/detail/components/object-data.component.ts +++ b/client/src/app/instance/detail/components/object-data.component.ts @@ -22,9 +22,9 @@ import { getHost } from 'src/app/shared/utils'; * @classdesc Detail object data component. */ export class ObjectDataComponent { - @Input() datasetName: string; + @Input() datasetSelected: string; @Input() outputFamilyList: OutputFamily[]; - @Input() categoryList: OutputCategory[]; + @Input() outputCategoryList: OutputCategory[]; @Input() attributeList: Attribute[]; @Input() object: any; @@ -36,7 +36,7 @@ export class ObjectDataComponent { * @return Category[] */ getCategoryByFamilySortedByDisplay(idFamily: number): OutputCategory[] { - return this.categoryList + return this.outputCategoryList .filter(category => category.id_output_family === idFamily) //.sort(sortByDisplay); } @@ -78,6 +78,6 @@ export class ObjectDataComponent { } getDownloadHref(value: string) { - return getHost() + '/download-file/' + this.datasetName + '/' + value; + return getHost() + '/download-file/' + this.datasetSelected + '/' + value; } } diff --git a/client/src/app/instance/detail/components/spectra/index.ts b/client/src/app/instance/detail/components/spectra/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..77b5e03935e6f4321da07852a1d56a460bc70c3a --- /dev/null +++ b/client/src/app/instance/detail/components/spectra/index.ts @@ -0,0 +1,7 @@ +import { SpectraObjectComponent } from "./spectra-object.component"; +import { SpectraGraphComponent } from "./graph/spectra-graph.component"; + +export const spectraComponents = [ + SpectraObjectComponent, + SpectraGraphComponent +]; diff --git a/client/src/app/instance/detail/components/spectra/spectra-object.component.html b/client/src/app/instance/detail/components/spectra/spectra-object.component.html index 734a18f1829d28bd19b50c0f38b22e7e6b52ca94..a5c472ccf3df9c49290d85d91f3e7890bf6df7ea 100644 --- a/client/src/app/instance/detail/components/spectra/spectra-object.component.html +++ b/client/src/app/instance/detail/components/spectra/spectra-object.component.html @@ -17,7 +17,8 @@ <div class="row justify-content-center"> <div class="col-auto"> <a [href]="getSpectra()" target="_blank" class="btn btn-lg btn-block dl-btn"> - <span [inlineSVG]="'assets/logo_spectra.svg'" title="Download SPECTRA archive"></span> + <!-- <span [inlineSVG]="'assets/logo_spectra.svg'" title="Download SPECTRA archive"></span> --> + Download SPECTRA archive </a> </div> </div> @@ -25,9 +26,9 @@ </div> <app-object-data - [datasetName]="datasetName" + [datasetSelected]="datasetSelected" [outputFamilyList]="outputFamilyList" - [categoryList]="categoryList" + [outputCategoryList]="outputCategoryList" [attributeList]="attributeList" [object]="object"> </app-object-data> diff --git a/client/src/app/instance/detail/components/spectra/spectra-object.component.ts b/client/src/app/instance/detail/components/spectra/spectra-object.component.ts index b0cfc9ba7007192308189c9362a8e21437b85b14..df397e7ea50f131d916162665963e277f9401229 100644 --- a/client/src/app/instance/detail/components/spectra/spectra-object.component.ts +++ b/client/src/app/instance/detail/components/spectra/spectra-object.component.ts @@ -25,9 +25,9 @@ import { getHost } from 'src/app/shared/utils'; * @implements OnInit */ export class SpectraObjectComponent implements OnInit { - @Input() datasetName: string; + @Input() datasetSelected: string; @Input() outputFamilyList: OutputFamily[]; - @Input() categoryList: OutputCategory[]; + @Input() outputCategoryList: OutputCategory[]; @Input() attributeList: Attribute[]; @Input() object: any; @Input() spectraIsLoading: boolean; @@ -51,7 +51,7 @@ export class SpectraObjectComponent implements OnInit { const spectraAttribute: Attribute = this.attributeList .filter(a => a.detail) .find(attribute => attribute.search_flag === 'SPECTRUM_1D'); - return getHost() + '/download-file/' + this.datasetName + '/' + this.object[spectraAttribute.label]; + return getHost() + '/download-file/' + this.datasetSelected + '/' + this.object[spectraAttribute.label]; } /** diff --git a/client/src/app/instance/detail/containers/detail.component.html b/client/src/app/instance/detail/containers/detail.component.html index 3b15ddb5652d3e326713933ced4e04c805ee3932..2899b8cf78fc9f670a81366d3efd8b049e074bc6 100644 --- a/client/src/app/instance/detail/containers/detail.component.html +++ b/client/src/app/instance/detail/containers/detail.component.html @@ -6,26 +6,27 @@ </button> </div> </div> - <div *ngIf="objectIsLoading | async" id="div-spinner" class="row justify-content-center mt-5"> - <span class="fas fa-circle-notch fa-spin fa-3x"></span> - <span class="sr-only">Loading...</span> - </div> - <div *ngIf="objectIsLoaded | async" [ngSwitch]="getObjectType(attributeList | async)"> + <app-spinner *ngIf="(attributeListIsLoading | async) + || (outputFamilyListIsLoading | async) + || (outputCategoryListIsLoading | async) + || (objectIsLoading | async)"> + </app-spinner> + <div *ngIf="(attributeListIsLoaded | async) && (outputFamilyListIsLoaded | async) && (outputCategoryListIsLoaded | async) && (objectIsLoaded | async)" [ngSwitch]="getObjectType(attributeList | async)"> <app-spectra-object *ngSwitchCase="'spectra'" - [datasetName]="datasetName | async" + [datasetSelected]="datasetSelected | async" [outputFamilyList]="outputFamilyList | async" - [categoryList]="categoryList | async" + [outputCategoryList]="outputCategoryList | async" [attributeList]="attributeList | async" [object]="object | async" + [spectraCSV]="spectraCSV | async" [spectraIsLoading]="spectraIsLoading | async" [spectraIsLoaded]="spectraIsLoaded | async" - [spectraCSV]="spectraCSV | async" (getSpectraCSV)="getSpectraCSV($event)"> </app-spectra-object> <app-default-object *ngSwitchDefault - [datasetName]="datasetName | async" + [datasetSelected]="datasetSelected | async" [outputFamilyList]="outputFamilyList | async" - [categoryList]="categoryList | async" + [outputCategoryList]="outputCategoryList | async" [attributeList]="attributeList | async" [object]="object | async"> </app-default-object> diff --git a/client/src/app/instance/detail/containers/detail.component.ts b/client/src/app/instance/detail/containers/detail.component.ts index b196802440b04495eda709ec3cd93761b1a4cac9..331290c257df23a6736d98e8f7f702e3ab2da687 100644 --- a/client/src/app/instance/detail/containers/detail.component.ts +++ b/client/src/app/instance/detail/containers/detail.component.ts @@ -11,13 +11,20 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { Location } from '@angular/common'; import { Store } from '@ngrx/store'; -import { Observable } from 'rxjs'; +import { Observable, Subscription } from 'rxjs'; -import * as fromDetail from '../store/detail.reducer'; -import * as detailActions from '../store/detail.action'; -import * as detailSelector from '../store/detail.selector'; -import * as metamodelSelector from '../../metamodel/selectors'; -import { Attribute, Category, Family } from '../../metamodel/model'; +import { Attribute, OutputCategory, OutputFamily } from 'src/app/metamodel/models'; +import * as fromDetail from 'src/app/instance/store/reducers/detail.reducer'; +import * as detailActions from 'src/app/instance/store/actions/detail.actions'; +import * as detailSelector from 'src/app/instance/store/selectors/detail.selector'; +import * as datasetSelector from 'src/app/metamodel/selectors/dataset.selector'; +import * as searchSelector from 'src/app/instance/store/selectors/search.selector'; +import * as outputFamilyActions from 'src/app/metamodel/actions/output-family.actions'; +import * as outputFamilySelector from 'src/app/metamodel/selectors/output-family.selector'; +import * as outputCategoryActions from 'src/app/metamodel/actions/output-category.actions'; +import * as outputCategorySelector from 'src/app/metamodel/selectors/output-category.selector'; +import * as attributeActions from 'src/app/metamodel/actions/attribute.actions'; +import * as attributeSelector from 'src/app/metamodel/selectors/attribute.selector'; /** * Interface for store state. @@ -40,38 +47,55 @@ interface StoreState { * @implements OnDestroy */ export class DetailComponent implements OnInit, OnDestroy { + public datasetSelected: Observable<string>; public pristine: Observable<boolean>; - public datasetName: Observable<string>; public attributeList: Observable<Attribute[]>; - public outputFamilyList: Observable<Family[]>; - public categoryList: Observable<Category[]>; + public attributeListIsLoading: Observable<boolean>; + public attributeListIsLoaded: Observable<boolean>; + public outputFamilyList: Observable<OutputFamily[]>; + public outputFamilyListIsLoading: Observable<boolean>; + public outputFamilyListIsLoaded: Observable<boolean>; + public outputCategoryList: Observable<OutputCategory[]>; + public outputCategoryListIsLoading: Observable<boolean>; + public outputCategoryListIsLoaded: Observable<boolean>; + public object: Observable<any>; public objectIsLoading: Observable<boolean>; public objectIsLoaded: Observable<boolean>; - public object: Observable<any>; + public spectraCSV: Observable<string>; public spectraIsLoading: Observable<boolean>; public spectraIsLoaded: Observable<boolean>; - public spectraCSV: Observable<string>; + + private attributeListIsLoadedSubscription: Subscription; constructor(private location: Location, private store: Store<StoreState>) { - this.pristine = this.store.select(detailSelector.getSearchIsPristine); - this.datasetName = this.store.select(detailSelector.getDatasetName); - this.outputFamilyList = this.store.select(metamodelSelector.getOutputFamilyList); - this.categoryList = this.store.select(metamodelSelector.getCategoryList); - this.objectIsLoading = this.store.select(detailSelector.getObjectIsLoading); - this.objectIsLoaded = this.store.select(detailSelector.getObjectIsLoaded); - this.object = this.store.select(detailSelector.getObject); - this.spectraIsLoading = this.store.select(detailSelector.getSpectraIsLoading); - this.spectraIsLoaded = this.store.select(detailSelector.getSpectraIsLoaded); - this.spectraCSV = this.store.select(detailSelector.getSpectraCSV); + this.datasetSelected = store.select(datasetSelector.selectDatasetNameByRoute); + this.pristine = store.select(searchSelector.selectPristine); + this.attributeList = store.select(attributeSelector.selectAllAttributes); + this.attributeListIsLoading = store.select(attributeSelector.selectAttributeListIsLoading); + this.attributeListIsLoaded = store.select(attributeSelector.selectAttributeListIsLoaded); + this.outputFamilyList = store.select(outputFamilySelector.selectAllOutputFamilies); + this.outputFamilyListIsLoading = store.select(outputFamilySelector.selectOutputFamilyListIsLoading); + this.outputFamilyListIsLoaded = store.select(outputFamilySelector.selectOutputFamilyListIsLoaded); + this.outputCategoryList = store.select(outputCategorySelector.selectAllOutputCategories); + this.outputCategoryListIsLoading = store.select(outputCategorySelector.selectOutputCategoryListIsLoading); + this.outputCategoryListIsLoaded = store.select(outputCategorySelector.selectOutputCategoryListIsLoaded); + this.object = this.store.select(detailSelector.selectObject); + this.objectIsLoading = this.store.select(detailSelector.selectObjectIsLoading); + this.objectIsLoaded = this.store.select(detailSelector.selectObjectIsLoaded); + this.spectraCSV = this.store.select(detailSelector.selectSpectraCSV); + this.spectraIsLoading = this.store.select(detailSelector.selectObjectIsLoading); + this.spectraIsLoaded = this.store.select(detailSelector.selectSpectraIsLoaded); } ngOnInit() { // Create a micro task that is processed after the current synchronous code // This micro task prevent the expression has changed after view init error - Promise.resolve(null).then(() => this.store.dispatch(new detailActions.InitDetailAction())); - this.datasetName.subscribe(datasetName => { - if (datasetName) { - this.attributeList = this.store.select(metamodelSelector.getAttributeList, { dname: datasetName }); + Promise.resolve(null).then(() => this.store.dispatch(attributeActions.loadAttributeList())); + Promise.resolve(null).then(() => this.store.dispatch(outputFamilyActions.loadOutputFamilyList())); + Promise.resolve(null).then(() => this.store.dispatch(outputCategoryActions.loadOutputCategoryList())); + this.attributeListIsLoadedSubscription = this.attributeListIsLoaded.subscribe(attributeListIsLoaded => { + if (attributeListIsLoaded) { + Promise.resolve(null).then(() => this.store.dispatch(detailActions.retrieveObject())); } }); } @@ -84,7 +108,7 @@ export class DetailComponent implements OnInit, OnDestroy { * @return string */ getObjectType(attributeList: Attribute[]): string { - const spectrumAttribute: Attribute = attributeList + const spectrumAttribute: Attribute = attributeList .filter(a => a.detail) .find(attribute => attribute.search_flag === 'SPECTRUM_1D'); if (spectrumAttribute) { @@ -106,13 +130,14 @@ export class DetailComponent implements OnInit, OnDestroy { * @param {string} spectraFile - The spectra file name. */ getSpectraCSV(spectraFile: string): void { - this.store.dispatch(new detailActions.RetrieveSpectraAction(spectraFile)); + this.store.dispatch(detailActions.retrieveSpectra({ filename: spectraFile })); } /** * Resets detail information. */ ngOnDestroy() { - this.store.dispatch(new detailActions.DestroyDetailAction()); + this.attributeListIsLoadedSubscription.unsubscribe(); + // this.store.dispatch(new detailActions.DestroyDetailAction()); } } diff --git a/client/src/app/instance/detail/detail-routing.module.ts b/client/src/app/instance/detail/detail-routing.module.ts index ee1308922ba3f0b402a1a1bee41c26a5c08dce7e..8f88b99bb56b2ad21b228b818173bdb623ed7f6d 100644 --- a/client/src/app/instance/detail/detail-routing.module.ts +++ b/client/src/app/instance/detail/detail-routing.module.ts @@ -10,10 +10,11 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -//import { DetailComponent } from './detail.component'; +import { DetailComponent } from './containers/detail.component'; const routes: Routes = [ - //{ path: '', component: DetailComponent } + { path: '', redirectTo: ':/dname/:id', pathMatch: 'full' }, + { path: ':dname/:id', component: DetailComponent } ]; @NgModule({ @@ -23,5 +24,5 @@ const routes: Routes = [ export class DetailRoutingModule { } export const routedComponents = [ - //DetailComponent + DetailComponent ]; diff --git a/client/src/app/instance/detail/detail.module.ts b/client/src/app/instance/detail/detail.module.ts index 7e1605ceeda56e6d572a37d69b6fb11fb8e8bc7d..fbaaabfa3e090c12c51338d99b4ec7ebd6f32bdc 100644 --- a/client/src/app/instance/detail/detail.module.ts +++ b/client/src/app/instance/detail/detail.module.ts @@ -11,12 +11,16 @@ import { NgModule } from '@angular/core'; import { SharedModule } from 'src/app/shared/shared.module'; import { DetailRoutingModule, routedComponents } from './detail-routing.module'; +import { dummiesComponents } from './components'; @NgModule({ imports: [ SharedModule, DetailRoutingModule ], - declarations: [routedComponents] + declarations: [ + routedComponents, + dummiesComponents + ] }) export class DetailModule { } diff --git a/client/src/app/instance/instance-routing.module.ts b/client/src/app/instance/instance-routing.module.ts index 37baa1075d4b111e51c541b0cad73beb09937cb2..f893d0721faffd7374ec7316e0030e4e5fbbb12c 100644 --- a/client/src/app/instance/instance-routing.module.ts +++ b/client/src/app/instance/instance-routing.module.ts @@ -18,7 +18,8 @@ const routes: Routes = [ { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) }, { path: 'documentation', loadChildren: () => import('./documentation/documentation.module').then(m => m.DocumentationModule) }, - { path: 'search', loadChildren: () => import('./search/search.module').then(m => m.SearchModule) } + { path: 'search', loadChildren: () => import('./search/search.module').then(m => m.SearchModule) }, + { path: 'detail', loadChildren: () => import('./detail/detail.module').then(m => m.DetailModule) } ] } ]; diff --git a/client/src/app/instance/instance.reducer.ts b/client/src/app/instance/instance.reducer.ts index f4454161d4f8074368ddc3d583a050798ea7abf4..f660ab9ab6c3dd59f99ddf24e047eac5cd2b82a7 100644 --- a/client/src/app/instance/instance.reducer.ts +++ b/client/src/app/instance/instance.reducer.ts @@ -14,19 +14,22 @@ import * as metamodel from './store/reducers/metamodel.reducer'; import * as search from './store/reducers/search.reducer'; import * as samp from './store/reducers/samp.reducer'; import * as coneSearch from './store/reducers/cone-search.reducer'; +import * as detail from './store/reducers/detail.reducer'; export interface State { metamodel: metamodel.State, search: search.State, samp: samp.State, coneSearch: coneSearch.State + detail: detail.State } const reducers = { metamodel: metamodel.metamodelReducer, search: search.searchReducer, samp: samp.sampReducer, - coneSearch: coneSearch.coneSearchReducer + coneSearch: coneSearch.coneSearchReducer, + detail: detail.detailReducer }; export const instanceReducer = combineReducers(reducers); diff --git a/client/src/app/instance/search/components/result/datatable-tab.component.html b/client/src/app/instance/search/components/result/datatable-tab.component.html index 66316d7af426d1a63ecfb6c0e2078d6b9d6d5605..26dd36d1be6a174d083b150ebb580194511e8e9c 100644 --- a/client/src/app/instance/search/components/result/datatable-tab.component.html +++ b/client/src/app/instance/search/components/result/datatable-tab.component.html @@ -10,6 +10,7 @@ </button> <app-datatable [dataset]="datasetList | datasetByName:datasetSelected" + [instanceSelected]="instanceSelected" [attributeList]="attributeList" [outputList]="outputList" [dataLength]="dataLength" diff --git a/client/src/app/instance/search/components/result/datatable-tab.component.ts b/client/src/app/instance/search/components/result/datatable-tab.component.ts index c2d7dd1dd0ce224bd65ad333c910a84809bc0c1d..c24e1979d36d8710d5efe016bd9ba69a5e4c35d2 100644 --- a/client/src/app/instance/search/components/result/datatable-tab.component.ts +++ b/client/src/app/instance/search/components/result/datatable-tab.component.ts @@ -23,6 +23,7 @@ import { Pagination } from 'src/app/instance/store/models'; */ export class DatatableTabComponent { @Input() datasetSelected: string; + @Input() instanceSelected: string; @Input() datasetList: Dataset[]; @Input() attributeList: Attribute[]; @Input() outputList: number[]; diff --git a/client/src/app/instance/search/containers/result.component.html b/client/src/app/instance/search/containers/result.component.html index ab045ae224c68d9ae47765843967539f45be1aa7..9e4fec28e05e52c08e8baab91789b911b6bbf5f6 100644 --- a/client/src/app/instance/search/containers/result.component.html +++ b/client/src/app/instance/search/containers/result.component.html @@ -64,6 +64,7 @@ </app-cone-search-plot-tab> --> <app-datatable-tab [datasetSelected]="datasetSelected | async" + [instanceSelected]="instanceSelected | async" [datasetList]="datasetList | async" [attributeList]="attributeList | async" [outputList]="outputList | async" diff --git a/client/src/app/instance/shared-search/components/datatable/datatable.component.html b/client/src/app/instance/shared-search/components/datatable/datatable.component.html index 8a373adc94235177078fdbe92c629b1bb642024b..881f79065975906242993d75e2239f945bd4ff4c 100644 --- a/client/src/app/instance/shared-search/components/datatable/datatable.component.html +++ b/client/src/app/instance/shared-search/components/datatable/datatable.component.html @@ -45,6 +45,7 @@ <app-detail-renderer [value]="datum[attribute.label]" [datasetName]="dataset.name" + [instanceSelected]="instanceSelected" [config]="getRendererConfig(attribute)"> </app-detail-renderer> </div> diff --git a/client/src/app/instance/shared-search/components/datatable/datatable.component.ts b/client/src/app/instance/shared-search/components/datatable/datatable.component.ts index 56d115ee220a55a674fc8b3a6343871b3c6c8178..698cf0403bf1ea003acb77f3b9da144bb38132db 100644 --- a/client/src/app/instance/shared-search/components/datatable/datatable.component.ts +++ b/client/src/app/instance/shared-search/components/datatable/datatable.component.ts @@ -26,6 +26,7 @@ import { Pagination, PaginationOrder } from 'src/app/instance/store/models'; */ export class DatatableComponent implements OnInit { @Input() dataset: Dataset; + @Input() instanceSelected: string; @Input() attributeList: Attribute[]; @Input() outputList: number[]; @Input() dataLength: number; diff --git a/client/src/app/instance/shared-search/components/datatable/renderer/detail-renderer.component.html b/client/src/app/instance/shared-search/components/datatable/renderer/detail-renderer.component.html index 0b6336b1e1acb9cf348dc857b43bd2fedc62ddc2..37c9f3133e39d52496faf4585956836050038ccc 100644 --- a/client/src/app/instance/shared-search/components/datatable/renderer/detail-renderer.component.html +++ b/client/src/app/instance/shared-search/components/datatable/renderer/detail-renderer.component.html @@ -1,4 +1,4 @@ -<a routerLink="/detail/{{ datasetName }}/{{ value }}" [target]="config.blank == true ? '_blank' : '_self'" +<a routerLink="/instance/{{ instanceSelected }}/detail/{{ datasetName }}/{{ value }}" [target]="config.blank == true ? '_blank' : '_self'" [ngClass]="{'btn btn-outline-primary btn-sm' : config.display == 'text-button'}"> {{ value }} </a> diff --git a/client/src/app/instance/shared-search/components/datatable/renderer/detail-renderer.component.ts b/client/src/app/instance/shared-search/components/datatable/renderer/detail-renderer.component.ts index 06411ef9ec5a95251f5cc49da809f0490eb95839..d6df4dfd8384e2931696c6807a5a0c97bfdeaefb 100644 --- a/client/src/app/instance/shared-search/components/datatable/renderer/detail-renderer.component.ts +++ b/client/src/app/instance/shared-search/components/datatable/renderer/detail-renderer.component.ts @@ -23,5 +23,6 @@ import { DetailRendererConfig } from 'src/app/metamodel/models/renderers/detail- export class DetailRendererComponent { @Input() value: string | number; @Input() datasetName: string; + @Input() instanceSelected: string; @Input() config: DetailRendererConfig; } diff --git a/client/src/app/instance/store/actions/detail.actions.ts b/client/src/app/instance/store/actions/detail.actions.ts new file mode 100644 index 0000000000000000000000000000000000000000..c88210bc8e4e24fb0ee165d34c38c07a90792322 --- /dev/null +++ b/client/src/app/instance/store/actions/detail.actions.ts @@ -0,0 +1,17 @@ +/** + * This file is part of Anis Client. + * + * @copyright Laboratoire d'Astrophysique de Marseille / CNRS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import { createAction, props } from '@ngrx/store'; + +export const retrieveObject = createAction('[Detail] Retrieve Object'); +export const retrieveObjectSuccess = createAction('[Detail] Retrieve Object Success', props<{ object: any }>()); +export const retrieveObjectFail = createAction('[Detail] Retrieve Object Fail'); +export const retrieveSpectra = createAction('[Detail] Retrieve Spectra', props<{ filename: string }>()); +export const retrieveSpectraSuccess = createAction('[Detail] Retrieve Spectra Success', props<{ spectraCSV: string }>()); +export const retrieveSpectraFail = createAction('[Detail] Retrieve Spectra Fail'); diff --git a/client/src/app/instance/store/effects/detail.effects.ts b/client/src/app/instance/store/effects/detail.effects.ts new file mode 100644 index 0000000000000000000000000000000000000000..256412aea966b727115af6394a73795b181e22e7 --- /dev/null +++ b/client/src/app/instance/store/effects/detail.effects.ts @@ -0,0 +1,80 @@ +/** + * This file is part of Anis Client. + * + * @copyright Laboratoire d'Astrophysique de Marseille / CNRS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import { Injectable } from '@angular/core'; + +import { Actions, createEffect, ofType, concatLatestFrom } from '@ngrx/effects'; +import { Store } from '@ngrx/store'; +import { of } from 'rxjs'; +import { map, tap, mergeMap, catchError } from 'rxjs/operators'; +import { ToastrService } from 'ngx-toastr'; + +import { DetailService } from '../services/detail.service'; +import * as detailActions from '../actions/detail.actions'; +import * as detailSelector from '../selectors/detail.selector'; +import * as attributeSelector from 'src/app/metamodel/selectors/attribute.selector'; +import * as datasetSelector from 'src/app/metamodel/selectors/dataset.selector'; + +@Injectable() +export class DetailEffects { + retrieveObject$ = createEffect(() => + this.actions$.pipe( + ofType(detailActions.retrieveObject), + concatLatestFrom(() => [ + this.store.select(datasetSelector.selectDatasetNameByRoute), + this.store.select(attributeSelector.selectAllAttributes), + this.store.select(detailSelector.selectIdByRoute) + ]), + mergeMap(([action, datasetName, attributeList, id]) => this.detailService.retrieveObject( + datasetName, + attributeList.find(attribute => attribute.order_by).id, + id, + attributeList.filter(attribute => attribute.detail).map(attribute => attribute.id) + ).pipe( + map(object => detailActions.retrieveObjectSuccess({ object: object[0] })), + catchError(() => of(detailActions.retrieveObjectFail())) + )) + ) + ); + + retrieveObjectFail$ = createEffect(() => + this.actions$.pipe( + ofType(detailActions.retrieveObjectFail), + tap(() => this.toastr.error('Loading Failed!', 'Unable to load the object')) + ), { dispatch: false} + ); + + retrieveSpectra$ = createEffect(() => + this.actions$.pipe( + ofType(detailActions.retrieveSpectra), + concatLatestFrom(() => this.store.select(datasetSelector.selectDatasetNameByRoute)), + mergeMap(([action, datasetName]) => this.detailService.retrieveSpectra( + datasetName, + action.filename + ).pipe( + map(spectraCSV => detailActions.retrieveSpectraSuccess({ spectraCSV })), + catchError(() => of(detailActions.retrieveSpectraFail())) + )) + ) + ); + + retrieveSpectraFail$ = createEffect(() => + this.actions$.pipe( + ofType(detailActions.retrieveSpectraFail), + tap(() => this.toastr.error('Loading Failed!', 'Unable to load spectra')) + ), { dispatch: false} + ); + + constructor( + private actions$: Actions, + private detailService: DetailService, + private store: Store<{ }>, + private toastr: ToastrService + ) {} +} diff --git a/client/src/app/instance/store/effects/index.ts b/client/src/app/instance/store/effects/index.ts index 3d2ecd77ad3f9e6f15ba5a0e1938aac5679cb49d..29c6402a3c50c5a7138b9d239ae5723e6421e3ec 100644 --- a/client/src/app/instance/store/effects/index.ts +++ b/client/src/app/instance/store/effects/index.ts @@ -2,10 +2,12 @@ import { MetamodelEffects } from './metamodel.effects'; import { SampEffects } from './samp.effects'; import { SearchEffects } from './search.effects'; import { ConeSearchEffects } from './cone-search.effects'; +import { DetailEffects } from './detail.effects'; export const instanceEffects = [ MetamodelEffects, SampEffects, SearchEffects, - ConeSearchEffects + ConeSearchEffects, + DetailEffects ]; diff --git a/client/src/app/instance/store/reducers/detail.reducer.ts b/client/src/app/instance/store/reducers/detail.reducer.ts new file mode 100644 index 0000000000000000000000000000000000000000..466fcfc1838c6e79d790cf87fafb944b96081189 --- /dev/null +++ b/client/src/app/instance/store/reducers/detail.reducer.ts @@ -0,0 +1,71 @@ +/** + * This file is part of Anis Client. + * + * @copyright Laboratoire d'Astrophysique de Marseille / CNRS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import { createReducer, on } from '@ngrx/store'; + +import * as detailActions from '../actions/detail.actions'; + +export interface State { + object: any; + objectIsLoading: boolean; + objectIsLoaded: boolean; + spectraCSV: string; + spectraIsLoading: boolean; + spectraIsLoaded: boolean; +} + +export const initialState: State = { + object: null, + objectIsLoading: false, + objectIsLoaded: false, + spectraCSV: null, + spectraIsLoading: false, + spectraIsLoaded: false, +}; + +export const detailReducer = createReducer( + initialState, + on(detailActions.retrieveObject, state => ({ + ...state, + objectIsLoading: true, + objectIsLoaded: false + })), + on(detailActions.retrieveObjectSuccess, (state, { object }) => ({ + ...state, + objectIsLoading: false, + objectIsLoaded: true, + object + })), + on(detailActions.retrieveObjectFail, state => ({ + ...state, + objectIsLoading: false + })), + on(detailActions.retrieveSpectra, state => ({ + ...state, + spectraIsLoading: true, + spectraIsLoaded: false + })), + on(detailActions.retrieveSpectraSuccess, (state, { spectraCSV }) => ({ + ...state, + spectraIsLoading: false, + spectraIsLoaded: true, + spectraCSV + })), + on(detailActions.retrieveSpectraFail, state => ({ + ...state, + spectraIsLoading: false + })) +); + +export const selectObject = (state: State) => state.object; +export const selectObjectIsLoading = (state: State) => state.objectIsLoading; +export const selectObjectIsLoaded = (state: State) => state.objectIsLoaded; +export const selectSpectraCSV = (state: State) => state.spectraCSV; +export const selectSpectraIsLoading = (state: State) => state.spectraIsLoading; +export const selectSpectraIsLoaded = (state: State) => state.spectraIsLoaded; diff --git a/client/src/app/instance/store/selectors/detail.selector.ts b/client/src/app/instance/store/selectors/detail.selector.ts new file mode 100644 index 0000000000000000000000000000000000000000..2fe62d5722257342c255c5b4680e6883ecad19f5 --- /dev/null +++ b/client/src/app/instance/store/selectors/detail.selector.ts @@ -0,0 +1,53 @@ +/** + * This file is part of Anis Client. + * + * @copyright Laboratoire d'Astrophysique de Marseille / CNRS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import { createSelector } from '@ngrx/store'; + +import * as reducer from '../../instance.reducer'; +import * as fromDetail from '../reducers/detail.reducer'; + +export const selectDetailState = createSelector( + reducer.getInstanceState, + (state: reducer.State) => state.detail +); + +export const selectObject = createSelector( + selectDetailState, + fromDetail.selectObject +); + +export const selectObjectIsLoading = createSelector( + selectDetailState, + fromDetail.selectObjectIsLoading +); + +export const selectObjectIsLoaded = createSelector( + selectDetailState, + fromDetail.selectObjectIsLoaded +); + +export const selectSpectraCSV = createSelector( + selectDetailState, + fromDetail.selectSpectraCSV +); + +export const selectSpectraIsLoading = createSelector( + selectDetailState, + fromDetail.selectSpectraIsLoading +); + +export const selectSpectraIsLoaded = createSelector( + selectDetailState, + fromDetail.selectSpectraIsLoaded +); + +export const selectIdByRoute = createSelector( + reducer.selectRouterState, + router => router.state.params.id +); diff --git a/client/src/app/instance/store/selectors/search.selector.ts b/client/src/app/instance/store/selectors/search.selector.ts index 094c36733e1f0aed698df8503b56aaf91977b642..44ebe388b9cde19e8bbfe3eff35a5bb9e7b68ecd 100644 --- a/client/src/app/instance/store/selectors/search.selector.ts +++ b/client/src/app/instance/store/selectors/search.selector.ts @@ -14,88 +14,88 @@ import * as reducer from '../../instance.reducer'; import * as fromSearch from '../reducers/search.reducer'; import * as coneSearchSelector from './cone-search.selector'; -export const selectInstanceState = createSelector( +export const selectSearchState = createSelector( reducer.getInstanceState, (state: reducer.State) => state.search ); export const selectPristine = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectPristine ); export const selectCurrentDataset = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectCurrentDataset ); export const selectCurrentStep = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectCurrentStep ); export const selectCriteriaStepChecked = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectCriteriaStepChecked ); export const selectOutputStepChecked = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectOutputStepChecked ); export const selectResultStepChecked = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectResultStepChecked ); export const selectIsConeSearchAdded = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectIsConeSearchAdded ); export const selectCriteriaList = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectCriteriaList ); export const selectOutputList = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectOutputList ); export const selectDataLengthIsLoading = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectDataLengthIsLoading ); export const selectDataLengthIsLoaded = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectDataLengthIsLoaded ); export const selectDataLength = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectDataLength ); export const selectDataIsLoading = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectDataIsLoading ); export const selectDataIsLoaded = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectDataIsLoaded ); export const selectData = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectData ); export const selectSelectedData = createSelector( - selectInstanceState, + selectSearchState, fromSearch.selectSelectedData ); diff --git a/client/src/app/instance/store/services/detail.service.ts b/client/src/app/instance/store/services/detail.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..e1b5db35066ac3cdcf46e331755d201835014ab4 --- /dev/null +++ b/client/src/app/instance/store/services/detail.service.ts @@ -0,0 +1,53 @@ +/** + * This file is part of Anis Client. + * + * @copyright Laboratoire d'Astrophysique de Marseille / CNRS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; + +import { Observable } from 'rxjs'; + +import { environment } from 'src/environments/environment'; + +@Injectable() +/** + * @class + * @classdesc Detail service. + */ +export class DetailService { + private API_PATH: string = environment.apiUrl + '/search/'; + private SERVICES_PATH: string = environment.servicesUrl; + + constructor(private http: HttpClient) { } + + /** + * Retrieves object details for the given parameters. + * + * @param {string} dname - The dataset name. + * @param {number} criterionId - The criterion ID. + * @param {string} objectSelected - The selected object ID. + * @param {number[]} outputList - The output list. + * + * @return Observable<any[]> + */ + retrieveObject(dname: string, criterionId: number, objectSelected: string, outputList: number[]): Observable<any[]> { + const query = dname + '?c=' + criterionId + '::eq::' + objectSelected + '&a=' + outputList.join(';'); + return this.http.get<any[]>(this.API_PATH + query); + } + + /** + * Retrieves object details for the given parameters. + * + * @param {string} spectraFile - The spectra file name. + * + * @return Observable<string> + */ + retrieveSpectra(dname: string, spectraFile: string): Observable<string> { + return this.http.get(this.SERVICES_PATH + '/spectra-to-csv/' + dname + '?filename=' + spectraFile, { responseType: 'text' }); + } +} diff --git a/client/src/app/instance/store/services/index.ts b/client/src/app/instance/store/services/index.ts index 4707c60a165f5e0b28a886c148854579537703d5..cabc079690c1bfea8a44fddb9baa7123796937b2 100644 --- a/client/src/app/instance/store/services/index.ts +++ b/client/src/app/instance/store/services/index.ts @@ -1,9 +1,11 @@ import { SearchService } from './search.service'; import { SampService } from './samp.service'; import { ConeSearchService } from './cone-search.service'; +import { DetailService } from './detail.service'; export const instanceServices = [ SearchService, SampService, - ConeSearchService + ConeSearchService, + DetailService ]; diff --git a/client/yarn.lock b/client/yarn.lock index 2a005f9358ac87f05bedd31cb41ab6f7bf727db2..374022b1be318ba6228961cb9dc4dcfcd78a8d14 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -1344,6 +1344,222 @@ resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.10.tgz#61cc8469849e5bcdd0c7044122265c39cec10cf4" integrity sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ== +"@types/d3-array@^1": + version "1.2.9" + resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-1.2.9.tgz#c7dc78992cd8ca5c850243a265fd257ea56df1fa" + integrity sha512-E/7RgPr2ylT5dWG0CswMi9NpFcjIEDqLcUSBgNHe/EMahfqYaTx4zhcggG3khqoEB/leY4Vl6nTSbwLUPjXceA== + +"@types/d3-axis@^1": + version "1.0.16" + resolved "https://registry.yarnpkg.com/@types/d3-axis/-/d3-axis-1.0.16.tgz#93d7a28795c2f8b0e2fd550fcc4d29b7f174e693" + integrity sha512-p7085weOmo4W+DzlRRVC/7OI/jugaKbVa6WMQGCQscaMylcbuaVEGk7abJLNyGVFLeCBNrHTdDiqRGnzvL0nXQ== + dependencies: + "@types/d3-selection" "^1" + +"@types/d3-brush@^1": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@types/d3-brush/-/d3-brush-1.1.5.tgz#c7cfb58decbfd53ad3e47f0376345e3640a68186" + integrity sha512-4zGkBafJf5zCsBtLtvDj/pNMo5X9+Ii/1hUz0GvQ+wEwelUBm2AbIDAzJnp2hLDFF307o0fhxmmocHclhXC+tw== + dependencies: + "@types/d3-selection" "^1" + +"@types/d3-chord@^1": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@types/d3-chord/-/d3-chord-1.0.11.tgz#5760765db1b1a4b936c0d9355a821dde9dd25da2" + integrity sha512-0DdfJ//bxyW3G9Nefwq/LDgazSKNN8NU0lBT3Cza6uVuInC2awMNsAcv1oKyRFLn9z7kXClH5XjwpveZjuz2eg== + +"@types/d3-collection@*": + version "1.0.10" + resolved "https://registry.yarnpkg.com/@types/d3-collection/-/d3-collection-1.0.10.tgz#bca161e336156968f267c077f7f2bfa8ff224e58" + integrity sha512-54Fdv8u5JbuXymtmXm2SYzi1x/Svt+jfWBU5junkhrCewL92VjqtCBDn97coBRVwVFmYNnVTNDyV8gQyPYfm+A== + +"@types/d3-color@^1": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.4.2.tgz#944f281d04a0f06e134ea96adbb68303515b2784" + integrity sha512-fYtiVLBYy7VQX+Kx7wU/uOIkGQn8aAEY8oWMoyja3N4dLd8Yf6XgSIR/4yWvMuveNOH5VShnqCgRqqh/UNanBA== + +"@types/d3-contour@^1": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@types/d3-contour/-/d3-contour-1.3.3.tgz#44529d498bbc1db78b195d75e1c9bb889edd647a" + integrity sha512-LxwmGIfVJIc1cKs7ZFRQ1FbtXpfH7QTXYRdMIJsFP71uCMdF6jJ0XZakYDX6Hn4yZkLf+7V8FgD34yCcok+5Ww== + dependencies: + "@types/d3-array" "^1" + "@types/geojson" "*" + +"@types/d3-dispatch@^1": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@types/d3-dispatch/-/d3-dispatch-1.0.9.tgz#c5a180f1e251de853b399cfbfbb6dd7f8bf842ae" + integrity sha512-zJ44YgjqALmyps+II7b1mZLhrtfV/FOxw9owT87mrweGWcg+WK5oiJX2M3SYJ0XUAExBduarysfgbR11YxzojQ== + +"@types/d3-drag@^1": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@types/d3-drag/-/d3-drag-1.2.5.tgz#0b1b852cb41577075aa625ae6149379ea6c34dfd" + integrity sha512-7NeTnfolst1Js3Vs7myctBkmJWu6DMI3k597AaHUX98saHjHWJ6vouT83UrpE+xfbSceHV+8A0JgxuwgqgmqWw== + dependencies: + "@types/d3-selection" "^1" + +"@types/d3-dsv@^1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-1.2.1.tgz#1524fee9f19d689c2f76aa0e24e230762bf96994" + integrity sha512-LLmJmjiqp/fTNEdij5bIwUJ6P6TVNk5hKM9/uk5RPO2YNgEu9XvKO0dJ7Iqd3psEdmZN1m7gB1bOsjr4HmO2BA== + +"@types/d3-ease@^1": + version "1.0.10" + resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-1.0.10.tgz#09910e8558439b6038a7ed620650e510394ffa6d" + integrity sha512-fMFTCzd8DOwruE9zlu2O8ci5ct+U5jkGcDS+cH+HCidnJlDs0MZ+TuSVCFtEzh4E5MasItwy+HvgoFtxPHa5Cw== + +"@types/d3-fetch@^1": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-1.2.2.tgz#b93bfe248b8b761af82f4dac57959c989f67da3e" + integrity sha512-rtFs92GugtV/NpiJQd0WsmGLcg52tIL0uF0bKbbJg231pR9JEb6HT4AUwrtuLq3lOeKdLBhsjV14qb0pMmd0Aw== + dependencies: + "@types/d3-dsv" "^1" + +"@types/d3-force@^1": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/d3-force/-/d3-force-1.2.4.tgz#6e274c72288c2db08fbdb8f5b87b9aa83e55a9e8" + integrity sha512-fkorLTKvt6AQbFBQwn4aq7h9rJ4c7ZVcPMGB8X6eFFveAyMZcv7t7m6wgF4Eg93rkPgPORU7sAho1QSHNcZu6w== + +"@types/d3-format@^1": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@types/d3-format/-/d3-format-1.4.2.tgz#ea17bf559b71d9afd569ae9bfe4c544dab863baa" + integrity sha512-WeGCHAs7PHdZYq6lwl/+jsl+Nfc1J2W1kNcMeIMYzQsT6mtBDBgtJ/rcdjZ0k0rVIvqEZqhhuD5TK/v3P2gFHQ== + +"@types/d3-geo@^1": + version "1.12.3" + resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-1.12.3.tgz#512ebe735cb1cdf5f87ad59608416e2e9e868c5a" + integrity sha512-yZbPb7/5DyL/pXkeOmZ7L5ySpuGr4H48t1cuALjnJy5sXQqmSSAYBiwa6Ya/XpWKX2rJqGDDubmh3nOaopOpeA== + dependencies: + "@types/geojson" "*" + +"@types/d3-hierarchy@^1": + version "1.1.8" + resolved "https://registry.yarnpkg.com/@types/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz#50657f420d565a06c0b950a4b82eee0a369f2dea" + integrity sha512-AbStKxNyWiMDQPGDguG2Kuhlq1Sv539pZSxYbx4UZeYkutpPwXCcgyiRrlV4YH64nIOsKx7XVnOMy9O7rJsXkg== + +"@types/d3-interpolate@^1": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-1.4.2.tgz#88902a205f682773a517612299a44699285eed7b" + integrity sha512-ylycts6llFf8yAEs1tXzx2loxxzDZHseuhPokrqKprTQSTcD3JbJI1omZP1rphsELZO3Q+of3ff0ZS7+O6yVzg== + dependencies: + "@types/d3-color" "^1" + +"@types/d3-path@^1": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-1.0.9.tgz#73526b150d14cd96e701597cbf346cfd1fd4a58c" + integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ== + +"@types/d3-polygon@^1": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/d3-polygon/-/d3-polygon-1.0.8.tgz#127ee83fccda5bf57384011da90f31367fea1530" + integrity sha512-1TOJPXCBJC9V3+K3tGbTqD/CsqLyv/YkTXAcwdsZzxqw5cvpdnCuDl42M4Dvi8XzMxZNCT9pL4ibrK2n4VmAcw== + +"@types/d3-quadtree@^1": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@types/d3-quadtree/-/d3-quadtree-1.0.9.tgz#c7c3b795b5af06e5b043d1d34e754a434b3bae59" + integrity sha512-5E0OJJn2QVavITFEc1AQlI8gLcIoDZcTKOD3feKFckQVmFV4CXhqRFt83tYNVNIN4ZzRkjlAMavJa1ldMhf5rA== + +"@types/d3-random@^1": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@types/d3-random/-/d3-random-1.1.3.tgz#8f7fdc23f92d1561e0694eb49567e8ab50537a19" + integrity sha512-XXR+ZbFCoOd4peXSMYJzwk0/elP37WWAzS/DG+90eilzVbUSsgKhBcWqylGWe+lA2ubgr7afWAOBaBxRgMUrBQ== + +"@types/d3-scale-chromatic@^1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-1.5.1.tgz#e2b7c3401e5c13809f831911eb820e444f4fc67a" + integrity sha512-7FtJYrmXTEWLykShjYhoGuDNR/Bda0+tstZMkFj4RRxUEryv16AGh3be21tqg84B6KfEwiZyEpBcTyPyU+GWjg== + +"@types/d3-scale@^2": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-2.2.6.tgz#28540b4dfc99d978970e873e4138a6bea2ea6ab8" + integrity sha512-CHu34T5bGrJOeuhGxyiz9Xvaa9PlsIaQoOqjDg7zqeGj2x0rwPhGquiy03unigvcMxmvY0hEaAouT0LOFTLpIw== + dependencies: + "@types/d3-time" "^1" + +"@types/d3-selection@^1": + version "1.4.3" + resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-1.4.3.tgz#36928bbe64eb8e0bbcbaa01fb05c21ff6c71fa93" + integrity sha512-GjKQWVZO6Sa96HiKO6R93VBE8DUW+DDkFpIMf9vpY5S78qZTlRRSNUsHr/afDpF7TvLDV7VxrUFOWW7vdIlYkA== + +"@types/d3-shape@^1": + version "1.3.8" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-1.3.8.tgz#c3c15ec7436b4ce24e38de517586850f1fea8e89" + integrity sha512-gqfnMz6Fd5H6GOLYixOZP/xlrMtJms9BaS+6oWxTKHNqPGZ93BkWWupQSCYm6YHqx6h9wjRupuJb90bun6ZaYg== + dependencies: + "@types/d3-path" "^1" + +"@types/d3-time-format@^2": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@types/d3-time-format/-/d3-time-format-2.3.1.tgz#87a30e4513b9d1d53b920327a361f87255bf3372" + integrity sha512-fck0Z9RGfIQn3GJIEKVrp15h9m6Vlg0d5XXeiE/6+CQiBmMDZxfR21XtjEPuDeg7gC3bBM0SdieA5XF3GW1wKA== + +"@types/d3-time@^1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-1.1.1.tgz#6cf3a4242c3bbac00440dfb8ba7884f16bedfcbf" + integrity sha512-ULX7LoqXTCYtM+tLYOaeAJK7IwCT+4Gxlm2MaH0ErKLi07R5lh8NHCAyWcDkCCmx1AfRcBEV6H9QE9R25uP7jw== + +"@types/d3-timer@^1": + version "1.0.10" + resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-1.0.10.tgz#329c51c2c931f44ed0acff78b8c84571acf0ed21" + integrity sha512-ZnAbquVqy+4ZjdW0cY6URp+qF/AzTVNda2jYyOzpR2cPT35FTXl78s15Bomph9+ckOiI1TtkljnWkwbIGAb6rg== + +"@types/d3-transition@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/d3-transition/-/d3-transition-1.3.2.tgz#ed59beca7b4d679cfa52f88a6a50e5bbeb7e0a3c" + integrity sha512-J+a3SuF/E7wXbOSN19p8ZieQSFIm5hU2Egqtndbc54LXaAEOpLfDx4sBu/PKAKzHOdgKK1wkMhINKqNh4aoZAg== + dependencies: + "@types/d3-selection" "^1" + +"@types/d3-voronoi@*": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@types/d3-voronoi/-/d3-voronoi-1.1.9.tgz#7bbc210818a3a5c5e0bafb051420df206617c9e5" + integrity sha512-DExNQkaHd1F3dFPvGA/Aw2NGyjMln6E9QzsiqOcBgnE+VInYnFBHBBySbZQts6z6xD+5jTfKCP7M4OqMyVjdwQ== + +"@types/d3-zoom@^1": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-1.8.3.tgz#00237900c6fdc2bb4fe82679ee4d74eb8fbe7b3c" + integrity sha512-3kHkL6sPiDdbfGhzlp5gIHyu3kULhtnHTTAl3UBZVtWB1PzcLL8vdmz5mTx7plLiUqOA2Y+yT2GKjt/TdA2p7Q== + dependencies: + "@types/d3-interpolate" "^1" + "@types/d3-selection" "^1" + +"@types/d3@^5.7.2": + version "5.16.4" + resolved "https://registry.yarnpkg.com/@types/d3/-/d3-5.16.4.tgz#a7dc24a3dc1c19922eee72ba16144fd5bcea987a" + integrity sha512-2u0O9iP1MubFiQ+AhR1id4Egs+07BLtvRATG6IL2Gs9+KzdrfaxCKNq5hxEyw1kxwsqB/lCgr108XuHcKtb/5w== + dependencies: + "@types/d3-array" "^1" + "@types/d3-axis" "^1" + "@types/d3-brush" "^1" + "@types/d3-chord" "^1" + "@types/d3-collection" "*" + "@types/d3-color" "^1" + "@types/d3-contour" "^1" + "@types/d3-dispatch" "^1" + "@types/d3-drag" "^1" + "@types/d3-dsv" "^1" + "@types/d3-ease" "^1" + "@types/d3-fetch" "^1" + "@types/d3-force" "^1" + "@types/d3-format" "^1" + "@types/d3-geo" "^1" + "@types/d3-hierarchy" "^1" + "@types/d3-interpolate" "^1" + "@types/d3-path" "^1" + "@types/d3-polygon" "^1" + "@types/d3-quadtree" "^1" + "@types/d3-random" "^1" + "@types/d3-scale" "^2" + "@types/d3-scale-chromatic" "^1" + "@types/d3-selection" "^1" + "@types/d3-shape" "^1" + "@types/d3-time" "^1" + "@types/d3-time-format" "^2" + "@types/d3-timer" "^1" + "@types/d3-transition" "^1" + "@types/d3-voronoi" "*" + "@types/d3-zoom" "^1" + "@types/eslint-scope@^3.7.0": version "3.7.0" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.0.tgz#4792816e31119ebd506902a482caec4951fabd86" @@ -1370,6 +1586,11 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.47.tgz#d7a51db20f0650efec24cd04994f523d93172ed4" integrity sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg== +"@types/geojson@*": + version "7946.0.8" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" + integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== + "@types/glob@^7.1.1": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" @@ -2402,7 +2623,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.20.0: +commander@2, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -2780,6 +3001,254 @@ custom-event@~1.0.0: resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= +d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" + integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== + +d3-axis@1: + version "1.0.12" + resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.12.tgz#cdf20ba210cfbb43795af33756886fb3638daac9" + integrity sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ== + +d3-brush@1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-1.1.6.tgz#b0a22c7372cabec128bdddf9bddc058592f89e9b" + integrity sha512-7RW+w7HfMCPyZLifTz/UnJmI5kdkXtpCbombUSs8xniAyo0vIbrDzDwUJB6eJOgl9u5DQOt2TQlYumxzD1SvYA== + dependencies: + d3-dispatch "1" + d3-drag "1" + d3-interpolate "1" + d3-selection "1" + d3-transition "1" + +d3-chord@1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-1.0.6.tgz#309157e3f2db2c752f0280fedd35f2067ccbb15f" + integrity sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA== + dependencies: + d3-array "1" + d3-path "1" + +d3-collection@1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e" + integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A== + +d3-color@1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a" + integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q== + +d3-contour@1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-1.3.2.tgz#652aacd500d2264cb3423cee10db69f6f59bead3" + integrity sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg== + dependencies: + d3-array "^1.1.1" + +d3-dispatch@1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.6.tgz#00d37bcee4dd8cd97729dd893a0ac29caaba5d58" + integrity sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA== + +d3-drag@1: + version "1.2.5" + resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-1.2.5.tgz#2537f451acd39d31406677b7dc77c82f7d988f70" + integrity sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w== + dependencies: + d3-dispatch "1" + d3-selection "1" + +d3-dsv@1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.2.0.tgz#9d5f75c3a5f8abd611f74d3f5847b0d4338b885c" + integrity sha512-9yVlqvZcSOMhCYzniHE7EVUws7Fa1zgw+/EAV2BxJoG3ME19V6BQFBwI855XQDsxyOuG7NibqRMTtiF/Qup46g== + dependencies: + commander "2" + iconv-lite "0.4" + rw "1" + +d3-ease@1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.7.tgz#9a834890ef8b8ae8c558b2fe55bd57f5993b85e2" + integrity sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ== + +d3-fetch@1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/d3-fetch/-/d3-fetch-1.2.0.tgz#15ce2ecfc41b092b1db50abd2c552c2316cf7fc7" + integrity sha512-yC78NBVcd2zFAyR/HnUiBS7Lf6inSCoWcSxFfw8FYL7ydiqe80SazNwoffcqOfs95XaLo7yebsmQqDKSsXUtvA== + dependencies: + d3-dsv "1" + +d3-force@1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.2.1.tgz#fd29a5d1ff181c9e7f0669e4bd72bdb0e914ec0b" + integrity sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg== + dependencies: + d3-collection "1" + d3-dispatch "1" + d3-quadtree "1" + d3-timer "1" + +d3-format@1: + version "1.4.5" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.5.tgz#374f2ba1320e3717eb74a9356c67daee17a7edb4" + integrity sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ== + +d3-geo@1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.12.1.tgz#7fc2ab7414b72e59fbcbd603e80d9adc029b035f" + integrity sha512-XG4d1c/UJSEX9NfU02KwBL6BYPj8YKHxgBEw5om2ZnTRSbIcego6dhHwcxuSR3clxh0EpE38os1DVPOmnYtTPg== + dependencies: + d3-array "1" + +d3-hierarchy@1: + version "1.1.9" + resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz#2f6bee24caaea43f8dc37545fa01628559647a83" + integrity sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ== + +d3-interpolate@1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" + integrity sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA== + dependencies: + d3-color "1" + +d3-path@1: + version "1.0.9" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf" + integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== + +d3-polygon@1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-1.0.6.tgz#0bf8cb8180a6dc107f518ddf7975e12abbfbd38e" + integrity sha512-k+RF7WvI08PC8reEoXa/w2nSg5AUMTi+peBD9cmFc+0ixHfbs4QmxxkarVal1IkVkgxVuk9JSHhJURHiyHKAuQ== + +d3-quadtree@1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-1.0.7.tgz#ca8b84df7bb53763fe3c2f24bd435137f4e53135" + integrity sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA== + +d3-random@1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.1.2.tgz#2833be7c124360bf9e2d3fd4f33847cfe6cab291" + integrity sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ== + +d3-scale-chromatic@1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-1.5.0.tgz#54e333fc78212f439b14641fb55801dd81135a98" + integrity sha512-ACcL46DYImpRFMBcpk9HhtIyC7bTBR4fNOPxwVSl0LfulDAwyiHyPOTqcDG1+t5d4P9W7t/2NAuWu59aKko/cg== + dependencies: + d3-color "1" + d3-interpolate "1" + +d3-scale@2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-2.2.2.tgz#4e880e0b2745acaaddd3ede26a9e908a9e17b81f" + integrity sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw== + dependencies: + d3-array "^1.2.0" + d3-collection "1" + d3-format "1" + d3-interpolate "1" + d3-time "1" + d3-time-format "2" + +d3-selection@1, d3-selection@^1.1.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.4.2.tgz#dcaa49522c0dbf32d6c1858afc26b6094555bc5c" + integrity sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg== + +d3-shape@1: + version "1.3.7" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7" + integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== + dependencies: + d3-path "1" + +d3-time-format@2: + version "2.3.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.3.0.tgz#107bdc028667788a8924ba040faf1fbccd5a7850" + integrity sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ== + dependencies: + d3-time "1" + +d3-time@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1" + integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA== + +d3-timer@1: + version "1.0.10" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.10.tgz#dfe76b8a91748831b13b6d9c793ffbd508dd9de5" + integrity sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw== + +d3-transition@1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.3.2.tgz#a98ef2151be8d8600543434c1ca80140ae23b398" + integrity sha512-sc0gRU4PFqZ47lPVHloMn9tlPcv8jxgOQg+0zjhfZXMQuvppjG6YuwdMBE0TuqCZjeJkLecku/l9R0JPcRhaDA== + dependencies: + d3-color "1" + d3-dispatch "1" + d3-ease "1" + d3-interpolate "1" + d3-selection "^1.1.0" + d3-timer "1" + +d3-voronoi@1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.4.tgz#dd3c78d7653d2bb359284ae478645d95944c8297" + integrity sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg== + +d3-zoom@1: + version "1.8.3" + resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.8.3.tgz#b6a3dbe738c7763121cd05b8a7795ffe17f4fc0a" + integrity sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ== + dependencies: + d3-dispatch "1" + d3-drag "1" + d3-interpolate "1" + d3-selection "1" + d3-transition "1" + +d3@^5.15.1: + version "5.16.0" + resolved "https://registry.yarnpkg.com/d3/-/d3-5.16.0.tgz#9c5e8d3b56403c79d4ed42fbd62f6113f199c877" + integrity sha512-4PL5hHaHwX4m7Zr1UapXW23apo6pexCgdetdJ5kTmADpG/7T9Gkxw0M0tf/pjoB63ezCCm0u5UaFYy2aMt0Mcw== + dependencies: + d3-array "1" + d3-axis "1" + d3-brush "1" + d3-chord "1" + d3-collection "1" + d3-color "1" + d3-contour "1" + d3-dispatch "1" + d3-drag "1" + d3-dsv "1" + d3-ease "1" + d3-fetch "1" + d3-force "1" + d3-format "1" + d3-geo "1" + d3-hierarchy "1" + d3-interpolate "1" + d3-path "1" + d3-polygon "1" + d3-quadtree "1" + d3-random "1" + d3-scale "2" + d3-scale-chromatic "1" + d3-selection "1" + d3-shape "1" + d3-time "1" + d3-time-format "2" + d3-timer "1" + d3-transition "1" + d3-voronoi "1" + d3-zoom "1" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -3851,7 +4320,7 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" -iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: +iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -6618,6 +7087,11 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +rw@1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" + integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q= + rxjs@6.6.7, rxjs@^6.6.6, rxjs@~6.6.0: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"