src/app/components/controls/vis-controls.component.ts
selector | app-vis-controls |
styleUrls | ./vis-controls.component.scss |
templateUrl | ./vis-controls.component.html |
Properties |
|
Methods |
Inputs |
Outputs |
constructor(ga: GoogleAnalyticsService)
|
||||||
Parameters :
|
config | |
Type : SheetConfig
|
|
currentSheet | |
Type : Sheet
|
|
error | |
Type : Error
|
|
selectedOrgans | |
Type : string[]
|
|
updatedConfig | |
Type : EventEmitter
|
|
changeBimodalDistanceX |
changeBimodalDistanceX()
|
Returns :
void
|
changeBimodalDistanceY |
changeBimodalDistanceY()
|
Returns :
void
|
changeHeight |
changeHeight()
|
Returns :
void
|
changeShowAS |
changeShowAS()
|
Returns :
void
|
changeShowOntology |
changeShowOntology()
|
Returns :
void
|
changeWidth |
changeWidth()
|
Returns :
void
|
exportControls | ||||||
exportControls(event: Event)
|
||||||
Parameters :
Returns :
void
|
showDiscrepencyId |
showDiscrepencyId()
|
Returns :
void
|
showDiscrepencyLabel |
showDiscrepencyLabel()
|
Returns :
void
|
showDuplicateId |
showDuplicateId()
|
Returns :
void
|
Public ga |
Type : GoogleAnalyticsService
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { GoogleAnalyticsService } from 'ngx-google-analytics';
import { GaAction, GaCategory } from '../../models/ga.model';
import { Error } from '../../models/response.model';
import { Sheet, SheetConfig } from '../../models/sheet.model';
@Component({
selector: 'app-vis-controls',
templateUrl: './vis-controls.component.html',
styleUrls: ['./vis-controls.component.scss'],
})
export class VisControlsComponent {
@Input() config!: SheetConfig;
@Input() error!: Error;
@Input() currentSheet!: Sheet;
@Input() selectedOrgans!: string[];
@Output() updatedConfig = new EventEmitter<{
property: string;
config: SheetConfig;
}>();
constructor(public ga: GoogleAnalyticsService) {}
changeWidth() {
this.updatedConfig.emit({
property: 'width',
config: this.config,
});
this.ga.event(GaAction.SLIDE, GaCategory.CONTROLS, 'Width Slider', this.config.width);
}
changeHeight() {
this.updatedConfig.emit({
property: 'height',
config: this.config,
});
this.ga.event(GaAction.SLIDE, GaCategory.CONTROLS, 'Height Slider', this.config.height);
}
changeShowOntology() {
this.config.show_ontology = !this.config.show_ontology;
this.updatedConfig.emit({
property: 'show-ontology',
config: this.config,
});
this.ga.event(GaAction.TOGGLE, GaCategory.CONTROLS, 'Toggle Ontology', +this.config.show_ontology);
}
showDiscrepencyLabel() {
this.config.discrepencyLabel = !this.config.discrepencyLabel;
this.config.discrepencyId = false;
this.config.duplicateId = false;
this.updatedConfig.emit({
property: 'show-discrepency-label',
config: this.config,
});
this.ga.event(GaAction.TOGGLE, GaCategory.CONTROLS, 'Toggle Discrepency Label', +this.config.discrepencyLabel);
}
showDiscrepencyId() {
this.config.discrepencyId = !this.config.discrepencyId;
this.config.discrepencyLabel = false;
this.config.duplicateId = false;
this.updatedConfig.emit({
property: 'show-discrepency-id',
config: this.config,
});
this.ga.event(GaAction.TOGGLE, GaCategory.CONTROLS, 'Toggle Discrepency ID', +this.config.discrepencyLabel);
}
showDuplicateId() {
this.config.duplicateId = !this.config.duplicateId;
this.config.discrepencyLabel = false;
this.config.discrepencyId = false;
this.updatedConfig.emit({
property: 'show-duplicate-id',
config: this.config,
});
this.ga.event(GaAction.TOGGLE, GaCategory.CONTROLS, 'Toggle Duplicate ID', +this.config.duplicateId);
}
changeBimodalDistanceX() {
this.updatedConfig.emit({
property: 'bm-x',
config: this.config,
});
this.ga.event(GaAction.SLIDE, GaCategory.CONTROLS, 'Bimodal Distance X Slider', this.config.bimodal_distance_x);
}
changeBimodalDistanceY() {
this.updatedConfig.emit({
property: 'bm-y',
config: this.config,
});
this.ga.event(GaAction.SLIDE, GaCategory.CONTROLS, 'Bimodal Distance Y Slider', this.config.bimodal_distance_y);
}
changeShowAS() {
this.updatedConfig.emit({
property: 'show-as',
config: this.config,
});
this.ga.event(GaAction.TOGGLE, GaCategory.CONTROLS, 'Toggle AS Visibility', +(this.config.show_all_AS ?? false));
}
exportControls(event: Event) {
event.stopPropagation();
const sJson = JSON.stringify(this.config);
const element = document.createElement('a');
element.setAttribute('href', 'data:text/json;charset=UTF-8,' + encodeURIComponent(sJson));
element.setAttribute('download', 'asct-b-graph-config.json');
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
this.ga.event(GaAction.CLICK, GaCategory.CONTROLS, 'Export Vis Controls', undefined);
}
}
<mat-expansion-panel class="mepNoPadding vis-controls" [expanded]="!error.hasError">
<mat-expansion-panel-header [expandedHeight]="'3.125rem'" class="controls">
<mat-panel-title>
<div>
<strong> Controls </strong>
</div>
</mat-panel-title>
<mat-panel-description>
<button mat-icon-button class="mr-2" (click)="exportControls($event)">
<mat-icon>get_app</mat-icon>
</button>
</mat-panel-description>
</mat-expansion-panel-header>
<div
class="py-1 pb-4"
*ngIf="currentSheet.name === 'all' || (currentSheet.name === 'some' && selectedOrgans.length > 8)"
>
<mat-slide-toggle
[checked]="config.show_all_AS"
color="primary"
(change)="changeShowAS()"
matTooltip="Toggle Visibility of Anatomical Structures"
matTooltipPosition="below"
>
<span class="control-title">Show all AS</span>
</mat-slide-toggle>
</div>
<div class="py-1 pb-4">
<mat-slide-toggle
[checked]="config.show_ontology"
color="primary"
(change)="changeShowOntology()"
matTooltip="Toggle Visibility of Ontology Links"
matTooltipPosition="below"
>
<span class="control-title">Ontology IDs</span>
</mat-slide-toggle>
</div>
<div class="py-1" matTooltip="Change Bimodal Distance (Y)" matTooltipPosition="below">
<div class="d-flex justify-content-between align-items-center w-100 h-100">
<div class="w-50">
<span class="control-title">Tree Width</span>
</div>
<div class="text-end w-50">
<strong
><input [(ngModel)]="config.width" type="number" matInput (change)="changeWidth()" class="numberInput"
/></strong>
</div>
<div></div>
</div>
<div class="d-flex justify-content-between align-items-center w-100 h-100">
<mat-slider
class="min p-0 w-100"
discrete="true"
color="primary"
showTickMarks="true"
tickInterval="100"
min="100"
max="1000"
step="100"
(change)="changeWidth()"
>
<input matSliderThumb [(ngModel)]="config.width" />
</mat-slider>
</div>
</div>
<div class="py-1" matTooltip="Change height of AS Tree" matTooltipPosition="below">
<div class="d-flex justify-content-between align-items-center w-100 h-100">
<div class="w-50">
<span class="control-title">Tree Height</span>
</div>
<div class="text-end w-50">
<strong>
<input [(ngModel)]="config.height" type="number" matInput (change)="changeHeight()" class="numberInput"
/></strong>
</div>
<div></div>
</div>
<div class="d-flex justify-content-between align-items-center w-100 h-100">
<mat-slider
class="min p-0 w-100"
thumbLabel
color="primary"
tickInterval="100"
min="100"
max="7000"
(change)="changeHeight()"
>
<input matSliderThumb [(ngModel)]="config.height"
/></mat-slider>
</div>
</div>
<div class="py-1" matTooltip="Change Bimodal Distance (X)" matTooltipPosition="below">
<div class="d-flex justify-content-between align-items-center w-100 h-100">
<div class="w-50">
<span class="control-title">Bimodal Distance X</span>
</div>
<div class="text-end w-50">
<strong>
<input
[(ngModel)]="config.bimodal_distance_x"
type="number"
matInput
(change)="changeBimodalDistanceX()"
class="numberInput"
/>
</strong>
</div>
<div></div>
</div>
<div class="d-flex justify-content-between align-items-center w-100 h-100">
<mat-slider
class="min p-0 w-100"
thumbLabel
color="primary"
tickInterval="100"
min="50"
max="500"
(change)="changeBimodalDistanceX()"
>
<input matSliderThumb [(ngModel)]="config.bimodal_distance_x"
/></mat-slider>
</div>
</div>
<div class="py-1" matTooltip="Change width of AS Tree" matTooltipPosition="below">
<div class="d-flex justify-content-between align-items-center w-100 h-100">
<div class="w-50">
<span class="control-title">Bimodal Distance Y</span>
</div>
<div class="text-end w-50">
<strong>
<input
[(ngModel)]="config.bimodal_distance_y"
type="number"
matInput
(change)="changeBimodalDistanceY()"
class="numberInput"
/>
</strong>
</div>
<div></div>
</div>
<div class="d-flex justify-content-between align-items-center w-100 h-100">
<mat-slider
class="min p-0 w-100"
thumbLabel
color="primary"
tickInterval="100"
min="10"
max="200"
(change)="changeBimodalDistanceY()"
>
<input matSliderThumb [(ngModel)]="config.bimodal_distance_y" />
</mat-slider>
</div>
</div>
<div class="py-1 pb-4">
<mat-slide-toggle
[checked]="config.discrepencyLabel"
color="primary"
(change)="showDiscrepencyLabel()"
matTooltip="Show the discrepency Label"
matTooltipPosition="below"
>
<span class="control-title">Label mismatch</span>
</mat-slide-toggle>
</div>
<div class="py-1 pb-4">
<mat-slide-toggle
[checked]="config.discrepencyId"
color="primary"
(change)="showDiscrepencyId()"
matTooltip="Show the discrepency ID"
matTooltipPosition="below"
>
<span class="control-title">ID Missing</span>
</mat-slide-toggle>
</div>
<div class="py-1 pb-4">
<mat-slide-toggle
[checked]="config.duplicateId"
color="primary"
(change)="showDuplicateId()"
matTooltip="Show the duplicate ID"
matTooltipPosition="below"
>
<span class="control-title">ID Duplicates</span>
</mat-slide-toggle>
</div>
</mat-expansion-panel>
./vis-controls.component.scss
@import './../../../assets/stylesheets/_colors.scss';
.mat-expansion-panel:not([class*='mat-elevation-z']) {
box-shadow: none;
}
.mat-expansion-panel-header:not(.compare) {
border-top-left-radius: 0.5rem !important;
border-top-right-radius: 0.5rem !important;
}
.mat-expansion-panel-header {
transition: all 0.3s;
background-color: $secondary !important;
padding-left: 0.9375rem !important;
padding-right: 0.9375rem !important;
border-top-left-radius: 0.5rem !important;
border-top-right-radius: 0.5rem !important;
}
.mat-expansion-panel-header:hover {
background-color: darken($color: $secondary, $amount: 8%) !important;
}
.numberInput {
background-color: #fafafa !important;
border-radius: 0.25rem !important;
font: inherit;
background: transparent;
color: currentColor;
border: none;
outline: none;
padding: 0;
margin: 0;
width: 500%;
max-width: 100%;
vertical-align: bottom;
text-align: inherit;
}
.controls .mat-expansion-panel-header-description {
justify-content: flex-end !important;
align-items: center;
margin-right: 0 !important;
}
.controls .mat-expansion-panel-header-description {
flex-basis: 0;
}
.controls .mat-expansion-panel-header-title {
display: flex;
align-items: center;
justify-content: space-between;
}
::ng-deep .mat-mdc-slide-toggle .mdc-switch.mdc-switch--selected:enabled .mdc-switch__icon {
fill: none !important;
}
::ng-deep .mat-mdc-slide-toggle .mdc-switch.mdc-switch--unselected:enabled .mdc-switch__icon {
fill: none !important;
}
.mat-mdc-slider .mdc-slider__track--active {
height: 0.125rem;
}
.mat-mdc-slider .mdc-slider__track--active {
height: 0.125rem;
}
mat-slider {
--mdc-slider-inactive-track-height: 0.18rem;
--mdc-slider-active-track-height: 0.18rem;
::ng-deep .mdc-slider__thumb-knob {
border-width: 0.438rem;
height: 0.813rem;
width: 0.813rem;
}
}
::ng-deep .mat-mdc-slide-toggle {
--mdc-switch-unselected-handle-color: #ffffff;
--mdc-switch-unselected-focus-handle-color: #ffffff;
--mdc-switch-unselected-hover-handle-color: #ffffff;
--mdc-switch-unselected-track-color: #989898;
--mdc-switch-unselected-hover-track-color: #989898;
--mdc-switch-unselected-focus-track-color: #989898;
}
.vis-controls {
font-size: 0.9rem;
}