Skip to content
Snippets Groups Projects
Commit f4fb99e7 authored by Remi  PLANEL's avatar Remi PLANEL
Browse files

btn to download plots

parent 6225734c
No related branches found
No related tags found
1 merge request!169Resolve "Being able to download the distributions in refseqDB as a svg/png/csv"
Pipeline #119718 passed
...@@ -4,7 +4,8 @@ import PlotFigure from "~/components/PlotFigure"; ...@@ -4,7 +4,8 @@ import PlotFigure from "~/components/PlotFigure";
import { useDisplay } from "vuetify"; import { useDisplay } from "vuetify";
import type { SortItem } from "@/components/ServerDbTable.vue" import type { SortItem } from "@/components/ServerDbTable.vue"
import { ServerDbTable } from "#components" import { ServerDbTable } from "#components"
import { useSerialize } from "@/composables/useSerialize";
import type { ComponentPublicInstance } from 'vue'
const sortBy: Ref<SortItem[]> = ref([{ key: 'type', order: "asc" }]) const sortBy: Ref<SortItem[]> = ref([{ key: 'type', order: "asc" }])
const itemValue = ref("id"); const itemValue = ref("id");
...@@ -12,6 +13,7 @@ const { width } = useDisplay(); ...@@ -12,6 +13,7 @@ const { width } = useDisplay();
const scaleTransform: Ref<string[]> = ref([]) const scaleTransform: Ref<string[]> = ref([])
const { serialize } = useSerialize()
const facets = ref([ const facets = ref([
"replicon", "replicon",
...@@ -32,6 +34,8 @@ const availableTaxo: Ref<string[]> = ref([ ...@@ -32,6 +34,8 @@ const availableTaxo: Ref<string[]> = ref([
"phylum", "phylum",
"Superkingdom" "Superkingdom"
]); ]);
const scaleTypes = ref<string[]>(['linear', 'sqrt', 'log', 'symlog'])
const selectedTaxoRank = ref("phylum"); const selectedTaxoRank = ref("phylum");
const headers = ref([ const headers = ref([
...@@ -121,22 +125,25 @@ const dataTableServerProps = computed(() => { ...@@ -121,22 +125,25 @@ const dataTableServerProps = computed(() => {
const defaultBarPlotOptions = computed(() => { const defaultBarPlotOptions = computed(() => {
return { return {
x: { label: null, tickRotate: 45, ticks: 10 }, x: { label: null, tickRotate: 45 },
y: { grid: true, type: scaleType.value }, y: { grid: true, clamp: true },
color: { legend: true },
width: computedWidth.value,
// height: plotHeight.value + 100, // height: plotHeight.value + 100,
} }
}) })
// system distri
const computedSystemDistribution = computed(() => { const computedSystemDistribution = computed(() => {
if (toValue(msResult)?.facetDistribution?.type) { if (toValue(msResult)?.facetDistribution?.type) {
return Object.entries(toValue(msResult).facetDistribution.type).map(([key, value]) => { return Object.entries(toValue(msResult).facetDistribution.type)
return { .map(([key, value]) => {
type: key, return {
count: value type: key,
} count: value
}).sort() }
}).sort()
} else { return [] } } else { return [] }
}) })
...@@ -144,13 +151,15 @@ const computedDistriSystemOptions = computed(() => { ...@@ -144,13 +151,15 @@ const computedDistriSystemOptions = computed(() => {
return { return {
...defaultBarPlotOptions.value, ...defaultBarPlotOptions.value,
marginBottom: 100, marginBottom: 100,
y: { ...defaultBarPlotOptions.value.y, type: toValue(scaleType), label: "Count" },
x: { ...defaultBarPlotOptions.value.x, label: "Systems" },
width: computedWidth.value,
marks: [ marks: [
// Plot.frame(), // Plot.frame(),
Plot.barY( Plot.barY(
toValue(computedSystemDistribution), toValue(computedSystemDistribution),
{ {
y: "count", x: 'type', tip: true, y: "count", x: 'type', tip: true,
// fill: "#6750a4",
sort: { x: "-y" }, sort: { x: "-y" },
}, },
...@@ -158,6 +167,9 @@ const computedDistriSystemOptions = computed(() => { ...@@ -158,6 +167,9 @@ const computedDistriSystemOptions = computed(() => {
], ],
}; };
}); });
// Taxo distri
const computedTaxonomyDistribution = computed(() => { const computedTaxonomyDistribution = computed(() => {
if (toValue(msResult)?.facetDistribution?.[selectedTaxoRank.value]) { if (toValue(msResult)?.facetDistribution?.[selectedTaxoRank.value]) {
return Object.entries(toValue(msResult).facetDistribution[selectedTaxoRank.value]).map(([key, value]) => { return Object.entries(toValue(msResult).facetDistribution[selectedTaxoRank.value]).map(([key, value]) => {
...@@ -174,6 +186,9 @@ const computedDistriTaxoOptions = computed(() => { ...@@ -174,6 +186,9 @@ const computedDistriTaxoOptions = computed(() => {
return { return {
...defaultBarPlotOptions.value, ...defaultBarPlotOptions.value,
marginBottom: 100, marginBottom: 100,
x: { ...defaultBarPlotOptions.value.x, label: selectedTaxoRank.value },
y: { ...defaultBarPlotOptions.value.y, type: toValue(scaleType), label: "Count" },
width: computedWidth.value,
marks: [ marks: [
Plot.barY( Plot.barY(
toValue(computedTaxonomyDistribution), toValue(computedTaxonomyDistribution),
...@@ -212,8 +227,8 @@ const binPlotOptions = ref({ ...@@ -212,8 +227,8 @@ const binPlotOptions = ref({
marginBottom: 200, marginBottom: 200,
padding: 0, padding: 0,
grid: true, grid: true,
x: { tickRotate: 90, tip: true, }, x: { tickRotate: 90, tip: true, label: "Systems" },
// y: { tickFormat: 's' },
color: { scheme: "turbo", legend: true }, color: { scheme: "turbo", legend: true },
}) })
...@@ -225,7 +240,11 @@ const binPlotDataOptions = computed(() => { ...@@ -225,7 +240,11 @@ const binPlotDataOptions = computed(() => {
color: { color: {
...binPlotOptions.value.color, ...binPlotOptions.value.color,
type: scaleType.value type: scaleType.value,
tickFormat: '~s',
ticks: scaleType.value === 'symlog' ? 3 : 5,
// width: 350
}, },
// fy: { domain: groupSortDomain.value }, // fy: { domain: groupSortDomain.value },
marks: [ marks: [
...@@ -236,6 +255,12 @@ const binPlotDataOptions = computed(() => { ...@@ -236,6 +255,12 @@ const binPlotDataOptions = computed(() => {
}) })
const scaleType = ref("linear") const scaleType = ref("linear")
const systemsDistributionPlot = ref<ComponentPublicInstance | null>(null)
const taxonomicDistributionPlot = ref<ComponentPublicInstance | null>(null)
const heatmapPlot = ref<ComponentPublicInstance | null>(null)
function downloadSvg(component: ComponentPublicInstance | null, filename: string) {
serialize(toValue(component), filename)
}
</script> </script>
<template> <template>
...@@ -253,21 +278,38 @@ const scaleType = ref("linear") ...@@ -253,21 +278,38 @@ const scaleType = ref("linear")
<v-btn icon="md:grid_view" value="grid"></v-btn> <v-btn icon="md:grid_view" value="grid"></v-btn>
<v-btn icon="md:view_agenda" value="fullwidth"></v-btn> <v-btn icon="md:view_agenda" value="fullwidth"></v-btn>
</v-btn-toggle> </v-btn-toggle>
<v-select v-model="scaleType" class="mx-2" density="compact" <v-select v-model="scaleType" class="mx-2" density="compact" :items="scaleTypes"
:items="['linear', 'sqrt', 'symlog']" label="Scale Type" hide-details="auto"></v-select> label="Scale Type" hide-details="auto"></v-select>
<v-select v-model="selectedTaxoRank" :items="availableTaxo" density="compact" <v-select v-model="selectedTaxoRank" :items="availableTaxo" density="compact"
label="Select taxonomic rank" hide-details="auto" class="mx-2"></v-select> label="Select taxonomic rank" hide-details="auto" class="mx-2"></v-select>
</v-toolbar> </v-toolbar>
<v-row align="start"> <v-row align="start">
<v-col :cols="fullWidth ? 12 : 6"> <v-col :cols="fullWidth ? 12 : 6">
<PlotFigure :options="unref(computedDistriSystemOptions)" defer></PlotFigure> <v-card variant="flat">
<v-toolbar density="compact" color="transparent">
<v-spacer></v-spacer>
<v-btn variant="text" size="x-small"
@click="downloadSvg(systemsDistributionPlot, 'systems-distribution.svg')">export
to svg</v-btn>
</v-toolbar>
<PlotFigure ref="systemsDistributionPlot"
:options="unref(computedDistriSystemOptions)" defer></PlotFigure>
</v-card>
</v-col> </v-col>
<v-col :cols="fullWidth ? 12 : 6"> <v-col :cols="fullWidth ? 12 : 6">
<v-card variant="flat">
<PlotFigure defer :options="unref(computedDistriTaxoOptions)"></PlotFigure> <v-toolbar density="compact" color="transparent">
<v-spacer></v-spacer>
<v-btn variant="text" size="x-small"
@click="downloadSvg(taxonomicDistributionPlot, 'taxonomic-distribution.svg')">export
to
svg</v-btn>
</v-toolbar>
<PlotFigure ref="taxonomicDistributionPlot" defer
:options="unref(computedDistriTaxoOptions)"></PlotFigure>
</v-card>
</v-col> </v-col>
</v-row> </v-row>
</v-card> </v-card>
...@@ -285,19 +327,26 @@ const scaleType = ref("linear") ...@@ -285,19 +327,26 @@ const scaleType = ref("linear")
<v-expansion-panel-text> <v-expansion-panel-text>
<v-card v-if="pendingAllHits === false" flat color="transparent"> <v-card v-if="pendingAllHits === false" flat color="transparent">
<v-toolbar flat color="transparent" density="compact"> <v-toolbar flat color="transparent" density="compact">
<v-select v-model="scaleType" class="mx-2" density="compact" <v-select v-model="scaleType" class="mx-2" density="compact" :items="scaleTypes"
:items="['linear', 'sqrt', 'symlog']" label="Scale Type" hide-details="auto"></v-select> label="Scale Type" hide-details="auto"></v-select>
<v-select v-model="selectedTaxoRank" :items="availableTaxo" density="compact" <v-select v-model="selectedTaxoRank" :items="availableTaxo" density="compact"
label="Select taxonomic rank" hide-details="auto" class="mx-2"></v-select> label="Select taxonomic rank" hide-details="auto" class="mx-2"></v-select>
</v-toolbar> </v-toolbar>
<PlotFigure v-if="toValue(binPlotDataOptions) !== null" :options="unref(binPlotDataOptions)" <v-card variant="flat">
defer> <v-toolbar density="compact" color="transparent">
</PlotFigure> <v-spacer></v-spacer>
<v-btn variant="text" size="x-small"
@click="downloadSvg(heatmapPlot, 'heatmap-systems-taxonomic.svg')">export to
svg</v-btn>
</v-toolbar>
<PlotFigure ref="heatmapPlot" v-if="toValue(binPlotDataOptions) !== null"
:options="unref(binPlotDataOptions)" defer>
</PlotFigure>
</v-card>
</v-card> </v-card>
<v-card v-else flat color="transparent"> <v-card v-else flat color="transparent">
<v-skeleton-loader type="card" :loading="pendingAllHits" <v-skeleton-loader type="card" :loading="pendingAllHits" height="400"></v-skeleton-loader>
height="400"></v-skeleton-loader>
</v-card> </v-card>
</v-expansion-panel-text> </v-expansion-panel-text>
</v-expansion-panel> </v-expansion-panel>
......
import Papa from 'papaparse'; import Papa from 'papaparse';
// import { saveAs } from "file-saver"; // import { saveAs } from "file-saver";
import { useDownloadBlob } from './useDownloadBlob';
const { download } = useDownloadBlob()
export function useCsvDownload( export function useCsvDownload(
rawData: MaybeRef<Record<string, any>>, rawData: MaybeRef<Record<string, any>>,
...@@ -29,12 +31,7 @@ export function useCsvDownload( ...@@ -29,12 +31,7 @@ export function useCsvDownload(
}) })
const csvContent = Papa.unparse(toValue(data), { columns: toValue(columns) }); const csvContent = Papa.unparse(toValue(data), { columns: toValue(columns) });
blob.value = new Blob([csvContent], { type: "text/csv" }); blob.value = new Blob([csvContent], { type: "text/csv" });
var a = document.createElement("a"); download(blob, filename)
a.href = URL.createObjectURL(blob.value);
a.download = filename.value;
a.click();
URL.revokeObjectURL(a.href);
} }
return { data, filename } return { data, filename }
} }
export function useDownloadBlob() {
function download(blob: MaybeRef<Blob>, filename: MaybeRef<string>) {
const toValueBlob = toValue(blob)
const toValueFilename = toValue(filename)
var a = document.createElement("a");
a.href = URL.createObjectURL(toValueBlob);
a.download = toValueFilename;
a.click();
URL.revokeObjectURL(a.href);
}
return { download }
}
\ No newline at end of file
import { useDownloadBlob } from './useDownloadBlob';
const { download } = useDownloadBlob()
export function useSerialize() {
const xmlns = ref("http://www.w3.org/2000/xmlns/");
const xlinkns = ref("http://www.w3.org/1999/xlink");
const svgns = ref("http://www.w3.org/2000/svg");
const blob = ref()
function serialize(compo: MaybeRef<ComponentPublicInstance | null>, filename: MaybeRef<string>) {
console.log(compo)
const toValueCompo = toValue(compo)
if (toValueCompo !== null) {
const svg = toValueCompo.$el.firstChild
console.log(svg)
const clonedSvg = svg.cloneNode(true);
const fragment = window.location.href + "#";
const walker = document.createTreeWalker(svg, NodeFilter.SHOW_ELEMENT);
while (walker.nextNode()) {
for (const attr of walker.currentNode.attributes) {
if (attr.value.includes(fragment)) {
attr.value = attr.value.replace(fragment, "#");
}
}
}
clonedSvg.setAttributeNS(xmlns.value, "xmlns", svgns.value);
clonedSvg.setAttributeNS(xmlns.value, "xmlns:xlink", xlinkns.value);
const serializer = new window.XMLSerializer;
const string = serializer.serializeToString(clonedSvg);
blob.value = new Blob([string], { type: "image/svg+xml" });
download(blob, filename)
}
}
return { serialize }
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment