From 3ecd6a1da4eda2e86f6018da25d8d13dd83917d9 Mon Sep 17 00:00:00 2001 From: Manuel Holtgrewe Date: Tue, 30 Jan 2024 12:59:19 +0100 Subject: [PATCH] feat: adding GenomeBrowserCard (#45) --- package-lock.json | 6 + package.json | 1 + .../GenomeBrowserCard.spec.ts | 42 +++++++ .../GenomeBrowserCard/GenomeBrowserCard.vue | 107 ++++++++++++++++++ .../GenomeBrowserCard/constants.spec.ts | 73 ++++++++++++ src/components/GenomeBrowserCard/constants.ts | 102 +++++++++++++++++ src/components/GenomeBrowserCard/types.ts | 2 + 7 files changed, 333 insertions(+) create mode 100644 src/components/GenomeBrowserCard/GenomeBrowserCard.spec.ts create mode 100644 src/components/GenomeBrowserCard/GenomeBrowserCard.vue create mode 100644 src/components/GenomeBrowserCard/constants.spec.ts create mode 100644 src/components/GenomeBrowserCard/constants.ts create mode 100644 src/components/GenomeBrowserCard/types.ts diff --git a/package-lock.json b/package-lock.json index 92b8bf7..c0f76d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@protobuf-ts/runtime": "^2.9.3", "@reactgular/chunks": "^1.0.1", "@types/luxon": "^3.4.2", + "igv": "^2.15.11", "luxon": "^3.4.4", "title-case": "^4.3.1", "vega": "^5.27.0", @@ -11620,6 +11621,11 @@ "node": ">= 4" } }, + "node_modules/igv": { + "version": "2.15.11", + "resolved": "https://registry.npmjs.org/igv/-/igv-2.15.11.tgz", + "integrity": "sha512-oJs6z4ogv1GefIWaMdG5s4jFRuFQ/PjUgrGBMn12SbeeIC/VgHkHr56K5yIaC8ZSyameq/7IFDQaXu0qIu6cpA==" + }, "node_modules/immutable": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", diff --git a/package.json b/package.json index 727c519..7c977a1 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "@protobuf-ts/runtime": "^2.9.3", "@reactgular/chunks": "^1.0.1", "@types/luxon": "^3.4.2", + "igv": "^2.15.11", "luxon": "^3.4.4", "title-case": "^4.3.1", "vega": "^5.27.0", diff --git a/src/components/GenomeBrowserCard/GenomeBrowserCard.spec.ts b/src/components/GenomeBrowserCard/GenomeBrowserCard.spec.ts new file mode 100644 index 0000000..7eddae8 --- /dev/null +++ b/src/components/GenomeBrowserCard/GenomeBrowserCard.spec.ts @@ -0,0 +1,42 @@ +import { describe, expect, it } from 'vitest' + +import { setupMountedComponents } from '../../lib/testUtils' +import GenomeBrowserCard from './GenomeBrowserCard.vue' + +describe.concurrent('GenomeBrowserCard.vue', async () => { + it('renders the GenomeBrowserCard with the hg19 genome', async () => { + // arrange: + const { wrapper } = await setupMountedComponents( + { component: GenomeBrowserCard }, + { + props: { + genomeRelease: 'grch37', + locus: 'chr17:41246243-41246243' + } + } + ) + + // act: nothing, only test rendering + + // assert: + expect(wrapper.exists()).toBe(true) + }) + + it('renders the GenomeBrowserCard with the hg38 genome', async () => { + // arrange: + const { wrapper } = await setupMountedComponents( + { component: GenomeBrowserCard }, + { + props: { + genomeRelease: 'grch38', + locus: 'chr17:41246243-41246243' + } + } + ) + + // act: nothing, only test rendering + + // assert: + expect(wrapper.exists()).toBe(true) + }) +}) diff --git a/src/components/GenomeBrowserCard/GenomeBrowserCard.vue b/src/components/GenomeBrowserCard/GenomeBrowserCard.vue new file mode 100644 index 0000000..3da101d --- /dev/null +++ b/src/components/GenomeBrowserCard/GenomeBrowserCard.vue @@ -0,0 +1,107 @@ + + + +@/lib/GenomeBrowser.c diff --git a/src/components/GenomeBrowserCard/constants.spec.ts b/src/components/GenomeBrowserCard/constants.spec.ts new file mode 100644 index 0000000..385133b --- /dev/null +++ b/src/components/GenomeBrowserCard/constants.spec.ts @@ -0,0 +1,73 @@ +import { describe, expect, it } from 'vitest' + +import { publicTracks } from './constants' + +describe('publicTracks', () => { + it('should have at least one track', () => { + // arrange: nothing to do + // act: nothing to do + + // assert: + expect(publicTracks.length).toBeGreaterThan(0) + }) + + it('should have a name for each track', () => { + // arrange: nothing to do + // act: nothing to do + + // assert: + publicTracks.forEach((track) => { + expect(track.name).toBeDefined() + }) + }) + + it('should have a sourceType for each track', () => { + // arrange: nothing to do + // act: nothing to do + + // assert: + publicTracks.forEach((track) => { + expect(track.sourceType).toBeDefined() + }) + }) + + it('should have a format for each track', () => { + // arrange: nothing to do + // act: nothing to do + + // assert: + publicTracks.forEach((track) => { + expect(track.format).toBeDefined() + }) + }) + + it('should have a visibilityWindow for each track', () => { + // arrange: nothing to do + // act: nothing to do + + // assert: + publicTracks.forEach((track) => { + expect(track.visibilityWindow).toBeDefined() + }) + }) + + it('should have a url for each track', () => { + // arrange: nothing to do + // act: nothing to do + + // assert: + publicTracks.forEach((track) => { + expect(track.url).toBeDefined() + }) + }) + + it('should have a color for each track', () => { + // arrange: nothing to do + // act: nothing to do + + // assert: + publicTracks.forEach((track) => { + expect(track.color).toBeDefined() + }) + }) +}) diff --git a/src/components/GenomeBrowserCard/constants.ts b/src/components/GenomeBrowserCard/constants.ts new file mode 100644 index 0000000..511524b --- /dev/null +++ b/src/components/GenomeBrowserCard/constants.ts @@ -0,0 +1,102 @@ +/** Default API base URL. */ +const API_BASE_URL = `/internal/proxy/nginx/` + +/** Visiblity window to use */ +const visibilityWindow = 10000000 + +const hescTadTrack = { + name: 'hESC TADs', + sourceType: 'annotation', + format: 'bed', + visibilityWindow, + url: `${API_BASE_URL}grch37/hesc.bed`, + color: 'gray' +} + +const curatedMmsTrack = { + name: 'Curated MMS', + sourceType: 'annotation', + format: 'bed', + visibilityWindow, + url: `${API_BASE_URL}grch37/patho-mms.bed`, + color: 'red' +} + +const duplicationTrack = { + name: 'UCSC Segmental Duplications', + sourceType: 'annotation', + format: 'bed', + visibilityWindow, + url: `${API_BASE_URL}grch37/genomicSuperDups.bed.gz`, + indexURL: `${API_BASE_URL}grch37/genomicSuperDups.bed.gz.tbi`, + color: 'black' +} + +const repeatsTrack = { + name: 'UCSC Repeat Masker', + sourceType: 'annotation', + format: 'bed', + visibilityWindow, + url: `${API_BASE_URL}grch37/rmsk.bed.gz`, + indexURL: `${API_BASE_URL}grch37/rmsk.bed.gz.tbi`, + color: 'black' +} + +const altTrack = { + name: 'UCSC Alt Loci Track', + sourceType: 'annotation', + format: 'bed', + visibilityWindow, + url: `${API_BASE_URL}grch37/altSeqLiftOverPsl.bed.gz`, + indexURL: `${API_BASE_URL}grch37/altSeqLiftOverPsl.bed.gz.tbi`, + color: 'black' +} + +const fixTrack = { + name: 'UCSC Fix Track', + sourceType: 'annotation', + format: 'bed', + visibilityWindow, + url: `${API_BASE_URL}grch37/fixSeqLiftOverPsl.bed.gz`, + indexURL: `${API_BASE_URL}grch37/fixSeqLiftOverPsl.bed.gz.tbi`, + color: 'black' +} + +const bgDbTracks = [ + { + title: 'gnomad-SV', + token: 'gnomad' + }, + { + title: 'DGV SVs', + token: 'dgv' + }, + { + title: 'DGV GS SVs', + token: 'dgv-gs' + }, + { + title: 'ExAC CNVs', + token: 'exac' + } +].map(({ title, token }) => { + return { + name: title, + sourceType: 'annotation', + format: 'bed', + visibilityWindow, + displayMode: 'SQUISHED', + url: `${API_BASE_URL}grch37/${token}.bed.gz`, + indexURL: `${API_BASE_URL}grch37/${token}.bed.gz.tbi`, + color: 'black' + } +}) + +export const publicTracks = [ + duplicationTrack, + repeatsTrack, + altTrack, + fixTrack, + hescTadTrack, + curatedMmsTrack +].concat(bgDbTracks) diff --git a/src/components/GenomeBrowserCard/types.ts b/src/components/GenomeBrowserCard/types.ts new file mode 100644 index 0000000..29c20b9 --- /dev/null +++ b/src/components/GenomeBrowserCard/types.ts @@ -0,0 +1,2 @@ +/** Alias for Genome Browser type. */ +export type GenomeBrowser = any