Merge pull request #8590 from dataease/pr@dev-v2@feat_batch-move

feat(数据大屏): 鼠标选中一些区域后,区域内的组件可通过滑动鼠标,批量移动
This commit is contained in:
王嘉豪 2024-03-19 18:41:43 +08:00 committed by GitHub
commit 2776131b7e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 127 additions and 23 deletions

View File

@ -221,6 +221,7 @@ const handleContextMenu = e => {
<template #item="{ index }">
<div>
<div
v-show="getComponent(index)?.component !== 'GroupArea'"
:title="getComponent(index)?.name"
class="component-item"
:class="{

View File

@ -9,7 +9,7 @@ import {
syncShapeItemStyle
} from '@/utils/style'
import $ from 'jquery'
import { _$, isPreventDrop } from '@/utils/utils'
import { _$, deepCopy, isPreventDrop } from '@/utils/utils'
import ContextMenu from './ContextMenu.vue'
import MarkLine from './MarkLine.vue'
import Area from './Area.vue'
@ -26,6 +26,7 @@ import DragShadow from '@/components/data-visualization/canvas/DragShadow.vue'
import {
canvasSave,
findDragComponent,
findNewComponent,
isGroupCanvas,
isMainCanvas,
isSameCanvas
@ -396,6 +397,7 @@ const hideArea = () => {
},
components: []
})
groupAreaChange(false)
}
const createGroup = () => {
@ -442,19 +444,23 @@ const createGroup = () => {
width.value = right - left
height.value = bottom - top
const areaDataStyle = {
left,
top,
width: width.value,
height: height.value
}
//
composeStore.setAreaData({
style: {
left,
top,
width: width.value,
height: height.value
},
style: areaDataStyle,
components: areaData
})
// group
if (areaData.length > 0) {
dvMainStore.setCurComponent({ component: null, index: null })
isShowArea.value = false
groupAreaChange(true, areaDataStyle)
}
}
@ -1346,6 +1352,21 @@ const contextMenuShow = computed(() => {
const markLineShow = computed(() => isMainCanvas(canvasId.value))
const groupAreaChange = (showArea, style?) => {
nextTick(() => {
if (showArea) {
const groupArea = findNewComponent('GroupArea', 'GroupArea')
groupArea.style.left = style.left
groupArea.style.top = style.top
groupArea.style.width = style.width
groupArea.style.height = style.height
dvMainStore.addComponent({ component: groupArea, index: undefined })
} else {
dvMainStore.deleteComponentById(100000001)
}
})
}
onMounted(() => {
if (isMainCanvas(canvasId.value)) {
initSnapshotTimer()

View File

@ -1,5 +1,11 @@
<template>
<div class="shape" ref="shapeInnerRef" :id="domId" @dblclick="handleDbClick">
<div
class="shape"
:class="{ 'shape-group-area': isGroupArea }"
ref="shapeInnerRef"
:id="domId"
@dblclick="handleDbClick"
>
<div v-if="showCheck" class="del-from-mobile" @click="delFromMobile">
<el-icon>
<Icon name="mobile-checkbox"></Icon>
@ -49,6 +55,7 @@
</div>
<div
v-for="item in isActive() ? getPointList() : []"
v-show="!isGroupArea"
:key="item"
class="shape-point"
:style="getPointStyle(item)"
@ -280,6 +287,10 @@ const angleToCursor = [
{ start: 293, end: 338, cursor: 'w' }
]
const isGroupArea = computed(() => {
return curComponent.value?.component === 'GroupArea'
})
const active = computed(() => {
return curComponent.value?.id === element.value.id
})
@ -518,16 +529,19 @@ const handleMouseDownOnShape = e => {
isFirst = false
}
//
dvMainStore.setShapeStyle(pos)
dvMainStore.setShapeStyle(pos, areaData.value.components)
//
// 使 $nextTick
nextTick(() => {
// 线
//
// curY - startY > 0 true false
// curX - startX > 0 true false
eventBus.emit('move', { isDownward: curY - startY > 0, isRightward: curX - startX > 0 })
})
// GroupArea
// 使 nextTick
if (!isGroupArea.value) {
nextTick(() => {
// 线
//
// curY - startY > 0 true false
// curX - startX > 0 true false
eventBus.emit('move', { isDownward: curY - startY > 0, isRightward: curX - startX > 0 })
})
}
}
const up = () => {
@ -754,7 +768,7 @@ const commonBackgroundSvgInner = computed(() => {
})
const componentBackgroundStyle = computed(() => {
if (element.value.commonBackground) {
if (element.value.commonBackground && element.value.component !== 'GroupArea') {
const {
backgroundColorSelect,
backgroundColor,
@ -937,6 +951,10 @@ onMounted(() => {
}
}
.shape-group-area {
z-index: 15;
}
.shape-shadow {
top: 0;
left: 0;

View File

@ -78,6 +78,19 @@ export const commonAttr = {
// 编辑器左侧组件列表
const list = [
{
id: 100000001,
component: 'GroupArea',
name: '组合区域',
label: '组合区域',
propValue: '&nbsp;',
icon: 'icon_graphical',
innerType: 'GroupArea',
style: {
width: 200,
height: 200
}
},
{
component: 'VQuery',
name: '查询',

View 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>

View File

@ -0,0 +1,13 @@
<template>
<div class="area"></div>
</template>
<script setup lang="ts"></script>
<style lang="less" scoped>
.area {
width: 100%;
height: 100%;
border: 1px solid #70c0ff;
}
</style>

View File

@ -254,7 +254,19 @@ export const dvMainStore = defineStore('dataVisualization', {
this.bashMatrixInfo = bashMatrixInfo
},
setShapeStyle({ top, left, width, height, rotate }) {
setShapeStyle({ top, left, width, height, rotate }, areaDataComponents = []) {
if (this.curComponent.component === 'GroupArea' && areaDataComponents.length > 0) {
const topOffset = top - this.curComponent.style.top
const leftOffset = left - this.curComponent.style.left
const widthOffset = width - this.curComponent.style.width
const heightOffset = height - this.curComponent.style.height
areaDataComponents.forEach(component => {
component.style.top = component.style.top + topOffset
component.style.left = component.style.left + leftOffset
component.style.width = component.style.width + widthOffset
component.style.height = component.style.height + heightOffset
})
}
if (this.dvInfo.type === 'dashboard') {
if (top) this.curComponent.style.top = top < 0 ? 0 : Math.round(top)
if (left) this.curComponent.style.left = left < 0 ? 0 : Math.round(left)

View File

@ -23,6 +23,8 @@ import SvgTriangle from '@/custom-component/svgs/svg-triangle/Component.vue'
import SvgTriangleAttr from '@/custom-component/svgs/svg-triangle/Attr.vue'
import DeTimeClock from '@/custom-component/de-time-clock/Component.vue'
import DeTimeClockAttr from '@/custom-component/de-time-clock/Attr.vue'
import GroupArea from '@/custom-component/group-area/Component.vue'
import GroupAreaAttr from '@/custom-component/group-area/Attr.vue'
export const componentsMap = {
VText: VText,
VQuery,
@ -48,7 +50,9 @@ export const componentsMap = {
SvgTriangle: SvgTriangle,
SvgTriangleAttr: SvgTriangleAttr,
DeTimeClock: DeTimeClock,
DeTimeClockAttr: DeTimeClockAttr
DeTimeClockAttr: DeTimeClockAttr,
GroupArea: GroupArea,
GroupAreaAttr: GroupAreaAttr
}
export default function findComponent(key) {

View File

@ -295,6 +295,15 @@ onUnmounted(() => {
const previewStatus = computed(() => editMode.value === 'preview')
const commonPropertiesShow = computed(
() => curComponent.value && !['UserView', 'GroupArea'].includes(curComponent.value.component)
)
const canvasPropertiesShow = computed(
() => !curComponent.value || ['GroupArea'].includes(curComponent.value.component)
)
const viewsPropertiesShow = computed(
() => curComponent.value && ['UserView'].includes(curComponent.value.component)
)
eventBus.on('handleNew', handleNew)
</script>
@ -348,7 +357,7 @@ eventBus.on('handleNew', handleNew)
<!-- 右侧侧组件列表 -->
<div style="width: auto; height: 100%" ref="leftSidebarRef">
<dv-sidebar
v-if="curComponent && !['UserView'].includes(curComponent.component)"
v-if="commonPropertiesShow"
:title="'属性'"
:width="240"
:side-name="'componentProp'"
@ -359,7 +368,7 @@ eventBus.on('handleNew', handleNew)
<component :is="findComponent(curComponent['component'] + 'Attr')" />
</dv-sidebar>
<dv-sidebar
v-show="!curComponent"
v-show="canvasPropertiesShow"
:title="'大屏配置'"
:width="240"
:side-name="'canvas'"
@ -370,7 +379,7 @@ eventBus.on('handleNew', handleNew)
<canvas-attr></canvas-attr>
</dv-sidebar>
<editor
v-show="curComponent && ['UserView'].includes(curComponent.component)"
v-show="viewsPropertiesShow"
:view="canvasViewInfo[curComponent ? curComponent.id : 'default']"
themes="dark"
:dataset-tree="state.datasetTree"