diff options
| author | Terry Truong <terry06890@gmail.com> | 2022-04-25 01:33:08 +1000 |
|---|---|---|
| committer | Terry Truong <terry06890@gmail.com> | 2022-04-25 01:33:08 +1000 |
| commit | 2ab48497797441164e7f57fca2660097d93398ca (patch) | |
| tree | a6f22d3edff60d182de454359bc40beda82fb5d8 /src/components | |
| parent | 23436a9ad4c2a710c7f0d49a07a720e0153d8225 (diff) | |
Adapt to handle open-tree-of-life data
Added data_otol/ with script that converts data from 'Open Tree of Life' release 13.4 into a JSON form.
Moved old tree-of-life data and images into data_tol_old/.
Added TolMap type to tol.ts, changed TolNode, and adapted other code to handle it.
Temporarily disabling tile images until image data is added.
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/AncestryBar.vue | 10 | ||||
| -rw-r--r-- | src/components/SearchModal.vue | 13 | ||||
| -rw-r--r-- | src/components/Tile.vue | 25 | ||||
| -rw-r--r-- | src/components/TileInfoModal.vue | 9 |
4 files changed, 32 insertions, 25 deletions
diff --git a/src/components/AncestryBar.vue b/src/components/AncestryBar.vue index 6d6ae3c..a156a96 100644 --- a/src/components/AncestryBar.vue +++ b/src/components/AncestryBar.vue @@ -3,6 +3,7 @@ import {defineComponent, PropType} from 'vue'; import Tile from './Tile.vue' import {LayoutNode} from '../layout'; import type {LayoutOptions} from '../layout'; +import type {TolMap} from '../tol'; // Displays a sequence of nodes, representing ancestors from a tree-of-life root to a currently-active root export default defineComponent({ @@ -12,7 +13,8 @@ export default defineComponent({ dims: {type: Array as unknown as PropType<[number,number]>, required: true}, // The ancestors to display nodes: {type: Array as PropType<LayoutNode[]>, required: true}, - // Options + // Other + tolMap: {type: Object as PropType<TolMap>, required: true}, lytOpts: {type: Object as PropType<LayoutOptions>, required: true}, uiOpts: {type: Object, required: true}, }, @@ -26,7 +28,7 @@ export default defineComponent({ }, usedNodes(){ // Childless versions of 'nodes' used to parameterise <tile> return this.nodes.map(n => { - let newNode = new LayoutNode(n.tolNode, []); + let newNode = new LayoutNode(n.name, []); newNode.dims = [this.tileSz, this.tileSz]; return newNode; }); @@ -80,8 +82,8 @@ export default defineComponent({ <template> <div :style="styles"> - <tile v-for="(node, idx) in usedNodes" :key="node.tolNode.name" class="shrink-0" - :layoutNode="node" :nonAbsPos="true" :lytOpts="lytOpts" :uiOpts="uiOpts" + <tile v-for="(node, idx) in usedNodes" :key="node.name" class="shrink-0" + :layoutNode="node" :tolMap="tolMap" :nonAbsPos="true" :lytOpts="lytOpts" :uiOpts="uiOpts" @leaf-click="onTileClick(nodes[idx])" @info-icon-click="onInfoIconClick"/> </div> </template> diff --git a/src/components/SearchModal.vue b/src/components/SearchModal.vue index 91f06ae..22b6896 100644 --- a/src/components/SearchModal.vue +++ b/src/components/SearchModal.vue @@ -1,15 +1,13 @@ <script lang="ts"> import {defineComponent, PropType} from 'vue'; import SearchIcon from './icon/SearchIcon.vue'; -import {TolNode} from '../tol'; import {LayoutNode} from '../layout'; +import type {TolMap} from '../tol'; // Displays a search box, and sends search requests export default defineComponent({ props: { - // Map from tree-of-life node names to TolNode objects - tolMap: {type: Object as PropType<Map<string,TolNode>>, required: true}, - // Options + tolMap: {type: Object as PropType<TolMap>, required: true}, uiOpts: {type: Object, required: true}, }, methods: { @@ -20,15 +18,14 @@ export default defineComponent({ }, onSearchEnter(){ let input = this.$refs.searchInput as HTMLInputElement; - let tolNode = this.tolMap.get(input.value); - if (tolNode == null){ + if (this.tolMap.hasOwnProperty(input.value)){ + this.$emit('search-node', input.value); + } else { input.value = ''; // Trigger failure animation input.classList.remove('animate-red-then-fade'); input.offsetWidth; // Triggers reflow input.classList.add('animate-red-then-fade'); - } else { - this.$emit('search-node', tolNode); } }, focusInput(){ diff --git a/src/components/Tile.vue b/src/components/Tile.vue index 1a506d6..a0c0f0f 100644 --- a/src/components/Tile.vue +++ b/src/components/Tile.vue @@ -3,12 +3,14 @@ import {defineComponent, PropType} from 'vue'; import InfoIcon from './icon/InfoIcon.vue'; import {LayoutNode} from '../layout'; import type {LayoutOptions} from '../layout'; +import type {TolMap} from '../tol'; +import {TolNode} from '../tol'; // Displays one, or a hierarchy of, tree-of-life nodes, as a 'tile' export default defineComponent({ props: { - // A LayoutNode representing a laid-out tree-of-life node to display layoutNode: {type: Object as PropType<LayoutNode>, required: true}, + tolMap: {type: Object as PropType<TolMap>, required: true}, // Options lytOpts: {type: Object as PropType<LayoutOptions>, required: true}, uiOpts: {type: Object, required: true}, @@ -26,12 +28,15 @@ export default defineComponent({ }; }, computed: { + tolNode(): TolNode{ + return this.tolMap[this.layoutNode.name]; + }, // Basic abbreviations isLeaf(): boolean { return this.layoutNode.children.length == 0; }, isExpandableLeaf(): boolean { - return this.isLeaf && this.layoutNode.tolNode.children.length > 0; + return this.isLeaf && this.tolNode.children.length > 0; }, showNonleafHeader(): boolean { return (this.layoutNode.showHeader && this.layoutNode.sepSweptArea == null) || @@ -83,9 +88,11 @@ export default defineComponent({ leafStyles(): Record<string,string> { return { // Image (and scrims) + //backgroundImage: + // 'linear-gradient(to bottom, rgba(0,0,0,0.4), #0000 40%, #0000 60%, rgba(0,0,0,0.4) 100%),' + + // 'url(\'/img/' + this.layoutNode.name.replaceAll('\'', '\\\'') + '.png\')', backgroundImage: - 'linear-gradient(to bottom, rgba(0,0,0,0.4), #0000 40%, #0000 60%, rgba(0,0,0,0.4) 100%),' + - 'url(\'/img/' + this.layoutNode.tolNode.name.replaceAll('\'', '\\\'') + '.png\')', + 'linear-gradient(to bottom, rgba(0,0,0,0.4), #0000 40%, #0000 60%, rgba(0,0,0,0.4) 100%)', backgroundSize: 'cover', // Other borderRadius: this.uiOpts.borderRadius + 'px', @@ -311,7 +318,7 @@ export default defineComponent({ <div v-if="isLeaf" :style="leafStyles" class="w-full h-full flex flex-col overflow-hidden" :class="{'hover:cursor-pointer': isExpandableLeaf}" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave" @mousedown="onMouseDown" @mouseup="onMouseUp"> - <h1 :style="leafHeaderStyles">{{layoutNode.tolNode.name}}</h1> + <h1 :style="leafHeaderStyles">{{layoutNode.name}}</h1> <info-icon :style="[infoIconStyles, {marginTop: 'auto'}]" class="self-end text-white/10 hover:text-white hover:cursor-pointer" @click.stop="onInfoIconClick" @mousedown.stop @mouseup.stop/> @@ -319,7 +326,7 @@ export default defineComponent({ <div v-else :style="nonleafStyles" class="w-full h-full" ref="nonleaf"> <div v-if="showNonleafHeader" :style="nonleafHeaderStyles" class="flex hover:cursor-pointer" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave" @mousedown="onMouseDown" @mouseup="onMouseUp"> - <h1 :style="nonleafHeaderTextStyles" class="grow">{{layoutNode.tolNode.name}}</h1> + <h1 :style="nonleafHeaderTextStyles" class="grow">{{layoutNode.name}}</h1> <info-icon :style="infoIconStyles" class="text-white/10 hover:text-white hover:cursor-pointer" @click.stop="onInfoIconClick" @mousedown.stop @mouseup.stop/> </div> @@ -328,13 +335,13 @@ export default defineComponent({ <div v-if="layoutNode?.sepSweptArea?.sweptLeft === false" :style="nonleafHeaderStyles" class="flex hover:cursor-pointer" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave" @mousedown="onMouseDown" @mouseup="onMouseUp"> - <h1 :style="nonleafHeaderTextStyles" class="grow">{{layoutNode.tolNode.name}}</h1> + <h1 :style="nonleafHeaderTextStyles" class="grow">{{layoutNode.name}}</h1> <info-icon :style="infoIconStyles" class="text-white/10 hover:text-white hover:cursor-pointer" @click.stop="onInfoIconClick" @mousedown.stop @mouseup.stop/> </div> </div> - <tile v-for="child in layoutNode.children" :key="child.tolNode.name" - :layoutNode="child" :lytOpts="lytOpts" :uiOpts="uiOpts" + <tile v-for="child in layoutNode.children" :key="child.name" + :layoutNode="child" :tolMap="tolMap" :lytOpts="lytOpts" :uiOpts="uiOpts" @leaf-click="onInnerLeafClick" @nonleaf-click="onInnerNonleafClick" @leaf-click-held="onInnerLeafClickHeld" @nonleaf-click-held="onInnerNonleafClickHeld" @info-icon-click="onInnerInfoIconClick"/> diff --git a/src/components/TileInfoModal.vue b/src/components/TileInfoModal.vue index 7549375..0e2fc94 100644 --- a/src/components/TileInfoModal.vue +++ b/src/components/TileInfoModal.vue @@ -1,18 +1,19 @@ <script lang="ts"> import {defineComponent, PropType} from 'vue'; import CloseIcon from './icon/CloseIcon.vue'; -import {TolNode} from '../tol'; +import {LayoutNode} from '../layout'; // Displays information about a tree-of-life node export default defineComponent({ props: { - tolNode: {type: Object as PropType<TolNode>, required: true}, + node: {type: Object as PropType<LayoutNode>, required: true}, uiOpts: {type: Object, required: true}, }, computed: { imgStyles(): Record<string,string> { return { - backgroundImage: 'url(\'/img/' + this.tolNode.name.replaceAll('\'', '\\\'') + '.png\')', + //backgroundImage: 'url(\'/img/' + this.node.name.replaceAll('\'', '\\\'') + '.png\')', + background: 'black', width: this.uiOpts.infoModalImgSz + 'px', height: this.uiOpts.infoModalImgSz + 'px', backgroundSize: 'cover', @@ -38,7 +39,7 @@ export default defineComponent({ bg-stone-50 rounded-md shadow shadow-black"> <close-icon @click.stop="onCloseClick" ref="closeIcon" class="block absolute top-2 right-2 w-6 h-6 hover:cursor-pointer"/> - <h1 class="text-center text-xl font-bold mb-2">{{tolNode.name}}</h1> + <h1 class="text-center text-xl font-bold mb-2">{{node.name}}</h1> <hr class="mb-4 border-stone-400"/> <div :style="imgStyles" class="float-left mr-4" alt="an image"></div> <div> |
