File
Description
Analyses Component
Used to display the list of available operations as a tree structure (the Tools tab)
Implements
Metadata
| changeDetection |
ChangeDetectionStrategy.Default |
| selector |
mev-analyses |
| styleUrls |
./analyses.component.scss |
| templateUrl |
./analyses.component.html |
Index
Properties
|
|
|
Methods
|
|
|
Outputs
|
|
|
Outputs
|
executedOperationId
|
Type : EventEmitter<any>
|
|
|
Methods
|
getPlottingOperationCategory
|
getPlottingOperationCategory()
|
|
|
Add a 'fake' operation for plotting. It is a frontend-only operation to provide
view for the normalization methods
The user can select a numerical matrix and custom feature set to view a boxplot showing the
distribution of expressions
Returns : { name: string; children: {}; }
|
|
ngOnInit
|
ngOnInit()
|
|
|
Initialize the datasource for the Operation Tree
|
|
Public
showExecutedOperationResult
|
showExecutedOperationResult(data: any)
|
|
|
Function is triggered when the user starts an analysis and emits a newly created executed operation id
Parameters :
| Name |
Type |
Optional |
| data |
any
|
No
|
|
|
Public
showOperationDetails
|
showOperationDetails(operation)
|
|
|
Function is triggered when the user clicks on a specific operation in the Operation Tree
Parameters :
| Name |
Optional |
| operation |
No
|
|
|
Private
_transformer
|
Default value : () => {...}
|
|
|
|
dataSource
|
Default value : new MatTreeFlatDataSource(this.treeControl, this.treeFlattener)
|
|
|
|
hasChild
|
Default value : () => {...}
|
|
|
|
operationCategories
|
Type : any[]
|
|
|
|
treeControl
|
Default value : new FlatTreeControl<ExampleFlatNode>(
node => node.level,
node => node.expandable
)
|
|
|
|
treeFlattener
|
Default value : new MatTreeFlattener(
this._transformer,
node => node.level,
node => node.expandable,
node => node.children
)
|
|
|
import {
Component,
OnInit,
ChangeDetectionStrategy,
Output,
EventEmitter
} from '@angular/core';
import { AnalysesService } from '../../services/analysis.service';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { Workspace } from '@app/features/workspace-manager/models/workspace';
import { Operation } from '../../models/operation';
import {
MatTreeFlatDataSource,
MatTreeFlattener
} from '@angular/material/tree';
import { FlatTreeControl } from '@angular/cdk/tree';
/**
* Operation category with nested structure.
* Each node has a name and an optional list of children.
*/
interface OperationCategoryNode {
name: string;
children?: Operation[];
}
/** Flat node with expandable and level information */
interface ExampleFlatNode {
expandable: boolean;
name: string;
level: number;
}
/**
* Analyses Component
* Used to display the list of available operations as a tree structure (the Tools tab)
*/
@Component({
selector: 'mev-analyses',
templateUrl: './analyses.component.html',
styleUrls: ['./analyses.component.scss'],
changeDetection: ChangeDetectionStrategy.Default
})
export class AnalysesComponent implements OnInit {
workspaceId: string;
workspace$: Observable<Workspace>;
operations: Operation[];
operationCategories: any[];
selectedOperation: Operation;
@Output() executedOperationId: EventEmitter<any> = new EventEmitter<any>();
treeControl = new FlatTreeControl<ExampleFlatNode>(
node => node.level,
node => node.expandable
);
private _transformer = (node: OperationCategoryNode, level: number) => {
return {
expandable: !!node.children && node.children.length > 0,
level: level,
...node
};
};
treeFlattener = new MatTreeFlattener(
this._transformer,
node => node.level,
node => node.expandable,
node => node.children
);
dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
hasChild = (_: number, node: ExampleFlatNode) => node.expandable;
constructor(
private route: ActivatedRoute,
private apiService: AnalysesService
) {}
/**
* Initialize the datasource for the Operation Tree
*/
ngOnInit(): void {
this.workspaceId = this.route.snapshot.paramMap.get('workspaceId');
this.workspace$ = this.apiService.getWorkspaceDetail(this.workspaceId);
this.apiService.getOperations().subscribe(operations => {
this.operations = operations;
});
this.apiService.getOperationCategories().subscribe(operationCategories => {
this.selectedOperation = operationCategories[0].children[0]; // show the parameters for the 1st operation by default
operationCategories.push(this.getPlottingOperationCategory());
this.dataSource.data = operationCategories;
this.treeControl.expand(this.treeControl.dataNodes[0]); // expand the 1st operation category by default
});
}
/**
* Add a 'fake' operation for plotting. It is a frontend-only operation to provide
* view for the normalization methods
* The user can select a numerical matrix and custom feature set to view a boxplot showing the
* distribution of expressions
*/
getPlottingOperationCategory() {
const op = {
name: 'Plotting',
children: [
{
id: 'Plotting',
name: 'Plot expressions',
description: 'Output view for the normalization methods',
mode: 'client',
inputs: {
input_matrix: {
description:
'The input matrix. For example, a gene expression matrix for a cohort of samples.',
name: 'Input matrix:',
required: true,
spec: {
attribute_type: 'DataResource',
many: false,
resource_types: ['MTX', 'I_MTX', 'EXP_MTX', 'RNASEQ_COUNT_MTX']
}
},
features: {
description: 'The genes/features to use in plotting',
name: 'Plot genes/features by:',
required: false,
spec: {
attribute_type: 'FeatureSet'
}
}
}
}
]
};
return op;
}
/**
* Function is triggered when the user clicks on a specific operation in the Operation Tree
*/
public showOperationDetails(operation) {
this.selectedOperation = operation;
}
/**
* Function is triggered when the user starts an analysis and emits a newly created executed operation id
*/
public showExecutedOperationResult(data: any) {
this.executedOperationId.emit(data);
}
}
<div class="analyses-container">
<section class="analyses-section">
<div class="tab-content">
The analysis pane on the left side displays the list of available
data analysis tools. Expand and collapse the list of tools clicking on a category.
Click on a item to set input parameters and run an analysis.
<div class="vertical-tab-container">
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<!-- tree node template for leaf nodes -->
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding [ngClass]="{ 'active-node': node.id === selectedOperation.id }">
<!-- use a disabled button to provide padding for tree leaf -->
<button mat-icon-button disabled></button>
<button (click)="showOperationDetails(node)">
{{node.name}}
</button>
</mat-tree-node>
<!-- tree node template for expandable nodes -->
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding>
<button matTreeNodeToggle [attr.aria-label]="'Toggle ' + node.name">
<mat-icon class="mat-icon-rtl-mirror">
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
{{node.name}}
</button>
</mat-tree-node>
</mat-tree>
<mat-divider [vertical]="true"></mat-divider>
<div class="operation-container">
<mev-operation *ngIf="selectedOperation" [operation]="selectedOperation" [workspaceId]="workspaceId"
[workspace$]="workspace$" (executedOperationId)="showExecutedOperationResult($event)"></mev-operation>
</div>
</div>
</div>
</section>
</div>
.analyses-section {
margin: 20px;
font-size: 14px !important;
}
.vertical-tab-container {
margin: 30px 0;
display: flex;
}
mat-tree {
background-color: #ddebf2 !important;
width: 300px;
button {
display: flex;
align-items: center;
border: 0;
background: none;
white-space: normal;
padding-right: 15px;
padding-left: 15px;
text-align: left;
&:hover {
color: grey;
}
}
.active-node {
font-weight: bold;
background-color: #eee !important;
}
}
.operation-container {
padding: 10px 20px;
width: 100%;
}
Legend
Html element with directive