Skip to content

Commit

Permalink
Merge pull request #100 from snjlee58/master
Browse files Browse the repository at this point in the history
Addition of show/hide toggle and fixes to hits filtering feature
  • Loading branch information
milot-mirdita authored Jan 7, 2025
2 parents 23dd4c0 + 93b639d commit 734bade
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 61 deletions.
31 changes: 21 additions & 10 deletions frontend/ResultView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,13 @@
</v-tabs>
<div v-for="(entry, index) in hits.results" :key="entry.db" v-if="selectedDatabases == 0 || (index + 1) == selectedDatabases">
<v-flex class="d-flex" :style="{ 'flex-direction' : $vuetify.breakpoint.xsOnly ? 'column' : null, 'align-items': 'center' }">
<h2 style="margin-top: 0.5em; margin-bottom: 1em; display: inline-block;">
<h2 style="margin-top: 0.5em; margin-bottom: 1em; display: inline-block;" class="mr-auto">
<span style="text-transform: uppercase;">{{ entry.db }}</span> <small>{{ entry.alignments ? Object.values(entry.alignments).length : 0 }} hits</small>
</h2>

<!-- Button to toggle Sankey Diagram visibility -->
<v-btn @click="isSankeyVisible = !isSankeyVisible" class="ml-auto mr-2" large>
{{ isSankeyVisible ? 'Hide Sankey' : 'Show Sankey' }}
<v-btn v-if="entry.hasTaxonomy" @click="toggleSankeyVisibility(entry.db)" class="mr-2" large>
{{ isSankeyVisible[entry.db] ? 'Hide Taxonomy' : 'Show Taxonomy' }}
</v-btn>

