mirror of
https://github.com/dataease/dataease.git
synced 2025-02-25 03:52:59 +08:00
feat(图表-气泡地图): 气泡添加水波纹动画配置
This commit is contained in:
parent
a550dac3f7
commit
7a5a61faaf
@ -22,6 +22,10 @@ declare interface ChartSenior {
|
|||||||
* 区域称映射,{区域id: {原始名称: 映射名称}}
|
* 区域称映射,{区域id: {原始名称: 映射名称}}
|
||||||
*/
|
*/
|
||||||
areaMapping: Record<string, Record<string, string>>
|
areaMapping: Record<string, Record<string, string>>
|
||||||
|
/**
|
||||||
|
* 气泡动效
|
||||||
|
*/
|
||||||
|
bubbleCfg: BubbleCfg
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -209,3 +213,25 @@ declare interface ScrollCfg {
|
|||||||
*/
|
*/
|
||||||
step: number
|
step: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 气泡动效设置
|
||||||
|
*/
|
||||||
|
declare interface BubbleCfg {
|
||||||
|
/**
|
||||||
|
* 开启动效
|
||||||
|
*/
|
||||||
|
enable: boolean
|
||||||
|
/**
|
||||||
|
* 动效类型
|
||||||
|
*/
|
||||||
|
type: 'wave'
|
||||||
|
/**
|
||||||
|
* 水波速度
|
||||||
|
*/
|
||||||
|
speed: number
|
||||||
|
/**
|
||||||
|
* 水波环数
|
||||||
|
*/
|
||||||
|
rings: number
|
||||||
|
}
|
||||||
|
@ -27,6 +27,7 @@ declare type EditorProperty =
|
|||||||
| 'map-symbolic-selector'
|
| 'map-symbolic-selector'
|
||||||
| 'flow-map-line-selector'
|
| 'flow-map-line-selector'
|
||||||
| 'flow-map-point-selector'
|
| 'flow-map-point-selector'
|
||||||
|
| 'bubble-animate'
|
||||||
declare type EditorPropertyInner = {
|
declare type EditorPropertyInner = {
|
||||||
[key in EditorProperty]?: string[]
|
[key in EditorProperty]?: string[]
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import { ElIcon, ElMessage } from 'element-plus-secondary'
|
|||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { BASE_VIEW_CONFIG } from '../util/chart'
|
import { BASE_VIEW_CONFIG } from '../util/chart'
|
||||||
import { cloneDeep, defaultsDeep } from 'lodash-es'
|
import { cloneDeep, defaultsDeep } from 'lodash-es'
|
||||||
|
import BubbleAnimateCfg from '@/views/chart/components/editor/editor-senior/components/BubbleAnimateCfg.vue'
|
||||||
const dvMainStore = dvMainStoreWithOut()
|
const dvMainStore = dvMainStoreWithOut()
|
||||||
|
|
||||||
const { nowPanelTrackInfo, nowPanelJumpInfo, dvInfo, componentData } = storeToRefs(dvMainStore)
|
const { nowPanelTrackInfo, nowPanelJumpInfo, dvInfo, componentData } = storeToRefs(dvMainStore)
|
||||||
@ -37,7 +38,8 @@ const emit = defineEmits([
|
|||||||
'onAssistLineChange',
|
'onAssistLineChange',
|
||||||
'onScrollCfgChange',
|
'onScrollCfgChange',
|
||||||
'onThresholdChange',
|
'onThresholdChange',
|
||||||
'onMapMappingChange'
|
'onMapMappingChange',
|
||||||
|
'onBubbleAnimateChange'
|
||||||
])
|
])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -123,6 +125,11 @@ const onMapMappingChange = val => {
|
|||||||
emit('onMapMappingChange', val)
|
emit('onMapMappingChange', val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onBubbleAnimateChange = val => {
|
||||||
|
console.log(val)
|
||||||
|
emit('onBubbleAnimateChange', val)
|
||||||
|
}
|
||||||
|
|
||||||
const showProperties = (prop: EditorProperty) => {
|
const showProperties = (prop: EditorProperty) => {
|
||||||
return properties?.value?.includes(prop)
|
return properties?.value?.includes(prop)
|
||||||
}
|
}
|
||||||
@ -359,6 +366,22 @@ const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</collapse-switch-item>
|
</collapse-switch-item>
|
||||||
|
<collapse-switch-item
|
||||||
|
:effect="themes"
|
||||||
|
title="气泡动效"
|
||||||
|
:change-model="chart.senior.bubbleCfg"
|
||||||
|
v-if="showProperties('bubble-animate')"
|
||||||
|
v-model="chart.senior.bubbleCfg.enable"
|
||||||
|
name="bubbleAnimate"
|
||||||
|
@modelChange="onBubbleAnimateChange"
|
||||||
|
>
|
||||||
|
<bubble-animate-cfg
|
||||||
|
:themes="themes"
|
||||||
|
:chart="props.chart"
|
||||||
|
:property-inner="propertyInnerAll['bubble-animate']"
|
||||||
|
@onBubbleAnimateChange="onBubbleAnimateChange"
|
||||||
|
/>
|
||||||
|
</collapse-switch-item>
|
||||||
</el-collapse>
|
</el-collapse>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,222 @@
|
|||||||
|
<script lang="tsx" setup>
|
||||||
|
import { PropType, reactive, watch } from 'vue'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
chart: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
themes: {
|
||||||
|
type: String as PropType<EditorTheme>,
|
||||||
|
default: 'dark'
|
||||||
|
},
|
||||||
|
propertyInner: {
|
||||||
|
type: Array<string>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['onBubbleAnimateChange'])
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.chart.senior.bubbleCfg,
|
||||||
|
() => {
|
||||||
|
init()
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
bubbleAnimateForm: {} as BubbleCfg,
|
||||||
|
isAutoBreakLine: false
|
||||||
|
})
|
||||||
|
|
||||||
|
const onBubbleAnimateChange = () => {
|
||||||
|
emit('onBubbleAnimateChange', state.bubbleAnimateForm)
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeSpeedSize = v => {
|
||||||
|
const _v = parseInt(v)
|
||||||
|
if (_v >= 0 && _v <= 5) {
|
||||||
|
state.bubbleAnimateForm.speed = _v
|
||||||
|
} else if (_v < 0) {
|
||||||
|
state.bubbleAnimateForm.speed = 0
|
||||||
|
} else if (_v > 5) {
|
||||||
|
state.bubbleAnimateForm.speed = 5
|
||||||
|
}
|
||||||
|
onBubbleAnimateChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeRingsSize = v => {
|
||||||
|
const _v = parseInt(v)
|
||||||
|
if (_v >= 0 && _v <= 5) {
|
||||||
|
state.bubbleAnimateForm.rings = _v
|
||||||
|
} else if (_v < 0) {
|
||||||
|
state.bubbleAnimateForm.rings = 0
|
||||||
|
} else if (_v > 5) {
|
||||||
|
state.bubbleAnimateForm.rings = 5
|
||||||
|
}
|
||||||
|
onBubbleAnimateChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
const init = () => {
|
||||||
|
const chart = JSON.parse(JSON.stringify(props.chart))
|
||||||
|
if (chart.senior) {
|
||||||
|
let senior = null
|
||||||
|
if (Object.prototype.toString.call(chart.senior) === '[object Object]') {
|
||||||
|
senior = JSON.parse(JSON.stringify(chart.senior))
|
||||||
|
} else {
|
||||||
|
senior = JSON.parse(chart.senior)
|
||||||
|
}
|
||||||
|
if (senior.bubbleCfg) {
|
||||||
|
state.bubbleAnimateForm = senior.bubbleCfg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :style="{ width: '100%', display: 'block' }" @keydown.stop @keyup.stop>
|
||||||
|
<el-form
|
||||||
|
ref="scrollForm"
|
||||||
|
:model="state.bubbleAnimateForm"
|
||||||
|
:disabled="!state.bubbleAnimateForm.enable"
|
||||||
|
label-position="top"
|
||||||
|
>
|
||||||
|
<div class="bubble-animate-setting">
|
||||||
|
<label
|
||||||
|
class="bubble-animate-label"
|
||||||
|
style="line-height: 20px"
|
||||||
|
:class="{ dark: 'dark' === themes }"
|
||||||
|
>
|
||||||
|
动效类型
|
||||||
|
</label>
|
||||||
|
<el-row style="flex: 1" :gutter="8">
|
||||||
|
<el-col :span="13">
|
||||||
|
<el-form-item class="form-item" :class="'form-item-' + themes">
|
||||||
|
<el-radio-group
|
||||||
|
style="padding-left: 1px"
|
||||||
|
size="small"
|
||||||
|
:effect="themes"
|
||||||
|
v-model="state.bubbleAnimateForm.type"
|
||||||
|
@change="onBubbleAnimateChange()"
|
||||||
|
>
|
||||||
|
<el-radio :effect="themes" label="wave"> 水波 </el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bubble-animate-setting">
|
||||||
|
<label class="bubble-animate-label" :class="{ dark: 'dark' === themes }"> 动效速率 </label>
|
||||||
|
<el-row style="flex: 1" :gutter="8">
|
||||||
|
<el-col :span="13">
|
||||||
|
<el-form-item class="form-item bubble-animate-slider" :class="'form-item-' + themes">
|
||||||
|
<el-slider
|
||||||
|
:effect="themes"
|
||||||
|
:min="1"
|
||||||
|
:max="5"
|
||||||
|
v-model="state.bubbleAnimateForm.speed"
|
||||||
|
@change="onBubbleAnimateChange()"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="11" style="padding-top: 2px">
|
||||||
|
<el-form-item class="form-item" :class="'form-item-' + themes">
|
||||||
|
<el-input
|
||||||
|
type="number"
|
||||||
|
:effect="themes"
|
||||||
|
v-model="state.bubbleAnimateForm.speed"
|
||||||
|
:min="1"
|
||||||
|
:max="5"
|
||||||
|
class="basic-input-number"
|
||||||
|
:controls="false"
|
||||||
|
@change="changeSpeedSize"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
<div class="bubble-animate-setting">
|
||||||
|
<label class="bubble-animate-label" :class="{ dark: 'dark' === themes }"> 水波环数 </label>
|
||||||
|
<el-row style="flex: 1" :gutter="8">
|
||||||
|
<el-col :span="13">
|
||||||
|
<el-form-item class="form-item bubble-animate-slider" :class="'form-item-' + themes">
|
||||||
|
<el-slider
|
||||||
|
:effect="themes"
|
||||||
|
:min="1"
|
||||||
|
:max="5"
|
||||||
|
v-model="state.bubbleAnimateForm.rings"
|
||||||
|
@change="onBubbleAnimateChange()"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="11" style="padding-top: 2px">
|
||||||
|
<el-form-item class="form-item" :class="'form-item-' + themes">
|
||||||
|
<el-input
|
||||||
|
type="number"
|
||||||
|
:effect="themes"
|
||||||
|
v-model="state.bubbleAnimateForm.rings"
|
||||||
|
:min="1"
|
||||||
|
:max="5"
|
||||||
|
class="basic-input-number"
|
||||||
|
:controls="false"
|
||||||
|
@change="changeRingsSize"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.basic-input-number {
|
||||||
|
:deep(input) {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
|
||||||
|
&::-webkit-inner-spin-button,
|
||||||
|
&::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bubble-animate-setting {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.bubble-animate-slider {
|
||||||
|
padding: 0 8px;
|
||||||
|
:deep(.ed-slider__button-wrapper) {
|
||||||
|
--ed-slider-button-wrapper-size: 36px;
|
||||||
|
--ed-slider-button-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bubble-animate-label {
|
||||||
|
padding-right: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
height: 32px;
|
||||||
|
line-height: 32px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
min-width: 56px;
|
||||||
|
|
||||||
|
&.dark {
|
||||||
|
color: #a6a6a6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1056,6 +1056,11 @@ const onScrollCfgChange = val => {
|
|||||||
renderChart(view.value)
|
renderChart(view.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onBubbleAnimateChange = val => {
|
||||||
|
view.value.senior.bubbleCfg = val
|
||||||
|
renderChart(view.value)
|
||||||
|
}
|
||||||
|
|
||||||
const onTableColumnWidthChange = val => {
|
const onTableColumnWidthChange = val => {
|
||||||
if (editMode.value !== 'edit') {
|
if (editMode.value !== 'edit') {
|
||||||
return
|
return
|
||||||
@ -2806,6 +2811,7 @@ const deleteChartFieldItem = id => {
|
|||||||
@onScrollCfgChange="onScrollCfgChange"
|
@onScrollCfgChange="onScrollCfgChange"
|
||||||
@onThresholdChange="onThresholdChange"
|
@onThresholdChange="onThresholdChange"
|
||||||
@onMapMappingChange="onMapMappingChange"
|
@onMapMappingChange="onMapMappingChange"
|
||||||
|
@onBubbleAnimateChange="onBubbleAnimateChange"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
|
@ -725,6 +725,13 @@ export const DEFAULT_SCROLL: ScrollCfg = {
|
|||||||
step: 50
|
step: 50
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const DEFAULT_BUBBLE_ANIMATE: BubbleCfg = {
|
||||||
|
enable: false,
|
||||||
|
speed: 1,
|
||||||
|
rings: 1,
|
||||||
|
type: 'wave'
|
||||||
|
}
|
||||||
|
|
||||||
export const DEFAULT_QUADRANT_STYLE: QuadrantAttr = {
|
export const DEFAULT_QUADRANT_STYLE: QuadrantAttr = {
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
stroke: '#aaa',
|
stroke: '#aaa',
|
||||||
@ -1572,7 +1579,8 @@ export const BASE_VIEW_CONFIG = {
|
|||||||
assistLineCfg: DEFAULT_ASSIST_LINE_CFG,
|
assistLineCfg: DEFAULT_ASSIST_LINE_CFG,
|
||||||
threshold: DEFAULT_THRESHOLD,
|
threshold: DEFAULT_THRESHOLD,
|
||||||
scrollCfg: DEFAULT_SCROLL,
|
scrollCfg: DEFAULT_SCROLL,
|
||||||
areaMapping: {}
|
areaMapping: {},
|
||||||
|
bubbleCfg: DEFAULT_BUBBLE_ANIMATE
|
||||||
},
|
},
|
||||||
flowMapStartName: [],
|
flowMapStartName: [],
|
||||||
flowMapEndName: []
|
flowMapEndName: []
|
||||||
|
@ -28,7 +28,7 @@ const { t } = useI18n()
|
|||||||
* 气泡地图
|
* 气泡地图
|
||||||
*/
|
*/
|
||||||
export class BubbleMap extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
export class BubbleMap extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||||
properties = MAP_EDITOR_PROPERTY
|
properties: EditorProperty[] = [...MAP_EDITOR_PROPERTY, 'bubble-animate']
|
||||||
propertyInner = MAP_EDITOR_PROPERTY_INNER
|
propertyInner = MAP_EDITOR_PROPERTY_INNER
|
||||||
axis = MAP_AXIS_TYPE
|
axis = MAP_AXIS_TYPE
|
||||||
axisConfig: AxisConfig = {
|
axisConfig: AxisConfig = {
|
||||||
@ -147,6 +147,7 @@ export class BubbleMap extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
const { basicStyle } = parseJson(chart.customAttr)
|
const { basicStyle } = parseJson(chart.customAttr)
|
||||||
|
const { bubbleCfg } = parseJson(chart.senior)
|
||||||
const { offsetHeight, offsetWidth } = document.getElementById(drawOption.container)
|
const { offsetHeight, offsetWidth } = document.getElementById(drawOption.container)
|
||||||
const options: DotLayerOptions = {
|
const options: DotLayerOptions = {
|
||||||
source: {
|
source: {
|
||||||
@ -173,6 +174,20 @@ export class BubbleMap extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
|||||||
active: true
|
active: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (bubbleCfg && bubbleCfg.enable) {
|
||||||
|
return new DotLayer({
|
||||||
|
...options,
|
||||||
|
size: {
|
||||||
|
field: 'size',
|
||||||
|
value: [10, Math.min(offsetHeight, offsetWidth) / 10]
|
||||||
|
},
|
||||||
|
animate: {
|
||||||
|
enable: true,
|
||||||
|
speed: bubbleCfg.speed,
|
||||||
|
rings: bubbleCfg.rings
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
return new DotLayer(options)
|
return new DotLayer(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user