Skip to content

Commit

Permalink
Add and adapt circular plot from bakrep
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasjelonek committed Jan 6, 2025
1 parent 1adcbf0 commit 88a6ef0
Show file tree
Hide file tree
Showing 24 changed files with 3,219 additions and 8 deletions.
10 changes: 8 additions & 2 deletions src/components/bakta-result/BaktaResultVisualization.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@
</button>
</li>
<li v-if="showShareButton" class="nav-item ms-auto">
<button class="nav-link" @click="putLinkToClipboard">
<i title="Copy link to clipboard" class="bi bi-share"></i>
<button class="nav-link" @click="putLinkToClipboard" title="Copy link to clipboard">
<i class="bi bi-share"></i>
</button>
</li>
</ul>
<div class="p-3 pb-5 pt-3 border border-top-0 my-0 py-0">
<BaktaStats v-if="currentTab === 'job'" :data="bakta" :job="job" />
<BaktaGenomeViewer v-if="currentTab === 'browser'" :data="bakta" />
<BaktaAnnotationTable v-if="currentTab === 'table'" :data="bakta" />
<FeaturePlotViewer v-if="currentTab === 'circular'" :bakta="bakta" />
</div>
<div
v-if="showShareButton"
Expand All @@ -39,6 +40,7 @@ import BaktaAnnotationTable from './BaktaAnnotationTable.vue'
import BaktaStats from './BaktaStats.vue'
import { ref, useTemplateRef } from 'vue'
import { Toast } from 'bootstrap'
import FeaturePlotViewer from './FeaturePlotViewer.vue'
defineProps<{
job: JobResult
Expand All @@ -60,6 +62,10 @@ const tabs: { key: tabs; label: string }[] = [
key: 'browser',
label: 'Genomeviewer',
},
{
key: 'circular',
label: 'Circular plot',
},
]
const currentTab = ref<tabs>('job')
const toast = useTemplateRef('copyToast')
Expand Down
17 changes: 17 additions & 0 deletions src/components/bakta-result/FeaturePlotViewer.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Meta, StoryObj } from '@storybook/vue3'

import FeaturePlotViewer from './FeaturePlotViewer.vue'
import { fn } from '@storybook/test'
import { ref } from 'vue'
import { fixtures, fixturesFn } from '@/test-data/bakta-results'
const meta: Meta<typeof FeaturePlotViewer> = {
component: FeaturePlotViewer,
}

export default meta
type Story = StoryObj<typeof FeaturePlotViewer>
export const Default: Story = {
args: {
bakta: fixturesFn('1.10'),
},
}
64 changes: 64 additions & 0 deletions src/components/bakta-result/FeaturePlotViewer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<template>
<div class="w-100 h-100">
<div v-if="bakta.sequences.length > 1" class="form-floating">
<select id="selectSequence" class="form-select" v-model="currentId">
<option v-for="s of bakta.sequences" :key="s.id" :value="s.id">
{{ s.id }}
</option>
</select>
<label for="selectSequence">Select sequence</label>
</div>
<select v-if="false" v-model="type">
<option value="circular">circular</option>
<option value="linear">linear</option>
</select>
<div class="my-2 w-100 h-100" ref="comp">
<BaktaCircularPlot
v-if="data.seq && type == 'circular'"
:sequence="data.seq"
:features="data.feat"
:size="size"
/>
<BaktaLinearPlot
v-if="data.seq && type == 'linear'"
:sequence="data.seq"
:features="data.feat"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { type Result } from '@/model/result-data'
import { computed, onMounted, ref, useTemplateRef } from 'vue'
import BaktaCircularPlot from './feature-plot/BaktaCircularPlot.vue'
import BaktaLinearPlot from './feature-plot/BaktaLinearPlot.vue'
const props = defineProps<{
bakta: Result
}>()
const currentId = ref<string>('')
const type = ref<'circular' | 'linear'>('circular')
const size = ref({ width: 1000, height: 1000 })
const data = computed(() => ({
seq: props.bakta.sequences.find((x) => x.id == currentId.value),
feat: props.bakta.features.filter((x) => x.sequence === currentId.value),
}))
const component = useTemplateRef('comp')
onMounted(() => {
if (props.bakta.sequences.length > 0) {
currentId.value = props.bakta.sequences[0].id
}
if (component.value) {
const obs = new ResizeObserver(() => {
if (component.value) {
const bbox = component.value.getBoundingClientRect()
const max = Math.max(bbox.width, bbox.height)
size.value = { width: max, height: max }
}
})
obs.observe(component.value)
}
})
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { Meta, StoryObj } from '@storybook/vue3'

import BaktaCircularPlot from './BaktaCircularPlot.vue'

import { ref } from 'vue'
import type { Result } from '@/model/result-data'
import { fixtures } from '@/test-data/bakta-results'
const meta: Meta<typeof BaktaCircularPlot> = {
component: BaktaCircularPlot,
}

const result: Result = fixtures.result['1.10']

export default meta
type Story = StoryObj<typeof BaktaCircularPlot>

export const Default: Story = {
args: { sequence: result.sequences[0], features: result.features },
render: (args) => ({
components: { BaktaCircularPlot },
setup() {
let cur = 0
const seq = ref(result.sequences[0])
const feat = ref(result.features.filter((x) => x.sequence === seq.value.id))
function nextSequence() {
cur = (cur + 1) % result.sequences.length
seq.value = result.sequences[cur]
feat.value = result.features.filter((x) => x.sequence === seq.value.id)
}
return { seq, feat, nextSequence, args }
},
template:
'<button @click="nextSequence">Toggle</button><BaktaCircularPlot v-bind="args" :sequence="seq" :features="feat" />',
}),
}
Loading

0 comments on commit 88a6ef0

Please sign in to comment.