<v-btn-toggle mandatory v-model="tableMode" >
Expand All @@ -112,8 +112,8 @@
</v-btn>
</v-btn-toggle>
</v-flex>
<v-flex v-if="isSankeyVisible && entry.taxonomyreport" class="mb-2">
<SankeyDiagram :rawData="entry.taxonomyreport" :currentSelectedNodeId="selectedTaxId" @selectTaxon="handleSankeySelect"></SankeyDiagram>
<v-flex v-if="entry.hasTaxonomy && isSankeyVisible[entry.db]" class="mb-2">
<SankeyDiagram :rawData="entry.taxonomyreport" :db="entry.db" :currentSelectedNodeId="selectedTaxId" :currentSelectedDb="selectedDb" @selectTaxon="handleSankeySelect"></SankeyDiagram>
</v-flex>
<table class="v-table result-table" style="position:relativ; margin-bottom: 3em;">
<colgroup>
Expand Down Expand Up @@ -185,7 +185,7 @@
</tr>
</thead>
<tbody>
<template v-for="(group, groupidx) in filteredAlignments(entry.alignments)" >
<template v-for="(group, groupidx) in filteredAlignments(entry.alignments, entry.db)" >
<tr v-for="(item, index) in group" :class="['hit', { 'active' : item.active }]">
<template v-if="index == 0 && isComplex">
<td class="thin" data-label="Query TM-score" :rowspan="group.length">{{ group[0].complexqtm.toFixed(2) }}</td>
Expand Down Expand Up @@ -281,7 +281,8 @@ export default {
activeTarget: null,
alnBoxOffset: 0,
selectedDatabases: 0,
isSankeyVisible: false,
isSankeyVisible: {}, // Track visibility for each entry.db
selectedDb: null,
selectedTaxId: null,
filteredHitsTaxIds: [],
tableMode: 0,
Expand Down Expand Up @@ -376,20 +377,30 @@ export default {
this.menuActivator.click(event);
}
},
handleSankeySelect({ nodeId, descendantIds }) {
toggleSankeyVisibility(db) {
// Toggle visibility for the specific entry.db
this.$set(this.isSankeyVisible, db, !this.isSankeyVisible[db]);
},
handleSankeySelect({ nodeId, descendantIds, db }) {
this.selectedTaxId = nodeId;
this.filteredHitsTaxIds = descendantIds ? descendantIds.map(Number) : null;
this.selectedDb = db;
},
filteredAlignments(alignments) {
filteredAlignments(alignments, db) {
// Convert alignments to an array if it is an object
if (alignments && !Array.isArray(alignments)) {
alignments = Object.values(alignments);
}
if (!Array.isArray(alignments)) {
return []; // Return an empty array if conversion fails
}
if (db !== this.selectedDb) {
// Reset filteredHitsTaxIds if db changes
return alignments;
}
if (!this.filteredHitsTaxIds || this.filteredHitsTaxIds.length === 0) {
return alignments; // Return all groups if no filteredAlignments
}
Expand Down
82 changes: 31 additions & 51 deletions frontend/SankeyDiagram.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="sankey-container">
<svg ref="sankeyContainer"></svg>
<svg ref="sankeyContainer" class="hide"></svg>
</div>
</template>

Expand All @@ -20,6 +20,14 @@ export default {
type: String,
default: null,
},
db: {
type: String,
required: true,
},
currentSelectedDb: {
type: String,
default: null,
}
},
data: () => ({
currentSelectedNode: null, // Track the currently selected node
Expand Down Expand Up @@ -66,6 +74,16 @@ export default {
});
},
},
currentSelectedDb: {
immediate: true,
handler(newValue) {
if (newValue !== this.db) {
// Reset the selected node when switching databases
this.currentSelectedNode = null;
this.createSankey(this.rawData);
}
}
}
},
methods: {
// Function for processing/parsing data
Expand All @@ -89,7 +107,7 @@ export default {
});
},
// Function for processing/parsing data
parseData(data, isFullGraph = true) {
parseData(data, isFullGraph = false) {
const nodes = [];
const unclassifiedNodes = [];
const allNodes = [];
Expand Down Expand Up @@ -151,49 +169,6 @@ export default {
currentLineage.push(node);
node.lineage = [...currentLineage];
}
} else if (this.isUnclassifiedTaxa(d)) {
// lineage tracking for unclassified taxa
let currentLineageCopy = [...currentLineage];
const parentName = d.name.replace("unclassified ", "");
let lastLineageNode = currentLineageCopy[currentLineageCopy.length - 1];
if (lastLineageNode) {
while (lastLineageNode && lastLineageNode.name !== parentName) {
currentLineageCopy.pop();
lastLineageNode = currentLineageCopy[currentLineageCopy.length - 1];
}
}
// Find the previous node in the lineage that is in rankOrder
const parentNode = currentLineageCopy.find((n) => n.name === parentName);
if (parentNode && parentNode === lastLineageNode) {
const lineage = currentLineageCopy;
let previousNode = null;
for (let i = lineage.length - 1; i >= 0; i--) {
// Start from the last item
if (this.rankOrder.includes(lineage[i].rank)) {
previousNode = lineage[i];
break;
}
}
// Determine the rank immediately to the right of this node
const parentRankIndex = this.rankOrder.indexOf(previousNode.rank);
// Edit properties for unclassified taxa
const nextRank = this.rankOrder[parentRankIndex + 1];
node.id = `dummy-${d.taxon_id}`;
node.rank = nextRank;
node.type = "unclassified";
// Add unclassified node to currentLineage and save lineage data
currentLineageCopy.push(node);
node.lineage = [...currentLineageCopy];
unclassifiedNodes.push(node);
}
}
});
Expand Down Expand Up @@ -277,6 +252,10 @@ export default {
}
const container = this.$refs.sankeyContainer;
if (!container || !container.parentElement) {
// Ensure the container and its parent are accessible
return;
}
d3.select(container).selectAll("*").remove(); // Clear the previous diagram
const nodeWidth = 30;
Expand All @@ -290,7 +269,8 @@ export default {
const svg = d3.select(container)
.attr("viewBox", `0 0 ${width} ${height}`)
.attr("width", "100%")
.attr("height", height);
.attr("height", height)
.classed("hide", false);
const sankeyGenerator = sankey()
.nodeId((d) => d.id)
Expand Down Expand Up @@ -431,7 +411,7 @@ export default {
.style("opacity", 1)
.html(`
<div style="padding-top: 4px; padding-bottom: 4px; padding-left: 8px; padding-right: 8px;">
<p style="font-size: 0.6rem; margin-bottom: 0px;">#${d.id}</p>
<p style="font-size: 0.6rem; margin-bottom: 0px;">#${d.taxon_id}</p>
<div style="display: flex; justify-content: space-between; align-items: center;">
<div style="font-weight: bold; font-size: 0.875rem;">${d.name}</div>
<span style="background-color: rgba(255, 167, 38, 0.25); color: #ffa726; font-weight: bold; padding: 4px 8px; border-radius: 12px; font-size: 0.875rem; margin-left: 10px;">${d.rank}</span>
Expand Down Expand Up @@ -468,7 +448,7 @@ export default {
// If the same node is clicked again, deselect it
if (this.currentSelectedNode && this.currentSelectedNode.id === d.id) {
this.currentSelectedNode = null;
this.$emit("selectTaxon", { nodeId: null, descendantIds: null }); // Emit an empty array to show all IDs
this.$emit("selectTaxon", { nodeId: null, descendantIds: null, db: this.db }); // Emit an empty array to show all IDs
return;
}
Expand All @@ -483,7 +463,7 @@ export default {
// Function to collect all IDs of the current node and its descendants
const collectIds = (node) => {
let childrenIds = [node.id];
let childrenIds = [node.taxon_id];
childrenIds = childrenIds.concat(this.findChildren(this.rawData, node));
return childrenIds;
};
Expand All @@ -495,7 +475,7 @@ export default {
this.currentSelectedNode = d;
// Emit the IDs array
this.$emit("selectTaxon", { nodeId: d.id, descendantIds: allNodeIds });
this.$emit("selectTaxon", { nodeId: d.taxon_id, descendantIds: allNodeIds, db: this.db });
});
;
Expand Down Expand Up @@ -574,7 +554,7 @@ export default {
for (let i = 0; i < rawData.length; i++) {
const d = rawData[i];
if (d.taxon_id === selectedNode.id) {
if (d.taxon_id === selectedNode.taxon_id) {
// Start adding child nodes from here
startAdding = true;
continue; // Move to the next iteration to skip the current node
Expand Down

0 comments on commit 734bade

Please sign in to comment.