diff options
| author | Terry Truong <terry06890@gmail.com> | 2022-07-04 20:46:36 +1000 |
|---|---|---|
| committer | Terry Truong <terry06890@gmail.com> | 2022-07-04 20:46:36 +1000 |
| commit | 6adc1e2696ec997c2e6b74043e06cfd87c6486c1 (patch) | |
| tree | 4a925de1285672bfc00eb083209ad0e09dca8eb1 /src | |
| parent | 567a21a8d0498f467f558d9ec1a6db8f1b52c0e6 (diff) | |
Add help-info content
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/HelpModal.vue | 412 | ||||
| -rw-r--r-- | src/components/SettingsModal.vue | 11 | ||||
| -rw-r--r-- | src/components/TileInfoModal.vue | 20 | ||||
| -rw-r--r-- | src/lib.ts | 2 |
4 files changed, 398 insertions, 47 deletions
diff --git a/src/components/HelpModal.vue b/src/components/HelpModal.vue index f410d42..57ae90e 100644 --- a/src/components/HelpModal.vue +++ b/src/components/HelpModal.vue @@ -1,44 +1,367 @@ <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 - w-4/5 max-w-[20cm] max-h-[80%] overflow-auto" :style="styles"> + w-4/5 max-w-[16cm] max-h-[80%] overflow-auto" :style="styles"> <close-icon @click.stop="onClose" ref="closeIcon" class="block absolute top-1 right-1 md:top-2 md:right-2 w-8 h-8 hover:cursor-pointer"/> - <h1 class="text-center text-xl font-bold py-2 border-b border-stone-400">Help</h1> - <div class="p-2 border-b border-stone-400"> - <s-collapsible class="border border-stone-400 rounded"> - <template v-slot:summary="slotProps"> - <div class="p-1 text-center" - :style="{backgroundColor: !slotProps.collapsed ? 'gray' : 'transparent'}"> - <down-icon class="inline-block w-5 h-5 transition-transform duration-300" - :class="{'-rotate-90': slotProps.collapsed}"/> - Summary text + <h1 class="text-center text-xl font-bold pt-2 pb-1">Help</h1> + <div class="flex flex-col gap-2 p-2"> + <s-collapsible :class="scClasses"> + <template #summary="slotProps"> + <div :class="scSummaryClasses"> + <down-icon :class="slotProps.collapsed ? downIconClasses : downIconExpandedClasses"/> + What is the Tree of Life? </div> </template> - <template v-slot:content> - <div class="p-1"> - Lorem ipsum dolor sit amet, consectetur adipiscing - elit, sed do eiusmod tempor incididunt ut labore - et dolore magna aliqua. Ut enim ad minim veniam, - quis nostrud exercitation ullamco laboris nisi ut - aliquip ex ea commodo consequat. + <template #content> + <div :class="contentClasses"> + <p> + In theory, the Tree of Life represents all living organisms, along with their parents, + grandparents, and so on, all the way up to a single common ancestor. + </p> + <div class="my-2 w-4/5 mx-auto flex flex-col items-center gap-1 md:flex-row md:gap-2 md:w-fit"> + <img src="data:," width="240" height="180" alt="Simple Tree of Life" + class="border border-black block mx-auto md:mx-0 md:shrink-0"/> + <p class="text-sm md:max-w-[4cm]"> + Each dot is a <strong>node</strong>, and represents a <strong>taxon</strong>, + which might be a species, genus, or otherwise. The top node is the + <strong>root</strong>, and those without children are <strong>leaves</strong>. + </p> + </div> + <p> + The metaphor doesn't always fit. For example, many bacteria can transfer + DNA to each other without creating children. But the concept is still helpful for + visualisation. + </p> + <br/> + <p> + Determining the structure of the tree is an ongoing area + of work, but much of it has been traced out using genetic information, + statistical analysis, and human inference. + </p> + </div> + </template> + </s-collapsible> + <s-collapsible :class="scClasses"> + <template #summary="slotProps"> + <div :class="scSummaryClasses"> + <down-icon :class="slotProps.collapsed ? downIconClasses : downIconExpandedClasses"/> + Visualising the Tree + </div> + </template> + <template #content> + <div :class="contentClasses"> + <p> + Tilo attempts to display the Tree of Life by representing nodes with tiles, + and placing tiles within other tiles to show tree structure. + </p> + <img src="data:," width="400" height="200" alt="Tree with Tile layout" + class="border border-black block mx-auto mt-2"/> + <br/> + <p> + Within a tile's header: + <ul class="list-disc pl-4"> + <li> + The color denotes the number of children. + White means zero, + <span style="color: limegreen">green</span> means 1+, + <span style="color: darkorange">orange</span> means 10+, + and <span style="color: crimson">red</span> means 100+. + </li> + <li> + An asterisk indicates that the node's placement lack evidence, or is disputed. + <span class="text-xs md:text-sm text-stone-500"> + (In the Open Tree of Life, each node has zero or more associated hypothetical + trees that either support or conflict with it. The asterisk is added if + there are no supporting trees, or if there is a single conflicting tree.) + </span> + </li> + </ul> + </p> + <br/> + <p> + There are many other methods of visualisation, which can enable viewing + many more nodes as text, or for exploring a more natural tree-like diagram. + Examples include + <a href="https://itol.embl.de/">iTOL</a> + <external-link-icon :class="linkIconClasses"/> + and <a href="https://www.onezoom.org/">OneZoom</a> + <external-link-icon :class="linkIconClasses"/>. + <div class="flex gap-2 justify-evenly mt-1 md:mt-2"> + <img src="data:," width="200" height="200" alt="iTOL" + class="border border-black block"/> + <img src="data:," width="200" height="200" alt="OneZoom" + class="border border-black block"/> + </div> + </p> + </div> + </template> + </s-collapsible> + <s-collapsible :class="scClasses"> + <template #summary="slotProps"> + <div :class="scSummaryClasses"> + <down-icon :class="slotProps.collapsed ? downIconClasses : downIconExpandedClasses"/> + Using Tilo + </div> + </template> + <template #content> + <div :class="contentClasses"> + <p> + This section provides some details not included in the tutorial. + </p> + <br/> + <h1 class="text-lg font-bold">Settings</h1> + <ul class="list-disc pl-4"> + <li> + <h2 class="font-bold">Sweep leaves left</h2> + <p> + If disabled, an expanded tile's children are simply laid out in order. + This can leave a lot of empty space when large children are next to small ones. + Moving the unexpanded children (the 'leaves') to the left helps avoid this. + <img src="data:," width="400" height="200" alt="Sweep leaves setting effect" + class="border border-black block mx-auto my-1"/> + </p> + </li> + <li> + <h2 class="font-bold">Sweep into parent</h2> + <p> + If enabled, leaves being swept left can be moved beyond the tile's + rectangle, into leftover space in the parent. + <img src="data:," width="400" height="200" alt="Sweep into parent setting effect" + class="border border-black block mx-auto my-1"/> + </p> + </li> + <li> + <h2 class="font-bold">Trees to use</h2> + <p> + Three choices are available, and all are simplified versions of + the tree from the Open Tree of Life. + <span class="text-xs md:text-sm text-stone-500"> + (Without this, some nodes would have over 10,000 children, and + significantly slow the browser down during rendering) + </span> + </p> + <ul class="list-[circle] pl-4"> + <li> + <span class="font-bold">Complex:</span> + The least simplified choice. In short, it only includes + nodes that have an image or description, with a soft limit of 600 children. + <span class="text-xs md:text-sm text-stone-500"> + (Has about 450,000 nodes) + </span> + </li> + <li> + <span class="font-bold">Visual:</span> + Only keeps nodes with images, with a soft limit of 300 children. + <span class="text-xs md:text-sm text-stone-500"> + (Has about 140,000 nodes) + </span> + </li> + <li> + <span class="font-bold">Minimal:</span> + Created using a rough list of 'well known' + taxons, and adding a few more at random. + <span class="text-xs md:text-sm text-stone-500"> + (Has about 3,300 nodes) + </span> + </li> + </ul> + </li> + <li> + <h2 class="font-bold">Slider Resets</h2> + <p> + You can {{touchDevice ? 'tap' : 'click'}} on + a slider's label to reset it to the default value. + </p> + </li> + </ul> + <br/> + <h1 class="text-lg font-bold">Keyboard Shortcuts</h1> + <ul class="list-disc pl-4"> + <li>Ctrl-F opens the search bar</li> + <li>Ctrl-Shift-F toggles the search animation</li> + <li>Esc closes an open pane, and cancels an active search or auto mode</li> + </ul> + <br/> + <h1 class="text-lg font-bold">Unusual Node Names</h1> + <ul class="list-disc pl-4"> + <li> + <h2 class="font-bold">Disambiguation Nodes</h2> + <p> + These have names like 'Iris [2]'. When multiple nodes have the same + name, all but one gets an '[N]' appended, where N is 2 or above. + </p> + </li> + <li> + <h2 class="font-bold">Compound Nodes</h2> + <p> + These are only present in the Complex tree, and have names like + '[Homo Sapiens + Homo Heidelbergensis]'. They provide structure for other nodes, + and are named after two prominent descendants. + </p> + </li> + </ul> + <br/> + <h1 class="text-lg font-bold">Overflowing Tiles</h1> + <p> + Some tiles have too many children to fit on-screen at once, and are displayed + with a scroll bar. For layout reasons, this is only done if they are the + outermost tile, so you may need to {{touchDevice ? 'double tap' : 'click and hold'}} + the tile to expand it. + </p> + </div> + </template> + </s-collapsible> + <s-collapsible :class="scClasses"> + <template #summary="slotProps"> + <div :class="scSummaryClasses"> + <down-icon :class="slotProps.collapsed ? downIconClasses : downIconExpandedClasses"/> + Data Sources + </div> + </template> + <template #content> + <div :class="contentClasses"> + <h1 class="text-lg font-bold">Sources</h1> + <ul class="list-disc pl-4"> + <li> + The tree structure was obtained from the Open Tree of Life + <a href="https://tree.opentreeoflife.org/about/synthesis-release" + :style="anchorStyles">synthesis release</a> + <external-link-icon :class="linkIconClasses"/> + version 13.4, accessed 23/04/2022. + </li> + <li> + The images and alternative-names data was partly obtained from the + Encyclopedia of Life. Name data was obtained from + <a href="https://opendata.eol.org/dataset/vernacular-names" :style="anchorStyles" + >here</a><external-link-icon :class="linkIconClasses"/>, + and image metadata from + <a href="https://opendata.eol.org/dataset/images-list" :style="anchorStyles" + >here</a><external-link-icon :class="linkIconClasses"/>, + accessed 24/04/2022. + </li> + <li> + The short descriptions, along with the remaining images and name data, + were obtained from Wikipedia. Descriptions were extracted from the + <a href="https://dumps.wikimedia.org/enwiki/" :style="anchorStyles">Wikipedia dump</a> + <external-link-icon :class="linkIconClasses"/> for 01/05/22, + and also obtained from the + <a href="https://databus.dbpedia.org/dbpedia/collections/latest-core" + :style="anchorStyles">DBpedia knowledge base</a> + <external-link-icon :class="linkIconClasses"/> + for 01/03/22. Images were downloaded from Wikipedia during Jun 2022. + </li> + </ul> + <br/> + <h1 class="text-lg font-bold">Data Inconsistencies</h1> + <p> + When handling datasets this large, these are almost unavoidable. Significant effort + was expended to minimise them, but, inevitably, there are always more. The most prominent + types are listed below. If you find a major error, feel free to let me know at + <a href="mailto:terry06890@gmail.com" :style="anchorStyles">terry06890@gmail.com</a>. + </p> + <ul class="list-disc pl-4"> + <li> + <h2 class="font-bold">Errors in Node Linkage</h2> + <p> + The datasets don't share the same set of node identifiers. So, in order to + link nodes from one dataset with another, their plain names were used. + This doesn't work when names are ambiguous. For example, 'Proboscidea' + might denote a taxon for elephants, but also plants. Most of these were + manually corrected, but there are almost certainly more. + </p> + </li> + <li> + <h2 class="font-bold">Errors Within the Datasets</h2> + <p> + Some issues are internal to the datasets themselves. For example, an image from + EOL might display a plant that is in the wrong taxon. As most of the datasets are + large projects distributed over many people over a long period of time, these + errors are difficult to avoid, and may require specialised knowledge to resolve. + </p> + </li> + <li> + <h2 class="font-bold">Errors in Descriptions</h2> + <p> + The short descriptions were extracted using imprecise heuristics. + There are many cases of leftover wikitext markup, or cut-off sentences. + </p> + </li> + </ul> + <br/> + <h1 class="text-lg font-bold">Some Possible Points of Confusion</h1> + <ul class="list-disc pl-4"> + <li> + <h2 class="font-bold">Unexpected Images</h2> + <p> + Not all the images are well-suited for display. For example, many + birds have their heads cropped out. And some fish are shown in a + preserved form that is hard to recognise. And some moths are shown + alongside a more prominent plant, and are hard to see. + </p> + </li> + <li> + <h2 class="font-bold">Unexpected Search Results</h2> + <ul class="list-[circle] pl-4"> + <li> + In the Complex tree, searching for 'orange', then pressing enter, brings up + a kind of butterfly, instead of a citrus plant. This is because suggestions + are not yet ordered by how well known the taxon is. + </li> + <li> + In some cases, a search might unexpectedly have no results. For example, + searching for 'golden retriever' brings up nothing. This is because + breeds of domestic dog are not considered separate species, but as + variant descendants of Canis familiaris. + </li> + </ul> + </li> + </ul> + </div> + </template> + </s-collapsible> + <s-collapsible :class="scClasses"> + <template #summary="slotProps"> + <div :class="scSummaryClasses"> + <down-icon :class="slotProps.collapsed ? downIconClasses : downIconExpandedClasses"/> + Other Credits + </div> + </template> + <template #content> + <div :class="contentClasses"> + <ul class="list-disc pl-4"> + <li> + The UI was built using the + <a href="https://vuejs.org/" :style="anchorStyles">Vue framework</a> + <external-link-icon :class="linkIconClasses"/> + </li> + <li> + Styling was enhanced using + <a href="https://tailwindcss.com/" :style="anchorStyles">Tailwind</a> + <external-link-icon :class="linkIconClasses"/> + </li> + <li> + The font is called + <a href="https://design.ubuntu.com/font/" :style="anchorStyles">Ubuntu Font</a> + <external-link-icon :class="linkIconClasses"/> + </li> + <li>Icons were obtained from + <a href="https://feathericons.com/" :style="anchorStyles">Feathericons</a> + <external-link-icon :class="linkIconClasses"/> + and <a href="https://ionic.io/ionicons" :style="anchorStyles">Ionicons</a> + <external-link-icon :class="linkIconClasses"/> + </li> + <li> + Images were cropped using + <a href="https://github.com/jwagner/smartcrop.js" :style="anchorStyles">Smartcrop</a> + <external-link-icon :class="linkIconClasses"/> + </li> + </ul> </div> </template> </s-collapsible> - <ul class="list-disc ml-3"> - <li>What is the Tree of Life? ('tips', )</li> - <li>Visualising the Tree (OneZoom, iTol) (tile layout, )</li> - <li>Using Tilo - (tutorial) - (leaf header colors, asterisk, compound nodes/names/images, overflown-root, ) - (settings: layout methods, reduced trees, click-label-to-reset) - (keyboard shortcuts) - </li> - <li>Data sources (OTOL, EOL, Wikipedia) (imprecision: tree, names, images, descs, )</li> - <li>Project page, error contact, other credits (feathericons, ionicons), </li> - </ul> </div> - <s-button :disabled="tutOpen" class="mx-auto my-2" + <s-button v-if="!tutOpen" class="mx-auto mb-2" :style="{color: uiOpts.textColor, backgroundColor: uiOpts.bgColor}" @click.stop="onStartTutorial"> Start Tutorial </s-button> @@ -52,6 +375,7 @@ import SButton from './SButton.vue'; import SCollapsible from './SCollapsible.vue'; import CloseIcon from './icon/CloseIcon.vue'; import DownIcon from './icon/DownIcon.vue'; +import ExternalLinkIcon from './icon/ExternalLinkIcon.vue'; import {UiOptions} from '../lib'; export default defineComponent({ @@ -67,6 +391,32 @@ export default defineComponent({ boxShadow: this.uiOpts.shadowNormal, }; }, + scClasses(): string { + return 'border border-stone-400 rounded'; + }, + scSummaryClasses(): string { + return "relative text-center p-1 bg-stone-300 hover:brightness-90 hover:bg-lime-200 md:p-2"; + }, + downIconClasses(): string { + return 'block absolute w-6 h-6 my-auto mx-1 transition-transform duration-300'; + }, + downIconExpandedClasses(): string { + return this.downIconClasses + ' -rotate-90'; + }, + contentClasses(): string { + return 'p-2 text-sm md:text-base'; + }, + anchorStyles(): Record<string,string> { + return { + color: this.uiOpts.altColorDark, + }; + }, + linkIconClasses(): string { + return 'inline-block w-3 h-3 ml-1'; + }, + touchDevice(): boolean { + return this.uiOpts.touchDevice; + }, }, methods: { onClose(evt: Event){ @@ -79,7 +429,7 @@ export default defineComponent({ this.$emit('close'); }, }, - components: {SButton, SCollapsible, CloseIcon, DownIcon, }, + components: {SButton, SCollapsible, CloseIcon, DownIcon, ExternalLinkIcon, }, emits: ['close', 'start-tutorial', ], }); </script> diff --git a/src/components/SettingsModal.vue b/src/components/SettingsModal.vue index 73b204d..c946095 100644 --- a/src/components/SettingsModal.vue +++ b/src/components/SettingsModal.vue @@ -4,8 +4,8 @@ min-w-[8cm] max-w-[80%] max-h-[80%] overflow-auto" :style="styles"> <close-icon @click.stop="onClose" ref="closeIcon" class="block absolute top-1 right-1 md:top-2 md:right-2 w-8 h-8 hover:cursor-pointer" /> - <h1 class="text-xl md:text-2xl font-bold text-center py-2 border-b border-stone-400">Settings</h1> - <div class="border-b border-stone-400 pb-2"> + <h1 class="text-xl md:text-2xl font-bold text-center py-2" :class="borderBClasses">Settings</h1> + <div class="pb-2" :class="borderBClasses"> <h2 class="font-bold md:text-xl text-center pt-1 md:pt-2 md:pb-1">Timing</h2> <div class="grid grid-cols-[130px_minmax(0,1fr)_65px] gap-1 px-2 md:px-3"> <!-- Row 1 --> @@ -24,7 +24,7 @@ <div class="my-auto text-right">{{uiOpts.autoActionDelay}} ms</div> </div> </div> - <div class="border-b border-stone-400 pb-2"> + <div class="pb-2" :class="borderBClasses"> <h2 class="font-bold md:text-xl text-center pt-1 md:pt-2 md:pb-1">Layout</h2> <div class="flex gap-2 justify-around px-2 pb-1"> <div> @@ -76,7 +76,7 @@ <div class="my-auto text-right">{{pxToDisplayStr(lytOpts.tileSpacing)}}</div> </div> </div> - <div class="border-b border-stone-400 pb-2 px-2 md:px-3"> + <div class="pb-2 px-2 md:px-3" :class="borderBClasses"> <h2 class="font-bold md:text-xl text-center pt-1 md:pt-2 -mb-2 ">Other</h2> <div> Tree to use @@ -139,6 +139,9 @@ export default defineComponent({ boxShadow: this.uiOpts.shadowNormal, }; }, + borderBClasses(): string { + return 'border-b border-stone-400'; + }, rLabelClasses(): string { // For reset-upon-click labels return "w-fit hover:cursor-pointer hover:text-lime-600"; }, diff --git a/src/components/TileInfoModal.vue b/src/components/TileInfoModal.vue index e1b31db..29901ee 100644 --- a/src/components/TileInfoModal.vue +++ b/src/components/TileInfoModal.vue @@ -4,13 +4,11 @@ max-w-[80%] min-w-[8cm] md:min-w-[14cm] max-h-[80%]" :style="styles"> <div class="pb-1 md:pb-2"> - <div class="flex"> - <h1 class="text-center text-xl font-bold grow pt-2 pb-1 md:text-2xl md:pt-3 md:pb-1"> - {{getDisplayName(nodeName, tolNode)}} - </h1> - <close-icon @click.stop="onClose" ref="closeIcon" - class="block m-1 md:m-2 w-8 h-8 hover:cursor-pointer"/> - </div> + <close-icon @click.stop="onClose" ref="closeIcon" + class="block absolute top-1 right-1 md:m-2 w-8 h-8 hover:cursor-pointer"/> + <h1 class="text-center text-xl font-bold pt-2 pb-1 mx-10 md:text-2xl md:pt-3 md:pb-1"> + {{getDisplayName(nodeName, tolNode)}} + </h1> <div class="flex justify-evenly text-sm md:text-base"> <div> Children: {{tolNode.children.length}} </div> <div> Tips: {{tolNode.tips}} </div> @@ -85,10 +83,10 @@ <div>{{descInfos[idx]!.text}}</div> <div class="text-sm text-right"> From - <a :href="'https://en.wikipedia.org/?curid=' + descInfos[idx]!.wikiId" target="_blank"> - Wikipedia - </a> - <external-link-icon class="inline-block w-3 h-3"/> + <a :href="'https://en.wikipedia.org/?curid=' + descInfos[idx]!.wikiId" + target="_blank">Wikipedia</a> + <external-link-icon class="inline-block w-3 h-3 ml-1"/> + {{descInfos[idx]!.fromDbp ? '(via DBpedia)' : ''}} </div> </div> <div v-else class="text-center"> @@ -117,7 +117,7 @@ export type UiOptions = { export function getDefaultLytOpts(): LayoutOptions { let screenSz = getBreakpoint(); return { - tileSpacing: screenSz == 'sm' ? 6 : 10, //px + tileSpacing: screenSz == 'sm' ? 6 : 9, //px headerSz: screenSz == 'sm' ? 18 : 22, // px minTileSz: 50, // px maxTileSz: 200, // px |
