first commit

catl
sqlnice 2024-05-23 09:41:43 +08:00
commit 3624472392
235 changed files with 30512 additions and 0 deletions

3
.browserslistrc Normal file
View File

@ -0,0 +1,3 @@
> 1%
last 2 versions
not dead

5
.editorconfig Normal file
View File

@ -0,0 +1,5 @@
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true

6
.env.development Normal file
View File

@ -0,0 +1,6 @@
/**
* Created by Zhang Haijun on 2018/8/13.
*/
VUE_APP_BASEURL = '/'
VUE_APP_MAPURL = 'http://58.210.9.131:5080'
VUE_APP_MAPTILE = '/SIPGIS/tile-services/TileService/SIPSD_sipmap/MapServer'

6
.env.production Normal file
View File

@ -0,0 +1,6 @@
/**
* Created by Zhang Haijun on 2018/8/13.
*/
VUE_APP_MAPURL = 'http://172.28.76.22'
VUE_APP_MAPTILE = '/SIPGIS/tile-services/TileService/ZNJT_GYYQ/MapServer'
VUE_APP_BASEURL = '/scr-web/'

36
.eslintrc.js Normal file
View File

@ -0,0 +1,36 @@
module.exports = {
root: true,
env: {
node: true
},
extends: [
'plugin:vue/essential',
'@vue/standard',
'@vue/typescript'
],
parserOptions: {
parser: '@typescript-eslint/parser'
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-unused-vars': [
0,
{
vars: 'all',
args: 'none'
}
],
semi: 0,
eqeqeq: 0,
'one-var': 0,
camelcase: 0,
'no-case-declarations': 0,
'space-before-function-paren': 0,
'vue/no-unused-components': 0
}
}

23
.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
.DS_Store
node_modules
/screen-web
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

24
README.md Normal file
View File

@ -0,0 +1,24 @@
# cmp-screen
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn serve
```
### Compiles and minifies for production
```
yarn build
```
### Lints and fixes files
```
yarn lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

5
babel.config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

69
package.json Normal file
View File

@ -0,0 +1,69 @@
{
"name": "cmp-screen",
"version": "5.6.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@antv/g6": "3.8.5",
"@antv/l7": "^2.3.7",
"@antv/l7-district": "^2.3.1",
"@antv/l7-maps": "^2.3.7",
"@jiaminghi/data-view": "^2.10.0",
"@turf/turf": "^6.3.0",
"@tweenjs/tween.js": "^18.6.4",
"@vue/composition-api": "^1.0.0-rc.9",
"axios": "^0.21.0",
"cmp-echarts": "2.0.1-5.6-release",
"core-js": "^3.6.5",
"crypto-js": "^4.0.0",
"echarts": "^4.9.0",
"echarts-liquidfill": "^2.0.0",
"element-ui": "^2.14.1",
"heatmapjs": "^2.0.2",
"js-cookie": "^2.2.1",
"leaflet": "^1.7.1",
"lodash-es": "^4.17.15",
"moment": "^2.29.1",
"nprogress": "^0.2.0",
"ol": "^6.5.0",
"ol-echarts": "^2.0.3",
"qs": "^6.9.4",
"stats.js": "^0.17.0",
"three": "0.122.0",
"three-js-csg": "^72.0.0",
"three-orbitcontrols": "^2.110.3",
"vue": "^2.6.11",
"vue-count-to": "^1.0.13",
"vue-router": "^3.2.0",
"vue-seamless-scroll": "^1.1.21",
"vuex": "^3.4.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^2.33.0",
"@typescript-eslint/parser": "^2.33.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-typescript": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/eslint-config-standard": "^5.1.2",
"@vue/eslint-config-typescript": "^5.0.2",
"babel-eslint": "^10.1.0",
"compress-webpack-plugin": "^1.0.6",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^6.2.2",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"typescript": "^4.2.4",
"vue-template-compiler": "^2.6.11"
}
}

12799
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

23
public/index.html Normal file
View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<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 %>static/img/shortcut.png">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<script type="text/javascript" src="./static/config.js"></script>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
public/static/img/jg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
public/static/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 651 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
public/static/img/ups.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -0,0 +1,3 @@
window.configs = {
showLogo: false
}

9
src/App.vue Normal file
View File

@ -0,0 +1,9 @@
<template>
<div id="app">
<router-view/>
</div>
</template>
<style lang="scss">
@import "./css/index.scss";
</style>

BIN
src/assets/img/animate.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

BIN
src/assets/img/header.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 566 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

