Skip to content

Commit

Permalink
improve hypertree UX
Browse files Browse the repository at this point in the history
  • Loading branch information
emiliorighi committed Aug 30, 2024
1 parent d6049ea commit cb78560
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 69 deletions.
30 changes: 6 additions & 24 deletions biogenome-client/src/components/tree/D3HyperTree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,27 @@

<script setup lang="ts">
import * as hyt from 'd3-hypertree'
import TaxonService from '../../services/clients/TaxonService'
import { useTreeData } from './setTreeData'
import { onMounted, reactive, ref, watch } from 'vue'
import { TreeNode } from '../../data/types'
import { useTaxonomyStore } from '../../stores/taxonomy-store'
const hypertree = ref(null)
const props = defineProps<{
filter: string | null
}>()
const taxonomyStore = useTaxonomyStore()
const hTree = reactive<{ tree: hyt.Hypertree | null }>({ tree: null })
const { data } = await TaxonService.getComputedTree()
const { root } = useTreeData(data.tree)
const isInitializing = ref(true)
const emits = defineEmits(['nodeChange'])
watch(() => props.filter, (v) => {
console.log(v)
console.log("FIlter..")
watch(() => taxonomyStore.taxidQuery, (v) => {
if (isInitializing.value || !v) return
setPath(v)
})
watch(() => isInitializing.value, (v) => {
console.log(v)
console.log("Init..")
if (props.filter && !v) setPath(props.filter)
if (taxonomyStore.taxidQuery && !v) setPath(taxonomyStore.taxidQuery)
})
function setPath(taxid: string) {
Expand All @@ -47,22 +35,17 @@ function setPath(taxid: string) {
hTree.tree.api.gotoNode(node).then(() => hTree.tree.drawDetailFrame())
}
}
}
onMounted(() => {
const { root } = useTreeData(taxonomyStore.treeData)
hTree.tree = createTree(root)
hTree.tree.initPromise
.then(() => new Promise((ok, err) => hTree.tree.animateUp(ok, err)))
.then(() => hTree.tree.drawDetailFrame())
.catch((err) => console.log(err))
.finally(() => isInitializing.value = !isInitializing.value)
// .then(() => {
// if (props.filter) {
// setPath(props.filter)
// }
// })
// taxonomyStore.showTree = true
})
function createTree(data) {
Expand Down Expand Up @@ -92,7 +75,6 @@ function createTree(data) {
},
interaction: {
onNodeClick: (n, m, l) => {
mytree.api.setPathHead(mytree.data.pathes, n)
mytree.api.goto({ re: -n.layout.z.re, im: -n.layout.z.im }, null)
.then(() => l.view.hypertree.drawDetailFrame())
Expand Down
25 changes: 15 additions & 10 deletions biogenome-client/src/pages/taxonomy/Taxon.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<template>
<VaInnerLoading :style="{ display: isLoading ? 'inherit' : 'initial' }" :size="50" :loading="isLoading">
<VaInnerLoading :style="{ display: taxonomyStore.isContentLoading ? 'inherit' : 'initial' }" :size="50"
:loading="taxonomyStore.isContentLoading">
<VaCard>
<VaCardContent v-if="taxon">
<h2 class="va-h2"> {{ taxon.name }}
<VaCardContent v-if="taxonomyStore.currentTaxon">
<h2 class="va-h2"> {{ taxonomyStore.currentTaxon.name }}
</h2>
</VaCardContent>
<VaTabs :key="taxid" v-model="tab">
Expand Down Expand Up @@ -30,9 +31,9 @@
</VaInnerLoading>
</template>
<script setup lang="ts">
import { computed, ref, watchEffect } from 'vue'
import { computed, onMounted, ref, watchEffect } from 'vue'
import { useI18n } from 'vue-i18n'
import { SampleLocations, Filter, TreeNode } from '../../data/types'
import { SampleLocations, Filter } from '../../data/types'
import { models } from '../../../config.json'
import GeoLocationService from '../../services/clients/GeoLocationService'
import ItemsBlock from '../common/components/ItemsBlock.vue'
Expand All @@ -45,7 +46,6 @@ import TaxonService from '../../services/clients/TaxonService'
const { init } = useToast()
const taxonomyStore = useTaxonomyStore()
const taxon = ref<TreeNode>()
const props = defineProps<{
taxid: string
Expand All @@ -63,12 +63,15 @@ const isLoading = ref(false)
watchEffect(async () => {
tab.value = 'wiki'
isLoading.value = true
await Promise.all([getTaxon(props.taxid), getStats(props.taxid)])
isLoading.value = false
await getTaxon(props.taxid)
await getStats(props.taxid)
await getCoordinates(props.taxid)
})
onMounted(async () => {
if (!taxonomyStore.treeData) await taxonomyStore.getTree()
})
const { t } = useI18n()
const validTabs = computed(() => {
Expand Down Expand Up @@ -96,14 +99,16 @@ async function getCoordinates(taxid: string) {
}
async function getTaxon(taxid: string) {
isLoading.value = true
try {
const { data } = await TaxonService.getTaxon(taxid)
taxon.value = { ...data }
taxonomyStore.currentTaxon = { ...data }
taxonomyStore.taxidQuery = taxid
} catch (error) {
const axiosError = error as AxiosError
init({ message: axiosError.message, color: 'danger' })
} finally {
isLoading.value = false
}
}
</script>
40 changes: 9 additions & 31 deletions biogenome-client/src/pages/taxonomy/Taxonomy.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
<div class="flex">
<va-select hideSelected :loading="isLoading" dropdownIcon="search" searchable highlight-matched-text
:textBy="(v: TreeNode) => `${v.name} (${v.rank})`" trackBy="taxid" @update:model-value="setCurrentTaxon"
@update:search="handleSearch" v-model="taxonomyStore.currentTaxon"
@update:search="taxonomyStore.handleSearch" v-model="taxonomyStore.currentTaxon"
:searchPlaceholderText="t('taxon.search.placeholder')" :noOptionsText="t('taxon.search.noOptions')"
:options="taxons">
:options="taxonomyStore.taxons">
</va-select>
</div>
<div class="flex">
<VaButton color="primary" :round="false" @click="showTree = !showTree" :loading="isTreeLoading">
{{ showTree ? t('taxon.search.hide') : t('taxon.search.show') }}
<VaButton color="primary" :round="false" @click="taxonomyStore.showTree = !taxonomyStore.showTree"
:loading="taxonomyStore.isTreeLoading">
{{ taxonomyStore.showTree ? t('taxon.search.hide') : t('taxon.search.show') }}
</VaButton>
</div>
<div class="flex">
Expand All @@ -23,12 +24,10 @@
</div>
</div>
<div class="content-row">
<div :class="['tree-container', { 'hidden': !showTree }]">
<Suspense @resolve="isTreeLoading = !isTreeLoading">
<D3HyperTree @node-change="setCurrentTaxon" :filter="taxonomyStore.taxidQuery" />
</Suspense>
<div v-if="taxonomyStore.treeData" :class="['tree-container', { 'hidden': !taxonomyStore.showTree }]">
<D3HyperTree @node-change="setCurrentTaxon" />
</div>
<div :class="['content-container', { 'full-width': !showTree }]">
<div :class="['content-container', { 'full-width': !taxonomyStore.showTree }]">
<router-view></router-view>
</div>
</div>
Expand Down Expand Up @@ -59,18 +58,13 @@
<script setup lang="ts">
import D3HyperTree from '../../components/tree/D3HyperTree.vue'
import { onMounted, ref } from 'vue';
import TaxonService from '../../services/clients/TaxonService';
import { useI18n } from 'vue-i18n'
import { useTaxonomyStore } from '../../stores/taxonomy-store'
import { TreeNode } from '../../data/types';
import { AxiosError } from 'axios';
import { useToast } from 'vuestic-ui'
import { useRouter, useRoute } from 'vue-router';
const isTreeLoading = ref(true)
const router = useRouter()
const route = useRoute()
const showTree = ref(false)
const rootNode = import.meta.env.VITE_ROOT_NODE ? import.meta.env.VITE_ROOT_NODE : '131567'
Expand All @@ -96,35 +90,19 @@ onMounted(() => {
const taxonomyStore = useTaxonomyStore()
const { init } = useToast()
const { t } = useI18n()
const taxons = ref<TreeNode[]>([])
const isLoading = ref(false)
function setCurrentTaxon(taxon: TreeNode) {
taxons.value = []
taxonomyStore.taxons = []
taxonomyStore.currentTaxon = { ...taxon }
// taxonomyStore.taxidQuery = null
taxonomyStore.taxidQuery = taxon.taxid
router.push({ name: 'taxon', params: { taxid: taxon.taxid } })
}
async function handleSearch(v: string) {
if (v.length < 2) return
isLoading.value = true
try {
const { data } = await TaxonService.getTaxons({ filter: v })
if (data.data) taxons.value = [...data.data]
} catch (error) {
console.log(error)
const axiosError = error as AxiosError
init({ message: axiosError.message, color: 'danger' })
} finally {
isLoading.value = false
}
}
</script>
Expand Down
41 changes: 37 additions & 4 deletions biogenome-client/src/stores/taxonomy-store.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { defineStore } from 'pinia'
import { SearchForm, TreeNode } from '../data/types'
import TaxonService from '../services/clients/TaxonService'
import { AxiosError } from 'axios'
import { useToast } from 'vuestic-ui'

const initSearchForm:SearchForm = {
const initSearchForm: SearchForm = {
filter: '',
sort_column: '',
sort_order: '',
rank:''
rank: ''
}

const initPagination = {
Expand All @@ -18,9 +21,14 @@ export const useTaxonomyStore = defineStore('taxonomy', {
return {
searchForm: { ...initSearchForm },
pagination: { ...initPagination },
ancestors: [],
currentTaxon: null as TreeNode | null,
taxidQuery:null as string | null,
taxidQuery: null as string | null,
taxons: [] as TreeNode[],
isTreeLoading: false,
isContentLoading: false,
showTree: false,
treeData: null as Record<string, any> | null,
init: useToast().init
}
},

Expand All @@ -31,5 +39,30 @@ export const useTaxonomyStore = defineStore('taxonomy', {
resetPagination() {
this.pagination = { ...initPagination }
},
async getTree() {
this.isTreeLoading = true
try {
const { data } = await TaxonService.getComputedTree()
this.treeData = { ...data.tree }
} catch (error) {
console.log(error)
} finally {
this.isTreeLoading = false
}
},
async handleSearch(v: string) {
if (v.length < 2) return
this.isContentLoading = true
try {
const { data } = await TaxonService.getTaxons({ filter: v })
if (data.data) this.taxons = [...data.data]
} catch (error) {
console.log(error)
const axiosError = error as AxiosError
this.init({ message: axiosError.message, color: 'danger' })
} finally {
this.isContentLoading = false
}
}
},
})

0 comments on commit cb78560

Please sign in to comment.