courses/eda/edaf/src/App.vue
2021-01-11 11:50:18 +08:00

271 lines
7.0 KiB
Vue

<style>
.info-div {
width: 100%;
position: absolute;
bottom: 0;
left: 0;
}
</style>
<template>
<v-app>
<v-app-bar
app
color="primary"
dark
dense
>
<v-app-bar-nav-icon>
<v-avatar size="20">
<img
src="/favicon.ico"
alt="veypi"
>
</v-avatar>
</v-app-bar-nav-icon>
<v-toolbar-title>
{{ $store.state.algorithms[$store.state.algorithm].text }}
</v-toolbar-title>
<v-spacer></v-spacer>
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Search"
single-line
hide-details
></v-text-field>
<v-icon class="mr-5" @click="info=!info">mdi-information</v-icon>
<v-icon class="mr-5" @click="sync">mdi-autorenew</v-icon>
<v-btn color="warning" class="mr-5" v-if="$store.state.algorithm===0" @click="$refs.core.lay2()">计算</v-btn>
<v-icon @click="dialog=!dialog">mdi-cog</v-icon>
</v-app-bar>
<v-main>
<v-system-bar>
<v-row class="text-center">
<v-col>边数: {{ $store.state.edgesNum }}</v-col>
<v-col>节点数: {{ $store.state.nodesNum }}</v-col>
</v-row>
</v-system-bar>
<router-view ref="core" style="height: 100%;width: 100%"></router-view>
</v-main>
<div class="info-div" v-if="info">
<v-data-table
class="mx-auto"
:headers="headers"
:items="nodeList"
:search="search"
disable-sort
dense
height="300px"
style="background: rgba(0,0,0,0.2);"
>
<template v-slot:item.x="{ item }">
{{ item.x.toFixed(2) }}
</template>
<template v-slot:item.y="{ item }">
{{ item.y.toFixed(2) }}
</template>
<template v-slot:item.act="{ item }">
<v-btn v-if="item.color === freeC " color="warning" @click="lock(item)">固定</v-btn>
<v-btn v-else color="primary" @click="unlock(item)">解除</v-btn>
</template>
</v-data-table>
</div>
<v-dialog
v-model="dialog"
transition="dialog-bottom-transition"
max-width="600"
>
<v-card>
<v-system-bar
color="success"
dark
>
设置
</v-system-bar>
<v-card-text class="mt-10">
<v-form>
<v-select v-model="$store.state.algorithm" :items="$store.state.algorithms" label="算法"></v-select>
<v-slider
label="节点数量"
class="mt-10"
v-model="$store.state.nodesNum"
thumb-label="always"
:max="$store.state.algorithm ? 100: 10"
:min="5"
></v-slider>
<v-slider
:max="$store.state.nodesNum * 5"
:min="$store.state.nodesNum * (1 + $store.state.algorithm) - 1" label="边数量" class="mt-10"
v-model="$store.state.edgesNum" thumb-label="always"></v-slider>
</v-form>
</v-card-text>
</v-card>
</v-dialog>
</v-app>
</template>
<script lang="ts">
import Vue from 'vue'
function uniform2NormalDistribution() {
let sum = 0.0
for (let i = 0; i < 12; i++) {
sum = sum + Math.random(1)
}
return sum - 6.0
}
function getNumberInNormalDistribution(mean, stdDev) {
return mean + (uniform2NormalDistribution() * stdDev)
}
export default Vue.extend({
name: 'App',
components: {},
data: () => ({
freeC: '#5cf43d',
search: '',
headers: [
{
text: '节点id',
align: 'start',
width: '60px',
value: 'id'
},
{text: 'x', value: 'x', width: 60},
{text: 'y', value: 'y', width: 60},
{text: 'act', value: 'act'}
],
dialog: false,
info: false
//
}),
computed: {
nodeList() {
return Object.keys(this.$store.state.nodes).map(v => {
return this.$store.state.nodes[v]
})
}
},
methods: {
lock(n) {
n.color = 'red'
n.fx = n.x
n.fy = n.y
const graph = this.$refs.core.graph
graph.updateItem(n.id, {color: n.color})
},
unlock(n) {
n.color = this.freeC
n.fx = null
n.fy = null
this.$refs.core.graph.updateItem(n.id, {color: n.color})
},
sync() {
const edges = {}
const nodes = {}
for (let i = 0; i < this.$store.state.nodesNum; i++) {
nodes['n' + i] = {
label: 'n' + i,
id: 'n' + i,
// 随机布局
color: this.freeC,
x: i * Math.random() * 100,
y: i * Math.random() * 100,
size: Math.floor(Math.random() * 20) + 5
}
}
// nodes.n0.color = 'red'
// nodes.n0.fx = 100
// nodes.n0.fy = 175
// nodes.n0.x = 100
// nodes.n0.y = 175
// nodes.n1.color = 'red'
// nodes.n1.fx = 200
// nodes.n1.fy = 225
// nodes.n1.x = 200
// nodes.n1.y = 225
// edges['0-2'] = {
// id: '0-2',
// source: 'n0',
// target: 'n2',
// value: 1
// }
// edges['2-3'] = {
// id: '2-3',
// source: 'n2',
// target: 'n3',
// value: 1
// }
// edges['3-4'] = {
// id: '3-4',
// source: 'n3',
// target: 'n4',
// value: 1
// }
// edges['4-1'] = {
// id: '4-1',
// source: 'n4',
// target: 'n1',
// value: 1
// }
let iter = 1
for (let i = 0; i < this.$store.state.nodesNum; i++) {
if (Object.keys(edges).length >= this.$store.state.edgesNum) {
this.$store.state.edges = edges
this.$store.state.nodes = nodes
this.$refs.core.loaddata()
return
}
let j = i
while (i === j) {
j = Math.floor(Math.random() * this.$store.state.nodesNum)
}
let ni = i
if (i > j) {
ni = j
j = i
}
const v = Math.abs(Math.floor(getNumberInNormalDistribution(4, 20)))
edges[ni + '-' + j] = {
id: ni + '-' + j,
source: 'n' + ni,
target: 'n' + j,
value: v
}
}
while (iter < 10) {
iter = iter + 1
for (let i = 0; i < this.$store.state.nodesNum; i++) {
for (let j = i + 1; j < this.$store.state.nodesNum; j++) {
// const v = Math.floor(Math.random() * 10)
const v = Math.floor(getNumberInNormalDistribution(4, 20))
if (v > 0) {
const id = i + '-' + j
edges[id] = {
id: id,
source: 'n' + i,
target: 'n' + j,
value: v
// label: v
}
if (Object.keys(edges).length >= this.$store.state.edgesNum) {
this.$store.state.edges = edges
this.$store.state.nodes = nodes
this.$refs.core.loaddata()
return
}
}
}
}
}
}
},
mounted() {
this.sync()
}
})
</script>