BIN
src/assets/img/stat_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 649 B

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,64 @@
<template>
<div class="scroll-wrapper" :style="style" @mouseenter="clearTimer" @mouseleave="enableTimer">
<slot :list="list"></slot>
</div>
</template>
<script>
import { computed, onMounted, onUnmounted, reactive, toRefs } from '@vue/composition-api'
export default {
props: {
data: {
type: Array
},
waitTime: {
type: Number,
default: 1500
},
singleHeight: {
type: Number,
default: 40
}
},
setup(props) {
const state = reactive({
animate: false
});
const list = computed(() => props.data);
const style = computed(() => {
return state.animate ? { transition: 'all 0.5s ease-in', transform: `translate(0, -${props.singleHeight}px)` } : {};
})
const scrollAnimate = () => {
state.animate = true;
setTimeout(() => {
state.animate = false;
list.value.push(list.value[0]);
list.value.shift();
}, 500)
}
let timer = null;
onMounted(() => {
enableTimer()
});
onUnmounted(() => {
clearTimer()
});
const enableTimer = () => {
if (timer) clearTimer();
timer = setInterval(scrollAnimate, props.waitTime)
}
const clearTimer = () => {
clearInterval(timer);
timer = null;
}
return {
...toRefs(state),
list,
style,
enableTimer,
clearTimer
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,55 @@
<template>
<div class="cell">
<img :src="icon" alt="" class="title-icon">
<div>
<div class="icon-container" v-for="(item, index) in data" :key="index">
<span class="icon" :style="{background: item.color}"></span>
<span class="text">{{item.text}}</span>
</div>
</div>
</div>
</template>
<script>
import { computed } from '@vue/composition-api'
export default {
props: {
icon: {
type: String,
default: '/scr-web/static/img/business_network/switch.png'
},
data: {
type: Array
}
},
setup(props) {
return {
}
}
}
</script>
<style lang="scss" scoped>
.cell {
display: flex;
margin-top: 20px;
justify-content: center;
align-items: center;
margin-bottom: 5px;
.title-icon{
width: 60px;
height: 80px;
margin-right: 10px;
}
span{
display: inline-block;
}
.icon-container{
margin-bottom: 5px;
}
.icon {
width: 14px;
height: 14px;
background: #19BE6B;
margin-right: 10px ;
}
}
</style>

View File

@ -0,0 +1,89 @@
<template>
<div class="full-screen-container" :style="style">
<slot></slot>
<div class="loading" v-if="loading">
<dv-decoration-9 style="width:300px;height:300px;" >数据加载中</dv-decoration-9>
</div>
</div>
</template>
<script>
import { computed, onMounted, onUnmounted, reactive, toRefs } from '@vue/composition-api'
import { debounce } from 'lodash-es'
// import 'utils/rem'
export default {
props: {
width: {
type: Number,
default: 1920
},
height: {
type: Number,
default: 1080
},
loading: {
type: Boolean,
default: false
}
},
setup(props, context) {
const state = reactive({
scale: null
});
const style = computed(() => {
return {
width: `${props.width}px`,
height: `${props.height}px`,
transform: `scale(${state.scale})`
}
});
function getScale() {
const { width, height } = props
const wRatio = window.innerWidth / width
const hRatio = window.innerHeight / height;
// return 1;
return wRatio < hRatio ? wRatio : hRatio
}
function setScale() {
state.scale = getScale();
context.emit('getScale', state.scale)
}
const onResize = debounce(setScale, 10)
onMounted(() => {
setScale()
window.addEventListener('resize', onResize)
});
onUnmounted(() => {
window.removeEventListener('resize', onResize)
});
return {
style
}
}
}
</script>
<style lang="scss" scoped >
.full-screen-container {
position: fixed;
top: 0px;
left: 0px;
overflow: hidden;
transform-origin: left top;
z-index: 999;
.loading{
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0,0,0,0.8);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center ;
color: rgba(255,255,255,0.8);
font-size: 20px;
}
}
</style>

View File

@ -0,0 +1,59 @@
<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-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>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
name: 'HelloWorld',
props: {
msg: String
}
});
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

View File

@ -0,0 +1,38 @@
<template>
<div class="no-data">
<i class="icon" :class="icon"></i>
<span class="text">{{text}}</span>
</div>
</template>
<script>
export default {
props: {
icon: {
type: String,
default: 'el-icon-s-order'
},
text: {
type: String,
default: '暂无数据'
}
}
}
</script>
<style lang="scss" scoped>
.no-data {
min-height: 200px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
.icon {
color: #1a84e6;
font-size: 50px;
margin-bottom: 10px;
}
.text {
color: #b3b5c3;
}
}
</style>

View File

