Skip to content

Commit 991144e

Browse files
authored
Merge pull request #82 from Integrative-Transcriptomics/update_wording_upsetplot
Adds help icon for dropdownboxes
2 parents b304075 + 0d17884 commit 991144e

File tree

8 files changed

+71
-52
lines changed

8 files changed

+71
-52
lines changed

server_tsspredator/server_visualization_processing.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,9 @@ def from_bedgraph_to_bw(inputDir, genome, fileType, strand, resultsDir, file, df
214214
adaptedFile = file.replace("_avg.bigwig", "_adapted.bigwig")
215215
df.to_csv(adaptedFile, sep='\t', index=False, header=False)
216216
outputBigWig = os.path.join(resultsDir, f'{genome}_{fileType}{strand}.bw')
217-
serverLocation = os.getenv('TSSPREDATOR_SERVER_LOCATION', os.path.join(os.getcwd(), "server_tsspredator"))
217+
current_location = os.getcwd()
218+
serverLocation = os.path.join(current_location, "server_tsspredator") if not current_location.endswith("server_tsspredator") else current_location
219+
serverLocation = os.getenv('TSSPREDATOR_SERVER_LOCATION', current_location)
218220
bedGraphPath = os.path.join(serverLocation, 'bedGraphToBigWig')
219221
result = subprocess.run([bedGraphPath, adaptedFile, chromSizes, outputBigWig],
220222
stdout=subprocess.PIPE,

src/components/Main/ParameterInputField.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ function FormConfig({
228228
>
229229

230230
<SingleSelectDropdown
231+
helpText={`Predefined set of parameters for the TSS prediction. The parameters can be adjusted in the parameter section.`}
232+
231233
label='Prediction parameters Preset'
232234
value={parameterPreset}
233235
onChange={(value) => {

src/components/Result.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ function Result() {
239239
{ value: "detected", label: "All detected TSSs" },
240240
]}
241241
style={{ maxWidth: "30vw"}}
242+
helpText={`Show only enriched TSSs or all detected TSSs in the UpSet plot and the Genome Viewer`}
243+
242244
/>
243245

244246
<div className='result-margin-left'>

src/components/Result/GenomeViewer.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ function GenomeViewer({ filePath, dataGosling, filter, gosRef, widthTrack, nameG
4949
<div className='gosling-component'>
5050
<div className='genome-viewer-select' style={{ paddingBottom: "1.5em" }}>
5151
<SingleSelectDropdown
52+
helpText={`Two different views are available: Single View shows the genome viewer grouped vertically by Genome/Condition, while the Aligned View aligns the strands vertically and the genomes/conditions on each row.`}
53+
5254
label="Change Genome Viewer Modus:"
5355
value={currentType}
5456
onChange={(value) => setCurrentType(value)}

src/components/Result/SingleSelect.jsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import React, { useState, useRef, useEffect } from "react";
22
import "../../css/DropDown.css"; // Import the same CSS for styling
3+
import { Info } from "lucide-react"; // Using lucide-react for the info icon
34

4-
function SingleSelectDropdown({ value, onChange, options, label, textColor = "black", style, headerStyle }) {
5+
6+
function SingleSelectDropdown({ value, onChange, options, label, textColor = "black", style, headerStyle, helpText }) {
57
const [isOpen, setIsOpen] = useState(false);
68
const [selectedOption, setSelectedOption] = useState(value);
79
const dropdownRef = useRef(null);
@@ -34,10 +36,19 @@ function SingleSelectDropdown({ value, onChange, options, label, textColor = "bl
3436

3537
return (
3638
<div className="custom-dropdown"
37-
style={{ margin: "0 1em ", color: textColor, ...style }}
39+
style={{ margin: "0 1em ", color: textColor, ...style,}}
3840
ref={dropdownRef}>
41+
<div style={{display:"flex"}}>
42+
43+
<div className="info-icon-container" style={{marginRight:"0.5em"}}>
44+
<Info style={{color:"orange"}} size={24} className="info-icon" />
45+
<div className="tooltip">{helpText}</div>
46+
</div>
3947
<h3 className="select-header" style={headerStyle}
40-
>{label}</h3>
48+
>{label}
49+
50+
</h3>
51+
</div>
4152
<div className="dropdown-header" onClick={toggleDropdown}>
4253
{options.find((opt) => opt.value === selectedOption)?.label || "Select..."}
4354
<span className="dropdown-arrow"></span>

src/components/Result/UpSet.jsx

Lines changed: 43 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ function UpSet({ showUpSet, allGenomes, filterForPlots, tableColumns, tableData,
3333
const [plotSettings, setPlotSettings] = useState({
3434
classUpsetPlot: "tssClass",
3535
type: "all",
36+
countType: "position"
3637
});
3738

3839
const handleClassUpsetPlotChange = (value) => {
@@ -41,6 +42,10 @@ function UpSet({ showUpSet, allGenomes, filterForPlots, tableColumns, tableData,
4142

4243
const handleTypeChange = (value) => {
4344
setPlotSettings((prev) => ({ ...prev, type: value }));
45+
};
46+
47+
const handleCountTSS = (value) => {
48+
setPlotSettings((prev) => ({ ...prev, countType: value }));
4449
};
4550

4651

@@ -71,7 +76,7 @@ function UpSet({ showUpSet, allGenomes, filterForPlots, tableColumns, tableData,
7176
* for upset plot: count frequncy of each tss class
7277
* and get all genome/condition names
7378
*/
74-
const TSSperPosition = (rows, columns, typeIntersection = "all") => {
79+
const TSSperPosition = (rows, columns) => {
7580
// get column indices
7681
const primaryIdx = columns.findIndex((col) => col["header"] === "Primary");
7782
const secondaryIdx = columns.findIndex((col) => col["header"] === "Secondary");
@@ -84,10 +89,8 @@ function UpSet({ showUpSet, allGenomes, filterForPlots, tableColumns, tableData,
8489

8590

8691
// save frequency of classes for a TSS (upset plot)
87-
let tssByClass = {};
8892
let tssWithMultipleClasses = {};
8993
// For the condition
90-
let tssByCondition = {};
9194
let tssWithMultipleConditions = {};
9295

9396
rows.forEach((row) => {
@@ -119,16 +122,6 @@ function UpSet({ showUpSet, allGenomes, filterForPlots, tableColumns, tableData,
119122
tssWithMultipleConditions[tmpTuple][tmpClass] = [genomeName]
120123
}
121124

122-
if (genomeName in tssByCondition) {
123-
if (!tssByCondition[genomeName].includes(tmpTuple)) {
124-
tssByCondition[genomeName].push(tmpTuple);
125-
} else if (typeIntersection === "dedup") {
126-
return; // Exit the current iteration of the loop
127-
}
128-
} else {
129-
tssByCondition[genomeName] = [tmpTuple];
130-
}
131-
132125
// add tss to tssWithMultipleClasses
133126
if (tmpTuple in tssWithMultipleClasses) {
134127
// Add once to set
@@ -147,19 +140,6 @@ function UpSet({ showUpSet, allGenomes, filterForPlots, tableColumns, tableData,
147140
tssWithMultipleClasses[tmpTuple][genomeName] = [tmpClass]
148141
}
149142

150-
151-
152-
// add tss to tssByClass
153-
if (tmpClass in tssByClass) {
154-
if (!tssByClass[tmpClass].includes(tmpTuple)) {
155-
tssByClass[tmpClass].push(tmpTuple);
156-
} else if (typeIntersection === "dedup") {
157-
return; // Exit the current iteration of the loop
158-
}
159-
} else {
160-
tssByClass[tmpClass] = [tmpTuple];
161-
}
162-
163143
}
164144
});
165145
if (plotSettings.classUpsetPlot === "tssClass") {
@@ -175,9 +155,6 @@ function UpSet({ showUpSet, allGenomes, filterForPlots, tableColumns, tableData,
175155
// create new plots
176156
processedData = TSSperPosition(tableData, tableColumns);
177157
}
178-
else if (selectedDataToShow === "dedup") {
179-
processedData = TSSperPosition(tableData, tableColumns, selectedDataToShow);
180-
}
181158
else {
182159
const genomeIdx = tableColumns.findIndex(
183160
(col) => col["header"] === "Genome" || col["header"] === "Condition"
@@ -212,7 +189,7 @@ function UpSet({ showUpSet, allGenomes, filterForPlots, tableColumns, tableData,
212189
color_tss[x] = COLORS_TSS[i]
213190
})
214191
let elems;
215-
if (plotSettings.type === "all") {
192+
if (plotSettings.countType === "classification") {
216193
elems = Object.entries(processedData).reduce((accum, curr) => {
217194
let tssName = curr[0]
218195
let mapGenomes = Object.entries(curr[1]).filter(x => x[0] !== "set").map((other) => {
@@ -240,7 +217,7 @@ function UpSet({ showUpSet, allGenomes, filterForPlots, tableColumns, tableData,
240217
}
241218
else {
242219
filteredSet = sets.filter(x => !ORDER_TSS_CLASSES.includes(x.name))
243-
if (!["all", "dedup"].includes(plotSettings.type)) {
220+
if (plotSettings.type !== "all") {
244221
filteredSet.forEach(x => x.color = color_tss[plotSettings.type])
245222
}
246223

@@ -268,21 +245,26 @@ function UpSet({ showUpSet, allGenomes, filterForPlots, tableColumns, tableData,
268245
width: "100%"
269246
}} className={showUpSet ? '' : 'hidden'}>
270247
<div className="upset-settings">
248+
<SingleSelectDropdown
249+
label="Categories to Analyze"
250+
value={plotSettings.classUpsetPlot}
251+
onChange={(value) => handleClassUpsetPlotChange(value)}
252+
options={[
253+
{ value: "tssClass", label: "TSS classes" },
254+
{ value: "conditions", label: "Conditions/Genomes" },
255+
]}
256+
helpText={`This option defines the axes of the UpSet plot.`}
257+
258+
/>
259+
271260
<SingleSelectDropdown
272261
label="Show UpSet Plot for"
273262
value={plotSettings.type}
274263
onChange={(value) => handleTypeChange(value)}
275264
options={[
276265
{
277266
value: "all",
278-
label: `Union of all TSS across ${plotSettings.classUpsetPlot === "tssClass"
279-
? "Conditions/Genomes"
280-
: "TSS classes"
281-
}`,
282-
},
283-
{
284-
value: "dedup",
285-
label: `Intersection of all TSS across ${plotSettings.classUpsetPlot === "tssClass"
267+
label: `All ${plotSettings.classUpsetPlot === "tssClass"
286268
? "Conditions/Genomes"
287269
: "TSS classes"
288270
}`,
@@ -292,17 +274,33 @@ function UpSet({ showUpSet, allGenomes, filterForPlots, tableColumns, tableData,
292274
: [...ORDER_TSS_CLASSES]
293275
).map((col) => ({ value: col, label: col })),
294276
]}
277+
helpText={`Either show data for all ${plotSettings.classUpsetPlot === "tssClass" ? "Conditions/Genomes" : "TSS classes"} or for specific ones`}
295278
/>
296279
<SingleSelectDropdown
297-
label="Categories to Analyze"
298-
value={plotSettings.classUpsetPlot}
299-
onChange={(value) => handleClassUpsetPlotChange(value)}
280+
label={`A TSSs is defined by its`}
281+
value={plotSettings.countType}
282+
onChange={(value) => handleCountTSS(value)}
283+
helpText={`A TSS can be associated with multiple ${plotSettings.classUpsetPlot === "tssClass"
284+
? "Conditions/Genomes"
285+
: "TSS classes"
286+
}. However, the genomic position is the same. This option defines how to count the TSSs, either as unique genomic positions or account also for the classification.
287+
Please consider that for the case that a TSS is classified twice as internal or antisense, it will only be counted once.`}
288+
300289
options={[
301-
{ value: "tssClass", label: "TSS classes" },
302-
{ value: "conditions", label: "Conditions/Genomes" },
290+
{
291+
value: "position",
292+
label: `Location`,
293+
},
294+
{
295+
value: "classification",
296+
label: `Location and ${plotSettings.classUpsetPlot === "tssClass"
297+
? "Conditions/Genomes"
298+
: "TSS classes"
299+
}`,
300+
}
303301
]}
304302
/>
305-
303+
306304

307305
</div>
308306

src/css/MasterTable.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ table thead {
176176
}
177177

178178
.info-icon-container {
179-
position: relative;
180-
display: flex;
179+
/* position: relative; */
180+
/* display: flex; */
181181
/* margin-right: 8px; */
182182
cursor: pointer;
183183
}

src/css/Result.css

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,11 @@ select[multiple] option:checked {
186186

187187
.upset-settings {
188188
display: flex;
189+
/* align items to bottom of div */
190+
align-items: flex-end;
189191
flex-direction: row;
190192
justify-content: space-between;
191-
align-items: center;
193+
align-items: bottom;
192194
width: 80%;
193195
margin-top: 1%;
194196
margin-bottom: 1%;

0 commit comments

Comments
 (0)