diff --git a/client/src/app/instance/search/components/result/cone-search-plot.component.ts b/client/src/app/instance/search/components/result/cone-search-plot.component.ts index 139e9a79a11e36a9a70737ad41b3256183394bd2..e57aa634c5bca4bb4d55476c965320d837ca57c7 100644 --- a/client/src/app/instance/search/components/result/cone-search-plot.component.ts +++ b/client/src/app/instance/search/components/result/cone-search-plot.component.ts @@ -7,11 +7,13 @@ * file that was distributed with this source code. */ -import { Component, Input, ChangeDetectionStrategy, ViewEncapsulation, OnInit } from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy, ViewEncapsulation, OnInit, SimpleChanges } from '@angular/core'; import * as d3 from 'd3'; +import { Dataset, Image } from 'src/app/metamodel/models'; import { ConeSearch } from 'src/app/instance/store/models'; +import { AppConfigService } from 'src/app/app-config.service'; /** * @class @@ -26,22 +28,45 @@ import { ConeSearch } from 'src/app/instance/store/models'; }) export class ConeSearchPlotComponent implements OnInit { @Input() coneSearch: ConeSearch; + @Input() dataset: Dataset; @Input() data: {x: number, y: number}[]; + @Input() selectedBackground: Image; // Interactive variables intialisation margin = { top: 50, right: 50, bottom: 50 , left: 50 }; width = 500; height = 500; degTorad = 0.0174532925; + image; x: d3.ScaleLinear<number, number>; y: d3.ScaleLinear<number, number>; + constructor(private config: AppConfigService) { } + ngOnInit(): void { this.coneSearchPlot(); } + ngOnChanges(changes: SimpleChanges) { + if (changes.selectedBackground && changes.selectedBackground.currentValue) { + console.log('coucou'); + this.image.attr('xlink:href', this.getHrefBackgroundImage()); + } + } + + getHrefBackgroundImage() { - //const scale = this.width / (this.rad * 2); + if (this.selectedBackground) { + let href = `${this.config.servicesUrl}/fits-cut-to-png/${this.dataset.name}?filename=${this.selectedBackground.file_path}`; + href += `&ra=${this.coneSearch.ra}`; + href += `&dec=${this.coneSearch.dec}`; + href += `&radius=${this.coneSearch.radius}`; + href += `&stretch=${this.selectedBackground.stretch}`; + href += `&pmin=${this.selectedBackground.pmin}`; + href += `&pmax=${this.selectedBackground.pmax}`; + href += `&axes=false`; + return href; + } else { const scale = this.coneSearch.radius / this.width; // arcsec/pix return `https://skyserver.sdss.org/dr16/SkyServerWS/ImgCutout/getjpeg?TaskName=Skyserver.Chart.Image &ra=${this.coneSearch.ra} @@ -49,6 +74,7 @@ export class ConeSearchPlotComponent implements OnInit { &scale=${scale} &width=${this.width} &height=${this.height}`; + } } coneSearchPlot(): void { @@ -66,8 +92,8 @@ export class ConeSearchPlotComponent implements OnInit { this.y = d3.scaleLinear().range([this.height, 0]).domain([coneSearchDomain.decMin, coneSearchDomain.decMax]); // Background image - svg.append('image') - .attr('xlink:href', this.getHrefBackgroundImage()) + this.image = svg.append('image'); + this.image.attr('xlink:href', this.getHrefBackgroundImage()) .attr('width', this.width) .attr('height', this.height); 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 9b4650c1c0d3f1b3fa7499cee57495a72331e880..d35da3bb90fac0e8f942488940b1827a7135561c 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,9 +10,17 @@ </button> <div class="row"> <div class="col-md-5" *ngIf="coneSearch"> + <div class="form-group"> + <label for="file_size">Background image</label> + <ng-select [(ngModel)]="selectedBackground"> + <ng-option *ngFor="let image of imageList" [value]="image">{{ image.file_path }}</ng-option> + </ng-select> + </div> <app-cone-search-plot *ngIf="dataIsLoaded" [coneSearch]="coneSearch" - [data]="getData()"> + [dataset]="datasetList | datasetByName:datasetSelected" + [data]="getData()" + [selectedBackground]="selectedBackground"> </app-cone-search-plot> </div> <div class="datatable-group" [ngClass]="{'col': !coneSearch, 'col-md-7' : coneSearch }"> 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 a3e98442298efd11af6481a3ebdb9a8c6d0e0f5b..239dde5745afd6c0239ff2185b6686ce28c5abd1 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 @@ -9,7 +9,7 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; -import { Instance, Attribute, Dataset } from 'src/app/metamodel/models'; +import { Instance, Attribute, Dataset, Image } from 'src/app/metamodel/models'; import { Pagination, SearchQueryParams, Criterion, ConeSearch } from 'src/app/instance/store/models'; /** @@ -37,6 +37,9 @@ export class DatatableTabComponent { @Input() dataIsLoading: boolean; @Input() dataIsLoaded: boolean; @Input() selectedData: any[]; + @Input() imageList: Image[]; + @Input() imageListIsLoading: boolean; + @Input() imageListIsLoaded: boolean; @Output() retrieveData: EventEmitter<Pagination> = new EventEmitter(); @Output() addSelectedData: EventEmitter<number | string> = new EventEmitter(); @Output() deleteSelectedData: EventEmitter<number | string> = new EventEmitter(); @@ -45,6 +48,8 @@ export class DatatableTabComponent { @Output() startTaskCreateArchive: EventEmitter<{ selectedData: boolean }> = new EventEmitter(); @Output() downloadFile: EventEmitter<{url: string, fileId: string, datasetName: string, filename: string}> = new EventEmitter(); + selectedBackground: Image = null; + getData() { const dataset = this.getDataset(); const columnRa = this.attributeList.find(a => a.id === dataset.cone_search_column_ra); diff --git a/client/src/app/instance/search/containers/result.component.html b/client/src/app/instance/search/containers/result.component.html index 5237bf3acd0c93aa76fde94e9bddd7522936ca2e..c4ba3724f9f109626bc4a7d957555a0190742fc0 100644 --- a/client/src/app/instance/search/containers/result.component.html +++ b/client/src/app/instance/search/containers/result.component.html @@ -86,6 +86,9 @@ [dataIsLoading]="dataIsLoading | async" [dataIsLoaded]="dataIsLoaded | async" [selectedData]="selectedData | async" + [imageList]="imageList | async" + [imageListIsLoading]="imageListIsLoading | async" + [imageListIsLoaded]="imageListIsLoaded | async" (retrieveData)="retrieveData($event)" (addSelectedData)="addSearchData($event)" (deleteSelectedData)="deleteSearchData($event)" diff --git a/client/src/app/instance/search/containers/result.component.ts b/client/src/app/instance/search/containers/result.component.ts index d97b50fdc50c8c96a565c445fdda1357de323061..5540c05ca04b19bceeba10fb179e21e743312cfb 100644 --- a/client/src/app/instance/search/containers/result.component.ts +++ b/client/src/app/instance/search/containers/result.component.ts @@ -14,7 +14,7 @@ import { Observable, Subscription } from 'rxjs'; import { AbstractSearchComponent } from './abstract-search.component'; import { Pagination, DownloadFile } from '../../store/models'; -import { Instance } from 'src/app/metamodel/models'; +import { Instance, Image } from 'src/app/metamodel/models'; import * as instanceSelector from 'src/app/metamodel/selectors/instance.selector'; import * as searchActions from '../../store/actions/search.actions'; import * as searchSelector from '../../store/selectors/search.selector'; @@ -22,6 +22,8 @@ import * as sampActions from 'src/app/samp/samp.actions'; import * as sampSelector from 'src/app/samp/samp.selector'; import * as downloadFileActions from '../../store/actions/download-file.actions'; import * as downloadFileSelector from '../../store/selectors/download-file.selector'; +import * as imageActions from 'src/app/metamodel/actions/image.actions'; +import * as imageSelector from 'src/app/metamodel/selectors/image.selector'; /** * @class @@ -45,6 +47,9 @@ export class ResultComponent extends AbstractSearchComponent { public selectedData: Observable<any>; public sampRegistered: Observable<boolean>; public downloadedFiles: Observable<DownloadFile[]>; + public imageList: Observable<Image[]>; + public imageListIsLoading: Observable<boolean>; + public imageListIsLoaded: Observable<boolean>; public pristineSubscription: Subscription; constructor(protected store: Store<{ }>) { @@ -59,6 +64,9 @@ export class ResultComponent extends AbstractSearchComponent { this.selectedData = this.store.select(searchSelector.selectSelectedData); this.sampRegistered = this.store.select(sampSelector.selectRegistered); this.downloadedFiles = this.store.select(downloadFileSelector.selectDownloadedFiles); + this.imageList = this.store.select(imageSelector.selectAllImages); + this.imageListIsLoading = this.store.select(imageSelector.selectImageListIsLoading); + this.imageListIsLoaded = this.store.select(imageSelector.selectImageListIsLoaded); } ngOnInit(): void { @@ -72,6 +80,7 @@ export class ResultComponent extends AbstractSearchComponent { Promise.resolve(null).then(() => this.store.dispatch(searchActions.retrieveDataLength())); } }); + Promise.resolve(null).then(() => this.store.dispatch(imageActions.loadImageList())); } /**