eda演示完成
This commit is contained in:
parent
215cb69313
commit
042333ed4b
@ -12,6 +12,23 @@ module.exports = {
|
||||
ecmaVersion: 2020
|
||||
},
|
||||
rules: {
|
||||
'space-before-function-paren': 'off',
|
||||
'no-callback-literal': 0,
|
||||
'arrow-parens': 0,
|
||||
// allow async-await
|
||||
'no-unused-vars': 0,
|
||||
'generator-star-spacing': 'off',
|
||||
'spaced-comment': 0,
|
||||
'object-curly-spacing': 0,
|
||||
'@typescript-eslint/no-empty-function': 0,
|
||||
'@typescript-eslint/no-this-alias': 0,
|
||||
'@typescript-eslint/no-var-requires': 0,
|
||||
'prefer-const': 0,
|
||||
'vue/no-parsing-error': [2, { 'x-invalid-end-tag': false }],
|
||||
camelcase: 0,
|
||||
// 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
'no-undef-init': 0,
|
||||
'no-useless-call': 0,
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
|
||||
}
|
||||
|
||||
@ -10,12 +10,14 @@
|
||||
"dependencies": {
|
||||
"@antv/g6": "^4.1.1",
|
||||
"core-js": "^3.6.5",
|
||||
"d3-force": "^2.1.1",
|
||||
"vue": "^2.6.11",
|
||||
"vue-router": "^3.2.0",
|
||||
"vuetify": "^2.4.2",
|
||||
"vuex": "^3.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/d3-force": "^2.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^2.33.0",
|
||||
"@typescript-eslint/parser": "^2.33.0",
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
@ -34,7 +36,11 @@
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"less": "^3.0.4",
|
||||
"less-loader": "^5.0.0",
|
||||
"sass": "^1.19.0",
|
||||
"sass-loader": "^8.0.0",
|
||||
"typescript": "~3.9.3",
|
||||
"vue-template-compiler": "^2.6.11"
|
||||
"vue-cli-plugin-vuetify": "~2.0.9",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"vuetify-loader": "^1.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 6.9 KiB |
@ -1,11 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
|
||||
@ -1,32 +1,270 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<div id="nav">
|
||||
<router-link to="/">Home</router-link> |
|
||||
<router-link to="/about">About</router-link>
|
||||
</div>
|
||||
<router-view/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less">
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
#nav {
|
||||
padding: 30px;
|
||||
|
||||
a {
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
|
||||
&.router-link-exact-active {
|
||||
color: #42b983;
|
||||
}
|
||||
}
|
||||
<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>
|
||||
|
||||
BIN
eda/edaf/src/assets/favicon.ico
Normal file
BIN
eda/edaf/src/assets/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.7 KiB |
@ -1,36 +1,94 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
For a guide and recipes on how to configure / customize this project,<br>
|
||||
check out the
|
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
||||
</p>
|
||||
<h3>Installed CLI Plugins</h3>
|
||||
<ul>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript" target="_blank" rel="noopener">typescript</a></li>
|
||||
</ul>
|
||||
<h3>Essential Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
||||
</ul>
|
||||
<h3>Ecosystem</h3>
|
||||
<ul>
|
||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<v-container>
|
||||
<v-row class="text-center">
|
||||
<v-col cols="12">
|
||||
<v-img
|
||||
:src="require('../assets/logo.svg')"
|
||||
class="my-3"
|
||||
contain
|
||||
height="200"
|
||||
/>
|
||||
</v-col>
|
||||
|
||||
<v-col class="mb-4">
|
||||
<h1 class="display-2 font-weight-bold mb-3">
|
||||
Welcome to Vuetify
|
||||
</h1>
|
||||
|
||||
<p class="subheading font-weight-regular">
|
||||
For help and collaboration with other Vuetify developers,
|
||||
<br>please join our online
|
||||
<a
|
||||
href="https://community.vuetifyjs.com"
|
||||
target="_blank"
|
||||
>Discord Community</a>
|
||||
</p>
|
||||
</v-col>
|
||||
|
||||
<v-col
|
||||
class="mb-5"
|
||||
cols="12"
|
||||
>
|
||||
<h2 class="headline font-weight-bold mb-3">
|
||||
What's next?
|
||||
</h2>
|
||||
|
||||
<v-row justify="center">
|
||||
<a
|
||||
v-for="(next, i) in whatsNext"
|
||||
:key="i"
|
||||
:href="next.href"
|
||||
class="subheading mx-3"
|
||||
target="_blank"
|
||||
>
|
||||
{{ next.text }}
|
||||
</a>
|
||||
</v-row>
|
||||
</v-col>
|
||||
|
||||
<v-col
|
||||
class="mb-5"
|
||||
cols="12"
|
||||
>
|
||||
<h2 class="headline font-weight-bold mb-3">
|
||||
Important Links
|
||||
</h2>
|
||||
|
||||
<v-row justify="center">
|
||||
<a
|
||||
v-for="(link, i) in importantLinks"
|
||||
:key="i"
|
||||
:href="link.href"
|
||||
class="subheading mx-3"
|
||||
target="_blank"
|
||||
>
|
||||
{{ link.text }}
|
||||
</a>
|
||||
</v-row>
|
||||
</v-col>
|
||||
|
||||
<v-col
|
||||
class="mb-5"
|
||||
cols="12"
|
||||
>
|
||||
<h2 class="headline font-weight-bold mb-3">
|
||||
Ecosystem
|
||||
</h2>
|
||||
|
||||
<v-row justify="center">
|
||||
<a
|
||||
v-for="(eco, i) in ecosystem"
|
||||
:key="i"
|
||||
:href="eco.href"
|
||||
class="subheading mx-3"
|
||||
target="_blank"
|
||||
>
|
||||
{{ eco.text }}
|
||||
</a>
|
||||
</v-row>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -38,26 +96,58 @@ import Vue from 'vue'
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'HelloWorld',
|
||||
props: {
|
||||
msg: String
|
||||
}
|
||||
|
||||
data: () => ({
|
||||
ecosystem: [
|
||||
{
|
||||
text: 'vuetify-loader',
|
||||
href: 'https://github.com/vuetifyjs/vuetify-loader'
|
||||
},
|
||||
{
|
||||
text: 'github',
|
||||
href: 'https://github.com/vuetifyjs/vuetify'
|
||||
},
|
||||
{
|
||||
text: 'awesome-vuetify',
|
||||
href: 'https://github.com/vuetifyjs/awesome-vuetify'
|
||||
}
|
||||
],
|
||||
importantLinks: [
|
||||
{
|
||||
text: 'Documentation',
|
||||
href: 'https://vuetifyjs.com'
|
||||
},
|
||||
{
|
||||
text: 'Chat',
|
||||
href: 'https://community.vuetifyjs.com'
|
||||
},
|
||||
{
|
||||
text: 'Made with Vuetify',
|
||||
href: 'https://madewithvuejs.com/vuetify'
|
||||
},
|
||||
{
|
||||
text: 'Twitter',
|
||||
href: 'https://twitter.com/vuetifyjs'
|
||||
},
|
||||
{
|
||||
text: 'Articles',
|
||||
href: 'https://medium.com/vuetify'
|
||||
}
|
||||
],
|
||||
whatsNext: [
|
||||
{
|
||||
text: 'Explore components',
|
||||
href: 'https://vuetifyjs.com/components/api-explorer'
|
||||
},
|
||||
{
|
||||
text: 'Select a layout',
|
||||
href: 'https://vuetifyjs.com/getting-started/pre-made-layouts'
|
||||
},
|
||||
{
|
||||
text: 'Frequently Asked Questions',
|
||||
href: 'https://vuetifyjs.com/getting-started/frequently-asked-questions'
|
||||
}
|
||||
]
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped lang="less">
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
|
||||
189
eda/edaf/src/g6/force.ts
Normal file
189
eda/edaf/src/g6/force.ts
Normal file
@ -0,0 +1,189 @@
|
||||
const d3Force = require('d3-force')
|
||||
|
||||
const forceLayout = {
|
||||
tick: () => {
|
||||
},
|
||||
center: [0, 0],
|
||||
nodeStrength: null,
|
||||
edgeStrength: null,
|
||||
preventOverlap: false,
|
||||
nodeSize: undefined,
|
||||
nodeSpacing: undefined,
|
||||
linkDistance: 50,
|
||||
forceSimulation: null,
|
||||
alphaDecay: 0.028,
|
||||
alphaMin: 0.001,
|
||||
alpha: 0.3,
|
||||
collideStrength: 1,
|
||||
onLayoutEnd: function () {
|
||||
},
|
||||
getDefaultCfg() {
|
||||
return {
|
||||
center: [0, 0],
|
||||
nodeStrength: null,
|
||||
edgeStrength: null,
|
||||
preventOverlap: false,
|
||||
nodeSize: undefined,
|
||||
nodeSpacing: undefined,
|
||||
linkDistance: 50,
|
||||
forceSimulation: null,
|
||||
alphaDecay: 0.028,
|
||||
alphaMin: 0.001,
|
||||
alpha: 0.3,
|
||||
collideStrength: 1,
|
||||
onLayoutEnd: function () {
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 初始化
|
||||
* @param {Object} data 数据
|
||||
*/
|
||||
init(data) {
|
||||
console.log('init')
|
||||
const self = this
|
||||
self.nodes = data.nodes || []
|
||||
const edges = data.edges || []
|
||||
self.edges = edges.map(function (edge) {
|
||||
const res = {}
|
||||
const expectKeys = ['targetNode', 'sourceNode', 'startPoint', 'endPoint']
|
||||
Object.keys(edge).forEach(function (key) {
|
||||
if (!(expectKeys.indexOf(key) > -1)) {
|
||||
res[key] = edge[key]
|
||||
}
|
||||
})
|
||||
return res
|
||||
})
|
||||
self.ticking = false
|
||||
},
|
||||
/**
|
||||
* 执行布局
|
||||
*/
|
||||
execute(reloadData: any) {
|
||||
console.log('execute')
|
||||
const self = this
|
||||
const nodes = self.nodes
|
||||
const edges = self.edges
|
||||
// 如果正在布局,忽略布局请求
|
||||
if (self.ticking) {
|
||||
return
|
||||
}
|
||||
let simulation = self.forceSimulation
|
||||
const alphaMin = self.alphaMin
|
||||
const alphaDecay = self.alphaDecay
|
||||
const alpha = self.alpha
|
||||
if (!simulation) {
|
||||
try {
|
||||
// 定义节点的力
|
||||
const nodeForce = d3Force.forceManyBody()
|
||||
if (self.nodeStrength) {
|
||||
nodeForce.strength(self.nodeStrength)
|
||||
}
|
||||
simulation = d3Force.forceSimulation().nodes(nodes)
|
||||
simulation
|
||||
.force('center', d3Force.forceCenter(self.center[0], self.center[1]))
|
||||
.force('charge', nodeForce)
|
||||
.alpha(alpha)
|
||||
.alphaDecay(alphaDecay)
|
||||
.alphaMin(alphaMin)
|
||||
if (self.preventOverlap) {
|
||||
self.overlapProcess(simulation)
|
||||
}
|
||||
// 如果有边,定义边的力
|
||||
if (edges) {
|
||||
// d3 的 forceLayout 会重新生成边的数据模型,为了避免污染源数据
|
||||
const edgeForce = d3Force
|
||||
.forceLink()
|
||||
.id(function (d) {
|
||||
return d.id
|
||||
})
|
||||
.links(edges)
|
||||
if (self.edgeStrength) {
|
||||
edgeForce.strength(self.edgeStrength)
|
||||
}
|
||||
if (self.linkDistance) {
|
||||
edgeForce.distance(self.linkDistance)
|
||||
}
|
||||
self.edgeForce = edgeForce
|
||||
simulation.force('link', edgeForce)
|
||||
}
|
||||
simulation
|
||||
.on('tick', function () {
|
||||
self.tick()
|
||||
})
|
||||
.on('end', function () {
|
||||
self.ticking = false
|
||||
if (self.onLayoutEnd) {
|
||||
self.onLayoutEnd()
|
||||
}
|
||||
})
|
||||
self.ticking = true
|
||||
self.forceSimulation = simulation
|
||||
self.ticking = true
|
||||
} catch (e) {
|
||||
self.ticking = false
|
||||
console.warn(e)
|
||||
}
|
||||
} else {
|
||||
if (reloadData) {
|
||||
simulation.nodes(nodes)
|
||||
if (edges && self.edgeForce) {
|
||||
self.edgeForce.links(edges)
|
||||
} else if (edges && !self.edgeForce) {
|
||||
// d3 的 forceLayout 会重新生成边的数据模型,为了避免污染源数据
|
||||
const edgeForce = d3Force
|
||||
.forceLink()
|
||||
.id(function (d) {
|
||||
return d.id
|
||||
})
|
||||
.links(edges)
|
||||
if (self.edgeStrength) {
|
||||
edgeForce.strength(self.edgeStrength)
|
||||
}
|
||||
if (self.linkDistance) {
|
||||
edgeForce.distance(self.linkDistance)
|
||||
}
|
||||
self.edgeForce = edgeForce
|
||||
simulation.force('link', edgeForce)
|
||||
}
|
||||
}
|
||||
if (self.preventOverlap) {
|
||||
self.overlapProcess(simulation)
|
||||
}
|
||||
simulation.alpha(alpha).restart()
|
||||
this.ticking = true
|
||||
}
|
||||
// TODO
|
||||
},
|
||||
/**
|
||||
* 根据传入的数据进行布局
|
||||
* @param {Object} data 数据
|
||||
*/
|
||||
layout(data) {
|
||||
console.log('layout')
|
||||
this.init(data)
|
||||
this.execute()
|
||||
},
|
||||
/**
|
||||
* 更新布局配置,但不执行布局
|
||||
* @param {Object} cfg 需要更新的配置项
|
||||
*/
|
||||
updateCfg(cfg) {
|
||||
console.log('update cfg')
|
||||
const self = this
|
||||
if (self.ticking) {
|
||||
self.forceSimulation.stop()
|
||||
self.ticking = false
|
||||
}
|
||||
self.forceSimulation = null
|
||||
Object.assign(self, cfg)
|
||||
},
|
||||
/**
|
||||
* 销毁
|
||||
*/
|
||||
destroy() {
|
||||
console.log('destroy')
|
||||
}
|
||||
}
|
||||
|
||||
export default forceLayout
|
||||
6
eda/edaf/src/g6/index.ts
Normal file
6
eda/edaf/src/g6/index.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import G6 from '@antv/g6'
|
||||
import forceLayout from '@/g6/force'
|
||||
|
||||
G6.registerLayout('forceLayout', forceLayout)
|
||||
|
||||
export default G6
|
||||
133
eda/edaf/src/libs/index.js
Normal file
133
eda/edaf/src/libs/index.js
Normal file
@ -0,0 +1,133 @@
|
||||
function multiply(a, b) {
|
||||
// 相乘约束
|
||||
if (a[0].length !== b.length) {
|
||||
throw new Error()
|
||||
}
|
||||
let m = a.length
|
||||
let p = a[0].length
|
||||
let n = b[0].length
|
||||
|
||||
// 初始化 m*n 全 0 二维数组
|
||||
let c = new Array(m).fill(0).map(arr => new Array(n).fill(0))
|
||||
|
||||
for (let i = 0; i < m; i++) {
|
||||
for (let j = 0; j < n; j++) {
|
||||
for (let k = 0; k < p; k++) {
|
||||
c[i][j] += a[i][k] * b[k][j]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
function det(square) {
|
||||
// 方阵约束
|
||||
if (square.length !== square[0].length) {
|
||||
throw new Error()
|
||||
}
|
||||
// 方阵阶数
|
||||
let n = square.length
|
||||
|
||||
let result = 0
|
||||
if (n > 3) {
|
||||
// n 阶
|
||||
for (let column = 0; column < n; column++) {
|
||||
// 去掉第 0 行第 column 列的矩阵
|
||||
let matrix = new Array(n - 1).fill(0).map(arr => new Array(n - 1).fill(0))
|
||||
for (let i = 0; i < n - 1; i++) {
|
||||
for (let j = 0; j < n - 1; j++) {
|
||||
if (j < column) {
|
||||
matrix[i][j] = square[i + 1][j]
|
||||
} else {
|
||||
matrix[i][j] = square[i + 1][j + 1]
|
||||
}
|
||||
}
|
||||
}
|
||||
result += square[0][column] * Math.pow(-1, 0 + column) * det(matrix)
|
||||
}
|
||||
} else if (n === 3) {
|
||||
// 3 阶
|
||||
result = square[0][0] * square[1][1] * square[2][2] +
|
||||
square[0][1] * square[1][2] * square[2][0] +
|
||||
square[0][2] * square[1][0] * square[2][1] -
|
||||
square[0][2] * square[1][1] * square[2][0] -
|
||||
square[0][1] * square[1][0] * square[2][2] -
|
||||
square[0][0] * square[1][2] * square[2][1]
|
||||
} else if (n === 2) {
|
||||
// 2 阶
|
||||
result = square[0][0] * square[1][1] - square[0][1] * square[1][0]
|
||||
} else if (n === 1) {
|
||||
// 1 阶
|
||||
result = square[0][0]
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function transpose(matrix) {
|
||||
let result = new Array(matrix.length).fill(0).map(arr => new Array(matrix[0].length).fill(0))
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
for (let j = 0; j < result[0].length; j++) {
|
||||
result[i][j] = matrix[j][i]
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function adjoint(square) {
|
||||
// 方阵约束
|
||||
if (square[0].length !== square.length) {
|
||||
throw new Error()
|
||||
}
|
||||
|
||||
let n = square.length
|
||||
|
||||
let result = new Array(n).fill(0).map(arr => new Array(n).fill(0))
|
||||
for (let row = 0; row < n; row++) {
|
||||
for (let column = 0; column < n; column++) {
|
||||
// 去掉第 row 行第 column 列的矩阵
|
||||
let matrix = []
|
||||
for (let i = 0; i < square.length; i++) {
|
||||
if (i !== row) {
|
||||
let arr = []
|
||||
for (let j = 0; j < square.length; j++) {
|
||||
if (j !== column) {
|
||||
arr.push(square[i][j])
|
||||
}
|
||||
}
|
||||
matrix.push(arr)
|
||||
}
|
||||
}
|
||||
result[row][column] = Math.pow(-1, row + column) * det(matrix)
|
||||
}
|
||||
}
|
||||
return transpose(result)
|
||||
}
|
||||
|
||||
function inv(square) {
|
||||
if (square[0].length !== square.length) {
|
||||
throw new Error()
|
||||
}
|
||||
let detValue = det(square)
|
||||
let result = adjoint(square)
|
||||
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
for (let j = 0; j < result.length; j++) {
|
||||
result[i][j] /= detValue
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function copyM(m, xs, xe, ys, ye) {
|
||||
let n = []
|
||||
for (let i = xs; i < xe; i++) {
|
||||
n.push([])
|
||||
for (let j = ys; j < ye; j++) {
|
||||
n[i - xs].push(m[i][j])
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
export { inv, multiply, copyM }
|
||||
@ -2,11 +2,13 @@ import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import vuetify from './plugins/vuetify'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
vuetify,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
|
||||
7
eda/edaf/src/plugins/vuetify.ts
Normal file
7
eda/edaf/src/plugins/vuetify.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import Vue from 'vue'
|
||||
import Vuetify from 'vuetify/lib/framework'
|
||||
|
||||
Vue.use(Vuetify)
|
||||
|
||||
export default new Vuetify({
|
||||
})
|
||||
4
eda/edaf/src/shims-vuetify.d.ts
vendored
Normal file
4
eda/edaf/src/shims-vuetify.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
declare module 'vuetify/lib/framework' {
|
||||
import Vuetify from 'vuetify'
|
||||
export default Vuetify
|
||||
}
|
||||
@ -5,11 +5,17 @@ Vue.use(Vuex)
|
||||
|
||||
export default new Vuex.Store({
|
||||
state: {
|
||||
algorithm: 1,
|
||||
algorithms: [
|
||||
{value: 0, text: '二次线长布局'},
|
||||
{value: 1, text: '力矢量布局'}
|
||||
],
|
||||
nodes: [],
|
||||
edges: {},
|
||||
nodesNum: 5,
|
||||
edgesNum: 4
|
||||
},
|
||||
mutations: {
|
||||
},
|
||||
actions: {
|
||||
},
|
||||
modules: {
|
||||
}
|
||||
mutations: {},
|
||||
actions: {},
|
||||
modules: {}
|
||||
})
|
||||
|
||||
@ -1,18 +1,173 @@
|
||||
<template>
|
||||
<div class="home">
|
||||
<img alt="Vue logo" src="../assets/logo.png">
|
||||
<HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
|
||||
<div class="home" id="container">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import HelloWorld from '@/components/HelloWorld.vue' // @ is an alias to /src
|
||||
import G6 from './../g6'
|
||||
import {multiply, inv, copyM} from '@/libs'
|
||||
|
||||
const modes = {
|
||||
default: ['drag-canvas', 'zoom-canvas', 'brush-select']
|
||||
}
|
||||
|
||||
function refreshDragedNodePosition(e: any) {
|
||||
const model = e.item.get('model')
|
||||
model.x = e.x
|
||||
model.y = e.y
|
||||
}
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'Home',
|
||||
components: {
|
||||
HelloWorld
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
graph: G6.Graph,
|
||||
cfg: {
|
||||
container: 'container',
|
||||
modes: modes,
|
||||
defaultNode: {
|
||||
size: 20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
mode() {
|
||||
return this.$store.state.algorithm
|
||||
},
|
||||
nodes() {
|
||||
return Object.keys(this.$store.state.nodes).map(v => {
|
||||
return this.$store.state.nodes[v]
|
||||
})
|
||||
},
|
||||
edges() {
|
||||
return Object.keys(this.$store.state.edges).map(v => this.$store.state.edges[v])
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
mode() {
|
||||
this.graph.destroy()
|
||||
this.init()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
lay2() {
|
||||
const p = []
|
||||
const l = []
|
||||
let fnum = 0
|
||||
this.nodes.forEach(v => {
|
||||
l.push([])
|
||||
this.nodes.forEach(() => {
|
||||
l[l.length - 1].push(0)
|
||||
})
|
||||
if (v.color === 'red') {
|
||||
fnum = fnum + 1
|
||||
p.push([v.x, v.y])
|
||||
}
|
||||
})
|
||||
if (fnum === 0) {
|
||||
alert('请固定至少一个点')
|
||||
return
|
||||
}
|
||||
this.nodes.forEach(v => {
|
||||
if (v.color !== 'red') {
|
||||
p.push([0, 0])
|
||||
}
|
||||
})
|
||||
this.edges.forEach(v => {
|
||||
const s = Number(v.source.slice(1))
|
||||
const e = Number(v.target.slice(1))
|
||||
l[s][e] = 1
|
||||
l[e][s] = 1
|
||||
})
|
||||
const ones = [l.map(e => 1)]
|
||||
const onesL = multiply(ones, l)
|
||||
const B = multiply(l, p)
|
||||
const A = []
|
||||
for (let i = 0; i < p.length; i++) {
|
||||
A.push([])
|
||||
for (let j = 0; j < p.length; j++) {
|
||||
A[i].push(0)
|
||||
if (i === j) {
|
||||
A[i][j] = onesL[0][i]
|
||||
}
|
||||
A[i][j] = A[i][j] - l[i][j]
|
||||
}
|
||||
}
|
||||
const nA = copyM(A, fnum, A.length, fnum, A.length)
|
||||
const nB = copyM(B, fnum, A.length, 0, 2)
|
||||
const res = multiply(inv(nA), nB)
|
||||
let index = 0
|
||||
console.log(res)
|
||||
this.nodes.forEach(v => {
|
||||
if (v.color !== 'red') {
|
||||
v.x = res[index][0]
|
||||
v.y = res[index][1]
|
||||
this.graph.updateItem(v.id, {x: v.x, y: v.y})
|
||||
index = index + 1
|
||||
}
|
||||
})
|
||||
},
|
||||
init() {
|
||||
const container = document.getElementById('container')
|
||||
this.cfg.width = container.scrollWidth
|
||||
this.cfg.height = container.scrollHeight || 500
|
||||
this.cfg.layout = this.mode === 1 ? {
|
||||
type: 'force',
|
||||
center: [this.cfg.width / 2, this.cfg.height / 2],
|
||||
preventOverlap: true,
|
||||
onTick: (e) => {
|
||||
},
|
||||
onLayoutEnd: () => {
|
||||
},
|
||||
workerEnabled: false
|
||||
} : undefined
|
||||
const graph = new G6.Graph(this.cfg)
|
||||
this.graph = graph
|
||||
this.loaddata()
|
||||
if (this.mode !== 1) {
|
||||
graph.on('node:drag', e => {
|
||||
if (e.item?.getModel().color === 'red') {
|
||||
return
|
||||
}
|
||||
refreshDragedNodePosition(e)
|
||||
graph.refresh()
|
||||
})
|
||||
return
|
||||
}
|
||||
const forceLayout = graph.get('layoutController').layoutMethod
|
||||
const start = (e) => {
|
||||
graph.layout()
|
||||
refreshDragedNodePosition(e)
|
||||
}
|
||||
const move = (e) => {
|
||||
forceLayout.execute()
|
||||
refreshDragedNodePosition(e)
|
||||
}
|
||||
const end = (e) => {
|
||||
// e.item.get('model').fx = null
|
||||
// e.item.get('model').fy = null
|
||||
}
|
||||
graph.on('node:dragstart', start)
|
||||
graph.on('node:drag', move)
|
||||
graph.on('node:dragend', end)
|
||||
graph.on('node:touchstart', start)
|
||||
graph.on('node:touchmove', move)
|
||||
graph.on('node:touchend', end)
|
||||
},
|
||||
loaddata() {
|
||||
this.graph.data({
|
||||
nodes: this.nodes,
|
||||
edges: this.edges
|
||||
})
|
||||
this.graph.render()
|
||||
// this.graph.fitView(20)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
5
eda/edaf/vue.config.js
Normal file
5
eda/edaf/vue.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
transpileDependencies: [
|
||||
'vuetify'
|
||||
]
|
||||
}
|
||||
@ -1207,6 +1207,11 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/d3-force@^2.1.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-force/-/d3-force-2.1.0.tgz#6a2210f04d02a0862c6b069de91bad904143e7b5"
|
||||
integrity sha512-LGDtC2YADu8OBniq9EBx/MOsXsMcJbEkmfSpXuz6oVdRamB+3CLCiq5EKFPEILGZQckkilGFq1ZTJ7kc289k+Q==
|
||||
|
||||
"@types/d3-timer@^1.0.9":
|
||||
version "1.0.10"
|
||||
resolved "https://registry.npm.taobao.org/@types/d3-timer/download/@types/d3-timer-1.0.10.tgz#329c51c2c931f44ed0acff78b8c84571acf0ed21"
|
||||
@ -2710,6 +2715,21 @@ check-types@^8.0.3:
|
||||
resolved "https://registry.npm.taobao.org/check-types/download/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552"
|
||||
integrity sha1-M1bMoZyIlUTy16le1JzlCKDs9VI=
|
||||
|
||||
"chokidar@>=2.0.0 <4.0.0", chokidar@^3.3.0, chokidar@^3.4.1:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.npm.taobao.org/chokidar/download/chokidar-3.5.0.tgz?cache=0&sync_timestamp=1609920546161&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchokidar%2Fdownload%2Fchokidar-3.5.0.tgz#458a4816a415e9d3b3caa4faec2b96a6935a9e65"
|
||||
integrity sha1-RYpIFqQV6dOzyqT67CuWppNanmU=
|
||||
dependencies:
|
||||
anymatch "~3.1.1"
|
||||
braces "~3.0.2"
|
||||
glob-parent "~5.1.0"
|
||||
is-binary-path "~2.1.0"
|
||||
is-glob "~4.0.1"
|
||||
normalize-path "~3.0.0"
|
||||
readdirp "~3.5.0"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.1"
|
||||
|
||||
chokidar@^2.1.8:
|
||||
version "2.1.8"
|
||||
resolved "https://registry.npm.taobao.org/chokidar/download/chokidar-2.1.8.tgz?cache=0&sync_timestamp=1609920546161&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchokidar%2Fdownload%2Fchokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
|
||||
@ -2729,21 +2749,6 @@ chokidar@^2.1.8:
|
||||
optionalDependencies:
|
||||
fsevents "^1.2.7"
|
||||
|
||||
chokidar@^3.3.0, chokidar@^3.4.1:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.npm.taobao.org/chokidar/download/chokidar-3.5.0.tgz?cache=0&sync_timestamp=1609920546161&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchokidar%2Fdownload%2Fchokidar-3.5.0.tgz#458a4816a415e9d3b3caa4faec2b96a6935a9e65"
|
||||
integrity sha1-RYpIFqQV6dOzyqT67CuWppNanmU=
|
||||
dependencies:
|
||||
anymatch "~3.1.1"
|
||||
braces "~3.0.2"
|
||||
glob-parent "~5.1.0"
|
||||
is-binary-path "~2.1.0"
|
||||
is-glob "~4.0.1"
|
||||
normalize-path "~3.0.0"
|
||||
readdirp "~3.5.0"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.1"
|
||||
|
||||
chownr@^1.1.1, chownr@^1.1.2:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.npm.taobao.org/chownr/download/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
|
||||
@ -2863,6 +2868,15 @@ cliui@^7.0.2:
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
clone-deep@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npm.taobao.org/clone-deep/download/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387"
|
||||
integrity sha1-wZ/Zvbv4WUK0/ZechNz31fB8I4c=
|
||||
dependencies:
|
||||
is-plain-object "^2.0.4"
|
||||
kind-of "^6.0.2"
|
||||
shallow-clone "^3.0.0"
|
||||
|
||||
clone@^1.0.2:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.npm.taobao.org/clone/download/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
|
||||
@ -3384,7 +3398,7 @@ d3-ease@^1.0.5:
|
||||
resolved "https://registry.npm.taobao.org/d3-ease/download/d3-ease-1.0.7.tgz#9a834890ef8b8ae8c558b2fe55bd57f5993b85e2"
|
||||
integrity sha1-moNIkO+LiujFWLL+Vb1X9Zk7heI=
|
||||
|
||||
d3-force@^2.0.1:
|
||||
d3-force@^2.0.1, d3-force@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npm.taobao.org/d3-force/download/d3-force-2.1.1.tgz#f20ccbf1e6c9e80add1926f09b51f686a8bc0937"
|
||||
integrity sha1-8gzL8ebJ6ArdGSbwm1H2hqi8CTc=
|
||||
@ -4368,7 +4382,7 @@ file-entry-cache@^5.0.1:
|
||||
dependencies:
|
||||
flat-cache "^2.0.1"
|
||||
|
||||
file-loader@^4.2.0:
|
||||
file-loader@^4.0.0, file-loader@^4.2.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npm.taobao.org/file-loader/download/file-loader-4.3.0.tgz#780f040f729b3d18019f20605f723e844b8a58af"
|
||||
integrity sha1-eA8ED3KbPRgBnyBgX3I+hEuKWK8=
|
||||
@ -4729,7 +4743,7 @@ glob-to-regexp@^0.3.0:
|
||||
resolved "https://registry.npm.taobao.org/glob-to-regexp/download/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
|
||||
integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=
|
||||
|
||||
glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
|
||||
glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.npm.taobao.org/glob/download/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
integrity sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=
|
||||
@ -5269,7 +5283,7 @@ internal-ip@^4.3.0:
|
||||
default-gateway "^4.2.0"
|
||||
ipaddr.js "^1.9.0"
|
||||
|
||||
interpret@^1.2.0:
|
||||
interpret@^1.0.0, interpret@^1.2.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npm.taobao.org/interpret/download/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
|
||||
integrity sha1-Zlq4vE2iendKQFhOgS4+D6RbGh4=
|
||||
@ -5886,7 +5900,7 @@ loader-utils@^0.2.16:
|
||||
json5 "^0.5.0"
|
||||
object-assign "^4.0.1"
|
||||
|
||||
loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0:
|
||||
loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.0, loader-utils@^1.2.3, loader-utils@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npm.taobao.org/loader-utils/download/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613"
|
||||
integrity sha1-xXm140yzSxp07cbB+za/o3HVphM=
|
||||
@ -6529,6 +6543,14 @@ nth-check@^1.0.2:
|
||||
dependencies:
|
||||
boolbase "~1.0.0"
|
||||
|
||||
null-loader@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npm.taobao.org/null-loader/download/null-loader-3.0.0.tgz#3e2b6c663c5bda8c73a54357d8fa0708dc61b245"
|
||||
integrity sha1-PitsZjxb2oxzpUNX2PoHCNxhskU=
|
||||
dependencies:
|
||||
loader-utils "^1.2.3"
|
||||
schema-utils "^1.0.0"
|
||||
|
||||
num2fraction@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.npm.taobao.org/num2fraction/download/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
|
||||
@ -7664,6 +7686,13 @@ readdirp@~3.5.0:
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
rechoir@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.npm.taobao.org/rechoir/download/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
|
||||
integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=
|
||||
dependencies:
|
||||
resolve "^1.1.6"
|
||||
|
||||
reflect-metadata@^0.1.13:
|
||||
version "0.1.13"
|
||||
resolved "https://registry.npm.taobao.org/reflect-metadata/download/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
|
||||
@ -7842,7 +7871,7 @@ resolve-url@^0.2.1:
|
||||
resolved "https://registry.npm.taobao.org/resolve-url/download/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
||||
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
|
||||
|
||||
resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2:
|
||||
resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2:
|
||||
version "1.19.0"
|
||||
resolved "https://registry.npm.taobao.org/resolve/download/resolve-1.19.0.tgz?cache=0&sync_timestamp=1605052120709&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fresolve%2Fdownload%2Fresolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c"
|
||||
integrity sha1-GvW/YwQJc0oGfK4pMYqsf6KaJnw=
|
||||
@ -7958,6 +7987,24 @@ safe-regex@^1.1.0:
|
||||
resolved "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=
|
||||
|
||||
sass-loader@^8.0.0:
|
||||
version "8.0.2"
|
||||
resolved "https://registry.npm.taobao.org/sass-loader/download/sass-loader-8.0.2.tgz?cache=0&sync_timestamp=1605100127712&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-8.0.2.tgz#debecd8c3ce243c76454f2e8290482150380090d"
|
||||
integrity sha1-3r7NjDziQ8dkVPLoKQSCFQOACQ0=
|
||||
dependencies:
|
||||
clone-deep "^4.0.1"
|
||||
loader-utils "^1.2.3"
|
||||
neo-async "^2.6.1"
|
||||
schema-utils "^2.6.1"
|
||||
semver "^6.3.0"
|
||||
|
||||
sass@^1.19.0:
|
||||
version "1.32.2"
|
||||
resolved "https://registry.npm.taobao.org/sass/download/sass-1.32.2.tgz#66dc0250bc86c15d19ddee7135e93d0cf3d3257b"
|
||||
integrity sha1-ZtwCULyGwV0Z3e5xNek9DPPTJXs=
|
||||
dependencies:
|
||||
chokidar ">=2.0.0 <4.0.0"
|
||||
|
||||
sax@~1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.npm.taobao.org/sax/download/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||
@ -7981,7 +8028,7 @@ schema-utils@^1.0.0:
|
||||
ajv-errors "^1.0.0"
|
||||
ajv-keywords "^3.1.0"
|
||||
|
||||
schema-utils@^2.0.0, schema-utils@^2.5.0, schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0:
|
||||
schema-utils@^2.0.0, schema-utils@^2.5.0, schema-utils@^2.6.1, schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0:
|
||||
version "2.7.1"
|
||||
resolved "https://registry.npm.taobao.org/schema-utils/download/schema-utils-2.7.1.tgz?cache=0&sync_timestamp=1601922251376&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7"
|
||||
integrity sha1-HKTzLRskxZDCA7jnpQvw6kzTlNc=
|
||||
@ -8017,7 +8064,7 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.1.2, semver@^6.3.0:
|
||||
resolved "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz?cache=0&sync_timestamp=1606851962993&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
||||
integrity sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=
|
||||
|
||||
semver@^7.3.2:
|
||||
semver@^7.1.2, semver@^7.3.2:
|
||||
version "7.3.4"
|
||||
resolved "https://registry.npm.taobao.org/semver/download/semver-7.3.4.tgz?cache=0&sync_timestamp=1606851962993&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
|
||||
integrity sha1-J6qn0uTKdkUvmNOt0JOnLJQ+3Jc=
|
||||
@ -8111,6 +8158,13 @@ sha.js@^2.4.0, sha.js@^2.4.8:
|
||||
inherits "^2.0.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
shallow-clone@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.npm.taobao.org/shallow-clone/download/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"
|
||||
integrity sha1-jymBrZJTH1UDWwH7IwdppA4C76M=
|
||||
dependencies:
|
||||
kind-of "^6.0.2"
|
||||
|
||||
shebang-command@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npm.taobao.org/shebang-command/download/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
||||
@ -8140,6 +8194,15 @@ shell-quote@^1.6.1:
|
||||
resolved "https://registry.npm.taobao.org/shell-quote/download/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2"
|
||||
integrity sha1-Z6fQLHbJ2iT5nSCAj8re0ODgS+I=
|
||||
|
||||
shelljs@^0.8.3:
|
||||
version "0.8.4"
|
||||
resolved "https://registry.npm.taobao.org/shelljs/download/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2"
|
||||
integrity sha1-3naE/ut2f4cWsyYHiooAh1iQ48I=
|
||||
dependencies:
|
||||
glob "^7.0.0"
|
||||
interpret "^1.0.0"
|
||||
rechoir "^0.6.2"
|
||||
|
||||
signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||
@ -9151,6 +9214,15 @@ vm-browserify@^1.0.1:
|
||||
resolved "https://registry.npm.taobao.org/vm-browserify/download/vm-browserify-1.1.2.tgz?cache=0&sync_timestamp=1572870837170&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvm-browserify%2Fdownload%2Fvm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
||||
integrity sha1-eGQcSIuObKkadfUR56OzKobl3aA=
|
||||
|
||||
vue-cli-plugin-vuetify@~2.0.9:
|
||||
version "2.0.9"
|
||||
resolved "https://registry.npm.taobao.org/vue-cli-plugin-vuetify/download/vue-cli-plugin-vuetify-2.0.9.tgz#982991aec28e79d1f0c2eb8f6e3d62e042087ee8"
|
||||
integrity sha1-mCmRrsKOedHwwuuPbj1i4EIIfug=
|
||||
dependencies:
|
||||
null-loader "^3.0.0"
|
||||
semver "^7.1.2"
|
||||
shelljs "^0.8.3"
|
||||
|
||||
vue-eslint-parser@^7.0.0:
|
||||
version "7.3.0"
|
||||
resolved "https://registry.npm.taobao.org/vue-eslint-parser/download/vue-eslint-parser-7.3.0.tgz?cache=0&sync_timestamp=1608031130825&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-eslint-parser%2Fdownload%2Fvue-eslint-parser-7.3.0.tgz#894085839d99d81296fa081d19643733f23d7559"
|
||||
@ -9219,6 +9291,14 @@ vue@^2.6.11:
|
||||
resolved "https://registry.npm.taobao.org/vue/download/vue-2.6.12.tgz?cache=0&sync_timestamp=1609362215490&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue%2Fdownload%2Fvue-2.6.12.tgz#f5ebd4fa6bd2869403e29a896aed4904456c9123"
|
||||
integrity sha1-9evU+mvShpQD4pqJau1JBEVskSM=
|
||||
|
||||
vuetify-loader@^1.3.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.npm.taobao.org/vuetify-loader/download/vuetify-loader-1.6.0.tgz#05df0805b3ab2ff0de198109d34f9da3f69da667"
|
||||
integrity sha1-Bd8IBbOrL/DeGYEJ00+do/adpmc=
|
||||
dependencies:
|
||||
file-loader "^4.0.0"
|
||||
loader-utils "^1.2.0"
|
||||
|
||||
vuetify@^2.4.2:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.npm.taobao.org/vuetify/download/vuetify-2.4.2.tgz#d37d160c1fc6b241fc166a32980b34590a017d6e"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user