forked from github/dataease
feat:仪表盘样式适配
This commit is contained in:
parent
09b772bc18
commit
dfde1da4f4
@ -18,6 +18,7 @@
|
||||
"@riophae/vue-treeselect": "0.4.0",
|
||||
"axios": "^0.21.1",
|
||||
"echarts": "^5.0.2",
|
||||
"element-resize-detector": "^1.2.2",
|
||||
"element-ui": "2.13.0",
|
||||
"fit2cloud-ui": "^0.1.12",
|
||||
"js-cookie": "2.2.0",
|
||||
|
@ -1,20 +1,10 @@
|
||||
<template>
|
||||
<div class="bg">
|
||||
<div id="preview-parent" class="canvas-container">
|
||||
<div
|
||||
class="canvas"
|
||||
:style="{
|
||||
width: changeStyleWithScale(canvasStyleData.width) + 'px',
|
||||
height: changeStyleWithScale(canvasStyleData.height) + 'px',
|
||||
}"
|
||||
>
|
||||
<ComponentWrapper
|
||||
v-for="(item, index) in componentData"
|
||||
:key="index"
|
||||
:config="item"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="canvasInfo" class="bg">
|
||||
<ComponentWrapper
|
||||
v-for="(item, index) in componentDataInfo"
|
||||
:key="index"
|
||||
:config="item"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -23,6 +13,10 @@ import { getStyle } from '@/components/canvas/utils/style'
|
||||
import { mapState } from 'vuex'
|
||||
import ComponentWrapper from './ComponentWrapper'
|
||||
import { changeStyleWithScale } from '@/components/canvas/utils/translate'
|
||||
import { uuid } from 'vue-uuid'
|
||||
import { deepCopy } from '@/components/canvas/utils/utils'
|
||||
import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import elementResizeDetectorMaker from 'element-resize-detector'
|
||||
|
||||
export default {
|
||||
components: { ComponentWrapper },
|
||||
@ -36,20 +30,84 @@ export default {
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: mapState([
|
||||
'componentData',
|
||||
'canvasStyleData'
|
||||
]),
|
||||
data() {
|
||||
return {
|
||||
isShowPreview: false,
|
||||
panelId: '',
|
||||
needToChangeHeight: [
|
||||
'top',
|
||||
'height',
|
||||
'fontSize',
|
||||
'borderWidth'
|
||||
],
|
||||
needToChangeWidth: [
|
||||
'left',
|
||||
'width'
|
||||
],
|
||||
scaleWidth: '100',
|
||||
scaleHeight: '100',
|
||||
timer: null,
|
||||
componentDataShow: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 此处单独计算componentData的值 不放入全局mapState中
|
||||
componentDataInfo() {
|
||||
return this.componentDataShow
|
||||
},
|
||||
...mapState([
|
||||
'componentData',
|
||||
'canvasStyleData'
|
||||
])
|
||||
},
|
||||
mounted() {
|
||||
// 计算组件当前合适宽度
|
||||
debugger
|
||||
const _this = this
|
||||
const erd = elementResizeDetectorMaker()
|
||||
// 监听div变动事件
|
||||
erd.listenTo(document.getElementById('canvasInfo'), element => {
|
||||
_this.$nextTick(() => {
|
||||
_this.restore()
|
||||
})
|
||||
})
|
||||
// 监听数据变动事件
|
||||
eventBus.$on('componentDataChange', () => {
|
||||
_this.restore()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
changeStyleWithScale,
|
||||
|
||||
getStyle,
|
||||
|
||||
close() {
|
||||
this.$emit('change', false)
|
||||
restore() {
|
||||
const canvasHeight = document.getElementById('canvasInfo').offsetHeight
|
||||
const canvasWidth = document.getElementById('canvasInfo').offsetWidth
|
||||
this.scaleWidth = canvasWidth * 100 / parseInt(this.canvasStyleData.width)// 获取宽度比
|
||||
this.scaleHeight = canvasHeight * 100 / parseInt(this.canvasStyleData.height)// 获取高度比
|
||||
this.handleScaleChange()
|
||||
},
|
||||
resetID(data) {
|
||||
data.forEach(item => {
|
||||
item.id = uuid.v1()
|
||||
})
|
||||
return data
|
||||
},
|
||||
format(value, scale) {
|
||||
return value * parseInt(scale) / 100
|
||||
},
|
||||
handleScaleChange() {
|
||||
const componentData = deepCopy(this.componentData)
|
||||
componentData.forEach(component => {
|
||||
Object.keys(component.style).forEach(key => {
|
||||
if (this.needToChangeHeight.includes(key)) {
|
||||
component.style[key] = this.format(component.style[key], this.scaleHeight)
|
||||
}
|
||||
if (this.needToChangeWidth.includes(key)) {
|
||||
component.style[key] = this.format(component.style[key], this.scaleWidth)
|
||||
}
|
||||
})
|
||||
})
|
||||
this.componentDataShow = componentData
|
||||
eventBus.$emit('resizing', '')
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -57,12 +115,14 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bg {
|
||||
min-width: 600px;
|
||||
min-height: 300px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid #E6E6E6;
|
||||
.canvas-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
.canvas {
|
||||
position: relative;
|
||||
margin: auto;
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div ref="element" class="bg">
|
||||
<div id="canvasInfo" class="bg">
|
||||
<ComponentWrapper
|
||||
v-for="(item, index) in componentDataInfo"
|
||||
:key="index"
|
||||
@ -10,12 +10,12 @@
|
||||
|
||||
<script>
|
||||
import { getStyle } from '@/components/canvas/utils/style'
|
||||
import { mapState } from 'vuex'
|
||||
import ComponentWrapper from './ComponentWrapper'
|
||||
import { changeStyleWithScale } from '@/components/canvas/utils/translate'
|
||||
import { uuid } from 'vue-uuid'
|
||||
import { deepCopy } from '@/components/canvas/utils/utils'
|
||||
import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import elementResizeDetectorMaker from 'element-resize-detector'
|
||||
import { get } from '@/api/panel/panel'
|
||||
|
||||
export default {
|
||||
@ -47,6 +47,7 @@ export default {
|
||||
scaleWidth: '100',
|
||||
scaleHeight: '100',
|
||||
timer: null,
|
||||
componentDataSource: {},
|
||||
componentData: {},
|
||||
canvasStyleData: {}
|
||||
|
||||
@ -58,8 +59,17 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const _this = this
|
||||
|
||||
// 加载数据
|
||||
this.restore()
|
||||
_this.restore()
|
||||
const erd = elementResizeDetectorMaker()
|
||||
// 监听div变动事件
|
||||
erd.listenTo(document.getElementById('canvasInfo'), element => {
|
||||
_this.$nextTick(() => {
|
||||
_this.resize()
|
||||
})
|
||||
})
|
||||
window.onresize = () => {
|
||||
debugger
|
||||
this.resize()
|
||||
@ -82,7 +92,7 @@ export default {
|
||||
this.panelId = this.$route.path.split('/')[2]
|
||||
// 加载视图数据
|
||||
get('panel/group/findOne/' + this.panelId).then(response => {
|
||||
this.componentData = this.resetID(JSON.parse(response.data.panelData))
|
||||
this.componentDataSource = this.resetID(JSON.parse(response.data.panelData))
|
||||
this.canvasStyleData = JSON.parse(response.data.panelStyle)
|
||||
this.resize()
|
||||
})
|
||||
@ -98,7 +108,7 @@ export default {
|
||||
return value * parseInt(scale) / 100
|
||||
},
|
||||
handleScaleChange() {
|
||||
const componentData = deepCopy(this.componentData)
|
||||
const componentData = deepCopy(this.componentDataSource)
|
||||
componentData.forEach(component => {
|
||||
Object.keys(component.style).forEach(key => {
|
||||
if (this.needToChangeHeight.includes(key)) {
|
||||
@ -118,6 +128,8 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bg {
|
||||
min-width: 800px;
|
||||
min-height: 600px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
|
@ -42,7 +42,7 @@ $subMenuHover:#1682e6;
|
||||
|
||||
$sideBarWidth: 210px;
|
||||
$topBarHeight: 56px;
|
||||
$contentHeight: calc(100vh - 56px);
|
||||
$contentHeight: 100vh;
|
||||
|
||||
// the :export directive is the magic sauce for webpack
|
||||
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
|
||||
|
@ -1,85 +0,0 @@
|
||||
<template>
|
||||
<de-container>
|
||||
|
||||
<de-aside-container>
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane name="PanelList">
|
||||
<span slot="label"><i class="el-icon-document" />列表</span>
|
||||
<panel-list />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="panels_star">
|
||||
<span slot="label"><i class="el-icon-star-off" />收藏</span>
|
||||
开发中...
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="panels_share" :lazy="true">
|
||||
<span slot="label"><i class="el-icon-share" />分享</span>
|
||||
<share-tree v-if="showShare" />
|
||||
</el-tab-pane>
|
||||
|
||||
</el-tabs>
|
||||
|
||||
</de-aside-container>
|
||||
|
||||
<de-main-container>
|
||||
<component :is="component" :param="param" />
|
||||
</de-main-container>
|
||||
</de-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DeMainContainer from '@/components/dataease/DeMainContainer'
|
||||
import DeContainer from '@/components/dataease/DeContainer'
|
||||
import DeAsideContainer from '@/components/dataease/DeAsideContainer'
|
||||
// import Group from './group/Group'
|
||||
import PanelList from './list/PanelList'
|
||||
import PanelViewShow from './list/PanelViewShow'
|
||||
import ShareTree from './GrantAuth/shareTree'
|
||||
|
||||
export default {
|
||||
name: 'Panel',
|
||||
components: { DeMainContainer, DeContainer, DeAsideContainer, PanelList, PanelViewShow, ShareTree },
|
||||
data() {
|
||||
return {
|
||||
component: PanelViewShow,
|
||||
param: {},
|
||||
activeName: 'PanelList',
|
||||
showShare: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick(tab, event) {
|
||||
// 点击分析面板需要刷新分享内容
|
||||
if (tab.name === 'panels_share') {
|
||||
this.refreshShare()
|
||||
}
|
||||
},
|
||||
// switchComponent(c) {
|
||||
// console.log(c)
|
||||
// this.param = c.param
|
||||
// switch (c.name) {
|
||||
// case 'PanelViewShow':
|
||||
// this.component = PanelViewShow
|
||||
// break
|
||||
// }
|
||||
// },
|
||||
refreshShare() {
|
||||
this.showShare = false
|
||||
this.$nextTick(() => (this.showShare = true))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ms-aside-container {
|
||||
height: calc(100vh - 56px);
|
||||
padding: 15px;
|
||||
min-width: 260px;
|
||||
max-width: 460px;
|
||||
}
|
||||
|
||||
.ms-main-container {
|
||||
height: calc(100vh - 56px);
|
||||
}
|
||||
|
||||
</style>
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<de-container v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
|
||||
<de-container v-loading="$store.getters.loadingMap[$store.getters.currentPath]" style="background-color: #f7f8fa">
|
||||
<de-main-container>
|
||||
<component :is="component" :param="param" />
|
||||
</de-main-container>
|
||||
@ -49,7 +49,7 @@ export default {
|
||||
<style scoped>
|
||||
.ms-aside-container {
|
||||
height: calc(100vh - 56px);
|
||||
padding: 15px;
|
||||
padding: 0px;
|
||||
min-width: 260px;
|
||||
max-width: 460px;
|
||||
}
|
||||
|
@ -1,156 +0,0 @@
|
||||
<template>
|
||||
<el-row style="height: 100%;overflow-y: hidden;width: 100%;">
|
||||
<el-row style="display: flex;height: 100%">
|
||||
|
||||
<el-col class="panel-design">
|
||||
<!--TODO 仪表盘设计公共设置区域-->
|
||||
<el-row class="panel-design-head">
|
||||
<span style="float: left;line-height: 40px; color: gray">
|
||||
<span>名称:{{ panelInfo.name || '测试仪表板' }}</span>
|
||||
</span>
|
||||
<span style="float: right;line-height: 40px;">
|
||||
<el-tooltip content="预览">
|
||||
<el-button class="el-icon-view" size="mini" circle />
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-row>
|
||||
<!--TODO 仪表盘预览区域-->
|
||||
<section>
|
||||
<Preview />
|
||||
</section>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-row>
|
||||
</template>
|
||||
<script>
|
||||
import ChartEdit from '@/views/chart/view/ChartEdit'
|
||||
|
||||
export default {
|
||||
name: 'ChartViewEdit',
|
||||
components: { ChartEdit },
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
panelInfo() {
|
||||
return this.$store.state.panel.panelInfo
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.view-list {
|
||||
height: 100%;
|
||||
width: 20%;
|
||||
min-width: 180px;
|
||||
max-width: 220px;
|
||||
border: 1px solid #E6E6E6;
|
||||
border-left: 0 solid;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.view-list-thumbnails-outline {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.view-list-thumbnails {
|
||||
width: 100%;
|
||||
padding: 0px 15px 15px 0px;
|
||||
}
|
||||
|
||||
.panel-design {
|
||||
height: 100%;
|
||||
min-width: 500px;
|
||||
border-top: 1px solid #E6E6E6;
|
||||
}
|
||||
|
||||
.panel-design-head {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.panel-design-show {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-top: 1px solid #E6E6E6;
|
||||
}
|
||||
|
||||
.padding-lr {
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.itxst {
|
||||
margin: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.col {
|
||||
width: 40%;
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
border: solid 1px #eee;
|
||||
border-radius: 5px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.col + .col {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.item {
|
||||
padding: 2px 12px;
|
||||
margin: 3px 3px 0 3px;
|
||||
border: solid 1px #eee;
|
||||
background-color: #f1f1f1;
|
||||
text-align: left;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.item + .item {
|
||||
border-top: none;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.item:hover {
|
||||
background-color: #fdfdfd;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.item-axis {
|
||||
padding: 2px 12px;
|
||||
margin: 3px 3px 0 3px;
|
||||
border: solid 1px #eee;
|
||||
background-color: #f1f1f1;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.item-axis:hover {
|
||||
background-color: #fdfdfd;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
border: 1px solid #000;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
@ -145,6 +145,7 @@ import GrantAuth from '../GrantAuth'
|
||||
import LinkGenerate from '@/views/link/generate'
|
||||
import { uuid } from 'vue-uuid'
|
||||
import bus from '@/utils/bus'
|
||||
import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import { loadTable, getScene, addGroup, delGroup, addTable, delTable, groupTree, defaultTree, get } from '@/api/panel/panel'
|
||||
|
||||
export default {
|
||||
@ -417,8 +418,6 @@ export default {
|
||||
|
||||
nodeClick(data, node) {
|
||||
if (data.nodeType === 'panel') {
|
||||
this.$store.dispatch('panel/setPanelInfo', data)
|
||||
this.currGroup = data
|
||||
// 加载视图数据
|
||||
this.$nextTick(() => {
|
||||
localStorage.setItem('canvasData', null)
|
||||
@ -426,6 +425,9 @@ export default {
|
||||
get('panel/group/findOne/' + data.id).then(response => {
|
||||
this.$store.commit('setComponentData', this.resetID(JSON.parse(response.data.panelData)))
|
||||
this.$store.commit('setCanvasStyle', JSON.parse(response.data.panelStyle))
|
||||
this.$store.dispatch('panel/setPanelInfo', data)
|
||||
this.currGroup = data
|
||||
eventBus.$emit('componentDataChange', '')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -57,12 +57,13 @@ export default {
|
||||
<style scoped>
|
||||
.ms-aside-container {
|
||||
height: calc(100vh - 56px);
|
||||
padding: 15px;
|
||||
padding: 0px;
|
||||
min-width: 260px;
|
||||
max-width: 460px;
|
||||
}
|
||||
.ms-main-container {
|
||||
height: calc(100vh - 56px);
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -1,25 +1,25 @@
|
||||
<template>
|
||||
<el-row style="height: 100%;overflow-y: hidden;width: 100%;">
|
||||
<el-row style="display: flex;height: 100%">
|
||||
|
||||
<el-col class="panel-design">
|
||||
<!--TODO 仪表盘设计公共设置区域-->
|
||||
<el-row class="panel-design-head">
|
||||
<span style="float: left;line-height: 40px; color: gray">
|
||||
<span>名称:{{ panelInfo.name || '测试仪表板' }}</span>
|
||||
</span>
|
||||
<span style="float: right;line-height: 40px;">
|
||||
<el-tooltip content="预览">
|
||||
<el-button class="el-icon-view" size="mini" circle @click="clickPreview" />
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-row>
|
||||
<!--TODO 仪表盘预览区域-->
|
||||
<section>
|
||||
<Preview />
|
||||
</section>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row style="height: 100%;width: 100%;">
|
||||
<el-col v-if="panelInfo.name.length>0" class="panel-design">
|
||||
<el-row class="panel-design-head">
|
||||
<!--TODO 仪表盘头部区域-->
|
||||
<span>{{ panelInfo.name || '测试仪表板' }}</span>
|
||||
<span style="float: right;">
|
||||
<el-tooltip content="预览">
|
||||
<el-button class="el-icon-view" size="mini" circle @click="clickPreview" />
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-row>
|
||||
<!--TODO 仪表盘预览区域-->
|
||||
<el-row class="panel-design-preview">
|
||||
<Preview />
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col v-if="panelInfo.name.length===0" style="height: 100%;">
|
||||
<el-row style="height: 100%;" class="custom-position">
|
||||
请从左侧选择仪表盘
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<script>
|
||||
@ -59,7 +59,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style>
|
||||
.view-list {
|
||||
height: 100%;
|
||||
width: 20%;
|
||||
@ -81,18 +81,26 @@ export default {
|
||||
}
|
||||
|
||||
.panel-design {
|
||||
min-height: 400px;
|
||||
height: 100%;
|
||||
min-width: 500px;
|
||||
overflow-y: auto;
|
||||
border-top: 1px solid #E6E6E6;
|
||||
}
|
||||
|
||||
.panel-design-head {
|
||||
height: 40px;
|
||||
background-color: white;
|
||||
padding: 0 6px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.panel-design-show {
|
||||
height: 100%;
|
||||
.panel-design-preview {
|
||||
width: 100%;
|
||||
height: calc(100% - 40px);
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding: 5px;
|
||||
border-top: 1px solid #E6E6E6;
|
||||
}
|
||||
|
||||
@ -165,4 +173,14 @@ export default {
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.custom-position {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
flex-flow: row nowrap;
|
||||
color: #9ea6b2;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user