diff --git a/client/components/Heatmap.js b/client/components/Heatmap.js index f85fe3665dbd915e2da7b6bc3978a2fe44f8cc63..c40d42e36f0b0d37b794214476ac0af7e75f6106 100644 --- a/client/components/Heatmap.js +++ b/client/components/Heatmap.js @@ -2,121 +2,123 @@ import Plotly from 'plotly.js-dist'; const d3 = require("d3"); const trace1 = { - x: [], - y: [], - type: 'scatter', + x: [], + y: [], + type: 'scatter', }; const plotHeatMapSize = 1100; export default { - display: 'Scatter', - data: { - data: [trace1], - attr: { displayModeBar: false }, - layout: { - plot_bgcolor: '#d3d3d3', - paper_bgcolor: '#d3d3d3', - }, + display: 'Scatter', + data: { + data: [trace1], + attr: { displayModeBar: false }, + layout: { + plot_bgcolor: '#d3d3d3', + paper_bgcolor: '#d3d3d3', }, - makePlot(parent,selectedChr,selectedRegion){ - const layout = { - title : "Z score Heatmap", - autosize: false, + }, + makePlot(parent, selectedChr, selectedRegion) { + const layout = { + title: "Z score Heatmap", + autosize: false, + width: plotHeatMapSize, + font: { + size: 8 + }, + margin: { + l: 90, + r: 50, + b: 60, + t: 30, + pad: 4 + }, + xaxis: { + showticklabels: true, + ticks: '', + side: 'bottom', + fixedrange: true, + type: 'category' + }, + yaxis: { + ticks: '', + fixedrange: true, + ticksuffix: ' ' + }, + showlegend: false + }; - width: plotHeatMapSize, - font:{ - size:8 - }, - margin: { - l: 90, - r: 50, - b: 60, - t: 30, - pad: 4 - }, - xaxis: { - showticklabels :true, - ticks: '', - side: 'bottom', - fixedrange:true, - type: 'category' - }, - yaxis: { - ticks: '', - fixedrange:true, - ticksuffix: ' ' - }, - showlegend: false - }; + const why = this; + const idProject = parent.project.id; + d3.csv(process.env.API_URL + "/projects/" + idProject + "/heatmap/" + selectedChr + "/" + selectedRegion).then( + function (allRows) { + const cols = []; + const lines = []; + for (const valeur in allRows[0]) { + if ((valeur !== "") && (valeur !== 'ID')) { + cols.push(valeur); + } + } - const why = this; - const idProject = parent.project.id; + const arr = []; + let row = allRows[0]; - d3.csv(process.env.API_URL+"/projects/" + idProject + "/heatmap/" + selectedChr + "/"+selectedRegion).then( - function(allRows){ - const cols =[]; - const lines = []; + for (let i = 0; i < allRows.length; i++) { + row = allRows[i]; + arr.push([]); + lines[i] = row.ID; + arr[i].push(new Array(cols)); + for (let j = 0; j < cols.length; j++) { + arr[i][j] = row[cols[j]]; + } + } - for(const valeur in allRows[0]) { - if ((valeur !== "")&&(valeur!=='ID')){ - cols.push(valeur); - } - } + const data = [ + { + z: arr, + x: cols, + y: lines, + type: 'heatmap', + colorscale: [ + ['-1', '#4A6FE3'], + ['-0.9', '#5F7BE1'], + ['-0.8', '#7086E1'], + ['-0.7', '#8091E1'], + ['-0.6', '#8F9DE1'], + ['-0.5', '#9DA8E2'], + ['-0.4', '#ABB4E2'], + ['-0.3', '#B9BFE3'], + ['-0.2', '#C7CBE3'], + ['-0.1', '#D5D7E3'], + ['0', '#E2E2E2'], + ['0.1', '#E4D3D6'], + ['0.2', '#E6C4C9'], + ['0.3', '#E6B4BD'], + ['0.4', '#E5A5B1'], + ['0.5', '#E495A5'], + ['0.6', '#E28699'], + ['0.7', '#DF758D'], + ['0.8', '#DB6581'], + ['0.9', '#D75376'], + ['1', '#D33F6A'] + ], + transforms: [{ + type: 'filter', + target: 'y', + operation: '!=', + value: 'PVALmin' + }] + } + ]; - const arr = []; - let row = allRows[0]; - console.log(row); - console.log(allRows); + why.data.data = data; + why.data.layout = layout; - for (let i=0; i<allRows.length; i++) { - row = allRows[i]; - arr.push([]); - lines[i] = row.ID; - arr[i].push( new Array(cols)); - for(let j=0; j < cols.length; j++){ - arr[i][j] = row[cols[j]]; - } - } - - const data = [ - { - z: arr, - x: cols, - y: lines, - type: 'heatmap', - colorscale: [['-1','#4A6FE3'], - ['-0.9','#5F7BE1'], - ['-0.8','#7086E1'], - ['-0.7','#8091E1'], - ['-0.6','#8F9DE1'], - ['-0.5','#9DA8E2'], - ['-0.4','#ABB4E2'], - ['-0.3','#B9BFE3'], - ['-0.2','#C7CBE3'], - ['-0.1','#D5D7E3'], - ['0','#E2E2E2'], - ['0.1','#E4D3D6'],['0.2','#E6C4C9'], - ['0.3','#E6B4BD'],['0.4','#E5A5B1'], - ['0.5','#E495A5'],['0.6','#E28699'], - ['0.7','#DF758D'],['0.8','#DB6581'], - ['0.9','#D75376'],['1','#D33F6A']], - transforms: [{ - type: 'filter', - target: 'y', - operation: '!=', - value: 'PVALmin' - }] - } - ]; - - why.data.data = data; - why.data.layout = layout; - - Plotly.newPlot('divHeatPlot', why.data.data,why.data.layout,{displayModeBar: false}); - parent.submanhattan.makePlot(parent,selectedChr,selectedRegion); - } - ); - } + Plotly.newPlot('divHeatPlot', why.data.data, why.data.layout, { displayModeBar: false }); + parent.submanhattan.makePlot(parent, selectedChr, selectedRegion); + } + ); + } } diff --git a/client/components/Manhattan.js b/client/components/Manhattan.js index ce2206546e9d9c84d5ac329c810a8cf3f45df0f7..2218a041c7e094ca79abe2fa8874d64518e9b25e 100644 --- a/client/components/Manhattan.js +++ b/client/components/Manhattan.js @@ -1,326 +1,345 @@ import Plotly from 'plotly.js-dist'; const d3 = require("d3"); - -const chromosomes = [ "chr1","chr2","chr3","chr4","chr5","chr6","chr7","chr8","chr9", - "chr10","chr11","chr12","chr13","chr14","chr15","chr16","chr17","chr18","chr19", - "chr20","chr21","chr22"]; - - -const couleur = ['orangered', '#4287f5']; +const chromosomes = [ + "chr1", + "chr2", + "chr3", + "chr4", + "chr5", + "chr6", + "chr7", + "chr8", + "chr9", + "chr10", + "chr11", + "chr12", + "chr13", + "chr14", + "chr15", + "chr16", + "chr17", + "chr18", + "chr19", + "chr20", + "chr21", + "chr22" +]; + +const color = ['orangered', '#4287f5']; let trace1 = { - x: [], - y: [], - type: 'scatter', + x: [], + y: [], + type: 'scatter', }; - const tableLines = []; export default { - display: 'Scatter', - data: { - data: [trace1], - attr: { displayModeBar: false }, - layout: { - plot_bgcolor: '#d3d3d3', - paper_bgcolor: '#d3d3d3', - }, - datarows:[] + display: 'Scatter', + data: { + data: [trace1], + attr: { displayModeBar: false }, + layout: { + plot_bgcolor: '#d3d3d3', + paper_bgcolor: '#d3d3d3', }, - updateTrace(){ - trace1 = { - x: [1, 2, 3, 4], - y: [10, 15, 13, 17], + datarows: [] + }, + updateTrace() { + trace1 = { + x: [1, 2, 3, 4], + y: [10, 15, 13, 17], + type: 'scatter', + }; + + this.data.data = [trace1]; + }, + makePlot(parent) { + const plotHeatMapSize = 1100; + const why = this; + const idProject = parent.project.id; + + d3.csv(process.env.API_URL + "/projects/" + idProject + "/genome") + .then((rows) => { + why.data.datarows = rows; + const dataplot = chromosomes.map((chr) => { + const rowsFiltered = rows.filter((row) => { + return (row.CHR === chr); + }); + const xvar = unpack(rowsFiltered, 'Region'); + const yvar = unpackLog(rowsFiltered, 'JOSTmin'); + return { + name: chr, + x: xvar, + y: yvar, + text: unpackText(rowsFiltered), + hovertemplate: '%{text}', + mode: 'markers', + showlegend: false, type: 'scatter', - }; - this.data.data = [trace1]; - - }, - makePlot(parent){ - const plotHeatMapSize = 1100; - - const why = this; - const idProject = parent.project.id; - - d3.csv(process.env.API_URL+"/projects/" + idProject + "/genome").then( - function(rows){ - why.data.datarows =rows; - const dataplot = chromosomes.map(function(chr) { - - const rowsFiltered = rows.filter(function(row) { - return (row.CHR === chr); - }); - const xvar = unpack(rowsFiltered, 'Region'); - const yvar = unpackLog(rowsFiltered, 'JOSTmin'); - return { - name: chr, - x: xvar, - y: yvar, - - text: unpackText(rowsFiltered), - - - hovertemplate: '%{text}', - mode: 'markers', - showlegend : false, - type:'scatter', - marker: { - color: 'red' - } - } - }); - - why.data.data = dataplot; - - - - - const layout = { - title: "Joint test association results by regions", - width: plotHeatMapSize, - hovermode:'closest', - showLink: false, - modeBarButtonsToRemove: [], - font:{ - size:8 - }, - margin: { - l: 80, - r: 50, - b: 60, - t: 30, - pad: 4 - }, - xaxis: { - - showgrid : true, - showticklabels :true, - tickmode: "array", - tickvals: ['Region67', 'Region206', 'Region339', 'Region461', - 'Region577', 'Region688', 'Region793', 'Region890', - 'Region974', 'Region1053', 'Region1138', 'Region1221', - 'Region1293', 'Region1352', 'Region1405', 'Region1457', - 'Region1507', 'Region1555', 'Region1598', 'Region1637', - 'Region1668', 'Region1692'], - ticktext: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', - '12', '13', '14', '15', '16', '17', '18', '19', '20', - '21', '22'], - tickfont: { - family: 'Arial, sans-serif', - size: 12, - color: 'black', - }, - title: "chromosome", - side: 'bottom', - type: 'category', - range : [0,'1704'], - - }, - yaxis: { - - range : [0,'2.3'], - // autorange: true, - title: "-log(Pvalue)", - type: 'log', - - - tickfont: { - family: 'Arial, sans-serif', - size: 10, - color: 'black' - } - - }, - }; - - why.data.layout = layout - - let k = 1; - let i; - let j; - const markerOffset = 0.04; - - for (i = 0; i < dataplot.length; i++) { - - k = 1-k; - dataplot[i].marker.color = couleur[k]; - - for (j=0; j<dataplot[i].x.length; j++){ - const dict = { - "type": 'line', - "xref": 'x', - "yref": 'y', - "x0": dataplot[i].x[j], - "y0": 0.01, - "x1": dataplot[i].x[j], - "y1": offsetSignal( dataplot[i].y[j], markerOffset), - "line": { - color: dataplot[i].marker.color, - width: 0.3 - } - }; - - tableLines.push(dict); - } - } - - - const update = { - shapes: tableLines - }; - - - const suggestiveline = -Math.log10(1e-5); - const suggestivelineColor = "orange"; - - const genomewideline = -Math.log10(5e-8); - const genomewidelineColor = "green"; - - const datmp = dataplot[0]; - const tbx = datmp.x; - const d = tbx[0]; - - const datmp2 = dataplot[dataplot.length-1]; - const tbx2 = datmp2.x - const e = tbx2[tbx2.length-1]; - - const trace1 = { - x: [d, e], - y: [suggestiveline, suggestiveline], - mode: 'lines+markers+text', - name: '1e-5', - textposition: 'top', - type: 'scatter', - showlegend: true, - marker: { - color: suggestivelineColor - } - }; - - const trace2 = { - x: [d, e], - y: [genomewideline, genomewideline], - mode: 'lines+markers+text', - name: '5e-8', - textposition: 'top', - type: 'scatter', - showlegend: true, - marker: { - color: genomewidelineColor - } - }; - - why.data.layout.shapes = tableLines; - why.data.data.push(trace1); - why.data.data.push(trace2); - - Plotly.newPlot('divWholeStatPlot', why.data.data,why.data.layout,{displayModeBar: false}); - parent.$refs.divWholeStatPlot.on('plotly_click', function(data){ - parent.isready2=true; - why.reactOnClick(data); - Plotly.update('divWholeStatPlot',why.data.layout); - - const selectedChr = data.points.map(function(d){ - return d.data.name; - - }); - - const selectedRegion = data.points[0].x; - parent.heatmap.makePlot(parent,selectedChr,selectedRegion); - - }); - - }); - }, - reactOnClick(data){ - let updaterange = data.points[0].x.split("Region"); - - console.log("updaterange " + updaterange); // __Modif__CN__ - - console.log(updaterange[1]); - // region 840 -> 850 - const tmp= Number(updaterange[1])+10; - - console.log("tmp " + tmp); // __Modif__CN__ - - updaterange = "Region"+tmp; - console.log("updaterange "+updaterange); - - const selectRectangle = { - "type": 'rect', - // x-reference is assigned to the x-values - "xref": 'x', - // y-reference is assigned to the plot paper [0,1] - "yref": 'paper', - "x0": data.points[0].x, - "y0": 0, - "x1": updaterange, - "y1": 1, - "fillcolor": '#d3d3d3', - "opacity": 0.6, - "line": { - width: 0 + marker: { + color: 'red' + } + } + }); + + why.data.data = dataplot; + + const layout = { + title: "Joint test association results by regions", + width: plotHeatMapSize, + hovermode: 'closest', + showLink: false, + modeBarButtonsToRemove: [], + font: { + size: 8 + }, + margin: { + l: 80, + r: 50, + b: 60, + t: 30, + pad: 4 + }, + xaxis: { + showgrid: true, + showticklabels: true, + tickmode: "array", + tickvals: [ + 'Region67', + 'Region206', + 'Region339', + 'Region461', + 'Region577', + 'Region688', + 'Region793', + 'Region890', + 'Region974', + 'Region1053', + 'Region1138', + 'Region1221', + 'Region1293', + 'Region1352', + 'Region1405', + 'Region1457', + 'Region1507', + 'Region1555', + 'Region1598', + 'Region1637', + 'Region1668', + 'Region1692' + ], + ticktext: [ + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '10', + '11', + '12', + '13', + '14', + '15', + '16', + '17', + '18', + '19', + '20', + '21', + '22' + ], + tickfont: { + family: 'Arial, sans-serif', + size: 12, + color: 'black', + }, + title: "chromosome", + side: 'bottom', + type: 'category', + range: [0, '1704'], + }, + yaxis: { + range: [0, '2.3'], + title: "-log(Pvalue)", + type: 'log', + tickfont: { + family: 'Arial, sans-serif', + size: 10, + color: 'black' } + }, }; - console.log(selectRectangle); - if (tableLines[tableLines.length - 1].type === 'rect') { - console.log("ca marche"); - tableLines.pop(); + why.data.layout = layout + + let k = 1; + let i; + let j; + const markerOffset = 0.04; + + for (i = 0; i < dataplot.length; i++) { + + k = 1 - k; + dataplot[i].marker.color = color[k]; + + for (j = 0; j < dataplot[i].x.length; j++) { + const dict = { + "type": 'line', + "xref": 'x', + "yref": 'y', + "x0": dataplot[i].x[j], + "y0": 0.01, + "x1": dataplot[i].x[j], + "y1": offsetSignal(dataplot[i].y[j], markerOffset), + "line": { + color: dataplot[i].marker.color, + width: 0.3 + } + }; + + tableLines.push(dict); + } } - tableLines.push(selectRectangle); - console.log(this.data.layout); - this.data.layout.shapes = tableLines; - } + const update = { + shapes: tableLines + }; + + const suggestiveline = -Math.log10(1e-5); + const suggestivelineColor = "orange"; + + const genomewideline = -Math.log10(5e-8); + const genomewidelineColor = "green"; + + const datmp = dataplot[0]; + const tbx = datmp.x; + const d = tbx[0]; + + const datmp2 = dataplot[dataplot.length - 1]; + const tbx2 = datmp2.x + const e = tbx2[tbx2.length - 1]; + + const trace1 = { + x: [d, e], + y: [suggestiveline, suggestiveline], + mode: 'lines+markers+text', + name: '1e-5', + textposition: 'top', + type: 'scatter', + showlegend: true, + marker: { + color: suggestivelineColor + } + }; + const trace2 = { + x: [d, e], + y: [genomewideline, genomewideline], + mode: 'lines+markers+text', + name: '5e-8', + textposition: 'top', + type: 'scatter', + showlegend: true, + marker: { + color: genomewidelineColor + } + }; + why.data.layout.shapes = tableLines; + why.data.data.push(trace1); + why.data.data.push(trace2); + + Plotly.newPlot('divWholeStatPlot', why.data.data, why.data.layout, { displayModeBar: false }); + parent.$refs.divWholeStatPlot.on('plotly_click', function (data) { + parent.isready2 = true; + why.reactOnClick(data); + Plotly.update('divWholeStatPlot', why.data.layout); + + const selectedChr = data.points.map(function (d) { + return d.data.name; + + }); + + const selectedRegion = data.points[0].x; + parent.heatmap.makePlot(parent, selectedChr, selectedRegion); + + }); + + }); + }, + reactOnClick(data) { + let updaterange = data.points[0].x.split("Region"); + const tmp = Number(updaterange[1]) + 10; + updaterange = "Region" + tmp; + const selectRectangle = { + "type": 'rect', + // x-reference is assigned to the x-values + "xref": 'x', + // y-reference is assigned to the plot paper [0,1] + "yref": 'paper', + "x0": data.points[0].x, + "y0": 0, + "x1": updaterange, + "y1": 1, + "fillcolor": '#d3d3d3', + "opacity": 0.6, + "line": { + width: 0 + } + }; + + if (tableLines[tableLines.length - 1].type === 'rect') { + tableLines.pop(); + } + tableLines.push(selectRectangle); + this.data.layout.shapes = tableLines; + } }; - // --------------------------------------------------------------------------------------------------------------------------- function offsetSignal(signal, markerOffset) { - - let result = 0; - if (Math.abs(signal) > markerOffset) { - if (signal > 0) { - result = signal - markerOffset; - } - else { - result = signal + markerOffset; - } + let result = 0; + if (Math.abs(signal) > markerOffset) { + if (signal > 0) { + result = signal - markerOffset; + } + else { + result = signal + markerOffset; } - return result; + } + return result; } - // --------------------------------------------------------------------------------------------------------------------------- function unpack(rows, key) { - return rows.map(function(row) { return row[key]; }); + return rows.map((row) => { return row[key]; }); } // --------------------------------------------------------------------------------------------------------------------------- function unpackLog(rows, key) { - return rows.map(function(row) { return -Math.log10(row[key]); }); + return rows.map((row) => { return -Math.log10(row[key]); }); } // --------------------------------------------------------------------------------------------------------------------------- function unpackText(rows) { - return rows.map(function(row) { - - const rsid = row.snp_ids; - const pos = row.MiddlePosition/1000000; - const chr = row.CHR; - const pval = row.JOSTmin; - const text = 'rsid: '+rsid+'<br>'+'pos: '+chr+':'+pos.toFixed(2)+'<br>-log(Pvalue): '+pval+'<extra></extra>'; - return text; - - }); - } + return rows.map(function (row) { + const rsid = row.snp_ids; + const pos = row.MiddlePosition / 1000000; + const chr = row.CHR; + const pval = row.JOSTmin; + const text = 'rsid: ' + rsid + '<br>' + 'pos: ' + chr + ':' + pos.toFixed(2) + '<br>-log(Pvalue): ' + pval + '<extra></extra>'; + return text; + }); +} diff --git a/client/components/PhenotypeCard.vue b/client/components/PhenotypeCard.vue index 0e35cdd25f5bab2580b03e0779d60c16c20a3fdb..cd38dab76ba49d68143066941292a9c90fe5cc2c 100644 --- a/client/components/PhenotypeCard.vue +++ b/client/components/PhenotypeCard.vue @@ -1,11 +1,5 @@ <template> <span style="padding:8px;font-size:16px;"> - <!-- <v-text-field - v-text=data.fullname - label="Phenotype Name" - filled - ></v-text-field> --> - <!-- v-text="pheno.id.slice(0, 1).toUpperCase()" --> <v-dialog persistent width=500> @@ -19,15 +13,15 @@ mdi-information </v-icon> {{ phe.full_name }} - </v-chip> - </template> + <template #default="dialog"> <v-card width="500" elevation="6"> <v-toolbar color="#298e49" - dark>Phenotype: {{ phe.full_name }}</v-toolbar> + dark>Phenotype: {{ phe.full_name }} + </v-toolbar> <v-card-text style="padding-top:12px;"> <p> @@ -55,16 +49,11 @@ mdi-close </v-icon> Close - </v-btn> </v-card-actions> - - </v-card> </template> - </v-dialog> - </span> </template> @@ -79,5 +68,4 @@ export default { } } } -// props: ['fullname'] </script> diff --git a/client/components/ShareLink.vue b/client/components/ShareLink.vue index 01038937bfaf00431d2f18e09f9bf3005f8e10fc..c1751d683d7ebe564b217949b1378a913bbbb965 100644 --- a/client/components/ShareLink.vue +++ b/client/components/ShareLink.vue @@ -1,48 +1,46 @@ <template> - <v-speed-dial v-model="dialShare" absolute top right direction="left" open-on-hover> - <template #activator> - <v-btn fab bottom small color="primary"> - <v-icon v-if="dialShare">mdi-close</v-icon> - <v-icon v-else>mdi-share-variant</v-icon> - </v-btn> - </template> - <v-btn dark fab bottom color="blue darken-7" small :href="`https://www.linkedin.com/shareArticle?mini=true&url=${pageUrl}`" target="_blank"> - <v-icon>mdi-linkedin</v-icon> - </v-btn> - <v-btn dark fab bottom color="blue" small :href="`https://www.facebook.com/sharer/sharer.php?u=${pageUrl}`" target="_blank"> - <v-icon>mdi-facebook</v-icon> - </v-btn> - <v-btn dark fab bottom color="green" small :href="`https://wa.me/?text=Checkout%20this%20page.%20${pageUrl}`" target="_blank"> - <v-icon>mdi-whatsapp</v-icon> - </v-btn> - <v-btn dark fab bottom color="primary" small :href="`mailto:?subject=JASS analysis&body=Here is an analysis computed in JASS: ${pageUrl}`" target="_blank" title="Send by mail"> - <v-icon>mdi-email</v-icon> - </v-btn> - <v-btn dark fab bottom color="primary" small title="Copy to clipboard" @click="copySign()"> - <v-icon>mdi-clipboard</v-icon> - </v-btn> - </v-speed-dial> + <v-speed-dial v-model="dialShare" absolute top right direction="left" open-on-hover> + <template #activator> + <v-btn fab bottom small color="primary"> + <v-icon v-if="dialShare">mdi-close</v-icon> + <v-icon v-else>mdi-share-variant</v-icon> + </v-btn> + </template> + <v-btn dark fab bottom color="blue darken-7" small :href="`https://www.linkedin.com/shareArticle?mini=true&url=${pageUrl}`" target="_blank"> + <v-icon>mdi-linkedin</v-icon> + </v-btn> + <v-btn dark fab bottom color="blue" small :href="`https://www.facebook.com/sharer/sharer.php?u=${pageUrl}`" target="_blank"> + <v-icon>mdi-facebook</v-icon> + </v-btn> + <v-btn dark fab bottom color="green" small :href="`https://wa.me/?text=Checkout%20this%20page.%20${pageUrl}`" target="_blank"> + <v-icon>mdi-whatsapp</v-icon> + </v-btn> + <v-btn dark fab bottom color="primary" small :href="`mailto:?subject=JASS analysis&body=Here is an analysis computed in JASS: ${pageUrl}`" target="_blank" title="Send by mail"> + <v-icon>mdi-email</v-icon> + </v-btn> + <v-btn dark fab bottom color="primary" small title="Copy to clipboard" @click="copySign()"> + <v-icon>mdi-clipboard</v-icon> + </v-btn> + </v-speed-dial> </template> <script> - export default { - props: { - pageUrl: { - type: String, - default: '' - } - }, - data() { - return { - dialShare: false - } - }, - methods: { - copySign() { - navigator.clipboard.writeText(this.pageUrl); - } +export default { + props: { + pageUrl: { + type: String, + default: '' + } + }, + data() { + return { + dialShare: false + } + }, + methods: { + copySign() { + navigator.clipboard.writeText(this.pageUrl); } - } - +} </script> diff --git a/client/components/SubManhattan.js b/client/components/SubManhattan.js index defec35a6a59a541a505b2a1311da0d4e50cc51b..abe578dedcb895779fa52060e626411b23abd25a 100644 --- a/client/components/SubManhattan.js +++ b/client/components/SubManhattan.js @@ -1,140 +1,123 @@ import Plotly from 'plotly.js-dist'; const d3 = require("d3"); -const couleur = ['red', 'blue']; +const color = ['red', 'blue']; const trace1 = { - x: [], - y: [], - type: 'scatter', + x: [], + y: [], + type: 'scatter', }; const plotHeatMapSize = 1100; - export default { - display: 'Scatter', - data: { - data: [trace1], - attr: { displayModeBar: false }, - layout: { - plot_bgcolor: '#d3d3d3', - paper_bgcolor: '#d3d3d3', - }, + display: 'Scatter', + data: { + data: [trace1], + attr: { displayModeBar: false }, + layout: { + plot_bgcolor: '#d3d3d3', + paper_bgcolor: '#d3d3d3', }, - makePlot(parent,selectedChr,selectedRegion){ - - const why =this; - const numberColor = (selectedChr + 1) % 2; - - - const idProject = parent.project.id; - d3.csv(process.env.API_URL+"/projects/" + idProject + "/manhattan/" + selectedChr + "/"+selectedRegion).then( - function(allRows){ - - const regions = []; - for (let i = 0; i < 2000; i++) { - regions[i] = "Region" + i; + }, + makePlot(parent, selectedChr, selectedRegion) { + const why = this; + const numberColor = (selectedChr + 1) % 2; + const idProject = parent.project.id; + + d3.csv(process.env.API_URL + "/projects/" + idProject + "/manhattan/" + selectedChr + "/" + selectedRegion) + .then((allRows) => { + const regions = []; + + for (let i = 0; i < 2000; i++) { + regions[i] = "Region" + i; + } + + const data = regions.map((region) => { + const rowsFiltered = allRows.filter((row) => { + return (row.Region === region); + }); + + return { + name: region, + x: unpack(rowsFiltered, 'snp_ids'), + y: unpackLog(rowsFiltered, 'JASS_PVAL'), + text: unpack(rowsFiltered, 'Region'), + mode: 'markers', + type: 'scatter', + marker: { + color: color[numberColor] } - - const data = regions.map(function(region) { - - const rowsFiltered = allRows.filter(function(row) { - return (row.Region === region); - }); - - return { - name: region, - x: unpack(rowsFiltered, 'snp_ids'), - y: unpackLog(rowsFiltered, 'JASS_PVAL'), - text: unpack(rowsFiltered, 'Region'), - mode: 'markers', - type:'scatter', - marker: { - color: couleur[numberColor] - } - } - // __Modif__CN__ - }); - - const titleplot = "Joint test association results for locus " + - selectedRegion + " on " + selectedChr; - - console.log("titleplot " + titleplot); // __Modif__CN__ - - const layout = { - title: titleplot, - width: plotHeatMapSize, - hovermode: 'closest', - font:{ - size:8 - }, - margin: { - l: 90, - r: 90, - b: 10, - t: 100, - pad: 4 - }, - xaxis: { - showticklabels :false, - ticks: '', - side: 'top', - type: 'category', - range : [-0.5,allRows.length] - }, - yaxis: { - title: "-log(Pvalue)", - ticks: '', - ticksuffix: ' ', - fixedrange:true, - }, - - }; - - why.data.data = data; - why.data.layout = layout; - - Plotly.newPlot('divLocalStatPlot', why.data.data,why.data.layout,{displayModeBar: false}); - - parent.$refs.divLocalStatPlot.on('plotly_relayout', - function(eventdata){ - console.log(eventdata); - const update = { - 'xaxis.range': [eventdata['xaxis.range[0]'], - eventdata['xaxis.range[1]']] - } - Plotly.relayout('divHeatPlot',update); - }); - - + } }); - - } - + const titleplot = "Joint test association results for locus " + selectedRegion + " on " + selectedChr; + + const layout = { + title: titleplot, + width: plotHeatMapSize, + hovermode: 'closest', + font: { + size: 8 + }, + margin: { + l: 90, + r: 90, + b: 10, + t: 100, + pad: 4 + }, + xaxis: { + showticklabels: false, + ticks: '', + side: 'top', + type: 'category', + range: [-0.5, allRows.length] + }, + yaxis: { + title: "-log(Pvalue)", + ticks: '', + ticksuffix: ' ', + fixedrange: true, + }, + }; + + why.data.data = data; + why.data.layout = layout; + + Plotly.newPlot('divLocalStatPlot', why.data.data, why.data.layout, { displayModeBar: false }); + + parent.$refs.divLocalStatPlot.on('plotly_relayout', + function (eventdata) { + const update = { + 'xaxis.range': [eventdata['xaxis.range[0]'], + eventdata['xaxis.range[1]']] + } + Plotly.relayout('divHeatPlot', update); + }); + }); + } } function unpack(rows, key) { - return rows.map(function(row) { return row[key]; }); + return rows.map((row) => { return row[key]; }); } // --------------------------------------------------------------------------------------------------------------------------- function unpackLog(rows, key) { - return rows.map(function(row) { return -Math.log10(row[key]); }); + return rows.map((row) => { return -Math.log10(row[key]); }); } // --------------------------------------------------------------------------------------------------------------------------- function unpackText(rows) { - return rows.map(function(row) { - - const rsid = row.snp_ids; - const pos = row.MiddlePosition/1000000; - const chr = row.CHR; - const pval = row.JOSTmin; - const text = 'rsid: '+rsid+'<br>'+'pos: '+chr+':'+pos.toFixed(2)+'<br>-log(Pvalue): '+pval+'<extra></extra>'; - return text; - - }); - } + return rows.map((row) => { + const rsid = row.snp_ids; + const pos = row.MiddlePosition / 1000000; + const chr = row.CHR; + const pval = row.JOSTmin; + const text = 'rsid: ' + rsid + '<br>' + 'pos: ' + chr + ':' + pos.toFixed(2) + '<br>-log(Pvalue): ' + pval + '<extra></extra>'; + return text; + }); +} diff --git a/client/pages/index.vue b/client/pages/index.vue index f453e1d02db721144715b09781d6f026142b3cc6..50fd46f198be6c1283ea623486b7e5082c6ec0a3 100644 --- a/client/pages/index.vue +++ b/client/pages/index.vue @@ -66,8 +66,7 @@ export default { }, myImg: '/jass19Avrilsmall.jpg' } - ], - initmeta: {}, + ] } } } diff --git a/client/pages/projects/_id.vue b/client/pages/projects/_id.vue index 69c3e5c9458273c76fdaac37d18326b86f96f600..65d5331f376c0703e70abdca3ce433d8d8ae11a9 100644 --- a/client/pages/projects/_id.vue +++ b/client/pages/projects/_id.vue @@ -1,6 +1,5 @@ <template> <v-container> - <v-row v-show="!isready" class="fill-height" align-content="center" @@ -27,8 +26,6 @@ </v-col> </v-row> <v-row v-show="isready" align="center"> - - <v-col cols="12"> <v-card> <ShareLink :page-url="sharedUrl" style="top:-1em" /> @@ -77,8 +74,8 @@ Univariate only significant Regions: {{ summary.JASSNotSignif.MinUnivSignif }}<br> Multivariate only significant Regions : {{ summary.JASSSignif.MinUnivNotSignif }}<br> Univariate and multivariate significant Regions : {{ summary.JASSSignif.MinUnivSignif }}<br> - </v-col> + <v-col> <vue-json-to-csv :json-data="Regions" :csv-title="'LD-independent lead SNPs - ' + project.id"> <v-btn small color="#298e49" style="color:#fff; text-transform:capitalize;" @click="processExportAllJASSPVAL()"> @@ -170,15 +167,10 @@ class="elevation-1"></v-data-table> <vue-json-to-csv :json-data="significantsRegions" :csv-title="'Significants regions - ' + project.id"> <v-btn small color="#298e49" style="color:#fff;">export csv</v-btn> - <!-- <button> - <b>export csv</b> - </button> --> </vue-json-to-csv> </p> </transition> </div> - - </v-card-title> </v-card> @@ -192,9 +184,6 @@ </v-row> <div id="divLocalStatPlot" ref="divLocalStatPlot"><!-- Plotly chart will be drawn inside this DIV --></div> - <!-- <v-card-title >Univariate Zscore heatmap</v-card-title> - <v-card-text>Association signal for each SNPs and Each phenotypes. The association is measured as a Zscore (beta regression coefficient divided by their standard error). - </v-card-text> --> <div id="divHeatPlot"><!-- Plotly chart will be drawn inside this DIV --></div> </v-card> </v-col> @@ -208,31 +197,21 @@ <script> import VueJsonToCsv from 'vue-json-to-csv'; import Plotly from 'plotly.js-dist'; - import PhenotypeCard from "@/components/PhenotypeCard.vue"; import ShareLink from "@/components/ShareLink.vue"; - - import manhattan from "../../components/Manhattan.js"; import heatmap from "../../components/Heatmap.js"; import submanhattan from "../../components/SubManhattan.js"; - - const _ = require('lodash'); - -console.log(heatmap); const d3 = require("d3"); - export default { components: { VueJsonToCsv, PhenotypeCard }, async asyncData({ $axios, params, $auth }) { - - const project = await $axios.$get('/projects/' + params.id,) console.log(project); const phenotypes = []; @@ -241,13 +220,19 @@ export default { project.phenotypes.forEach(pheno => { phenotypes.push(pheno.id); }) + project.phenotypes.forEach(pheno => { outcomes.push(pheno.outcome); }) const phenotypesDict = project.phenotypes; + return { - project, phenotypes, outcomes, phenotypesDict, ShareLink + project, + phenotypes, + outcomes, + phenotypesDict, + ShareLink } }, data() { @@ -268,32 +253,26 @@ export default { progress: 0, gencov: null, metadata: { "nb_phenotypes": 0, "nb_snps": 0 }, - summary: { "JASSSignif": { "MinUnivNotSignif": 0, "MinUnivSignif": 0 }, "JASSNotSignif": { "MinUnivNotSignif": 0, "MinUnivSignif": 0 } }, + summary: { + "JASSSignif": { + "MinUnivNotSignif": 0, + "MinUnivSignif": 0 + }, + "JASSNotSignif": { + "MinUnivNotSignif": 0, + "MinUnivSignif": 0 + } + }, sharedUrl: '' } }, - created() { this.status = this.getStatus(); }, - methods: { - createPlots() { - if (this.status != null) { - console.log(this.status); - } - console.log("SUMMARY"); - console.log(this.summary); - console.log(this.summary.JASSSignif.MinUnivNotSignif); - const zLine = []; - console.log("X"); - const x = this.outcomes.sort(); - console.log(x); - console.log("GENCOV"); - console.log(this.gencov); for (let i = 0; i < x.length; i++) { zLine.push([]); @@ -310,7 +289,6 @@ export default { } } - console.log(zLine) const dataplot = [ { z: zLine, @@ -336,8 +314,6 @@ export default { } ]; - console.log(dataplot); - const layout = { width: 400, margin: { l: 100, r: 100, t: 10, b: 80 }, @@ -348,29 +324,19 @@ export default { showgrid: false, showline: true } - }; - this.manhattan = manhattan; this.heatmap = heatmap; this.submanhattan = submanhattan; manhattan.makePlot(this); Plotly.newPlot('divCorrelationHeat', dataplot, layout, { displayModeBar: false }); - - console.log(this.$refs); - console.log(this.$refs.divWholeStatPlot); - }, - - createHeatmapPlot() { Plotly.newPlot('divWholeStatPlot', manhattan.data.data, manhattan.data.layout); this.$refs.divWholeStatPlot.on('plotly_click', function (data) { - console.log(data); - manhattan.reactOnClick(data); Plotly.update('divWholeStatPlot', manhattan.data.layout); }); @@ -378,22 +344,18 @@ export default { }, quadranPlot() { const desiredLink = process.env.API_URL + "/projects/" + this.project.id + "/quadrant"; - console.log("quadrant " + desiredLink); window.open(desiredLink, '_blank'); }, qqPlot() { const desiredLink = process.env.API_URL + "/projects/" + this.project.id + "/qqplot"; - console.log("qq " + desiredLink); window.open(desiredLink, '_blank'); }, manhattanPlot() { const desiredLink = process.env.API_URL + "/projects/" + this.project.id + "/globalmanhattan"; - console.log("globalmanhattan " + desiredLink); window.open(desiredLink, '_blank'); }, genomeFullCsv() { const desiredLink = process.env.API_URL + "/projects/" + this.project.id + "/genome_full"; - console.log("manhattan " + desiredLink); window.open(desiredLink, '_blank'); }, processShowGJASSPVAL() { @@ -420,41 +382,33 @@ export default { }, async getStatus() { - - await this.$axios.$get('/projects/' + this.project.id).then((async function (result) { - console.log(result.status.worktable); - console.log(result.progress); this.progress = result.progress; - this.sharedUrl = "http://" + window.location.host + "/projects/" + this.project.id; - console.log(this.project.id); this.status = result.status; - if (result.status.metadata === "READY" && !this.isready) { + if (result.status.metadata === "READY" && !this.isready) { await this.$axios.$get('/projects/' + this.project.id + "/gencov").then((async function (result2) { this.gencov = result2; await this.$axios.$get('/projects/' + this.project.id + "/summary").then((function (result3) { this.summary = result3; - console.log(result3); - // show Plot ... this.isready = true; this.createPlots(); - console.log("ready"); }).bind(this)); await this.$axios.$get('/projects/' + this.project.id + "/metadata").then((function (result4) { this.metadata = result4; }).bind(this)); }).bind(this)).catch(error => { - console.error(error.response.data.detail); this.gencov = { 'error': error.response.data.detail } this.isready = true; }); } + let keepFetching = true; + for (const step in result.status) { if (result.status[step] !== "READY") { keepFetching = true @@ -463,14 +417,13 @@ export default { keepFetching = false; } } + if (keepFetching) { setTimeout(this.getStatus, 5000); } }).bind(this)).catch((function () { setTimeout(this.getStatus, 10000); }).bind(this)); - - } } } @@ -483,10 +436,8 @@ export default { } .fade-enter, -.fade-leave-to - -/* .fade-leave-active below version 2.1.8 */ - { +.fade-leave-to { + /* .fade-leave-active below version 2.1.8 */ opacity: 0; } @@ -499,10 +450,8 @@ export default { } .slide-fade-enter, -.slide-fade-leave-to - -/* .slide-fade-leave-active below version 2.1.8 */ - { +.slide-fade-leave-to { + /* .slide-fade-leave-active below version 2.1.8 */ transform: translateX(10px); opacity: 0; }