File

components/control-panel/control-panel.component.ts

Description

Earthquake settings group

Index

Properties

Properties

settings
settings: TectonicSettings
Type : TectonicSettings

Tectonic settings

types
types: SourceType[]
Type : SourceType[]

Earthquake source types

import {AsyncPipe} from '@angular/common';
import {Component, computed, OnDestroy, OnInit} from '@angular/core';
import {ReactiveFormsModule} from '@angular/forms';
import {MatOptgroup, MatOption} from '@angular/material/core';
import {MatFormField, MatLabel} from '@angular/material/form-field';
import {MatSelect} from '@angular/material/select';
import {MatSlideToggle} from '@angular/material/slide-toggle';
import {NshmpLibNgHazardModelFormComponent} from '@ghsc/nshmp-lib-ng/hazard';
import {
  NshmpLibNgControlPanelButtonsComponent,
  NshmpService,
} from '@ghsc/nshmp-lib-ng/nshmp';
import {
  SettingGroup,
  SourceType,
  sourceTypeToCapitalCase,
  TectonicSettings,
  tectonicSettingsToString,
  TreeInfo,
} from '@ghsc/nshmp-utils-ts/libs/nshmp-lib/model';
import {map, Subscription} from 'rxjs';

import {MfdSource} from '../../models/control-form.model';
import {AppService} from '../../services/app.service';

/**
 * Earthquake settings group
 */
interface SettingsGroup {
  /** Tectonic settings */
  settings: TectonicSettings;
  /** Earthquake source types */
  types: SourceType[];
}

/**
 * Control panel form fields to set values to call MFD service.
 */
@Component({
  imports: [
    NshmpLibNgHazardModelFormComponent,
    NshmpLibNgControlPanelButtonsComponent,
    MatFormField,
    MatLabel,
    MatSelect,
    MatOptgroup,
    MatOption,
    MatSlideToggle,
    AsyncPipe,
    ReactiveFormsModule,
  ],
  selector: 'app-control-panel',
  styleUrl: './control-panel.component.scss',
  templateUrl: './control-panel.component.html',
})
export class ControlPanelComponent implements OnInit, OnDestroy {
  /** Function to convert tectonic settings to string */
  settingsToString = tectonicSettingsToString;
  /** Function to convert source type to string */
  sourceTypeToString = sourceTypeToCapitalCase;

  /** Form field state */
  formGroup = this.service.formGroup;

  /** Settings group state */
  settingsGroup = computed(() => {
    const usage = this.service.usage();

    if (usage) {
      return this.toSourceTypes(usage.response.trees);
    } else {
      return [];
    }
  });

  /** Source trees state */
  sourceTrees$ = this.formGroup.controls.source.valueChanges.pipe(
    map(source =>
      this.toSourceTrees(source, this.service.usage().response.trees),
    ),
  );

  private subs: Subscription[] = [];

  constructor(
    public service: AppService,
    private nshmpService: NshmpService,
  ) {}

  ngOnInit(): void {
    const controls = this.formGroup.controls;

    this.subs.push(
      controls.model.valueChanges.subscribe(() => this.onModelChange()),
    );

    this.subs.push(
      controls.sourceAsString.valueChanges.subscribe(sourceAsString => {
        controls.source.setValue(JSON.parse(sourceAsString) as MfdSource);
        this.onSourceChange();
      }),
    );

    this.subs.push(
      controls.sourceTree.valueChanges.subscribe(() =>
        this.service.resetState(),
      ),
    );

    this.subs.push(
      controls.cumulative.valueChanges.subscribe(() =>
        this.service.createPlots(),
      ),
    );

    this.subs.push(
      controls.weightedMfds.valueChanges.subscribe(() =>
        this.service.createPlots(),
      ),
    );
  }

  ngOnDestroy(): void {
    this.subs.forEach(sub => sub.unsubscribe());
  }

  /**
   * On form submit.
   */
  onSubmit(): void {
    this.service.callService();
    this.nshmpService.selectPlotControl();
  }

  private onModelChange(): void {
    const trees = this.service.usage().response.trees;
    const defaultSource = this.service.defaultSource(trees);
    const defaultTreeInfo = this.service.defaultSourceTree(
      trees,
      defaultSource,
    );

    this.formGroup.patchValue({
      source: defaultSource,
      sourceAsString: JSON.stringify(defaultSource),
      sourceTree: defaultTreeInfo.id,
    });

    this.service.resetState();
  }

  private onSourceChange(): void {
    const trees = this.service.usage().response.trees;
    const defaultTreeInfo = this.service.defaultSourceTree(
      trees,
      this.formGroup.getRawValue().source,
    );

    this.formGroup.patchValue({
      sourceTree: defaultTreeInfo.id,
    });
    this.service.resetState();
  }

  toSourceValue(
    sourceType: SourceType,
    tectonicSettings: TectonicSettings,
  ): string {
    return JSON.stringify({
      sourceType,
      tectonicSettings,
    });
  }

  /**
   * Returns the tree info list associated with a source and trees.
   *
   * @param source The MfdSource
   * @param trees The setting groups
   */
  private toSourceTrees(source: MfdSource, trees: SettingGroup[]): TreeInfo[] {
    if (
      source === null ||
      source === undefined ||
      trees === null ||
      trees === undefined
    ) {
      return [];
    }

    const settingsTree = trees.find(
      tree => tree.setting === source.tectonicSettings,
    );
    const tree = settingsTree?.data?.find(
      data => data.type === source.sourceType,
    );
    const data = tree?.data.sort((a, b) => a.name.localeCompare(b.name));

    return data ?? [];
  }

  /**
   *  Convert setting group to source types.
   *
   * @param trees The settings groups
   */
  private toSourceTypes(trees: SettingGroup[]): SettingsGroup[] {
    if (trees === null || trees === undefined) {
      return [];
    }

    return trees.map(tree => {
      const types = [...tree.data].map(data => data.type);

      return {
        settings: tree.setting,
        types: types.sort((a, b) => a.localeCompare(b)),
      };
    });
  }
}

results matching ""

    No results matching ""