mirror of
https://github.com/robonen/eulerian-cycle.git
synced 2026-03-20 02:44:47 +00:00
Added pop-ups, guide, fixed selection when dragging and duplicating links
This commit is contained in:
@@ -4,4 +4,6 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
@import url("~@/assets/css/formular.css");
|
@import url("~@/assets/css/formular.css");
|
||||||
|
@import "~@/assets/css/creation.css";
|
||||||
|
@import "~@/assets/css/graph.css";
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -223,4 +223,4 @@ html {
|
|||||||
.disabled-button {
|
.disabled-button {
|
||||||
opacity: 0.2;
|
opacity: 0.2;
|
||||||
cursor: auto;
|
cursor: auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
background-color: var(--body-color);
|
background-color: var(--body-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
body>#app {
|
body > #app {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: "Formular";
|
font-family: "Formular";
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -308,7 +308,7 @@ header {
|
|||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
transition: .2s;
|
transition: 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-icon:last-child {
|
.menu-icon:last-child {
|
||||||
@@ -394,7 +394,8 @@ p {
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-prompt, .prompt {
|
.menu-prompt,
|
||||||
|
.prompt {
|
||||||
left: 100%;
|
left: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 6;
|
z-index: 6;
|
||||||
@@ -410,7 +411,7 @@ p {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
box-shadow: 0px 1px 5px 1px 0px 1px 5px 1px rgb(56 58 63 / 35%);
|
box-shadow: 0px 1px 5px 1px 0px 1px 5px 1px rgb(56 58 63 / 35%);
|
||||||
transition: .2s;
|
transition: 0.2s;
|
||||||
display: block;
|
display: block;
|
||||||
width: -webkit-max-content;
|
width: -webkit-max-content;
|
||||||
width: -moz-max-content;
|
width: -moz-max-content;
|
||||||
@@ -457,10 +458,11 @@ p {
|
|||||||
transform: translate(-50%, 0);
|
transform: translate(-50%, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-icon:hover .menu-prompt, .control-button:hover .prompt {
|
.menu-icon:hover .menu-prompt,
|
||||||
|
.control-button:hover .prompt {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
transition-delay: .5s;
|
transition-delay: 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
@@ -474,6 +476,7 @@ p {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
box-shadow: 0px 1px 5px 1px rgb(56 58 63 / 15%);
|
box-shadow: 0px 1px 5px 1px rgb(56 58 63 / 15%);
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-el.popup-button-cont {
|
.popup-el.popup-button-cont {
|
||||||
@@ -504,4 +507,23 @@ p {
|
|||||||
z-index: 0;
|
z-index: 0;
|
||||||
color: gray;
|
color: gray;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fade-enter-active {
|
||||||
|
animation: fade-in 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-leave-active {
|
||||||
|
animation: fade-in 0.5s reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in {
|
||||||
|
from {
|
||||||
|
transform: translateY(-40px);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
ref="renderer"
|
ref="renderer"
|
||||||
@dblclick="createNode"
|
@dblclick="createNode"
|
||||||
@click.left.stop="unselectAllNodes"
|
@click.left.stop="unselectAllNodes"
|
||||||
|
@contextmenu.prevent
|
||||||
>
|
>
|
||||||
<g>
|
<g>
|
||||||
<component
|
<component
|
||||||
@@ -66,6 +67,9 @@ export default {
|
|||||||
// Const
|
// Const
|
||||||
const RADIUS = 25;
|
const RADIUS = 25;
|
||||||
|
|
||||||
|
// Vars
|
||||||
|
let draggableNode = false;
|
||||||
|
|
||||||
// Reactive
|
// Reactive
|
||||||
const renderer = ref(null);
|
const renderer = ref(null);
|
||||||
|
|
||||||
@@ -104,6 +108,7 @@ export default {
|
|||||||
// }
|
// }
|
||||||
// );
|
// );
|
||||||
|
|
||||||
|
// Methods
|
||||||
const loopPosition = (coords) => {
|
const loopPosition = (coords) => {
|
||||||
const node = nodes.value[coords];
|
const node = nodes.value[coords];
|
||||||
|
|
||||||
@@ -117,7 +122,6 @@ export default {
|
|||||||
},${y}`;
|
},${y}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Methods
|
|
||||||
const hasntIntersections = (node) => {
|
const hasntIntersections = (node) => {
|
||||||
return nodes.value.every((current) => {
|
return nodes.value.every((current) => {
|
||||||
return (
|
return (
|
||||||
@@ -127,13 +131,13 @@ export default {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Nodes
|
||||||
const activateNodes = (ids) =>
|
const activateNodes = (ids) =>
|
||||||
ids.forEach((e) => (nodes.value[e].selected = true));
|
ids.forEach((e) => (nodes.value[e].selected = true));
|
||||||
|
|
||||||
const deactivateNodes = (ids) =>
|
const deactivateNodes = (ids) =>
|
||||||
ids.forEach((e) => (nodes.value[e].selected = false));
|
ids.forEach((e) => (nodes.value[e].selected = false));
|
||||||
|
|
||||||
// Nodes
|
|
||||||
const createNode = ({ offsetX, offsetY }) => {
|
const createNode = ({ offsetX, offsetY }) => {
|
||||||
if (nodes.value.length >= 99) return;
|
if (nodes.value.length >= 99) return;
|
||||||
|
|
||||||
@@ -167,6 +171,11 @@ export default {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const selectNode = (id) => {
|
const selectNode = (id) => {
|
||||||
|
if (draggableNode) {
|
||||||
|
draggableNode = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (linker.sourceEmpty()) {
|
if (linker.sourceEmpty()) {
|
||||||
linker.setSource(id);
|
linker.setSource(id);
|
||||||
activateNodes([id]);
|
activateNodes([id]);
|
||||||
@@ -207,19 +216,36 @@ export default {
|
|||||||
const nodeMove = ({ offsetX, offsetY }) => {
|
const nodeMove = ({ offsetX, offsetY }) => {
|
||||||
const d = drag.value;
|
const d = drag.value;
|
||||||
|
|
||||||
|
draggableNode = true;
|
||||||
|
|
||||||
nodes.value[d.id].x = offsetX - d.offsetX;
|
nodes.value[d.id].x = offsetX - d.offsetX;
|
||||||
nodes.value[d.id].y = offsetY - d.offsetY;
|
nodes.value[d.id].y = offsetY - d.offsetY;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Links
|
// Links
|
||||||
linker.onLink((source, target) => {
|
linker.onLink((source, target) => {
|
||||||
|
let duplicateLink = null;
|
||||||
|
|
||||||
|
links.value.forEach((e, idx) => {
|
||||||
|
if (
|
||||||
|
(e.source === source && e.target === target) ||
|
||||||
|
(e.source === target && e.target === source)
|
||||||
|
)
|
||||||
|
duplicateLink = idx;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (duplicateLink !== null) {
|
||||||
|
links.value.splice(duplicateLink, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
links.value.push({
|
links.value.push({
|
||||||
selected: false,
|
selected: false,
|
||||||
source,
|
source,
|
||||||
target,
|
target,
|
||||||
});
|
});
|
||||||
|
|
||||||
euler.loadLinks([...links.value]);
|
euler.loadLinks(Object.values(links.value));
|
||||||
|
|
||||||
if (euler.check()) emit("isEuler", euler.find());
|
if (euler.check()) emit("isEuler", euler.find());
|
||||||
else emit("isEuler", []);
|
else emit("isEuler", []);
|
||||||
@@ -254,7 +280,8 @@ svg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
circle,
|
circle,
|
||||||
line {
|
line,
|
||||||
|
path {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
67
src/components/Guide.vue
Normal file
67
src/components/Guide.vue
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<popup
|
||||||
|
leftBtnText="Назад"
|
||||||
|
:rightBtnText="currentStep + 1 === steps.length ? 'Завершить' : 'Далее'"
|
||||||
|
@left="stepDown"
|
||||||
|
@right="stepUp"
|
||||||
|
@close="close"
|
||||||
|
>
|
||||||
|
<template v-slot:title>
|
||||||
|
{{ steps[currentStep].name }}
|
||||||
|
<span class="version">{{ currentStep + 1 }} / {{ steps.length }}</span>
|
||||||
|
</template>
|
||||||
|
<template v-slot:content>
|
||||||
|
{{ steps[currentStep].content }}
|
||||||
|
</template>
|
||||||
|
</popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from "vue";
|
||||||
|
import Popup from "./Popup";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Guide",
|
||||||
|
components: {
|
||||||
|
Popup,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
steps: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
// Reactive
|
||||||
|
const currentStep = ref(0);
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
const stepDown = () => {
|
||||||
|
if (currentStep.value <= 0) return;
|
||||||
|
|
||||||
|
currentStep.value -= 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const stepUp = () => {
|
||||||
|
if (currentStep.value + 1 >= props.steps.length) {
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentStep.value += 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
currentStep.value = 0;
|
||||||
|
emit("close");
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
currentStep,
|
||||||
|
stepDown,
|
||||||
|
stepUp,
|
||||||
|
close,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -1,24 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="matrix-cont">
|
<div class="adjacency_matrix-cont">
|
||||||
<div class="value-rows-matrix-cont">
|
<div class="adjacency_matrix">
|
||||||
<div class="value-row-matrix" v-for="ni in size" :key="ni">
|
<div class="adjacency_matrix-menu">
|
||||||
{{ ni }}
|
<div class="header header-matrix">Матрица смежности</div>
|
||||||
|
<div class="menu-icon close-icon"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="matrix-cont">
|
||||||
<div class="body-matrix">
|
<div class="value-rows-matrix-cont">
|
||||||
<div class="matrix">
|
<div class="value-row-matrix">0</div>
|
||||||
<div class="matrix-column" v-for="nj in size" :key="nj">
|
<div class="value-row-matrix">1</div>
|
||||||
<div class="value-matrix-column">{{ nj }}</div>
|
<div class="value-row-matrix">2</div>
|
||||||
<div
|
</div>
|
||||||
class="matrix-cell"
|
<div class="body-matrix">
|
||||||
v-for="ni in size"
|
<div class="matrix">
|
||||||
:key="ni"
|
<div class="matrix-column">
|
||||||
:class="{
|
<div class="value-matrix-column">0</div>
|
||||||
'active-cell': isActive(ni - 1, nj - 1),
|
<div class="auto-matrix-cell"></div>
|
||||||
'auto-matrix-cell': isAbove(ni - 1, nj - 1),
|
<div class="auto-matrix-cell"></div>
|
||||||
}"
|
<div class="auto-matrix-cell"></div>
|
||||||
@click="change(ni - 1, nj - 1)"
|
</div>
|
||||||
></div>
|
<div class="matrix-column">
|
||||||
|
<div class="value-matrix-column">1</div>
|
||||||
|
<div class="auto-matrix-cell"></div>
|
||||||
|
<div class="auto-matrix-cell"></div>
|
||||||
|
<div class="auto-matrix-cell"></div>
|
||||||
|
</div>
|
||||||
|
<div class="matrix-column">
|
||||||
|
<div class="value-matrix-column">2</div>
|
||||||
|
<div class="auto-matrix-cell"></div>
|
||||||
|
<div class="auto-matrix-cell"></div>
|
||||||
|
<div class="auto-matrix-cell"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -26,67 +39,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// active-cell - one with background
|
|
||||||
// matrix-cell - default
|
|
||||||
// auto-matrix-cell - without background
|
|
||||||
// active-auto-cell - one
|
|
||||||
|
|
||||||
const newArray = (size) =>
|
|
||||||
Array(size)
|
|
||||||
.fill(0)
|
|
||||||
.map(() => Array(size).fill(0));
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Matrix",
|
name: "Matrix",
|
||||||
props: {
|
|
||||||
size: {
|
|
||||||
type: Number,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
matrix: newArray(this.size),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
size(val) {
|
|
||||||
this.matrix = newArray(val);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
isActive(i, j) {
|
|
||||||
return this.matrix[i][j] === 1;
|
|
||||||
},
|
|
||||||
isAbove(i, j) {
|
|
||||||
return i > j;
|
|
||||||
},
|
|
||||||
change(i, j) {
|
|
||||||
const val = this.matrix[i][j] === 1 ? 0 : 1;
|
|
||||||
|
|
||||||
this.matrix[i][j] = val;
|
|
||||||
|
|
||||||
if (i != j) this.matrix[j][i] = val;
|
|
||||||
|
|
||||||
this.checkEuler();
|
|
||||||
},
|
|
||||||
checkEuler() {
|
|
||||||
const isValid = this.matrix.reduce(
|
|
||||||
(res, current) => {
|
|
||||||
const relations = current.reduce((sum, i) => sum + i);
|
|
||||||
|
|
||||||
res.sum += relations;
|
|
||||||
res.even &= !(relations % 2);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
{ sum: 0, even: 1 }
|
|
||||||
);
|
|
||||||
|
|
||||||
const result = isValid.sum && isValid.even;
|
|
||||||
|
|
||||||
this.$emit("valid", result);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
58
src/components/Popup.vue
Normal file
58
src/components/Popup.vue
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<div class="popup-cont">
|
||||||
|
<div class="popup">
|
||||||
|
<div class="popup-el popup-header">
|
||||||
|
<div class="header">
|
||||||
|
<slot name="title"></slot>
|
||||||
|
</div>
|
||||||
|
<div class="menu-icon close-icon" @click="closeBtn"></div>
|
||||||
|
</div>
|
||||||
|
<div class="popup-el popup-text">
|
||||||
|
<slot name="content"></slot>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="popup-el popup-text gray">by Robonen</div> -->
|
||||||
|
<div class="popup-el popup-button-cont">
|
||||||
|
<div v-if="leftBtnText" class="popup-button" @click="leftBtn">
|
||||||
|
{{ leftBtnText }}
|
||||||
|
</div>
|
||||||
|
<div v-if="rightBtnText" class="main-popup-button" @click="rightBtn">
|
||||||
|
{{ rightBtnText }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "View",
|
||||||
|
props: {
|
||||||
|
leftBtnText: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
rightBtnText: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(_, { emit }) {
|
||||||
|
// Methods
|
||||||
|
const closeBtn = () => {
|
||||||
|
emit("close");
|
||||||
|
};
|
||||||
|
|
||||||
|
const leftBtn = () => {
|
||||||
|
emit("left");
|
||||||
|
};
|
||||||
|
|
||||||
|
const rightBtn = () => {
|
||||||
|
emit("right");
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
closeBtn,
|
||||||
|
leftBtn,
|
||||||
|
rightBtn,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -6,15 +6,16 @@ const app = createApp(App).use(router);
|
|||||||
|
|
||||||
app.directive("click-outside", {
|
app.directive("click-outside", {
|
||||||
beforeMount(el, binding) {
|
beforeMount(el, binding) {
|
||||||
el.clickOutsideEvent = function (event) {
|
const ourClickEventHandler = (event) => {
|
||||||
if (!(el === event.target || el.contains(event.target))) {
|
if (!el.contains(event.target) && el !== event.target) {
|
||||||
binding.value(event, el);
|
binding.value(event, el);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
document.body.addEventListener("click", el.clickOutsideEvent);
|
el.__vueClickEventHandler__ = ourClickEventHandler;
|
||||||
|
document.addEventListener("click", ourClickEventHandler);
|
||||||
},
|
},
|
||||||
unmounted(el) {
|
unmounted(el) {
|
||||||
document.body.removeEventListener("click", el.clickOutsideEvent);
|
document.removeEventListener("click", el.__vueClickEventHandler__);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="wrapper">
|
|
||||||
<div class="input-cont">
|
|
||||||
<div class="text-input-cont">размер матрицы:</div>
|
|
||||||
<div class="number">
|
|
||||||
<button class="number-minus" type="button" @click="sub">-</button>
|
|
||||||
<input type="number" v-model="size" />
|
|
||||||
<button class="number-plus" type="button" @click="add">+</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<matrix
|
|
||||||
:size="size"
|
|
||||||
@valid="isValid = $event"
|
|
||||||
@save="matrix = $event"
|
|
||||||
></matrix>
|
|
||||||
<router-link
|
|
||||||
to="/view"
|
|
||||||
class="creation-button"
|
|
||||||
:class="{ 'disabled-button': !isValid }"
|
|
||||||
>
|
|
||||||
СОЗДАТЬ ГРАФ
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Matrix from "../components/Matrix.vue";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Home",
|
|
||||||
components: {
|
|
||||||
Matrix,
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
document.addEventListener("keydown", (evt) => {
|
|
||||||
if (evt.keyCode === 38) this.add();
|
|
||||||
if (evt.keyCode === 40) this.sub();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
size: 5,
|
|
||||||
isValid: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
add() {
|
|
||||||
if (this.size < 30) this.size++;
|
|
||||||
},
|
|
||||||
sub() {
|
|
||||||
if (this.size > 1) this.size--;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
size(val) {
|
|
||||||
this.size = Math.min(Math.max(1, val), 30);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@import "~@/assets/css/creation.css";
|
|
||||||
</style>
|
|
||||||
@@ -1,78 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<!--<div class="adjacency_matrix-cont">
|
<guide v-show="showGuide" :steps="guide" @close="showGuide = false"></guide>
|
||||||
<div class="adjacency_matrix">
|
<popup v-show="showInfo" @close="showInfo = false">
|
||||||
<div class="adjacency_matrix-menu">
|
<template v-slot:title>
|
||||||
<div class="header header-matrix">Матрица смежности</div>
|
Циклы в эйлером графе
|
||||||
<div class="menu-icon close-icon"></div>
|
<span class="version">v0.2</span>
|
||||||
</div>
|
</template>
|
||||||
<div class="matrix-cont">
|
<template v-slot:content>
|
||||||
<div class="value-rows-matrix-cont">
|
<p>
|
||||||
<div class="value-row-matrix">0</div>
|
<b>Эйлеров цикл</b>
|
||||||
<div class="value-row-matrix">1</div>
|
— путь, проходящий по всем ребрам графа, и при этом только по
|
||||||
<div class="value-row-matrix">2</div>
|
одному разу.
|
||||||
</div>
|
</p>
|
||||||
<div class="body-matrix">
|
</template>
|
||||||
<div class="matrix">
|
</popup>
|
||||||
<div class="matrix-column">
|
|
||||||
<div class="value-matrix-column">0</div>
|
|
||||||
<div class="auto-matrix-cell"></div>
|
|
||||||
<div class="auto-matrix-cell"></div>
|
|
||||||
<div class="auto-matrix-cell"></div>
|
|
||||||
</div>
|
|
||||||
<div class="matrix-column">
|
|
||||||
<div class="value-matrix-column">1</div>
|
|
||||||
<div class="auto-matrix-cell"></div>
|
|
||||||
<div class="auto-matrix-cell"></div>
|
|
||||||
<div class="auto-matrix-cell"></div>
|
|
||||||
</div>
|
|
||||||
<div class="matrix-column">
|
|
||||||
<div class="value-matrix-column">2</div>
|
|
||||||
<div class="auto-matrix-cell"></div>
|
|
||||||
<div class="auto-matrix-cell"></div>
|
|
||||||
<div class="auto-matrix-cell"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>-->
|
|
||||||
<!--<div class="popup-cont">
|
|
||||||
<div class="popup">
|
|
||||||
<div class="popup-el popup-header">
|
|
||||||
<div class="header">Эйлеров граф <span class="version">v0.1</span></div>
|
|
||||||
<div class="menu-icon close-icon"></div>
|
|
||||||
</div>
|
|
||||||
<div class="popup-el popup-text">
|
|
||||||
<p>
|
|
||||||
Граф как математический объект есть совокупность двух множеств —
|
|
||||||
множества самих объектов, называемого множеством вершин, и множества
|
|
||||||
их парных связей, называемого множеством рёбер.
|
|
||||||
</p>
|
|
||||||
<p>Элемент множества рёбер есть пара элементов множества вершин.</p>
|
|
||||||
</div>
|
|
||||||
<div class="popup-el popup-text gray">by Robonen</div>
|
|
||||||
<div class="popup-el popup-button-cont">
|
|
||||||
<div class="popup-button">Уволиться</div>
|
|
||||||
<div class="main-popup-button">Поставить 10 баллов</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>-->
|
|
||||||
<div class="addition-cont menu">
|
<div class="addition-cont menu">
|
||||||
<div class="menu-cont">
|
<div class="menu-cont">
|
||||||
<div class="menu-icon matrix-icon">
|
<div class="menu-icon matrix-icon">
|
||||||
<div class="menu-prompt">Матрица смежности</div>
|
<div class="menu-prompt">Матрица смежности</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-icon help-icon">
|
<div class="menu-icon help-icon" @click="showGuide = true">
|
||||||
<div class="menu-prompt">Обучение управлению</div>
|
<div class="menu-prompt">Обучение управлению</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-icon info-icon">
|
<div class="menu-icon info-icon" @click="showInfo = true">
|
||||||
<div class="menu-prompt">О программе</div>
|
<div class="menu-prompt">О программе</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<header>
|
<header>
|
||||||
<!--<div class="error">Эйлерова цикла в этом графе нет</div>-->
|
<transition name="fade">
|
||||||
|
<div v-if="errorText" class="error" @click="errorText = ''">
|
||||||
|
{{ errorText }}
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
<div class="header-step-cont inaccessible">
|
<div class="header-step-cont inaccessible">
|
||||||
<div class="header-step-text">
|
<div class="header-step-text">
|
||||||
<div class="header-vertex">
|
<div class="header-vertex">
|
||||||
@@ -142,23 +102,54 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { computed, ref } from "vue";
|
import { computed, onMounted, ref } from "vue";
|
||||||
import Graph from "../components/Graph.vue";
|
import Graph from "../components/Graph";
|
||||||
// Frontend не выдержит ещё одних правок. Тут и так сейчас много говна
|
import Guide from "../components/Guide";
|
||||||
|
import Popup from "../components/Popup";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "View",
|
name: "View",
|
||||||
components: {
|
components: {
|
||||||
Graph,
|
Graph,
|
||||||
|
Guide,
|
||||||
|
Popup,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
// Const
|
// Const
|
||||||
let timer = null;
|
let timer = null;
|
||||||
|
const guide = [
|
||||||
|
{
|
||||||
|
name: "Создание вершин",
|
||||||
|
content:
|
||||||
|
"Для создания новой вершины необходимо дважды нажать левую кнопку мыши",
|
||||||
|
video: "/video/create.mp4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Связывание вершин",
|
||||||
|
content:
|
||||||
|
"Чтобы связать вершины, необходимо кликнуть левой кнопкой мыши по вершине, которую необходимо связать. Далее выбираются вершины, с которыми необходимо связать",
|
||||||
|
video: "/video/linking.mp4",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
// Reactive
|
// Reactive
|
||||||
const steps = ref([]);
|
const steps = ref([]);
|
||||||
const currentStep = ref(0);
|
const currentStep = ref(0);
|
||||||
const currentStepData = ref({});
|
const currentStepData = ref({});
|
||||||
const played = ref(false);
|
const played = ref(false);
|
||||||
|
const showInfo = ref(false);
|
||||||
|
const showGuide = ref(false);
|
||||||
|
const errorText = ref("");
|
||||||
|
|
||||||
|
// Mounted
|
||||||
|
onMounted(() => {
|
||||||
|
const key = "first_start";
|
||||||
|
|
||||||
|
if (JSON.parse(localStorage.getItem(key)) !== true) {
|
||||||
|
localStorage.setItem(key, true);
|
||||||
|
showGuide.value = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Computed
|
// Computed
|
||||||
const stepExists = computed(() => {
|
const stepExists = computed(() => {
|
||||||
@@ -170,6 +161,10 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
|
const log = () => {
|
||||||
|
showInfo.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
const getSteps = (data) => {
|
const getSteps = (data) => {
|
||||||
steps.value = data;
|
steps.value = data;
|
||||||
currentStep.value = 0;
|
currentStep.value = 0;
|
||||||
@@ -215,12 +210,12 @@ export default {
|
|||||||
prevStep,
|
prevStep,
|
||||||
play,
|
play,
|
||||||
stop,
|
stop,
|
||||||
|
log,
|
||||||
|
showInfo,
|
||||||
|
showGuide,
|
||||||
|
guide,
|
||||||
|
errorText,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
@import "~@/assets/css/creation.css";
|
|
||||||
@import "~@/assets/css/graph.css";
|
|
||||||
</style>
|
|
||||||
|
|||||||
Reference in New Issue
Block a user