aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENCE.txt (renamed from LICENSE.txt)0
-rw-r--r--README.md83
-rw-r--r--backend/README.md4
-rw-r--r--backend/data/README.md2
-rw-r--r--package.json12
-rw-r--r--src/App.vue6
-rw-r--r--src/README.md41
-rw-r--r--src/components/AncestryBar.vue2
-rw-r--r--src/components/HelpModal.vue4
-rw-r--r--src/components/LoadingModal.vue4
-rw-r--r--src/components/SButton.vue3
-rw-r--r--src/components/SearchModal.vue4
-rw-r--r--src/components/SettingsModal.vue4
-rw-r--r--src/components/Tile.vue3
-rw-r--r--src/components/TileInfoModal.vue3
-rw-r--r--src/components/TutorialPane.vue8
-rw-r--r--src/index.css46
-rw-r--r--src/lib.ts4
-rw-r--r--src/main.ts8
-rw-r--r--src/tol.ts6
20 files changed, 144 insertions, 103 deletions
diff --git a/LICENSE.txt b/LICENCE.txt
index 47844fb..47844fb 100644
--- a/LICENSE.txt
+++ b/LICENCE.txt
diff --git a/README.md b/README.md
index e354e7e..a283d6a 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,70 @@
# Tilo
-Provides an interactive visualisation of the biological Tree of Life.
+
+A visual explorer for the biological Tree of Life.
+
+## Project Overview
+
+The UI is largely coded in Typescript, using the [Vue](https://vuejs.org)
+framework, with [Vite](https://vitejs.dev) as the build tool. Much of
+the styling is done using [Tailwind](https://tailwindcss.com). Packages
+are managed using [npm](https://www.npmjs.com) and [Node.js](https://nodejs.org).
+
+On the server side, tree data is served and generated using Python, with packages
+managed using [Pip](https://pypi.org/project/pip). Tree data is stored using [Sqlite](https://www.sqlite.org).
## Files
-- package.json: Contains project information, including package dependencies.
-- src: Contains most of the client-side code.
-- index.html: Holds code for the main page, into which code from 'src' will be included.
-- backend: Contains code for the server, and generating tree-of-life data
-- vite.config.js: For configuring Vite.
-- tailwind.config.js: For configuring Tailwind.
-- postcss.config.js: For configuring Tailwind.
-- tsconfig.json: For configuring Typescript.
-- .gitignore: Lists files to be ignored by Git.
-- public: Contains files to be copied unchanged when building for production.
-
-## Overview
-(TODO)
+
+### Project Level
+- **package.json**: Contains npm project information, such as package dependencies.
+- **package-lock.json**: Auto-generated by npm. Used for replicable installations.
+- **LICENCE.txt**: This project's license (MIT).
+- **.gitignore**: Lists files to be ignored by Git.
+### Client & Server
+- **src**: Contains most of the client-side code.
+- **index.html**: Holds code for the main page, into which code from 'src' will be included.
+- **public**: Contains files to be copied unchanged in the production-build of the UI.
+- **backend**: Contains code for the server, and for generating tree-of-life data.
+### Configuration
+- **vite.config.js**: For configuring Vite.
+- **tailwind.config.js**: For configuring Tailwind.
+- **postcss.config.js**: For configuring Tailwind.
+- **tsconfig.json**: For configuring Typescript.
## Setup Instructions
-(TODO)
-##
+Note: Running your own version of the client and server should be
+straightforward, but generating the database will take a long time.
+More details are in backend/data/README.md.
+
+### Base Requirements
+- **[Python](https://www.python.org/downloads)**: For running server-side code, and generating the database.
+- **Pip**: For installing Python packages. Included in the Python download.
+- **[Git](https://git-scm.com/downloads)** (optional): For downloading and viewing snapshots of the project.
+
+### Client Side
+1. If you don't have npm or Node.js installed, you can download a Node installer from
+ <https://nodejs.org/en/download>, which includes npm. This project was coded using version 16.
+1. In this directory, run the command `npm install`, which install packages listed in
+ package.json, creating a `node_modules` directory to hold them.
+
+### Server Side
+1. If you don't have Python 3 installed, see <https://www.python.org/downloads>.
+ The package manager Pip is included.
+1. The database used by the server is generated using scripts in backend/data/.
+ See it's README.md for instructions. You'll likely need to install a few
+ packages using Pip.
+1. To run the dev server, you'll need to install jsonpickle. This can be done
+ using `python -m pip install jsonpickle`. If you want to keep the installed
+ package separate from your system's packages, it's common practice to use
+ the 'venv' module.
+
+### Running Tilo
+1. In the backend/ directory, run `./server.py`, which starts a basic HTTP server that provides
+ tree-of-life data on port 8000.
+1. In this directory, or somewhere in src/, run `npm run dev`. This starts a dev server that
+ provides Tilo's user interface on port 3000.
+1. Open a web browser, and navigate to <http://localhost:3000>.
+
+## Licence
-During development, a client request to the server on the same machine
-would be blocked due to the Same Origin Policy. This is avoided by
-adding an 'Access-Control-Allow-Origin: *' header to server responses.
-This should be disabled during production.
+Tilo is licensed under the MIT licence, provided in LICENSE.txt
diff --git a/backend/README.md b/backend/README.md
index 358ed72..1823576 100644
--- a/backend/README.md
+++ b/backend/README.md
@@ -1,7 +1,7 @@
# Files
+- data: Contains scripts for generating the tree-of-life database
+- tilo.py: WSGI script that serves tree-of-life data
- server.py: Basic dev server that serves a WSGI script
-- tilo.py: WSGI script that serves tree-of-life data
-- data: Contains scripts for generating the tree-of-life database
# During development
Having generated the database as data/data.db, running `server.py`,
diff --git a/backend/data/README.md b/backend/data/README.md
index 13aeb89..ba64114 100644
--- a/backend/data/README.md
+++ b/backend/data/README.md
@@ -49,7 +49,7 @@ This directory holds files used to generate data.db, which contains tree-of-life
For the most part, these steps should be done in order.
As a warning, the whole process takes a lot of time and file space. The tree will probably
-have about 2.5 billion nodes. Downloading the images will take several days, and occupy over
+have about 2.5 billion nodes. Downloading the images takes several days, and occupies over
200 GB. And if you want good data, you'll need to do some manual review, which can take weeks.
## Environment
diff --git a/package.json b/package.json
index f9c23ff..f20f11e 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,8 @@
{
- "name": "grid-of-life",
+ "name": "tilo",
"private": true,
"version": "0.0.0",
- "description": "An interactive visualisation of the biological tree of life",
+ "description": "A visual explorer for the biological Tree of Life",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
@@ -12,16 +12,16 @@
"author": "Terry Truong",
"license": "MIT",
"dependencies": {
- "smartcrop-cli": "^2.0.3",
- "vue": "^3.2.25"
+ "vue": "^3.2.25",
+ "smartcrop-cli": "^2.0.3"
},
"devDependencies": {
+ "vite": "^2.8.0",
"@vitejs/plugin-vue": "^2.2.0",
+ "tailwindcss": "^3.0.23",
"autoprefixer": "^10.4.2",
"postcss": "^8.4.7",
- "tailwindcss": "^3.0.23",
"typescript": "^4.6.2",
- "vite": "^2.8.0",
"vue-tsc": "^0.32.1"
}
}
diff --git a/src/App.vue b/src/App.vue
index f26e1fb..4285f6a 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -101,6 +101,9 @@ import {queryServer, InfoResponse, Action,
UiOptions, getDefaultLytOpts, getDefaultUiOpts, OptionType} from './lib';
import {arraySum, randWeightedChoice, timeout} from './util';
+// Constants
+const SERVER_WAIT_MSG = 'Loading data';
+const PROCESSING_WAIT_MSG = 'Processing';
// Type representing auto-mode actions
type AutoAction = 'move across' | 'move down' | 'move up' | Action;
// Function used in auto-mode to reduce action cycles
@@ -117,9 +120,6 @@ function getReverseAction(action: AutoAction): AutoAction | null {
return null;
}
}
-// Constants
-const SERVER_WAIT_MSG = 'Loading data';
-const PROCESSING_WAIT_MSG = 'Processing';
export default defineComponent({
data(){
diff --git a/src/README.md b/src/README.md
index 23f05ee..5c88b2e 100644
--- a/src/README.md
+++ b/src/README.md
@@ -1,21 +1,22 @@
# Files
-- main.ts: Included by ../index.html. Creates the main Vue component.
-- App.vue: The main Vue component.
-- components:
- - Tile.vue: Displays a tree-of-life node.
- - TileInfoModal.vue: Modal displaying info about a Tile's node.
- - SearchModal.vue: Modal providing a search bar.
- - SettingsModal: Modal displaying configurable settings.
- - HelpModal.vue: Modal displaying help info.
- - AncestryBar.vue: Displays ancestors of the outermost Tile.
- - TutorialPane.vue: Displays tutorial content.
- - LoadingModal.vue: Displays a loading indicator.
- - SButton.vue: Simple button component.
- - IconButton.vue: Simple button component containing an SVG icon.
- - SCollapsible.vue: Simple collapsible-content component.
- - icon: Contains components that display SVG icons.
-- lib.ts: Contains classes/types and utility functions.
-- layout.ts: Contains code for laying out Tiles.
-- util.ts: Contains utility functions.
-- index.css: Included by main.ts. Provides Tailwind's CSS classes.
-- env.d.ts: From Vite's template files.
+- **main.ts**: Included by ../index.html. Creates the main Vue component.
+- **App.vue**: The main Vue component.
+- **components**:
+ - **Tile.vue**: Displays a tree-of-life node.
+ - **TileInfoModal.vue**: Modal displaying info about a Tile's node.
+ - **SearchModal.vue**: Modal providing a search bar.
+ - **SettingsModal**: Modal displaying configurable settings.
+ - **HelpModal.vue**: Modal displaying help info.
+ - **AncestryBar.vue**: Displays ancestors of the outermost Tile.
+ - **TutorialPane.vue**: Displays tutorial content.
+ - **LoadingModal.vue**: Displays a loading indicator.
+ - **SButton.vue**: Simple button component.
+ - **IconButton.vue**: Simple button component containing an SVG icon.
+ - **SCollapsible.vue**: Simple collapsible-content component.
+ - **icon**: Contains components that display SVG icons.
+- **tol.ts**: Holds types for tree-of-life data.
+- **layout.ts**: Holds code for laying out tiles.
+- **lib.ts**: Holds project-wide globals.
+- **util.ts**: Holds utility functions.
+- **index.css**: Included by main.ts. Provides Tailwind's CSS classes.
+- **env.d.ts**: From Vite's template files.
diff --git a/src/components/AncestryBar.vue b/src/components/AncestryBar.vue
index fcf9933..6f2d37c 100644
--- a/src/components/AncestryBar.vue
+++ b/src/components/AncestryBar.vue
@@ -75,7 +75,7 @@ export default defineComponent({
},
},
watch: {
- // Used to scroll to end of bar upon node/screen changes
+ // For scrolling-to-end upon node/screen changes
nodes(){
this.$nextTick(() => this.scrollToEnd());
},
diff --git a/src/components/HelpModal.vue b/src/components/HelpModal.vue
index 7375584..cc11afb 100644
--- a/src/components/HelpModal.vue
+++ b/src/components/HelpModal.vue
@@ -358,14 +358,14 @@
</template>
<template #content>
<div :class="contentClasses">
- <li>Tilo's code is licensed under the MIT license.</li>
+ <li>Tilo's code is licensed under the MIT licence.</li>
<br/>
<h1 class="text-lg font-bold">Other Credits</h1>
<ul class="list-disc pl-4">
<li>
The UI was largely coded in
<a href="https://www.typescriptlang.org/" :style="aStyles">Typescript</a>,
- and built using the <a href="https://vuejs.org/" :style="aStyles">Vue framework</a>
+ and built using the <a href="https://vuejs.org/" :style="aStyles">Vue</a> framework.
</li>
<li>
Tree data was processed using
diff --git a/src/components/LoadingModal.vue b/src/components/LoadingModal.vue
index 506abf4..ee8d699 100644
--- a/src/components/LoadingModal.vue
+++ b/src/components/LoadingModal.vue
@@ -28,8 +28,6 @@ export default defineComponent({
};
},
},
- components: {
- LoaderIcon,
- },
+ components: {LoaderIcon, },
});
</script>
diff --git a/src/components/SButton.vue b/src/components/SButton.vue
index 54c7843..508f8e6 100644
--- a/src/components/SButton.vue
+++ b/src/components/SButton.vue
@@ -1,6 +1,5 @@
<template>
-<button :disabled="disabled"
- class="block rounded px-4 py-2"
+<button :disabled="disabled" class="block rounded px-4 py-2"
:class="{'hover:brightness-125': !disabled, 'brightness-50': disabled}">
<slot>?</slot>
</button>
diff --git a/src/components/SearchModal.vue b/src/components/SearchModal.vue
index 025ed71..e90707a 100644
--- a/src/components/SearchModal.vue
+++ b/src/components/SearchModal.vue
@@ -61,7 +61,7 @@ export default defineComponent({
pendingDelayedSuggReq: 0, // Set via setTimeout() for a non-initial search-suggestions request
pendingSuggInput: '', // Used to remember what input triggered a suggestions request
// Other
- focusedSuggIdx: null as null | number, // Denotes a search-suggestion selected using the arrow keys
+ focusedSuggIdx: null as null | number, // Index of a search-suggestion selected using the arrow keys
};
},
computed: {
@@ -197,7 +197,7 @@ export default defineComponent({
if (tolNodeName == ''){
return;
}
- // Check if the node has already been retrieved
+ // Check if the node data is already here
if (this.lytMap.has(tolNodeName)){
this.$emit('search', tolNodeName);
return;
diff --git a/src/components/SettingsModal.vue b/src/components/SettingsModal.vue
index a298230..4f5f05e 100644
--- a/src/components/SettingsModal.vue
+++ b/src/components/SettingsModal.vue
@@ -107,9 +107,7 @@
Reset
</s-button>
<transition name="fade">
- <div v-if="saved" class="absolute right-1 bottom-1" ref="saveIndicator">
- Saved
- </div>
+ <div v-if="saved" class="absolute right-1 bottom-1" ref="saveIndicator"> Saved </div>
</transition>
</div>
</div>
diff --git a/src/components/Tile.vue b/src/components/Tile.vue
index c2f2b9c..2edd531 100644
--- a/src/components/Tile.vue
+++ b/src/components/Tile.vue
@@ -1,5 +1,5 @@
<template>
-<div :style="styles" @scroll="onScroll"> <!-- Need enclosing div for transitions -->
+<div :style="styles" @scroll="onScroll">
<div v-if="isLeaf" :class="[hasOneImage ? 'flex' : 'grid', {'hover:cursor-pointer': isExpandableLeaf}]"
class="w-full h-full flex-col grid-cols-1" :style="leafStyles"
@mouseenter="onMouseEnter" @mouseleave="onMouseLeave" @mousedown="onMouseDown" @mouseup="onMouseUp">
@@ -557,6 +557,7 @@ export default defineComponent({
</script>
<style>
+/* For making a parent-swept-area div look continuous with the tile div */
.hide-right-edge::before {
content: '';
position: absolute;
diff --git a/src/components/TileInfoModal.vue b/src/components/TileInfoModal.vue
index 0461de6..053604c 100644
--- a/src/components/TileInfoModal.vue
+++ b/src/components/TileInfoModal.vue
@@ -1,8 +1,7 @@
<template>
<div class="fixed left-0 top-0 w-full h-full bg-black/40" @click="onClose">
<div class="absolute left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2
- max-w-[80%] min-w-[8cm] md:min-w-[14cm] max-h-[80%]"
- :style="styles">
+ max-w-[80%] min-w-[8cm] md:min-w-[14cm] max-h-[80%]" :style="styles">
<div class="pb-1 md:pb-2">
<close-icon @click.stop="onClose" ref="closeIcon"
class="absolute top-1 right-1 md:top-2 md:right-2 w-8 h-8 hover:cursor-pointer"/>
diff --git a/src/components/TutorialPane.vue b/src/components/TutorialPane.vue
index 90d0aca..8de656c 100644
--- a/src/components/TutorialPane.vue
+++ b/src/components/TutorialPane.vue
@@ -1,13 +1,12 @@
<template>
<div :style="styles" class="relative flex flex-col justify-between">
- <close-icon @click.stop="onClose"
- class="absolute top-2 right-2 w-8 h-8 hover:cursor-pointer"/>
+ <close-icon @click.stop="onClose" class="absolute top-2 right-2 w-8 h-8 hover:cursor-pointer"/>
<h1 class="text-center text-lg font-bold pt-3 pb-2">
{{stage == 0 ? 'Welcome' : `Tutorial (Step ${stage} of ${lastStage})`}}
</h1>
<transition name="fade" mode="out-in">
<div v-if="stage == 0" :style="contentStyles">
- This is a visualiser for exploring the biological Tree of Life.
+ This is a visual explorer for the biological Tree of Life.
</div>
<div v-else-if="stage == 1" :style="contentStyles">
{{touchDevice ? 'Tap' : 'Click'}} a tile to expand it, showing it's children
@@ -75,7 +74,8 @@ import {Action, UiOptions} from '../lib';
export default defineComponent({
props: {
- actionsDone: {type: Object as PropType<Set<Action>>, required: true}, // Used to avoid disabling actions already seen
+ actionsDone: {type: Object as PropType<Set<Action>>, required: true},
+ // Used to avoid disabling actions already done
triggerFlag: {type: Boolean, required: true},
// Used to indicate that a tutorial-requested 'trigger' action has been done
skipWelcome: {type: Boolean, default: false},
diff --git a/src/index.css b/src/index.css
index 3330a37..855e9f0 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,29 +1,8 @@
+/* From Tailwind */
@tailwind base;
@tailwind components;
@tailwind utilities;
-@font-face {
- font-family: Ubuntu;
- src: url('/fonts/Ubuntu-Regular.woff2');
-}
-body {
- font-family: Ubuntu, system-ui, sans-serif;
- touch-action: manipulation; /* Prevents non-standard gestures such as double-tap to zoom */
-}
-a {
- @apply hover:underline hover:cursor-pointer;
-}
-::-webkit-scrollbar {
- background-color: #1c1917;
- width: 12px;
- height: 12px;
-}
-::-webkit-scrollbar-thumb {
- background: #65a30d;
- border-radius: 5px;
- border: 3px solid #1c1917;
-}
-
/* For transitions/animations */
.fade-enter-from, .fade-leave-to {
opacity: 0;
@@ -114,3 +93,26 @@ a {
color: inherit;
}
}
+
+/* Other */
+@font-face {
+ font-family: Ubuntu;
+ src: url('/fonts/Ubuntu-Regular.woff2');
+}
+body {
+ font-family: Ubuntu, system-ui, sans-serif;
+ touch-action: manipulation; /* Prevents non-standard gestures such as double-tap to zoom */
+}
+a {
+ @apply hover:underline hover:cursor-pointer;
+}
+::-webkit-scrollbar {
+ background-color: #1c1917;
+ width: 12px;
+ height: 12px;
+}
+::-webkit-scrollbar-thumb {
+ background: #65a30d;
+ border-radius: 5px;
+ border: 3px solid #1c1917;
+}
diff --git a/src/lib.ts b/src/lib.ts
index 7ff0b73..d2ad959 100644
--- a/src/lib.ts
+++ b/src/lib.ts
@@ -1,5 +1,5 @@
/*
- * Project-wide types/classes
+ * Project-wide globals
*/
import {TolNode} from './tol';
@@ -8,6 +8,7 @@ import {getBreakpoint, Breakpoint, getScrollBarWidth, onTouchDevice} from './uti
// For server requests
const SERVER_URL = (new URL(window.location.href)).origin + '/data'
+const SERVER_IMG_PATH = '/img/'
export async function queryServer(params: URLSearchParams){
// Construct URL
let url = new URL(SERVER_URL);
@@ -23,7 +24,6 @@ export async function queryServer(params: URLSearchParams){
}
return responseObj;
}
-const SERVER_IMG_PATH = '/img/'
export function getImagePath(imgName: string): string {
return SERVER_IMG_PATH + imgName.replaceAll('\'', '\\\'');
}
diff --git a/src/main.ts b/src/main.ts
index 50a4dab..f289386 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,5 +1,5 @@
-import { createApp } from 'vue'
-import App from './App.vue'
-import './index.css'
+import {createApp} from 'vue';
+import App from './App.vue';
+import './index.css';
-createApp(App).mount('#app')
+createApp(App).mount('#app');
diff --git a/src/tol.ts b/src/tol.ts
index bf7a2f5..2618bfc 100644
--- a/src/tol.ts
+++ b/src/tol.ts
@@ -1,5 +1,5 @@
/*
- * Used to represent tree-of-life data
+ * Types for representing tree-of-life data
*/
// Represents a tree-of-life node
@@ -8,10 +8,10 @@ export class TolNode {
children: string[];
parent: string | null;
tips: number;
- pSupport: boolean;
+ pSupport: boolean; // Indicates phylogenetic support
commonName: null | string;
imgName: null | string |
- [string, string] | [null, string] | [string, null]; // Pairs represent compound-images
+ [string, string] | [null, string] | [string, null]; // Pairs represent compound images
constructor(children: string[] = [], parent = null, tips = 0, pSupport = false){
this.otolId = null;
this.children = children;