fix(图表): 修复tab中图表放大后,导出图片后,轮播提示显示异常的问题

This commit is contained in:
jianneng-fit2cloud
2025-09-05 14:12:40 +08:00
committed by jianneng-fit2cloud
parent 0bf47a22dc
commit dd7a93a8d3
5 changed files with 90 additions and 56 deletions

View File

@@ -326,6 +326,7 @@ const dialogInit = (canvasStyle, view, item, opt, params = { scale: 0.5 }) => {
nextTick(() => {
initWatermark()
ChartCarouselTooltip.paused()
useEmitt().emitter.emit('showEnlargeDialog', true)
})
}
@@ -425,7 +426,7 @@ const openMessageLoading = cb => {
const mapChartTypes = ['bubble-map', 'flow-map', 'heat-map', 'map', 'symbolic-map']
const htmlToImage = () => {
downLoading.value = mapChartTypes.includes(viewInfo.value.type) ? false : true
useEmitt().emitter.emit('renderChart-' + viewInfo.value.id)
useEmitt().emitter.emit('renderChart-viewDialog-' + viewInfo.value.id)
useEmitt().emitter.emit('l7-prepare-picture', viewInfo.value.id)
// 表格和支持最值图表的渲染时间为2000毫秒其他图表为500毫秒。
const renderTime =
@@ -443,14 +444,14 @@ const htmlToImage = () => {
a.href = dataUrl
a.click()
useEmitt().emitter.emit('l7-unprepare-picture', viewInfo.value.id)
useEmitt().emitter.emit('renderChart-' + viewInfo.value.id)
useEmitt().emitter.emit('renderChart-viewDialog-' + viewInfo.value.id)
initWatermark()
})
.catch(error => {
downLoading.value = false
initWatermark()
useEmitt().emitter.emit('l7-unprepare-picture', viewInfo.value.id)
useEmitt().emitter.emit('renderChart-' + viewInfo.value.id)
useEmitt().emitter.emit('renderChart-viewDialog-' + viewInfo.value.id)
console.error('oops, something went wrong!', error)
})
}, renderTime)
@@ -460,6 +461,7 @@ const initWatermark = () => {
activeWatermarkCheckUser('enlarge-inner-content', 'canvas-main', state.scale)
}
const handleClose = () => {
useEmitt().emitter.emit('showEnlargeDialog', false)
ChartCarouselTooltip.closeEnlargeDialogDestroy(viewInfo.value.id)
}
defineExpose({

View File

@@ -173,6 +173,7 @@ import { imgUrlTrans } from '@/utils/imgUtils'
import Board from '@/components/de-board/Board.vue'
import ChartCarouselTooltip from '@/views/chart/components/js/g2plot_tooltip_carousel'
import { debounce } from 'lodash-es'
import { useEmitt } from '@/hooks/web/useEmitt'
const dvMainStore = dvMainStoreWithOut()
const snapshotStore = snapshotStoreWithOut()
const { tabMoveInActiveId, bashMatrixInfo, editMode, mobileInPc } = storeToRefs(dvMainStore)
@@ -695,6 +696,16 @@ onMounted(() => {
setTimeout(() => {
viewToolTipsChange()
}, 1000)
useEmitt({
name: 'showEnlargeDialog',
callback: show => {
if (show) {
carouselTimer && clearInterval(carouselTimer)
} else {
initCarousel()
}
}
})
})
onBeforeUnmount(() => {
document.removeEventListener('visibilitychange', viewToolTipsChange)

View File

@@ -456,38 +456,49 @@ class ChartCarouselTooltip {
private bindEventListeners() {
// 定义图表元素ID前缀数组
// 图表在不同的显示页面可能有不同的ID前缀
const chartElementIds = ['enlarge-inner-content-', 'enlarge-inner-shape-']
const chartElementIds = ['container-canvas-%s-common']
let chartElement = null
const sprintf = (fmt: string, ...args: unknown[]) => {
let i = 0
return fmt.replace(/%s/g, () => String(args[i++]))
}
// 查找图表元素
for (const idPrefix of chartElementIds) {
chartElement = document.getElementById(idPrefix + this.chart.id)
chartElement = document.getElementById(sprintf(idPrefix, this.chart.id))
if (chartElement) break
}
// 绑定鼠标进入和离开事件
chartElement?.addEventListener('mouseenter', () => this.paused())
chartElement?.addEventListener('mouseleave', ev => {
setTimeout(() => {
// 获取鼠标位置
const mouseX = ev.clientX
const mouseY = ev.clientY
// 获取div的边界信息
const rect = chartElement.getBoundingClientRect()
// 判断鼠标位置是否在div内
const isInside =
mouseX >= rect.left + 10 &&
mouseX <= rect.right - 10 &&
mouseY >= rect.top + 10 &&
mouseY <= rect.bottom - 10
console.log(isInside)
if (!isInside) {
this.paused()
this.resume()
}
}, 300)
})
const addMouseEvent = el => {
el?.addEventListener('mouseenter', () => this.paused())
el?.addEventListener('mouseleave', ev => {
setTimeout(() => {
// 获取鼠标位置
const mouseX = ev.clientX
const mouseY = ev.clientY
// 获取div的边界信息
const rect = el.getBoundingClientRect()
// 判断鼠标位置是否在div内
const isInside =
mouseX >= rect.left + 10 &&
mouseX <= rect.right - 10 &&
mouseY >= rect.top + 10 &&
mouseY <= rect.bottom - 10
console.log(isInside)
if (!isInside) {
this.paused()
this.resume()
}
}, 300)
})
}
addMouseEvent(chartElement)
const showViewDialog = document.getElementById(
'container-viewDialog-' + this.chart.id + '-common'
)
if (showViewDialog && this.chart.container?.startsWith('container-viewDialog-')) {
addMouseEvent(showViewDialog)
}
// 定义鼠标滚轮事件处理函数
const handleMouseWheel = this.debounce(() => {
CAROUSEL_MANAGER_INSTANCES?.forEach(instance => {

View File

@@ -1747,6 +1747,14 @@ function calculateTooltipPosition(chart, isCarousel, tooltipCtl, chartElement, e
return { x: event.clientX, y: event.clientY }
}
}
const getChartElements = chart => {
return (
document.getElementById('container-viewDialog-' + chart.id + '-common') ||
document.getElementById('container-preview-' + chart.id + '-common') ||
document.getElementById('enlarge-inner-content-' + chart.id) ||
document.getElementById('shape-id-' + chart.id)
)
}
export function configPlotTooltipEvent<O extends PickOptions, P extends Plot<O>>(
chart: Chart,
plot: P
@@ -1758,11 +1766,7 @@ export function configPlotTooltipEvent<O extends PickOptions, P extends Plot<O>>
}
// 图表容器,用于计算 tooltip 的位置
// 获取图表元素,优先顺序:放大 > 预览 > 公共连接页面 > 默认
const chartElement =
document.getElementById('container-viewDialog-' + chart.id + '-common') ||
document.getElementById('container-preview-' + chart.id + '-common') ||
document.getElementById('enlarge-inner-content-' + chart.id) ||
document.getElementById('shape-id-' + chart.id)
let chartElement = getChartElements(chart)
// 是否是放大弹窗
const enlargeElement = chartElement?.id.includes('viewDialog')
// 轮播时tooltip的zIndex
@@ -1822,14 +1826,8 @@ export function configPlotTooltipEvent<O extends PickOptions, P extends Plot<O>>
plot.chart.getOptions().tooltip.follow = false
tooltipCtl.title = Math.random().toString()
// 当显示提示为事件触发时使用event的client坐标否则使用tooltipCtl.point 数据点的位置,在图表中,需要加上图表在绘制区的位置
const { x, y } = calculateTooltipPosition(
chart,
isCarousel,
tooltipCtl,
chartElement,
event,
enlargeElement
)
chartElement = getChartElements(chart)
const { x, y } = calculateTooltipPosition(chart, isCarousel, tooltipCtl, chartElement, event)
plot.chart.getTheme().components.tooltip.x = x
plot.chart.getTheme().components.tooltip.y = y
})

View File

@@ -714,6 +714,24 @@ const changeDataset = () => {
const loadPlugin = ref(false)
// 渲染图表回调
const renderChartCallback = val => {
if (!state.initReady) {
return
}
initTitle()
const viewInfo = val ? val : view.value
nextTick(() => {
if (view.value?.plugin?.isPlugin) {
chartComponent?.value?.invokeMethod({
methodName: 'renderChart',
args: [viewInfo]
})
return
}
chartComponent?.value?.renderChart?.(viewInfo)
})
}
onMounted(() => {
if (!view.value.isPlugin) {
state.drillClickDimensionList = view.value?.chartExtRequest?.drill ?? []
@@ -798,21 +816,7 @@ onMounted(() => {
useEmitt({
name: 'renderChart-' + view.value.id,
callback: function (val) {
if (!state.initReady) {
return
}
initTitle()
const viewInfo = val ? val : view.value
nextTick(() => {
if (view.value?.plugin?.isPlugin) {
chartComponent?.value?.invokeMethod({
methodName: 'renderChart',
args: [viewInfo]
})
return
}
chartComponent?.value?.renderChart?.(viewInfo)
})
renderChartCallback(val)
}
})
useEmitt({
@@ -849,6 +853,14 @@ onMounted(() => {
clearExtremum(chart)
}
})
if (showPosition.value === 'viewDialog') {
useEmitt({
name: 'renderChart-viewDialog-' + view.value.id,
callback: function (val) {
renderChartCallback(val)
}
})
}
const { refreshViewEnable, refreshUnit, refreshTime } = view.value
buildInnerRefreshTimer(refreshViewEnable, refreshUnit, refreshTime)