Skip to content

Commit

Permalink
Merge branch 'displacement' into kim/displacement
Browse files Browse the repository at this point in the history
  • Loading branch information
Kim committed Nov 13, 2024
2 parents 066c856 + 956630d commit 5f27cf0
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
</button>
</div>
<mat-menu #menu="matMenu">
<div class="chart-config-menu-panel" [ngSwitch]="searchType" (click)="$event.stopPropagation()">
<app-timeseries-chart-config *ngSwitchCase="SearchTypes.DISPLACEMENT"></app-timeseries-chart-config>
<app-timeseries-chart-config *ngSwitchDefault></app-timeseries-chart-config>
<div class="chart-config-menu-panel" (click)="$event.stopPropagation()">
<app-timeseries-chart-config (resetReferenceEvent)="onResetReference()"></app-timeseries-chart-config>
</div>
</mat-menu>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Component, OnDestroy, OnInit, Output, EventEmitter } from '@angular/core';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon'
import { MatButtonModule } from '@angular/material/button'
Expand Down Expand Up @@ -31,6 +31,7 @@ export class ChartModalComponent implements OnInit, OnDestroy {
private subs = new SubSink()
public searchType: SearchType;
public SearchTypes = SearchType;
@Output() public resetReferenceEvent = new EventEmitter();

constructor(public dialog: MatDialog,
private $store: Store<AppState>,
Expand All @@ -42,6 +43,9 @@ export class ChartModalComponent implements OnInit, OnDestroy {
searchtype => this.searchType = searchtype
))
}
public onResetReference() {
this.resetReferenceEvent.emit();
}

ngOnDestroy(): void {
this.subs.unsubscribe()
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
<mat-checkbox (change)="onToggleLines($event)" [checked]="showLines">Show Lines</mat-checkbox>
<div style="display: flex; flex-direction: column;">
<mat-checkbox (change)="onToggleLines($event)" [checked]="showLines">Show Lines</mat-checkbox>
<button mat-button (click)="resetReference()">Reset chart reference</button>
</div>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Component, OnDestroy, OnInit, Output, EventEmitter } from '@angular/core';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxChange, MatCheckboxModule } from '@angular/material/checkbox';
Expand All @@ -18,7 +18,7 @@ import * as chartsStore from '@store/charts'
export class TimeseriesChartConfigComponent implements OnInit, OnDestroy {
private subs = new SubSink()
public showLines: boolean = true

@Output() public resetReferenceEvent = new EventEmitter();
constructor(private store$: Store<AppState>) { }

public onToggleLines(event: MatCheckboxChange) {
Expand All @@ -36,6 +36,10 @@ export class TimeseriesChartConfigComponent implements OnInit, OnDestroy {
);
}

public resetReference() {
this.resetReferenceEvent.emit();
}

ngOnDestroy(): void {
this.subs.unsubscribe()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<div #ts_slider class="slider"></div>
<div #ts_slider class="slider" style="visibility: hidden;"></div>
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import {Component, ElementRef, ViewChild, OnInit, OnDestroy} from '@angular/core';
import {Component, ElementRef, OnDestroy, OnInit, ViewChild, Renderer2} from '@angular/core';
import * as noUiSlider from 'nouislider';
import { Store } from "@ngrx/store";
import { AppState } from "@store";
import {PipsMode} from 'nouislider';
import {Store} from '@ngrx/store';
import {AppState} from '@store';
// import * as models from "@models";
// import {Observable, Subject} from 'rxjs';
// import {UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators} from "@angular/forms";
// import * as filtersStore from "@store/filters";
import {SubSink} from "subsink";
import {SubSink} from 'subsink';
// import {debounceTime, distinctUntilChanged} from "rxjs/operators";
// import wNumb from 'wnumb';
import * as filtersStore from '@store/filters';
import * as models from '@models';
// import moment from 'moment/moment';
import {Observable, Subject} from 'rxjs';
import {debounceTime, distinctUntilChanged} from 'rxjs/operators';

// import {debounceTime, distinctUntilChanged} from 'rxjs/operators';

@Component({
Expand All @@ -36,9 +38,11 @@ export class TimeseriesChartTemporalSliderComponent implements OnInit, OnDestroy
public endDate$ = this.store$.select(filtersStore.getEndDate);
public startDate: Date = new Date();
public endDate: Date = new Date();
private userChangedRange: boolean = false;

constructor(
private store$: Store<AppState>
private store$: Store<AppState>,
private renderer: Renderer2
){}

ngOnInit() {
Expand All @@ -55,12 +59,17 @@ export class TimeseriesChartTemporalSliderComponent implements OnInit, OnDestroy
this.lastMaxRange.start = this.maxRange.start;
this.lastMaxRange.end = this.maxRange.end;
this.sliderRef.nativeElement.noUiSlider.updateOptions({
start: [this.maxRange.start, this.maxRange.end],
range: {
'min': this.maxRange.start,
'max': this.maxRange.end
}
});
if (!this.userChangedRange) {
this.sliderRef.nativeElement.noUiSlider.updateOptions({
start: [this.maxRange.start, this.maxRange.end],
});
}
this.renderer.setStyle(this.sliderRef.nativeElement, 'visibility', 'visible');
}
}
)
Expand All @@ -77,6 +86,7 @@ export class TimeseriesChartTemporalSliderComponent implements OnInit, OnDestroy
this.sliderRef.nativeElement.noUiSlider.updateOptions({
start: [this.selectedRange.start, this.selectedRange.end]
});
this.userChangedRange = true;
const action = new filtersStore.SetStartDate(new Date(start));
this.store$.dispatch(action);
const action2 = new filtersStore.SetEndDate(new Date(end));
Expand Down Expand Up @@ -118,8 +128,7 @@ export class TimeseriesChartTemporalSliderComponent implements OnInit, OnDestroy
'max': 100
},
pips: {
// @ts-ignore
mode: 'count',
mode: PipsMode.Count,
values: 5,
stepped: true,
density: 4,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div #tsChartWrapper class="chart-wrapper" (resized)="onResized()">
<div #timeseriesChart id="timeseriesChart">
<div #timeseriesChart id="timeseriesChart" [contextMenuTriggerFor]="menu" [contextMenuTriggerData]="{'tooltipData': hoveredData}">
</div>
<app-chart-modal class="ts-chart-config-button"></app-chart-modal>
<app-chart-modal class="ts-chart-config-button" (resetReferenceEvent)="resetBasePoint()"></app-chart-modal>
<app-timeseries-chart-zoom class="ts-chart-zoom" (zoomInEvent)="onZoomIn()" (zoomOutEvent)="onZoomOut()"
(zoomToFitEvent)="onZoomToFit()"></app-timeseries-chart-zoom>

Expand All @@ -10,4 +10,10 @@
<mat-spinner></mat-spinner>
</div>
}
<mat-menu #menu="matMenu">
<ng-template matMenuContent let-tooltipData="tooltipData">
<button mat-button (click)="setReference(tooltipData)">Set as Reference</button>

</ng-template>
</mat-menu>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,6 @@
top: 17px;
right: 95px;
}


