Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2069aa6f0 | ||
|
|
f2c19fa834 | ||
|
|
b7f197587d | ||
|
|
f343ac3fb5 | ||
|
|
91e3115faa | ||
|
|
9bf1b4ed8e | ||
|
|
ad97b7cc94 | ||
|
|
503b1db3f2 | ||
|
|
cbbaba7e2f | ||
|
|
6a44561b3a | ||
|
|
b6874241b2 | ||
|
|
24af8ed413 | ||
|
|
5fb3048fa9 | ||
|
|
4d27edfe46 | ||
|
|
2027b9a8e4 | ||
|
|
c1fa037bde | ||
|
|
4907e74e27 | ||
|
|
918b8be1c4 | ||
|
|
3275b63b62 | ||
|
|
fc0daad7ce | ||
|
|
14e6f14867 | ||
|
|
a194bd00b3 |
@ -155,6 +155,7 @@ const backHandler = (url: string) => {
|
||||
openHandler.value.invokeMethod(pm)
|
||||
return
|
||||
}
|
||||
dvMainStore.canvasStateChange({ key: 'curPointArea', value: 'base' })
|
||||
wsCache.delete('DE-DV-CATCH-' + dvInfo.value.id)
|
||||
window.open(url, '_self')
|
||||
}
|
||||
@ -191,6 +192,11 @@ const openOuterParamsSet = () => {
|
||||
const multiplexingCanvasOpen = () => {
|
||||
multiplexingRef.value.dialogInit('dataV')
|
||||
}
|
||||
|
||||
const fullScreenPreview = () => {
|
||||
dvMainStore.canvasStateChange({ key: 'curPointArea', value: 'base' })
|
||||
fullScreeRef.value.toggleFullscreen()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -305,12 +311,7 @@ const multiplexingCanvasOpen = () => {
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-else
|
||||
class="preview-button"
|
||||
@click="() => fullScreeRef.toggleFullscreen()"
|
||||
style="float: right"
|
||||
>
|
||||
<el-button v-else class="preview-button" @click="fullScreenPreview" style="float: right">
|
||||
预览
|
||||
</el-button>
|
||||
<el-button
|
||||
|
||||
@ -3,15 +3,16 @@ 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'
|
||||
import ComposeShow from '@/components/data-visualization/canvas/ComposeShow.vue'
|
||||
import { composeStoreWithOut } from '@/store/modules/data-visualization/compose'
|
||||
import RealTimeGroup from '@/components/data-visualization/RealTimeGroup.vue'
|
||||
import { contextmenuStoreWithOut } from '@/store/modules/data-visualization/contextmenu'
|
||||
const dropdownMore = ref(null)
|
||||
const lockStore = lockStoreWithOut()
|
||||
|
||||
@ -19,10 +20,12 @@ const dvMainStore = dvMainStoreWithOut()
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const layerStore = layerStoreWithOut()
|
||||
const composeStore = composeStoreWithOut()
|
||||
const contextmenuStore = contextmenuStoreWithOut()
|
||||
|
||||
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 +37,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,7 +69,18 @@ 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) => {
|
||||
contextmenuStore.hideContextMenu()
|
||||
// 初始化点击是 laterIndex=0
|
||||
if (!curComponent.value) {
|
||||
composeStore.setLaterIndex(null)
|
||||
@ -149,6 +170,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
|
||||
@ -172,12 +201,24 @@ const getIconName = item => {
|
||||
}
|
||||
}
|
||||
|
||||
const menuAsideHiddenClose = (param, element) => {
|
||||
const iconDom = document.getElementById('close-button')
|
||||
if (iconDom) {
|
||||
iconDom.click()
|
||||
}
|
||||
if (param?.opt === 'rename') {
|
||||
setTimeout(() => {
|
||||
editComponentName(element)
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
|
||||
const menuAsideClose = (param, index) => {
|
||||
const iconDom = document.getElementById('close-button')
|
||||
if (iconDom) {
|
||||
iconDom.click()
|
||||
}
|
||||
if (param.opt === 'rename') {
|
||||
if (param?.opt === 'rename') {
|
||||
setTimeout(() => {
|
||||
editComponentName(getComponent(index))
|
||||
}, 200)
|
||||
@ -204,12 +245,97 @@ 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="hiddenAreaOnClick($event, element)"
|
||||
>
|
||||
<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="menuAsideHiddenClose($event, element)"
|
||||
></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 +348,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="{
|
||||
@ -434,7 +563,6 @@ const handleContextMenu = e => {
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
cursor: none;
|
||||
i {
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
@ -519,6 +647,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">
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
</style>
|
||||
@ -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,12 +117,14 @@ onMounted(() => {
|
||||
})
|
||||
})
|
||||
|
||||
const onClick = () => {
|
||||
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 => {
|
||||
@ -192,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()
|
||||
@ -80,7 +84,15 @@ const show = () => {
|
||||
layerStore.showComponent()
|
||||
menuOpt('show')
|
||||
}
|
||||
|
||||
const categoryChange = type => {
|
||||
if (curComponent.value) {
|
||||
snapshotStore.recordSnapshotCache()
|
||||
curComponent.value['category'] = type
|
||||
if (type === 'hidden') {
|
||||
dvMainStore.canvasStateChange({ key: 'curPointArea', value: 'hidden' })
|
||||
}
|
||||
}
|
||||
}
|
||||
const rename = () => {
|
||||
emit('rename')
|
||||
menuOpt('rename')
|
||||
@ -153,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(() => {
|
||||
@ -211,14 +228,33 @@ 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>
|
||||
@ -231,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>
|
||||
|
||||
@ -9,14 +9,17 @@ import { storeToRefs } from 'pinia'
|
||||
import elementResizeDetectorMaker from 'element-resize-detector'
|
||||
import UserViewEnlarge from '@/components/visualization/UserViewEnlarge.vue'
|
||||
import CanvasOptBar from '@/components/visualization/CanvasOptBar.vue'
|
||||
import { isMainCanvas } from '@/utils/canvasUtils'
|
||||
import { isDashboard, isMainCanvas } from '@/utils/canvasUtils'
|
||||
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'
|
||||
import CanvasFilterBtn from '@/custom-component/canvas-filter-btn/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: {
|
||||
type: Object,
|
||||
@ -96,6 +99,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)) {
|
||||
@ -153,7 +164,9 @@ const resetLayout = () => {
|
||||
let canvasHeight = previewCanvas.value.clientHeight
|
||||
scaleWidth.value = Math.floor((canvasWidth * 100) / canvasStyleData.value.width)
|
||||
scaleHeight.value = Math.floor((canvasHeight * 100) / canvasStyleData.value.height)
|
||||
scaleMin.value = Math.min(scaleWidth.value, scaleHeight.value)
|
||||
scaleMin.value = isDashboard()
|
||||
? Math.min(scaleWidth.value, scaleHeight.value)
|
||||
: (canvasWidth * 100) / canvasStyleData.value.width
|
||||
if (dashboardActive.value) {
|
||||
cellWidth.value = canvasWidth / pcMatrixCount.value.x
|
||||
cellHeight.value = canvasHeight / pcMatrixCount.value.y
|
||||
@ -161,7 +174,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
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -248,7 +265,7 @@ const winMsgHandle = event => {
|
||||
) {
|
||||
const attachParams = msgInfo.params
|
||||
if (attachParams) {
|
||||
dvMainStore.addOuterParamsFilter(attachParams, componentData.value, 'outer')
|
||||
dvMainStore.addOuterParamsFilter(attachParams, baseComponentData.value, 'outer')
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -266,6 +283,8 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
//初始化隐藏弹框区
|
||||
dvMainStore.canvasStateChange({ key: 'curPointArea', value: 'base' })
|
||||
clearInterval(refreshTimer.value)
|
||||
window.removeEventListener('message', winMsgHandle)
|
||||
})
|
||||
@ -280,6 +299,9 @@ const userViewEnlargeOpen = (opt, item) => {
|
||||
}
|
||||
const handleMouseDown = () => {
|
||||
dvMainStore.setCurComponent({ component: null, index: null })
|
||||
if (!curComponent.value || (curComponent.value && curComponent.value.category !== 'hidden')) {
|
||||
dvMainStore.canvasStateChange({ key: 'curPointArea', value: 'base' })
|
||||
}
|
||||
}
|
||||
|
||||
const onPointClick = param => {
|
||||
@ -307,6 +329,16 @@ const onPointClick = param => {
|
||||
console.warn('de_inner_params send error')
|
||||
}
|
||||
}
|
||||
|
||||
// v-if 使用 内容不渲染 默认参数不起用
|
||||
const popAreaAvailable = computed(
|
||||
() => canvasStyleData.value?.popupAvailable && isMainCanvas(canvasId.value)
|
||||
)
|
||||
|
||||
const filterBtnShow = computed(
|
||||
() => popAreaAvailable.value && popComponentData.value && popComponentData.value.length > 0
|
||||
)
|
||||
|
||||
defineExpose({
|
||||
restore
|
||||
})
|
||||
@ -317,16 +349,31 @@ defineExpose({
|
||||
:id="domId"
|
||||
class="canvas-container"
|
||||
:style="canvasStyle"
|
||||
:class="{ 'de-download-custom': downloadStatus }"
|
||||
ref="previewCanvas"
|
||||
@mousedown="handleMouseDown"
|
||||
>
|
||||
<!--弹框触发区域-->
|
||||
<canvas-filter-btn v-if="filterBtnShow"></canvas-filter-btn>
|
||||
<!-- 弹框区域 -->
|
||||
<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"
|
||||
|
||||
@ -304,7 +304,7 @@ const boardMoveActive = computed(() => {
|
||||
'symbolic-map',
|
||||
'heat-map'
|
||||
]
|
||||
return CHARTS.includes(element.value.innerType)
|
||||
return element.value.isPlugin || CHARTS.includes(element.value.innerType)
|
||||
})
|
||||
|
||||
const dashboardActive = computed(() => {
|
||||
|
||||
@ -94,7 +94,7 @@ const invokeMethod = param => {
|
||||
if (pluginProxy.value['invokeMethod']) {
|
||||
pluginProxy.value['invokeMethod'](param)
|
||||
} else {
|
||||
pluginProxy.value[param.methodName](param.args)
|
||||
pluginProxy.value[param.methodName]?.(...param.args)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
<!-- IconSlider.vue -->
|
||||
<template>
|
||||
<el-tooltip offset="18" effect="dark" placement="left" content="查询">
|
||||
<div class="canvas-filter" @mousedown.stop @mousedup.stop>
|
||||
<div class="icon-slider" @mouseenter="slideOut" @mouseleave="slideBack">
|
||||
<div
|
||||
class="icon-container"
|
||||
:class="{ 'icon-container-active': filterActive }"
|
||||
:style="{ transform: `translateX(${offset}px)` }"
|
||||
@click="popAreaActiveChange"
|
||||
>
|
||||
<el-icon><Filter /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import { ElTooltip } from 'element-plus-secondary'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const offset = ref(0)
|
||||
const slideDistance = ref(14) // 滑动距离
|
||||
const { canvasState } = storeToRefs(dvMainStore)
|
||||
|
||||
const filterActive = computed(() => canvasState.value.curPointArea === 'hidden')
|
||||
const slideOut = () => {
|
||||
offset.value = -slideDistance.value
|
||||
}
|
||||
|
||||
const popAreaActiveChange = () => {
|
||||
dvMainStore.popAreaActiveSwitch()
|
||||
}
|
||||
const slideBack = () => {
|
||||
offset.value = 0
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.canvas-filter {
|
||||
position: absolute;
|
||||
right: -14px;
|
||||
bottom: 50px;
|
||||
width: 28px;
|
||||
height: 32px;
|
||||
}
|
||||
.icon-slider {
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
width: 28px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
transition: transform 0.3s ease; /* 过渡动画 */
|
||||
background: rgba(26, 26, 26, 1);
|
||||
font-size: 14px;
|
||||
border: 1px solid rgba(67, 67, 67, 1);
|
||||
border-radius: 16px 0 0 16px;
|
||||
padding: 6px 0 0 6px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: rgba(235, 235, 235, 0.1);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: rgba(235, 235, 235, 0.2);
|
||||
}
|
||||
}
|
||||
.icon-container-active {
|
||||
transform: translateX(-14px) !important;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
</style>
|
||||
@ -9,6 +9,7 @@ import { useI18n } from '@/hooks/web/useI18n'
|
||||
import elementResizeDetectorMaker from 'element-resize-detector'
|
||||
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||
import CommonStyleSet from '@/custom-component/common/CommonStyleSet.vue'
|
||||
import CommonEvent from '@/custom-component/common/CommonEvent.vue'
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
|
||||
const { t } = useI18n()
|
||||
@ -87,6 +88,12 @@ const colorPickerWidth = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
// 暂时关闭
|
||||
const eventsShow = computed(() => {
|
||||
return false
|
||||
// return !dashboardActive.value && ['Picture'].includes(element.value.component)
|
||||
})
|
||||
|
||||
const backgroundCustomShow = computed(() => {
|
||||
return (
|
||||
dashboardActive.value ||
|
||||
@ -149,6 +156,15 @@ const stopEvent = e => {
|
||||
:element="element"
|
||||
></common-style-set>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item
|
||||
v-if="element && element.events && eventsShow"
|
||||
:effect="themes"
|
||||
title="事件"
|
||||
name="style"
|
||||
class="common-style-area"
|
||||
>
|
||||
<common-event :themes="themes" :element="element"></common-event>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, toRefs } from 'vue'
|
||||
import { ElFormItem } from 'element-plus-secondary'
|
||||
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
themes?: EditorTheme
|
||||
element: any
|
||||
}>(),
|
||||
{
|
||||
themes: 'dark'
|
||||
}
|
||||
)
|
||||
const { themes, element } = toRefs(props)
|
||||
|
||||
const eventsInfo = computed(() => {
|
||||
return element.value.events
|
||||
})
|
||||
|
||||
const onEventChange = () => {
|
||||
snapshotStore.recordSnapshotCache('renderChart')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-row class="custom-row">
|
||||
<el-form label-position="top">
|
||||
<el-form-item class="form-item" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
:effect="themes"
|
||||
size="small"
|
||||
v-model="eventsInfo.checked"
|
||||
@change="onEventChange"
|
||||
>开启事件绑定</el-checkbox
|
||||
>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="form-item" :class="'form-item-' + themes" style="margin-bottom: 8px">
|
||||
<el-radio-group
|
||||
:effect="themes"
|
||||
v-model="eventsInfo.type"
|
||||
class="radio-span"
|
||||
@change="onEventChange"
|
||||
>
|
||||
<el-radio label="displayChange" :effect="themes"> 开启弹框区 </el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
@ -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;
|
||||
|
||||
@ -8,6 +8,18 @@ export const commonStyle = {
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
export const BASE_EVENTS = {
|
||||
checked: false,
|
||||
type: 'displayChange', // openHidden jump
|
||||
jump: {
|
||||
value: null
|
||||
},
|
||||
displayChange: {
|
||||
value: true, // 事件当前值 false
|
||||
target: 'all'
|
||||
}
|
||||
}
|
||||
|
||||
// 流媒体视频信息配置
|
||||
export const STREAMMEDIALINKS = {
|
||||
videoType: 'flv',
|
||||
@ -159,12 +171,13 @@ export const COMMON_COMPONENT_BACKGROUND_MAP = {
|
||||
export const commonAttr = {
|
||||
animations: [],
|
||||
canvasId: 'canvas-main',
|
||||
events: {},
|
||||
events: BASE_EVENTS,
|
||||
groupStyle: {}, // 当一个组件成为 Group 的子组件时使用
|
||||
isLock: false, // 是否锁定组件
|
||||
maintainRadio: false, // 布局时保持宽高比例
|
||||
aspectRatio: 1, // 锁定时的宽高比例
|
||||
isShow: true, // 是否显示组件
|
||||
category: 'base', //组件类型 base 基础组件 hidden隐藏组件
|
||||
// 当前组件动作
|
||||
dragging: false,
|
||||
resizing: false,
|
||||
|
||||
@ -4,7 +4,7 @@ import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import CanvasGroup from '@/custom-component/common/CanvasGroup.vue'
|
||||
import { deepCopy } from '@/utils/utils'
|
||||
import { DEFAULT_CANVAS_STYLE_DATA_DARK } from '@/views/chart/components/editor/util/dataVisualiztion'
|
||||
import { DEFAULT_CANVAS_STYLE_DATA_DARK } from '@/views/chart/components/editor/util/dataVisualization'
|
||||
import { groupSizeStyleAdaptor } from '@/utils/style'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { canvasStyleData, curComponent } = storeToRefs(dvMainStore)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="pic-main">
|
||||
<div class="pic-main" @click="onPictureClick">
|
||||
<img
|
||||
draggable="false"
|
||||
v-if="propValue['url']"
|
||||
@ -20,6 +20,9 @@
|
||||
import { CSSProperties, computed, nextTick, toRefs } from 'vue'
|
||||
import { imgUrlTrans } from '@/utils/imgUtils'
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
|
||||
const props = defineProps({
|
||||
propValue: {
|
||||
type: String,
|
||||
@ -46,7 +49,16 @@ const imageAdapter = computed(() => {
|
||||
}
|
||||
return style as CSSProperties
|
||||
})
|
||||
|
||||
const onPictureClick = e => {
|
||||
if (element.value.events && element.value.events.checked) {
|
||||
if (element.value.events.type === 'displayChange') {
|
||||
// 打开弹框区域
|
||||
nextTick(() => {
|
||||
dvMainStore.popAreaActiveSwitch()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
const uploadImg = () => {
|
||||
nextTick(() => {
|
||||
eventBus.emit('uploadImg')
|
||||
@ -59,6 +71,7 @@ const uploadImg = () => {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
.pic-upload {
|
||||
display: flex;
|
||||
|
||||
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.stop @mousedup.stop>
|
||||
<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>
|
||||
@ -178,7 +178,7 @@ const showTypeError = computed(() => {
|
||||
})
|
||||
|
||||
const showDatasetError = computed(() => {
|
||||
if (!curComponent.value) return false
|
||||
if (!curComponent.value || curComponent.value.displayType !== '9') return false
|
||||
if (!curComponent.value.checkedFields?.length) return false
|
||||
if (!fields.value?.length) return false
|
||||
let displayField = null
|
||||
|
||||
@ -108,6 +108,7 @@ export const copyStore = defineStore('copy', {
|
||||
// 旧-新ID映射关系
|
||||
const idMap = {}
|
||||
const newComponent = deepCopyHelper(data, idMap)
|
||||
newComponent['category'] = 'base'
|
||||
if (newComponent.canvasId.includes('Group')) {
|
||||
newComponent.canvasId = 'canvas-main'
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ import {
|
||||
DEFAULT_CANVAS_STYLE_DATA_DARK,
|
||||
DEFAULT_CANVAS_STYLE_DATA_LIGHT,
|
||||
DEFAULT_CANVAS_STYLE_DATA_SCREEN_DARK
|
||||
} from '@/views/chart/components/editor/util/dataVisualiztion'
|
||||
} from '@/views/chart/components/editor/util/dataVisualization'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import chartViewManager from '@/views/chart/components/js/panel'
|
||||
import {
|
||||
@ -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 = {
|
||||
|
||||
@ -3,7 +3,7 @@ import { store } from '../../index'
|
||||
import { dvMainStoreWithOut } from './dvMain'
|
||||
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { curComponent } = storeToRefs(dvMainStore)
|
||||
const { curComponent, componentData } = storeToRefs(dvMainStore)
|
||||
|
||||
export const eventStore = defineStore('event', {
|
||||
actions: {
|
||||
@ -13,6 +13,16 @@ export const eventStore = defineStore('event', {
|
||||
|
||||
removeEvent(event) {
|
||||
delete curComponent.value.events[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
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -2,7 +2,7 @@ import { defineStore, storeToRefs } from 'pinia'
|
||||
import { store } from '../../index'
|
||||
import { dvMainStoreWithOut } from './dvMain'
|
||||
import { deepCopy } from '@/utils/utils'
|
||||
import { BASE_THEMES } from '@/views/chart/components/editor/util/dataVisualiztion'
|
||||
import { BASE_THEMES } from '@/views/chart/components/editor/util/dataVisualization'
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
|
||||
@ -510,3 +510,9 @@ strong {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.de-download-custom {
|
||||
div {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -67,6 +67,9 @@ export function download2AppTemplate(downloadType, canvasDom, name, callBack?) {
|
||||
})
|
||||
})
|
||||
} catch (e) {
|
||||
if (callBack) {
|
||||
callBack()
|
||||
}
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
@ -96,6 +99,9 @@ export function downloadCanvas2(type, canvasDom, name, callBack?) {
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
if (callBack) {
|
||||
callBack()
|
||||
}
|
||||
console.error('oops, something went wrong!', error)
|
||||
})
|
||||
}
|
||||
|
||||
@ -214,6 +214,7 @@ if (!chart.value.customStyle.component.hasOwnProperty('labelShow')) {
|
||||
<el-input-number
|
||||
v-model="chart.customStyle.component.queryConditionWidth"
|
||||
:min="0"
|
||||
:effect="themes"
|
||||
controls-position="right"
|
||||
/>
|
||||
</el-form-item>
|
||||
@ -226,6 +227,7 @@ if (!chart.value.customStyle.component.hasOwnProperty('labelShow')) {
|
||||
<el-input-number
|
||||
v-model="chart.customStyle.component.queryConditionSpacing"
|
||||
:min="0"
|
||||
:effect="themes"
|
||||
controls-position="right"
|
||||
/>
|
||||
</el-form-item>
|
||||
@ -249,8 +251,8 @@ if (!chart.value.customStyle.component.hasOwnProperty('labelShow')) {
|
||||
:class="'form-item-' + themes"
|
||||
>
|
||||
<el-radio-group :effect="themes" v-model="chart.customStyle.component.layout">
|
||||
<el-radio label="vertical"> 上侧 </el-radio>
|
||||
<el-radio label="horizontal"> 左侧 </el-radio>
|
||||
<el-radio label="vertical" :effect="themes"> 上侧 </el-radio>
|
||||
<el-radio label="horizontal" :effect="themes"> 左侧 </el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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,
|
||||
@ -842,8 +842,8 @@ function getTooltipPosition(event) {
|
||||
return result
|
||||
}
|
||||
|
||||
export async function exportPivotExcel(instancce: PivotSheet, chart: ChartObj) {
|
||||
const { meta, fields } = instancce.dataCfg
|
||||
export async function exportPivotExcel(instance: PivotSheet, chart: ChartObj) {
|
||||
const { meta, fields } = instance.dataCfg
|
||||
const rowLength = fields?.rows?.length || 0
|
||||
const colLength = fields?.columns?.length || 0
|
||||
const valueLength = fields?.values?.length || 0
|
||||
@ -873,7 +873,7 @@ export async function exportPivotExcel(instancce: PivotSheet, chart: ChartObj) {
|
||||
cell.value = metaMap[row]?.name ?? row
|
||||
cell.alignment = { vertical: 'middle', horizontal: 'center' }
|
||||
})
|
||||
const { layoutResult } = instancce.facet
|
||||
const { layoutResult } = instance.facet
|
||||
// 行头
|
||||
const { rowLeafNodes, rowsHierarchy, rowNodes } = layoutResult
|
||||
const maxColIndex = rowsHierarchy.maxLevel + 1
|
||||
|
||||
@ -242,7 +242,7 @@ watch([() => resultMode.value], () => {
|
||||
|
||||
watch([() => scale.value], () => {
|
||||
nextTick(() => {
|
||||
chartComponent?.value?.renderChart(view.value)
|
||||
chartComponent?.value?.renderChart?.(view.value)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -30,7 +30,7 @@ import treeSort from '@/utils/treeSortUtils'
|
||||
import {
|
||||
DEFAULT_CANVAS_STYLE_DATA_LIGHT,
|
||||
DEFAULT_CANVAS_STYLE_DATA_SCREEN_DARK
|
||||
} from '@/views/chart/components/editor/util/dataVisualiztion'
|
||||
} from '@/views/chart/components/editor/util/dataVisualization'
|
||||
import type { TabPaneName } from 'element-plus-secondary'
|
||||
import { timestampFormatDate } from './form/util'
|
||||
import { interactiveStoreWithOut } from '@/store/modules/interactive'
|
||||
|
||||
2
pom.xml
2
pom.xml
@ -19,7 +19,7 @@
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<dataease.version>2.8.0</dataease.version>
|
||||
<dataease.version>2.8.1</dataease.version>
|
||||
<java.version>21</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<spring-cloud-alibaba.version>2023.0.1.0</spring-cloud-alibaba.version>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user