Merge pull request #13164 from dataease/pr@dev-v2@fix_tooltip_overlay

fix(图表): 修复图表提示被遮挡 #12616
This commit is contained in:
wisonic-s 2024-11-06 14:25:16 +08:00 committed by GitHub
commit 03b8d8923b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 270 additions and 40 deletions

View File

@ -19,9 +19,12 @@ import {
BAR_EDITOR_PROPERTY_INNER
} from '@/views/chart/components/js/panel/charts/bar/common'
import {
configPlotTooltipEvent,
getLabel,
getPadding,
setGradientColor
getTooltipContainer,
setGradientColor,
TOOLTIP_TPL
} from '@/views/chart/components/js/panel/common/common_antv'
import { useI18n } from '@/hooks/web/useI18n'
import { DEFAULT_LABEL } from '@/views/chart/components/editor/util/chart'
@ -82,6 +85,7 @@ export class Bar extends G2PlotChartView<ColumnOptions, Column> {
newChart = new ColumnClass(container, options)
newChart.on('interval:click', action)
extremumEvt(newChart, chart, options, container)
configPlotTooltipEvent(chart, newChart)
return newChart
}
@ -308,7 +312,10 @@ export class StackBar extends Bar {
const res = valueFormatter(param.value, tooltipAttr.tooltipFormatter)
obj.value = res ?? ''
return obj
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return {
...options,
@ -522,7 +529,10 @@ export class GroupStackBar extends StackBar {
const obj = { name: `${param.category} - ${param.group}`, value: param.value }
obj.value = valueFormatter(param.value, tooltipAttr.tooltipFormatter)
return obj
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return {
...options,
@ -605,7 +615,10 @@ export class PercentageStackBar extends GroupStackBar {
const obj = { name: param.category, value: param.value }
obj.value = (Math.round(param.value * 10000) / 100).toFixed(l.reserveDecimalCount) + '%'
return obj
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return {
...options,

View File

@ -4,10 +4,13 @@ import {
} from '@/views/chart/components/js/panel/types/impl/g2plot'
import { cloneDeep, defaultTo, isEmpty, map } from 'lodash-es'
import {
configPlotTooltipEvent,
getPadding,
getTooltipContainer,
getYAxis,
getYAxisExt,
setGradientColor
setGradientColor,
TOOLTIP_TPL
} from '@/views/chart/components/js/panel/common/common_antv'
import type {
BidirectionalBar as G2BidirectionalBar,
@ -171,7 +174,7 @@ export class BidirectionalHorizontalBar extends G2PlotChartView<
...sourceData[0]
}
})
configPlotTooltipEvent(chart, newChart)
return newChart
}
@ -299,7 +302,10 @@ export class BidirectionalHorizontalBar extends G2PlotChartView<
})
}
return result
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return {
...options,

View File

@ -3,7 +3,13 @@ import {
G2PlotDrawOptions
} from '@/views/chart/components/js/panel/types/impl/g2plot'
import type { Bar, BarOptions } from '@antv/g2plot/esm/plots/bar'
import { getPadding, setGradientColor } from '@/views/chart/components/js/panel/common/common_antv'
import {
configPlotTooltipEvent,
getPadding,
getTooltipContainer,
setGradientColor,
TOOLTIP_TPL
} from '@/views/chart/components/js/panel/common/common_antv'
import { cloneDeep } from 'lodash-es'
import {
flow,
@ -93,7 +99,7 @@ export class HorizontalBar extends G2PlotChartView<BarOptions, Bar> {
const newChart = new Bar(container, options)
newChart.on('interval:click', action)
configPlotTooltipEvent(chart, newChart)
return newChart
}
@ -313,7 +319,10 @@ export class HorizontalStackBar extends HorizontalBar {
const res = valueFormatter(param.value, tooltipAttr.tooltipFormatter)
obj.value = res ?? ''
return obj
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return {
...options,
@ -423,7 +432,10 @@ export class HorizontalPercentageStackBar extends HorizontalStackBar {
const obj = { name: param.category, value: param.value }
obj.value = (Math.round(param.value * 10000) / 100).toFixed(l.reserveDecimalCount) + '%'
return obj
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return {
...options,

View File

@ -1,6 +1,11 @@
import { G2PlotChartView, G2PlotDrawOptions } from '../../types/impl/g2plot'
import { flow, hexColorToRGBA, parseJson } from '../../../util'
import { setGradientColor } from '../../common/common_antv'
import {
configPlotTooltipEvent,
getTooltipContainer,
setGradientColor,
TOOLTIP_TPL
} from '../../common/common_antv'
import { useI18n } from '@/hooks/web/useI18n'
import type { Bar as G2Progress, BarOptions } from '@antv/g2plot/esm/plots/bar'
import {
@ -134,7 +139,7 @@ export class ProgressBar extends G2PlotChartView<BarOptions, G2Progress> {
const newChart = new G2Progress(container, options)
newChart.on('interval:click', action)
configPlotTooltipEvent(chart, newChart)
return newChart
}
protected configBasicStyle(chart: Chart, options: BarOptions): BarOptions {
@ -224,7 +229,10 @@ export class ProgressBar extends G2PlotChartView<BarOptions, G2Progress> {
}
})
return result.length == 0 ? originalItems : result
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
}
}

View File

@ -3,7 +3,13 @@ import {
G2PlotDrawOptions
} from '@/views/chart/components/js/panel/types/impl/g2plot'
import type { Bar, BarOptions } from '@antv/g2plot/esm/plots/bar'
import { getPadding, setGradientColor } from '@/views/chart/components/js/panel/common/common_antv'
import {
configPlotTooltipEvent,
getPadding,
getTooltipContainer,
setGradientColor,
TOOLTIP_TPL
} from '@/views/chart/components/js/panel/common/common_antv'
import { cloneDeep, find } from 'lodash-es'
import { flow, hexColorToRGBA, parseJson } from '@/views/chart/components/js/util'
import { valueFormatter } from '@/views/chart/components/js/formatter'
@ -161,7 +167,7 @@ export class RangeBar extends G2PlotChartView<BarOptions, Bar> {
const newChart = new BarClass(container, options)
newChart.on('interval:click', action)
configPlotTooltipEvent(chart, newChart)
return newChart
}
@ -232,7 +238,10 @@ export class RangeBar extends G2PlotChartView<BarOptions, Bar> {
}
}
return { value: res, values: param.values, name: param.field }
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
} else {
tooltip = false

View File

@ -2,7 +2,14 @@ import type { WaterfallOptions, Waterfall as G2Waterfall } from '@antv/g2plot/es
import { G2PlotChartView, G2PlotDrawOptions } from '../../types/impl/g2plot'
import { flow, hexColorToRGBA, parseJson } from '../../../util'
import { valueFormatter } from '../../../formatter'
import { getPadding, getTooltipSeriesTotalMap, setGradientColor } from '../../common/common_antv'
import {
configPlotTooltipEvent,
getPadding,
getTooltipContainer,
getTooltipSeriesTotalMap,
setGradientColor,
TOOLTIP_TPL
} from '../../common/common_antv'
import { isEmpty } from 'lodash-es'
import { useI18n } from '@/hooks/web/useI18n'
const { t } = useI18n()
@ -92,6 +99,7 @@ export class Waterfall extends G2PlotChartView<WaterfallOptions, G2Waterfall> {
const { Waterfall: G2Waterfall } = await import('@antv/g2plot/esm/plots/waterfall')
const newChart = new G2Waterfall(container, options)
newChart.on('interval:click', action)
configPlotTooltipEvent(chart, newChart)
return newChart
}
@ -224,7 +232,10 @@ export class Waterfall extends G2PlotChartView<WaterfallOptions, G2Waterfall> {
}
})
return result
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return {
...options,

View File

@ -3,7 +3,13 @@ import {
G2PlotDrawOptions
} from '@/views/chart/components/js/panel/types/impl/g2plot'
import type { Area as G2Area, AreaOptions } from '@antv/g2plot/esm/plots/area'
import { getPadding, setGradientColor } from '@/views/chart/components/js/panel/common/common_antv'
import {
configPlotTooltipEvent,
getPadding,
getTooltipContainer,
setGradientColor,
TOOLTIP_TPL
} from '@/views/chart/components/js/panel/common/common_antv'
import { cloneDeep } from 'lodash-es'
import {
flow,
@ -116,6 +122,7 @@ export class Area extends G2PlotChartView<AreaOptions, G2Area> {
newChart.on('point:click', action)
extremumEvt(newChart, chart, options, container)
configPlotTooltipEvent(chart, newChart)
return newChart
}
@ -352,7 +359,10 @@ export class StackArea extends Area {
value: valueFormatter(param.value, tooltipAttr.tooltipFormatter)
}
return obj
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return { ...options, tooltip }
}

View File

@ -3,7 +3,12 @@ import {
G2PlotDrawOptions
} from '@/views/chart/components/js/panel/types/impl/g2plot'
import type { Line as G2Line, LineOptions } from '@antv/g2plot/esm/plots/line'
import { getPadding } from '../../common/common_antv'
import {
configPlotTooltipEvent,
getPadding,
getTooltipContainer,
TOOLTIP_TPL
} from '../../common/common_antv'
import {
flow,
hexColorToRGBA,
@ -116,6 +121,7 @@ export class Line extends G2PlotChartView<LineOptions, G2Line> {
newChart.on('point:click', action)
extremumEvt(newChart, chart, options, container)
configPlotTooltipEvent(chart, newChart)
return newChart
}
@ -279,7 +285,10 @@ export class Line extends G2PlotChartView<LineOptions, G2Line> {
}
})
return result
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return {
...options,

View File

@ -4,12 +4,15 @@ import {
} from '@/views/chart/components/js/panel/types/impl/g2plot'
import type { DualAxes, DualAxesOptions } from '@antv/g2plot/esm/plots/dual-axes'
import {
configPlotTooltipEvent,
getAnalyse,
getLabel,
getPadding,
getTooltipContainer,
getYAxis,
getYAxisExt,
setGradientColor
setGradientColor,
TOOLTIP_TPL
} from '../../common/common_antv'
import { flow, hexColorToRGBA, parseJson } from '@/views/chart/components/js/util'
import { cloneDeep, isEmpty, defaultTo, map, filter, union, defaultsDeep } from 'lodash-es'
@ -158,7 +161,7 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
newChart.on('point:click', action)
newChart.on('interval:click', action)
configPlotTooltipEvent(chart, newChart)
return newChart
}
@ -544,7 +547,10 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
}
})
return result
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return {
...options,

View File

@ -1,7 +1,7 @@
import type { FunnelOptions, Funnel as G2Funnel } from '@antv/g2plot/esm/plots/funnel'
import { G2PlotChartView, G2PlotDrawOptions } from '../../types/impl/g2plot'
import { flow, parseJson, setUpSingleDimensionSeriesColor } from '@/views/chart/components/js/util'
import { getPadding } from '../../common/common_antv'
import { configPlotTooltipEvent, getPadding } from '../../common/common_antv'
import { useI18n } from '@/hooks/web/useI18n'
import { Datum } from '@antv/g2plot/esm/types/common'
import { valueFormatter } from '@/views/chart/components/js/formatter'
@ -110,6 +110,7 @@ export class Funnel extends G2PlotChartView<FunnelOptions, G2Funnel> {
const { Funnel: G2Funnel } = await import('@antv/g2plot/esm/plots/funnel')
const newChart = new G2Funnel(container, options)
newChart.on('interval:click', action)
configPlotTooltipEvent(chart, newChart)
return newChart
}

View File

@ -8,6 +8,7 @@ import { valueFormatter } from '@/views/chart/components/js/formatter'
import { useI18n } from '@/hooks/web/useI18n'
import { isEmpty, map } from 'lodash-es'
import { cloneDeep, defaultTo } from 'lodash-es'
import { configPlotTooltipEvent, getTooltipContainer, TOOLTIP_TPL } from '../../common/common_antv'
const { t } = useI18n()
/**
@ -209,6 +210,7 @@ export class Quadrant extends G2PlotChartView<ScatterOptions, G2Scatter> {
newChart.on('point:click', action)
newChart.on('click', () => quadrantDefaultBaseline(defaultBaselineQuadrant))
newChart.on('afterrender', () => quadrantDefaultBaseline(defaultBaselineQuadrant))
configPlotTooltipEvent(chart, newChart)
return newChart
}
@ -379,7 +381,10 @@ export class Quadrant extends G2PlotChartView<ScatterOptions, G2Scatter> {
})
}
return result
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return {
...options,

View File

@ -1,7 +1,7 @@
import type { RadarOptions, Radar as G2Radar } from '@antv/g2plot/esm/plots/radar'
import { G2PlotChartView, G2PlotDrawOptions } from '../../types/impl/g2plot'
import { flow, parseJson } from '../../../util'
import { getPadding } from '../../common/common_antv'
import { configPlotTooltipEvent, getPadding } from '../../common/common_antv'
import { valueFormatter } from '../../../formatter'
import type { Datum } from '@antv/g2plot/esm/types/common'
import { useI18n } from '@/hooks/web/useI18n'
@ -117,6 +117,7 @@ export class Radar extends G2PlotChartView<RadarOptions, G2Radar> {
const { Radar: G2Radar } = await import('@antv/g2plot/esm/plots/radar')
const newChart = new G2Radar(container, options)
newChart.on('point:click', action)
configPlotTooltipEvent(chart, newChart)
return newChart
}

View File

@ -5,7 +5,12 @@ import {
import type { ScatterOptions, Scatter as G2Scatter } from '@antv/g2plot/esm/plots/scatter'
import { flow, parseJson } from '../../../util'
import { valueFormatter } from '../../../formatter'
import { getPadding } from '../../common/common_antv'
import {
configPlotTooltipEvent,
getPadding,
getTooltipContainer,
TOOLTIP_TPL
} from '../../common/common_antv'
import { useI18n } from '@/hooks/web/useI18n'
import { isEmpty } from 'lodash-es'
@ -133,6 +138,7 @@ export class Scatter extends G2PlotChartView<ScatterOptions, G2Scatter> {
const { Scatter: G2Scatter } = await import('@antv/g2plot/esm/plots/scatter')
const newChart = new G2Scatter(container, options)
newChart.on('point:click', action)
configPlotTooltipEvent(chart, newChart)
return newChart
}
@ -233,7 +239,10 @@ export class Scatter extends G2PlotChartView<ScatterOptions, G2Scatter> {
}
})
return result
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return {
...options,

View File

@ -10,8 +10,11 @@ import {
setUpSingleDimensionSeriesColor
} from '@/views/chart/components/js/util'
import {
configPlotTooltipEvent,
getPadding,
getTooltipSeriesTotalMap
getTooltipContainer,
getTooltipSeriesTotalMap,
TOOLTIP_TPL
} from '@/views/chart/components/js/panel/common/common_antv'
import { valueFormatter } from '@/views/chart/components/js/formatter'
import {
@ -118,6 +121,7 @@ export class Pie extends G2PlotChartView<PieOptions, G2Pie> {
const { Pie: G2Pie } = await import('@antv/g2plot/esm/plots/pie')
const newChart = new G2Pie(container, options)
newChart.on('interval:click', action)
configPlotTooltipEvent(chart, newChart)
return newChart
}
@ -237,7 +241,10 @@ export class Pie extends G2PlotChartView<PieOptions, G2Pie> {
}
})
return result
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return {
...options,

View File

@ -10,8 +10,11 @@ import {
PIE_EDITOR_PROPERTY_INNER
} from './common'
import {
configPlotTooltipEvent,
getPadding,
getTooltipSeriesTotalMap
getTooltipContainer,
getTooltipSeriesTotalMap,
TOOLTIP_TPL
} from '@/views/chart/components/js/panel/common/common_antv'
import { parseJson, flow, setUpSingleDimensionSeriesColor } from '@/views/chart/components/js/util'
import { Label } from '@antv/g2plot/lib/types/label'
@ -94,7 +97,7 @@ export class Rose extends G2PlotChartView<RoseOptions, G2Rose> {
const plot = new G2Rose(container, options)
plot.on('interval:click', action)
configPlotTooltipEvent(chart, plot)
return plot
}
@ -213,7 +216,10 @@ export class Rose extends G2PlotChartView<RoseOptions, G2Rose> {
}
})
return result
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return {
...options,

View File

@ -30,6 +30,8 @@ import { Scene } from '@antv/l7-scene'
import { type IZoomControlOption } from '@antv/l7-component'
import { PositionType } from '@antv/l7-core'
import { centroid } from '@turf/centroid'
import type { Plot } from '@antv/g2plot'
import type { PickOptions } from '@antv/g2plot/lib/core/plot'
export function getPadding(chart: Chart): number[] {
if (chart.drill) {
@ -124,7 +126,9 @@ export function getTheme(chart: Chart) {
color: tooltipColor,
fontSize: tooltipFontsize + 'px',
background: tooltipBackgroundColor,
boxShadow: '0 4px 8px 0 rgba(0, 0, 0, 0.1)'
boxShadow: '0 4px 8px 0 rgba(0, 0, 0, 0.1)',
'z-index': 3000,
position: 'fixed'
}
}
},
@ -206,7 +210,10 @@ export function getTooltip(chart: Chart) {
formatter: function (param: Datum) {
const value = valueFormatter(param.value, t.tooltipFormatter)
return { name: param.field, value }
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
} else {
tooltip = false
@ -257,7 +264,10 @@ export function getMultiSeriesTooltip(chart: Chart) {
}
})
return result
}
},
container: getTooltipContainer(`tooltip-${chart.id}`),
itemTpl: TOOLTIP_TPL,
enterable: true
}
return tooltip
}
@ -1195,7 +1205,10 @@ function shouldHideZoom(basicStyle: any): boolean {
* @param basicStyle
*/
function getCenter(basicStyle: any): [number, number] {
let center = [DEFAULT_BASIC_STYLE.mapCenter.longitude, DEFAULT_BASIC_STYLE.mapCenter.latitude]
let center: [number, number] = [
DEFAULT_BASIC_STYLE.mapCenter.longitude,
DEFAULT_BASIC_STYLE.mapCenter.latitude
]
if (basicStyle.autoFit === false) {
center = [basicStyle.mapCenter.longitude, basicStyle.mapCenter.latitude]
}
@ -1210,3 +1223,107 @@ function getCenter(basicStyle: any): [number, number] {
function addCustomZoom(plotScene: Scene, newZoomOptions: any): void {
plotScene.addControl(new CustomZoom(newZoomOptions))
}
const G2_TOOLTIP_WRAPPER = 'g2-tooltip-wrapper'
export function getTooltipContainer(id) {
let wrapperDom = document.getElementById(G2_TOOLTIP_WRAPPER)
if (!wrapperDom) {
wrapperDom = document.createElement('div')
wrapperDom.id = G2_TOOLTIP_WRAPPER
document.body.appendChild(wrapperDom)
}
const curDom = document.getElementById(id)
if (curDom) {
curDom.remove()
}
const g2Tooltip = document.createElement('div')
g2Tooltip.setAttribute('id', id)
g2Tooltip.classList.add('g2-tooltip')
// 最多半屏鼠标移入可滚动
g2Tooltip.style.maxHeight = '50%'
g2Tooltip.style.overflowY = 'auto'
g2Tooltip.style.display = 'none'
g2Tooltip.style.position = 'fixed'
g2Tooltip.style.left = '0px'
g2Tooltip.style.top = '0px'
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 {
wrapperDom.appendChild(g2Tooltip)
}
return g2Tooltip
}
export function configPlotTooltipEvent<O extends PickOptions, P extends Plot<O>>(
chart: Chart,
plot: P
) {
const { tooltip } = parseJson(chart.customAttr)
if (!tooltip.show) {
return
}
// 鼠标可移入, 移入之后保持显示, 移出之后隐藏
plot.options.tooltip.container.addEventListener('mouseenter', e => {
e.target.style.visibility = 'visible'
e.target.style.display = 'block'
})
plot.options.tooltip.container.addEventListener('mouseleave', e => {
e.target.style.visibility = 'hidden'
e.target.style.display = 'none'
})
// 手动处理 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
}
const event = plot.chart.interactions.tooltip?.context?.event
if (tooltipCtl.tooltip) {
// 处理视图放大后再关闭 tooltip dom 被清除
const container = tooltipCtl.tooltip.cfg.container
container.style.display = 'block'
const dom = document.getElementById(container.id)
if (!dom) {
const full = document.getElementsByClassName('fullscreen')
if (full.length) {
full.item(0).appendChild(container)
} else {
const wrapperDom = document.getElementById(G2_TOOLTIP_WRAPPER)
wrapperDom.appendChild(container)
}
}
}
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
const container = tooltipCtl.tooltip?.cfg?.container
if (container) {
container.style.display = 'none'
}
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>'