@ -0,0 +1,106 @@
<template>
<el-row class="stat-container">
<!-- <dv-border-box-8 :reverse="true" style="height: 74px"> -->
<div class="stat-border" style="top: -2px"></div>
<div class="stat-border" style="top: -2px; right: 1px"></div>
<div class="stat-border" style="bottom: 0; right: 1px"></div>
<div class="stat-border" style="bottom: 0;"></div>
<el-col :span="24/configs.length" class="stat-part" v-for="item in configs" :key="item.title">
<div class="title">
<i class="icon" :class="item.icon"></i>
<span>{{item.title}}</span>
</div>
<div class="stat-count" v-for="(cell,index) in item.data" :key="index">
<template v-if="item.type === 'COUNT'">
<div>{{cell.title}}</div>
<div class="number" :class="cell.className" :style="cell.style">{{cell.value}} {{cell.unit}}</div>
</template>
<template v-if="item.type === 'PROGRESS'">
<div :style="item.titleStyle">{{cell.title}}</div>
<div class="progress-wrap">
<Progress :used="cell.used" :total="cell.total" :unit="cell.unit" :color="cell.color"></Progress>
</div>
</template>
</div>
</el-col>
<!-- </dv-border-box-8> -->
</el-row>
</template>
<script>
import Progress from 'components/progress'
export default {
components: { Progress },
props: {
configs: {
type: Array,
required: true
}
}
}
</script>
<style lang="scss" scoped>
.stat-container {
position: relative;
height: 74px;
width: 100%;
background: url('~assets/img/stat_bg.png');
border-bottom: 1px solid #0391d8;
border-top: 1px solid #0391d8;
margin: 10px 0;
.stat-border {
position: absolute;
width: 14px;
height: 2px;
background: #009ce0;
}
.stat-part {
display: flex;
align-items: center;
color: #fff;
height: 72px;
overflow: hidden;
.stat-count {
font-size: 17px;
flex: 1;
padding-left: 20px;
padding-right: 10px;
.number {
font-size: 25px;
font-weight: bold;
&.lgreen {
color: #42edf8;
}
&.green {
color: #39db3c;
}
&.purple {
color: #b34ef9;
}
&.yellow {
color: #ffc400;
}
}
}
.progress-wrap {
margin-top: 10px;
}
.title {
color: #fff;
height: 68px;
display: flex;
justify-content: center;
align-items: center;
font-size: 17px;
width: 140px;
background: #1b3c88;
.icon {
font-size: 28px;
margin-right: 5px;
}
span{
max-width: 90px;
}
}
}
}
</style>

View File

@ -0,0 +1,70 @@
<template>
<div class="outside-header">
<span>
<router-link to="/screen/list" v-if="logo">
<img class="logo" title="返回" :src="logo" alt="">
</router-link>
</span>
<span class="screen-title">
{{title}}
</span>
<span class="time"><span @click="operateScreen" title="全屏">{{currentTime}}</span></span>
</div>
</template>
<script>
import useHeader from 'components/ScreenWrapper/useHeader'
export default {
props: {
code: {
type: String,
required: true
}
},
setup(props, context) {
const { currentTime, operateScreen, logo, title } = useHeader(context.root.$store, props.code)
return {
currentTime,
logo,
title,
operateScreen
}
}
}
</script>
<style lang="scss" scoped>
.outside-header {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 93px;
background: url('~assets/img/header.gif');
background-size: 100% 100%;
display: flex;
& > span {
flex: 1;
}
.logo {
margin-left: 253px;
margin-top: 9px;
}
.screen-title {
text-align: center;
margin-left: 25px;
margin-top: 2px;
font-size: 48px;
color: #6Fffff;
}
.time {
font-size: 18px;
color: #fafbfd;
display: inline-block;
margin-top: 20px;
span {
cursor: pointer;
margin-left: 110px;
}
}
}
</style>

View File

@ -0,0 +1,103 @@
<template>
<full-screen-container class="container" :loading="loading" @getScale="scale => $emit('getScale', scale)">
<div class="header">
<span>
<router-link to="/screen/list" v-if="logo">
<img class="logo" title="返回" :src="logo" alt="">
</router-link>
</span>
<img :src="animateImg" alt="" class="left-animate">
<img :src="animateImg" alt="" class="right-animate">
<span class="screen-title">
{{title}}
</span>
<span class="time"><span @click="operateScreen" title="全屏">{{currentTime}}</span></span>
</div>
<div class="body">
<slot></slot>
</div>
</full-screen-container>
</template>
<script>
import useHeader from './useHeader'
import Header from './Header'
export default {
components: { Header },
props: {
code: {
type: String,
required: true
},
loading: {
type: Boolean,
default: false
}
},
setup(props, context) {
const { currentTime, operateScreen, logo, title } = useHeader(context.root.$store, props.code)
return {
currentTime,
logo,
animateImg: require('assets/img/animate.gif'),
title,
operateScreen
}
}
}
</script>
<style lang="scss" scoped>
.left-animate {
position: absolute;
left: 40px;
top: 100px;
}
.right-animate {
position: absolute;
right: 40px;
top: 100px;
}
.container {
width: 100vw;
height: 100vh;
min-height: 700px;
background: url('~assets/img/screen_bg.png') no-repeat;
background-size: 100% 100%;
overflow: hidden;
.header {
display: flex;
align-items: center;
height: 75px;
& > span {
flex: 1;
}
.logo {
margin-left: 210px;
}
.screen-title {
text-align: center;
margin-left: 25px;
margin-top: -2px;
font-size: 40px;
color: #6fffff;
}
.time {
font-size: 20px;
color: #fafbfd;
display: inline-block;
margin-top: -5px;
span {
cursor: pointer;
margin-left: 140px;
}
}
}
.body {
color: #fff;
padding: 40px 115px;
height: calc(100% - 100px);
box-sizing: border-box;
// display: flex;
}
}
</style>

View File

@ -0,0 +1,27 @@
export function enableFullScreen() {
const docElm = document.documentElement
// W3C
if (docElm.requestFullscreen) {
docElm.requestFullscreen()
} else if (docElm.mozRequestFullScreen) {
// FireFox
docElm.mozRequestFullScreen()
} else if (docElm.webkitRequestFullScreen) {
// Chrome等
docElm.webkitRequestFullScreen()
} else if (docElm.msRequestFullscreen) {
// IE11
document.body.msRequestFullscreen()
}
}
export function disableFullScreen() {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
}
}

View File

@ -0,0 +1,54 @@
import { reactive, toRefs, onUnmounted, ref, computed } from '@vue/composition-api'
import moment from 'moment'
import 'moment/locale/zh-cn'
import { enableFullScreen, disableFullScreen } from './tools'
import { getSystemConfigs } from 'services/system'
export default function (store, code) {
const title = computed(() => {
return store.getters.screenConfigs[code]
})
const state = reactive({
currentTime: ''
})
let timer = null
onUnmounted(() => {
clearInterval(timer)
timer = null
})
function setTimer() {
const getTime = () => {
const time = moment()
state.currentTime = `${time.format('YYYY年MM月DD日 dddd HH:mm:ss')}`;
}
getTime()
timer = setInterval(() => {
getTime()
}, 1000)
}
setTimer();
let isFull = false;
function operateScreen() {
if (isFull) {
disableFullScreen()
} else {
enableFullScreen()
}
isFull = !isFull;
}
// 获取logo
const logo = ref('');
async function getLogo () {
const data = await getSystemConfigs({ codes: 'loginLogo' });
if (data.success) {
logo.value = data.data.loginLogo;
}
}
if (window.configs?.showLogo) getLogo()
return {
...toRefs(state),
logo,
title,
operateScreen
}
}

View File

@ -0,0 +1,38 @@
<template>
<div class="table-td" :title="value" :style="style">
<slot>
<el-tooltip class="item" effect="dark" :content="value.toString()" placement="top-start">
<span>{{value}}</span>
</el-tooltip>
</slot>
</div>
</template>
<script>
import { computed } from '@vue/composition-api'
export default {
props: {
value: {
type: [String, Number],
default: ''
},
width: {
type: String
}
},
setup(props) {
return {
style: props.width ? { width: props.width, flex: 'none' } : {}
}
}
}
</script>
<style lang="scss" scoped>
div.table-td {
flex: 1;
// width: calc(100% / 7);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
padding: 12px 5px;
}
</style>

View File

