Newer
Older
<script setup lang="ts">
import * as Plot from "@observablehq/plot";
import PlotFigure from "~/components/PlotFigure";
import { useDisplay } from "vuetify";
import { useFacetsStore, type Facets } from '~~/stores/facets'
const computedHeight = height.value - 500
return computedHeight > minTableHeight.value ? computedHeight : minTableHeight.value
// SORTING
const sortBy: Ref<{ key: string, order: string }[]> = ref([{ key: 'type', order: "asc" }])
const msSortBy = computed(() => {
if (sortBy.value.length > 0) {
return sortBy.value.map((curr) => {
if (curr?.key && curr?.order) {
return `${curr.key}:${curr.order}`
}
else { return "" }
})
} else { return [""] }
})
const availableTaxo: Ref<string[]> = ref(["species", "genus", "family", "order", "phylum", "Superkingdom"]);
const selectedTaxoRank = ref("phylum");
const computedWidth = computed(() => {
const plotHeight = computed(() => {
return computedWidth.value / 4;
const filter: Ref<string> = ref('')
const hitsPerPage: Ref<number> = ref(25)
const limit = ref(1000)
const facets = ref([
"type",
"Superkingdom",
"phylum",
"order",
"family",
"genus",
"species",
])
const prependHeaders = ref([
{ title: "Replicon", key: "replicon" },
{
title: "System",
key: "type",
},
{
title: "Subtype",
key: "subtype",
},
]);
const appendHeaders = ref([
{
title: "Accessions",
key: "accession_in_sys"
function capitalize([first, ...rest]) {
return first.toUpperCase() + rest.join('').toLowerCase();
}
const {
hits: items,
pending,
totalHits: itemsLength,
filterError,
facetDistribution }
= useFetchMsDocument(
"refseq",
search,
filter,
limit,
hitsPerPage,
page,
facetStore.setFacets({ facetDistribution: facetDistri, facetStat: undefined })
})
const computedSystemDistribution = computed(() => {
if (facetDistribution.value?.type) {
return Object.entries(facetDistribution.value.type).map(([key, value]) => {
return { type: key, count: value }
}).sort()
} else { return [] }
})
const computedTaxonomyDistribution = computed(() => {
if (facetDistribution.value?.[selectedTaxoRank.value]) {
return Object.entries(facetDistribution.value[selectedTaxoRank.value]).map(([key, value]) => {
return { [selectedTaxoRank.value]: key, count: value }
}).sort()
} else { return [] }
})
const computedHeaders = computed(() => {
return [...prependHeaders.value, ...availableTaxo.value.map(taxo => {
return {
title: capitalize(taxo),
key: taxo
}), ...appendHeaders.value]
})
function itemToFilter(item, key) {
const value = item[key]
const filterToAdd = /\s/g.test(value) ? `${key}="${value}"` : `${key}=${value}`
return filter.value === '' ? filterToAdd : `${filter.value} AND ${filterToAdd}`
const itemFilterKeys = computed(() => {
return [...availableTaxo.value, 'type', 'subtype']
})
color: { legend: true },
width: computedWidth.value,
}
})
const computedDistriSystemOptions = computed(() => {
return {
...defaultBarPlotOptions.value,
marginBottom: 120,
toValue(computedSystemDistribution),
{
y: "count", x: 'type', tip: true,
fill: "#6750a4",
sort: { x: "-y" },
},
const computedDistriTaxoOptions = computed(() => {
return {
...defaultBarPlotOptions.value,
marginBottom: 200,
toValue(computedTaxonomyDistribution),
{
y: "count",
x: selectedTaxoRank.value,
tip: true,
fill: "#6750a4",
sort: { x: "-y" },
}
// const datatable = ref(null)
const hasToGenerateDownload = ref(false)
let itemsToDownload = ref()
watch(hasToGenerateDownload, (val) => {
console.log(val)
if (val === true) {
const { hits: items, pending, totalHits: itemsLength, filterError, facetDistribution } = useFetchMsDocument("refseq", search, filter, limit, hitsPerPage, page, facets)
</script>
<template>
<v-toolbar color="primary" density="compact">
<v-app-bar-nav-icon></v-app-bar-nav-icon>
<JsonCSV :data="itemsToDownload" name="refseq-defenes-system.csv">
<v-btn icon @click="hasToGenerateDownload = true">
<v-tooltip activator="parent" location="bottom">Download {{ itemsLength }} entries</v-tooltip>
</v-btn>
</JsonCSV>
</v-toolbar>
<!-- </template> -->
<v-card-text>
Tu peux mettre du texte ici
</v-card-text>
<v-col>
<v-text-field v-model="search" prepend-inner-icon="mdi-magnify" label="Search for defense systems" hide-details
class="mx-2 mb-1" clearable></v-text-field>
</v-col>
<v-col class="pt-1">
Examples: <v-chip color="primary" @click="search = 'RADAR'">RADAR</v-chip> <v-chip color="primary"
@click="search = 'BREX'">BREX</v-chip>
</v-col>
<v-col cols="auto">
<v-text-field v-model="filter" prepend-inner-icon="mdi-magnify" label="Filter" hide-details="auto" class="mx-2"
clearable :error-messages="filterError"></v-text-field></v-col>
<v-data-table-server v-model:page="page" v-model:items-per-page="hitsPerPage" v-model:sortBy="sortBy" fixed-header
:loading="pending" :headers="computedHeaders" :items="items" :items-length="itemsLength" :item-value="itemValue"
multi-sort density="compact" :height="computedTableHeight" class="elevation-1 mt-2">
<template #[`item.${key}`]="{ item }" v-for="key in itemFilterKeys" :key="key">
<v-chip @click="filter = itemToFilter(item, key)">{{ item[key] }}</v-chip>
</template>
<template #[`item.accession_in_sys`]="{ item }">
<accession-chips :accessions="item.accession_in_sys" baseUrl="http://toto.pasteur.cloud"></accession-chips>
<v-card-title> Systems Distribution</v-card-title>
<PlotFigure :options="unref(computedDistriSystemOptions)" defer></PlotFigure>
<v-card-title> Taxonomic Distribution</v-card-title>
<v-select v-model="selectedTaxoRank" :items="availableTaxo" density="compact"
label="Select taxonomic rank"></v-select>
<PlotFigure defer :options="unref(computedDistriTaxoOptions)"></PlotFigure>