imatrix-ui 2.9.99 → 7.7.20-p2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/super-ui.css +1 -1
- package/lib/super-ui.umd.min.js +13 -6
- package/package.json +3 -2
- package/src/api/sso-service.js +12 -1
- package/src/directives/permission/permission.js +1 -1
- package/src/i18n/langs/cn.js +64 -3
- package/src/i18n/langs/en.js +65 -4
- package/src/permission.js +16 -22
- package/src/router/index.js +18 -1
- package/src/store/getters.js +2 -1
- package/src/store/modules/user.js +16 -1
- package/src/styles/index.scss +11 -2
- package/src/utils/calculator/calculator-factory.js +125 -0
- package/src/utils/calculator/calculator-util.js +6 -0
- package/src/utils/common-util.js +21 -1
- package/src/utils/eventBus.js +2 -0
- package/src/utils/iconUtils.js +23 -0
- package/src/utils/jump-page-utils.js +467 -0
- package/src/utils/permission.js +1 -1
- package/src/utils/permissionAuth.js +1 -1
- package/src/utils/request.js +4 -2
- package/src/utils/restful-interface-utils.js +47 -0
- package/src/utils/util.js +451 -0
- package/src/utils/watermark.js +95 -0
- package/src/views/layout/NewLayout.vue +77 -0
- package/src/views/layout/components/AppMain.vue +9 -0
- package/src/views/layout/components/Breadcrumb/index.vue +33 -1
- package/src/views/layout/components/Menubar/Item.vue +46 -0
- package/src/views/layout/components/Menubar/Link.vue +31 -0
- package/src/views/layout/components/Menubar/SidebarItem.vue +101 -0
- package/src/views/layout/components/Menubar/index.vue +143 -0
- package/src/views/layout/components/iframe-page.vue +31 -0
- package/src/views/layout/components/index.js +1 -0
- package/src/views/redirect/index.vue +3 -3
- package/src/views/wf-history/tache-subprocess-history.vue +45 -0
|
@@ -66,10 +66,12 @@ export default {
|
|
|
66
66
|
selectMenu = cookieMenu
|
|
67
67
|
}
|
|
68
68
|
if (selectMenu) {
|
|
69
|
+
// 解决表单页面无法获得列表路由
|
|
69
70
|
const path = selectMenu.substring(0, selectMenu.indexOf('~~'))
|
|
70
71
|
const title = selectMenu.substring(selectMenu.indexOf('~~') + 2)
|
|
71
72
|
if (matched && matched.length > 0) {
|
|
72
|
-
|
|
73
|
+
const lastRoute = matched[matched.length - 1]
|
|
74
|
+
if (this.isShouldConcatLastMenu(title, path, lastRoute)) {
|
|
73
75
|
matched.push({ path: path, meta: { title: title }})
|
|
74
76
|
}
|
|
75
77
|
} else {
|
|
@@ -78,6 +80,36 @@ export default {
|
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
82
|
this.levelList = matched
|
|
83
|
+
},
|
|
84
|
+
// 新建页面时会把列表页面路由刷没,导致菜单路径缺少最后一层菜单问题
|
|
85
|
+
isShouldConcatLastMenu(title, path, lastRoute) {
|
|
86
|
+
if (this.isTitleNotEqual(title, lastRoute) && this.isPathNotEqual(path, lastRoute)) {
|
|
87
|
+
// title和path都不同,表示是不同的页面,需要添加到matched集合中
|
|
88
|
+
return true
|
|
89
|
+
}
|
|
90
|
+
return false
|
|
91
|
+
},
|
|
92
|
+
/**
|
|
93
|
+
* Vue.prototype._selectMenu的菜单标题是否与最后的路由页面标题一致
|
|
94
|
+
* 返回true表示不一样,返回false表示一样
|
|
95
|
+
*/
|
|
96
|
+
isTitleNotEqual(title, lastRoute) {
|
|
97
|
+
if (title && lastRoute.meta && (title !== lastRoute.meta.title && title !== this.$t(lastRoute.meta.title))) {
|
|
98
|
+
// 表示title不一样,当前可能是在表单页面,需要添加到matched集合中
|
|
99
|
+
return true
|
|
100
|
+
}
|
|
101
|
+
return false
|
|
102
|
+
},
|
|
103
|
+
/**
|
|
104
|
+
* Vue.prototype._selectMenu的菜单的访问路径是否与最后的路由页面的路径一致
|
|
105
|
+
* 返回true表示不一样,返回false表示一样
|
|
106
|
+
*/
|
|
107
|
+
isPathNotEqual(path, lastRoute) {
|
|
108
|
+
if (path && lastRoute.path && path !== lastRoute.path) {
|
|
109
|
+
// 表示path不一样,当前可能是在表单页面,需要添加到matched集合中
|
|
110
|
+
return true
|
|
111
|
+
}
|
|
112
|
+
return false
|
|
81
113
|
}
|
|
82
114
|
}
|
|
83
115
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export default {
|
|
3
|
+
name: 'MenuItem',
|
|
4
|
+
functional: true,
|
|
5
|
+
props: {
|
|
6
|
+
icon: {
|
|
7
|
+
type: String,
|
|
8
|
+
default: ''
|
|
9
|
+
},
|
|
10
|
+
title: {
|
|
11
|
+
type: String,
|
|
12
|
+
default: ''
|
|
13
|
+
},
|
|
14
|
+
hasChildren: {
|
|
15
|
+
type: Boolean,
|
|
16
|
+
default: false
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
render(h, context) {
|
|
20
|
+
let icon = context.props.icon
|
|
21
|
+
const { title, hasChildren } = context.props
|
|
22
|
+
const vnodes = []
|
|
23
|
+
|
|
24
|
+
if (icon) {
|
|
25
|
+
if (icon.indexOf('fa-') === 0) {
|
|
26
|
+
// 表示以“fa-”开头,使用font-awesome中的图标
|
|
27
|
+
icon = 'fa ' + icon
|
|
28
|
+
}
|
|
29
|
+
icon += ' svg-icon'
|
|
30
|
+
vnodes.push(<div style='display: inline-block;'><i class={icon}/></div>)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (title) {
|
|
34
|
+
let width = '130px'
|
|
35
|
+
if (hasChildren) {
|
|
36
|
+
// 当是父菜单时,为了使后面的三角能显示出来,需要将宽度设小点
|
|
37
|
+
width = '100px'
|
|
38
|
+
}
|
|
39
|
+
vnodes.push(<div slot='title' style='display: inline-block'>
|
|
40
|
+
<div title={title} style={'display: inline-block;width:' + width + ';overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-break:keep-all;'}>{(title)}</div>
|
|
41
|
+
</div>)
|
|
42
|
+
}
|
|
43
|
+
return vnodes
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
</script>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
<template>
|
|
3
|
+
<div>
|
|
4
|
+
<!-- eslint-disable vue/require-component-is-->
|
|
5
|
+
<!-- <a v-if="isExter" :href="to.path" target="_blank" rel="noopener">
|
|
6
|
+
<slot />
|
|
7
|
+
</a> -->
|
|
8
|
+
|
|
9
|
+
<router-link :to="to">
|
|
10
|
+
<slot />
|
|
11
|
+
</router-link>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script>
|
|
16
|
+
|
|
17
|
+
export default {
|
|
18
|
+
props: {
|
|
19
|
+
to: {
|
|
20
|
+
type: Object,
|
|
21
|
+
required: true
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
data() {
|
|
25
|
+
const isExter = this.to.isExternal
|
|
26
|
+
return {
|
|
27
|
+
isExter
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
</script>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="menu-wrapper">
|
|
3
|
+
<template v-if="!item.children || item.children.lenght === 0">
|
|
4
|
+
<app-link :to="toPath(item)">
|
|
5
|
+
<el-menu-item :index="item.fullPath+'~~'+item.i18nValue" :class="{'submenu-title-noDropdown':!isNest}">
|
|
6
|
+
<item :icon="item.iconName" :title="item.i18nValue" />
|
|
7
|
+
</el-menu-item>
|
|
8
|
+
</app-link>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<el-submenu v-else :index="item.fullPath+'~~'+item.i18nValue">
|
|
12
|
+
<template slot="title">
|
|
13
|
+
<item :icon="item.iconName" :title="item.i18nValue" :has-children="item.children.length > 0?true:false" />
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<template v-for="child in item.children">
|
|
17
|
+
<sidebar-item
|
|
18
|
+
v-if="child.children&&child.children.length>0"
|
|
19
|
+
:key="child.code"
|
|
20
|
+
:is-nest="true"
|
|
21
|
+
:item="child"
|
|
22
|
+
class="nest-menu"
|
|
23
|
+
/>
|
|
24
|
+
<app-link v-else :key="child.code" :to="toPath(child)">
|
|
25
|
+
<el-menu-item :index="child.fullPath+'~~'+child.i18nValue">
|
|
26
|
+
<item :icon="child.iconName" :title="child.i18nValue" />
|
|
27
|
+
</el-menu-item>
|
|
28
|
+
</app-link>
|
|
29
|
+
</template>
|
|
30
|
+
</el-submenu>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script>
|
|
35
|
+
import Item from './Item'
|
|
36
|
+
import AppLink from './Link'
|
|
37
|
+
|
|
38
|
+
export default {
|
|
39
|
+
name: 'SidebarItem',
|
|
40
|
+
components: { Item, AppLink },
|
|
41
|
+
props: {
|
|
42
|
+
// route object
|
|
43
|
+
item: {
|
|
44
|
+
type: Object,
|
|
45
|
+
required: true
|
|
46
|
+
},
|
|
47
|
+
isNest: {
|
|
48
|
+
type: Boolean,
|
|
49
|
+
default: false
|
|
50
|
+
},
|
|
51
|
+
basePath: {
|
|
52
|
+
type: String,
|
|
53
|
+
default: ''
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
data() {
|
|
57
|
+
return {
|
|
58
|
+
onlyOneChild: null
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
methods: {
|
|
62
|
+
hasOneShowingChild(children, parent) {
|
|
63
|
+
if (children && children.length > 0) {
|
|
64
|
+
this.onlyOneChild = children[0]
|
|
65
|
+
}
|
|
66
|
+
// When there is only one child router, the child router is displayed by default
|
|
67
|
+
if (children.length === 1) {
|
|
68
|
+
return true
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Show parent if there are no child router to display
|
|
72
|
+
if (!children || children.length === 0) {
|
|
73
|
+
// children不存在
|
|
74
|
+
this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
|
|
75
|
+
return true
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return false
|
|
79
|
+
},
|
|
80
|
+
toPath(menu) {
|
|
81
|
+
const toPathObj = {}
|
|
82
|
+
const routePath = menu.fullPath
|
|
83
|
+
if (this.isExternalLink(menu.pageType)) {
|
|
84
|
+
toPathObj.path = '/iframe-page/page'
|
|
85
|
+
toPathObj.query = {}
|
|
86
|
+
toPathObj.query.src = routePath
|
|
87
|
+
toPathObj.isExternal = true
|
|
88
|
+
} else {
|
|
89
|
+
toPathObj.path = routePath
|
|
90
|
+
}
|
|
91
|
+
return toPathObj
|
|
92
|
+
},
|
|
93
|
+
isExternalLink(pageType) {
|
|
94
|
+
if (pageType && pageType === 'iframe') {
|
|
95
|
+
return true
|
|
96
|
+
}
|
|
97
|
+
return false
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
</script>
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<el-scrollbar wrap-class="scrollbar-wrapper">
|
|
4
|
+
<el-menu
|
|
5
|
+
:show-timeout="200"
|
|
6
|
+
:default-active="defaultActive?defaultActive:''"
|
|
7
|
+
:collapse="isCollapse"
|
|
8
|
+
mode="vertical"
|
|
9
|
+
@select="selectMenu"
|
|
10
|
+
>
|
|
11
|
+
<el-menu-item v-if="systemName" :title="systemName" index="1" disabled class="system-item" style="padding-left: 10px">
|
|
12
|
+
{{ systemName }}
|
|
13
|
+
</el-menu-item>
|
|
14
|
+
<sidebar-item v-for="menu in menus" :key="menu.code" :item="menu" />
|
|
15
|
+
</el-menu>
|
|
16
|
+
</el-scrollbar>
|
|
17
|
+
<hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script>
|
|
22
|
+
import { mapGetters } from 'vuex'
|
|
23
|
+
import SidebarItem from './SidebarItem'
|
|
24
|
+
import Vue from 'vue'
|
|
25
|
+
import { getLanguageWithLocale } from '../../../../utils/util'
|
|
26
|
+
import { isShowSystemMenu } from '../../../../utils/common-util'
|
|
27
|
+
import Cookies from 'js-cookie'
|
|
28
|
+
export default {
|
|
29
|
+
name: 'Menubar',
|
|
30
|
+
components: {
|
|
31
|
+
SidebarItem
|
|
32
|
+
},
|
|
33
|
+
data() {
|
|
34
|
+
let systemName
|
|
35
|
+
if (isShowSystemMenu() === true) {
|
|
36
|
+
const language = getLanguageWithLocale()
|
|
37
|
+
const systemNameObj = Vue.prototype.systemNameObj
|
|
38
|
+
if (systemNameObj) {
|
|
39
|
+
systemName = systemNameObj[language]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
firstLeafMenu: null, // 第一个有权限的叶子菜单,用于默认展开第一个父菜单
|
|
44
|
+
systemName,
|
|
45
|
+
defaultActive: ''
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
computed: {
|
|
49
|
+
...mapGetters([
|
|
50
|
+
'sidebar',
|
|
51
|
+
'menus'
|
|
52
|
+
]),
|
|
53
|
+
isCollapse() {
|
|
54
|
+
return !this.sidebar.opened
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
watch: {
|
|
58
|
+
$route() {
|
|
59
|
+
this.firstLeafMenu = this.getFirstMenu(this.menus)
|
|
60
|
+
if (this.firstLeafMenu) {
|
|
61
|
+
// Breadcrumb组件需要使用Vue.prototype._selectMenu的值,格式为:fullPath~~title
|
|
62
|
+
this.defaultActive = this.firstLeafMenu.fullPath + '~~' + this.firstLeafMenu.i18nValue
|
|
63
|
+
Vue.prototype._selectMenu = this.defaultActive
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
created() {
|
|
68
|
+
this.firstLeafMenu = this.getFirstMenu(this.menus)
|
|
69
|
+
if (this.firstLeafMenu) {
|
|
70
|
+
// Breadcrumb组件需要使用Vue.prototype._selectMenu的值,格式为:fullPath~~title
|
|
71
|
+
this.defaultActive = this.firstLeafMenu.fullPath + '~~' + this.firstLeafMenu.i18nValue
|
|
72
|
+
Vue.prototype._selectMenu = this.defaultActive
|
|
73
|
+
}
|
|
74
|
+
if (this.firstLeafMenu && this.firstLeafMenu.fullPath) {
|
|
75
|
+
// 跳转到第一个页面
|
|
76
|
+
if (this.firstLeafMenu.pageType && this.firstLeafMenu.pageType === 'iframe') {
|
|
77
|
+
const iframeSrc = this.firstLeafMenu.fullPath
|
|
78
|
+
this.$router.push({ path: '/iframe-page/page', query: { src: iframeSrc }})
|
|
79
|
+
} else {
|
|
80
|
+
this.$router.push({ path: this.firstLeafMenu.fullPath })
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
methods: {
|
|
85
|
+
toggleSideBar() {
|
|
86
|
+
this.$store.dispatch('toggleSidebar')
|
|
87
|
+
},
|
|
88
|
+
selectMenu(index, indexPath) {
|
|
89
|
+
Vue.prototype._selectMenu = index
|
|
90
|
+
Cookies.set('selectMenu', index)
|
|
91
|
+
},
|
|
92
|
+
getFirstMenu(menus) {
|
|
93
|
+
if (menus && menus.length > 0) {
|
|
94
|
+
let shouldSelectMenu
|
|
95
|
+
for (let i = 0; i < menus.length; i++) {
|
|
96
|
+
const menu = menus[i]
|
|
97
|
+
shouldSelectMenu = this.getShouldSelectMenu(menu)
|
|
98
|
+
if (shouldSelectMenu) {
|
|
99
|
+
// 表示获得到了应该选中的菜单
|
|
100
|
+
break
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (!shouldSelectMenu) {
|
|
104
|
+
// 如果没有获得默认选中的菜单,则默认选中第一个菜单
|
|
105
|
+
shouldSelectMenu = this.getSelectMenuWithFirstMenu(menus[0])
|
|
106
|
+
}
|
|
107
|
+
return shouldSelectMenu
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
getShouldSelectMenu(menu) {
|
|
111
|
+
if (menu) {
|
|
112
|
+
const cookieMenu = Cookies.get('selectMenu')
|
|
113
|
+
let currentRoute = this.$route.path
|
|
114
|
+
if (cookieMenu && cookieMenu.indexOf('~~') > 0) {
|
|
115
|
+
// cookie中记录了选中的菜单路径
|
|
116
|
+
const path = cookieMenu.substring(0, cookieMenu.lastIndexOf('~~'))
|
|
117
|
+
currentRoute = path
|
|
118
|
+
}
|
|
119
|
+
let shouldSelectMenu
|
|
120
|
+
const children = menu.children
|
|
121
|
+
if (children && children.length > 0) {
|
|
122
|
+
shouldSelectMenu = this.getFirstMenu(children)
|
|
123
|
+
} else if (menu.fullPath && menu.fullPath === currentRoute) {
|
|
124
|
+
shouldSelectMenu = menu
|
|
125
|
+
}
|
|
126
|
+
return shouldSelectMenu
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
getSelectMenuWithFirstMenu(menu) {
|
|
130
|
+
if (menu) {
|
|
131
|
+
let shouldSelectMenu
|
|
132
|
+
const children = menu.children
|
|
133
|
+
if (children && children.length > 0) {
|
|
134
|
+
shouldSelectMenu = this.getFirstMenu(children)
|
|
135
|
+
} else {
|
|
136
|
+
shouldSelectMenu = menu
|
|
137
|
+
}
|
|
138
|
+
return shouldSelectMenu
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
</script>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<iframe v-if="src && src!== null" ref="menuContent" :src="src" name="menu-content" title="Main content" frameborder="0" />
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script>
|
|
8
|
+
export default {
|
|
9
|
+
data() {
|
|
10
|
+
return {
|
|
11
|
+
src: null
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
watch: {
|
|
15
|
+
$route(to, from) {
|
|
16
|
+
// 必须这样写,否则会在切换页面时无法获得pageCode参数
|
|
17
|
+
this.src = this.$route.query.src
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
mounted() {
|
|
21
|
+
this.src = this.$route.query.src
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<style lang="scss" scoped>
|
|
27
|
+
iframe{
|
|
28
|
+
width: 100%;
|
|
29
|
+
height: calc(100vh - 50px);
|
|
30
|
+
}
|
|
31
|
+
</style>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
export default {
|
|
3
3
|
beforeCreate() {
|
|
4
|
-
const { query } = this.$route
|
|
5
|
-
|
|
6
|
-
this.$router.replace({ path: '/' +
|
|
4
|
+
const { params, query } = this.$route
|
|
5
|
+
const { path } = params
|
|
6
|
+
this.$router.replace({ path: '/' + path, query })
|
|
7
7
|
},
|
|
8
8
|
render: function(h) {
|
|
9
9
|
return h() // avoid warning message
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div style="padding-bottom: 10px">
|
|
4
|
+
<el-radio-group v-model="type">
|
|
5
|
+
<el-radio-button label="graph">
|
|
6
|
+
{{ $t('imatrixUIPublicModel.graphView') }}
|
|
7
|
+
</el-radio-button>
|
|
8
|
+
<el-radio-button label="list">
|
|
9
|
+
{{ $t('imatrixUIPublicModel.listView') }}
|
|
10
|
+
</el-radio-button>
|
|
11
|
+
</el-radio-group>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div v-if="type==='graph'" class="graphDiv">
|
|
15
|
+
<workflow-history :id="workflowId" />
|
|
16
|
+
</div>
|
|
17
|
+
<workflow-history-list v-if="type==='list'" :workflow-id="workflowId" />
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script>
|
|
22
|
+
export default {
|
|
23
|
+
name: 'TacheSubprocessHistory',
|
|
24
|
+
data() {
|
|
25
|
+
return {
|
|
26
|
+
type: 'graph',
|
|
27
|
+
workflowId: null
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
created() {
|
|
31
|
+
const workflowId = this.$route.query.workflowId
|
|
32
|
+
if (workflowId) {
|
|
33
|
+
this.workflowId = parseInt(workflowId)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
38
|
+
<style scoped>
|
|
39
|
+
.graphDiv {
|
|
40
|
+
overflow:auto;
|
|
41
|
+
height: 100%;
|
|
42
|
+
height: calc(100vh - 20px);
|
|
43
|
+
}
|
|
44
|
+
</style>
|
|
45
|
+
|