diff --git a/components/content/MolstarPdbePlugin.vue b/components/content/MolstarPdbePlugin.vue index 79949bc6f3a142c50ef336ff92337503c501e63f..bfb97d00e8270868bd9240955db9c07836a13a83 100644 --- a/components/content/MolstarPdbePlugin.vue +++ b/components/content/MolstarPdbePlugin.vue @@ -4,16 +4,18 @@ import { withTrailingSlash, withLeadingSlash, joinURL } from 'ufo' import { useRuntimeConfig, computed } from '#imports' import * as d3 from "d3"; import * as Plot from "@observablehq/plot"; - - import PlotFigure from "~/components/PlotFigure"; +import { useDisplay } from "vuetify"; + export interface Props { height?: number dataUrls?: string[] dataUrl?: string uniq?: boolean } + +const { mobile } = useDisplay() // const selectedPdb = ref('') const refinedDataUrls = computed(() => { @@ -100,66 +102,63 @@ const pdbeMolstarComponent = ref(null) const selectedPdb: Ref<string | null> = ref(null) const selectedPaePath = computed(() => { - return selectedPdb.value ? `${selectedPdb.value.split(".").slice(0, -1).join('.')}.tsv` : null + return selectedPdb.value ? `${selectedPdb.value.split(".").slice(0, -1).join('.')}.png` : null }) -const paeData = ref([]) -watch(selectedPaePath, async (newPaePath) => { - if (newPaePath !== null) { - try { - const data = await d3.tsv(newPaePath); - console.log(data.length) - console.log(data[0][0]) - console.log(data?.[0]?.[0] !== undefined) - if (data.length > 500) { - paeError.value = `The PAE is too large to be displayed (${data.length} residus)` - paeData.value = [] - } - else if (data?.[0]?.[0] === undefined) { - paeError.value = "The PAE cannot be downloaded" - paeData.value = [] - } - else { - paeData.value = data - paeError.value = null - } - - } - catch (error) { - console.log(error) - } - } else { - paeData.value = [] - } - -}) +// const paeData = ref([]) +// watch(selectedPaePath, async (newPaePath) => { +// if (newPaePath !== null) { +// try { +// const data = await d3.tsv(newPaePath); +// if (data.length > 500) { +// paeError.value = `The PAE is too large to be displayed (${data.length} residus)` +// paeData.value = [] +// } +// else if (data?.[0]?.[0] === undefined) { +// paeError.value = "The PAE cannot be downloaded" +// paeData.value = [] +// } +// else { +// paeData.value = data +// paeError.value = null +// } + +// } +// catch (error) { +// console.log(error) +// } +// } else { +// paeData.value = [] +// } -const sanitizedPaeData = computed(() => { - return paeData.value.reduce((acc, curr, index) => { - const scoredResidue = index - // let newAcc = [...acc] - for (const [alignedResidue, value] of Object.entries(curr)) { - // console.log(value) - acc.push({ alignedResidue: parseInt(alignedResidue), scoredResidue: parseInt(scoredResidue), value: parseFloat(value) }) - // newAcc = [...newAcc, ...[{ alignedResidue: parseInt(alignedResidue), scoredResidue: parseInt(scoredResidue), value: parseFloat(value) }]] - } +// }) - return acc - }, []) -}) +// const sanitizedPaeData = computed(() => { +// return paeData.value.reduce((acc, curr, index) => { +// const scoredResidue = index +// // let newAcc = [...acc] +// for (const [alignedResidue, value] of Object.entries(curr)) { +// // console.log(value) +// acc.push({ alignedResidue: parseInt(alignedResidue), scoredResidue: parseInt(scoredResidue), value: parseFloat(value) }) +// // newAcc = [...newAcc, ...[{ alignedResidue: parseInt(alignedResidue), scoredResidue: parseInt(scoredResidue), value: parseFloat(value) }]] +// } + +// return acc +// }, []) +// }) -const plotPaeOptions = computed(() => { - return { - width: 640, - height: 640, - color: { scheme: "Greens", legend: true, reverse: true, label: "Expected position error (Ångströms)" }, - y: { reverse: true }, - marks: [ - Plot.dot(sanitizedPaeData.value, { x: "scoredResidue", y: "alignedResidue", stroke: "value" }) - ] - } -}) +// const plotPaeOptions = computed(() => { +// return { +// width: 640, +// height: 640, +// color: { scheme: "Greens", legend: true, reverse: true, label: "Expected position error (Ångströms)" }, +// y: { reverse: true }, +// marks: [ +// Plot.dot(sanitizedPaeData.value, { x: "scoredResidue", y: "alignedResidue", stroke: "value" }) +// ] +// } +// }) watch(selectedPdb, (newSelectedPdb, prevSelectPdb) => { viewPdb(newSelectedPdb) @@ -171,10 +170,13 @@ function viewPdb(pdbPath: string | null) { dialog.value = true const format = toValue(pdbPath)?.split(".").slice(-1)[0]?.toLowerCase() ?? "pdb" moleculeFormat.value = format + if (pdbeMolstarComponent.value?.viewerInstance) { + console.log(pdbeMolstarComponent.value) const viewerInstance = pdbeMolstarComponent.value.viewerInstance const customData = { url: pdbPath, format: format, binary: false } viewerInstance.visual.update({ customData }) + } } } @@ -217,7 +219,7 @@ const moleculeFormat: Ref<string> = ref("pdb") </v-toolbar> <v-card-text> <v-row> - <v-col cols="auto"> + <v-col :cols="mobile ? 12 : 'auto'"> <v-sheet v-if="selectedPdb" class="d-flex align-center justify-center flex-wrap text-center mx-auto px-4 my-3" :height="computedHeight" :width="computedWidth" position="relative"> @@ -226,12 +228,13 @@ const moleculeFormat: Ref<string> = ref("pdb") :custom-data-format="moleculeFormat"></pdbe-molstar> </v-sheet> </v-col> - <v-col> - <PlotFigure v-if="sanitizedPaeData?.length > 0 && paeError === null" defer + <v-col :cols="mobile ? 12 : undefined"> + <v-img :src="selectedPaePath"></v-img> + + <!-- <PlotFigure v-if="sanitizedPaeData?.length > 0 && paeError === null" defer :options="plotPaeOptions"></PlotFigure> - <v-alert v-else type="warning" variant="tonal">{{ paeError }}</v-alert> + <v-alert v-else type="warning" variant="tonal">{{ paeError }}</v-alert> --> <v-card flat color="transparent"> - <v-card-title>Model Confidence</v-card-title> <v-card-text> AlphaFold produces a per-residue model