forked from github/dataease
feat(数据大屏): 数据大屏支持隐藏组件
This commit is contained in:
parent
9e914b2b1b
commit
fe41b7ad88
@ -3,9 +3,9 @@ import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||
import { layerStoreWithOut } from '@/store/modules/data-visualization/layer'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { ElIcon, ElRow } from 'element-plus-secondary'
|
||||
import { ElIcon, ElRow, ElSwitch } from 'element-plus-secondary'
|
||||
import Icon from '../icon-custom/src/Icon.vue'
|
||||
import { nextTick, ref } from 'vue'
|
||||
import { computed, nextTick, ref } from 'vue'
|
||||
import draggable from 'vuedraggable'
|
||||
import { lockStoreWithOut } from '@/store/modules/data-visualization/lock'
|
||||
import ContextMenuAsideDetails from '@/components/data-visualization/canvas/ContextMenuAsideDetails.vue'
|
||||
@ -22,7 +22,8 @@ const composeStore = composeStoreWithOut()
|
||||
|
||||
const { areaData, isCtrlOrCmdDown, isShiftDown, laterIndex } = storeToRefs(composeStore)
|
||||
|
||||
const { componentData, curComponent, canvasViewInfo } = storeToRefs(dvMainStore)
|
||||
const { componentData, canvasStyleData, curComponent, canvasViewInfo, canvasState } =
|
||||
storeToRefs(dvMainStore)
|
||||
const getComponent = index => {
|
||||
return componentData.value[componentData.value.length - 1 - index]
|
||||
}
|
||||
@ -34,6 +35,13 @@ const areaDataPush = component => {
|
||||
areaData.value.components.push(component)
|
||||
}
|
||||
}
|
||||
|
||||
const hiddenAreaActive = computed(
|
||||
() => canvasState.value.curPointArea === 'hidden' && !curComponent.value
|
||||
)
|
||||
const baseAreaActive = computed(
|
||||
() => canvasState.value.curPointArea === 'base' && !curComponent.value
|
||||
)
|
||||
// shift 选择算法逻辑
|
||||
// 1.记录上次点击的laterIndex(初始状态laterIndex=0);
|
||||
// 2.获取当前index curClickIndex;
|
||||
@ -59,6 +67,16 @@ const shiftDataPush = curClickIndex => {
|
||||
dvMainStore.setCurComponent({ component: null, index: null })
|
||||
}
|
||||
|
||||
const hiddenAreaOnClick = (e, element) => {
|
||||
let indexResult
|
||||
componentData.value.forEach((component, index) => {
|
||||
if (element.id === component.id) {
|
||||
indexResult = index
|
||||
}
|
||||
})
|
||||
dvMainStore.setCurComponent({ component: element, index: indexResult })
|
||||
}
|
||||
|
||||
const onClick = (e, index) => {
|
||||
// 初始化点击是 laterIndex=0
|
||||
if (!curComponent.value) {
|
||||
@ -149,6 +167,14 @@ const showComponent = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const popComponentData = computed(() =>
|
||||
componentData.value.filter(ele => ele.category && ele.category === 'hidden')
|
||||
)
|
||||
|
||||
const baseComponentData = computed(() =>
|
||||
componentData.value.filter(ele => ele.category !== 'hidden' && ele.component !== 'GroupArea')
|
||||
)
|
||||
|
||||
const dragOnEnd = ({ oldIndex, newIndex }) => {
|
||||
const source = componentData.value[newIndex]
|
||||
const comLength = componentData.value.length
|
||||
@ -204,12 +230,94 @@ const handleContextMenu = e => {
|
||||
document.body.removeChild(customContextMenu)
|
||||
})
|
||||
}
|
||||
|
||||
const areaClick = area => {
|
||||
dvMainStore.setCurComponent({ component: null, index: null })
|
||||
dvMainStore.canvasStateChange({ key: 'curPointArea', value: area })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!--为了保持图层视觉上的一致性 这里进行数组的倒序排列 相应的展示和移动按照倒序处理-->
|
||||
<div class="real-time-component-list">
|
||||
<button hidden="true" id="close-button"></button>
|
||||
<div class="layer-area" @click="areaClick('hidden')" :class="{ activated: hiddenAreaActive }">
|
||||
<span>弹窗区域({{ popComponentData.length }})</span>
|
||||
<el-switch v-model="canvasStyleData.popupAvailable" size="small" />
|
||||
</div>
|
||||
<el-row class="list-wrap">
|
||||
<div class="list-container" @contextmenu="handleContextMenu">
|
||||
<draggable
|
||||
@end="dragOnEnd"
|
||||
:list="popComponentData"
|
||||
animation="100"
|
||||
class="drag-list"
|
||||
item-key="id"
|
||||
>
|
||||
<template #item="{ element, index }">
|
||||
<div>
|
||||
<div
|
||||
:title="element.name"
|
||||
class="component-item"
|
||||
:class="{
|
||||
'container-item-not-show': !element.isShow,
|
||||
activated:
|
||||
(curComponent && curComponent?.id === element?.id) ||
|
||||
areaData.components.includes(element)
|
||||
}"
|
||||
@click="hiddenAreaOnClick($event, element)"
|
||||
>
|
||||
<div style="width: 22px; padding-left: 3px"></div>
|
||||
<el-icon class="component-icon">
|
||||
<Icon :name="getIconName(element)"></Icon>
|
||||
</el-icon>
|
||||
<span
|
||||
:id="`component-label-${element?.id}`"
|
||||
class="component-label"
|
||||
@dblclick="editComponentName(element)"
|
||||
>
|
||||
{{ element?.name }}
|
||||
</span>
|
||||
<div
|
||||
v-show="!nameEdit || (nameEdit && curComponent?.id !== element?.id)"
|
||||
class="icon-container"
|
||||
:class="{
|
||||
'icon-container-show': !element?.isShow
|
||||
}"
|
||||
>
|
||||
<el-dropdown
|
||||
ref="dropdownMore"
|
||||
trigger="click"
|
||||
placement="bottom-start"
|
||||
effect="dark"
|
||||
:hide-timeout="0"
|
||||
>
|
||||
<span :class="'dropdownMore-' + index" @click="onClick(transformIndex(index))">
|
||||
<el-icon class="component-base">
|
||||
<Icon name="dv-more" class="opt-icon"></Icon>
|
||||
</el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<context-menu-aside-details
|
||||
:element="element"
|
||||
@close="menuAsideClose($event, index)"
|
||||
></context-menu-aside-details>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
</el-row>
|
||||
<div
|
||||
class="layer-area layer-screen"
|
||||
@click="areaClick('base')"
|
||||
:class="{ activated: baseAreaActive }"
|
||||
>
|
||||
<span>大屏区域({{ baseComponentData.length }})</span>
|
||||
</div>
|
||||
<el-row class="list-wrap">
|
||||
<div class="list-container" @contextmenu="handleContextMenu">
|
||||
<draggable
|
||||
@ -222,7 +330,10 @@ const handleContextMenu = e => {
|
||||
<template #item="{ index }">
|
||||
<div>
|
||||
<div
|
||||
v-show="getComponent(index)?.component !== 'GroupArea'"
|
||||
v-show="
|
||||
getComponent(index)?.component !== 'GroupArea' &&
|
||||
getComponent(index)?.category !== 'hidden'
|
||||
"
|
||||
:title="getComponent(index)?.name"
|
||||
class="component-item"
|
||||
:class="{
|
||||
@ -519,6 +630,43 @@ const handleContextMenu = e => {
|
||||
color: #5f5f5f !important;
|
||||
}
|
||||
}
|
||||
|
||||
.layer-area {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
padding: 0 8px;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
&:hover {
|
||||
background-color: rgba(235, 235, 235, 0.1);
|
||||
}
|
||||
:deep(.ed-switch.is-checked .ed-switch__core > .ed-switch__action) {
|
||||
left: calc(100% - 12px);
|
||||
}
|
||||
:deep(span.ed-switch__core) {
|
||||
min-width: 24px;
|
||||
border: none;
|
||||
height: 6px;
|
||||
border-radius: 3px;
|
||||
.ed-switch__action {
|
||||
left: 0;
|
||||
box-shadow: 0 2px 4px rgba(31, 35, 41, 0.12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.activated {
|
||||
background-color: var(--ed-color-primary-1a, rgba(51, 112, 255, 0.1)) !important;
|
||||
color: var(--ed-color-primary);
|
||||
}
|
||||
|
||||
.layer-screen {
|
||||
border-top: rgba(255, 255, 255, 0.15) 1px solid;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
|
@ -44,14 +44,15 @@ import PointShadow from '@/components/data-visualization/canvas/PointShadow.vue'
|
||||
import DragInfo from '@/components/visualization/common/DragInfo.vue'
|
||||
import { activeWatermark } from '@/components/watermark/watermark'
|
||||
import { personInfoApi } from '@/api/user'
|
||||
import ComponentHangPopver from '@/custom-component/independent-hang/ComponentHangPopver.vue'
|
||||
import PopArea from '@/custom-component/pop-area/Component.vue'
|
||||
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const composeStore = composeStoreWithOut()
|
||||
const contextmenuStore = contextmenuStoreWithOut()
|
||||
|
||||
const { curComponent, dvInfo, editMode, tabMoveOutComponentId } = storeToRefs(dvMainStore)
|
||||
const { curComponent, dvInfo, editMode, tabMoveOutComponentId, canvasState } =
|
||||
storeToRefs(dvMainStore)
|
||||
const { editorMap, areaData } = storeToRefs(composeStore)
|
||||
const emits = defineEmits(['scrollCanvasToTop'])
|
||||
const props = defineProps({
|
||||
@ -67,6 +68,11 @@ const props = defineProps({
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
popComponentData: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => []
|
||||
},
|
||||
canvasViewInfo: {
|
||||
type: Object,
|
||||
required: true
|
||||
@ -1398,6 +1404,11 @@ const groupAreaClickChange = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// v-if 使用 内容不渲染 默认参数不起用
|
||||
const popAreaAvailable = computed(
|
||||
() => canvasStyleData.value?.popupAvailable && isMainCanvas(canvasId.value)
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
if (isMainCanvas(canvasId.value)) {
|
||||
initSnapshotTimer()
|
||||
@ -1460,6 +1471,18 @@ defineExpose({
|
||||
:component-data="componentData"
|
||||
:canvas-id="canvasId"
|
||||
></canvas-opt-bar>
|
||||
<!-- 弹框区域 -->
|
||||
<PopArea
|
||||
v-if="popAreaAvailable"
|
||||
:dv-info="dvInfo"
|
||||
:canvas-id="canvasId"
|
||||
:canvas-style-data="canvasStyleData"
|
||||
:canvasViewInfo="canvasViewInfo"
|
||||
:pop-component-data="popComponentData"
|
||||
:scale="curBaseScale"
|
||||
:canvas-state="canvasState"
|
||||
:show-position="'popEdit'"
|
||||
></PopArea>
|
||||
<!-- 网格线 -->
|
||||
<drag-shadow
|
||||
v-if="infoBox && infoBox.moveItem && editMode !== 'preview'"
|
||||
|
@ -1,16 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import { getStyle } from '@/utils/style'
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import { ref, onMounted, toRefs, getCurrentInstance, computed } from 'vue'
|
||||
import { ref, onMounted, toRefs, getCurrentInstance, computed, nextTick } from 'vue'
|
||||
import findComponent from '@/utils/components'
|
||||
import { downloadCanvas, imgUrlTrans } from '@/utils/imgUtils'
|
||||
import ComponentEditBar from '@/components/visualization/ComponentEditBar.vue'
|
||||
import ComponentSelector from '@/components/visualization/ComponentSelector.vue'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import Board from '@/components/de-board/Board.vue'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
|
||||
const componentWrapperInnerRef = ref(null)
|
||||
const componentEditBarRef = ref(null)
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
|
||||
const props = defineProps({
|
||||
active: {
|
||||
@ -100,6 +102,9 @@ const handleInnerMouseDown = e => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
}
|
||||
if (showPosition.value.includes('popEdit')) {
|
||||
onClick(e)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@ -112,13 +117,14 @@ onMounted(() => {
|
||||
})
|
||||
})
|
||||
|
||||
const onClick = () => {
|
||||
// do event click
|
||||
// const events = config.value.events
|
||||
// Object.keys(events).forEach(event => {
|
||||
// currentInstance.ctx[event](events[event])
|
||||
// })
|
||||
// eventBus.emit('v-click', config.value.id)
|
||||
const onClick = e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
// 将当前点击组件的事件传播出去
|
||||
eventBus.emit('componentClick')
|
||||
dvMainStore.setInEditorStatus(true)
|
||||
dvMainStore.setClickComponentStatus(true)
|
||||
dvMainStore.setCurComponent({ component: config.value, index: index.value })
|
||||
}
|
||||
|
||||
const getComponentStyleDefault = style => {
|
||||
@ -193,7 +199,6 @@ const deepScale = computed(() => scale.value / 100)
|
||||
<div
|
||||
class="wrapper-outer"
|
||||
:class="showPosition + '-' + config.component"
|
||||
@click="onClick"
|
||||
@mousedown="handleInnerMouseDown"
|
||||
@mouseenter="onMouseEnter"
|
||||
>
|
||||
|
@ -19,7 +19,7 @@ const layerStore = layerStoreWithOut()
|
||||
const composeStore = composeStoreWithOut()
|
||||
|
||||
const { areaData } = storeToRefs(composeStore)
|
||||
const { curComponent } = storeToRefs(dvMainStore)
|
||||
const { curComponent, componentData } = storeToRefs(dvMainStore)
|
||||
const emit = defineEmits(['close', 'rename'])
|
||||
const { emitter } = useEmitt()
|
||||
const props = defineProps({
|
||||
@ -31,6 +31,10 @@ const props = defineProps({
|
||||
|
||||
const { activePosition } = toRefs(props)
|
||||
|
||||
const popComponentDataLength = computed(
|
||||
() => componentData.value.filter(ele => ele.category === 'hidden').length
|
||||
)
|
||||
|
||||
const lock = () => {
|
||||
snapshotStore.recordSnapshotCache()
|
||||
lockStore.lock()
|
||||
@ -84,6 +88,9 @@ const categoryChange = type => {
|
||||
if (curComponent.value) {
|
||||
snapshotStore.recordSnapshotCache()
|
||||
curComponent.value['category'] = type
|
||||
if (type === 'hidden') {
|
||||
dvMainStore.canvasStateChange({ key: 'curPointArea', value: 'hidden' })
|
||||
}
|
||||
}
|
||||
}
|
||||
const rename = () => {
|
||||
@ -158,7 +165,12 @@ const handleComposeMouseDown = e => {
|
||||
}
|
||||
|
||||
const composeDivider = computed(() => {
|
||||
return !(!curComponent || curComponent['isLock'] || curComponent['component'] != 'Group')
|
||||
return !(
|
||||
!curComponent ||
|
||||
curComponent['isLock'] ||
|
||||
curComponent['component'] != 'Group' ||
|
||||
curComponent.category === 'hidden'
|
||||
)
|
||||
})
|
||||
|
||||
const isGroupArea = computed(() => {
|
||||
@ -216,23 +228,36 @@ const editQueryCriteria = () => {
|
||||
取消组合
|
||||
</li>
|
||||
<el-divider class="custom-divider" v-show="composeDivider" />
|
||||
<template v-if="curComponent && !isGroupArea">
|
||||
<template v-if="!curComponent['isLock']">
|
||||
<template v-if="curComponent">
|
||||
<template v-if="!curComponent['isLock'] && curComponent.category === 'hidden'">
|
||||
<li @click="categoryChange('base')">移动到大屏显示区</li>
|
||||
<li @click="editQueryCriteria">编辑</li>
|
||||
<li v-if="activePosition === 'aside'" @click="rename">重命名</li>
|
||||
<li @click="copy">复制</li>
|
||||
<li @click="paste">粘贴</li>
|
||||
<el-divider class="custom-divider" />
|
||||
<li @click="deleteComponent">删除</li>
|
||||
</template>
|
||||
<template v-if="!curComponent['isLock'] && curComponent.category !== 'hidden'">
|
||||
<li v-if="curComponent.component === 'VQuery'" @click="editQueryCriteria">编辑</li>
|
||||
<li @click="upComponent">上移一层</li>
|
||||
<li @click="upComponent">上移一层</li>
|
||||
<li @click="downComponent">下移一层</li>
|
||||
<li @click="topComponent">置于顶层</li>
|
||||
<li @click="bottomComponent">置于底层</li>
|
||||
<li
|
||||
@click="categoryChange('hidden')"
|
||||
v-show="
|
||||
curComponent['category'] === 'base' &&
|
||||
curComponent.component === 'VQuery' &&
|
||||
popComponentDataLength === 0
|
||||
"
|
||||
>
|
||||
移动到大屏弹框区
|
||||
</li>
|
||||
<el-divider class="custom-divider" />
|
||||
<li @click="hide" v-show="curComponent['isShow']">隐藏</li>
|
||||
<li @click="show" v-show="!curComponent['isShow']">取消隐藏</li>
|
||||
<li @click="categoryChange('hidden')" v-show="curComponent['category'] === 'base'">
|
||||
转为隐藏组件
|
||||
</li>
|
||||
<li @click="categoryChange('base')" v-show="curComponent['category'] === 'hidden'">
|
||||
转为基础组件
|
||||
</li>
|
||||
<li @click="lock">锁定</li>
|
||||
<el-divider class="custom-divider" />
|
||||
<li v-if="activePosition === 'aside'" @click="rename">重命名</li>
|
||||
@ -242,7 +267,7 @@ const editQueryCriteria = () => {
|
||||
<el-divider class="custom-divider" />
|
||||
<li @click="deleteComponent">删除</li>
|
||||
</template>
|
||||
<li v-else @click="unlock">解锁</li>
|
||||
<li v-if="curComponent['isLock']" @click="unlock">解锁</li>
|
||||
</template>
|
||||
<li v-else-if="!curComponent && !areaData.components.length" @click="paste">粘贴</li>
|
||||
</ul>
|
||||
|
@ -14,8 +14,9 @@ import { activeWatermark } from '@/components/watermark/watermark'
|
||||
import { personInfoApi } from '@/api/user'
|
||||
import router from '@/router'
|
||||
import { XpackComponent } from '@/components/plugin'
|
||||
import PopArea from '@/custom-component/pop-area/Component.vue'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { pcMatrixCount, curComponent, mobileInPc } = storeToRefs(dvMainStore)
|
||||
const { pcMatrixCount, curComponent, mobileInPc, canvasState } = storeToRefs(dvMainStore)
|
||||
const openHandler = ref(null)
|
||||
const props = defineProps({
|
||||
canvasStyleData: {
|
||||
@ -96,6 +97,14 @@ const dashboardActive = computed(() => {
|
||||
const isReport = computed(() => {
|
||||
return !!router.currentRoute.value.query?.report
|
||||
})
|
||||
|
||||
const popComponentData = computed(() =>
|
||||
componentData.value.filter(ele => ele.category && ele.category === 'hidden')
|
||||
)
|
||||
|
||||
const baseComponentData = computed(() =>
|
||||
componentData.value.filter(ele => ele.category !== 'hidden' && ele.component !== 'GroupArea')
|
||||
)
|
||||
const canvasStyle = computed(() => {
|
||||
let style = {}
|
||||
if (canvasStyleData.value && canvasStyleData.value.width && isMainCanvas(canvasId.value)) {
|
||||
@ -163,7 +172,11 @@ const resetLayout = () => {
|
||||
? scaleMin.value * 1.2
|
||||
: outerScale.value * 100
|
||||
} else {
|
||||
changeRefComponentsSizeWithScale(componentData.value, canvasStyleData.value, scaleMin.value)
|
||||
changeRefComponentsSizeWithScale(
|
||||
baseComponentData.value,
|
||||
canvasStyleData.value,
|
||||
scaleMin.value
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -250,7 +263,7 @@ const winMsgHandle = event => {
|
||||
) {
|
||||
const attachParams = msgInfo.params
|
||||
if (attachParams) {
|
||||
dvMainStore.addOuterParamsFilter(attachParams, componentData.value, 'outer')
|
||||
dvMainStore.addOuterParamsFilter(attachParams, baseComponentData.value, 'outer')
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -309,6 +322,12 @@ const onPointClick = param => {
|
||||
console.warn('de_inner_params send error')
|
||||
}
|
||||
}
|
||||
|
||||
// v-if 使用 内容不渲染 默认参数不起用
|
||||
const popAreaAvailable = computed(
|
||||
() => canvasStyleData.value?.popupAvailable && isMainCanvas(canvasId.value)
|
||||
)
|
||||
|
||||
defineExpose({
|
||||
restore
|
||||
})
|
||||
@ -322,13 +341,25 @@ defineExpose({
|
||||
ref="previewCanvas"
|
||||
@mousedown="handleMouseDown"
|
||||
>
|
||||
<!-- 弹框区域 -->
|
||||
<PopArea
|
||||
v-if="popAreaAvailable"
|
||||
:dv-info="dvInfo"
|
||||
:canvas-id="canvasId"
|
||||
:canvas-style-data="canvasStyleData"
|
||||
:canvasViewInfo="canvasViewInfo"
|
||||
:pop-component-data="popComponentData"
|
||||
:scale="scaleMin"
|
||||
:canvas-state="canvasState"
|
||||
:show-position="'preview'"
|
||||
></PopArea>
|
||||
<canvas-opt-bar
|
||||
:canvas-id="canvasId"
|
||||
:canvas-style-data="canvasStyleData"
|
||||
:component-data="componentData"
|
||||
:component-data="baseComponentData"
|
||||
></canvas-opt-bar>
|
||||
<ComponentWrapper
|
||||
v-for="(item, index) in componentData"
|
||||
v-for="(item, index) in baseComponentData"
|
||||
v-show="item.isShow"
|
||||
:active="item.id === (curComponent || {})['id']"
|
||||
:canvas-id="canvasId"
|
||||
|
@ -45,8 +45,7 @@ const onEventChange = () => {
|
||||
class="radio-span"
|
||||
@change="onEventChange"
|
||||
>
|
||||
<el-radio label="displayChange" :effect="themes"> 开启隐藏组件 </el-radio>
|
||||
<el-radio label="jump" :effect="themes"> 跳转 </el-radio>
|
||||
<el-radio label="displayChange" :effect="themes"> 开启弹框区 </el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -99,6 +99,8 @@ const outerStyle = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
const curShadowShow = computed(() => curComponent.value && curComponent.value.category !== 'hidden')
|
||||
|
||||
defineExpose({
|
||||
rulerScroll
|
||||
})
|
||||
@ -115,7 +117,7 @@ defineExpose({
|
||||
<div class="ruler-shadow" :style="outerStyle"></div>
|
||||
<div :style="wStyle" class="ruler-outer-scroll">
|
||||
<div class="ruler" :style="{ width: `${scaleWidth}px` }">
|
||||
<div v-if="curComponent" :style="curComponentShadow" class="cur-shadow"></div>
|
||||
<div v-if="curShadowShow" :style="curComponentShadow" class="cur-shadow"></div>
|
||||
<div class="ruler-line" :style="{ width: `${scaleWidth}px` }"></div>
|
||||
<div
|
||||
v-for="(tick, index) in ticks"
|
||||
@ -144,7 +146,7 @@ defineExpose({
|
||||
transform: rotate(90deg);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
z-index: 1;
|
||||
z-index: 2;
|
||||
.ruler {
|
||||
.ruler-line {
|
||||
top: 0;
|
||||
|
@ -20,8 +20,9 @@
|
||||
import { CSSProperties, computed, nextTick, toRefs } from 'vue'
|
||||
import { imgUrlTrans } from '@/utils/imgUtils'
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import { eventStoreWithOut } from '@/store/modules/data-visualization/event'
|
||||
const eventStore = eventStoreWithOut()
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
|
||||
const props = defineProps({
|
||||
propValue: {
|
||||
type: String,
|
||||
@ -57,8 +58,10 @@ const imageAdapter = computed(() => {
|
||||
const onPictureClick = e => {
|
||||
if (element.value.events && element.value.events.checked) {
|
||||
if (element.value.events.type === 'displayChange') {
|
||||
// 打开隐藏组件
|
||||
eventStore.displayEventChange(element.value)
|
||||
// 打开弹框区域
|
||||
nextTick(() => {
|
||||
dvMainStore.popAreaActiveSwitch()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
core/core-frontend/src/custom-component/pop-area/Attr.vue
Normal file
13
core/core-frontend/src/custom-component/pop-area/Attr.vue
Normal file
@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div class="attr-list de-collapse-style">
|
||||
<CommonAttr :element="curComponent"></CommonAttr>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import CommonAttr from '@/custom-component/common/CommonAttr.vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { curComponent } = storeToRefs(dvMainStore)
|
||||
</script>
|
205
core/core-frontend/src/custom-component/pop-area/Component.vue
Normal file
205
core/core-frontend/src/custom-component/pop-area/Component.vue
Normal file
@ -0,0 +1,205 @@
|
||||
<template>
|
||||
<!--此区域暂时放到类似视图和分组平行的组件作为后续扩展使用,但当前版本只作为类似MarkLine 和canvasCore平行组件 仅做区域显示使用-->
|
||||
<div class="pop-area" :style="popCanvasStyle" @mousedown="handleMouseDown">
|
||||
<div style="width: 100%; height: 100%">
|
||||
<div v-if="popComponentData && popComponentData.length > 0" class="pop-content">
|
||||
<!--使用ComponentWrapper 保留扩展能力-->
|
||||
<ComponentWrapper
|
||||
v-for="(item, index) in popComponentData"
|
||||
:id="'component-pop-' + item.id"
|
||||
:view-info="canvasViewInfo[item.id]"
|
||||
:key="index"
|
||||
:config="item"
|
||||
:index="index"
|
||||
:dv-info="dvInfo"
|
||||
:show-position="showPosition"
|
||||
:style="customPopStyle"
|
||||
:scale="innerScale"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="pop-area-main"
|
||||
:class="{ 'pop-area-active': areaActive }"
|
||||
:style="baseStyle"
|
||||
@drop="handleDrop"
|
||||
@dragover="handleDragOver"
|
||||
@dragleave="handleDragLeave"
|
||||
>
|
||||
<span>可点击或拖拽查询组件到此位置,点击预览可查看弹窗区</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, onMounted, ref, toRefs } from 'vue'
|
||||
import { findDragComponent } from '@/utils/canvasUtils'
|
||||
import { guid } from '@/views/visualized/data/dataset/form/util'
|
||||
import { changeComponentSizeWithScale } from '@/utils/changeComponentsSizeWithScale'
|
||||
import { adaptCurThemeCommonStyle } from '@/utils/canvasStyle'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import ComponentWrapper from '@/components/data-visualization/canvas/ComponentWrapper.vue'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const areaActive = ref(false)
|
||||
const props = defineProps({
|
||||
dvInfo: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
canvasStyleData: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
popComponentData: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
canvasViewInfo: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
canvasId: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'canvas-main'
|
||||
},
|
||||
scale: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 1
|
||||
},
|
||||
showPosition: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'preview'
|
||||
},
|
||||
canvasState: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const { canvasStyleData, popComponentData, canvasViewInfo, scale, canvasState } = toRefs(props)
|
||||
const baseStyle = computed(() => {
|
||||
return {
|
||||
fontSize: 30 * props.scale + 'px',
|
||||
height: canvasStyleData.value.height * props.scale * 0.15 + 'px'
|
||||
}
|
||||
})
|
||||
|
||||
const innerScale = computed(() =>
|
||||
props.showPosition === 'preview' ? props.scale : props.scale * 100
|
||||
)
|
||||
|
||||
const handleDragOver = e => {
|
||||
areaActive.value = true
|
||||
e.preventDefault()
|
||||
e.dataTransfer.dropEffect = 'copy'
|
||||
}
|
||||
|
||||
const handleDragLeave = e => {
|
||||
areaActive.value = false
|
||||
}
|
||||
|
||||
const handleDrop = e => {
|
||||
areaActive.value = false
|
||||
// 判断当前区域师傅已经有隐藏组件
|
||||
if (!popComponentData.value || popComponentData.value.length === 0) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
const componentInfo = e.dataTransfer.getData('id')
|
||||
if (componentInfo) {
|
||||
const component = findDragComponent(componentInfo)
|
||||
if (component.component === 'VQuery') {
|
||||
component.style.top = 0
|
||||
component.style.left = 0
|
||||
component.id = guid()
|
||||
component.category = 'hidden'
|
||||
component.commonBackground.backgroundColor = 'rgba(41, 41, 41, 1)'
|
||||
changeComponentSizeWithScale(component)
|
||||
dvMainStore.addComponent({ component: component, index: undefined })
|
||||
adaptCurThemeCommonStyle(component)
|
||||
snapshotStore.recordSnapshotCache('renderChart', component.id)
|
||||
} else {
|
||||
ElMessage.error('及支持添加查询组件')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleDragEnd = () => {
|
||||
areaActive.value = false
|
||||
}
|
||||
|
||||
const customPopStyle = computed(() => {
|
||||
return {
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
}
|
||||
})
|
||||
|
||||
const popCanvasStyle = computed(() => {
|
||||
if (canvasState.value.curPointArea === 'hidden') {
|
||||
let queryCount = 0
|
||||
popComponentData.value.forEach(popItem => {
|
||||
queryCount = 0 + popItem.propValue.length
|
||||
})
|
||||
return {
|
||||
height: queryCount < 8 ? '15%' : (queryCount * 45 * scale.value) / 4 + 'px'
|
||||
}
|
||||
} else {
|
||||
return { height: '0px!important', overflow: 'hidden', border: '0!important' }
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
eventBus.on('handleDragEnd-canvas-main', handleDragEnd)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
eventBus.off('handleDragEnd-canvas-main', handleDragEnd)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.pop-area {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
max-height: 50%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border: 1px dashed rgba(67, 67, 67, 1);
|
||||
background: rgba(26, 26, 26, 1);
|
||||
transition: height 0.2s ease;
|
||||
z-index: 1;
|
||||
}
|
||||
.pop-area-main {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: rgba(166, 166, 166, 1);
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.pop-area-active {
|
||||
border: 1px dashed rgba(51, 112, 255, 1) !important;
|
||||
background: #1d2331 !important;
|
||||
}
|
||||
.pop-content {
|
||||
position: static !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
:deep(.no-list-label .container .ed-button) {
|
||||
font-size: 32px;
|
||||
}
|
||||
:deep(.no-list-label .container) {
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -36,6 +36,9 @@ export const dvMainStore = defineStore('dataVisualization', {
|
||||
chartAreaCollapse: false,
|
||||
datasetAreaCollapse: false
|
||||
},
|
||||
canvasState: {
|
||||
curPointArea: 'base' // 当前焦点所在画布区域 base 主画布区域 hidden 隐藏画布区域
|
||||
},
|
||||
embeddedCallBack: 'no', // 嵌入模式是否允许反馈参数
|
||||
editMode: 'preview', // 编辑器模式 edit preview
|
||||
mobileInPc: false,
|
||||
@ -278,6 +281,18 @@ export const dvMainStore = defineStore('dataVisualization', {
|
||||
}
|
||||
this.curComponent = component
|
||||
this.curComponentIndex = index
|
||||
// 更新当前活动区域
|
||||
if (this.curComponent && this.curComponent['category']) {
|
||||
// 如果是图片 且图片配置了切换显示区
|
||||
if (
|
||||
this.curComponent.component !== 'Picture' ||
|
||||
(this.curComponent.component === 'Picture' &&
|
||||
(!this.curComponent.events?.checked ||
|
||||
this.curComponent.events?.type !== 'displayChange'))
|
||||
) {
|
||||
this.canvasState['curPointArea'] = this.curComponent['category']
|
||||
}
|
||||
}
|
||||
},
|
||||
setBashMatrixInfo(bashMatrixInfo) {
|
||||
this.bashMatrixInfo = bashMatrixInfo
|
||||
@ -1178,6 +1193,18 @@ export const dvMainStore = defineStore('dataVisualization', {
|
||||
}
|
||||
}
|
||||
},
|
||||
popAreaActiveSwitch() {
|
||||
if (this.canvasState['curPointArea'] === 'base') {
|
||||
this.canvasState['curPointArea'] = 'hidden'
|
||||
} else {
|
||||
this.canvasState['curPointArea'] = 'base'
|
||||
}
|
||||
},
|
||||
canvasStateChange({ key, value }) {
|
||||
if (this.canvasState[key] && value) {
|
||||
this.canvasState[key] = value
|
||||
}
|
||||
},
|
||||
createInit(dvType, resourceId?, pid?, watermarkInfo?) {
|
||||
const optName = dvType === 'dashboard' ? '新建仪表板' : '新建数据大屏'
|
||||
this.dvInfo = {
|
||||
|
@ -17,6 +17,7 @@ export const eventStore = defineStore('event', {
|
||||
|
||||
displayEventChange(component) {
|
||||
component.events.displayChange.value = !component.events.displayChange.value
|
||||
dvMainStore.canvasStateChange({ key: 'curPointArea', value: area })
|
||||
componentData.value.forEach(item => {
|
||||
if (item.category === 'hidden') {
|
||||
item.isShow = component.events.displayChange.value
|
||||
|
@ -123,6 +123,8 @@ export function historyAdaptor(
|
||||
//历史字段适配
|
||||
canvasStyleResult.component['seniorStyleSetting'] =
|
||||
canvasStyleResult.component['seniorStyleSetting'] || deepCopy(SENIOR_STYLE_SETTING_LIGHT)
|
||||
canvasStyleResult['popupAvailable'] =
|
||||
canvasStyleResult['popupAvailable'] === undefined ? true : canvasStyleResult['popupAvailable'] //兼容弹框区域开关
|
||||
const reportFilterInfo = canvasInfo.reportFilterInfo
|
||||
canvasDataResult.forEach(componentItem => {
|
||||
componentItem['canvasActive'] = false
|
||||
|
@ -33,6 +33,8 @@ import DeStreamMedia from '@/custom-component/de-stream-media/Component.vue'
|
||||
import DeStreamMediaAttr from '@/custom-component/de-stream-media/Attr.vue'
|
||||
import ScrollText from '@/custom-component/scroll-text/Component.vue'
|
||||
import ScrollTextAttr from '@/custom-component/scroll-text/Attr.vue'
|
||||
import PopArea from '@/custom-component/pop-area/Component.vue'
|
||||
import PopAreaAttr from '@/custom-component/pop-area/Attr.vue'
|
||||
export const componentsMap = {
|
||||
VText: VText,
|
||||
VQuery,
|
||||
@ -68,7 +70,9 @@ export const componentsMap = {
|
||||
DeStreamMedia: DeStreamMedia,
|
||||
DeStreamMediaAttr: DeStreamMediaAttr,
|
||||
ScrollText: ScrollText,
|
||||
ScrollTextAttr: ScrollTextAttr
|
||||
ScrollTextAttr: ScrollTextAttr,
|
||||
PopArea: PopArea,
|
||||
PopAreaAttr: PopAreaAttr
|
||||
}
|
||||
|
||||
export default function findComponent(key) {
|
||||
|
@ -84,6 +84,7 @@ export const DEFAULT_CANVAS_STYLE_DATA_BASE = {
|
||||
refreshViewLoading: true, // 仪表板图表loading提示
|
||||
refreshUnit: 'minute', // 仪表板刷新时间带外 默认 分钟
|
||||
refreshTime: 5, // 仪表板刷新时间 默认5分钟
|
||||
popupAvailable: true, // 弹窗区域是否可用 默认为true
|
||||
scale: 60,
|
||||
scaleWidth: 100,
|
||||
scaleHeight: 100,
|
||||
|
@ -78,7 +78,8 @@ const {
|
||||
canvasStyleData,
|
||||
canvasViewInfo,
|
||||
editMode,
|
||||
dvInfo
|
||||
dvInfo,
|
||||
canvasState
|
||||
} = storeToRefs(dvMainStore)
|
||||
const { editorMap } = storeToRefs(composeStore)
|
||||
const canvasOut = ref(null)
|
||||
@ -122,6 +123,18 @@ const handleNew = newComponentInfo => {
|
||||
component.style.top = ((height - component.style.height) * scale) / 200
|
||||
component.style.left = ((width - component.style.width) * scale) / 200
|
||||
component.id = guid()
|
||||
const popComponents = componentData.value.filter(
|
||||
ele => ele.category && ele.category === 'hidden'
|
||||
)
|
||||
// 弹框区域组件 只允许有一个过滤组件
|
||||
if (
|
||||
canvasState.value.curPointArea === 'hidden' &&
|
||||
component.component === 'VQuery' &&
|
||||
(!popComponents || popComponents.length === 0)
|
||||
) {
|
||||
component.category = canvasState.value.curPointArea
|
||||
component.commonBackground.backgroundColor = 'rgba(41, 41, 41, 1)'
|
||||
}
|
||||
changeComponentSizeWithScale(component)
|
||||
dvMainStore.addComponent({ component: component, index: undefined })
|
||||
adaptCurThemeCommonStyle(component)
|
||||
@ -130,6 +143,7 @@ const handleNew = newComponentInfo => {
|
||||
}
|
||||
|
||||
const handleDrop = e => {
|
||||
console.log('===handleDrop2')
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
const componentInfo = e.dataTransfer.getData('id')
|
||||
@ -369,6 +383,14 @@ const scrollCanvas = e => {
|
||||
deHRulerRef.value.rulerScroll(e)
|
||||
}
|
||||
|
||||
const coreComponentData = computed(() =>
|
||||
componentData.value.filter(ele => !ele.category || ele.category !== 'hidden')
|
||||
)
|
||||
|
||||
const popComponentData = computed(() =>
|
||||
componentData.value.filter(ele => ele.category && ele.category === 'hidden')
|
||||
)
|
||||
|
||||
eventBus.on('handleNew', handleNew)
|
||||
</script>
|
||||
|
||||
@ -389,7 +411,7 @@ eventBus.on('handleNew', handleNew)
|
||||
>
|
||||
<!-- 左侧组件列表 -->
|
||||
<dv-sidebar
|
||||
:title="'图层'"
|
||||
:title="'图层管理'"
|
||||
:width="180"
|
||||
:scroll-width="3"
|
||||
:aside-position="'left'"
|
||||
@ -429,7 +451,8 @@ eventBus.on('handleNew', handleNew)
|
||||
class="canvas-area-shadow editor-main"
|
||||
v-if="state.canvasInitStatus"
|
||||
ref="mainCanvasCoreRef"
|
||||
:component-data="componentData"
|
||||
:component-data="coreComponentData"
|
||||
:pop-component-data="popComponentData"
|
||||
:canvas-style-data="canvasStyleData"
|
||||
:canvas-view-info="canvasViewInfo"
|
||||
:canvas-id="state.canvasId"
|
||||
|
Loading…
Reference in New Issue
Block a user