mirror of
https://github.com/dataease/dataease.git
synced 2026-05-15 13:32:18 +08:00
refactor(数据大屏): 保持比例填充展示模式优化 (#16716)
This commit is contained in:
@@ -100,6 +100,11 @@ const props = defineProps({
|
||||
showLinkageButton: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
outerScreenAdaptor: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null
|
||||
}
|
||||
})
|
||||
|
||||
@@ -115,7 +120,8 @@ const {
|
||||
outerScale,
|
||||
outerSearchCount,
|
||||
showPopBar,
|
||||
fontFamily
|
||||
fontFamily,
|
||||
outerScreenAdaptor
|
||||
} = toRefs(props)
|
||||
const domId = 'preview-' + canvasId.value
|
||||
const scaleWidthPoint = ref(100)
|
||||
@@ -136,17 +142,21 @@ const state = reactive({
|
||||
scrollMain: 0
|
||||
})
|
||||
|
||||
const screenAdaptor = computed(() => {
|
||||
return outerScreenAdaptor.value || canvasStyleData.value?.screenAdaptor
|
||||
})
|
||||
|
||||
const curSearchCount = computed(() => {
|
||||
return outerSearchCount.value + searchCount.value
|
||||
})
|
||||
// 大屏是否保持宽高比例 非全屏 full 都需要保持宽高比例
|
||||
const dataVKeepRadio = computed(() => {
|
||||
return canvasStyleData.value?.screenAdaptor !== 'full'
|
||||
return screenAdaptor.value !== 'full'
|
||||
})
|
||||
|
||||
// 仪表板是否跟随宽度缩放 非全屏 full 都需要保持宽高比例
|
||||
const dashboardScaleWithWidth = computed(() => {
|
||||
return isDashboard() && canvasStyleData.value?.dashboardAdaptor === 'withWidth'
|
||||
return isDashboard() && screenAdaptor.value === 'withWidth'
|
||||
})
|
||||
const isReport = computed(() => {
|
||||
return !!router.currentRoute.value.query?.report
|
||||
@@ -176,11 +186,11 @@ const canvasStyle = computed(() => {
|
||||
}
|
||||
if (canvasStyleData.value && canvasStyleData.value.width && isMainCanvas(canvasId.value)) {
|
||||
style = getCanvasStyle(canvasStyleData.value)
|
||||
if (canvasStyleData.value?.screenAdaptor === 'keep') {
|
||||
if (screenAdaptor.value === 'keep') {
|
||||
style['height'] = canvasStyleData.value?.height + 'px'
|
||||
style['width'] = canvasStyleData.value?.width + 'px'
|
||||
style['margin'] = 'auto'
|
||||
} else if (canvasStyleData.value?.screenAdaptor === 'keepProportion') {
|
||||
} else if (screenAdaptor.value === 'keepProportion') {
|
||||
style['aspect-ratio'] = canvasStyleData.value?.width / canvasStyleData.value?.height
|
||||
style['height'] = 'auto'
|
||||
style['width'] = 'auto'
|
||||
@@ -189,12 +199,11 @@ const canvasStyle = computed(() => {
|
||||
? downloadStatus.value
|
||||
? getDownloadStatusMainHeight()
|
||||
: '100%'
|
||||
: !canvasStyleData.value?.screenAdaptor ||
|
||||
canvasStyleData.value?.screenAdaptor === 'widthFirst'
|
||||
: !screenAdaptor.value || screenAdaptor.value === 'widthFirst'
|
||||
? changeStyleWithScale(canvasStyleData.value?.height, scaleMin.value) + 'px'
|
||||
: '100%'
|
||||
style['width'] =
|
||||
!dashboardActive.value && canvasStyleData.value?.screenAdaptor === 'heightFirst'
|
||||
!dashboardActive.value && screenAdaptor.value === 'heightFirst'
|
||||
? changeStyleWithScale(canvasStyleData.value?.width, scaleHeightPoint.value) + 'px'
|
||||
: '100%'
|
||||
}
|
||||
@@ -518,9 +527,15 @@ const scrollPreview = () => {
|
||||
}
|
||||
|
||||
const showUnpublishFlag = computed(() => dvInfo.value?.status === 0 && isMainCanvas(canvasId.value))
|
||||
|
||||
const getPreviewCanvasSize = () => {
|
||||
return {
|
||||
innerWidth: previewCanvas.value.clientWidth,
|
||||
innerHeight: previewCanvas.value.clientHeight
|
||||
}
|
||||
}
|
||||
defineExpose({
|
||||
restore,
|
||||
getPreviewCanvasSize,
|
||||
getDownloadStatusMainHeightV2
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -604,6 +604,7 @@ strong {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: inherit;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.preview-content-inner-height-first {
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import DePreview from '@/components/data-visualization/canvas/DePreview.vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { fullscreenFlag } = storeToRefs(dvMainStore)
|
||||
const dePreviewRef = ref(null)
|
||||
const dePreviewOuterRef = ref(null)
|
||||
const dataInitState = ref(true)
|
||||
const keepProportion = ref('heightFirst')
|
||||
const props = defineProps({
|
||||
canvasStylePreview: {
|
||||
required: true,
|
||||
@@ -30,6 +32,11 @@ const props = defineProps({
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 联动按钮位置
|
||||
showLinkageButton: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showPosition: {
|
||||
required: false,
|
||||
type: String,
|
||||
@@ -45,17 +52,14 @@ const props = defineProps({
|
||||
const restore = () => {
|
||||
dePreviewRef.value.restore()
|
||||
}
|
||||
|
||||
const contentInnerClass = computed(() => {
|
||||
//屏幕适配方式 widthFirst=宽度优先(默认) heightFirst=高度优先 full=铺满全屏 keepSize=不缩放
|
||||
if (props.canvasStylePreview.screenAdaptor === 'heightFirst') {
|
||||
if (screenAdaptor.value === 'heightFirst') {
|
||||
return 'preview-content-inner-height-first'
|
||||
} else if (props.canvasStylePreview.screenAdaptor === 'full') {
|
||||
} else if (screenAdaptor.value === 'full') {
|
||||
return 'preview-content-inner-full'
|
||||
} else if (props.canvasStylePreview.screenAdaptor === 'keep') {
|
||||
} else if (screenAdaptor.value === 'keep') {
|
||||
return 'preview-content-inner-size-keep'
|
||||
} else if (props.canvasStylePreview.screenAdaptor === 'keepProportion') {
|
||||
return 'preview-content-inner-keep-proportion'
|
||||
} else {
|
||||
return 'preview-content-inner-width-first'
|
||||
}
|
||||
@@ -67,6 +71,43 @@ const outerStyle = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
const screenAdaptor = computed(() => {
|
||||
if (props.canvasStylePreview.screenAdaptor === 'keepProportion') {
|
||||
return keepProportion.value
|
||||
} else {
|
||||
return props.canvasStylePreview.screenAdaptor
|
||||
}
|
||||
})
|
||||
|
||||
const keepProportionCheck = outerContentRect => {
|
||||
const { width, height } = outerContentRect
|
||||
const { innerWidth, innerHeight } = dePreviewRef.value.getPreviewCanvasSize()
|
||||
if (width > innerWidth || height < innerHeight) {
|
||||
keepProportion.value = 'heightFirst'
|
||||
} else {
|
||||
keepProportion.value = 'widthFirst'
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const observer = new ResizeObserver(entries => {
|
||||
for (let entry of entries) {
|
||||
console.log('元素新尺寸:', entry.contentRect)
|
||||
// entry.contentRect 包含 width, height, top, left 等属性
|
||||
keepProportionCheck(entry.contentRect)
|
||||
}
|
||||
})
|
||||
|
||||
if (dePreviewOuterRef.value) {
|
||||
observer.observe(dePreviewOuterRef.value)
|
||||
}
|
||||
|
||||
// 在组件卸载时停止观察
|
||||
onBeforeUnmount(() => {
|
||||
observer.disconnect()
|
||||
})
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
restore
|
||||
})
|
||||
@@ -75,6 +116,7 @@ defineExpose({
|
||||
<template>
|
||||
<div
|
||||
id="de-preview-content"
|
||||
ref="dePreviewOuterRef"
|
||||
:class="{ 'de-screen-full': fullscreenFlag }"
|
||||
:style="outerStyle"
|
||||
class="content-outer"
|
||||
@@ -90,6 +132,8 @@ defineExpose({
|
||||
:cur-gap="curPreviewGap"
|
||||
:show-position="showPosition"
|
||||
:download-status="downloadStatus"
|
||||
:outer-screen-adaptor="screenAdaptor"
|
||||
:show-linkage-button="showLinkageButton"
|
||||
></de-preview>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,6 +19,7 @@ import EmptyBackground from '../../components/empty-background/src/EmptyBackgrou
|
||||
import { useRoute } from 'vue-router_2'
|
||||
import { filterEnumMapSync } from '@/utils/componentUtils'
|
||||
import CanvasOptBar from '@/components/visualization/CanvasOptBar.vue'
|
||||
import DvPreview from '@/views/data-visualization/DvPreview.vue'
|
||||
const routeWatch = useRoute()
|
||||
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
@@ -281,9 +282,24 @@ defineExpose({
|
||||
:canvas-style-data="state.canvasStylePreview || {}"
|
||||
:component-data="state.canvasDataPreview || []"
|
||||
></canvas-opt-bar>
|
||||
<dv-preview
|
||||
ref="dvPreviewRef"
|
||||
style="height: 100vh"
|
||||
v-if="state.canvasStylePreview && state.initState && state.dvInfo?.type === 'dataV'"
|
||||
:canvas-data-preview="state.canvasDataPreview"
|
||||
:canvas-style-preview="state.canvasStylePreview"
|
||||
:canvas-view-info-preview="state.canvasViewInfoPreview"
|
||||
:dv-info="state.dvInfo"
|
||||
:cur-preview-gap="state.curPreviewGap"
|
||||
:is-selector="props.isSelector"
|
||||
:download-status="downloadStatus"
|
||||
:show-pop-bar="true"
|
||||
:show-position="state.showPosition"
|
||||
:show-linkage-button="false"
|
||||
></dv-preview>
|
||||
<de-preview
|
||||
ref="dvPreview"
|
||||
v-if="state.canvasStylePreview && state.initState"
|
||||
v-if="state.canvasStylePreview && state.initState && state.dvInfo?.type === 'dashboard'"
|
||||
:component-data="state.canvasDataPreview"
|
||||
:canvas-style-data="state.canvasStylePreview"
|
||||
:canvas-view-info="state.canvasViewInfoPreview"
|
||||
|
||||
Reference in New Issue
Block a user