From cc742a4437c3ed65e3f483b315f8e2447abfb867 Mon Sep 17 00:00:00 2001 From: tylercchase Date: Tue, 1 Oct 2024 13:10:16 -0400 Subject: [PATCH 01/23] chore: add GRD_HS to on demand product types --- src/app/models/hyp3-jobs.model.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/models/hyp3-jobs.model.ts b/src/app/models/hyp3-jobs.model.ts index 2a6c43fb8..88a28c58e 100644 --- a/src/app/models/hyp3-jobs.model.ts +++ b/src/app/models/hyp3-jobs.model.ts @@ -12,7 +12,7 @@ export const RtcGammaJobType: Hyp3JobType = { productTypes: [{ dataset: sentinel_1, productTypes: [ - 'SLC', 'GRD_HD' + 'SLC', 'GRD_HD', 'GRD_HS' ], beamModes: ['IW'], polarizations: [ From eef65faca99c2b8950c5ac92749d26c36f0383b1 Mon Sep 17 00:00:00 2001 From: Yoreley Date: Wed, 2 Oct 2024 19:07:52 -0700 Subject: [PATCH 02/23] Added character limit --- .../save-search-dialog.component.html | 12 ++++++++---- src/assets/i18n/es.json | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/app/components/shared/save-search-dialog/save-search-dialog.component.html b/src/app/components/shared/save-search-dialog/save-search-dialog.component.html index 6d4a91b51..727e4ff23 100644 --- a/src/app/components/shared/save-search-dialog/save-search-dialog.component.html +++ b/src/app/components/shared/save-search-dialog/save-search-dialog.component.html @@ -3,15 +3,19 @@

{{ saveTypeName | uppercase | translate | titlecase }}

- - + + [(ngModel)]="saveName" + [maxLength]="20"> + {{saveNameInput.value?.length || 0}}/20
diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index 1404d3add..11664bfb8 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -922,4 +922,4 @@ "ZOOM_TO_FIT": "Acercar para ajustar", "ZOOM_TO_RESULTS": "Acercar a los resultados", "ZOOM_TO_SCENE": "Acercar a la escena" -} \ No newline at end of file +} From 6769fe9fc84028672545bc43ff0830564dab6799 Mon Sep 17 00:00:00 2001 From: ASF Discovery Machine User <60239462+ASF-Discovery@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:49:55 -0800 Subject: [PATCH 03/23] Updated translations from Phrase phrase: update src/assets/i18n/en.json to latest state phrase: update src/assets/i18n/es.json to latest state phrase: update src/assets/i18n/de.json to latest state --- src/assets/i18n/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index 11664bfb8..0ea9c40f7 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -739,7 +739,7 @@ "SETTINGS_OVERSCAN": "ajustes_overscan", "SHARE_SEARCH": "Compartir Búsqueda", "SHARE_WITH_EMAIL": "Compartir Con Correo Electrónico", - "SHORTWAVE_DISPLACEMENT": "Desplazamiento", + "SHORTWAVE_DISPLACEMENT": "Desplazamiento de onda corta", "SHOW_PRODUCT_FILTERS_CRITERIA": "Mostrar criterios de filtros de productos", "SHOW_RAW_DATA": "Mostrar datos sin procesar", "SIGMA0": "sigma0", From 79255537e29119e027c0a448b705dfb8a70186b4 Mon Sep 17 00:00:00 2001 From: ASF Discovery Machine User <60239462+ASF-Discovery@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:59:58 -0800 Subject: [PATCH 04/23] Updated translations from Phrase phrase: update src/assets/i18n/en.json to latest state phrase: update src/assets/i18n/es.json to latest state phrase: update src/assets/i18n/de.json to latest state --- src/assets/i18n/en.json | 1 + src/assets/i18n/es.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 506551b15..41e0a11cb 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -111,6 +111,7 @@ "CANADAS_OPEN_LICENSE": "Canada's Open Government License", "CANCEL": "Cancel", "CENTER_COLUMN_AND_FILES_COLUMN_RIGHT_WILL_POPULATE": "(center column) and Files column (right) will populate.", + "CHARACTERS": "characters", "CHART": "Chart", "CHEVRON_RIGHT": "chevron_right", "CIRCLE DRAW": "Circle Draw", diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index 0ea9c40f7..649108801 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -112,6 +112,7 @@ "CANADAS_OPEN_LICENSE": "Licencia de Gobierno Abierto de Canadá", "CANCEL": "Cancelar", "CENTER_COLUMN_AND_FILES_COLUMN_RIGHT_WILL_POPULATE": "(columna central) y la columna Archivos (derecha) se completarán.", + "CHARACTERS": "caracteres", "CHART": "Cuadro", "CHEVRON_RIGHT": "chevron_right", "CIRCLE DRAW": "Dibujar Circulo", @@ -739,7 +740,7 @@ "SETTINGS_OVERSCAN": "ajustes_overscan", "SHARE_SEARCH": "Compartir Búsqueda", "SHARE_WITH_EMAIL": "Compartir Con Correo Electrónico", - "SHORTWAVE_DISPLACEMENT": "Desplazamiento de onda corta", + "SHORTWAVE_DISPLACEMENT": "Desplazamiento", "SHOW_PRODUCT_FILTERS_CRITERIA": "Mostrar criterios de filtros de productos", "SHOW_RAW_DATA": "Mostrar datos sin procesar", "SIGMA0": "sigma0", From a5729bb0ecb639cdfc26c89da848cfa5db1470ce Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Thu, 3 Oct 2024 14:53:08 -0700 Subject: [PATCH 05/23] Dummy checkboxes for displacement --- .../timeseries-results-menu.component.html | 64 ++++++++++++++----- .../timeseries-results-menu.component.scss | 30 +++++++++ .../timeseries-results-menu.component.ts | 41 +++++++++++- .../timeseries-results-menu.module.ts | 4 +- .../timeseries-chart.component.ts | 49 ++++++++++---- 5 files changed, 158 insertions(+), 30 deletions(-) diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html index 2198653cb..7e310554b 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html @@ -16,24 +16,56 @@
- @if(pointHistory.length !== 0) { - - @for (point of pointHistory; track $index) { - - - place - - {{point.flatCoordinates[1] | floatPrecision: 2}}, {{point.flatCoordinates[0] | floatPrecision: 2}} + @if(pointHistory.length !== 0) { + +
+ + + + {{task().name}} - - } - - } - @else { -
+ + + +
    + @for (subtask of task().subtasks; track subtask; let i = $index) { +
  • + + {{subtask.name}} + +
  • + } +
+
+
+ } + @else { +
{{ 'NO_POINT_SELECTED' | translate }} -
- } +
+ } + + + + + + + + + + + + + + + + +
diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.scss b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.scss index 2802227c0..e819feb97 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.scss +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.scss @@ -305,3 +305,33 @@ label { ::ng-deep .mdc-radio__outer-circle { border-color: #ffcc33 !important; /*change radio button color when selected*/ } + +.point-list-section { + +} + +.parent-checkbox-section { + margin: 0; +} + +.parent-checkbox-label { + font-weight: bold; +} + +.point-list-ul-section { + display: block; + margin-left: 10px; +} + +ul { + list-style-type: none; + margin-top: 8px; +} + +::ng-deep .mdc-checkbox { + height: 7px; +} + +::ng-deep .mat-mdc-checkbox .mdc-checkbox__background { + top: 4px +} diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts index 8091b4d39..7bf79c98b 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Input, OnDestroy, ViewChild, ElementRef } from '@angular/core'; +import {Component, OnInit, Input, OnDestroy, ViewChild, ElementRef, ChangeDetectionStrategy, computed, signal} from '@angular/core'; import { first, Observable, Subject } from 'rxjs'; import { ResizeEvent } from 'angular-resizable-element'; @@ -19,11 +19,17 @@ import moment2 from 'moment'; import { SetScenes } from '@store/scenes'; import { getPathRange } from '@store/filters'; +export interface Task { + name: string; + completed: boolean; + subtasks?: Task[]; +} @Component({ selector: 'app-timeseries-results-menu', templateUrl: './timeseries-results-menu.component.html', - styleUrls: ['./timeseries-results-menu.component.scss', '../results-menu.component.scss'] + styleUrls: ['./timeseries-results-menu.component.scss', '../results-menu.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class TimeseriesResultsMenuComponent implements OnInit, OnDestroy { @@ -215,6 +221,37 @@ export class TimeseriesResultsMenuComponent implements OnInit, OnDestroy { }) } + readonly task = signal({ + name: 'ALL POINTS', + completed: false, + subtasks: [ + {name: 'Child task 1', completed: false}, + {name: 'Child task 2', completed: false}, + {name: 'Child task 3', completed: false}, + ], + }); + + readonly partiallyComplete = computed(() => { + const task = this.task(); + if (!task.subtasks) { + return false; + } + return task.subtasks.some(t => t.completed) && !task.subtasks.every(t => t.completed); + }); + + update(completed: boolean, index?: number) { + this.task.update(task => { + if (index === undefined) { + task.completed = completed; + task.subtasks?.forEach(t => (t.completed = completed)); + } else { + task.subtasks![index].completed = completed; + task.completed = task.subtasks?.every(t => t.completed) ?? true; + } + return {...task}; + }); + } + ngOnDestroy() { this.subs.unsubscribe(); } diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.module.ts b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.module.ts index 8d7451db3..33e62ef63 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.module.ts +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.module.ts @@ -20,6 +20,7 @@ import {MatTab, MatTabGroup} from '@angular/material/tabs'; import { TimeseriesChartTemporalSliderComponent } from '@components/timeseries-chart/timeseries-chart-temporal-slider/timeseries-chart-temporal-slider.component'; +import {MatCheckbox} from '@angular/material/checkbox'; @NgModule({ @@ -43,7 +44,8 @@ import { PipesModule, MatTabGroup, MatTab, - TimeseriesChartTemporalSliderComponent + TimeseriesChartTemporalSliderComponent, + MatCheckbox ], exports: [ TimeseriesResultsMenuComponent diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.ts b/src/app/components/timeseries-chart/timeseries-chart.component.ts index ac77c6b75..aa9100050 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.ts +++ b/src/app/components/timeseries-chart/timeseries-chart.component.ts @@ -10,6 +10,15 @@ import * as chartsStore from '@store/charts'; import { SubSink } from 'subsink'; import { AsfLanguageService } from "@services/asf-language.service"; +interface TimeSeriesChartPoint { + unwrapped_phase: number + interferometric_correlation: number + temporal_coherence: number + date: string + temporal_baseline: number + id: string +} + @Component({ selector: 'app-timeseries-chart', templateUrl: './timeseries-chart.component.html', @@ -179,6 +188,9 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { const self = this; + const Observable10 = this.swatches(); + console.log(Observable10); + this.lineGraph = this.clipContainer.append("path") this.dots = this.clipContainer.append('g').selectAll('circle') @@ -325,8 +337,8 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { .attr('height', this.height + this.margin.top + this.margin.bottom) .append('g') .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`); - this.drawChart(); + this.drawChart(); } private tooltipDateFormat(date) { @@ -342,18 +354,33 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { return join(date, dateFormat, ' '); } + public swatches() { + const colors = d3.schemeCategory10 + const n = colors.length; + const dark = d3.lab(colors[0]).l < 50; + + console.log( colors, n, dark); + + return colors; + + // const canvas = this.svg`${colors.map((c, i) => this.svg``)}`; + // const canvas = ''; + // const label = document.createElement("DIV"); + // label.textContent = name; + // label.style.position = "absolute"; + // label.style.top = "4px"; + // label.style.color = dark ? `#fff` : `#000`; + // canvas.onclick = () => { + // label.textContent = "Copied!"; + // navigator.clipboard.writeText(JSON.stringify(colors)); + // setTimeout(() => label.textContent = name, 2000); + // }; + // @ts-ignore + // return html`${canvas}${label}`; + } + public ngOnDestroy(): void { this.subs.unsubscribe(); } } - -interface TimeSeriesChartPoint { - unwrapped_phase: number - interferometric_correlation: number - temporal_coherence: number - date: string - temporal_baseline: number - id: string -} - From 6490e83d4d748577af982443f0d1d8efbe054229 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Mon, 7 Oct 2024 10:34:59 -0700 Subject: [PATCH 06/23] WIP on displacement checkboxes --- .../timeseries-results-menu.component.html | 9 +++++---- .../timeseries-results-menu.component.scss | 2 +- .../timeseries-results-menu.component.ts | 8 +++++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html index 7e310554b..9c800fa9a 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html @@ -24,7 +24,7 @@ class="parent-checkbox" [checked]="task().completed" [indeterminate]="partiallyComplete()" - (change)="update($event.checked)" + (change)="updateSeries($event.checked)" > {{task().name}} @@ -33,10 +33,11 @@
    - @for (subtask of task().subtasks; track subtask; let i = $index) { + @for (point of pointHistory; track $index) {
  • - - {{subtask.name}} + + {{point.flatCoordinates[1] | floatPrecision: 2}}, {{point.flatCoordinates[0] | floatPrecision: 2}}
  • } diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.scss b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.scss index e819feb97..7c7417304 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.scss +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.scss @@ -325,7 +325,7 @@ label { ul { list-style-type: none; - margin-top: 8px; + margin-top: 0; } ::ng-deep .mdc-checkbox { diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts index 7bf79c98b..11c87c2e3 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts @@ -239,7 +239,7 @@ export class TimeseriesResultsMenuComponent implements OnInit, OnDestroy { return task.subtasks.some(t => t.completed) && !task.subtasks.every(t => t.completed); }); - update(completed: boolean, index?: number) { + public updateSeries(completed: boolean, index?: number) { this.task.update(task => { if (index === undefined) { task.completed = completed; @@ -247,6 +247,12 @@ export class TimeseriesResultsMenuComponent implements OnInit, OnDestroy { } else { task.subtasks![index].completed = completed; task.completed = task.subtasks?.every(t => t.completed) ?? true; + this.pointHistoryService.selectedPoint = index; + this.pointHistoryService.passDraw = true; + let format = new WKT(); + let wktRepresentation = format.writeGeometry(this.pointHistory[index]); + this.mapService.loadPolygonFrom(wktRepresentation.toString()) + } return {...task}; }); From 322dd81e5a5c007f03b1c642cf27642995c86847 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Mon, 7 Oct 2024 14:50:24 -0700 Subject: [PATCH 07/23] WIP on checkboxes --- .../timeseries-results-menu.component.html | 5 ++- .../timeseries-results-menu.component.scss | 10 +++++ .../timeseries-results-menu.component.ts | 4 +- .../timeseries-chart.component.scss | 10 ++--- .../timeseries-chart.component.ts | 38 ++----------------- 5 files changed, 23 insertions(+), 44 deletions(-) diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html index 9c800fa9a..e3f87ace0 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html @@ -37,7 +37,10 @@
  • - {{point.flatCoordinates[1] | floatPrecision: 2}}, {{point.flatCoordinates[0] | floatPrecision: 2}} + place + + {{point.flatCoordinates[1] | floatPrecision: 2}}, {{point.flatCoordinates[0] | floatPrecision: 2}} +
  • } diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.scss b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.scss index 7c7417304..57c68b213 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.scss +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.scss @@ -292,6 +292,16 @@ label { @include themify($themes) { color: darken(themed('dark-primary-text'), 25%); } + font-size: 18px; + line-height: 29px; + margin: 0 0; + width: 18px; +} + +.ts-wkt-label { + margin-left: 5px; + position: relative; + top: -5px; } .ts-wkt-text { diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts index 11c87c2e3..75a9c25ca 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit, Input, OnDestroy, ViewChild, ElementRef, ChangeDetectionStrategy, computed, signal} from '@angular/core'; +import {Component, OnInit, Input, OnDestroy, ViewChild, ElementRef, computed, signal} from '@angular/core'; import { first, Observable, Subject } from 'rxjs'; import { ResizeEvent } from 'angular-resizable-element'; @@ -29,8 +29,6 @@ export interface Task { selector: 'app-timeseries-results-menu', templateUrl: './timeseries-results-menu.component.html', styleUrls: ['./timeseries-results-menu.component.scss', '../results-menu.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - }) export class TimeseriesResultsMenuComponent implements OnInit, OnDestroy { diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.scss b/src/app/components/timeseries-chart/timeseries-chart.component.scss index b047a13f2..44aaa09ef 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.scss +++ b/src/app/components/timeseries-chart/timeseries-chart.component.scss @@ -1,16 +1,16 @@ @import "asf-theme"; -#timeseriesChart { - height: 100%; - width: 100%; -} - .chart-wrapper { height: 90%; width: 100%; display: flex; } +#timeseriesChart { + height: 100%; + width: 100%; +} + ::ng-deep .timeseries-base { @include themify($themes) { fill: themed('blue-link'); diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.ts b/src/app/components/timeseries-chart/timeseries-chart.component.ts index 9f20c8c3b..1281920f7 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.ts +++ b/src/app/components/timeseries-chart/timeseries-chart.component.ts @@ -15,6 +15,7 @@ interface TimeSeriesChartPoint { interferometric_correlation: number temporal_coherence: number date: string + file_name: string, temporal_baseline: number id: string } @@ -25,8 +26,8 @@ interface TimeSeriesChartPoint { styleUrl: './timeseries-chart.component.scss' }) export class TimeseriesChartComponent implements OnInit, OnDestroy { - @ViewChild('timeseriesChart', { static: true }) timeseriesChart: ElementRef; @ViewChild('tsChartWrapper', { static: true }) tsChartWrapper: ElementRef; + @ViewChild('timeseriesChart', { static: true }) timeseriesChart: ElementRef; @Input() zoomIn$: Observable; @Input() zoomOut$: Observable; @Input() zoomToFit$: Observable; @@ -59,15 +60,13 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { private showLines = true; private xAxisTitle = ''; private yAxisTitle = ''; - // private currentLanguage: string = null; private subs = new SubSink(); constructor( private store$: Store, private language: AsfLanguageService, - ) { - } + ) { } public ngOnInit(): void { @@ -113,10 +112,8 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { } public translateChartText() { - this.xAxisTitle = this.language.translate.instant('SCENE') + ' ' + this.language.translate.instant('DATE'); - this.yAxisTitle = this.language.translate.instant('SHORTWAVE_DISPLACEMENT') + ' (' + this.language.translate.instant('METERS') + ')'; } @@ -314,9 +311,6 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { .attr('stroke', 'steelblue') .attr('stroke-width', 1) }; - public updateAxis(_axis, _value) { - - } public onResized() { this.createSVG(); @@ -363,21 +357,6 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { console.log( colors, n, dark); return colors; - - // const canvas = this.svg`${colors.map((c, i) => this.svg``)}`; - // const canvas = ''; - // const label = document.createElement("DIV"); - // label.textContent = name; - // label.style.position = "absolute"; - // label.style.top = "4px"; - // label.style.color = dark ? `#fff` : `#000`; - // canvas.onclick = () => { - // label.textContent = "Copied!"; - // navigator.clipboard.writeText(JSON.stringify(colors)); - // setTimeout(() => label.textContent = name, 2000); - // }; - // @ts-ignore - // return html`${canvas}${label}`; } public ngOnDestroy(): void { @@ -385,14 +364,3 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { } } - -interface TimeSeriesChartPoint { - unwrapped_phase: number - interferometric_correlation: number - temporal_coherence: number - date: string - file_name: string, - temporal_baseline: number - id: string -} - From 046fb013ed8d87df53183d9f38fd23d12360a13b Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Mon, 7 Oct 2024 15:37:53 -0700 Subject: [PATCH 08/23] WIP --- .../timeseries-chart-temporal-slider.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/components/timeseries-chart/timeseries-chart-temporal-slider/timeseries-chart-temporal-slider.component.html b/src/app/components/timeseries-chart/timeseries-chart-temporal-slider/timeseries-chart-temporal-slider.component.html index cad77d868..c18ec1bd2 100644 --- a/src/app/components/timeseries-chart/timeseries-chart-temporal-slider/timeseries-chart-temporal-slider.component.html +++ b/src/app/components/timeseries-chart/timeseries-chart-temporal-slider/timeseries-chart-temporal-slider.component.html @@ -1 +1 @@ -

    timeseries-chart-temporal-slider works!

    +

    Timeseries Date Slider Goes Here

    From 5fe4ed30842add593fa408d295e277b922c69bb5 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Tue, 8 Oct 2024 14:32:32 -0700 Subject: [PATCH 09/23] WIP --- .../timeseries-chart.component.ts | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.ts b/src/app/components/timeseries-chart/timeseries-chart.component.ts index ac8b2299c..7c146eb96 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.ts +++ b/src/app/components/timeseries-chart/timeseries-chart.component.ts @@ -140,6 +140,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { delete data[key] } } + for (let key of Object.keys(data).filter(x => x !== 'mean')) { this.dataSource.push({ 'unwrapped_phase': data[key].unwrapped_phase, @@ -161,7 +162,9 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { } private drawChart() { - const marginBottom = 40; + + // Determine scale extents + // const marginBottom = 40; const unwrapped_phases = this.dataSource.map(p => p['unwrapped_phase'] as number) const dates = this.dataSource.map(p => Date.parse(p['date'])).filter(d => !isNaN(d)) const inner_margins = 1.25 @@ -169,6 +172,8 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { const min_x = Math.min(...dates) const max_y = Math.max(...unwrapped_phases) * inner_margins const max_x = Math.max(...dates) + + // Create scales this.x = d3.scaleUtc() .domain([min_x, max_x]) .range([0, this.width]) @@ -180,7 +185,8 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { .range([this.height, 0]); this.yAxis = this.svg.append('g'); this.svg.append("g") - .attr("transform", `translate(0,${this.height - marginBottom})`) + // .attr("transform", `translate(0,${this.height - marginBottom})`) + .attr("transform", `translate(0,${this.height})`) this.clipContainer = this.svg.append('g') .attr('clip-path', 'url(#clip)'); @@ -192,12 +198,13 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { this.toolTip = toolTip this.toolTip.attr('transform', `translate(0, 0)`).style('text-anchor', 'middle').style('z-index', 100).style('opacity', 0) - const self = this; - + // Set up color scale const Observable10 = this.swatches(); console.log(Observable10); - this.lineGraph = this.clipContainer.append("path") + this.lineGraph = this.clipContainer.append("path"); + + const self = this; this.dots = this.clipContainer.append('g').selectAll('circle') .data(this.dataSource) @@ -229,7 +236,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { return 'timeseries-base'; } }) - .attr('r', 5) + .attr('r', 5); this.zoom = d3.zoom() .extent([[0, 0], [this.width, this.height]]) @@ -313,6 +320,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { this.toolTip.style('left', `${bounding.x + (a ? -150 : 20)}px`) .style('top', `${bounding.y - 10}px`); } + private addPairAttributes(ps) { return ps .attr('class', 'base-line') From 52b0d15991386790d54a395bdf22bf604715753e Mon Sep 17 00:00:00 2001 From: Kim Date: Wed, 16 Oct 2024 09:45:15 -0800 Subject: [PATCH 10/23] rtc link to rtc static uses local incidence angle url. Remove size display --- .../results-menu/scene-files/scene-files.component.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/components/results-menu/scene-files/scene-files.component.ts b/src/app/components/results-menu/scene-files/scene-files.component.ts index ad5f0d999..0d72d5d58 100644 --- a/src/app/components/results-menu/scene-files/scene-files.component.ts +++ b/src/app/components/results-menu/scene-files/scene-files.component.ts @@ -437,7 +437,13 @@ export class SceneFilesComponent implements OnInit, OnDestroy, AfterContentInit }; return this.asfApiService.query(queryParams).pipe( map(products => products?.results?.length > 0 ? this.productService.fromResponse(products).slice(0, 1) : []), - tap(products => products.map(product => product.productTypeDisplay = scene.metadata.productType + "-STATIC Layer")) + tap(products => products.map(product => { + product.productTypeDisplay = "Local Incidence Angle GeoTIFF"; + product.bytes = 0; + product.downloadUrl = product.metadata.opera.additionalUrls.find(url => url.endsWith('local_incidence_angle.tif')); + return product; + } + )) ); } else { return of([]); From acc3095b1d72f5c622b95da44974d3964577efd2 Mon Sep 17 00:00:00 2001 From: William Horn Date: Wed, 16 Oct 2024 11:06:54 -0800 Subject: [PATCH 11/23] fix: update angular cli in buildspec --- buildspec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildspec.yml b/buildspec.yml index 17d627cd3..f91506006 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -7,7 +7,7 @@ phases: commands: - n 18 - npm set progress=false - - npm install -g @angular/cli@17.2.7 + - npm install -g @angular/cli@17.3.10 pre_build: commands: - cp src/app/services/envs/env-${MATURITY}.ts src/app/services/env.ts From b1a7666bf01b6f31d8d07a0ef36bd18a85f13ea9 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Thu, 17 Oct 2024 15:11:41 -0700 Subject: [PATCH 12/23] WIP Before Adding Data Series --- .../timeseries-results-menu.component.html | 22 +-- .../timeseries-results-menu.component.ts | 123 ++++-------- .../timeseries-chart-voronoi.ts | 179 ++++++++++++++++++ .../timeseries-chart.component.ts | 23 ++- src/app/services/netcdf-service.service.ts | 7 +- 5 files changed, 243 insertions(+), 111 deletions(-) create mode 100644 src/app/components/timeseries-chart/timeseries-chart-voronoi.ts diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html index e3f87ace0..791074bbe 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html @@ -22,12 +22,12 @@ - {{task().name}} + {{task().aoi}} @@ -35,7 +35,7 @@
      @for (point of pointHistory; track $index) {
    • - place @@ -53,22 +53,6 @@ {{ 'NO_POINT_SELECTED' | translate }}
} - - - - - - - - - - - - - - - - diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts index 75a9c25ca..c34749fb0 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts @@ -15,13 +15,11 @@ import { SubSink } from 'subsink'; import { Point } from 'ol/geom'; import { WKT } from 'ol/format'; -import moment2 from 'moment'; -import { SetScenes } from '@store/scenes'; import { getPathRange } from '@store/filters'; export interface Task { - name: string; - completed: boolean; + aoi: string; + checked: boolean; subtasks?: Task[]; } @@ -88,6 +86,27 @@ export class TimeseriesResultsMenuComponent implements OnInit, OnDestroy { this.subs.add(this.pointHistoryService.history$.subscribe(history => { this.pointHistory = history; this.mapService.setDisplacementLayer(history); + console.log('results menu sub this.pointHistory', this.pointHistory); + const task = this.task(); + let found = false + for (const point of this.pointHistory) { + found = false; + for (const pt of task.subtasks) { + if (pt.aoi.toString() === point.flatCoordinates.toString()) { + found = true; + break; + } + } + if (!found) { + let p = {aoi: point.flatCoordinates, checked: true}; + task.subtasks.push(p); + } + } + + console.log('results menu sub task.subtasks', task.subtasks); + + return {...task}; + })); this.subs.add(this.drawService.polygon$.subscribe(polygon => { @@ -149,84 +168,17 @@ export class TimeseriesResultsMenuComponent implements OnInit, OnDestroy { public updateChart(geometry): void { this.netcdfService.getTimeSeries(geometry).pipe(first()).subscribe(data => { + console.log('updateChart data', data); + console.log('updateChart geometry', geometry); this.chartData.next(data); - // just going to use the data here to have some test - - let test_products = [] - for(let a of Object.keys(data)) { - if(a === 'mean') { - continue - } - let dummy_product = { - name: "20221107_20221213.unw.nc", - productTypeDisplay: "20221107_20221213.unw.nc", - file: "20221107_20221213.unw.nc", - id: "20221107_20221213.unw.nc", - downloadUrl: "", - bytes: 1234, - browses: [], - thumbnail: "string", - dataset: "sentinel-1", - groupId: "string", - isUnzippedFile: false, - isDummyProduct: false, - metadata: { - date: moment2(), - stopDate: moment2(), - polygon: "POLYGON ((-120.6596489990334 38.10046393341369, -120.7165475579197 38.10851198053945, -120.766930740861 38.11562044217759, -120.8205210213509 38.12315205210022, -120.8714495693995 38.13028813229113, -120.9237420515751 38.13758904376237, -120.9763848233747 38.14491322663075, -121.0284993874585 38.15213949038783, -121.0805374061872 38.15933042899581, -121.1317842372317 38.16638876359664, -121.1831324092139 38.17343685331883, -121.2343267090171 38.1804400907544, -121.2851343767767 38.18736716519965, -121.3356959243903 38.19423758535788, -121.3861081098637 38.20106467487116, -121.4362721727969 38.20783544395677, -121.48323466170885 38.21415300334824, -121.4961042842803 38.15636388218255, -121.5433137463578 38.16270254678292, -121.5911446754841 38.1691031129965, -121.6386899947014 38.17544523556456, -121.6861407154369 38.18175427917799, -121.7332794261246 38.18800202289999, -121.7803915044837 38.19422601057961, -121.827141292521 38.20038272861196, -121.8737037166488 38.20649520761842, -121.9200946535652 38.21256588219698, -121.9662943385527 38.21859236147657, -122.0122835841423 38.22457236130022, -122.0581361973249 38.23051573928061, -122.1041763492786 38.23646390681441, -122.149693424194 38.24232638029159, -122.1961235981019 38.24828575950047, -122.242840340764 38.25426186141181, -122.2851111656349 38.25965821461571, -122.3300033441712 38.2653676014464, -122.3758025278513 38.27117216227268, -122.4195396691845 38.27670031010642, -122.3858453485523 38.44296136955153, -122.3532454174394 38.60872264056508, -122.321281901071 38.77481263179438, -122.2870678391941 38.9402423639722, -122.28657198358258 38.94018057384403, -122.2484647545139 39.10551216594683, -122.2139845790114 39.27116104878576, -122.1797260176706 39.4367089374228, -122.1454462898122 39.60250573468526, -122.1112187045845 39.76830723022915, -122.0657227757032 39.76272908715357, -122.0199986201785 39.75710391072595, -121.974167995761 39.75144665647245, -121.9280106375743 39.74573006489359, -121.8819129486135 39.74000139035989, -121.8355618840318 39.73422190999039, -121.7893509902118 39.72844019721962, -121.7438269303752 39.72272426697831, -121.6969816389773 39.71682457472104, -121.6515073229837 39.71107635608378, -121.6043191954164 39.70509395348859, -121.5584565168173 39.69925815820748, -121.5109102827927 39.69319018010273, -121.4645931051444 39.68725740118437, -121.4191841855194 39.68142061388765, -121.3710837028612 39.67522101887367, -121.3249639873766 39.66925411189222, -121.2737070377029 39.66260665395009, -121.23414991223851 39.657450537553174, -121.2225423730193 39.71501508524592, -121.1765350243167 39.70900995464177, -121.1256787673412 39.70235510426308, -121.0761429466098 39.6958485542612, -121.0248065795119 39.68908396631235, -120.9731471040036 39.68225266837984, -120.9238122923641 39.67570292460091, -120.8690679290765 39.66841567043333, -120.8147668765373 39.66115958039808, -120.7685909543843 39.65495848719279, -120.7156528937689 39.64783419415447, -120.663007754518 39.64072322969391, -120.6113623558398 39.6337213126097, -120.5575229174151 39.62639828522865, -120.4998084040708 39.61852276683964, -120.4452699517613 39.61104894626836, -120.3863396198317 39.60294709422497, -120.3350203072667 39.59585767211257, -120.2794058786818 39.5881523754319, -120.2276117469398 39.58094649107327, -120.22744443645614 39.58092314818873, -120.2134545404021 39.63753782618391, -120.1722737074452 39.6317932200585, -120.1244336159495 39.62510726553644, -120.0702567931258 39.61751657755807, -120.022269227435 39.61076456269333, -119.9734628265665 39.60387622000747, -119.9205724742573 39.59639065119934, -119.8710716027977 39.58935798135493, -119.8176837356334 39.58175135017377, -119.7678667295637 39.57462631850627, -119.7172666919774 39.56736632596481, -119.6677829890141 39.56024234859523, -119.6164294368659 39.55282685903347, -119.5655855530352 39.54546030402012, -119.5122825240406 39.53771380091477, -119.4596714762434 39.53004121358733, -119.4118356441431 39.52303826133494, -119.3539548115401 39.51454620335684, -119.2999598520621 39.50659276685604, -119.242172282983 39.49805375475951, -119.1867112941332 39.48982722325655, -119.2279582300632 39.32389259181299, -119.2695651047809 39.15814430461985, -119.3154157605841 38.99290396440068, -119.3553955782568 38.82692456194625, -119.4076391719693 38.66278010421749, -119.46426202130762 38.48267405863559, -119.4994803127931 38.33275776186966, -119.5473964124392 38.1679932576986, -119.5759619696445 38.00032674732519, -119.6328594358995 38.00892055228446, -119.685940538886 38.01691396436385, -119.735510021753 38.02435806698762, -119.7876843769492 38.0321663403309, -119.8349767585424 38.03922663419335, -119.8827140678868 38.04633197874039, -119.9336830819589 38.05389196505576, -119.9837372437618 38.06129369064131, -120.029196677421 38.0680003062205, -120.0790441003354 38.07532784287181, -120.1269111066452 38.08234457142717, -120.1767641224129 38.08962794955193, -120.2211977375846 38.09610549717873, -120.2696883291999 38.10314938009251, -120.3131576383198 38.10945036625376, -120.3570069870991 38.11578848698885, -120.4046282389668 38.12264764067351, -120.4517936234199 38.12942103705984, -120.48468630063608 38.134130553754865, -120.4964144795629 38.07720256883281, -120.5521610008301 38.08517268978709, -120.6049996926634 38.09270374285773, -120.6596489990334 38.10046393341369))", - productType: "", - beamMode: "", - polarization: "", - flightDirection: null, - path: 1, - frame: 1, - absoluteOrbit: [1], - stackSize: 1, - faradayRotation: null, - offNadirAngle: null, - instrument: null, - pointingAngle: null, - missionName: null, - flightLine: null, - perpendicular: null, - temporal: null, - canInSAR: false, - burst: null, - opera: null, - fileName: null, - job:null, - pgeVersion: null, - subproducts: [], - parentID: "", - ariaVersion: null, - } - } - let response_file = data[a]; - dummy_product.name = a - dummy_product.productTypeDisplay = a - dummy_product.id = a - dummy_product.file = a - dummy_product.groupId = a - dummy_product.downloadUrl = response_file.uri - dummy_product.metadata.date = moment2(response_file.time) - test_products.push(dummy_product) - } - this.store$.dispatch(new SetScenes({ - products: test_products, - searchType: SearchType.DISPLACEMENT - })) - + console.log('updateChart this.chartData', this.chartData); }) } readonly task = signal({ - name: 'ALL POINTS', - completed: false, - subtasks: [ - {name: 'Child task 1', completed: false}, - {name: 'Child task 2', completed: false}, - {name: 'Child task 3', completed: false}, - ], + aoi: 'ALL AOIs', + checked: false, + subtasks: [], }); readonly partiallyComplete = computed(() => { @@ -234,24 +186,29 @@ export class TimeseriesResultsMenuComponent implements OnInit, OnDestroy { if (!task.subtasks) { return false; } - return task.subtasks.some(t => t.completed) && !task.subtasks.every(t => t.completed); + return task.subtasks.some(t => t.checked) && !task.subtasks.every(t => t.checked); }); - public updateSeries(completed: boolean, index?: number) { + public updateSeries(checked: boolean, index?: number) { + console.log('updateSeries', checked, index); this.task.update(task => { if (index === undefined) { - task.completed = completed; - task.subtasks?.forEach(t => (t.completed = completed)); + task.checked = checked; + task.subtasks?.forEach(t => (t.checked = checked)); } else { - task.subtasks![index].completed = completed; - task.completed = task.subtasks?.every(t => t.completed) ?? true; + task.subtasks![index].checked = checked; + task.checked = task.subtasks?.every(t => t.checked) ?? true; this.pointHistoryService.selectedPoint = index; + console.log('updateSeries() this.pointHistoryService.selectedPoint', this.pointHistoryService.selectedPoint); this.pointHistoryService.passDraw = true; let format = new WKT(); let wktRepresentation = format.writeGeometry(this.pointHistory[index]); this.mapService.loadPolygonFrom(wktRepresentation.toString()) } + console.log('updateSeries() task', task); + console.log('updateSeries() task.subtasks', task.subtasks); + console.log('updateSeries() this.pointHistory', this.pointHistory); return {...task}; }); } diff --git a/src/app/components/timeseries-chart/timeseries-chart-voronoi.ts b/src/app/components/timeseries-chart/timeseries-chart-voronoi.ts new file mode 100644 index 000000000..321d7252b --- /dev/null +++ b/src/app/components/timeseries-chart/timeseries-chart-voronoi.ts @@ -0,0 +1,179 @@ +import {Component, ElementRef, OnDestroy, OnInit, ViewChild} from '@angular/core'; +import { HttpClient } from '@angular/common/http'; + + +import * as d3 from 'd3'; + +@Component({ + selector: 'app-timeseries-chart', + templateUrl: './timeseries-chart.component.html', + styleUrl: './timeseries-chart.component.scss' +}) +export class TimeseriesChartComponent implements OnInit, OnDestroy { + @ViewChild('timeseriesChart', {static: true}) timeseriesChart: ElementRef; + public url: string = '/assets/unemployment.json'; + public unemploymentData: any; + public svg?: d3.Selection; + public showVoronoi = false; + + + constructor(private http: HttpClient) { + } + + public ngOnInit(): void { + this.http.get(this.url).subscribe(res => { + this.unemploymentData = res; + console.log('this.unemploymentData',this.unemploymentData); + this.makeChartFromFile(); + }); + } + + public makeChartFromFile() { + this.makeChart(d3, this.unemploymentData, this.showVoronoi); + } + + public toggleVoronoi() { + this.showVoronoi = !this.showVoronoi; + this.makeChartFromFile(); + } + + public makeChart(d3,unemployment,voronoi){ + console.log('***** makeChart *****'); + console.log('d3', d3); + console.log('unemployment', unemployment); + console.log('voronoi', voronoi); + + if (this.svg) { + d3.selectAll('#timeseries-chart > svg').remove(); + d3.selectAll('.tooltip').remove(); + } + + const element = document.getElementById("timeseriesChart"); + element.innerHTML = ''; + // Specify the chart’s dimensions. + const width = 928; + const height = 600; + const marginTop = 20; + const marginRight = 20; + const marginBottom = 30; + const marginLeft = 30; + + // Create the positional scales. + const x = d3.scaleUtc() + .domain(d3.extent(unemployment, d => new Date(d.date))) + .range([marginLeft, width - marginRight]); + + const y = d3.scaleLinear() + .domain([0, d3.max(unemployment, d => d.unemployment)]).nice() + .range([height - marginBottom, marginTop]); + + // Create the SVG container. + this.svg = d3.select("#timeseriesChart").append("svg") + .attr("width", width) + .attr("height", height) + .attr("viewBox", [0, 0, width, height]) + .attr("style", "max-width: 100%; height: auto; overflow: visible; font: 10px sans-serif;"); + + // Add the horizontal axis. + this.svg.append("g") + .attr("transform", `translate(0,${height - marginBottom})`) + .call(d3.axisBottom(x).ticks(width / 80).tickSizeOuter(0)); + + // Add the vertical axis. + this.svg.append("g") + .attr("transform", `translate(${marginLeft},0)`) + .call(d3.axisLeft(y)) + .call(g => g.select(".domain").remove()) + .call(voronoi ? () => {} : g => g.selectAll(".tick line").clone() + .attr("x2", width - marginLeft - marginRight) + .attr("stroke-opacity", 0.1)) + .call(g => g.append("text") + .attr("x", -marginLeft) + .attr("y", 10) + .attr("fill", "currentColor") + .attr("text-anchor", "start") + .text("↑ Unemployment (%)")); + + + // Compute the points in pixel space as [x, y, z], where z is the name of the series. + const points = unemployment.map((d) => [x(new Date(d.date)), y(d.unemployment), d.division]); + console.log('points', points); + console.log('unemployment', unemployment); + + // An optional Voronoi display (for fun). + if (voronoi) this.svg.append("path") + .attr("fill", "none") + .attr("stroke", "#ccc") + .attr("d", d3.Delaunay + .from(points) + .voronoi([0, 0, width, height]) + .render()); + + // Group the points by series. + const groups = d3.rollup(points, v => Object.assign(v, {z: v[0][2]}), d => d[2]); + console.log('groups', groups); + + // Draw the lines. + const line = d3.line(); + const path = this.svg.append("g") + .attr("fill", "none") + .attr("stroke", "steelblue") + .attr("stroke-width", 1.5) + .attr("stroke-linejoin", "round") + .attr("stroke-linecap", "round") + .selectAll("path") + .data(groups.values()) + .join("path") + .style("mix-blend-mode", "multiply") + .attr("d", line); + + // Add an invisible layer for the interactive tip. + const dot = this.svg.append("g") + .attr("display", "none"); + + dot.append("circle") + .attr("r", 2.5); + + dot.append("text") + .attr("text-anchor", "middle") + .attr("y", -8); + + this.svg + .on("pointerenter", pointerEntered) + .on("pointermove", pointerMoved) + .on("pointerleave", pointerLeft) + .on("touchstart", event => event.preventDefault()); + + return; + + // When the pointer moves, find the closest point, update the interactive tip, and highlight + // the corresponding line. Note: we don't actually use Voronoi here, since an exhaustive search + // is fast enough. + function pointerMoved(event) { + const [xm, ym] = d3.pointer(event); + const i = d3.leastIndex(points, ([x, y]) => Math.hypot(x - xm, y - ym)); + const [x, y, k] = points[i]; + path.style("stroke", ({z}) => z === k ? null : "#ddd").filter(({z}) => z === k).raise(); + dot.attr("transform", `translate(${x},${y})`); + dot.select("text").text(k); + // this.svg.property("value", unemployment[i]).dispatch("input", {bubbles: true}); + } + + function pointerEntered() { + path.style("mix-blend-mode", null).style("stroke", "#ddd"); + dot.attr("display", null); + } + + function pointerLeft() { + path.style("mix-blend-mode", "multiply").style("stroke", null); + dot.attr("display", "none"); + // this.svg.node().value = null; + // this.svg.dispatch("input", {bubbles: true}); + } + + } + + ngOnDestroy() { + // this.subs.unsubscribe(); + } +} diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.ts b/src/app/components/timeseries-chart/timeseries-chart.component.ts index 7c146eb96..b6c673250 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.ts +++ b/src/app/components/timeseries-chart/timeseries-chart.component.ts @@ -140,8 +140,11 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { delete data[key] } } - - for (let key of Object.keys(data).filter(x => x !== 'mean')) { + console.log('****** timeseries-chart init data *******', data); + for (let key of Object.keys(data).filter(x => x !== 'mean' && x !== 'aoi')) { + console.log('timeseries-chart init key', key); + console.log('timeseries-chart init data', data); + console.log('timeseries-chart init data[key]', data[key]); this.dataSource.push({ 'unwrapped_phase': data[key].unwrapped_phase, 'interferometric_correlation': data[key].interferometric_correlation, @@ -206,8 +209,16 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { const self = this; - this.dots = this.clipContainer.append('g').selectAll('circle') + console.log('dataSource', this.dataSource); + const points = this.dataSource.map((d) => [this.x(new Date(d.date)), this.y(d.unwrapped_phase), d.id]); + console.log('points', points); + const groups = d3.rollup(points, v => Object.assign(v, {z: v[0][2]}), d => d[2]); + console.log('groups', groups); + + this.dots = this.clipContainer.append('g') + .selectAll('circle') .data(this.dataSource) + // .data(groups.values()) .enter() .append('circle') .attr('cx', (d: TimeSeriesChartPoint) => this.x(Date.parse(d.date))) @@ -367,10 +378,8 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { public swatches() { const colors = d3.schemeCategory10 - const n = colors.length; - const dark = d3.lab(colors[0]).l < 50; - - console.log( colors, n, dark); + // const n = colors.length; + // const dark = d3.lab(colors[0]).l < 50; return colors; } diff --git a/src/app/services/netcdf-service.service.ts b/src/app/services/netcdf-service.service.ts index de37a6317..60bb9b32d 100644 --- a/src/app/services/netcdf-service.service.ts +++ b/src/app/services/netcdf-service.service.ts @@ -74,6 +74,7 @@ export class NetcdfService { let index_id = wktRepresenation; console.log(`getting ${index_id}`) if(this.cache.hasOwnProperty(index_id)) { + console.log('cache hit', of(this.cache[index_id])); return of(this.cache[index_id]) } else { return this.http.post(`${this.url}${this.timeSeriesEndpoint}`, { @@ -82,16 +83,18 @@ export class NetcdfService { }, { responseType: 'json' }).pipe( first(), map( response => { + (response as any).aoi = wktRepresenation; this.cache[index_id] = response; - this.totalKeys.push(index_id) + this.totalKeys.push(index_id); if(this.totalKeys.length > this.maxCacheSize) { let deleted = this.totalKeys.splice(0); delete this.cache[deleted[0]]; } + console.log('cache miss', response); return response } )) } } -} \ No newline at end of file +} From ba2f3687e932900c682c44f73adb5b3d678dabcd Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Thu, 17 Oct 2024 15:43:24 -0700 Subject: [PATCH 13/23] WIP Charting series, but not really --- .../timeseries-results-menu.component.ts | 20 +++++--- .../timeseries-chart.component.ts | 51 +++++++++++-------- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts index c34749fb0..cb00b5246 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.ts @@ -117,7 +117,7 @@ export class TimeseriesResultsMenuComponent implements OnInit, OnDestroy { this.pointHistoryService.addPoint(temp); // this.selectedPoint = temp; } - this.updateChart(temp); + this.updateChart(); } })) @@ -166,13 +166,17 @@ export class TimeseriesResultsMenuComponent implements OnInit, OnDestroy { this.mapService.loadPolygonFrom(wktRepresenation.toString()) } - public updateChart(geometry): void { - this.netcdfService.getTimeSeries(geometry).pipe(first()).subscribe(data => { - console.log('updateChart data', data); - console.log('updateChart geometry', geometry); - this.chartData.next(data); - console.log('updateChart this.chartData', this.chartData); - }) + public updateChart(): void { + let allPointsData = []; + for (const geometry of this.pointHistory) { + this.netcdfService.getTimeSeries(geometry).pipe(first()).subscribe(data => { + console.log('updateChart data', data); + console.log('updateChart geometry', geometry); + allPointsData.push(data); + }) + console.log('updateChart allPointsData', allPointsData); + this.chartData.next(allPointsData); + } } readonly task = signal({ diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.ts b/src/app/components/timeseries-chart/timeseries-chart.component.ts index b6c673250..8f1da1dcc 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.ts +++ b/src/app/components/timeseries-chart/timeseries-chart.component.ts @@ -11,6 +11,7 @@ import { SubSink } from 'subsink'; import { AsfLanguageService } from "@services/asf-language.service"; interface TimeSeriesChartPoint { + aoi: string unwrapped_phase: number interferometric_correlation: number temporal_coherence: number @@ -131,29 +132,37 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { } public initChart(data): void { + console.log('****** timeseries-chart init data *******', data); this.dataSource = [] - - // pre-process data, remove test v_2 files from results - // won't be necessary in production - for (let key of Object.keys(data)) { - if (key.startsWith('v_2_')) { - delete data[key] - } - } + let aoi: string = ''; console.log('****** timeseries-chart init data *******', data); - for (let key of Object.keys(data).filter(x => x !== 'mean' && x !== 'aoi')) { - console.log('timeseries-chart init key', key); - console.log('timeseries-chart init data', data); - console.log('timeseries-chart init data[key]', data[key]); - this.dataSource.push({ - 'unwrapped_phase': data[key].unwrapped_phase, - 'interferometric_correlation': data[key].interferometric_correlation, - 'temporal_coherence': data[key].temporal_coherence, - 'date': data[key].secondary_datetime, - 'file_name': data[key].source_file_name, - 'id': key, - 'temporal_baseline': data[key].temporal_baseline - }) + for (let result of data) { + aoi = ''; + // pre-process data, remove test v_2 files from results + // won't be necessary in production + for (let key of Object.keys(result)) { + if (key.startsWith('v_2_')) { + delete result[key]; + } + if (key.startsWith('aoi')) { + aoi = result[key]; + } + } + for (let key of Object.keys(result).filter(x => x !== 'mean' && x !== 'aoi')) { + console.log('timeseries-chart init key', key); + console.log('timeseries-chart init result', result); + console.log('timeseries-chart init result[key]', result[key]); + this.dataSource.push({ + 'aoi': aoi, + 'unwrapped_phase': result[key].unwrapped_phase, + 'interferometric_correlation': result[key].interferometric_correlation, + 'temporal_coherence': result[key].temporal_coherence, + 'date': result[key].secondary_datetime, + 'file_name': result[key].source_file_name, + 'id': key, + 'temporal_baseline': result[key].temporal_baseline + }) + } } this.averageData = ({ ...data.mean From bd277afcaa0638f93b7eadcf77a49434ffdd1727 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 18 Oct 2024 11:34:30 -0700 Subject: [PATCH 14/23] WIP Changing to accept DataReady --- .../timeseries-chart.component.ts | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.ts b/src/app/components/timeseries-chart/timeseries-chart.component.ts index 8f1da1dcc..7eb1528ed 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.ts +++ b/src/app/components/timeseries-chart/timeseries-chart.component.ts @@ -21,6 +21,16 @@ interface TimeSeriesChartPoint { id: string } +interface TimeSeriesData { + unwrapped_phase: number + date: string +} + +interface DataReady { + name: string, + values: TimeSeriesData[] +} + @Component({ selector: 'app-timeseries-chart', templateUrl: './timeseries-chart.component.html', @@ -37,6 +47,8 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { public json_data: string = ''; private svg?: d3.Selection; public dataSource: TimeSeriesChartPoint[] = []; + public dataReadyForChart: DataReady[] = []; + public timeSeriesData: TimeSeriesData[] = []; public averageData = {}; public displayedColumns: string[] = ['position', 'unwrapped_phase', 'interferometric_correlation', 'temporal_coherence'] private currentTransform: d3.ZoomTransform; @@ -50,6 +62,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { private y: d3.ScaleLinear; public xAxis: d3.Selection; private yAxis: d3.Selection; + // private dots: d3.Selection; private dots: d3.Selection; private lineGraph: d3.Selection; private toolTip: d3.Selection @@ -148,6 +161,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { aoi = result[key]; } } + this.timeSeriesData = []; for (let key of Object.keys(result).filter(x => x !== 'mean' && x !== 'aoi')) { console.log('timeseries-chart init key', key); console.log('timeseries-chart init result', result); @@ -162,8 +176,15 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { 'id': key, 'temporal_baseline': result[key].temporal_baseline }) + this.timeSeriesData.push({ + 'unwrapped_phase': result[key].unwrapped_phase, + 'date': result[key].secondary_datetime + }); } + this.dataReadyForChart.push({ 'name': aoi, 'values': this.timeSeriesData }); + } + console.log('timeseries-chart init dataReadyForChart', this.dataReadyForChart); this.averageData = ({ ...data.mean }) @@ -219,7 +240,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { const self = this; console.log('dataSource', this.dataSource); - const points = this.dataSource.map((d) => [this.x(new Date(d.date)), this.y(d.unwrapped_phase), d.id]); + const points = this.dataSource.map((d) => [this.x(new Date(d.date)), this.y(d.unwrapped_phase), d.aoi]); console.log('points', points); const groups = d3.rollup(points, v => Object.assign(v, {z: v[0][2]}), d => d[2]); console.log('groups', groups); @@ -227,6 +248,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { this.dots = this.clipContainer.append('g') .selectAll('circle') .data(this.dataSource) + // .data(this.dataReadyForChart) // .data(groups.values()) .enter() .append('circle') From f0a9980480db94b16c4895b620dc35815ceae8b3 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 18 Oct 2024 13:08:34 -0700 Subject: [PATCH 15/23] WIP Point colors represent different series The lines are still one color and not quite right. --- .../timeseries-chart.component.ts | 89 +++++++++++-------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.ts b/src/app/components/timeseries-chart/timeseries-chart.component.ts index 7eb1528ed..4389be311 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.ts +++ b/src/app/components/timeseries-chart/timeseries-chart.component.ts @@ -5,7 +5,7 @@ import { Observable, Subject } from 'rxjs'; import { Store } from '@ngrx/store'; import { AppState } from '@store'; -import * as sceneStore from '@store/scenes'; +// import * as sceneStore from '@store/scenes'; import * as chartsStore from '@store/charts'; import { SubSink } from 'subsink'; import { AsfLanguageService } from "@services/asf-language.service"; @@ -62,15 +62,15 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { private y: d3.ScaleLinear; public xAxis: d3.Selection; private yAxis: d3.Selection; - // private dots: d3.Selection; - private dots: d3.Selection; + private dots: d3.Selection; + // private dots: d3.Selection; private lineGraph: d3.Selection; private toolTip: d3.Selection public margin = { top: 10, right: 20, bottom: 60, left: 55 }; private thing: d3.Selection private hoveredElement; - private selectedScene: string; + // private selectedScene: string; private showLines = true; private xAxisTitle = ''; private yAxisTitle = ''; @@ -91,13 +91,13 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { this.initChart(data); }) - this.subs.add( - this.store$.select(sceneStore.getSelectedScene).subscribe(test => { - this.selectedScene = test.id; - this.updateChart(); - - }) - ); + // this.subs.add( + // this.store$.select(sceneStore.getSelectedScene).subscribe(test => { + // this.selectedScene = test.id; + // this.updateChart(); + // + // }) + // ); this.subs.add( this.store$.select(chartsStore.getShowLines).subscribe( @@ -231,9 +231,14 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { this.toolTip = toolTip this.toolTip.attr('transform', `translate(0, 0)`).style('text-anchor', 'middle').style('z-index', 100).style('opacity', 0) + const allGroup = [...new Set(this.dataReadyForChart.map(d => d.name))]; + console.log('allGroup', allGroup); + // Set up color scale - const Observable10 = this.swatches(); - console.log(Observable10); + // A color scale: one color for each group + const colorPalette = d3.scaleOrdinal() + .domain(allGroup) + .range(d3.schemeSet2); this.lineGraph = this.clipContainer.append("path"); @@ -246,17 +251,23 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { console.log('groups', groups); this.dots = this.clipContainer.append('g') + .selectAll("myDots") + .data(this.dataReadyForChart) + .enter() + .append('g') + // @ts-ignore + .style("fill", function (d: DataReady){ return colorPalette(d.name) }) .selectAll('circle') - .data(this.dataSource) - // .data(this.dataReadyForChart) + .data(d => d.values) + // .data(this.dataSource) // .data(groups.values()) .enter() .append('circle') - .attr('cx', (d: TimeSeriesChartPoint) => this.x(Date.parse(d.date))) - .attr('cy', (d: TimeSeriesChartPoint) => this.y(d.unwrapped_phase)) - .on('mouseover', function (_event: any, p: TimeSeriesChartPoint) { + .attr('cx', (d) => this.x(Date.parse(d.date))) + .attr('cy', (d) => this.y(d.unwrapped_phase)) + .on('mouseover', function (_event: any, p: TimeSeriesData) { self.hoveredElement = this; - const date = new Date(p.date) + const date = new Date(p.date); toolTip.interrupt(); toolTip .style('opacity', .9); @@ -268,16 +279,16 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { .duration(500) .style('opacity', 0); }) - .on('click', (_event, d) => { - this.store$.dispatch(new sceneStore.SetSelectedScene(d.id)) - }) - .attr('class', (d) => { - if (this.selectedScene === d.id) { - return 'timeseries-selected'; - } else { - return 'timeseries-base'; - } - }) + // .on('click', (_event, d) => { + // this.store$.dispatch(new sceneStore.SetSelectedScene(d.id)) + // }) + // .attr('class', (d) => { + // if (this.selectedScene === d.id) { + // return 'timeseries-selected'; + // } else { + // return 'timeseries-base'; + // } + // }) .attr('r', 5); this.zoom = d3.zoom() @@ -336,16 +347,16 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { this.dots .attr('cx', d => newX(Date.parse(d.date))) .attr('cy', d => newY(d.unwrapped_phase)) - .attr('class', (d) => { - if (this.selectedScene === d.id) { - return 'timeseries-selected'; - } else { - return 'timeseries-base'; - } - }) - .on('click', (_event, d) => { - this.store$.dispatch(new sceneStore.SetSelectedScene(d.id)) - }) + // .attr('class', (d) => { + // if (this.selectedScene === d.id) { + // return 'timeseries-selected'; + // } else { + // return 'timeseries-base'; + // } + // }) + // .on('click', (_event, d) => { + // this.store$.dispatch(new sceneStore.SetSelectedScene(d.id)) + // }) if (this.showLines) { this.addPairAttributes( From bdb7e042184e56691d809168e7d91be4a27e8f4e Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 18 Oct 2024 14:14:29 -0700 Subject: [PATCH 16/23] WIP B-4 New Line Logic --- .../timeseries-chart/timeseries-chart.component.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.ts b/src/app/components/timeseries-chart/timeseries-chart.component.ts index 4389be311..df254a9b2 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.ts +++ b/src/app/components/timeseries-chart/timeseries-chart.component.ts @@ -9,6 +9,7 @@ import { AppState } from '@store'; import * as chartsStore from '@store/charts'; import { SubSink } from 'subsink'; import { AsfLanguageService } from "@services/asf-language.service"; +// import {line} from 'd3'; interface TimeSeriesChartPoint { aoi: string @@ -339,7 +340,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { .ticks(smallChart ? 10 : 5, 's') ); - var lineFunction = d3.line() + var lineFunction = d3.line() .x(function (d) { return newX(Date.parse(d.date)); }) .y(function (d) { return newY(d.unwrapped_phase); }) @@ -361,8 +362,12 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { if (this.showLines) { this.addPairAttributes( this.lineGraph - .attr('d', _ => lineFunction(this.dataSource)) - .attr('fill', 'none') + // .data(this.dataReadyForChart) + .join("path") + // .attr("d", d => line(d.values)) + // .attr("stroke", d => (d.name)) + .attr('d', _ => lineFunction(this.dataReadyForChart.flatMap(d => d.values))) + .attr('fill', 'none') ) } } From d27b509da4e49690f7bfbfc0e66132251d15fb00 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 18 Oct 2024 15:22:01 -0700 Subject: [PATCH 17/23] WIP Series showing with colors --- .../timeseries-chart.component.ts | 81 ++++++++++++------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.ts b/src/app/components/timeseries-chart/timeseries-chart.component.ts index df254a9b2..0c76927bc 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.ts +++ b/src/app/components/timeseries-chart/timeseries-chart.component.ts @@ -9,7 +9,6 @@ import { AppState } from '@store'; import * as chartsStore from '@store/charts'; import { SubSink } from 'subsink'; import { AsfLanguageService } from "@services/asf-language.service"; -// import {line} from 'd3'; interface TimeSeriesChartPoint { aoi: string @@ -77,6 +76,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { private yAxisTitle = ''; private subs = new SubSink(); + private allGroup: string[]; constructor( private store$: Store, @@ -232,16 +232,15 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { this.toolTip = toolTip this.toolTip.attr('transform', `translate(0, 0)`).style('text-anchor', 'middle').style('z-index', 100).style('opacity', 0) - const allGroup = [...new Set(this.dataReadyForChart.map(d => d.name))]; - console.log('allGroup', allGroup); + this.allGroup = [...new Set(this.dataReadyForChart.map(d => d.name))]; + console.log('allGroup', this.allGroup); + + this.lineGraph = this.clipContainer.append("path"); - // Set up color scale // A color scale: one color for each group const colorPalette = d3.scaleOrdinal() - .domain(allGroup) - .range(d3.schemeSet2); - - this.lineGraph = this.clipContainer.append("path"); + .domain(this.allGroup) + .range(d3.schemeSet2); const self = this; @@ -340,9 +339,9 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { .ticks(smallChart ? 10 : 5, 's') ); - var lineFunction = d3.line() - .x(function (d) { return newX(Date.parse(d.date)); }) - .y(function (d) { return newY(d.unwrapped_phase); }) + // var lineFunction = d3.line() + // .x(function (d) { return newX(Date.parse(d.date)); }) + // .y(function (d) { return newY(d.unwrapped_phase); }) this.dots @@ -360,15 +359,36 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { // }) if (this.showLines) { - this.addPairAttributes( - this.lineGraph - // .data(this.dataReadyForChart) - .join("path") - // .attr("d", d => line(d.values)) - // .attr("stroke", d => (d.name)) - .attr('d', _ => lineFunction(this.dataReadyForChart.flatMap(d => d.values))) - .attr('fill', 'none') - ) + // this.addPairAttributes( + // this.lineGraph + // // .data(this.dataReadyForChart) + // .join("path") + // // .attr("d", d => line(d.values)) + // // .attr("stroke", d => (d.name)) + // .attr('d', _ => lineFunction(this.dataReadyForChart.flatMap(d => d.values))) + // .attr('fill', 'none') + // ) + + // A color scale: one color for each group + const colorPalette = d3.scaleOrdinal() + .domain(this.allGroup) + .range(d3.schemeSet2); + + // Add the lines + let line = d3.line() + .x(function (d) { return newX(Date.parse(d.date)); }) + .y(function (d) { return newY(d.unwrapped_phase); }) + this.svg.selectAll("myLines") + .data(this.dataReadyForChart) + .enter() + .append("path") + .attr("d", function(d){ // @ts-ignore + return line(d.values) } ) + // @ts-ignore + .attr("stroke", function (d: DataReady){ return colorPalette(d.name) }) + .style("stroke-width", 2) + .style("fill", "none") + } } @@ -379,12 +399,12 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { .style('top', `${bounding.y - 10}px`); } - private addPairAttributes(ps) { - return ps - .attr('class', 'base-line') - .attr('stroke', 'steelblue') - .attr('stroke-width', 1) - }; + // private addPairAttributes(ps) { + // return ps + // .attr('class', 'base-line') + // .attr('stroke', 'steelblue') + // .attr('stroke-width', 1) + // }; public onResized() { this.createSVG(); @@ -423,12 +443,11 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { return join(date, dateFormat, ' '); } - public swatches() { - const colors = d3.schemeCategory10 - // const n = colors.length; - // const dark = d3.lab(colors[0]).l < 50; + public swatches(d: any) { + return d3.scaleOrdinal() + .domain(d) + .range(d3.schemeCategory10); - return colors; } public ngOnDestroy(): void { From 323e62162ee2aa03cce29ea5a35cc59ac6a79cc1 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 18 Oct 2024 15:44:52 -0700 Subject: [PATCH 18/23] WIP --- .../timeseries-chart.component.ts | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.ts b/src/app/components/timeseries-chart/timeseries-chart.component.ts index 0c76927bc..d4d357084 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.ts +++ b/src/app/components/timeseries-chart/timeseries-chart.component.ts @@ -322,6 +322,40 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { .attr('class', 'ts-chart-label') .text(this.yAxisTitle); + // this.svg + // .on("pointerenter", pointerentered) + // .on("pointermove", pointermoved) + // .on("pointerleave", pointerleft) + // .on("touchstart", event => event.preventDefault()); + // + // // When the pointer moves, find the closest point, update the interactive tip, and highlight + // // the corresponding line. Note: we don't actually use Voronoi here, since an exhaustive search + // // is fast enough. + // function pointermoved(event) { + // const [xm, ym] = d3.pointer(event); + // // @ts-ignore + // const i = d3.leastIndex(points, ([x, y]) => Math.hypot(x - xm, y - ym)); + // const [x, y, k] = points[i]; + // this.path.style("stroke", ({z}) => z === k ? null : "#ddd").filter(({z}) => z === k).raise(); + // this.dot.attr("transform", `translate(${x},${y})`); + // this.dot.select("text").text(k); + // // @ts-ignore + // self.svg.property("value", self.dataReadyForChart[i]).dispatch("input", {bubbles: true}); + // } + // + // function pointerentered() { + // this.path.style("mix-blend-mode", null).style("stroke", "#ddd"); + // this.dot.attr("display", null); + // } + // + // function pointerleft() { + // this.path.style("mix-blend-mode", "multiply").style("stroke", null); + // this.dot.attr("display", "none"); + // this.svg.node().value = null; + // // @ts-ignore + // self.svg.dispatch("input", {bubbles: true}); + // } + this.updateChart(); } From 2a5913544ec37824c5746d2221c79337723c3318 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 18 Oct 2024 18:40:37 -0700 Subject: [PATCH 19/23] WIP Show Lines works better --- .../components/timeseries-chart/timeseries-chart.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.ts b/src/app/components/timeseries-chart/timeseries-chart.component.ts index d4d357084..7a36cd19c 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.ts +++ b/src/app/components/timeseries-chart/timeseries-chart.component.ts @@ -69,6 +69,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { public margin = { top: 10, right: 20, bottom: 60, left: 55 }; private thing: d3.Selection private hoveredElement; + private data: any; // private selectedScene: string; private showLines = true; @@ -89,6 +90,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { this.createSVG(); this.chartData.subscribe(data => { + this.data = data; this.initChart(data); }) @@ -109,7 +111,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { } else { this.lineGraph.remove() } - this.updateChart(); + this.initChart(this.data); } ) ) From 693922efc23e077650fb76dd73ca3f7e0f1fdda2 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 18 Oct 2024 18:59:33 -0700 Subject: [PATCH 20/23] WIP Zoom broken but better --- .../timeseries-chart/timeseries-chart.component.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.ts b/src/app/components/timeseries-chart/timeseries-chart.component.ts index 7a36cd19c..f3df0fe77 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.ts +++ b/src/app/components/timeseries-chart/timeseries-chart.component.ts @@ -137,14 +137,17 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { public onZoomIn(): void { this.thing.transition().call(this.zoom.scaleBy, 2); + this.drawChart(); } public onZoomOut(): void { this.thing.transition().call(this.zoom.scaleBy, .5); + this.drawChart(); } public onZoomToFit(): void { this.thing.transition().call(this.zoom.transform, d3.zoomIdentity); + this.drawChart(); } public initChart(data): void { @@ -297,7 +300,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { .extent([[0, 0], [this.width, this.height]]) .on('zoom', (eve: d3.D3ZoomEvent) => { this.currentTransform = eve.transform; - this.updateChart(); + this.initChart(this.data); }); this.thing = d3.select('#timeseriesChart').selectChild() this.thing.call(this.zoom) From 1c99b70b89dc0028df16469127db2758738555c5 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Sat, 19 Oct 2024 13:19:36 -0700 Subject: [PATCH 21/23] WIP Zoom fixed --- .../components/timeseries-chart/timeseries-chart.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/components/timeseries-chart/timeseries-chart.component.ts b/src/app/components/timeseries-chart/timeseries-chart.component.ts index f3df0fe77..1f447a463 100644 --- a/src/app/components/timeseries-chart/timeseries-chart.component.ts +++ b/src/app/components/timeseries-chart/timeseries-chart.component.ts @@ -421,6 +421,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy { .data(this.dataReadyForChart) .enter() .append("path") + .attr('clip-path', 'url(#clip)') .attr("d", function(d){ // @ts-ignore return line(d.values) } ) // @ts-ignore From 09de9d71389528bf9ac9e19630f13d6fcbce8473 Mon Sep 17 00:00:00 2001 From: ASF Discovery Machine User <60239462+ASF-Discovery@users.noreply.github.com> Date: Sat, 19 Oct 2024 12:33:59 -0800 Subject: [PATCH 22/23] Updated translations from Phrase phrase: update src/assets/i18n/en.json to latest state phrase: update src/assets/i18n/es.json to latest state phrase: update src/assets/i18n/de.json to latest state --- src/assets/i18n/en.json | 2 +- src/assets/i18n/es.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 41e0a11cb..85234e963 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -739,7 +739,7 @@ "SETTINGS_OVERSCAN": "settings_overscan", "SHARE_SEARCH": "Share Search", "SHARE_WITH_EMAIL": "Share With Email", - "SHORTWAVE_DISPLACEMENT": "Shortwave Displacement", + "SHORTWAVE_DISPLACEMENT": "Short Wave Displacement", "SHOW_PRODUCT_FILTERS_CRITERIA": "Show product filters criteria", "SHOW_RAW_DATA": "Show raw data", "SIGMA0": "sigma0", diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index 649108801..09e629458 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -923,4 +923,4 @@ "ZOOM_TO_FIT": "Acercar para ajustar", "ZOOM_TO_RESULTS": "Acercar a los resultados", "ZOOM_TO_SCENE": "Acercar a la escena" -} +} \ No newline at end of file From bcb590b23c2681c66e4ea69ab390b951256bb429 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Sat, 19 Oct 2024 13:35:24 -0700 Subject: [PATCH 23/23] WIP Remarked out center column --- .../timeseries-results-menu.component.html | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html index 791074bbe..c96f6bacc 100644 --- a/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html +++ b/src/app/components/results-menu/timeseries-results-menu/timeseries-results-menu.component.html @@ -57,33 +57,33 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + +