Skip to content

Commit

Permalink
Merge pull request #10451 from dataease/pr@dev-v2@feat_screen-ruler-cur
Browse files Browse the repository at this point in the history
Pr@dev v2@feat screen ruler cur
  • Loading branch information
ziyujiahao committed Jun 23, 2024
2 parents 87c2005 + 7058c97 commit 7c347b4
Show file tree
Hide file tree
Showing 5 changed files with 278 additions and 10 deletions.
1 change: 1 addition & 0 deletions core/core-frontend/src/assets/svg/dv-ruler.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ onUnmounted(() => {
background-color: @side-area-background;
border-top: 1px solid @side-outline-border-color;
color: #fff;
z-index: 2;
transition: 0.5s;
.scale-area {
display: flex;
Expand Down
113 changes: 105 additions & 8 deletions core/core-frontend/src/custom-component/common/DeRuler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,60 @@ const props = defineProps({
tickLabelFormatter: {
type: Function,
default: value => value.toString() // 刻度标签格式化函数,默认直接转为字符串
},
size: {
type: Number,
default: 300 // 尺子方向
},
direction: {
type: String,
default: 'horizontal' // 尺子方向
}
})
const labelInterval = 5
const { canvasStyleData } = storeToRefs(dvMainStore)
const { canvasStyleData, curComponent } = storeToRefs(dvMainStore)
const rulerSize = computed(() =>
props.direction === 'horizontal' ? canvasStyleData.value.width : canvasStyleData.value.height
)
const curComponentSize = computed(() => {
if (curComponent.value) {
return (
((props.direction === 'horizontal'
? curComponent.value.style.width
: curComponent.value.style.height) *
canvasStyleData.value.scale) /
100
)
} else {
return 0
}
})
const curComponentShadow = computed(() => {
if (curComponent.value) {
return {
left:
(props.direction === 'horizontal'
? curComponent.value.style.left
: curComponent.value.style.top) + 'px',
width:
(props.direction === 'horizontal'
? curComponent.value.style.width
: curComponent.value.style.height) + 'px'
}
} else {
return {}
}
})
const ticks = computed(() => {
const result = []
let currentValue = 0
while (currentValue <= canvasStyleData.value.width) {
while (currentValue <= rulerSize.value) {
const isLong = currentValue % (labelInterval * tickSize.value) === 0
const label = isLong ? props.tickLabelFormatter(currentValue) : ''
result.push({ position: (currentValue * canvasStyleData.value.scale) / 100, label, isLong })
Expand All @@ -29,30 +72,50 @@ const ticks = computed(() => {
const wStyle = computed(() => {
return {
width: canvasStyleData.value.width * 1.5 + 'px'
width: rulerSize.value * 1.5 + 'px'
}
})
const radio = computed(() => rulerSize.value / canvasStyleData.value.width)
const tickSize = computed(
() =>
10 *
Math.max(Math.floor(200000 / (canvasStyleData.value.width * canvasStyleData.value.scale)), 1)
Math.max(
Math.floor((200000 * radio.value) / (rulerSize.value * canvasStyleData.value.scale)),
1
)
)
const scaleWidth = computed(() => (canvasStyleData.value.width * canvasStyleData.value.scale) / 100)
const scaleWidth = computed(() => (rulerSize.value * canvasStyleData.value.scale) / 100)
const rulerScroll = e => {
wRuleRef.value.scrollTo(e.scrollLeft, 0)
const left = props.direction === 'vertical' ? e.scrollTop : e.scrollLeft
wRuleRef.value.scrollTo(left, 0)
}
const outerStyle = computed(() => {
return {
width: props.direction === 'vertical' ? props.size - 30 + 'px' : '100%'
}
})
defineExpose({
rulerScroll
})
</script>

<template>
<div class="ruler-outer" ref="wRuleRef">
<div
class="ruler-outer"
:style="outerStyle"
:class="{ 'ruler-vertical': direction === 'vertical' }"
ref="wRuleRef"
>
<!--覆盖着尺子上方防止鼠标移到尺子位置滑动-->
<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 class="ruler-line" :style="{ width: `${scaleWidth}px` }"></div>
<div
v-for="(tick, index) in ticks"
Expand All @@ -73,8 +136,36 @@ defineExpose({
width: 0px !important;
height: 0px !important;
}
.ruler-vertical {
position: absolute;
left: 30px;
top: 30px;
transform-origin: top left;
transform: rotate(90deg);
overflow-y: auto;
overflow-x: hidden;
z-index: 1;
.ruler {
.ruler-line {
top: 0;
}
.ruler-tick {
top: 0;
.tick-label {
transform: rotate(180deg);
}
}
}
}
.ruler-shadow {
position: absolute;
height: 30px;
z-index: 10;
overflow: hidden;
}
.ruler-outer {
width: 100%;
overflow-x: auto;
background-color: #2c2c2c;
}
Expand Down Expand Up @@ -119,4 +210,10 @@ defineExpose({
transform: translateX(2%);
white-space: nowrap;
}
.cur-shadow {
background: rgba(10, 123, 224, 0.3);
height: 30px;
position: absolute;
}
</style>
144 changes: 144 additions & 0 deletions core/core-frontend/src/custom-component/common/DeRulerVertical.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { storeToRefs } from 'pinia'
const dvMainStore = dvMainStoreWithOut()
const wRuleRef = ref(null)
const props = defineProps({
tickLabelFormatter: {
type: Function,
default: value => value.toString() // 刻度标签格式化函数,默认直接转为字符串
},
direction: {
type: String,
default: 'horizontal' // 尺子方向
}
})
const labelInterval = 5
const { canvasStyleData } = storeToRefs(dvMainStore)
const ticks = computed(() => {
const result = []
let currentValue = 0
while (currentValue <= canvasStyleData.value.height) {
const isLong = currentValue % (labelInterval * tickSize.value) === 0
const label = isLong ? props.tickLabelFormatter(currentValue) : ''
result.push({ position: (currentValue * canvasStyleData.value.scale) / 100, label, isLong })
currentValue += tickSize.value
}
return result
})
const hStyle = computed(() => {
return {
height: canvasStyleData.value.height * 1.5 + 'px'
}
})
const tickSize = computed(
() =>
10 *
Math.max(Math.floor(200000 / (canvasStyleData.value.height * canvasStyleData.value.scale)), 1)
)
const scaleHeight = computed(
() => (canvasStyleData.value.height * canvasStyleData.value.scale) / 100
)
const rulerScroll = e => {
wRuleRef.value.scrollTo(0, e.scrollHeight)
}
defineExpose({
rulerScroll
})
</script>

<template>
<div class="ruler-outer-vertical" ref="wRuleRef">
testtest
<!--覆盖着尺子上方防止鼠标移到尺子位置滑动-->
<div class="ruler-shadow-vertical"></div>
<div :style="hStyle" class="ruler-outer-vertical-scroll">
<div class="ruler" :style="{ height: `${scaleHeight}px` }">
<div class="ruler-line" :style="{ height: `${scaleHeight}px` }"></div>
<div
v-for="(tick, index) in ticks"
:key="index"
class="ruler-tick"
:class="{ 'long-tick': tick.isLong }"
:style="{ left: `${tick.position}px` }"
>
<span v-if="tick.isLong" class="tick-label">{{ tick.label }}</span>
</div>
</div>
</div>
</div>
</template>

<style scoped lang="less">
::-webkit-scrollbar {
width: 0px !important;
height: 0px !important;
}
.ruler-shadow-vertical {
position: absolute;
width: 30px;
height: 100%;
z-index: 10;
overflow: hidden;
}
.ruler-outer-vertical {
position: absolute;
width: 30px;
height: 100%;
overflow-y: auto;
background-color: #2c2c2c;
}
.ruler-outer-vertical-scroll {
display: flex;
align-items: center;
justify-content: center;
}
.ruler {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
height: 100%;
border-left: 1px solid #974e4e;
background-color: #2c2c2c;
}
.ruler-line {
position: absolute;
bottom: 0;
height: 1px;
background-color: #ac2a2a;
}
.ruler-tick {
position: absolute;
bottom: 1px;
height: 3px;
width: 1px;
background-color: #e38a8a;
}
.long-tick {
width: 1px;
height: 15px;
}
.tick-label {
position: absolute;
bottom: 2px;
font-size: 8px;
left: 50%;
transform: translateX(2%);
white-space: nowrap;
}
</style>
29 changes: 27 additions & 2 deletions core/core-frontend/src/views/data-visualization/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const contextmenuStore = contextmenuStoreWithOut()
const composeStore = composeStoreWithOut()
const canvasCacheOutRef = ref(null)
const deWRulerRef = ref(null)
const deHRulerRef = ref(null)
const {
fullscreenFlag,
Expand All @@ -82,6 +83,7 @@ const canvasInner = ref(null)
const leftSidebarRef = ref(null)
const dvLayout = ref(null)
const canvasCenterRef = ref(null)
const mainHeight = ref(300)
const state = reactive({
datasetTree: [],
scaleHistory: null,
Expand Down Expand Up @@ -179,9 +181,9 @@ const initScroll = () => {
nextTick(() => {
const { width, height } = canvasStyleData.value
const mainWidth = canvasCenterRef.value.clientWidth
const mainHeight = canvasCenterRef.value.clientHeight
mainHeight.value = canvasCenterRef.value.clientHeight
const scrollX = (1.5 * width - mainWidth) / 2
const scrollY = (1.5 * height - mainHeight) / 2 + 20
const scrollY = (1.5 * height - mainHeight.value) / 2 + 20
// 设置画布初始滚动条位置
canvasOut.value.scrollTo(scrollX, scrollY)
})
Expand Down Expand Up @@ -361,7 +363,9 @@ const viewsPropertiesShow = computed(
const scrollCanvas = e => {
deWRulerRef.value.rulerScroll(e)
deHRulerRef.value.rulerScroll(e)
}
eventBus.on('handleNew', handleNew)
</script>

Expand Down Expand Up @@ -393,7 +397,13 @@ eventBus.on('handleNew', handleNew)
</dv-sidebar>
<!-- 中间画布 -->
<main id="dv-main-center" class="center" ref="canvasCenterRef">
<div class="de-ruler-icon-outer">
<el-icon class="de-ruler-icon">
<Icon name="dv-ruler" />
</el-icon>
</div>
<de-ruler ref="deWRulerRef"></de-ruler>
<de-ruler direction="vertical" :size="mainHeight" ref="deHRulerRef"></de-ruler>
<el-scrollbar
ref="canvasOut"
@scroll="scrollCanvas"
Expand Down Expand Up @@ -554,4 +564,19 @@ eventBus.on('handleNew', handleNew)
justify-content: center;
align-items: center;
}
.de-ruler-icon-outer {
background: #2c2c2c;
position: absolute;
width: 30px;
height: 30px;
z-index: 3;
color: #ebebeb;
.de-ruler-icon {
margin-left: 6px;
margin-top: 6px;
font-size: 24px;
color: #ebebeb;
}
}
</style>

0 comments on commit 7c347b4

Please sign in to comment.