From 718f12b99daaf48dcbb576c67117d08c58faa27a Mon Sep 17 00:00:00 2001 From: Remi PLANEL <rplanel@pasteur.fr> Date: Thu, 25 Apr 2024 14:59:33 +0200 Subject: [PATCH] add elevated card --- components/OperonStructure.vue | 17 ++- components/content/ArticleStructure.vue | 104 ++++++++------- .../content/ArticleSystemDistributionPlot.vue | 121 +++++++++--------- components/content/PdockqMatrix.vue | 36 ++++-- components/content/SystemOperonStructure.vue | 24 ++-- 5 files changed, 170 insertions(+), 132 deletions(-) diff --git a/components/OperonStructure.vue b/components/OperonStructure.vue index 2ea26c63..93fa51e1 100644 --- a/components/OperonStructure.vue +++ b/components/OperonStructure.vue @@ -23,7 +23,7 @@ const margin = ref<PlotMargin>({ marginLeft: 5, }) - +const snackbar = ref(false) const plotHeight = computed(() => { const { marginTop, marginBottom } = toValue(margin) @@ -211,13 +211,24 @@ function drawGene({ width, height }) { <div ref="gbContainer"> <v-card flat color="transparent"> <v-card-item> - <v-card-title>Operon structure</v-card-title> + <v-card-title>Operon structure <v-btn size="x-small" density="comfortable" variant="tonal" + icon="mdi-help" @click="snackbar = true"> + </v-btn></v-card-title> <v-card-subtitle>defenseFinder model version : {{ structureVersion }}</v-card-subtitle> </v-card-item> - <v-alert size="small" type="info" variant="text"> click on structure to visualize them</v-alert> + <svg ref="svgRef" :width="computedContainerWidth" :height="plotHeight"> <g class="x-axis" /> </svg> + <v-snackbar v-model="snackbar"> + Click on the structure image to + visualize it. + <template v-slot:actions> + <v-btn color="info" variant="text" @click="snackbar = false"> + Close + </v-btn> + </template> + </v-snackbar> </v-card> </div> </template> \ No newline at end of file diff --git a/components/content/ArticleStructure.vue b/components/content/ArticleStructure.vue index 8333dc67..814b1da0 100644 --- a/components/content/ArticleStructure.vue +++ b/components/content/ArticleStructure.vue @@ -105,55 +105,65 @@ async function fetchStructures() { </script> <template> - <v-card flat> + <v-card flat color="transparent"> + <template v-for="[subsystem, structures] in perSubsystemStructures" :key="subsystem[0]"> - <ProseH3>{{ subsystem }}</ProseH3> - <SystemOperonStructure :system="computedSystem" :subsystem="subsystem" :structures="structures" /> + <!-- <ProseH3>{{ subsystem }}</ProseH3> --> + <v-card-text class="pa-1"> + <SystemOperonStructure :system="computedSystem" :subsystem="subsystem" :structures="structures" /> + </v-card-text> </template> - <ProseH3>Summary</ProseH3> - <v-data-table :headers="headers" :items="sanitizedStructures" :group-by="groupBy"> - <template #[`item.proteins_in_the_prediction`]="{ item }"> - <CollapsibleChips - :items="namesToCollapsibleChips(item.proteins_in_the_prediction, item.system, item.fasta_file)"> - </CollapsibleChips> - </template> - <template #[`item.system_genes`]="{ item }"> - <CollapsibleChips :items="namesToCollapsibleChips(item.system_genes, item.system)"> - </CollapsibleChips> - - </template> - <template v-slot:group-header="{ item, columns, toggleGroup, isGroupOpen }"> - <tr> - <td :colspan="columns.length"> - <VBtn :icon="isGroupOpen(item) ? '$expand' : '$next'" size="small" variant="text" - @click="toggleGroup(item)"></VBtn> - {{ item.value === 'na' ? 'No subtype' : item.value }} - </td> - </tr> - </template> - <template #[`item.structure`]="{ item }"> - <v-row justify="space-between" dense no-gutters align="center"> - <v-col> - <v-btn size="x-small" variant="text" icon="md:visibility" - @click="displayStructure(item)"></v-btn> - </v-col> - <v-col> - <v-menu> - <template v-slot:activator="{ props }"> - <v-btn :disabled="item.structuresUrls?.length < 1" size="x-small" variant="text" - icon="md:download" class="ml-1" v-bind="props"></v-btn> - </template> - <v-list> - <v-list-item v-for="(url, index) in item.structuresUrls" :key="index" :value="index" - :href="url"> - <v-list-item-title>{{ url.split('.').slice(-1)[0] }}</v-list-item-title> - </v-list-item> - </v-list> - </v-menu> - </v-col> - </v-row> - </template> - </v-data-table> + <!-- <ProseH3>Summary</ProseH3> --> + <v-card-text class="pa-1"> + <v-card variant="elevated" elevation="1"> + <v-card-item> + <v-card-title>Summary</v-card-title> + </v-card-item> + <v-data-table :headers="headers" :items="sanitizedStructures" :group-by="groupBy"> + <template #[`item.proteins_in_the_prediction`]="{ item }"> + <CollapsibleChips + :items="namesToCollapsibleChips(item.proteins_in_the_prediction, item.system, item.fasta_file)"> + </CollapsibleChips> + </template> + <template #[`item.system_genes`]="{ item }"> + <CollapsibleChips :items="namesToCollapsibleChips(item.system_genes, item.system)"> + </CollapsibleChips> + + </template> + <template v-slot:group-header="{ item, columns, toggleGroup, isGroupOpen }"> + <tr> + <td :colspan="columns.length"> + <VBtn :icon="isGroupOpen(item) ? '$expand' : '$next'" size="small" variant="text" + @click="toggleGroup(item)"></VBtn> + {{ item.value === 'na' ? 'No subtype' : item.value }} + </td> + </tr> + </template> + <template #[`item.structure`]="{ item }"> + <v-row justify="space-between" dense no-gutters align="center"> + <v-col> + <v-btn size="x-small" variant="text" icon="md:visibility" + @click="displayStructure(item)"></v-btn> + </v-col> + <v-col> + <v-menu> + <template v-slot:activator="{ props }"> + <v-btn :disabled="item.structuresUrls?.length < 1" size="x-small" variant="text" + icon="md:download" class="ml-1" v-bind="props"></v-btn> + </template> + <v-list> + <v-list-item v-for="(url, index) in item.structuresUrls" :key="index" + :value="index" :href="url"> + <v-list-item-title>{{ url.split('.').slice(-1)[0] }}</v-list-item-title> + </v-list-item> + </v-list> + </v-menu> + </v-col> + </v-row> + </template> + </v-data-table> + </v-card> + </v-card-text> <PdbeMolstarPlugin v-model:title="structureTitle" /> </v-card> </template> \ No newline at end of file diff --git a/components/content/ArticleSystemDistributionPlot.vue b/components/content/ArticleSystemDistributionPlot.vue index 4013dafa..1d38ba8c 100644 --- a/components/content/ArticleSystemDistributionPlot.vue +++ b/components/content/ArticleSystemDistributionPlot.vue @@ -215,7 +215,7 @@ async function fetchRefSeqTaxo() { </script> <template> - <v-card flat color="transparent"> + <v-card flat color="transparent" class="pa-1"> <v-card-text> Among the {{ d3.format(",")(systemStatistics.totalGenome) }} complete genomes of RefSeq, the {{ page.title }} is @@ -224,69 +224,62 @@ async function fetchRefSeqTaxo() { The system was detected in {{ d3.format(",")(systemStatistics.speciesWithSystem) }} different species. </v-card-text> - - <v-card flat :loading="pending"> - <v-row no-gutters> - <v-col> - <v-select v-model="selectedTaxoRank" :items="taxoRanks" density="compact" - label="Select taxonomic rank" hide-details="auto" class="mx-2"></v-select> - </v-col> - <!-- <v-col cols="12" md="4"> - <v-select v-model="plotY" :items="axisOptions" density="compact" label="Y axis based on" - hide-details="auto" class="mx-2"></v-select> - </v-col> - <v-col cols="12" md="4"> - <v-select v-model="plotFill" :items="axisOptions" density="compact" label="Color based on" - hide-details="auto" class="mx-2"></v-select> - </v-col> --> - </v-row> - <v-row class="d-flex" no-gutters> - <v-col cols="12" md="5"> - <v-card flat> - <v-card-item class="mb-4"> - <v-card-title> Genome Percent - </v-card-title> - </v-card-item> - <v-card-text class="pr-0"> - <v-range-slider v-model="genomePercentValue" step="1" thumb-label="always" - :min="genomePercentDomain[0]" :max="genomePercentDomain[1]"> - <template #append> - <v-btn variant="text" density="compact" icon="md:restart_alt" - @click="resetPercent()"></v-btn> - </template></v-range-slider> - </v-card-text> - </v-card> - </v-col> - <v-col cols="12" md="7"> - <v-card flat> - <v-card-item> - <v-card-title> Minimum genomes count to display - </v-card-title> - </v-card-item> - <v-card-text class="pr-0"> - <v-row> - - <v-col> - <v-text-field density="compact" v-model="genomeCountValue" type="number" - :disabled="!genomeCountThreshold" :min="genomeCountDomain[0]" - :max="genomeCountDomain[1]" hide-details></v-text-field> - </v-col> - <v-col cols="3"> - <v-switch v-model="genomeCountThreshold" color="primary" - :label="genomeCountThreshold ? 'activated' : 'disabled'" - hide-details></v-switch> - </v-col> - </v-row> - </v-card-text> - </v-card> - </v-col> - - </v-row> - <PlotFigure v-if="!pending" ref="systemsDistributionPlot" :options="unref(distributionOptions)" defer> - </PlotFigure> - <v-card v-else> - {{ pending }}... - </v-card> + <v-card variant="elevated" elevation="1" :loading="pending"> + <v-card-text> + <v-row no-gutters> + <v-col> + <v-select v-model="selectedTaxoRank" :items="taxoRanks" density="compact" + label="Select taxonomic rank" hide-details="auto" class="mx-2"></v-select> + </v-col> + </v-row> + <v-row class="d-flex" no-gutters> + <v-col cols="12" md="5"> + <v-card flat> + <v-card-item class="mb-4"> + <v-card-title> Genome Percent + </v-card-title> + </v-card-item> + <v-card-text class="pr-0"> + <v-range-slider v-model="genomePercentValue" step="1" thumb-label="always" + :min="genomePercentDomain[0]" :max="genomePercentDomain[1]"> + <template #append> + <v-btn variant="text" density="compact" icon="md:restart_alt" + @click="resetPercent()"></v-btn> + </template></v-range-slider> + </v-card-text> + </v-card> + </v-col> + <v-col cols="12" md="7"> + <v-card flat> + <v-card-item> + <v-card-title> Minimum genomes count to display + </v-card-title> + </v-card-item> + <v-card-text class="pr-0"> + <v-row> + + <v-col> + <v-text-field density="compact" v-model="genomeCountValue" type="number" + :disabled="!genomeCountThreshold" :min="genomeCountDomain[0]" + :max="genomeCountDomain[1]" hide-details></v-text-field> + </v-col> + <v-col cols="3"> + <v-switch v-model="genomeCountThreshold" color="primary" + :label="genomeCountThreshold ? 'activated' : 'disabled'" + hide-details></v-switch> + </v-col> + </v-row> + </v-card-text> + </v-card> + </v-col> + + </v-row> + <PlotFigure v-if="!pending" ref="systemsDistributionPlot" :options="unref(distributionOptions)" defer> + </PlotFigure> + <v-card v-else> + {{ pending }}... + </v-card> + </v-card-text> </v-card> </v-card> </template> \ No newline at end of file diff --git a/components/content/PdockqMatrix.vue b/components/content/PdockqMatrix.vue index cd573513..f39b4ffc 100644 --- a/components/content/PdockqMatrix.vue +++ b/components/content/PdockqMatrix.vue @@ -42,6 +42,8 @@ const margin = ref<PlotMargin>({ const data = ref<SearchResponse | undefined>(undefined) const client = useMeiliSearchRef() const matrixPlot = ref() +const snackbar = ref(false) + onMounted(async () => { try { const d = await client.index(toValue(dbName)).search("", { @@ -193,17 +195,31 @@ function displayStructure(item) { } </script> <template> - <v-row v-if="computedSystem !== null && groupedPdocks?.length > 0" class="d-flex align-content-start" - :class="mobile ? 'd-flex-column' : 'd-flex-row'"> - <v-card v-for="option in computedPDocksMatrixPlotOptions" :key="option.legend.label" flat color="transparent"> - <v-card-text> - <PlotFigure ref="matrixPlot" :options="unref(option)" defer class="pdockq-plot" - :data-label="option.legend.label"></PlotFigure> - </v-card-text> - - </v-card> + + <v-card v-if="computedSystem !== null && groupedPdocks?.length > 0" + v-for="option in computedPDocksMatrixPlotOptions" :key="option.legend.label" flat color="transparent"> + + <v-card-item> + <v-card-title>Dimer pDockQ matrix <v-btn size="x-small" density="comfortable" variant="tonal" + icon="mdi-help" @click="snackbar = true"> + </v-btn> + </v-card-title> + </v-card-item> + <v-card-text> + <PlotFigure ref="matrixPlot" :options="unref(option)" defer class="pdockq-plot" + :data-label="option.legend.label"></PlotFigure> + </v-card-text> + <v-snackbar v-model="snackbar" multi-line vertical> + <p>HeatMap that represent bla bla.</p> + <p>You can click on each cell to display dimer predicted structure</p> + <template v-slot:actions> + <v-btn color="info" variant="text" @click="snackbar = false"> + Close + </v-btn> + </template> + </v-snackbar> <PdbeMolstarPlugin v-model:title="structureTitle" /> - </v-row> + </v-card> <v-card v-else flat color="transparent"> <v-card-text> <v-alert type="info" variant="tonal">No matrix available for this system.</v-alert> diff --git a/components/content/SystemOperonStructure.vue b/components/content/SystemOperonStructure.vue index 620b6a65..b99c5149 100644 --- a/components/content/SystemOperonStructure.vue +++ b/components/content/SystemOperonStructure.vue @@ -115,12 +115,20 @@ async function fetchOperonStructure() { </script> <template> - <v-row align="center"> - <v-col :cols="wholeRow ? 12 : 6" class="pa-0"> - <OperonStructure :genes="sanitizedHits" :system :subsystem /> - </v-col> - <v-col :cols="wholeRow ? 12 : 6" class="pa-0"> - <PdockqMatrix :subsystem="subsystem" /> - </v-col> - </v-row> + <v-card variant="elevated" elevation="1"> + <v-card-item> + <v-card-title>{{ subsystem }}</v-card-title> + </v-card-item> + <v-card-text> + <v-row align="top"> + <v-col :cols="wholeRow ? 12 : 6" align-self="stretch" style="background-color: transparent;"> + <OperonStructure :genes="sanitizedHits" :system :subsystem /> + </v-col> + + <v-col :cols="wholeRow ? 12 : 6"> + <PdockqMatrix :subsystem="subsystem" /> + </v-col> + </v-row> + </v-card-text> + </v-card> </template> \ No newline at end of file -- GitLab