diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 52af528ff..219cab2bf 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -2,7 +2,6 @@ import { NgModule } from '@angular/core';
import { Routes, RouterModule, NoPreloading } from '@angular/router';
import { GeneDetailsComponent } from './gene-details/gene-details.component';
-import { GeneAlleleListComponent } from './gene-allele-list/gene-allele-list.component';
import { GeneProteinFeaturesComponent } from './gene-protein-features/gene-protein-features.component';
import { GenotypeDetailsComponent } from './genotype-details/genotype-details.component';
import { AlleleDetailsComponent } from './allele-details/allele-details.component';
@@ -25,13 +24,14 @@ import { IdentifierMapperResultsComponent } from './identifier-mapper-results/id
import { getAppConfig } from './config';
import { RefGenesViewComponent } from './ref-genes-view/ref-genes-view.component';
import { CurationStatsComponent } from './curation-stats/curation-stats.component';
+import { GeneAllelesPageComponent } from './gene-alleles-page/gene-alleles-page.component';
const routes: Routes = [
{ path: 'gene/:uniquename', component: GeneDetailsComponent,
data: {
}
},
- { path: 'gene_alleles/:uniquename', component: GeneAlleleListComponent,
+ { path: 'gene_alleles/:uniquename', component: GeneAllelesPageComponent,
data: {
}
},
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 8eca84f7a..ff45c7116 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -157,6 +157,7 @@ import { RefGenesViewComponent } from './ref-genes-view/ref-genes-view.component
import { CurationStatsComponent } from './curation-stats/curation-stats.component';
import { AnnotationTableWidgetsComponent } from './annotation-table-widgets/annotation-table-widgets.component';
import { StatsSummaryComponent } from './stats-summary/stats-summary.component';
+import { GeneAllelesPageComponent } from './gene-alleles-page/gene-alleles-page.component';
@Pipe({ name: 'safeUrl' })
export class SafeUrlPipe implements PipeTransform {
@@ -280,6 +281,7 @@ export class SafeUrlPipe implements PipeTransform {
CurationStatsComponent,
AnnotationTableWidgetsComponent,
StatsSummaryComponent,
+ GeneAllelesPageComponent,
],
imports: [
BrowserModule,
diff --git a/src/app/gene-allele-list/gene-allele-list.component.css b/src/app/gene-allele-list/gene-allele-list.component.css
index cede4118e..637733b9d 100644
--- a/src/app/gene-allele-list/gene-allele-list.component.css
+++ b/src/app/gene-allele-list/gene-allele-list.component.css
@@ -34,3 +34,7 @@ td {
padding-left: 0.5em;
border-left: 2px solid black;
}
+
+.view-genotype {
+ white-space: nowrap;
+}
diff --git a/src/app/gene-allele-list/gene-allele-list.component.html b/src/app/gene-allele-list/gene-allele-list.component.html
index 3ce6c38ed..d1a2c6b73 100644
--- a/src/app/gene-allele-list/gene-allele-list.component.html
+++ b/src/app/gene-allele-list/gene-allele-list.component.html
@@ -1,85 +1,47 @@
-
diff --git a/src/app/gene-allele-list/gene-allele-list.component.ts b/src/app/gene-allele-list/gene-allele-list.component.ts
index 689a15ef1..8cd4dc77c 100644
--- a/src/app/gene-allele-list/gene-allele-list.component.ts
+++ b/src/app/gene-allele-list/gene-allele-list.component.ts
@@ -1,153 +1,74 @@
-import { Component, OnInit, Input } from '@angular/core';
+import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
-import { ActivatedRoute, Params } from '@angular/router';
-import { GeneDetails, PombaseAPIService, GenotypeShort,
- AlleleShort } from '../pombase-api.service';
-import { DeployConfigService } from '../deploy-config.service';
-import { Util } from '../shared/util';
+import { AlleleShort } from '../pombase-api.service';
-class AlleleSection {
- public nameAndDescription: string;
-
- constructor(public alleleUniquename: string,
- public alleleName: string,
- public alleleDescription: string,
- public alleleType: string,
- public expressedAlleles: Array) {
- this.alleleName = Util.tidyAlleleName(alleleName);
-
- let description = this.alleleDescription;
-
- if (!description) {
- description = 'unknown';
- this.alleleDescription = '';
- }
-
- this.nameAndDescription = name + '(' + description + ')';
- }
-
- expressedAlleleCount(): number {
- return this.expressedAlleles.length;
- }
-
- genotypeCount(): number {
- let count = 0;
-
- for (const expressedAllele of this.expressedAlleles) {
- count += expressedAllele.genotypes.length;
- }
-
- return count;
+class DisplayAllele {
+ displayName: string;
+ constructor(public uniquename: string,
+ public name: string,
+ public description: string,
+ public alleleType: string) {
+ this.displayName = this.name.replace(/,/g, ',');
+ this.description = this.description.replace(/,/g, ',');
}
-}
-
-class ExpressedAlleleSection {
- constructor(public expression: string, public genotypes: Array) {
+ nameDescription(): string {
+ return (this.name || 'unknown') + '(' + (this.name || 'unknown') + ')';
}
}
-type ExpressedAlleleMap = { [expression: string]: Array };
-type AlleleMap = { [alleleUniquename: string]: ExpressedAlleleMap };
-
-function genotypeSorter(g1: GenotypeShort, g2: GenotypeShort) {
- if (g1.loci.length < g2.loci.length) {
- return -1;
- }
- if (g1.loci.length > g2.loci.length) {
- return 1;
- }
-
- if (g1.loci[0].expressed_alleles.length < g2.loci[0].expressed_alleles.length) {
- return -1;
- }
- if (g1.loci[0].expressed_alleles.length > g2.loci[0].expressed_alleles.length) {
- return 1;
- }
-
- return g1.displayNameLong.localeCompare(g2.displayNameLong);
-}
-
@Component({
selector: 'app-gene-allele-list',
templateUrl: './gene-allele-list.component.html',
styleUrls: ['./gene-allele-list.component.css']
})
-export class GeneAlleleListComponent implements OnInit {
- @Input() geneDetails: GeneDetails;
-
- alleleTable: Array;
- sortByColumnName: string = 'type';
-
- genotypeVisible: { [key: string ]: boolean } = {};
-
- constructor(private pombaseApiService: PombaseAPIService,
- private route: ActivatedRoute,
- public deployConfigService: DeployConfigService) { }
+export class GeneAlleleListComponent implements OnChanges {
+ @Input() alleles: Array;
- genotypesVisible(allele: AlleleSection): boolean {
- return !!this.genotypeVisible[allele.alleleUniquename];
- }
-
- anyVisibleGenotypes(): boolean {
- return Object.keys(this.genotypeVisible).length > 0;
- }
-
- showGenotypes(allele: AlleleSection): void {
- this.genotypeVisible[allele.alleleUniquename] = true;
- }
-
- showAllGenotypes(): void {
- for (const allele of this.alleleTable) {
- this.genotypeVisible[allele.alleleUniquename] = true;
- }
- }
+ displayAlleles: Array = [];
- hideAllGenotypes(): void {
- this.genotypeVisible = {};
- }
+ sortByColumnName: string = 'type';
- alleleRowspan(allele: AlleleSection): number {
- if (this.genotypesVisible(allele)) {
- return allele.genotypeCount();
- } else {
- return 1;
- }
- }
+ constructor() { }
sortBy(columnName: 'name'|'description'|'type'): void {
this.sortByColumnName = columnName;
- this.sortTable();
+ this.makeTable();
}
- sortTable(): void {
+ makeTable(): void {
+ this.displayAlleles =
+ this.alleles.map(a => {
+ return new DisplayAllele(a.uniquename, a.name, a.description, a.allele_type);
+ });
+
if (this.sortByColumnName == 'type') {
- this.alleleTable.sort((a, b) => {
+ this.displayAlleles.sort((a, b) => {
if (a.alleleType === b.alleleType) {
- return a.nameAndDescription.localeCompare(b.nameAndDescription);
+ return a.nameDescription().localeCompare(b.nameDescription());
} else {
return a.alleleType.localeCompare(b.alleleType);
}
});
} else {
- this.alleleTable.sort((a, b) => {
+ this.displayAlleles.sort((a, b) => {
let result;
if (this.sortByColumnName === 'name') {
- result = a.alleleName.localeCompare(b.alleleName);
+ result = a.name.localeCompare(b.name);
} else {
- if (a.alleleDescription.length == 0 && b.alleleDescription.length == 0) {
+ if (a.description.length == 0 && b.description.length == 0) {
result = 0;
} else {
- if (a.alleleDescription.length == 0) {
+ if (a.description.length == 0) {
// missing / blank description sort last
result = 1;
} else {
- if (b.alleleDescription.length == 0) {
+ if (b.description.length == 0) {
return -1
} else {
- result = a.alleleDescription.localeCompare(b.alleleDescription);
+ result = a.description.localeCompare(b.description);
}
}
}
@@ -159,86 +80,10 @@ export class GeneAlleleListComponent implements OnInit {
return result;
})
-
}
}
- makeAlleleTable(): void {
- this.alleleTable = [];
-
- const alleleExpressionGenotypeMap: AlleleMap = {};
-
- const alleleMap: { [alleleUniquename: string]: AlleleShort } = {};
-
- GENOTYPE:
- for (const genotypeUniquename of Object.keys(this.geneDetails.genotypes_by_uniquename)) {
- const genotypeShort = this.geneDetails.genotypes_by_uniquename[genotypeUniquename];
-
- for (const locus of genotypeShort.loci) {
- for (const expressedAllele of locus.expressed_alleles) {
- const allele = expressedAllele.allele;
-
- if (allele.gene_uniquename !== this.geneDetails.uniquename) {
- continue;
- }
-
- if (!alleleMap[allele.uniquename]) {
- alleleMap[allele.uniquename] = allele;
- }
-
- if (!alleleExpressionGenotypeMap[allele.uniquename]) {
- alleleExpressionGenotypeMap[allele.uniquename] = {};
- }
-
- const expressedAlleleMap = alleleExpressionGenotypeMap[allele.uniquename];
-
- if (!expressedAlleleMap[expressedAllele.expression]) {
- expressedAlleleMap[expressedAllele.expression] = [];
- }
-
- expressedAlleleMap[expressedAllele.expression].push(genotypeShort);
- }
- }
- }
-
- for (const [alleleUniquename, expressedAlleleMap] of Object.entries(alleleExpressionGenotypeMap)) {
- const expressedAlleleSections = [];
- for (const [expression, genotypes] of Object.entries(expressedAlleleMap)) {
- genotypes.sort(genotypeSorter);
- expressedAlleleSections.push(new ExpressedAlleleSection(expression, genotypes));
- }
-
- expressedAlleleSections.sort((a, b) =>
- a.expression.localeCompare(b.expression)
- );
-
- const alleleShort = alleleMap[alleleUniquename];
-
- const alleleName = alleleShort.name;
- const alleleDescription = alleleShort.description;
- const alleleType = alleleShort.allele_type;
-
- const alleleSection =
- new AlleleSection(alleleUniquename, alleleName, alleleDescription, alleleType,
- expressedAlleleSections);
- this.alleleTable.push(alleleSection);
- }
-
- this.sortTable();
- }
-
- ngOnInit(): void {
- this.route.params.forEach((params: Params) => {
- if (params['uniquename'] !== undefined) {
- let uniquename = params['uniquename'];
-
- this.pombaseApiService.getGene(uniquename)
- .then(geneDetails => {
- this.geneDetails = geneDetails;
-
- this.makeAlleleTable();
- });
- }
- })
+ ngOnChanges(changes: SimpleChanges): void {
+ this.makeTable();
}
}
diff --git a/src/app/gene-alleles-page/gene-alleles-page.component.css b/src/app/gene-alleles-page/gene-alleles-page.component.css
new file mode 100644
index 000000000..9ad876a35
--- /dev/null
+++ b/src/app/gene-alleles-page/gene-alleles-page.component.css
@@ -0,0 +1,7 @@
+.allele-section {
+ padding-bottom: 1em;
+}
+
+.deletion, .wild-type {
+ font-size: 150%;
+}
\ No newline at end of file
diff --git a/src/app/gene-alleles-page/gene-alleles-page.component.html b/src/app/gene-alleles-page/gene-alleles-page.component.html
new file mode 100644
index 000000000..c7989dc88
--- /dev/null
+++ b/src/app/gene-alleles-page/gene-alleles-page.component.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+ Wild type allele
1">s:
+
+
+
0">
+
0 || wildtypeAlleles.length > 0">
+ Other alleles:
+
+
+
+
diff --git a/src/app/gene-alleles-page/gene-alleles-page.component.spec.ts b/src/app/gene-alleles-page/gene-alleles-page.component.spec.ts
new file mode 100644
index 000000000..c572c6e57
--- /dev/null
+++ b/src/app/gene-alleles-page/gene-alleles-page.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { GeneAllelesPageComponent } from './gene-alleles-page.component';
+
+describe('GeneAllelesPageComponent', () => {
+ let component: GeneAllelesPageComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ GeneAllelesPageComponent ]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(GeneAllelesPageComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/gene-alleles-page/gene-alleles-page.component.ts b/src/app/gene-alleles-page/gene-alleles-page.component.ts
new file mode 100644
index 000000000..96e559ef0
--- /dev/null
+++ b/src/app/gene-alleles-page/gene-alleles-page.component.ts
@@ -0,0 +1,75 @@
+import { Component, OnInit, Input } from '@angular/core';
+
+import { ActivatedRoute, Params } from '@angular/router';
+import { GeneDetails, PombaseAPIService, AlleleShort } from '../pombase-api.service';
+import { DeployConfigService } from '../deploy-config.service';
+
+@Component({
+ selector: 'app-gene-alleles-page',
+ templateUrl: './gene-alleles-page.component.html',
+ styleUrls: ['./gene-alleles-page.component.css']
+})
+export class GeneAllelesPageComponent implements OnInit {
+ @Input() geneDetails: GeneDetails;
+
+ deletionAlleles: Array = [];
+ wildtypeAlleles: Array = [];
+ otherAlleles: Array = [];
+
+ constructor(private pombaseApiService: PombaseAPIService,
+ private route: ActivatedRoute,
+ public deployConfigService: DeployConfigService) { }
+
+ makeAlleleTables(): void {
+ this.deletionAlleles = [];
+ this.wildtypeAlleles = [];
+ this.otherAlleles = [];
+
+ const seenAlleles: Set = new Set();
+
+ for (const genotypeUniquename of Object.keys(this.geneDetails.genotypes_by_uniquename)) {
+ const genotypeShort = this.geneDetails.genotypes_by_uniquename[genotypeUniquename];
+
+ for (const locus of genotypeShort.loci) {
+ for (const expressedAllele of locus.expressed_alleles) {
+ const allele = expressedAllele.allele;
+
+ if (allele.gene_uniquename !== this.geneDetails.uniquename) {
+ continue;
+ }
+
+ if (seenAlleles.has(allele.uniquename)) {
+ continue;
+ }
+
+ seenAlleles.add(allele.uniquename);
+
+ if (allele.allele_type == 'deletion') {
+ this.deletionAlleles.push(allele);
+ } else {
+ if (allele.allele_type == 'wild_type') {
+ this.wildtypeAlleles.push(allele);
+ } else {
+ this.otherAlleles.push(allele);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ngOnInit(): void {
+ this.route.params.forEach((params: Params) => {
+ if (params['uniquename'] !== undefined) {
+ let uniquename = params['uniquename'];
+
+ this.pombaseApiService.getGene(uniquename)
+ .then(geneDetails => {
+ this.geneDetails = geneDetails;
+
+ this.makeAlleleTables();
+ });
+ }
+ })
+ }
+}
diff --git a/src/styles.css b/src/styles.css
index 37a7d889b..a4cf83e79 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -202,7 +202,7 @@ html body hr {
}
ul {
- padding-left: 25px;
+ padding-left: 1.5em;
}
.app-link {