@ -0,0 +1,88 @@
<template>
<ul class="scroll-table">
<li class="table-header">
<div v-for="(item, index) in columns" :key="item" :title="item" :style="getStyle(index)">
<span>{{item}}</span></div>
</li>
<div class="table-body">
<vueSeamlessScroll :data="data" :class-option="{singleHeight: 43, ...options}">
<li class="table-tr" v-for="(item, index) in data" :key="index">
<slot :row="item"></slot>
</li>
</vueSeamlessScroll>
<NoData v-if="!data.length" ></NoData>
</div>
</ul>
</template>
<script>
import { computed } from '@vue/composition-api'
import vueSeamlessScroll from 'vue-seamless-scroll'
import NoData from '../NoData'
export default {
components: { vueSeamlessScroll, NoData },
props: {
options: {
type: Object,
default: function () {
return {}
}
},
columns: {
type: Array
},
columnWidth: {
type: Array,
default: function() {
return []
}
},
data: {
type: Array
}
},
setup(props) {
const getStyle = index => {
const width = props.columnWidth[index];
return width ? { width: width, flex: 'none' } : {}
}
return {
getStyle
}
}
}
</script>
<style lang="scss" scoped>
.scroll-table {
height: 100%;
color: #fff;
font-size: 12px;
padding: 0;
list-style: none;
.table-header {
background: #152e6a;
color: #fff;
display: flex;
div {
flex: 1;
// width: calc(100% / 7);
padding: 10px 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.table-body {
height: calc(100% - 37px);
overflow: hidden;
.table-tr {
display: flex;
&:nth-child(odd) {
background: #06153b;
}
&:nth-child(even) {
background: rgba(60, 126, 241, 0.2);
}
}
}
}
</style>

View File

@ -0,0 +1,55 @@
<template>
<div class="progress" >
<div class="content" :style="{ background: color, width: `${percent}%` }"></div>
<div class="text">{{percent.toFixed(2)}}%</div>
</div>
</template>
<script>
import { computed } from '@vue/composition-api'
export default {
props: {
percent: {
type: Number
}
},
setup(props) {
const color = computed(() => {
if (props.percent > 90) {
return '#F84540'
} else if (props.percent > 75) {
return '#FF9900'
} else if (props.percent > 50) {
return '#2D8CF0'
}
return '#19BE6B'
})
return {
color
}
}
}
</script>
<style lang="scss" scoped>
.progress {
width: 100%;
height: 12px;
position: relative;
background: #061330;
.content {
background: #19BE6B;
position: absolute;
top: 0;
left: 0;
height: 12px;
}
.text {
position: absolute;
right: 0;
top: -2px;
// margin-right: 2px;
font-size: 8px;
font-family: Microsoft YaHei;
color: #fff;
}
}
</style>

View File

@ -0,0 +1,172 @@
<template>
<div id="mountNode" style="height: 100%; width: 100%"></div>
</template>
<script>
import G6 from '@antv/g6';
import registerDefault from './registerDefault';
export default {
props: {
defaultEdgeType: {
type: String
},
defaultNodeType: {
type: String,
default: 'circle'
},
//
options: {
type: Object,
default: function() {
return {};
}
},
data: {
type: Object,
default: function() {
return {};
}
},
layout: {
type: Object
}
},
data() {
return {
graph: null,
currentLayout: ''
};
},
created() {
registerDefault(G6, this.defaultNodeType, this.defaultEdgeType);
},
mounted() {
this.initGraph();
window.addEventListener('resize', this.changeSize);
},
beforeUnmount() {
window.removeEventListener('resize', this.changeSize);
},
watch: {
data() {
if (this.graph) {
this.graph.changeData(this.data);
}
}
},
methods: {
initGraph() {
const target = document.getElementById('mountNode');
// const minimap = new G6.Minimap(this.minimapConfig);
// grid
const options = {
// plugins: [grid], // minimap
modes: {
default: [
'drag-canvas',
'zoom-canvas',
'drag-node',
'drag-combo'
// {
// type: 'tooltip', //
// formatText:
// this.tipFormat ||
// function(model) {
// //
// const text = [];
// text.push(`<div>${model.label}</div>`);
// return text.join('');
// },
// offset: 60
// }
] //
},
// fitCenter: true,
container: 'mountNode', // String | HTMLElement Step 1 id
width: target.offsetWidth, // Number
height: target.offsetHeight, // Number
defaultNode: {
type: 'image',
size: [60],
color: '#ffffff',
style: {
fill: '#9EC9FF',
lineWidth: 1
},
labelCfg: {
style: {
fill: '#ffffff',
fontSize: 12
},
position: 'bottom'
}
},
defaultEdge: {
type: 'circle-running',
style: {
stroke: '#7ECEF4',
lineWidth: 2
}
},
groupByTypes: false,
defaultCombo: {
type: 'rect',
padding: [40, 40, 40, 40],
style: {
fill: '#112A51',
stroke: '#112A51',
radius: 4
},
labelCfg: {
refY: 20,
refX: 20,
position: 'top',
style: {
fill: '#ffffff',
fontSize: 15
}
}
},
layout: this.layout
};
const graph = new G6.Graph(options);
this.graph = graph;
graph.read(this.data);
this.bindEvent();
},
save () {
const data = this.graph.save();
return data;
},
itemClick(evt, type) {
const { clientX, clientY, item } = evt;
const params = {
x: clientX, y: clientY, item: item.getModel()
}
this.$emit(type, params)
},
bindEvent() {
this.graph.on('node:click', evt => {
this.itemClick(evt, 'nodeClick')
});
this.graph.on('edge:click', evt => {
this.itemClick(evt, 'edgeClick')
});
this.graph.on('canvas:click', evt => {
this.$emit('canvasClick')
});
},
changeSize() {
setTimeout(() => {
const target = document.getElementById('mountNode');
const width = target.offsetWidth;
const height = target.offsetHeight;
this.graph.changeSize(width, height);
}, 1000);
}
}
};
</script>
<style lang="scss">
</style>

View File

@ -0,0 +1,129 @@
export default function registerDefault(
G6,
nodeType = 'circle',
lineType = 'quadratic'
) {
G6.registerNode(
'background-animate',
{
afterDraw(cfg, group) {
const r = cfg.size / 2;
const back1 = group.addShape('circle', {
zIndex: -3,
attrs: {
x: 0,
y: 0,
r,
fill: cfg.color,
opacity: 0.6
},
name: 'back1-shape'
});
const back2 = group.addShape('circle', {
zIndex: -2,
attrs: {
x: 0,
y: 0,
r,
fill: cfg.color,
opacity: 0.6
},
name: 'back2-shape'
});
const back3 = group.addShape('circle', {
zIndex: -1,
attrs: {
x: 0,
y: 0,
r,
fill: cfg.color,
opacity: 0.6
},
name: 'back3-shape'
});
group.sort(); // Sort according to the zIndex
back1.animate(
{
// Magnifying and disappearing
r: r + 10,
opacity: 0.1
},
{
duration: 3000,
easing: 'easeCubic',
delay: 0,
repeat: true // repeat
}
); // no delay
back2.animate(
{
// Magnifying and disappearing
r: r + 10,
opacity: 0.1
},
{
duration: 3000,
easing: 'easeCubic',
delay: 1000,
repeat: true // repeat
}
); // 1s delay
back3.animate(
{
// Magnifying and disappearing
r: r + 10,
opacity: 0.1
},
{
duration: 3000,
easing: 'easeCubic',
delay: 2000,
repeat: true // repeat
}
); // 3s delay
}
},
'image'
);
G6.registerEdge(
'circle-running',
{
afterDraw(cfg, group) {
// 获得当前边的第一个图形,这里是边本身的 path
const shape = group.get('children')[0];
// 边 path 的起点位置
const startPoint = shape.getPoint(0);
// 添加红色 circle 图形
const circle = group.addShape('circle', {
attrs: {
x: startPoint.x,
y: startPoint.y,
fill: '#29EEF7',
r: 3
},
name: 'circle-shape'
});
// 对红色圆点添加动画
circle.animate(
ratio => {
// 每一帧的操作,入参 ratio这一帧的比例值Number。返回值这一帧需要变化的参数集Object
// 根据比例值,获得在边 path 上对应比例的位置。
const tmpPoint = shape.getPoint(ratio);
// 返回需要变化的参数集,这里返回了位置 x 和 y
return {
x: tmpPoint.x,
y: tmpPoint.y
};
},
{
repeat: true, // 动画重复
duration: 3000 // 一次动画的时间长度
}
);
}
},
lineType
);
}

View File

@ -0,0 +1,76 @@
<template>
<bar-chart v-bind="$attrs"
:setting="configs"
></bar-chart>
</template>
<script>
import charts from 'cmp-echarts'
const { BarCharts } = charts
export default {
components: { BarChart: BarCharts },
props: {
setting: {
type: Object,
default() {
return {}
}
}
},
setup(props, context) {
const { rotate = 0 } = props.setting
const configs = {
series: {
label: {
show: true,
color: '#fff',
position: 'top'
}
},
legend: {
textStyle: {
color: '#fff'
},
pageIconColor: '#fff',
pageIconInactiveColor: '#2F4554'
},
xAxis: {
axisLabel: {
color: '#fff',
interval: 0,
rotate
},
axisLine: {
lineStyle: {
color: '#ffffff'
}
},
splitArea: {
show: false
}
},
yAxis: {
axisLabel: {
color: '#fff'
},
nameTextStyle: {
color: '#fff'
},
axisLine: {
lineStyle: {
color: '#ffffff'
}
},
splitLine: {
lineStyle: {
type: 'solid',
color: '#1B263D'
}
}
}
}
return {
configs
}
}
}
</script>

View File

@ -0,0 +1,60 @@
<template>
<bar-reverse-chart v-bind="$attrs"
:setting="configs"
></bar-reverse-chart>
</template>
<script>
import charts from 'cmp-echarts'
const { BarReverseCharts } = charts
const configs = {
series: {
label: {
show: true,
formatter: '{b}',
color: '#fff',
position: [10, -20]
}
},
legend: {
textStyle: {
color: '#fff'
}
},
xAxis: {
axisLabel: {
color: '#fff',
interval: 0
},
axisLine: {
lineStyle: {
color: '#ffffff'
}
},
splitArea: {
show: false
}
},
yAxis: {
axisLine: { show: false },
axisLabel: { show: false },
axisTick: { show: false },
splitLine: { show: false }
}
}
export default {
components: { BarReverseChart: BarReverseCharts },
props: {
setting: {
type: Object,
default() {
return {}
}
}
},
setup(props, context) {
return {
configs
}
}
}
</script>

View File

@ -0,0 +1,60 @@
<template>
<line-chart v-bind="$attrs"
:setting="setting"
></line-chart>
</template>
<script>
import charts from 'cmp-echarts'
import 'cmp-echarts/lib/cmp-echarts.css'
const { LineCharts } = charts
const setting = {
legend: {
textStyle: {
color: '#fff'
},
pageIconColor: '#fff',
pageIconInactiveColor: '#2F4554'
},
xAxis: {
axisLabel: {
color: '#fff'
},
axisLine: {
lineStyle: {
color: '#ffffff'
}
},
splitArea: {
show: false
}
},
yAxis: {
axisLabel: {
color: '#fff'
},
nameTextStyle: {
color: '#fff'
},
axisLine: {
lineStyle: {
color: '#ffffff'
}
},
splitLine: {
lineStyle: {
type: 'solid',
color: '#1B263D'
}
}
}
}
export default {
components: { LineChart: LineCharts },
setup(props, context) {
return {
setting
}
}
}
</script>

View File

@ -0,0 +1,72 @@
<template>
<pie-chart v-bind="$attrs"
:setting="setting"
></pie-chart>
</template>
<script>
import charts from 'cmp-echarts'
import { computed } from '@vue/composition-api'
const { PieCharts } = charts
export default {
props: {
configs: {
type: Object,
default() {
return {}
}
}
},
components: { PieChart: PieCharts },
setup(props, context) {
console.log(context)
const setting = computed(() => {
const { attrs: { data = [] } } = context;
const total = data.reduce((total, item) => {
return total + item.value / 1
}, 0)
return {
legend: {
textStyle: {
rich: {
name: {
align: 'left',
color: '#fff',
width: 50
},
count: {
align: 'right',
color: '#fff',
width: 50,
fontWeight: 600
}
}
}
},
series: {
label: {
show: true,
position: 'center',
formatter: function() {
return `{count|总数\r\n\r\n${total}}`
},
textStyle: {
color: '#fff'
},
rich: {
count: {
fontSize: 19,
color: '#fff'
}
}
},
itemStyle: {}
},
...props.configs
}
})
return {
setting
}
}
}
</script>

View File

@ -0,0 +1,191 @@
<template>
<div :style="{height:height,width:width}" class="chart-container">
<div class="chart" :class="{hide: isNoData}" :id="id" style="width: 100%;height: 100%"></div>
<NoData v-show="isNoData" class="chart-no-data"></NoData>
</div>
</template>
<script>
import mixins, { getLinerColor } from '../mixins'
import { yAxis, xAxis, grid } from '../defaultSetting'
import Axios from 'axios'
export default {
props: {
is3d: {
type: Boolean,
default: false
}
},
mixins: [mixins],
data () {
return {}
},
computed: {
isNoData() {
return !this.data.keys || !this.data.keys.length;
}
},
mounted () {
this.eveSet()
},
methods: {
//
eveSet () {
this.chart.on('click', (params) => {
const event = params.event.event
event.stopPropagation()
this.$emit('goToPage', params)
})
},
updateChart () {
const legends = []
const series = []
const { colorMap = {}, linerColor, axisLabel = {}, showSeriesLabel = true } = this.setting;
const color = (linerColor && linerColor.map(item => {
return getLinerColor(item[0], item[1])
}));
// [getLinerColor('#0089FF', '#A057A1')];
const { values = [], keys = [] } = this.data;
const { showLegend = false } = this.setting;
values.forEach((item, index) => {
legends.push(item.name)
const data = item.data.map(cell => {
return {
value: cell,
itemStyle: {
color: colorMap[item.name]
}
}
})
series.push({
name: item.name,
type: 'bar',
smooth: true,
stack: 'all',
barMaxWidth: 30,
label: {
show: showSeriesLabel,
position: 'top',
color: '#fff'
},
itemStyle: {
// normal: {
// areaStyle: { type: 'default' },
// color: new this.echarts.graphic.LinearGradient(
// 0, 0, 1, 1, [{
// offset: 0,
// color: startColor
// },
// {
// offset: 1,
// color: endColor
// }
// ]
// )
// }
},
data,
zlevel: 11
});
if (this.is3d) {
series.push({
type: 'bar',
barWidth: 8,
itemStyle: {
normal: {
color
}
},
barGap: 0,
data
}, {
name: 'b',
tooltip: {
show: false
},
type: 'pictorialBar',
itemStyle: {
borderWidth: 1,
borderColor: color[0],
color: color[0]
},
symbol: 'path://M 0,0 l 120,0 l -30,60 l -120,0 z',
symbolSize: ['30', '12'],
symbolOffset: ['0', '-8'],
symbolRotate: 5,
symbolPosition: 'end',
data,
z: 3
})
}
})
const options = {
color,
legend: {
show: showLegend,
top: 0,
textStyle: {
color: '#fff'
}
},
title: {
text: this.data.title
},
tooltip: {
trigger: 'axis',
...(this.setting.tooltip || {})
},
toolbox: this.setting.toolbox,
grid: {
...grid,
top: 30,
left: '1%',
right: '5%',
bottom: 1
},
xAxis: [{
...xAxis,
type: 'category',
name: this.unit,
splitLine: {
show: false
},
axisLabel: {
color: '#fff',
interval: 0,
...axisLabel
},
axisTick: {
show: false
},
data: this.data.keys.map(item => {
return item.replace(' ', '\n')
})
}],
yAxis: [{
...yAxis,
type: 'value',
splitLine: {
show: false
},
axisLabel: {
color: '#fff'
},
splitArea: {
show: false,
areaStyle: {
color: ['rgba(255,255,255,1)', 'rgba(248,251,255,1)']
}
}
}],
series: series
}
this.chart.setOption(options, true)
}
}
}
</script>
<style lang="scss" scoped>
@import '../index';
</style>

View File

@ -0,0 +1,2 @@
import BarCharts from './BarCharts.vue';
export default BarCharts;

View File

@ -0,0 +1,114 @@
<template>
<div :class="className" :id="id" :style="{height:height,width:width}"></div>
</template>
<script>
import mixins, { getLinerColor } from '../mixins'
import { yAxis, xAxis, grid } from '../defaultSetting'
export default {
mixins: [mixins],
data () {
return {}
},
mounted () {
this.eveSet()
},
methods: {
//
eveSet () {
this.chart.on('click', (params) => {
const event = params.event.event
event.stopPropagation()
this.$emit('goToPage', params)
})
},
updateChart () {
const legends = []
const series = []
const { barColor: [startColor = '#8699FF', endColor = '#4B66FF'] = [], yAxisLabel = {}, showXAxis = true } = this.setting;
this.data.values.forEach(item => {
legends.unshift(item.name)
series.push({
name: item.name,
type: 'bar',
smooth: true,
stack: 'all',
barMaxWidth: 11,
itemStyle: {
normal: {
// barBorderRadius: 5,
areaStyle: { type: 'default' },
color: getLinerColor(startColor, endColor)
}
},
data: item.data.reverse(),
zlevel: 11
})
})
const options = {
color: this.setting.color,
title: {
text: this.data.title
},
tooltip: {
trigger: 'axis'
},
toolbox: this.setting.toolbox,
grid: {
...grid,
top: 10,
left: '1%',
right: '5%'
},
xAxis: [{
show: showXAxis,
...xAxis,
type: 'value',
name: this.unit,
splitLine: {
show: false
},
axisTick: {
show: false
},
splitArea: {
show: false,
areaStyle: {
color: ['rgba(255,255,255,1)', 'rgba(248,251,255,1)']
}
},
axisLabel: {
color: '#fff'
}
}],
yAxis: [{
...yAxis,
type: 'category',
data: this.data.keys.map(item => {
return item.replace(' ', '\n')
}),
axisLine: {
show: false
},
splitLine: {
show: false
},
axisLabel: {
color: '#ffffff',
...yAxisLabel
},
splitArea: {
show: true,
areaStyle: {
color: ['rgba(0,0,0,0.0)', 'rgba(250,250,250,0.05)']
}
}
}],
series: series
}
this.chart.setOption(options, true)
}
}
}
</script>

View File

@ -0,0 +1,2 @@
import BarReverseCharts from './BarReverseCharts.vue';
export default BarReverseCharts;

View File

@ -0,0 +1,51 @@
export const legend = {
type: 'scroll',
itemWidth: 12,
itemHeight: 12,
icon: 'roundRect',
padding: [0, 20],
textStyle: {
color: '##999999'
}
};
export const grid = {
left: 1,
right: 1,
top: 30,
bottom: 1,
containLabel: true
};
export const yAxis = {
type: 'value',
nameGap: 5,
min: 0,
splitLine: {
lineStyle: {
color: ['#ebebeb'],
type: 'dashed'
}
},
axisLine: {
lineStyle: {
color: ['#d9d9d9']
}
},
axisTick: {
show: false
}
};
export const xAxis = {
axisLine: {
lineStyle: {
color: ['#d9d9d9']
}
},
axisTick: {
show: false
}
};
export const toolbox = {
feature: {
saveAsImage: {}
}
};

View File

@ -0,0 +1,66 @@
<template>
<div :class="className" :style="{height:height,width:width}" :id="id"></div>
</template>
<script>
import mixins from '../mixins';
export default {
mixins: [mixins],
data () {
return {};
},
methods: {
updateChart () {
const series = [];
series.push(
{
type: 'gauge',
center: ['50%', '55%'],
radius: '90%',
// min: this.data.min,
// max: this.data.max,
axisLine: { // 线
lineStyle: { // lineStyle线
width: 5
}
},
axisTick: { //
length: 15, // length线
lineStyle: { // lineStyle线
color: 'auto'
}
},
splitLine: { // 线
length: 10, // length线
lineStyle: { // lineStylelineStyle线
color: 'auto'
}
},
title: {
// 使TEXTSTYLE
fontWeight: 'bolder',
fontSize: 18,
color: '#fff'
},
axisLabel: {
fontSize: 8
},
detail: {
fontSize: 16
},
data: this.data
}
);
const options = {
tooltip: {
formatter: '{a} <br/>{c} {b}'
},
toolbox: this.setting.toolbox,
series: series
};
this.chart.setOption(options, true);
}
}
};
</script>

View File

@ -0,0 +1,5 @@
/**
* Created by Zhang Haijun on 2018/6/14.
*/
import GaugeCharts from './GaugeCharts.vue';
export default GaugeCharts;

View File

@ -0,0 +1,106 @@
<template>
<div :class="className" :id="id" :style="{height:height,width:width}"></div>
</template>
<script>
import mixins from '../mixins';
export default {
mixins: [mixins],
watch: {},
data () {
return {
chart: null
};
},
mounted () {
this.eveSet();
},
methods: {
//
hideOperate () {
const targetArr = document.getElementsByClassName('operate-node-menu');
for (const item of targetArr) {
item.style.display = 'none';
}
},
//
eveSet () {
this.chart.on('mouseup', (params) => {
if (params.dataType == 'edge') return;
const event = params.event.event;
event.stopPropagation();
if (event.button == 2) {
this.hideOperate();
this.$emit('mouseup', params);
}
});
const self = this;
document.addEventListener('click', function (event) {
event.stopPropagation();
self.hideOperate();
});
document.oncontextmenu = function () {
return false;
};
},
updateChart () {
const options = {
animationDuration: 100,
animationDurationUpdate: 300,
animationEasingUpdate: 'quinticInOut',
toolbox: this.setting.toolbox,
series: [
{
type: 'graph',
layout: 'force',
draggable: true,
symbolSize: 50,
roam: true, //
edgeSymbol: ['circle', 'none'],
edgeSymbolSize: [0, 10],
focusNodeAdjacency: true, //
lineStyle: {
normal: {
opacity: 1,
width: 1,
curveness: 0
}
},
label: {
normal: {
position: this.setting.labelPosition || 'bottom',
show: true,
textStyle: {
fontSize: 12
}
}
},
force: {
layoutAnimation: true, //
repulsion: [1000, 1200], //
edgeLength: [150, 200]//
},
edgeLabel: {
normal: {
show: true,
textStyle: {
fontSize: 12
},
formatter: '{c}',
backgroundColor: '#fff',
padding: 5,
color: '#4b59fd',
borderRadius: 3
}
},
data: this.data.nodes,
links: this.data.links
}
]
};
this.chart.setOption(options, true);
}
}
};
</script>

View File

@ -0,0 +1,2 @@
import GraphCharts from './GraphCharts.vue';
export default GraphCharts;

Some files were not shown because too many files have changed in this diff Show More