:host ::ng-deep .ts-reference-point {
fill: red !important;
}
55 changes: 40 additions & 15 deletions src/app/components/timeseries-chart/timeseries-chart.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Component, ElementRef, Input, OnDestroy, OnInit, ViewChild } from '@ang

import * as d3 from 'd3';
// import * as models from '@models';
import { debounceTime, Observable, withLatestFrom,
import {
debounceTime, Observable, withLatestFrom,
// Subject
} from 'rxjs';

Expand All @@ -20,6 +21,8 @@ import * as models from '@models';
interface TimeSeriesData {
short_wavelength_displacement: number
date: string,
id: string,
base: number,
seriesNumber: number,
color: string,
}
Expand Down Expand Up @@ -70,6 +73,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy {
public margin = { top: 10, right: 30, bottom: 60, left: 55 };
private thing: d3.Selection<SVGGElement, {}, HTMLElement, any>
private hoveredElement;
public hoveredData;
private data: any;
private lines;
private points;
Expand All @@ -89,6 +93,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy {
private subs = new SubSink();
// private allGroup: string[];

private baseData: TimeSeriesData;
constructor(
private store$: Store<AppState>,
private language: AsfLanguageService,
Expand All @@ -110,8 +115,8 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy {
debounceTime(1000),
withLatestFrom(this.store$.select(chartsStore.getTimeseriesChartStates))
).subscribe(([_updated_id, chartStates]) => {
this.refreshChart(chartStates);
}));
this.refreshChart(chartStates);
}));

this.subs.add(
this.store$.select(chartsStore.getTimeseriesChartStates).subscribe(
Expand Down Expand Up @@ -152,7 +157,8 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy {
this.startDate = start;
if (this.lastStartDate !== this.startDate) {
this.lastStartDate = this.startDate;
this.initChart(this.data); }
this.initChart(this.data);
}
}
)
);
Expand All @@ -163,17 +169,18 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy {
this.endDate = end;
if (this.lastEndDate !== this.endDate) {
this.lastEndDate = this.endDate;
this.initChart(this.data); }
this.initChart(this.data);
}
}
)
);

}

