aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/App.vue65
-rw-r--r--src/components/SearchModal.vue2
-rw-r--r--src/components/SettingsPane.vue19
-rw-r--r--src/components/TileInfoModal.vue1
4 files changed, 64 insertions, 23 deletions
diff --git a/src/App.vue b/src/App.vue
index caf5aa9..55dc271 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -39,9 +39,9 @@ function getReverseAction(action: Action): Action | null {
}
// Initialise tree-of-life data
-const rootName = "cellular organisms";
-const tolMap: TolMap = new Map();
-tolMap.set(rootName, new TolNode());
+const ROOT_NAME = "cellular organisms";
+const initialTolMap: TolMap = new Map();
+initialTolMap.set(ROOT_NAME, new TolNode());
// Configurable options
const defaultLytOpts: LayoutOptions = {
@@ -86,13 +86,15 @@ const defaultUiOpts = {
// Timing related
tileChgDuration: 300, //ms (for tile move/expand/collapse)
clickHoldDuration: 400, //ms (duration after mousedown when a click-and-hold is recognised)
+ // Other
+ useReducedTree: false,
};
export default defineComponent({
data(){
- let layoutTree = initLayoutTree(tolMap, rootName, 0);
+ let layoutTree = initLayoutTree(initialTolMap, ROOT_NAME, 0);
return {
- tolMap: tolMap,
+ tolMap: initialTolMap,
layoutTree: layoutTree,
activeRoot: layoutTree, // Differs from layoutTree root when expand-to-view is used
layoutMap: initLayoutMap(layoutTree), // Maps names to LayoutNode objects
@@ -207,7 +209,9 @@ export default defineComponent({
// Check if data for node-to-expand exists, getting from server if needed
let tolNode = this.tolMap.get(layoutNode.name)!;
if (!this.tolMap.has(tolNode.children[0])){
- return fetch('/data/node?name=' + encodeURIComponent(layoutNode.name))
+ let urlPath = '/data/node?name=' + encodeURIComponent(layoutNode.name)
+ urlPath += this.uiOpts.useReducedTree ? '&tree=reduced' : '';
+ return fetch(urlPath)
.then(response => response.json())
.then(obj => {
Object.getOwnPropertyNames(obj).forEach(key => {this.tolMap.set(key, obj[key])});
@@ -284,7 +288,9 @@ export default defineComponent({
// Check if data for node-to-expand exists, getting from server if needed
let tolNode = this.tolMap.get(layoutNode.name)!;
if (!this.tolMap.has(tolNode.children[0])){
- return fetch('/data/node?name=' + encodeURIComponent(layoutNode.name))
+ let urlPath = '/data/node?name=' + encodeURIComponent(layoutNode.name)
+ urlPath += this.uiOpts.useReducedTree ? '&tree=reduced' : '';
+ return fetch(urlPath)
.then(response => response.json())
.then(obj => {
Object.getOwnPropertyNames(obj).forEach(key => {this.tolMap.set(key, obj[key])});
@@ -513,6 +519,15 @@ export default defineComponent({
tryLayout(this.activeRoot, this.tileAreaPos, this.tileAreaDims, this.lytOpts,
{allowCollapse: true, layoutMap: this.layoutMap});
},
+ onTreeChange(){
+ // Collapse tree to root
+ if (this.activeRoot != this.layoutTree){
+ this.onDetachedAncestorClick(this.layoutTree);
+ }
+ this.onNonleafClick(this.layoutTree);
+ // Re-initialise tree
+ this.initTreeFromServer();
+ },
// For other events
onResize(){
if (!this.resizeThrottled){
@@ -540,6 +555,24 @@ export default defineComponent({
}
},
// Helper methods
+ initTreeFromServer(){
+ let urlPath = '/data/node?name=' + encodeURIComponent(ROOT_NAME);
+ urlPath += this.uiOpts.useReducedTree ? '&tree=reduced' : '';
+ fetch(urlPath)
+ .then(response => response.json())
+ .then(obj => {
+ this.tolMap.clear();
+ Object.getOwnPropertyNames(obj).forEach(key => {this.tolMap.set(key, obj[key])});
+ this.layoutTree = initLayoutTree(this.tolMap, this.layoutTree.name, 0);
+ this.activeRoot = this.layoutTree;
+ this.layoutMap = initLayoutMap(this.layoutTree);
+ tryLayout(this.activeRoot, this.tileAreaPos, this.tileAreaDims, this.lytOpts,
+ {allowCollapse: true, layoutMap: this.layoutMap});
+ })
+ .catch(error => {
+ console.log('ERROR loading initial tolnode data', error);
+ });
+ },
resetMode(){
this.infoModalNode = null;
this.searchOpen = false;
@@ -563,20 +596,7 @@ export default defineComponent({
window.addEventListener('keyup', this.onKeyUp);
tryLayout(this.activeRoot, this.tileAreaPos, this.tileAreaDims, this.lytOpts,
{allowCollapse: true, layoutMap: this.layoutMap});
- // Get initial tol node data
- fetch('/data/node?name=' + encodeURIComponent(rootName))
- .then(response => response.json())
- .then(obj => {
- Object.getOwnPropertyNames(obj).forEach(key => {this.tolMap.set(key, obj[key])});
- this.layoutTree = initLayoutTree(this.tolMap, this.layoutTree.name, 0);
- this.activeRoot = this.layoutTree;
- this.layoutMap = initLayoutMap(this.layoutTree);
- tryLayout(this.activeRoot, this.tileAreaPos, this.tileAreaDims, this.lytOpts,
- {allowCollapse: true, layoutMap: this.layoutMap});
- })
- .catch(error => {
- console.log('ERROR loading initial tolnode data', error);
- });
+ this.initTreeFromServer();
},
unmounted(){
window.removeEventListener('resize', this.onResize);
@@ -627,7 +647,8 @@ export default defineComponent({
<!-- Settings -->
<transition name="slide-bottom-right">
<settings-pane v-if="settingsOpen" :lytOpts="lytOpts" :uiOpts="uiOpts"
- @settings-close="settingsOpen = false" @layout-option-change="onLayoutOptionChange"/>
+ @settings-close="settingsOpen = false"
+ @layout-option-change="onLayoutOptionChange" @tree-change="onTreeChange"/>
<div v-else class="absolute bottom-0 right-0 w-[100px] h-[100px] invisible">
<!-- Note: Above enclosing div prevents transition interference with inner rotate -->
<div class="absolute bottom-[-50px] right-[-50px] w-[100px] h-[100px] visible -rotate-45
diff --git a/src/components/SearchModal.vue b/src/components/SearchModal.vue
index dbe47af..eccc685 100644
--- a/src/components/SearchModal.vue
+++ b/src/components/SearchModal.vue
@@ -41,6 +41,7 @@ export default defineComponent({
let url = new URL(window.location.href);
url.pathname = '/data/chain';
url.search = '?name=' + encodeURIComponent(tolNodeName);
+ url.search += (this.uiOpts.useReducedTree ? '&tree=reduced' : '');
fetch(url.toString())
.then(response => response.json())
.then(obj => {
@@ -80,6 +81,7 @@ export default defineComponent({
let url = new URL(window.location.href);
url.pathname = '/data/search';
url.search = '?name=' + encodeURIComponent(input.value);
+ url.search += (this.uiOpts.useReducedTree ? '&tree=reduced' : '');
this.lastSuggReqId += 1;
let suggsId = this.lastSuggReqId;
let reqDelay = 0;
diff --git a/src/components/SettingsPane.vue b/src/components/SettingsPane.vue
index 13a7f26..cf046c3 100644
--- a/src/components/SettingsPane.vue
+++ b/src/components/SettingsPane.vue
@@ -34,9 +34,12 @@ export default defineComponent({
}
this.onLytOptChg();
},
+ onTreeChg(){
+ this.$emit('tree-change');
+ },
},
components: {CloseIcon, },
- emits: ['settings-close', 'layout-option-change', ],
+ emits: ['settings-close', 'layout-option-change', 'tree-change', ],
});
</script>
@@ -115,5 +118,19 @@ export default defineComponent({
<label>Animation Duration <input type="range" min="0" max="3000" class="mx-2 w-[3cm]"
v-model.number="uiOpts.tileChgDuration"/></label>
</div>
+ <hr class="border-stone-400"/>
+ <div>
+ Tree
+ <ul>
+ <li>
+ <label> <input type="radio" v-model="uiOpts.useReducedTree" :value="false"
+ @change="onTreeChg"/> Default </label>
+ </li>
+ <li>
+ <label> <input type="radio" v-model="uiOpts.useReducedTree" :value="true"
+ @change="onTreeChg"/> Reduced </label>
+ </li>
+ </ul>
+ </div>
</div>
</template>
diff --git a/src/components/TileInfoModal.vue b/src/components/TileInfoModal.vue
index 72515d3..6701f1f 100644
--- a/src/components/TileInfoModal.vue
+++ b/src/components/TileInfoModal.vue
@@ -82,6 +82,7 @@ export default defineComponent({
<h1 class="text-center text-xl font-bold mb-2">
{{displayName}}
<div v-if="tolNode.children.length > 0">({{tolNode.children.length}} children)</div>
+ <div>({{tolNode.tips}} tips)</div>
</h1>
<hr class="mb-4 border-stone-400"/>
<div class="flex">