import {AsyncPipe, LowerCasePipe} from '@angular/common';
import {ChangeDetectionStrategy, Component, computed, DestroyRef, inject} from '@angular/core';
import {MatTab, MatTabContent, MatTabGroup} from '@angular/material/tabs';
import {hazardUtils} from '@ghsc/nshmp-lib-ng/hazard';
import {NshmpDataTablePanelComponent, NshmpScrollToTopComponent} from '@ghsc/nshmp-lib-ng/nshmp';
import {PlotTableDataParams} from '@ghsc/nshmp-lib-ng/plot';
import {Imt, imtToString} from '@ghsc/nshmp-utils-ts/libs/nshmp-lib/gmm';
import {PlotData} from 'plotly.js';
import {map, Observable} from 'rxjs';
import {AppService} from '../../services/app.service';
import {PlotsComponent} from '../plots/plots.component';
interface Filenames {
hazard: string;
magnitudes: string;
sources: string;
spectra: string;
}
/**
* Main content for application with tabs:
* - Plots tab: show dynamic hazard plots
* - Hazard data tab: table of hazard data
* - Spectra data tab: table of spectra data
*/
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: {id: 'hazard-dynamic-content'},
imports: [
NshmpDataTablePanelComponent,
MatTabGroup,
MatTab,
PlotsComponent,
LowerCasePipe,
NshmpScrollToTopComponent,
AsyncPipe,
MatTabContent,
],
selector: 'app-content',
styleUrl: './content.component.scss',
templateUrl: './content.component.html',
})
export class ContentComponent {
service = inject(AppService);
private destroyRef = inject(DestroyRef);
/** Whether there is data */
hasData = computed(() => this.service.serviceResponse() !== null);
/** Hazard table data */
hazardTableData = computed(() => {
const plot = this.service.hazardPlotState();
return plot.toTableData({
...this.tableParams(),
// Remove return period from data
filter: (_, index) => index > 0,
});
});
/** Hazard table data */
magnitudesTableData = computed(() => {
const plot = this.service.magnitudesPlotState();
return plot.toTableData(this.tableParams());
});
/** Hazard table data */
sourcesTableData = computed(() => {
const plot = this.service.sourcesPlotState();
return plot.toTableData(this.tableParams());
});
/** Spectra table data */
spectraTableData = computed(() =>
hazardUtils.responseSpectraToTableData(this.service.responseSpectra()),
);
filenames$: Observable<Filenames> = this.service.formGroup.valueChanges.pipe(
map(values => {
return {
hazard: `hazard-curves-${values.model}-${values.sourceType}-${values.vs30}.csv`,
magnitudes: `magnitude-curves-${values.model}-${values.imt}-${values.vs30}.csv`,
sources: `sources-curves-${values.model}-${values.imt}-${values.vs30}.csv`,
spectra: `response-spectra-${values.model}-${values.sourceType}-${values.vs30}.csv`,
};
}),
);
private tableParams(): PlotTableDataParams {
return {
addLabel: true,
labelTransform: label => (label in Imt ? imtToString(label as Imt) : label),
xLabelTransform: (label: string, data: Partial<PlotData>) =>
data?.name === Imt.PGV.toString() ? label.replace('(g)', '(cm/s)') : label,
xValueFormat: (x: number) => x.toFixed(4),
yValueFormat: (y: number) => y.toExponential(4),
};
}
}