diff --git a/src/api.js b/src/api.js index b344696..e580a7d 100644 --- a/src/api.js +++ b/src/api.js @@ -1,5 +1,11 @@ import * as d3 from 'd3'; import { getHashCode } from './helpers'; +import { MUT_TYPES } from './constants'; + +import Signature from './classes/Signature'; +import Project from './classes/Project'; +import SignatureGroup from './classes/SignatureGroup'; +import CancerType from './classes/CancerType'; const globalPlotData = {}; @@ -31,23 +37,81 @@ export default class API { return fetch(url, { method: "POST" }) .then(function(response) { return response.json(); + }) + .then(function(allData) { + let signatures = {}; + for(let mutType of MUT_TYPES) { + signatures[mutType] = allData['sigs'][mutType].map((sigData) => { + return new Signature( + sigData['name'], + sigData['description'], + sigData['index'], + sigData['publication'], + mutType + ); + }); + } + let projects = {}; + for(var projID of Object.keys(allData['projects'])) { + let projData = allData['projects'][projID]; + projects[projID] = new Project( + projID, + projData['name'], + projData['num_donors'], + projData['source'], + projData['has_clinical'], + projData['has_extended'], + projData['has_counts'] + ); + } + let sigGroups = []; + for(let sigGroupData of allData['sigs_per_cancer_type']) { + let sigGroup = new SignatureGroup( + sigGroupData['id'], + sigGroupData['group'] + ); + for(let cancerTypeData of sigGroupData['cancer-types']) { + let cancerType = new CancerType( + cancerTypeData['id'], + cancerTypeData['name'], + cancerTypeData['signatures'] + ); + sigGroup.addCancerType(cancerType); + } + sigGroups.push(sigGroup); + } + return { + 'sigs': signatures, + 'projects': projects, + 'sigs_per_cancer_type': sigGroups + }; }); } - // Fetches with cacheing - static fetchChromosomes() { - let url = API.api_base + "chromosomes"; + static fetchAutocompleteGene(partialGeneId) { + let url = API.api_base + "autocomplete-gene"; - return API.request( - fetch(url, { method: "POST" }) - .then(function(response) { - return response.json(); - }), - url, - null - ); + let body = { + "gene_id_partial": partialGeneId + }; + + return fetch(url, { method: "POST", body: JSON.stringify(body) }) + .then(function(response) { + return response.json(); + }); } + static fetchGeneEventTrack(dataOptions) { + let url = API.api_base + "genome-event-track"; + + return fetch(url, { method: "POST", body: JSON.stringify(dataOptions) }) + .then(function(response) { + return response.json(); + }); + } + + // Fetches with cacheing + static fetchKaryotype() { let url = API.api_base + "karyotype"; @@ -98,8 +162,8 @@ export default class API { ); } - static fetchSingleDonorExposures(dataOptions) { - let url = API.api_base + "exposures-single-donor"; + static fetchSingleSampleExposures(dataOptions) { + let url = API.api_base + "exposures-single-sample"; return API.request( d3.json(url, { method: "POST", body: JSON.stringify(dataOptions) }), @@ -128,8 +192,8 @@ export default class API { ); } - static fetchSingleDonorGenomeSignatureBins(dataOptions) { - let url = API.api_base + "signature-genome-bins-single-donor"; + static fetchSingleSampleGenomeSignatureBins(dataOptions) { + let url = API.api_base + "signature-genome-bins-single-sample"; dataOptions['regionWidth'] = 5000000; return API.request( @@ -148,4 +212,6 @@ export default class API { dataOptions ); } + + } \ No newline at end of file diff --git a/src/classes/CancerType.js b/src/classes/CancerType.js new file mode 100644 index 0000000..f752620 --- /dev/null +++ b/src/classes/CancerType.js @@ -0,0 +1,28 @@ +import { MUT_TYPES } from './../constants.js'; + +export default class CancerType { + + constructor(id, name, signatures) { + this.name = name; // string + this.id = id; // string + this.signatures = {}; + for(let mutType of MUT_TYPES) { + if(signatures.hasOwnProperty(mutType)) { + this.signatures[mutType] = signatures[mutType]; + } else { + this.signatures[mutType] = []; + } + } + } + + get signaturesFlat() { + let result = []; + for(let mutType of MUT_TYPES) { + for(let sig of this.signatures[mutType]) { + result.push(sig); + } + } + return result; + } + +} \ No newline at end of file diff --git a/src/classes/Project.js b/src/classes/Project.js new file mode 100644 index 0000000..d8f112e --- /dev/null +++ b/src/classes/Project.js @@ -0,0 +1,13 @@ +export default class Project { + + constructor(id, name, numDonors, source, hasClinical, hasExtended, hasCounts) { + this.id = id; + this.name = name; + this.numDonors = numDonors; + this.source = source; + this.hasClinical = hasClinical; + this.hasExtended = hasExtended; + this.hasCounts = hasCounts; + } + +} \ No newline at end of file diff --git a/src/classes/Signature.js b/src/classes/Signature.js new file mode 100644 index 0000000..a6bfe9a --- /dev/null +++ b/src/classes/Signature.js @@ -0,0 +1,12 @@ + +export default class Signature { + + constructor(name, description, index, publication, mutType) { + this.name = name; + this.description = description; + this.index = index; + this.publication = publication; + this.mutType = mutType; + } + +} \ No newline at end of file diff --git a/src/classes/SignatureGroup.js b/src/classes/SignatureGroup.js new file mode 100644 index 0000000..edf57a4 --- /dev/null +++ b/src/classes/SignatureGroup.js @@ -0,0 +1,13 @@ +export default class SignatureGroup { + + constructor(id, name) { + this.id = id; + this.name = name; + this.cancerTypes = []; + } + + addCancerType(cancerType) { + this.cancerTypes.push(cancerType); + } + +} \ No newline at end of file diff --git a/src/colors.js b/src/colors.js new file mode 100644 index 0000000..32870e0 --- /dev/null +++ b/src/colors.js @@ -0,0 +1,49 @@ +export const KARYOTYPE_COLORS = { + 'gneg': '#E3E3E3', + 'gpos25': '#8E8E8E', + 'gpos50': '#555555', + 'gpos75': '#393939', + 'gpos100': '#000000', + 'acen': '#963232', + 'stalk': '#7F7F7F', + 'gvar': '#000000' +}; + +export const MUTATION_COLORS = { + 'C>A': '#21BDEC', + 'C>G': '#000000', + 'C>T': '#E02C2E', + 'T>A': '#999999', + 'T>C': '#A2CD69', + 'T>G': '#EAC6C5', + + 'AC>NN': '#A7CEE2', + 'AT>NN': '#2679B2', + 'CC>NN': '#B3DE8E', + 'CG>NN': '#399F34', + 'CT>NN': '#F99B9B', + 'GC>NN': '#E01F27', + 'TA>NN': '#FCBE75', + 'TC>NN': '#FD7F23', + 'TG>NN': '#CAB3D5', + 'TT>NN': '#694098', + + 'D1C': '#FCBD75', + 'D1T': '#FD8024', + 'I1C': '#B1DC8F', + 'I1T': '#3BA036', + 'DR2': '#FCCAB7', + 'DR3': '#FA8A6E', + 'DR4': '#EE463A', + 'DR5+': '#BA1822', + 'IR2': '#D1E1F1', + 'IR3': '#96C4DE', + 'IR4': '#4E99C7', + 'IR5+': '#1D66A9', + 'DM2': '#E2E2EF', + 'DM3': '#B6B7D7', + 'DM4': '#8684BB', + 'DM5+': '#614399' +}; + + diff --git a/src/components/App.vue b/src/components/App.vue index 9f4a499..4992c9a 100644 --- a/src/components/App.vue +++ b/src/components/App.vue @@ -9,6 +9,7 @@ import { debounce } from 'lodash'; import { mapGetters } from 'vuex'; import API from './../api.js'; +import { MUT_TYPES } from './../constants.js'; // child components import PlotGrid from './PlotGrid.vue'; @@ -24,9 +25,6 @@ export default { let vm = this; vm.checkHash(); - API.fetchChromosomes().then(function(chromosomeLengths) { - vm.$store.commit('setChromosomeLengths', chromosomeLengths); - }); // resize bindings vm.$store.commit('setWindowWidth', window.innerWidth); @@ -40,9 +38,9 @@ export default { computed: { ...mapGetters([ 'selectedChromosome', - 'selectedSignatures', + 'selectedSignatureNames', 'selectedPlots', - 'selectedDatasets', + 'selectedDatasetNames', 'currentMode', 'currentModeTitle', 'currentModeOptions' @@ -52,32 +50,45 @@ export default { checkHash: function() { let vm = this; // check for data in hash - var paramStr = window.location.hash.substring(1) // remove the initial "#" - if(paramStr.length > 0 && paramStr.substring(0, 3) != "bib") { - var params = JSON.parse(decodeURIComponent(paramStr)); - if(params.datasets && params.signatures && params.plots && params.chr) { - vm.$store.commit('setSelectedChromosome', { - 'name': params.chr.name, - 'start': params.chr.start, - 'end': params.chr.end - }); - vm.$store.commit('setSelectedSignatures', params.signatures); - vm.$store.commit('setSelectedDatasets', params.datasets); - vm.$store.commit('setSelectedPlots', params.plots); + API.fetchDataListing().then((listing) => { + var paramStr = window.location.hash.substring(1); // remove the initial "#" + if(paramStr.length > 0 && paramStr.substring(0, 3) != "bib") { + var params = JSON.parse(decodeURIComponent(paramStr)); + if(params.datasets && params.signatures && params.plots && params.chr) { + vm.$store.commit('setSelectedChromosome', { + 'name': params.chr.name, + 'start': params.chr.start, + 'end': params.chr.end + }); + + let selectedSignatures = {}; + for(let mutType of MUT_TYPES) { + selectedSignatures[mutType] = params.signatures[mutType].map((selectedName) => { + return listing['sigs'][mutType].find((sig) => (sig.name === selectedName)); + }); + } + vm.$store.commit('setSelectedSignatures', selectedSignatures); + let selectedDatasets = []; + for(let dataset of params.datasets) { + selectedDatasets.push(listing['projects'][dataset]); + } + vm.$store.commit('setSelectedDatasets', selectedDatasets); + vm.$store.commit('setSelectedPlots', params.plots); + } + if(params.mode && params.mode.mode && params.mode.title && params.mode.options) { + vm.$store.commit('setMode', { + mode: params.mode.mode, + title: params.mode.title, + options: params.mode.options + }); + } } - if(params.mode && params.mode.mode && params.mode.title && params.mode.options) { - vm.$store.commit('setMode', { - mode: params.mode.mode, - title: params.mode.title, - options: params.mode.options - }); - } - } + }) }, setHash: function() { let hashData = { - 'datasets': this.selectedDatasets, - 'signatures': this.selectedSignatures, + 'datasets': this.selectedDatasetNames, + 'signatures': this.selectedSignatureNames, 'plots': this.selectedPlots.map((plotInfo) => { return { "type": plotInfo.type, @@ -101,13 +112,13 @@ export default { } }, watch: { - selectedSignatures: { + selectedSignatureNames: { handler: function() { this.setHash(); }, deep: true }, - selectedDatasets: { + selectedDatasetNames: { handler: function() { this.setHash(); }, diff --git a/src/components/ChromosomeSelect.vue b/src/components/ChromosomeSelect.vue index b8931ce..90602e3 100644 --- a/src/components/ChromosomeSelect.vue +++ b/src/components/ChromosomeSelect.vue @@ -9,7 +9,7 @@ + + diff --git a/src/components/Karyotype.vue b/src/components/Karyotype.vue index 6fef0ab..2c59e00 100644 --- a/src/components/Karyotype.vue +++ b/src/components/Karyotype.vue @@ -7,7 +7,7 @@