private refreshChart(chartStates: {[key: string]: models.timeseriesChartItemState}): void {
private refreshChart(chartStates: { [key: string]: models.timeseriesChartItemState }): void {
const cache = this.netcdfService.getCache()
const allPointsData: {point: {}, state: models.timeseriesChartItemState}[] = Object.keys(chartStates).map(
wkt => ({point: cache[wkt], state: chartStates[wkt]})
const allPointsData: { point: {}, state: models.timeseriesChartItemState }[] = Object.keys(chartStates).map(
wkt => ({ point: cache[wkt], state: chartStates[wkt] })
);
this.data = allPointsData;
this.initChart(this.data)
Expand Down Expand Up @@ -235,10 +242,12 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy {
'temporal_baseline': result.point[key].temporal_baseline,
})
this.timeSeriesData.push({
'short_wavelength_displacement': result.point[key].short_wavelength_displacement,
'short_wavelength_displacement': result.point[key].short_wavelength_displacement - (this.baseData?.base ?? 0),
'date': result.point[key].secondary_datetime,
'seriesNumber': result.state.seriesNumber,
'color': result.state.color,
'base': result.point[key].short_wavelength_displacement,
'id': key + result.point[key].short_wavelength_displacement
});
}
this.timeSeriesData.sort((a, b) => {
Expand Down Expand Up @@ -297,7 +306,9 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy {
const toolTip = d3.select('body').append('div')
.attr('class', 'tooltip')
.style('opacity', 0);

if (this.toolTip) {
this.toolTip.remove();
}
this.toolTip = toolTip
this.toolTip.attr('transform', `translate(0, 0)`).style('text-anchor', 'middle').style('z-index', 100).style('opacity', 0)

Expand Down Expand Up @@ -390,23 +401,30 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy {
.attr('clip-path', 'url(#clip)')
.style('fill', (d) : string=> { return d.color })
.style('opacity', (d) => d.opacity)
.attr('class', (d) : string=> { return d.name.replace(/\W/g, '')})
.attr('class', (d): string => { return d.name.replace(/\W/g, '') })
.selectAll('circle')
.data(d => d.values)
.enter()
.append('circle')
.attr('cx', (d) => this.x(Date.parse(d.date)))
.attr('cy', (d) => this.y(d.short_wavelength_displacement))
.attr('class', (d): string => {
if (this.baseData && this.baseData.id === d.id) {
return 'ts-reference-point'
}
})
.on('mouseover', function (_event: any, p: TimeSeriesData) {
self.hoveredElement = this;
self.hoveredData = p;
const date = new Date(p.date);
toolTip.interrupt();
toolTip
.style('opacity', .9);
toolTip.html(`<div style="text-align: left"><b>Series ${p.seriesNumber}</b><br>${self.tooltipDateFormat(date)}, ${p.short_wavelength_displacement.toFixed(5)} meters</div>`);
toolTip.html(`<div style="text-align: left">${self.tooltipDateFormat(date)}, ${p.short_wavelength_displacement.toFixed(5)} meters<br><b>Series ${p.seriesNumber}</b></div>`);
self.updateTooltip();
})
.on('mouseleave', function (_) {
self.hoveredData = null;
toolTip.transition()
.duration(500)
.style('opacity', 0);
Expand All @@ -415,7 +433,10 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy {

this.updateChart();
}

public setReference(reference) {
this.baseData = reference;
this.initChart(this.data);
}
// When the pointer moves, find the closest point, update the interactive tip, and highlight
// the corresponding line.
private pointerMoved(event, lines, dots, points) {
Expand All @@ -428,7 +449,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy {
let colorName: string;
let dClassName: string;
// set the color of the selected line to the color of the series; make all other lines grey
lines.style("stroke", (d: DataReady)=> {
lines.style("stroke", (d: DataReady) => {
if (d.name === k) {
dClassName = '.' + d.name.replace(/\W/g, '');
colorName = d.color;
Expand Down Expand Up @@ -458,7 +479,7 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy {

private pointerLeft(lines, _dots) {
let dClassName: string;
lines.style("stroke", (d: DataReady)=> {
lines.style("stroke", (d: DataReady) => {
dClassName = '.' + d.name.replace(/\W/g, '');
this.svg.selectAll(dClassName + ' ' + 'circle').style("fill", d.color);
return d.color;
Expand Down Expand Up @@ -545,6 +566,10 @@ export class TimeseriesChartComponent implements OnInit, OnDestroy {
.range(d3.schemeCategory10);

}
public resetBasePoint() {
this.baseData = null;
this.initChart(this.data);
}

public ngOnDestroy(): void {
this.subs.unsubscribe();
Expand Down
11 changes: 9 additions & 2 deletions src/app/components/timeseries-chart/timeseries-chart.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ import { TimeseriesChartConfigComponent } from './timeseries-chart-config'
import { ChartModalComponent } from '@components/shared/chart-modal/chart-modal.component'
import {TimeseriesChartZoomComponent} from '@components/timeseries-chart/timeseries-chart-zoom/timeseries-chart-zoom.component';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatMenuModule } from '@angular/material/menu';
import { ContextMenuTriggerDirective } from '@directives/context-menu.directive';

@NgModule({
declarations: [TimeseriesChartComponent],
declarations: [TimeseriesChartComponent,
ContextMenuTriggerDirective

],
imports: [
CommonModule,
MatSharedModule,
Expand All @@ -25,7 +31,8 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
ChartModalComponent,
TimeseriesChartConfigComponent,
TimeseriesChartZoomComponent,
MatProgressSpinnerModule
MatProgressSpinnerModule,
MatMenuModule,

],
exports: [
Expand Down
Loading

0 comments on commit 5f27cf0

Please sign in to comment.