File

lib/components/plot-settings/plot-settings.component.ts

Description

Angular material form fields for changing plot settings.

Metadata

Index

Properties
Methods
Inputs
Outputs

Inputs

showLabel
Default value : true

Whether to show plot label

Outputs

updatedPlot

Methods

Private updatePlotFromSettings
updatePlotFromSettings(plot: NshmpPlot)

Update the Plotly config and layout from the application plot settings.

Parameters :
Name Type Optional Description
plot NshmpPlot No

The NSHMP plot

Returns : NshmpPlot

Properties

configSettings
Type : FormGroup<PlotlyConfigFormGroup>

Config settings form state

Private destroyRef
Default value : inject(DestroyRef)
exportFormat
Type : []
Default value : ['png', 'svg', 'jpeg', 'webp']

Plotly export formats

layoutSettings
Type : FormGroup<NshmpPlotLayoutFormGroup>

Layout settings form state

Readonly plot
Default value : input.required<NshmpPlot, NshmpPlot>({ transform: plot => { this.plotSettings = plot.settingsForm; this.configSettings = plot.settingsForm.controls.config; this.layoutSettings = plot.settingsForm.controls.layout; this.plotSettings.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => { this.updatedPlot.emit(this.updatePlotFromSettings(plot)); }); return plot; }, })

Sets the plot

Parameters :
Name Description
plot

The NSHMP plot

plotSettings
Type : FormGroup<NshmpPlotSettingFormGroup>

Plot settings form state

Readonly showLabel
Default value : true

Whether to show plot label

Readonly updatedPlot
import {Component, DestroyRef, inject, input, output} from '@angular/core';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {FormGroup, ReactiveFormsModule} from '@angular/forms';
import {MatOption} from '@angular/material/core';
import {MatDivider} from '@angular/material/divider';
import {MatError, MatFormField, MatHint, MatLabel, MatSuffix} from '@angular/material/form-field';
import {MatInput} from '@angular/material/input';
import {MatSelect} from '@angular/material/select';
import {MatSlideToggle} from '@angular/material/slide-toggle';
import {NshmpSectionComponent} from '@ghsc/nshmp-lib-ng/nshmp';
import {PlotlyPlot} from '@ghsc/nshmp-utils-ts/libs/plotly';
import {DataTitle} from 'plotly.js';

import {
  NshmpPlot,
  NshmpPlotLayoutFormGroup,
  NshmpPlotSettingFormGroup,
  PlotlyConfigFormGroup,
} from '../../models/nshmp-plot.model';
import {NshmpPlotSettingsAxisComponent} from '../plot-settings-axis/plot-settings-axis.component';

/**
 * Angular material form fields for changing plot settings.
 */
@Component({
  imports: [
    MatLabel,
    MatFormField,
    MatInput,
    MatSlideToggle,
    MatHint,
    MatError,
    NshmpPlotSettingsAxisComponent,
    NshmpSectionComponent,
    MatSuffix,
    MatSelect,
    MatOption,
    MatDivider,
    ReactiveFormsModule,
  ],
  selector: 'nshmp-plot-settings',
  styleUrl: './plot-settings.component.scss',
  templateUrl: './plot-settings.component.html',
})
export class NshmpPlotSettingsComponent {
  private destroyRef = inject(DestroyRef);

  /** Plot settings form state */
  plotSettings!: FormGroup<NshmpPlotSettingFormGroup>;
  /** Layout settings form state */
  layoutSettings!: FormGroup<NshmpPlotLayoutFormGroup>;
  /** Config settings form state */
  configSettings!: FormGroup<PlotlyConfigFormGroup>;
  /** Plotly export formats */
  exportFormat = ['png', 'svg', 'jpeg', 'webp'];

  readonly updatedPlot = output<NshmpPlot>();

