mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-08 03:20:12 +08:00
Merge pull request #13 from lancatlin/app-neil
Add tree chart and drag to scroll function in visualisation section
This commit is contained in:
6 files changed
+292
-52
No files matched your search
+5
-5
@@ -26,13 +26,13 @@ onMounted(async () => {
|
|||||||
<template>
|
<template>
|
||||||
<div class="bg-background-primary h-screen">
|
<div class="bg-background-primary h-screen">
|
||||||
<!--header-->
|
<!--header-->
|
||||||
<div id="header" class="bg-background-secondary content-center h-[6%] p-1">
|
<div id="header" class="bg-background-secondary content-center h-[6vh] p-1">
|
||||||
<HeaderPart />
|
<HeaderPart />
|
||||||
</div>
|
</div>
|
||||||
<!--main-->
|
<!--main-->
|
||||||
<div id="main" class="h-[94%] grid grid-cols-3 gap-3 p-3">
|
<div id="main" class="h-[94vh] grid grid-cols-3 gap-3 p-3">
|
||||||
<!--Topic and Command List-->
|
<!--Topic and Command List-->
|
||||||
<div class="bg-background-secondary inline-block h-full rounded-lg">
|
<div class="bg-background-secondary h-full rounded-lg">
|
||||||
<section id="quest" class="h-2/3 m-3">
|
<section id="quest" class="h-2/3 m-3">
|
||||||
<QuestPart />
|
<QuestPart />
|
||||||
</section>
|
</section>
|
||||||
@@ -42,7 +42,7 @@ onMounted(async () => {
|
|||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<!--Terminal and Hint-->
|
<!--Terminal and Hint-->
|
||||||
<div class="bg-background inline-block h-full py-2 rounded-lg">
|
<div class="bg-background h-full rounded-lg">
|
||||||
<section id="terminal" class="h-3/5">
|
<section id="terminal" class="h-3/5">
|
||||||
<TerminalPart />
|
<TerminalPart />
|
||||||
</section>
|
</section>
|
||||||
@@ -51,7 +51,7 @@ onMounted(async () => {
|
|||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<!--Visualization-->
|
<!--Visualization-->
|
||||||
<div class="bg-background-primary inline-block h-full">
|
<div class="h-full">
|
||||||
<div class="bg-border rounded-xl h-[90%] px-3 py-6">
|
<div class="bg-border rounded-xl h-[90%] px-3 py-6">
|
||||||
<div class="bg-background rounded-xl h-full px-1 py-6">
|
<div class="bg-background rounded-xl h-full px-1 py-6">
|
||||||
<section id="visualization" class="bg-background-primary h-full">
|
<section id="visualization" class="bg-background-primary h-full">
|
||||||
|
|||||||
@@ -1,38 +1,51 @@
|
|||||||
<script setup></script>
|
<script setup></script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="inline-block">
|
<div class="h-full flex items-center justify-center mx-3">
|
||||||
<button id="stream" class="p-1">
|
<div class="flex items-center gap-3">
|
||||||
<font-awesome-icon
|
<button id="stream" class="flex items-center">
|
||||||
:icon="['fas', 'bars-staggered']"
|
<font-awesome-icon
|
||||||
class="text-text-primary"
|
:icon="['fas', 'bars']"
|
||||||
/>
|
class="text-text-primary h-5 w-5"
|
||||||
</button>
|
/>
|
||||||
<button id="backward" class="p-1">
|
</button>
|
||||||
<font-awesome-icon :icon="['fas', 'arrow-left']" class="text-border" />
|
<button id="backward" class="flex items-center">
|
||||||
</button>
|
<font-awesome-icon
|
||||||
<button>
|
:icon="['fas', 'arrow-left']"
|
||||||
<p class="text-text-primary inline font-bold p-1">1. Command's Basics</p>
|
class="text-text-line h-5 w-5"
|
||||||
</button>
|
/>
|
||||||
<p class="text-text-primary inline font-bold p-1">‧</p>
|
</button>
|
||||||
<button>
|
<button>
|
||||||
<p class="text-text-primary inline font-bold p-1">
|
<p class="text-text-primary inline-block font-bold whitespace-nowrap">
|
||||||
1. Try Your First Command
|
1. Command's Basics
|
||||||
</p>
|
</p>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
<p class="text-text-primary inline-block font-bold">●</p>
|
||||||
<div class="float-right inline-block">
|
<button>
|
||||||
<button id="warning" class="p-1">
|
<p class="text-text-primary inline-block font-bold whitespace-nowrap">
|
||||||
<font-awesome-icon
|
1. Try Your First Command
|
||||||
:icon="['fas', 'triangle-exclamation']"
|
</p>
|
||||||
class="text-text-primary"
|
</button>
|
||||||
/>
|
</div>
|
||||||
</button>
|
<div class="h-full w-full flex gap-3 items-center justify-end">
|
||||||
<button id="setting" class="p-1">
|
<button id="warning" class="flex items-center">
|
||||||
<font-awesome-icon :icon="['fas', 'gear']" class="text-text-primary" />
|
<font-awesome-icon
|
||||||
</button>
|
:icon="['fas', 'triangle-exclamation']"
|
||||||
<button id="fullscreen" class="p-1">
|
class="text-text-primary h-5 w-5"
|
||||||
<font-awesome-icon :icon="['fas', 'expand']" class="text-text-primary" />
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
<button id="setting" class="flex items-center">
|
||||||
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'gear']"
|
||||||
|
class="text-text-primary h-5 w-5"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button id="fullscreen" class="flex items-center">
|
||||||
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'expand']"
|
||||||
|
class="text-text-primary h-5 w-5"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -9,7 +9,7 @@ api
|
|||||||
.get('/quests/helloworld')
|
.get('/quests/helloworld')
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log(res.data)
|
console.log(res.data)
|
||||||
questData.value = JSON.stringify(res.data.content)
|
questData.value = res.data
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
questErr.value = err
|
questErr.value = err
|
||||||
@@ -17,14 +17,18 @@ api
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<h1 id="topic" class="text-text">Try Your First Command</h1>
|
<div class="overflow-auto h-full w-full max-h-full">
|
||||||
<hr class="border-text-line border-2 my-2" />
|
<h1 id="topic" class="text-red-500" v-if="questErr">
|
||||||
<div>
|
Failed to get quest infomation
|
||||||
<p class="text-red-500" v-if="questErr">{{ questErr.message }}</p>
|
</h1>
|
||||||
<p class="text-text" v-else-if="questData">--Quest Information--</p>
|
<h1 id="topic" class="text-text" v-else-if="questData">
|
||||||
<!--
|
{{ questData.title }}
|
||||||
<p class="text-text" v-else-if="quest" v-html="questData"></p>
|
</h1>
|
||||||
-->
|
<hr class="border-text-line border-2 my-2" />
|
||||||
<p class="text-text" v-else>Loading...</p>
|
<div>
|
||||||
|
<p class="text-red-500" v-if="questErr">{{ questErr.message }}</p>
|
||||||
|
<p class="text-text" v-else-if="questData">{{ questData.instruction }}</p>
|
||||||
|
<p class="text-text" v-else>Loading...</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
<script setup></script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="tree w-max h-max">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="#">Parent</a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="#">Child</a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="#">Grand Child</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">Child</a>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#">Grand Child</a></li>
|
||||||
|
<li>
|
||||||
|
<a href="#">Grand Child</a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="#">Great Grand Child</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">Great Grand Child</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">Great Grand Child</a>
|
||||||
|
<ul>
|
||||||
|
<li><a>Grand Child</a></li>
|
||||||
|
<li>
|
||||||
|
<a>Grand Child</a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a>Great Grand Child</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a>Great Grand Child</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><a>Grand Child</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><a href="#">Grand Child</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.tree ul {
|
||||||
|
padding-top: 20px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
transition: all 0.5s;
|
||||||
|
-webkit-transition: all 0.5s;
|
||||||
|
-moz-transition: all 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree li {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
list-style-type: none;
|
||||||
|
position: relative;
|
||||||
|
padding: 20px 5px 0 5px;
|
||||||
|
vertical-align: top;
|
||||||
|
|
||||||
|
transition: all 0.5s;
|
||||||
|
-webkit-transition: all 0.5s;
|
||||||
|
-moz-transition: all 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree li::before,
|
||||||
|
.tree li::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 50%;
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
width: 50%;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
.tree li::after {
|
||||||
|
right: auto;
|
||||||
|
left: 50%;
|
||||||
|
border-left: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree li:only-child::after,
|
||||||
|
.tree li:only-child::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree li:only-child {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree li:first-child::before,
|
||||||
|
.tree li:last-child::after {
|
||||||
|
border: 0 none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree li:last-child::before {
|
||||||
|
border-right: 1px solid #ccc;
|
||||||
|
border-radius: 0 5px 0 0;
|
||||||
|
-webkit-border-radius: 0 5px 0 0;
|
||||||
|
-moz-border-radius: 0 5px 0 0;
|
||||||
|
}
|
||||||
|
.tree li:first-child::after {
|
||||||
|
border-radius: 5px 0 0 0;
|
||||||
|
-webkit-border-radius: 5px 0 0 0;
|
||||||
|
-moz-border-radius: 5px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree ul ul::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 50%;
|
||||||
|
border-left: 1px solid #ccc;
|
||||||
|
width: 0;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree li a {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 5px 10px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #666;
|
||||||
|
font-family: arial, verdana, tahoma;
|
||||||
|
font-size: 11px;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
border-radius: 5px;
|
||||||
|
-webkit-border-radius: 5px;
|
||||||
|
-moz-border-radius: 5px;
|
||||||
|
|
||||||
|
transition: all 0.5s;
|
||||||
|
-webkit-transition: all 0.5s;
|
||||||
|
-moz-transition: all 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree li a:hover,
|
||||||
|
.tree li a:hover + ul li a {
|
||||||
|
background: #c8e4f8;
|
||||||
|
color: #000;
|
||||||
|
border: 1px solid #94a0b4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree li a:hover + ul li::after,
|
||||||
|
.tree li a:hover + ul li::before,
|
||||||
|
.tree li a:hover + ul::before,
|
||||||
|
.tree li a:hover + ul ul::before {
|
||||||
|
border-color: #94a0b4;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,5 +1,63 @@
|
|||||||
<script setup></script>
|
<script setup>
|
||||||
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
|
import TreeChart from './TreeChart.vue'
|
||||||
|
|
||||||
|
const treeRef = ref(null)
|
||||||
|
let pos = { top: 0, left: 0, x: 0, y: 0 }
|
||||||
|
|
||||||
|
function mouseMoveHandler(e) {
|
||||||
|
const dx = e.clientX - pos.x
|
||||||
|
const dy = e.clientY - pos.y
|
||||||
|
|
||||||
|
treeRef.value.scrollTop = pos.top - dy
|
||||||
|
treeRef.value.scrollLeft = pos.left - dx
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseUpHandler() {
|
||||||
|
treeRef.value.style.cursor = 'grab'
|
||||||
|
treeRef.value.style.removeProperty('user-select')
|
||||||
|
|
||||||
|
document.removeEventListener('mousemove', mouseMoveHandler)
|
||||||
|
document.removeEventListener('mouseup', mouseUpHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseDownHandler(e) {
|
||||||
|
treeRef.value.style.cursor = 'grabbing'
|
||||||
|
treeRef.value.style.userSelect = 'none'
|
||||||
|
|
||||||
|
pos = {
|
||||||
|
left: treeRef.value.scrollLeft,
|
||||||
|
top: treeRef.value.scrollTop,
|
||||||
|
x: e.clientX,
|
||||||
|
y: e.clientY,
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', mouseMoveHandler)
|
||||||
|
document.addEventListener('mouseup', mouseUpHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
treeRef.value.style.cursor = 'grab'
|
||||||
|
treeRef.value.addEventListener('mousedown', mouseDownHandler)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
treeRef.value.removeEventListener('mousedown', mouseDownHandler)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<p class="text-text">--Visualization--</p>
|
<div
|
||||||
|
id="tree"
|
||||||
|
ref="treeRef"
|
||||||
|
class="h-full w-full overflow-auto cursor-grabbing"
|
||||||
|
>
|
||||||
|
<TreeChart />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+2
-2
@@ -9,7 +9,7 @@ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
|||||||
|
|
||||||
/* import specific icons */
|
/* import specific icons */
|
||||||
import {
|
import {
|
||||||
faBarsStaggered,
|
faBars,
|
||||||
faArrowLeft,
|
faArrowLeft,
|
||||||
faList,
|
faList,
|
||||||
faGear,
|
faGear,
|
||||||
@@ -28,7 +28,7 @@ import App from './App.vue'
|
|||||||
|
|
||||||
/* add icons to the library */
|
/* add icons to the library */
|
||||||
library.add(
|
library.add(
|
||||||
faBarsStaggered,
|
faBars,
|
||||||
faArrowLeft,
|
faArrowLeft,
|
||||||
faTriangleExclamation,
|
faTriangleExclamation,
|
||||||
faGear,
|
faGear,
|
||||||
|
|||||||
Reference in new issue
Block a user