Merge pull request #8389 from dataease/pr@dev@fix_antv_tooltip_covered
fix(视图): AntV 提示太长会被遮挡 #8322 #8201
This commit is contained in:
commit
f32b2ea844
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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"> </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>'
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user