  /**
   * Sets the plot
   *
   * @param plot The NSHMP plot
   */
  readonly plot = input.required<NshmpPlot, NshmpPlot>({
    transform: plot => {
      this.plotSettings = plot.settingsForm;
      this.configSettings = plot.settingsForm.controls.config;
      this.layoutSettings = plot.settingsForm.controls.layout;

      this.plotSettings.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
        this.updatedPlot.emit(this.updatePlotFromSettings(plot));
      });

      return plot;
    },
  });

  /** Whether to show plot label */
  readonly showLabel = input(true);

  /**
   * Update the Plotly config and layout from the application plot settings.
   *
   * @param plot The NSHMP plot
   */
  private updatePlotFromSettings(plot: NshmpPlot): NshmpPlot {
    const settings = plot.settingsForm.getRawValue();

    const plotData: PlotlyPlot = {
      ...plot.plotData,
      config: {
        ...plot.plotData.config,
        ...settings.config,
        toImageButtonOptions: {
          ...plot.plotData.config.toImageButtonOptions,
          ...settings.config.toImageButtonOptions,
        },
      },
      layout: {
        ...plot.plotData.layout,
        ...settings.layout,
        legend: {
          ...plot.plotData.layout.legend,
          x: settings.layout.legend.x,
          y: settings.layout.legend.y,
        },
        showlegend: settings.layout.legend.showlegend,
        title: {
          ...(plot.plotData.layout.title as DataTitle),
          font: {
            ...(plot.plotData.layout.title as DataTitle).font,
            size: settings.layout.title.size,
          },
          text: settings.layout.title.text,
        },
        xaxis: {
          ...plot.plotData.layout.xaxis,
          nticks: settings.layout.xaxis.nticks,
          title: {
            ...(plot.plotData?.layout?.xaxis?.title as DataTitle),
            font: {
              ...(plot.plotData?.layout?.xaxis?.title as DataTitle).font,
              size: settings.layout.xaxis.title.size,
            },
            text: settings.layout.xaxis.title.text,
          },
          type: settings.layout.xaxis.type,
        },
        yaxis: {
          ...plot.plotData.layout.yaxis,
          nticks: settings.layout.yaxis.nticks,
          title: {
            ...(plot.plotData?.layout?.yaxis?.title as DataTitle),
            font: {
              ...(plot.plotData?.layout?.yaxis?.title as DataTitle).font,
              size: settings.layout.yaxis.title.size,
            },
            text: settings.layout.yaxis.title.text,
          },
          type: settings.layout.yaxis.type,
        },
      },
    };

    return {
      ...plot,
      plotData,
    };
  }
}
@if (plotSettings && layoutSettings) {
  @let label = showLabel() ? plot().label : '';

  <nshmp-section [label]="label">
    <form class="padding-x-1" [formGroup]="plotSettings">
      <!-- Plot Settings: title text -->
      <mat-form-field class="grid-col-12 padding-top-2 title-input">
        <mat-label>Title</mat-label>
        <input type="text" matInput [formControl]="layoutSettings.controls.title.controls.text" />
      </mat-form-field>

      <!-- Plot Settings: title font size -->
      <mat-form-field class="grid-col-12 title-font-size-input">
        <mat-label>Title Font Size</mat-label>
        <input matInput type="number" [formControl]="layoutSettings.controls.title.controls.size" />
      </mat-form-field>

      <!-- Plot Settings: aspect ratio -->
      <mat-form-field class="grid-col-12 padding-bottom-2 plot-aspect-ratio-input">
        <mat-label>Aspect Ratio</mat-label>
        <input type="string" matInput [formControl]="layoutSettings.controls.aspectRatio" />
      </mat-form-field>

      @if (layoutSettings.controls.legend; as legend) {
        <nshmp-section label="Legend">
          <!-- Plot Settings: Legend -->
          <!-- Legend: show legend -->
          <div class="grid-row">
            <mat-slide-toggle
              class="show-legend-toggle grid-col-12"
              [formControl]="legend.controls.showlegend"
            >
              Legend
            </mat-slide-toggle>
          </div>

          <!-- Legend: location-->
          <div class="grid-row padding-bottom-2">
            <mat-form-field class="grid-col-6 legend-x-input">
              <mat-label>Legend X Location</mat-label>
              <input [formControl]="legend.controls.x" type="number" matInput max="3" min="-2" />
              <mat-hint>[-2, 3] Normalized unts</mat-hint>
              <mat-error>[-2, 3]</mat-error>
            </mat-form-field>

            <mat-form-field class="grid-col-6 legend-y-input">
              <mat-label>Legend Y location</mat-label>
              <input [formControl]="legend.controls.y" type="number" matInput max="3" min="-2" />
              <mat-hint>[-2, 3] Normalized units</mat-hint>
              <mat-error>[-2, 3]</mat-error>
            </mat-form-field>
          </div>
        </nshmp-section>
      }

      <!-- X-Axis Settings-->
      <nshmp-plot-settings-axis
        class="x-axis-settings"
        [settings]="layoutSettings.controls.xaxis"
        label="X-Axis"
      />

      <!-- Y-Axis Settings -->
      <nshmp-plot-settings-axis
        class="y-axis-settings"
        [settings]="layoutSettings.controls.yaxis"
        label="Y-Axis"
      />

      <!-- Export Settings -->
      @if (configSettings && configSettings.controls.toImageButtonOptions; as exportSettings) {
        <nshmp-section label="Export Options">
          <!-- Export Settings: Height -->
          @if (exportSettings.controls.height) {
            <mat-form-field class="grid-col-12 export-height-input">
              <mat-label>Height</mat-label>
              <input type="text" matInput [formControl]="exportSettings.controls.height" />
              <span matTextSuffix>px</span>
            </mat-form-field>
          }

          <!-- Export Settings: Width -->
          @if (exportSettings.controls.width) {
            <mat-form-field class="grid-col-12 export-width-input">
              <mat-label>Width</mat-label>
              <input type="text" matInput [formControl]="exportSettings.controls.width" />
              <span matTextSuffix>px</span>
            </mat-form-field>
          }

          <!-- Export Settings: Scale -->
          @if (exportSettings.controls.scale) {
            <mat-form-field class="grid-col-12 export-scale-input margin-bottom-2">
              <mat-label>Scaling Factor</mat-label>
              <input type="text" matInput [formControl]="exportSettings.controls.scale" />
              <mat-hint>Scale canvas by this factor for better resolution</mat-hint>
            </mat-form-field>
          }

          <!-- Export Settings: Format -->
          @if (exportSettings.controls.format) {
            <mat-form-field class="grid-col-12 export-format-select">
              <mat-label>Format</mat-label>
              <mat-select [formControl]="exportSettings.controls.format">
                @for (format of exportFormat; track format) {
                  <mat-option [value]="format">
                    {{ format }}
                  </mat-option>
                }
              </mat-select>
            </mat-form-field>
          }
        </nshmp-section>
      }

      <mat-divider class="padding-bottom-2" />
    </form>
  </nshmp-section>
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""