From 308d555abb5504f202d4240023870bb9f3117fd5 Mon Sep 17 00:00:00 2001 From: Alessio Del Conte Date: Fri, 2 Aug 2024 16:30:09 +0200 Subject: [PATCH] Add label test to FV --- .../page-features-viewer.component.html | 413 +++++++++--------- .../page-features-viewer.component.ts | 12 +- .../lib/ngx-features-viewer.component.html | 9 +- .../src/lib/ngx-features-viewer.component.ts | 2 +- .../src/lib/services/draw.service.ts | 2 +- .../src/lib/services/features.service.ts | 9 +- 6 files changed, 233 insertions(+), 214 deletions(-) diff --git a/projects/demo-showcase/src/app/page-features-viewer/page-features-viewer.component.html b/projects/demo-showcase/src/app/page-features-viewer/page-features-viewer.component.html index 3d98038..8aed286 100644 --- a/projects/demo-showcase/src/app/page-features-viewer/page-features-viewer.component.html +++ b/projects/demo-showcase/src/app/page-features-viewer/page-features-viewer.component.html @@ -1,206 +1,207 @@
-
-

Feature viewer

-

- The feature viewer allows you to represent features on a reference sequence. The viewer is interactive and - allows you to select features and display additional information about them in a tooltip. -

- -

- Multiple features can be grouped together in a trace. A trace can be nested in another trace, forming a tree - structure. -

- -

- Labels (left and right) can be easily customized using templates. The tooltip can also be customized using a - template. When using the template, you can access the trace (for the labels) and the trace, feature, index, and - coordinates (for the tooltip). -

-

- Example for the right label template: -

- -
-
-<ng-template let-trace="trace" ngx-features-viewer-label where="right">
-  <div class="d-flex h-100 w-100 justify-content-center align-items-center font-monospace">
-    <button class="btn btn-sm btn-primary" (click)="onTraceButtonClick(trace)">Trace { { trace.id } } </button>
-  </div>
-</ng-template>
-
-
-
- -

- It supports different types of representation for features: -

-
    -
  • - Continuous - a list of values associated 1-1 with the sequence. The curve can be represented in - different ways, using the following parameters - -
    -  {
    -    type: 'continuous';
    -    values: Array‹number›;
    -    min?: number;
    -    max?: number;
    -    "stroke-width"?: number;
    -    "stroke-color"?: string;
    -    curveType?: 'curveStep' | 'curveBasis' | 'curveLinear';
    -    showArea?: boolean;
    -  }
    -
    -
    -
  • - -
  • - Locus - a list of intervals associated with the sequence. The intervals can be represented in different - ways, using the following parameters - -
    -  {
    -    type: 'locus';
    -    start: number;
    -    end: number;
    -    height?: number;
    -    'text-color'?: string;
    -    'stroke-color'?: string;
    -    'stroke-width'?: number;
    -  }
    -
    -
    -
  • - -
  • - Polygons - a polygon that is placed in a specific position on the sequence. The polygon can be - represented in different ways, using the following parameters - -
    -  {
    -    type: 'poly';
    -    sides: number;
    -    position: number;
    -    adjustToWidth?: boolean;
    -    radius?: number;  // radius of the circle where the polygon is inscribed
    -    'stroke-color'?: string;
    -    'stroke-width'?: number;
    -  }
    -
    -
    -
  • - -
  • - Pin - a pin that is placed in a specific position on the sequence. It is a simple circle - that can be represented in different ways, using the following parameters - -
    -  {
    -    type: 'pin';
    -    position: number;
    -    adjustToWidth?: boolean;
    -    radius?: number;  // radius of the circle
    -    'stroke-color'?: string;
    -    'stroke-width'?: number;
    -  }
    -
    -
    -
  • - -
  • - DSSP - a representation of the secondary structure of a protein. The shape is different for each - secondary structure type. The representation can be customized using the following parameters - -
    -  {
    -    type: 'dssp';
    -    code: DSSPCode;  // one of 'H', 'E', 'C', 'T', ...
    -    start: number;
    -    end: number;
    -  }
    -
    -
    -
  • -
- -

- Customize the viewer -

- -

- The viewer can be customized with different settings, at different levels. The high level settings are: -

- - -
-{
-  // Define the base size of each trace
-  'content-size': number;
-  'line-height': number;
-
-  // Define margins
-  'margin-right': number;
-  'margin-left': number;
-  'margin-top': number;
-  'margin-bottom': number;
-
-  'sequence-show'?: boolean;
-  'sequence-background-color'?: 'clustalx' | 'nucleotide';
-  'sequence-background-opacity'?: number;
-  'sequence-background-height'?: '100%' | 'content-size' | 'line-height';
-
-  'x-axis-show'?: boolean;
-
-  // Define colors
-  'background-color': string;
-  'plot-background-color': string;
-  'grid-line-color': string;
-  'text-color': string;
-}
-
-
- -

- Then the some settings called options can be defined for each trace. The options are: -

- - -
-{
-  // Define the base size of the trace
-  'content-size': number;
-  'line-height': number;
-
-  'expanded': boolean; // Define if the trace is expanded or not (default is false), only works if the trace has nested traces
-
-  // Define margins between traces
-  'margin-top': number;
-  'margin-bottom': number;
-
-  // Settings for the grid line at the 0 position
-  'zero-line': boolean;
-  'zero-line-color': string;
-  'zero-line-width': number;
-
-  // Settings for the grid lines
-  'grid': boolean;
-  'grid-line-color': string;
-  'grid-line-width': number;
-  'grid-y-values': number[];
-}
-
-
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -

