Skip to content

Commit

Permalink
Merge branch 'ngx-structure-viewer'
Browse files Browse the repository at this point in the history
  • Loading branch information
damiclem committed Jun 20, 2024
2 parents 45e0091 + 957209c commit e27e8e0
Show file tree
Hide file tree
Showing 23 changed files with 232 additions and 167 deletions.
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ quote_type = single
[*.md]
max_line_length = off
trim_trailing_whitespace = false

[*.scss]
indent_size = 4
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ testem.log
# System files
.DS_Store
Thumbs.db
.nx/
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v18.19.1
v20.14.0
2 changes: 1 addition & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"builder": "@angular-devkit/build-angular:browser-esbuild",
"options": {
"outputPath": "docs",
"index": "projects/demo-showcase/src/index.html",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,24 @@ <h1>Feature viewer</h1>
<!-- Show output -->
<div style="display: block; height: auto; width: 100%;">
<ngx-features-viewer [sequence]="sequence" [features]="features" [settings]="settings">
<ng-template let-trace="trace" [ngx-features-viewer-label]>
<!-- Left label -->
<ng-template let-trace="trace" ngx-features-viewer-label>
<div [class.text-muted]="!trace.expanded">
{{ trace.label }}&nbsp;
<!-- Add symbol if expanded -->
@if (trace.expanded) {
<i class="bi bi-caret-down-fill"></i>
<i class="bi bi-caret-down-fill"></i>
} @else {
<i class="bi bi-caret-right"></i>
<i class="bi bi-caret-right"></i>
}
</div>
</ng-template>
<!-- Right label -->
<ng-template let-trace="trace" ngx-features-viewer-label="right">
<div [class.text-muted]="!trace.expanded">
Right label!
</div>
</ng-template>
</ngx-features-viewer>
</div>
<!-- TODO Remove this -->
Expand All @@ -72,4 +79,4 @@ <h1>Feature viewer</h1>
Suspendisse potenti. Duis imperdiet aliquam hendrerit.
</p>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ <h1>Structure viewer</h1>
<!-- Section: color chains -->
<app-section-chains></app-section-chains>
<!-- Section: show contacts -->
<!-- <app-section-interactions></app-section-interactions> -->
<app-section-interactions></app-section-interactions>
<!-- Section: show highlights -->
<!-- <app-section-highlights></app-section-highlights> -->
<app-section-highlights></app-section-highlights>
</div>
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
@if (chains$ | async; as chains) {
<!-- Section: color chains -->
<div class="row mb-3">
<!-- Example -->
<div class="col-9">
<div class="rounded squared overflow-hidden shadow-sm">
<!-- Viewer instance -->
<ngx-structure-viewer [settings]="settings" [source]="source" [loci]="chains"></ngx-structure-viewer>
</div>
<!-- Section: color chains -->
<div class="row mb-3">
<!-- Example -->
<div class="col-9">
<div class="rounded squared overflow-hidden shadow-sm">
<!-- Viewer instance -->
<ngx-structure-viewer [settings]="settings" [source]="source" [loci]="chains"></ngx-structure-viewer>
</div>
<!-- Description -->
<div class="col-3 pt-0 p-3">
<h2>Color chain</h2>
<div class="d-flex flex-column gap-2">
<!-- Loop through each chain -->
@for (chain of chains; track $index) {
<div class="flex-1">
<div class="d-flex flex-row gap-2">
<!-- Show color -->
<div class="d-block flex-shrink-0 p-2" [style.background-color]="chain.color">
<!-- Empty div -->
</div>
<!-- Show input code -->
<code class="bg-body-tertiary flex-grow-1 p-3">
<pre class="m-0">{{ chain | json }}</pre>
</code>
</div>
<!-- Description -->
<div class="col-3 pt-0 p-3">
<h2>Color chain</h2>
<div class="d-flex flex-column gap-2">
<!-- Loop through each chain -->
@for (chain of chains; track $index) {
<div class="flex-1">
<div class="d-flex flex-row gap-2">
<!-- Show color -->
<div class="d-block flex-shrink-0 p-2" [style.background-color]="chain.color">
<!-- Empty div -->
</div>
<!-- Show input code -->
<code class="bg-body-tertiary flex-grow-1 p-3">
<pre class="m-0">{{ chain | json }}</pre>
</code>
</div>
}
</div>
}
</div>
</div>
</div>
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NgxStructureViewerComponent, Locus, Settings, Source } from '@ngx-structure-viewer';
import { NgxStructureViewerComponent, Locus, Settings, Source, StructureService, PluginService } from '@ngx-structure-viewer';
import { Observable, interval, map, shareReplay, startWith } from 'rxjs';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { CommonModule } from '@angular/common';
Expand All @@ -9,6 +9,10 @@ import { CommonModule } from '@angular/common';
NgxStructureViewerComponent,
CommonModule,
],
providers: [
StructureService,
PluginService,
],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './section-chains.component.html',
Expand All @@ -22,7 +26,10 @@ export class SectionChainsComponent {

readonly chains$: Observable<Locus[]>;

constructor() {
constructor(
public structureService: StructureService,
public pluginService: PluginService,
) {
// Define settings
this.settings = {
'background-color': '#2b3035ff',
Expand Down Expand Up @@ -62,6 +69,11 @@ export class SectionChainsComponent {
// Cache result
shareReplay(1),
);

// TODO Check that service has been imported
structureService.structure$.subscribe(() => {
console.log('Hello, world!');
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { NgxStructureViewerComponent, Settings, Source } from '@ngx-structure-vi
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { Observable, map, of } from 'rxjs';
import { Observable, map, of, tap } from 'rxjs';

@Component({
selector: 'app-section-sources',
Expand Down Expand Up @@ -51,6 +51,8 @@ export class SectionSourcesComponent {
map((data: string) => new Blob([data], { type: 'text/plain' })),
// Provide local source
map((data: Blob) => ({ ...this.local, data })),
// TODO Remove this
tap((source) => console.log('Local source:', source)),
);

this.remote$ = of({ ...this.remote, link: 'https://files.rcsb.org/view/8VAP.cif' });
Expand Down
3 changes: 2 additions & 1 deletion projects/demo-showcase/src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
@import "../../../node_modules/bootstrap/scss/utilities/api";

// 8. Add additional custom code here
@import "../../../node_modules/bootstrap-icons/font/bootstrap-icons.scss";
//@import "../../../node_modules/bootstrap-icons/font/bootstrap-icons.scss";
@import "./styles/background";
@import "./styles/scaffold";
@import "./styles/utils";

Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
<div style="position: relative; display: block; width: 100%; height: 100%;" #root>
<!-- Case inner label exists -->
@if (label) {
<!-- Case template for left label exists -->
@if (labelLeft) {
<!-- Loop through each trace, generate custom tooltip -->
@for(kv of featuresService.traces | keyvalue; track $index) {
<!-- Then, generate trace as specified in the given template -->
<div [id]="'label-' + kv.key" tabindex=0 (click)="drawService.onLabelClick(kv.value)" (keyup)="drawService.onLabelClick(kv.value)">
<ng-container [ngTemplateOutlet]="label.templateRef" [ngTemplateOutletContext]="{ trace: kv.value }"></ng-container>
<div [id]="'label-left-' + kv.key" tabindex=0 (click)="drawService.onLabelClick(kv.value)" (keyup)="drawService.onLabelClick(kv.value)">
<ng-container [ngTemplateOutlet]="labelLeft.templateRef" [ngTemplateOutletContext]="{ trace: kv.value }"></ng-container>
</div>
}
}
</div>
<!-- Case template for right label exists -->
@if(labelRight) {
<!-- Loop through each trace, generate custom tooltip -->
@for(kv of featuresService.traces | keyvalue; track $index) {
<!-- Then, generate trace as specified in the given template -->
<div [id]="'label-right-' + kv.key" tabindex=0>
<ng-container [ngTemplateOutlet]="labelRight.templateRef" [ngTemplateOutletContext]="{ trace: kv.value }"></ng-container>
</div>
}
}
</div>
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
// prettier-ignore
import { AfterViewInit, ChangeDetectionStrategy, Component, ContentChild, ElementRef, HostListener, Input, OnChanges, OnDestroy, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core';
import { Observable, Subscription, tap, switchMap } from 'rxjs';
import { CommonModule } from '@angular/common';
import {
AfterContentInit,
AfterViewInit,
ChangeDetectionStrategy,
Component,
ContentChildren,
ElementRef,
HostListener,
Input,
OnChanges,
OnDestroy,
QueryList,
SimpleChanges,
ViewChild,
ViewEncapsulation
} from '@angular/core';
import {Observable, Subscription, switchMap, tap} from 'rxjs';
import {CommonModule} from '@angular/common';
// Custom components
import { NgxFeaturesViewerLabelDirective } from './ngx-features-viewer.directive';
import {NgxFeaturesViewerLabelDirective} from './ngx-features-viewer.directive';
// Custom providers
import { InitializeService } from './services/initialize.service';
import { FeaturesService } from './services/features.service';
import { ResizeService } from './services/resize.service';
import { ZoomService } from './services/zoom.service';
import { DrawService } from './services/draw.service';
import {InitializeService} from './services/initialize.service';
import {FeaturesService} from './services/features.service';
import {ResizeService} from './services/resize.service';
import {ZoomService} from './services/zoom.service';
import {DrawService} from './services/draw.service';
// Custom data types
import { Hierarchy } from './hierarchy';
import { Settings } from './settings';
import {Hierarchy} from './hierarchy';
import {Settings} from './settings';


// TODO Define sequence type
Expand All @@ -38,13 +52,17 @@ export type Sequence = Array<string>;
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class NgxFeaturesViewerComponent implements AfterViewInit, OnChanges, OnDestroy {

export class NgxFeaturesViewerComponent implements AfterViewInit, AfterContentInit, OnChanges, OnDestroy {
@ViewChild('root')
public _root!: ElementRef;

@ContentChild(NgxFeaturesViewerLabelDirective)
public label?: NgxFeaturesViewerLabelDirective;
@ContentChildren(NgxFeaturesViewerLabelDirective)
public labels?: QueryList<NgxFeaturesViewerLabelDirective>;

public labelLeft?: NgxFeaturesViewerLabelDirective;

public labelRight?: NgxFeaturesViewerLabelDirective;

@Input()
public set settings(settings: Settings) {
Expand Down Expand Up @@ -90,7 +108,7 @@ export class NgxFeaturesViewerComponent implements AfterViewInit, OnChanges, OnD
// Initialize zoom scale
tap(() => {
// const { width, height } = this.resizeService;
const { left: ms, right: me, bottom: mb } = this.resizeService.margin;
const {left: ms, right: me, bottom: mb} = this.resizeService.margin;
const h = this.resizeService.height;
const w = this.resizeService.width;
// // Define number of residues in sequnce
Expand Down Expand Up @@ -123,20 +141,41 @@ export class NgxFeaturesViewerComponent implements AfterViewInit, OnChanges, OnD
this._update = this.update$.subscribe();
}

ngOnChanges(changes: SimpleChanges): void {
public ngOnChanges(changes: SimpleChanges): void {
// Case input sequence changes
if (changes && changes['sequence']) {
// Emit sequence
this.sequence$.next(this.sequence);
}
}

ngAfterViewInit(): void {
public ngAfterContentInit(): void {
// Case label templates are defined
if (this.labels) {
// Loop thorugh each label template
this.labels.forEach((label) => {
// Case both labels are defined, then throw error
if (this.labelLeft && this.labelRight) {
throw new Error('Only one label can be defined');
}
// Case label is left
if (label.where === 'left') {
this.labelLeft = label;
}
// Case label is right
if (label.where === 'right') {
this.labelRight = label;
}
});
}
}

public ngAfterViewInit(): void {
// Emit root element
this.initService.initialize$.next(this._root);
}

ngOnDestroy(): void {
public ngOnDestroy(): void {
// Unsubscribe from update emission
this._update.unsubscribe();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Directive, TemplateRef } from '@angular/core';
import { Directive, Input, TemplateRef } from '@angular/core';

@Directive({
// eslint-disable-next-line @angular-eslint/directive-selector
Expand All @@ -7,6 +7,16 @@ import { Directive, TemplateRef } from '@angular/core';
})
export class NgxFeaturesViewerLabelDirective {

where: 'left' | 'right' = 'left';

@Input('ngx-features-viewer-label') set _where(value: 'left' | 'right' | '' | undefined) {
if (value === 'left' || value === 'right') {
this.where = value;
} else {
this.where = 'left';
}
}

constructor(public templateRef: TemplateRef<unknown>) { }

}
4 changes: 2 additions & 2 deletions projects/ngx-structure-viewer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ngx-structure-viewer",
"version": "0.0.13",
"version": "0.0.15",
"license": "MIT",
"author": {
"name": "Damiano Clementel",
Expand All @@ -9,7 +9,7 @@
"peerDependencies": {
"@angular/common": "^17.0.0",
"@angular/core": "^17.0.0",
"molstar": "^3.44.0",
"molstar": "^4.0.0",
"rxjs": "~7.8.1"
},
"dependencies": {
Expand Down
Loading

0 comments on commit e27e8e0

Please sign in to comment.