Skip to content

Commit 49f369f

Browse files
authored
Merge pull request #1017 from broadinstitute/sysbio-thursday-fixes
Sysbio thursday fixes
2 parents 1d5f0bb + 9f1c16f commit 49f369f

File tree

6 files changed

+81
-125
lines changed

6 files changed

+81
-125
lines changed

src/portals/SysBio/components/BulkTable.vue

Lines changed: 30 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,51 @@
11
<template>
2-
<div id="bulk-table" :class="isSubtable ? 'bulk-subtable' : ''">
2+
<div id="bulk-table">
33
<div>
44
<div>
55
</div>
6-
<div v-if="!isSubtable" class="text-right mb-2">
6+
<div class="text-right mb-2">
77
<data-download
88
:data="bulkData"
99
filename="bulk_gene"
1010
></data-download>
1111
</div>
1212
<div class="show-inline">
1313
<div class="table-total-rows">Total rows:{{ rows }}</div>
14-
<b-form-radio-group v-if="!isSubtable" class="show-inline"
14+
<b-form-radio-group class="show-inline"
1515
v-model="showGenes">
1616
<b-form-radio
1717
value="">
1818
All genes
1919
</b-form-radio>
2020
<b-form-radio
2121
:value="up">
22+
<span class="upregulated">&#9608;</span>
2223
Upregulated only
2324
</b-form-radio>
2425
<b-form-radio
2526
:value="down">
27+
<span class="downregulated">&#9608;</span>
2628
Downregulated only
2729
</b-form-radio>
2830
</b-form-radio-group>
2931
</div>
3032
<div v-if="tableData.length > 0">
3133
<b-table v-model="currentData"
32-
:hover="isSubtable"
34+
:hover="false"
3335
small
3436
responsive="sm"
3537
:items="tableData"
3638
:fields="config.fields"
3739
:per-page="perPage"
3840
:current-page="currentPage"
3941
:tbody-tr-class="rowClasses"
42+
:sort-by.sync="sortField"
43+
:sort-desc.sync="sortDesc"
4044
>
4145
<template #cell(gene)="r">
42-
<!-- Link to where? -->
43-
<a :href='`/gene.html?gene=${r.item.gene}`'>
44-
{{ r.item.gene }}
45-
</a>
46+
<button class="invisible-button" @click="findGene(r.item.gene)">{{ r.item.gene }}</button>
4647
</template>
47-
<template #cell(expand)="row">
48-
<b-button
49-
variant="outline-primary"
50-
size="sm"
51-
@click="showDetails(row, 1)"
52-
>
53-
{{ row.detailsShowing ? "Hide" : "Show" }}
54-
</b-button>
55-
</template>
56-
<template #row-details="row">
57-
<div class="subtable-all" v-if="
58-
subtableData[subtableKey(row.item)]?.length > 0"
59-
>
60-
<div class="row subtable-selectors">
61-
<div class="col-md-1"></div>
62-
<div class="col-md-4">
63-
<div class="label">View data by categorical field.</div>
64-
<select v-model="catField">
65-
<option v-for="field in
66-
subtableFields[subtableKey(row.item)].filter(f => f.isCat)"
67-
:value="field">
68-
{{ field.label }}
69-
</option>
70-
</select>
71-
</div>
72-
<div class="col-md-2"></div>
73-
<div class="col-md-4">
74-
75-
<div class="label">View data by continuous field.</div>
76-
<select v-model="contField">
77-
<option v-for="field in
78-
subtableFields[subtableKey(row.item)].filter(f => f.isNumerical)"
79-
:value="field">
80-
{{ field.label }}
81-
</option>
82-
</select>
83-
</div>
84-
<div class="col-md-1"></div>
85-
</div>
86-
<div class="row subtable-plots">
87-
<div class="col-md-6">
88-
<bulk-violin-plot
89-
v-if="catFields.length > 0"
90-
:data="subtableData[subtableKey(row.item)]"
91-
:gene="row.item.gene"
92-
:xField="catField?.key || catFields[0].key"
93-
:xLabel="catField?.label || catFields[0].label"
94-
/>
95-
<div v-else class="no-fields">
96-
No categorical fields available for this dataset.
97-
</div>
98-
</div>
99-
<div class="col-md-6">
100-
<scatterplot
101-
v-if="contFields.length > 0"
102-
:plotData="subtableData[subtableKey(row.item)]"
103-
:config="scatterConfig"
104-
:plotId="`bulk_${row.item.gene}`"
105-
:hideDownload="true"
106-
:tightenLeft="true">
107-
</scatterplot>
108-
<div v-else class="no-fields">
109-
No continuous fields available for this dataset.</div>
110-
</div>
111-
</div>
112-
<bulk-table
113-
:bulkData="subtableData[subtableKey(row.item)]"
114-
:config="{fields : subtableFields[subtableKey(row.item)]}"
115-
:isSubtable="true"
116-
>
117-
</bulk-table>
118-
</div>
119-
120-
</template>
121-
</b-table>
48+
</b-table>
12249
<b-pagination
12350
v-model="currentPage"
12451
class="pagination-sm justify-content-center"
@@ -156,7 +83,6 @@ export default Vue.component("bulk-table", {
15683
props: [
15784
"bulkData",
15885
"config",
159-
"isSubtable",
16086
"filter",
16187
"dataset",
16288
"highlightedGene",
@@ -176,15 +102,16 @@ export default Vue.component("bulk-table", {
176102
currentData: [],
177103
tableYField: "-log10P",
178104
tableXField: "logFoldChange",
105+
sortField: "absoluteFoldChange",
106+
sortDesc: true,
179107
up: "upregulated",
180108
down: "downregulated"
181109
};
182110
},
183111
async mounted(){
184-
if (this.isSubtable){
185-
return;
112+
if (this.highlightedGene !== ""){
113+
await this.findGene(this.highlightedGene);
186114
}
187-
await this.findGene(this.highlightedGene);
188115
this.$emit("upGenes", this.upregulatedGenes);
189116
this.$emit("downGenes", this.downregulatedGenes);
190117
},
@@ -229,7 +156,7 @@ export default Vue.component("bulk-table", {
229156
if (this.filter) {
230157
data = data.filter(this.filter);
231158
}
232-
if (!!this.showGenes && !this.isSubtable){
159+
if (!!this.showGenes){
233160
data = data.filter(item => this.showRegulation(item) === this.showGenes);
234161
}
235162
return data;
@@ -257,9 +184,6 @@ export default Vue.component("bulk-table", {
257184
tissueFormatter: Formatters.tissueFormatter,
258185
tpmFormatter: Formatters.tpmFormatter,
259186
async getSubtable(item) {
260-
if (this.isSubtable){
261-
return;
262-
}
263187
let queryKey = this.subtableKey(item);
264188
if (!this.subtableData[queryKey]) {
265189
let data = await this.query(this.config.subtableEndpoint, queryKey);
@@ -347,9 +271,6 @@ export default Vue.component("bulk-table", {
347271
return item.gene === this.highlightedGene ? "table-warning " : "";
348272
},
349273
showRegulation(item){
350-
if (this.isSubtable){
351-
return "";
352-
}
353274
let cond = this.regulationConditions;
354275
if (item[this.tableYField] < cond.yGreater){
355276
return "";
@@ -362,11 +283,19 @@ export default Vue.component("bulk-table", {
362283
}
363284
return "";
364285
},
365-
async findGene(gene){
366-
// Populate the subtable before toggling it open
286+
findGene(gene){
287+
if (gene === ""){
288+
return;
289+
}
290+
if (this.highlightedGene !== gene){
291+
this.$emit("highlightRow", gene);
292+
}
367293
this.$emit("geneFound", false);
368-
//await this.getSubtable(dataItem);
369-
let location = this.allGenes.indexOf(gene);
294+
let sortedItems = this.bulkData.toSorted(
295+
(a,b) => this.sortDesc
296+
? b[this.sortField] - a[this.sortField]
297+
: a[this.sortField] - b[this.sortField]);
298+
let location = sortedItems.findIndex(i => i.gene === gene);
370299
if (location === -1){
371300
return;
372301
}
@@ -377,18 +306,18 @@ export default Vue.component("bulk-table", {
377306
},
378307
watch: {
379308
async highlightedGene(newGene){
380-
if (!!newGene){await this.findGene(newGene)};
309+
if (!!newGene){ this.findGene(newGene)};
381310
},
382311
async tableData(data){
383-
await this.findGene(this.highlightedGene);
312+
this.findGene(this.highlightedGene);
384313
},
385314
upregulatedGenes(newGenes){
386315
this.$emit("upGenes", newGenes);
387316
},
388317
downregulatedGenes(newGenes){
389318
this.$emit("downGenes", newGenes);
390319
},
391-
currentData(newData){
320+
async currentData(newData){
392321
console.log("Current data received");
393322
}
394323
}

src/portals/SysBio/components/BulkVolcanoPlot.vue

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,30 @@ export default Vue.component("bulk-volcano-plot", {
174174
tempObj.value['y'] = v[this.yAxisField];
175175
176176
sumstat.push(tempObj);
177-
})
177+
});
178+
179+
this.svg.append("g")
180+
.attr("id", "axisLabelsGroup")
181+
.attr("transform", "translate(0,0)");
182+
183+
this.svg.select("#axisLabelsGroup")
184+
.style("font-family", "Arial").style("font-size", 12)
185+
.style("text-anchor", "middle")
186+
187+
let amp = this.$store.state.selectedAMP;
188+
let upregulatedIn = amp.split("vs")[0];
189+
this.svg.select("#axisLabelsGroup")
190+
.append("text")
191+
.attr("x", margin.left + 50)
192+
.attr("y", (height + margin.bottom))
193+
.text(`← down-regulated in ${upregulatedIn}`);
194+
195+
this.svg.select("#axisLabelsGroup")
196+
.append("text")
197+
.attr("x", margin.left + width)
198+
.attr("y", (height + margin.bottom))
199+
.attr("text-anchor", "end")
200+
.text(`up-regulated in ${upregulatedIn}`)
178201
179202
//render axis labels
180203
this.svg.append("text")

src/portals/SysBio/css/sysbio.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,3 +350,19 @@ div.filtering-ui-content div.col.filter-col-sm input {
350350
.download-images-setting:hover ul.options {
351351
display: block;
352352
}
353+
tr.upregulated {
354+
border-left: 5px solid #ff00c7 !important;
355+
}
356+
span.upregulated {
357+
color: #ff00c7 !important;
358+
}
359+
tr.downregulated {
360+
border-left: 5px solid #12bdfe !important;
361+
}
362+
span.downregulated {
363+
color: #12bdfe;
364+
}
365+
button.invisible-button {
366+
border: none;
367+
background-color: inherit;
368+
}

src/portals/SysBio/views/BulkBrowser/Template.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
<!-- BODY -->
77
<div class="sysbio-body f-col">
88
<h2>Differential Gene Expression Browser</h2>
9-
<div>
10-
Fill in differential expression documentation here.
9+
<div v-html="$parent.docs" class="docs">
1110
</div>
1211
<div class="flex-column flex-small-gap">
1312
<div id="center-width" class="flex-gap flex-column">
@@ -136,6 +135,7 @@
136135
<bulk-table
137136
:bulkData="$parent.bulkData19K"
138137
@geneFound="v => $parent.geneFound(v)"
138+
@highlightRow="gene => $parent.highlight(gene)"
139139
:dataset="$store.state.selectedDataset"
140140
:config="$parent.tableConfig"
141141
:scatterConfig="$parent.scatterplotConfig"
@@ -165,7 +165,7 @@
165165
<div class="row select-library">
166166
<div class="col-md-3">
167167
<div class="label">Select a library type</div>
168-
<select v-model="$parent.selectedLibraryType">
168+
<select v-model="$parent.selectedLibraryType" class="form-control">
169169
<option :value="''">
170170
Select a library type
171171
</option>

src/portals/SysBio/views/BulkBrowser/main.js

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ import { createColorScale } from "../../utils/visuals.js";
1212
import Scatterplot from "../../../../components/Scatterplot.vue";
1313
import BulkVolcanoPlot from "../../components/BulkVolcanoPlot.vue";
1414
import BulkTable from "../../components/BulkTable.vue";
15-
import BulkViolinPlot from "../../components/BulkViolinPlot.vue";
1615
import GeneSelectPicker from "../../../../components/GeneSelectPicker.vue";
17-
import MouseGeneSelect from "../../../../components/MouseGeneSelect.vue";
1816
import EnrichrPlot from "../../components/EnrichrPlot.vue";
1917
import Formatters from "@/utils/formatters";
2018
import uiUtils from "@/utils/uiUtils";
@@ -33,24 +31,19 @@ new Vue({
3331
Scatterplot,
3432
BulkVolcanoPlot,
3533
BulkTable,
36-
BulkViolinPlot,
3734
GeneSelectPicker,
38-
MouseGeneSelect,
3935
EnrichrPlot,
40-
// ResearchBarPlot,
41-
//CriterionFunctionGroup,
42-
//FilterGreaterThan,
43-
//ResearchSingleCellBrowser,
4436
//ResearchSingleCellInfo,
45-
//uiUtils
37+
4638
},
4739
data() {
4840
return {
4941
loading: true,
50-
foundGene: false,
42+
foundGene: true,
5143
dataReady: false,
5244
enrichrReady: false,
5345
tableHidden: false,
46+
bulkDataSortField: "absoluteFoldChange",
5447
allMetadata: null,
5548
bulkMetadata: null,
5649
plotId: "bulk_heatmap",
@@ -63,6 +56,8 @@ new Vue({
6356
enrichrDown: [],
6457
enrichrLibraries: [],
6558
enrichrByor: "matkp_enrichrlibraries", // Using MATKP list until further notice
59+
byorDocs: "sysbiofairplex_geneexpressionbrowser",
60+
docs: "",
6661
enrichrLibrary: "KEGG_2015", //hardcoding default
6762
libraryPage: 1,
6863
selectedLibraryType: "",
@@ -163,11 +158,6 @@ new Vue({
163158
selectedGene() {
164159
return this.$store.state.selectedGene;
165160
},
166-
zNormData() {
167-
let outputData = structuredClone(this.$store.state.singleBulkZNormData);
168-
outputData.forEach(item => item["-log10P"] = item.log10FDR);
169-
return outputData.sort((a,b) => a.logFoldChange - b.logFoldChange);
170-
},
171161
bulkData19K() {
172162
let results = this.$store.state.bulkData19K.filter(
173163
item => item.gene !== undefined
@@ -290,6 +280,8 @@ new Vue({
290280
}
291281
this.getParams();
292282
this.enrichrLibraries = await getTextContent(this.enrichrByor);
283+
const documentation = await getTextContent(this.byorDocs, true);
284+
this.docs = documentation;
293285
await this.$store.dispatch("queryBulkFile");
294286
await this.populateEnrichr();
295287
this.dataReady = true;

0 commit comments

Comments
 (0)