- Example showcase -

+ + + + + + - - Trace button clicked {{ traceButtonClicked | json }}
- Feature selected {{ featureSelected?.trace?.label | json }} {{ featureSelected?.feature?.label | json }} {{ featureSelected?.range | json }} -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
@@ -224,9 +225,17 @@

-
- -
+ @if (x$ | async) { + @if (includes(trace)) { +
+ +
+ } @else { +
+ +
+ } + }
sp|P04637|P53_HUMAN Cellular tumor antigen p53 OS=Homo sapiens OX=9606 GN=TP53 PE=1 SV=4 @@ -66,6 +66,8 @@ export class PageFeaturesViewerComponent { public traceButtonClicked: string | null = null; public featureSelected: SelectionContext | null = null; + x$: Observable = of(true).pipe(delay(3000)); + constructor(public themeSelectorService: ThemeSelectorService) { // Define theme retrieval pipeline const theme$ = this.themeSelectorService.theme$; @@ -575,4 +577,12 @@ export class PageFeaturesViewerComponent { onTraceButtonClick(trace: Trace) { this.traceButtonClicked = trace.label || 'Label not defined'; } + + test(trace: any) { + console.log(trace); + } + + includes(trace: any) { + return trace.label.includes('Trace'); + } } diff --git a/projects/ngx-features-viewer/src/lib/ngx-features-viewer.component.html b/projects/ngx-features-viewer/src/lib/ngx-features-viewer.component.html index 25e50ab..9e5719d 100644 --- a/projects/ngx-features-viewer/src/lib/ngx-features-viewer.component.html +++ b/projects/ngx-features-viewer/src/lib/ngx-features-viewer.component.html @@ -2,23 +2,22 @@ @if (initializeService.labelLeft; as label) { - @for (trace of featuresService.tracesNoNesting; track trace.id) { + @for (trace of featuresService.tracesNoNesting$ | async; track trace.id) {
- +
} } @if (initializeService.labelRight; as label) { - @for (trace of featuresService.tracesNoNesting; track trace.id) { + @for (trace of featuresService.tracesNoNesting$ | async; track trace.id) {
+ [ngTemplateOutletContext]="{ trace: trace }"/>
} } diff --git a/projects/ngx-features-viewer/src/lib/ngx-features-viewer.component.ts b/projects/ngx-features-viewer/src/lib/ngx-features-viewer.component.ts index 9b50319..a0bbee0 100644 --- a/projects/ngx-features-viewer/src/lib/ngx-features-viewer.component.ts +++ b/projects/ngx-features-viewer/src/lib/ngx-features-viewer.component.ts @@ -20,7 +20,7 @@ import { } from '@angular/core'; import * as d3 from "d3"; import { KeyboardEvent } from "react"; -import { map, Observable, Subscription, switchMap, tap } from 'rxjs'; +import { map, Observable, of, Subscription, switchMap, tap } from 'rxjs'; import { Sequence } from "./sequence"; import { DrawService } from './services/draw.service'; import { FeaturesService } from './services/features.service'; diff --git a/projects/ngx-features-viewer/src/lib/services/draw.service.ts b/projects/ngx-features-viewer/src/lib/services/draw.service.ts index 48b6bae..ca95a94 100644 --- a/projects/ngx-features-viewer/src/lib/services/draw.service.ts +++ b/projects/ngx-features-viewer/src/lib/services/draw.service.ts @@ -1058,7 +1058,7 @@ export class DrawService { } // Emit current traces - this.traces$.next(this.featuresService.tracesNoNesting.filter(trace => trace.show)); + this.traces$.next(this.featuresService.tracesNoNesting$.value.filter(trace => trace.show)); } } diff --git a/projects/ngx-features-viewer/src/lib/services/features.service.ts b/projects/ngx-features-viewer/src/lib/services/features.service.ts index 029d974..4aefc7d 100644 --- a/projects/ngx-features-viewer/src/lib/services/features.service.ts +++ b/projects/ngx-features-viewer/src/lib/services/features.service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; import { Feature } from "../features/feature"; import { InternalTrace, InternalTraces, Trace, Traces } from "../trace"; import { checkContentSettings } from './initialize.service'; @@ -7,7 +8,7 @@ import { checkContentSettings } from './initialize.service'; @Injectable({providedIn : 'platform'}) export class FeaturesService { protected traceMap = new Map(); - public tracesNoNesting!: InternalTraces; + public tracesNoNesting$ = new BehaviorSubject([]); protected _parent = new Map(); protected _children = new Map(); @@ -84,9 +85,9 @@ export class FeaturesService { // Set internal traces convert(traces, 0); - this.tracesNoNesting = Array.from(this.traceMap.values()); + this.tracesNoNesting$.next(Array.from(this.traceMap.values())); - for (const trace of this.tracesNoNesting) { + for (const trace of this.tracesNoNesting$.value) { if (trace.expanded) { trace.show = true; @@ -107,7 +108,7 @@ export class FeaturesService { } public get traces(): InternalTraces { - return this.tracesNoNesting.filter((trace) => trace.show); + return this.tracesNoNesting$.value.filter((trace) => trace.show); } /**