From 97cb80f8b999bc0c91eb29fe8c277437abd8cb2c Mon Sep 17 00:00:00 2001 From: jianneng-fit2cloud Date: Fri, 31 Oct 2025 18:32:38 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E5=9B=BE=E8=A1=A8):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=A4=A7=E5=B1=8F=E7=BC=A9=E6=94=BE=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E6=8F=90=E7=A4=BA=E6=A1=86=E4=BD=8D=E7=BD=AE=E5=81=8F?= =?UTF-8?q?=E7=A7=BB=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E8=BD=AE=E6=92=AD=E5=90=8E=E4=B8=8D=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E8=87=AA=E5=AE=9A=E4=B9=89=E6=8F=90=E7=A4=BA=E5=AE=B9?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core-frontend/src/models/chart/chart.d.ts | 1 + .../chart/components/js/G2TooltipCarousel.ts | 16 ++--- .../components/js/panel/charts/g2/bar/bar.ts | 7 ++- .../js/panel/charts/g2/bar/barUtil.ts | 59 ++++++++++++------- .../js/panel/charts/g2/bar/group-stack-bar.ts | 4 +- .../charts/g2/bar/percentage-stack-bar.ts | 9 ++- .../js/panel/charts/g2/bar/stack-bar.ts | 6 +- .../js/panel/charts/g2/line/area.ts | 12 +++- .../js/panel/charts/g2/line/line.ts | 7 ++- .../js/panel/charts/g2/mix/mix-dual-line.ts | 9 ++- .../js/panel/charts/g2/mix/mix-group.ts | 9 ++- .../js/panel/charts/g2/mix/mix-stack.ts | 9 ++- .../components/js/panel/charts/g2/mix/mix.ts | 9 ++- .../views/components/ChartComponentG2Plot.vue | 3 +- 14 files changed, 98 insertions(+), 62 deletions(-) diff --git a/core/core-frontend/src/models/chart/chart.d.ts b/core/core-frontend/src/models/chart/chart.d.ts index b5970a4e9c..18c3b14035 100644 --- a/core/core-frontend/src/models/chart/chart.d.ts +++ b/core/core-frontend/src/models/chart/chart.d.ts @@ -78,6 +78,7 @@ declare interface Chart { fontFamily?: string dashboardHidden?: boolean inMobile?: boolean + [key: any]: any } declare type CustomAttr = DeepPartial | JSONString> declare type CustomStyle = DeepPartial | JSONString> diff --git a/core/core-frontend/src/views/chart/components/js/G2TooltipCarousel.ts b/core/core-frontend/src/views/chart/components/js/G2TooltipCarousel.ts index 31ad27d644..0192cb5cf7 100644 --- a/core/core-frontend/src/views/chart/components/js/G2TooltipCarousel.ts +++ b/core/core-frontend/src/views/chart/components/js/G2TooltipCarousel.ts @@ -256,14 +256,8 @@ class G2TooltipCarousel { if (!el) return false // 检查可见比例 const rect = el.getBoundingClientRect() - let visibleHeight = Math.min(rect.bottom, window.innerHeight) - Math.max(rect.top, 60) - let visibleWidth = Math.min(rect.right, window.innerWidth) - Math.max(rect.left, 0) - const dvMainCenter = document.getElementById('dv-main-center') - if (dvMainCenter) { - const dvRect = dvMainCenter.getBoundingClientRect() - visibleHeight = Math.min(rect.bottom, dvRect.bottom) - Math.max(rect.top, dvRect.top) - visibleWidth = Math.min(rect.right, dvRect.right) - Math.max(rect.left, dvRect.left) - } + const visibleHeight = Math.min(rect.bottom, window.innerHeight) - Math.max(rect.top, 60) + const visibleWidth = Math.min(rect.right, window.innerWidth) - Math.max(rect.left, 0) const percentHeight = visibleHeight / rect.height const percentWidth = visibleWidth / rect.width return percentHeight > 0.7 && percentWidth > 0.7 @@ -445,7 +439,7 @@ class G2TooltipCarousel { try { const ctx = this.newChart.getContext() const root = ctx.canvas.document.getElementsByClassName('plot')[0] - const { center } = root.getRenderBounds() + const { height } = root.getRenderBounds() const scaleX = (this.newChart.getScale() || ctx.views[0].scale).x const x = tooltipData.data.data.x || @@ -456,8 +450,8 @@ class G2TooltipCarousel { ]) const { insetLeft, marginLeft, paddingLeft } = root.__data__ return { - offsetX: insetLeft + marginLeft + paddingLeft + x2, - offsetY: center[1] + offsetX: insetLeft + marginLeft + paddingLeft + x2 * this.chart.tScale, + offsetY: (height / 2) * this.chart.tScale } } catch (e) { console.error('Get Tooltip offsetX fail:', e) diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/bar.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/bar.ts index 55fd14d191..64e2b31a4a 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/bar.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/bar.ts @@ -25,6 +25,7 @@ import { import { createTooltipWrapper, tooltipCss, + tooltipMaxHeight, Transform, ViewSpec } from '@/views/chart/components/js/panel/charts/g2/bar/barUtil' @@ -224,7 +225,7 @@ export class Bar extends G2ChartView { tooltip: { mount: createTooltipWrapper(chart), css: tooltipCss(tooltipAttr), - enterable: false, + enterable: true, shared: true, position: 'top-right', render: (_, { title, items: originalItems }) => { @@ -263,7 +264,9 @@ export class Bar extends G2ChartView { .replace('{value}', value) }) .join('') - const listHtml = `
    ${itemsHtml}
` + const listHtml = `
    ${itemsHtml}
` return `${titleHtml}${listHtml}` } } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/barUtil.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/barUtil.ts index abaebbf2c3..3ced83e2de 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/barUtil.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/barUtil.ts @@ -62,7 +62,8 @@ export function createTooltipWrapper(chart: Chart) { g2TooltipWrapper.style.top = '0px' document.body.appendChild(g2TooltipWrapper) } - return g2TooltipWrapper + // 如果开启轮播则不使用自定义tooltip容器 + return chart.customAttr?.tooltip?.carousel?.enable ? undefined : g2TooltipWrapper } export function tooltipCss(tooltipAttr: DeepPartial) { @@ -88,24 +89,39 @@ export function tooltipCss(tooltipAttr: DeepPartial) { } } +/** + * 计算 tooltip 最大高度 + * 最大高度为图表高度-20px + * @param chart + */ +export function tooltipMaxHeight(chart: Chart) { + const chartContainer = document.getElementById(chart.container) + const defaultHeight = 80 + const maxHeight = chartContainer + ? Math.max(chartContainer.getBoundingClientRect().height - 20, defaultHeight) + : defaultHeight + return `max-height: ${maxHeight}px;` +} + export function listenerTooltipShow(newChart: G2Chart, chart: Chart) { newChart.on('tooltip:show', event => { - const tooltipWrapper = document.getElementById(tooltipWrapperId(chart.container)) - if (tooltipWrapper) { - tooltipWrapper.style.zIndex = chart.container.indexOf('viewDialog') > -1 ? '9999' : '2000' - const allTooltips = tooltipWrapper?.querySelectorAll('.g2-tooltip') - if (!allTooltips) return - allTooltips.forEach(item => { - const tooltip = item as HTMLElement - tooltip.style.visibility = 'visible' - if (event?.offsetY) { - const { top, height } = newChart - ?.getContext() - ?.canvas?.context?.contextService?.$container?.getBoundingClientRect() - if (top) { - tooltip.style.top = top + height / 2 - tooltip.getBoundingClientRect().height / 2 + 'px' - } - } + const isCarousel = chart.customAttr?.tooltip?.carousel?.enable + const tooltipWrapper = isCarousel + ? document.getElementById(chart.container) + : document.getElementById(tooltipWrapperId(chart.container)) + if (!tooltipWrapper) return + tooltipWrapper.style.zIndex = chart.container.indexOf('viewDialog') > -1 ? '9999' : '2000' + const allTooltips = tooltipWrapper?.querySelectorAll('.g2-tooltip') + if (!allTooltips) return + allTooltips.forEach(item => { + const tooltip = item as HTMLElement + const { height, right } = newChart + ?.getContext() + ?.canvas?.context?.contextService?.$container?.getBoundingClientRect() + if (isCarousel) { + const tooltipHeight = tooltip.getBoundingClientRect().height + tooltip.style.top = (height / 2 - tooltipHeight / 2 + 20) * chart.tScale + 'px' + } else { const clientY = event?.client?.y if (!clientY) return if (clientY < tooltip.getBoundingClientRect().height) { @@ -120,13 +136,12 @@ export function listenerTooltipShow(newChart: G2Chart, chart: Chart) { document.getElementById('preview-canvas-main') if (!targetDiv || clientX == null) return - const dvRight = targetDiv.getBoundingClientRect().right const tooltipWidth = tooltip.getBoundingClientRect().width - const left = clientX + 20 + const left = clientX tooltip.style.left = - left + tooltipWidth > dvRight ? `${dvRight - tooltipWidth}px` : `${left}px` - }) - } + left + tooltipWidth > right ? `${clientX - tooltipWidth - 20}px` : `${left + 20}px` + } + }) }) } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/group-stack-bar.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/group-stack-bar.ts index cdf6ae4296..d2ba619802 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/group-stack-bar.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/group-stack-bar.ts @@ -12,11 +12,11 @@ import { } from '@/views/chart/components/js/panel/charts/g2/bar/barUtil' import { valueFormatter } from '@/views/chart/components/js/formatter' import { - TOOLTIP_ITEM_TPL, toLinearGradient, + TOOLTIP_ITEM_TPL, TOOLTIP_TITLE_TPL } from '@/views/chart/components/js/panel/common/common_antv' -import { defaultsDeep, isEmpty } from 'lodash-es' +import { isEmpty } from 'lodash-es' /** * 分组堆叠柱状图 diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/percentage-stack-bar.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/percentage-stack-bar.ts index d0536f71e6..30bb32f74c 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/percentage-stack-bar.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/percentage-stack-bar.ts @@ -3,6 +3,7 @@ import { flow, parseJson } from '@/views/chart/components/js/util' import { createTooltipWrapper, tooltipCss, + tooltipMaxHeight, ViewSpec } from '@/views/chart/components/js/panel/charts/g2/bar/barUtil' import { GroupStackBar } from '@/views/chart/components/js/panel/charts/g2/bar/group-stack-bar' @@ -89,10 +90,6 @@ export class PercentageStackBar extends GroupStackBar { css: tooltipCss(tooltip), enterable: true, shared: true, - bounding: { - x: 0, - y: 0 - }, position: 'top-right', render: (_, { title, items: originalItems }) => { const titleHtml = TOOLTIP_TITLE_TPL.replace('{title}', title) @@ -122,7 +119,9 @@ export class PercentageStackBar extends GroupStackBar { .replace('{value}', value) }) .join('') - const listHtml = `
    ${itemsHtml}
` + const listHtml = `
    ${itemsHtml}
` return `${titleHtml}${listHtml}` } } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/stack-bar.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/stack-bar.ts index 84ed38d3ee..2ab48b439e 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/stack-bar.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/bar/stack-bar.ts @@ -129,7 +129,7 @@ export class StackBar extends Bar { tooltip: { mount: createTooltipWrapper(chart), css: tooltipCss(tooltip), - enterable: false, + enterable: true, shared: true, position: 'top-right', render: (_, { title, items: originalItems }) => { @@ -151,7 +151,9 @@ export class StackBar extends Bar { .replace('{value}', value) }) .join('') - const listHtml = `
    ${itemsHtml}
` + const listHtml = `
    ${itemsHtml}
` return `${titleHtml}${listHtml}` } } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/line/area.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/line/area.ts index 2896bbcb14..760452c946 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/line/area.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/line/area.ts @@ -29,7 +29,7 @@ import { } from '../../../common/common_antv' import { registerSymbol, Symbols } from '@antv/g2/esm/utils/marker' import G2TooltipCarousel from '@/views/chart/components/js/G2TooltipCarousel' -import { createTooltipWrapper, tooltipCss } from '../bar/barUtil' +import { createTooltipWrapper, tooltipCss, tooltipMaxHeight } from '../bar/barUtil' const { t } = useI18n() const DEFAULT_DATA = [] @@ -571,6 +571,7 @@ export class Area extends G2ChartView { crosshairsLineDash: [4, 4], mount: createTooltipWrapper(chart), css: tooltipCss(tooltipAttr), + enterable: true, render: (e, { title, items: originalItems }) => { const titleHtml = TOOLTIP_TITLE_TPL.replace('{title}', title) let tooltipItems = originalItems @@ -607,7 +608,9 @@ export class Area extends G2ChartView { .replace('{value}', value) }) .join('') - const listHtml = `
    ${itemsHtml}
` + const listHtml = `
    ${itemsHtml}
` return `${titleHtml}${listHtml}` } } @@ -829,6 +832,7 @@ export class StackArea extends Area { crosshairsLineDash: [4, 4], mount: createTooltipWrapper(chart), css: tooltipCss(tooltipAttr), + enterable: true, render: (e, { title, items }) => { const titleHtml = TOOLTIP_TITLE_TPL.replace('{title}', title) const result = [] @@ -849,7 +853,9 @@ export class StackArea extends Area { .replace('{value}', value) }) .join('') - const listHtml = `
    ${itemsHtml}
` + const listHtml = `
    ${itemsHtml}
` return `${titleHtml}${listHtml}` } } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/line/line.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/line/line.ts index a49a9f7f17..118797df9b 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/line/line.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/line/line.ts @@ -26,7 +26,7 @@ import { import { extremumEvt, addExtremumText } from '@/views/chart/components/js/extremumUitl' import { registerSymbol, Symbols } from '@antv/g2/esm/utils/marker' import G2TooltipCarousel from '@/views/chart/components/js/G2TooltipCarousel' -import { createTooltipWrapper, tooltipCss } from '../bar/barUtil' +import { createTooltipWrapper, tooltipCss, tooltipMaxHeight } from '../bar/barUtil' const { t } = useI18n() const DEFAULT_DATA = [] @@ -650,6 +650,7 @@ export class Line extends G2ChartView { mount: createTooltipWrapper(chart), css: tooltipCss(tooltipAttr), position: 'top-right', + enterable: true, render: (e, { title, items: originalItems }) => { const titleHtml = TOOLTIP_TITLE_TPL.replace('{title}', title) let tooltipItems = originalItems @@ -686,7 +687,9 @@ export class Line extends G2ChartView { .replace('{value}', value) }) .join('') - const listHtml = `
    ${itemsHtml}
` + const listHtml = `
    ${itemsHtml}
` return `${titleHtml}${listHtml}` } } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix-dual-line.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix-dual-line.ts index 9015f5b97d..1a8169637c 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix-dual-line.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix-dual-line.ts @@ -25,7 +25,8 @@ import { registerSymbol, Symbols } from '@antv/g2/esm/utils/marker' import G2TooltipCarousel from '@/views/chart/components/js/G2TooltipCarousel' import { createTooltipWrapper, - tooltipCss + tooltipCss, + tooltipMaxHeight } from '@/views/chart/components/js/panel/charts/g2/bar/barUtil' const { t } = useI18n() @@ -594,7 +595,7 @@ export class GroupLineMix extends G2ChartView { crosshairsLineDash: [4, 4], mount: createTooltipWrapper(chart), css: tooltipCss(tooltip), - enterable: false, + enterable: true, render: (_, { title, items }) => { const titleHtml = TOOLTIP_TITLE_TPL.replace('{title}', title) if (tooltip.seriesTooltipFormatter?.length) { @@ -621,7 +622,9 @@ export class GroupLineMix extends G2ChartView { .replace('{value}', value) }) .join('') - const listHtml = `
    ${itemsHtml}
` + const listHtml = `
    ${itemsHtml}
` return `${titleHtml}${listHtml}` } } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix-group.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix-group.ts index 82d5643c3a..ec27169031 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix-group.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix-group.ts @@ -28,7 +28,8 @@ import { registerSymbol, Symbols } from '@antv/g2/esm/utils/marker' import G2TooltipCarousel from '@/views/chart/components/js/G2TooltipCarousel' import { createTooltipWrapper, - tooltipCss + tooltipCss, + tooltipMaxHeight } from '@/views/chart/components/js/panel/charts/g2/bar/barUtil' const { t } = useI18n() @@ -575,7 +576,7 @@ export class GroupLineMix extends G2ChartView { crosshairsLineDash: [4, 4], mount: createTooltipWrapper(chart), css: tooltipCss(tooltip), - enterable: false, + enterable: true, render: (_, { title, items }) => { const titleHtml = TOOLTIP_TITLE_TPL.replace('{title}', title) if (tooltip.seriesTooltipFormatter?.length) { @@ -602,7 +603,9 @@ export class GroupLineMix extends G2ChartView { .replace('{value}', value) }) .join('') - const listHtml = `
    ${itemsHtml}
` + const listHtml = `
    ${itemsHtml}
` return `${titleHtml}${listHtml}` } } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix-stack.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix-stack.ts index 47778ffb51..b5c05b5e06 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix-stack.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix-stack.ts @@ -27,7 +27,8 @@ import { registerSymbol, Symbols } from '@antv/g2/esm/utils/marker' import G2TooltipCarousel from '@/views/chart/components/js/G2TooltipCarousel' import { createTooltipWrapper, - tooltipCss + tooltipCss, + tooltipMaxHeight } from '@/views/chart/components/js/panel/charts/g2/bar/barUtil' const { t } = useI18n() @@ -573,7 +574,7 @@ export class StackLineMix extends G2ChartView { crosshairsLineDash: [4, 4], mount: createTooltipWrapper(chart), css: tooltipCss(tooltip), - enterable: false, + enterable: true, render: (_, { title, items }) => { const titleHtml = TOOLTIP_TITLE_TPL.replace('{title}', title) if (tooltip.seriesTooltipFormatter?.length) { @@ -600,7 +601,9 @@ export class StackLineMix extends G2ChartView { .replace('{value}', value) }) .join('') - const listHtml = `
    ${itemsHtml}
` + const listHtml = `
    ${itemsHtml}
` return `${titleHtml}${listHtml}` } } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix.ts index 9c2f3cb29a..356f3fcc0c 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/mix/mix.ts @@ -26,7 +26,8 @@ import { CHART_MIX_EDITOR_PROPERTY, CHART_MIX_EDITOR_PROPERTY_INNER } from './co import G2TooltipCarousel from '@/views/chart/components/js/G2TooltipCarousel' import { createTooltipWrapper, - tooltipCss + tooltipCss, + tooltipMaxHeight } from '@/views/chart/components/js/panel/charts/g2/bar/barUtil' const { t } = useI18n() @@ -425,7 +426,7 @@ export class ColumnLineMix extends G2ChartView { crosshairsLineDash: [4, 4], mount: createTooltipWrapper(chart), css: tooltipCss(tooltip), - enterable: false, + enterable: true, render: (_, { title, items }) => { const titleHtml = TOOLTIP_TITLE_TPL.replace('{title}', title) if (tooltip.seriesTooltipFormatter?.length) { @@ -452,7 +453,9 @@ export class ColumnLineMix extends G2ChartView { .replace('{value}', value) }) .join('') - const listHtml = `
    ${itemsHtml}
` + const listHtml = `
    ${itemsHtml}
` return `${titleHtml}${listHtml}` } } diff --git a/core/core-frontend/src/views/chart/components/views/components/ChartComponentG2Plot.vue b/core/core-frontend/src/views/chart/components/views/components/ChartComponentG2Plot.vue index ed7a397c4b..62394e23f9 100644 --- a/core/core-frontend/src/views/chart/components/views/components/ChartComponentG2Plot.vue +++ b/core/core-frontend/src/views/chart/components/views/components/ChartComponentG2Plot.vue @@ -359,10 +359,11 @@ const renderG2 = async (chart, chartView: G2PlotChartView) => { if (dvMainStore.mobileInPc) { dashboardHidden = !props.element.inMobile } + const tScale = dvMainStore.canvasStyleData?.tScale myChart = await chartView.drawChart({ chartObj: myChart, container: containerId, - chart: { ...chart, container: containerId, dashboardHidden }, + chart: { ...chart, container: containerId, dashboardHidden, tScale }, scale: scale.value, action, quadrantDefaultBaseline