fix(视图): AntV 提示太长会被遮挡 #8322 #8201

This commit is contained in:
wisonic-s 2024-03-06 17:59:24 +08:00
parent e40046dc13
commit e5b86d9326
15 changed files with 181 additions and 74 deletions

View File

@ -40,7 +40,7 @@
<chart-component-g2
v-else-if="!chart.type.includes('text') && chart.type !== 'label' && !chart.type.includes('table') && renderComponent() === 'antv'"
:ref="element.propValue.id"
class="chart-class show-in-dialog"
class="chart-class"
:chart="chart"
/>
<chart-component-s2

View File

@ -10,7 +10,8 @@ import {
getSlider,
getAnalyse,
setGradientColor,
getMeta
getMeta,
configPlotTooltipEvent
} from '@/views/chart/chart/common/common_antv'
import { antVCustomColor, getColors, handleEmptyDataStrategy, hexColorToRGBA } from '@/views/chart/chart/util'
import { cloneDeep, find } from 'lodash-es'
@ -138,7 +139,8 @@ export function baseBarOptionAntV(plot, container, chart, action, isGroup, isSta
plot.off('interval:click')
plot.on('interval:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}
@ -258,7 +260,8 @@ export function hBaseBarOptionAntV(plot, container, chart, action, isGroup, isSt
plot.off('interval:click')
plot.on('interval:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}
@ -451,7 +454,8 @@ export function timeRangeBarOptionAntV(plot, container, chart, action) {
plot.off('interval:click')
plot.on('interval:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}
@ -546,6 +550,7 @@ export function baseBidirectionalBarOptionAntV(plot, container, chart, action, i
plot.off('interval:click')
plot.on('interval:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}

View File

@ -88,7 +88,8 @@ export function getTheme(chart) {
'g2-tooltip': {
color: tooltipColor,
fontSize: tooltipFontsize + 'px',
background: tooltipBackgroundColor
background: tooltipBackgroundColor,
'z-index': 3000
}
}
},
@ -318,7 +319,10 @@ export function getTooltip(chart) {
if (customAttr.tooltip) {
const t = JSON.parse(JSON.stringify(customAttr.tooltip))
if (t.show) {
tooltip = {}
tooltip = {
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL
}
let xAxis, yAxis, extStack, xAxisExt
try {
@ -485,56 +489,55 @@ export function getTooltip(chart) {
//
if (chart.type === 'scatter' && xAxis && xAxis.length > 0 && xAxis[0].groupType === 'q') {
tooltip.fields = ['x', 'category', 'value', 'group', 'field']
tooltip.customContent = (title, data) => {
const key1 = xAxis[0]?.name
let key2, v1, v2, subGroup
tooltip.showTitle = true
tooltip.title = 'category'
let subGroupTpl = ''
if (xAxisExt?.length) {
subGroupTpl = '<div>' +
'<span class="g2-tooltip-name">{subGroupName}</span>:' +
'<span class="g2-tooltip-value">{subGroupValue}</span>' +
'</div>'
}
tooltip.itemTpl = '<li class="g2-tooltip-list-item">' +
subGroupTpl +
'<div>' +
'<span class="g2-tooltip-name">{name}</span>:' +
'<span class="g2-tooltip-value">{x}</span>' +
'</div>' +
'<div>' +
'<span class="g2-tooltip-name">{group}</span>:' +
'<span class="g2-tooltip-value">{value}</span>' +
'</div>' +
'</li>'
tooltip.customItems = items => {
items?.forEach(item => {
item.title = item.data.category
item.name = xAxis[0]?.name
let hasSubGroup = false
if (data && data.length > 0) {
title = data[0].data.category
key2 = data[0].data.group
subGroup = data[0].data.field
hasSubGroup = xAxisExt.length > 0
item.group = item.data.group
item.subGroupValue = item.data.field
item.subGroupName = xAxisExt?.[0]?.name
const fx = xAxis[0]
if (fx.formatterCfg) {
v1 = valueFormatter(data[0].data.x, fx.formatterCfg)
item.x = valueFormatter(item.data.x, fx.formatterCfg)
} else {
v1 = valueFormatter(data[0].data.x, formatterItem)
item.x = valueFormatter(item.data.x, formatterItem)
}
for (let i = 0; i < yAxis.length; i++) {
const f = yAxis[i]
if (f.name === key2) {
if (f.name === item.group) {
if (f.formatterCfg) {
v2 = valueFormatter(data[0].data.value, f.formatterCfg)
item.value = valueFormatter(item.data.value, f.formatterCfg)
} else {
v2 = valueFormatter(data[0].data.value, formatterItem)
item.value = valueFormatter(item.data.value, formatterItem)
}
break
}
}
}
return `
<div>
<div class="g2-tooltip-title">${title}</div>
` +
(hasSubGroup
? `<div class="g2-tooltip-item">
<span class="g2-tooltip-name">${xAxisExt[0].name}:</span><span class="g2-tooltip-value">${subGroup}</span>
</div>` : ``) +
`
<div class="g2-tooltip-item">
<span class="g2-tooltip-name">${key1}:</span><span class="g2-tooltip-value">${v1}</span>
</div>
<div class="g2-tooltip-item">
<span class="g2-tooltip-name">${key2}:</span><span class="g2-tooltip-value">${v2}</span>
</div>
<div class="g2-tooltip-item">&nbsp;</div>
</div>
`
})
return items
}
}
}
@ -1160,3 +1163,75 @@ export function getMeta(chart) {
}
return meta
}
export function getTooltipContainer(id) {
const curDom = document.getElementById(id)
if (curDom) {
curDom.remove()
}
const g2Tooltip = document.createElement('div')
g2Tooltip.setAttribute('id', id)
g2Tooltip.classList.add('g2-tooltip')
const g2TooltipTitle = document.createElement('div')
g2TooltipTitle.classList.add('g2-tooltip-title')
g2Tooltip.appendChild(g2TooltipTitle)
const g2TooltipList = document.createElement('ul')
g2TooltipList.classList.add('g2-tooltip-list')
g2Tooltip.appendChild(g2TooltipList)
const full = document.getElementsByClassName('fullscreen')
if (full.length) {
full.item(0).appendChild(g2Tooltip)
} else {
document.body.appendChild(g2Tooltip)
}
return g2Tooltip
}
export function configPlotTooltipEvent(chart, plot) {
const customAttr = JSON.parse(chart.customAttr)
const t = JSON.parse(JSON.stringify(customAttr.tooltip))
if (!t.show) {
return
}
// 手动处理 tooltip 的显示和隐藏事件,需配合源码理解
// https://github.com/antvis/G2/blob/master/src/chart/controller/tooltip.ts#showTooltip
plot.on('tooltip:show', () => {
const tooltipCtl = plot.chart.getController('tooltip')
if (!tooltipCtl) {
return
}
if (tooltipCtl.tooltip) {
// 处理视图放大后再关闭 tooltip 的 dom 被清除
const container = tooltipCtl.tooltip.cfg.container
const dom = document.getElementById(container.id)
if (!dom) {
const full = document.getElementsByClassName('fullscreen')
if (full.length) {
full.item(0).appendChild(container)
} else {
document.body.appendChild(container)
}
}
}
const event = plot.chart.interactions.tooltip?.context?.event
plot.chart.getOptions().tooltip.follow = false
tooltipCtl.title = Math.random().toString()
plot.chart.getTheme().components.tooltip.x = event.clientX
plot.chart.getTheme().components.tooltip.y = event.clientY
})
// https://github.com/antvis/G2/blob/master/src/chart/controller/tooltip.ts#hideTooltip
plot.on('plot:mouseleave', () => {
const tooltipCtl = plot.chart.getController('tooltip')
if (!tooltipCtl) {
return
}
plot.chart.getOptions().tooltip.follow = true
tooltipCtl.hideTooltip()
})
}
export const TOOLTIP_TPL = '<li class="g2-tooltip-list-item" data-index={index}>' +
'<span class="g2-tooltip-marker" style="background:{color}"></span>' +
'<span class="g2-tooltip-name">{name}</span>:' +
'<span class="g2-tooltip-value">{value}</span>' +
'</li>'

View File

@ -1,4 +1,11 @@
import { getLabel, getLegend, getPadding, getTheme, getTooltip } from '@/views/chart/chart/common/common_antv'
import {
configPlotTooltipEvent,
getLabel,
getLegend,
getPadding,
getTheme,
getTooltip
} from '@/views/chart/chart/common/common_antv'
import { Funnel } from '@antv/g2plot'
import { antVCustomColor } from '@/views/chart/chart/util'
@ -54,7 +61,8 @@ export function baseFunnelOptionAntV(plot, container, chart, action) {
plot.off('interval:click')
plot.on('interval:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}

View File

@ -9,7 +9,8 @@ import {
getPadding,
getSlider,
getAnalyse,
setGradientColor
setGradientColor,
configPlotTooltipEvent
} from '@/views/chart/chart/common/common_antv'
import { antVCustomColor, handleEmptyDataStrategy } from '@/views/chart/chart/util'
import _ from 'lodash'
@ -110,7 +111,8 @@ export function baseLineOptionAntV(plot, container, chart, action) {
plot.off('point:click')
plot.on('point:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}
@ -220,6 +222,7 @@ export function baseAreaOptionAntV(plot, container, chart, action, isStack) {
plot.off('point:click')
plot.on('point:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}

View File

@ -1,4 +1,5 @@
import {
configPlotTooltipEvent,
getLabel,
getLegend,
getPadding,
@ -107,7 +108,8 @@ export function baseMixOptionAntV(plot, container, chart, action) {
plot.on('point:click', action)
plot.off('interval:click')
plot.on('interval:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}

View File

@ -1,4 +1,5 @@
import {
configPlotTooltipEvent,
getLabel,
getLegend,
getPadding,
@ -90,7 +91,8 @@ export function basePieOptionAntV(plot, container, chart, action) {
plot.off('interval:click')
plot.on('interval:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}
@ -167,6 +169,7 @@ export function basePieRoseOptionAntV(plot, container, chart, action) {
plot.off('interval:click')
plot.on('interval:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}

View File

@ -1,4 +1,11 @@
import { getLabel, getLegend, getPadding, getTheme, getTooltip } from '@/views/chart/chart/common/common_antv'
import {
configPlotTooltipEvent,
getLabel,
getLegend,
getPadding,
getTheme,
getTooltip
} from '@/views/chart/chart/common/common_antv'
import { Radar } from '@antv/g2plot'
import { antVCustomColor } from '@/views/chart/chart/util'
import { minBy, maxBy } from 'lodash'
@ -146,7 +153,8 @@ export function baseRadarOptionAntV(plot, container, chart, action) {
plot.off('point:click')
plot.on('point:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}

View File

@ -7,7 +7,10 @@ import {
getYAxis,
getPadding,
getSlider,
getAnalyse
getAnalyse,
getTooltipContainer,
TOOLTIP_TPL,
configPlotTooltipEvent
} from '@/views/chart/chart/common/common_antv'
import { Scatter } from '@antv/g2plot'
@ -92,6 +95,7 @@ export function baseScatterOptionAntV(plot, container, chart, action) {
plot.off('point:click')
plot.on('point:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}

View File

@ -1,4 +1,11 @@
import { getLabel, getLegend, getPadding, getTheme, getTooltip } from '@/views/chart/chart/common/common_antv'
import {
configPlotTooltipEvent,
getLabel,
getLegend,
getPadding,
getTheme,
getTooltip
} from '@/views/chart/chart/common/common_antv'
import { Treemap } from '@antv/g2plot'
export function baseTreemapOptionAntV(plot, container, chart, action) {
@ -51,6 +58,7 @@ export function baseTreemapOptionAntV(plot, container, chart, action) {
plot.off('polygon:click')
plot.on('polygon:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}

View File

@ -1,4 +1,5 @@
import {
configPlotTooltipEvent,
getLabel,
getPadding,
getTheme,
@ -108,7 +109,8 @@ export function baseWaterfallOptionAntV(plot, container, chart, action) {
plot.off('interval:click')
plot.on('interval:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}

View File

@ -1,4 +1,5 @@
import {
configPlotTooltipEvent,
getPadding,
getTheme,
getTooltip
@ -48,5 +49,7 @@ export function baseWordCloudOptionAntV(plot, container, chart, action) {
plot = new WordCloud(container, options)
plot.off('point:click')
plot.on('point:click', action)
// 处理 tooltip 被其他视图遮挡
configPlotTooltipEvent(chart, plot)
return plot
}

View File

@ -34,7 +34,6 @@
<div
:id="chartId"
style="width: 100%;overflow: hidden;"
class="g2-container"
:style="{height:chartHeight}"
/>
</div>
@ -482,18 +481,3 @@ export default {
}
}
</script>
<style lang="less" scoped>
.g2-container {
::v-deep .g2-tooltip {
position: fixed !important;
}
}
.fullscreen, .show-in-dialog {
.g2-container {
::v-deep .g2-tooltip {
position: absolute !important;
}
}
}
</style>

View File

@ -1165,6 +1165,7 @@
<script>
import { CHART_FONT_FAMILY, CHART_FONT_LETTER_SPACE, DEFAULT_SIZE } from '../../chart/chart'
import { includesAny } from '@/utils/StringUtils'
import _ from 'lodash'
export default {
name: 'SizeSelector',
props: {

View File

@ -1598,6 +1598,7 @@ import { CHART_FONT_FAMILY, CHART_FONT_LETTER_SPACE, DEFAULT_SIZE } from '../../
import { equalsAny, includesAny } from '@/utils/StringUtils'
import { mapState } from 'vuex'
import { SERIES_NUMBER_FIELD } from '@antv/s2'
import _ from 'lodash'
export default {
name: 'SizeSelectorAntV',