mirror of
https://github.com/dataease/dataease.git
synced 2026-06-17 04:51:43 +08:00
fix(图表): 修复面积图以及柱条图可能出现提示中缺少指标的问题
This commit is contained in:
@@ -32,8 +32,13 @@ import {
|
||||
} from '@/views/chart/components/editor/util/chart'
|
||||
import {
|
||||
createTooltipWrapper,
|
||||
getSeriesTooltipFormatter,
|
||||
getSeriesTooltipFormatterMap,
|
||||
getStackTooltipGroupName,
|
||||
getTooltipItemFormatter,
|
||||
handleEmptyDataStrategy,
|
||||
isSeriesTooltipFormatterShown,
|
||||
isTooltipItemShown,
|
||||
renderGroupedTooltipItems,
|
||||
tooltipCss,
|
||||
tooltipMaxHeight,
|
||||
@@ -248,12 +253,7 @@ export class Bar extends G2ChartView<ViewSpec, G2Column> {
|
||||
if (!tooltipAttr.show) {
|
||||
return options
|
||||
}
|
||||
const formatterMap = tooltipAttr.seriesTooltipFormatter
|
||||
?.filter(i => i.show)
|
||||
.reduce((pre, next) => {
|
||||
pre[next.id] = next
|
||||
return pre
|
||||
}, {}) as Record<string, SeriesFormatter>
|
||||
const formatterMap = getSeriesTooltipFormatterMap(tooltipAttr)
|
||||
const tooltipOptions: ViewSpec = {
|
||||
tooltip: d => d,
|
||||
interaction: {
|
||||
@@ -268,24 +268,34 @@ export class Bar extends G2ChartView<ViewSpec, G2Column> {
|
||||
const titleHtml = TOOLTIP_TITLE_TPL.replace('{title}', title)
|
||||
let tooltipItems = originalItems
|
||||
if (tooltipAttr.seriesTooltipFormatter?.length) {
|
||||
tooltipItems = originalItems.filter(item => formatterMap[item.quotaList[0].id])
|
||||
// 只隐藏明确配置为不展示的字段,避免过期 formatter 漏掉新指标。
|
||||
tooltipItems = originalItems.filter(item =>
|
||||
isTooltipItemShown(formatterMap, item, 'yAxis')
|
||||
)
|
||||
}
|
||||
const result = []
|
||||
const head = originalItems[0]
|
||||
tooltipItems.forEach(item => {
|
||||
const formatter = formatterMap[item.quotaList[0].id] ?? yAxis[0]
|
||||
const formatter = getTooltipItemFormatter(formatterMap, item, yAxis, 'yAxis')
|
||||
const value =
|
||||
item.value === null || item.value === undefined
|
||||
? ''
|
||||
: valueFormatter(item.value, formatter.formatterCfg)
|
||||
const name = isEmpty(formatter.chartShowName)
|
||||
? formatter.name
|
||||
: valueFormatter(
|
||||
item.value,
|
||||
formatter?.formatterCfg ?? tooltipAttr.tooltipFormatter
|
||||
)
|
||||
const name = isEmpty(formatter?.chartShowName)
|
||||
? formatter?.name ?? item.name
|
||||
: formatter.chartShowName
|
||||
result.push({ ...item, name, value })
|
||||
})
|
||||
head.dynamicTooltipValue?.forEach(item => {
|
||||
const formatter = formatterMap[item.fieldId]
|
||||
if (formatter) {
|
||||
const formatter = getSeriesTooltipFormatter(
|
||||
formatterMap,
|
||||
item.fieldId,
|
||||
chart.extTooltip
|
||||
)
|
||||
if (formatter && isSeriesTooltipFormatterShown(formatterMap, item.fieldId)) {
|
||||
const value =
|
||||
item.value === null || item.value === undefined
|
||||
? ''
|
||||
|
||||
@@ -283,6 +283,82 @@ export function tooltipMaxHeight(chart: Chart) {
|
||||
return `max-height: ${maxHeight}px;max-width: ${chartRect.width / 2}px;`
|
||||
}
|
||||
|
||||
export function getSeriesTooltipFormatterMap(tooltipAttr?: DeepPartial<ChartTooltipAttr>) {
|
||||
return (tooltipAttr?.seriesTooltipFormatter || []).reduce((pre, next) => {
|
||||
if (!next?.id) {
|
||||
return pre
|
||||
}
|
||||
const formatter = next as SeriesFormatter
|
||||
// 同一字段可出现在不同指标槽位,优先用 seriesId 区分具体槽位。
|
||||
if (formatter.seriesId) {
|
||||
pre[formatter.seriesId] = formatter
|
||||
}
|
||||
if (!formatter.seriesId || formatter.seriesId === formatter.id) {
|
||||
pre[formatter.id] = formatter
|
||||
}
|
||||
return pre
|
||||
}, {} as Record<string, SeriesFormatter>)
|
||||
}
|
||||
|
||||
export function getTooltipItemFieldId(item?: any) {
|
||||
return item?.quotaList?.[0]?.id ?? item?.data?.quotaList?.[0]?.id ?? item?.fieldId
|
||||
}
|
||||
|
||||
// 旧图表样式可能带着过期 formatter;当前字段缺少配置时按默认展示处理。
|
||||
export function isSeriesTooltipFormatterShown(
|
||||
formatterMap: Record<string, SeriesFormatter>,
|
||||
fieldId?: string,
|
||||
axisType?: AxisType
|
||||
) {
|
||||
if (!fieldId) {
|
||||
return true
|
||||
}
|
||||
if (axisType) {
|
||||
// 带槽位的主指标不能被旧的 id 级 show:false 误隐藏。
|
||||
const seriesKey = `${fieldId}-${axisType}`
|
||||
return Object.prototype.hasOwnProperty.call(formatterMap, seriesKey)
|
||||
? formatterMap[seriesKey]?.show !== false
|
||||
: true
|
||||
}
|
||||
if (Object.prototype.hasOwnProperty.call(formatterMap, fieldId)) {
|
||||
return formatterMap[fieldId]?.show !== false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export function isTooltipItemShown(
|
||||
formatterMap: Record<string, SeriesFormatter>,
|
||||
item?: any,
|
||||
axisType?: AxisType
|
||||
) {
|
||||
return isSeriesTooltipFormatterShown(formatterMap, getTooltipItemFieldId(item), axisType)
|
||||
}
|
||||
|
||||
// 带槽位的 formatter 缺项时回退到当前轴字段,避免旧 id 级配置污染新指标。
|
||||
export function getSeriesTooltipFormatter(
|
||||
formatterMap: Record<string, SeriesFormatter>,
|
||||
fieldId?: string,
|
||||
fields: Partial<Axis>[] = [],
|
||||
axisType?: AxisType
|
||||
) {
|
||||
const field = fields.find(field => field?.id === fieldId)
|
||||
const seriesId = (field as Partial<SeriesFormatter>)?.seriesId
|
||||
if (axisType && fieldId) {
|
||||
const seriesKey = `${fieldId}-${axisType}`
|
||||
return formatterMap[seriesKey] || (seriesId && formatterMap[seriesId]) || field
|
||||
}
|
||||
return (fieldId && formatterMap[fieldId]) || (seriesId && formatterMap[seriesId]) || field
|
||||
}
|
||||
|
||||
export function getTooltipItemFormatter(
|
||||
formatterMap: Record<string, SeriesFormatter>,
|
||||
item: any,
|
||||
fields: Partial<Axis>[] = [],
|
||||
axisType?: AxisType
|
||||
) {
|
||||
return getSeriesTooltipFormatter(formatterMap, getTooltipItemFieldId(item), fields, axisType)
|
||||
}
|
||||
|
||||
// 将字段显示名降级到原始字段名,避免 tooltip 分组标题为空
|
||||
export function getFieldDisplayName(field?: Partial<ChartViewField>) {
|
||||
return field?.chartShowName || field?.name || ''
|
||||
|
||||
@@ -38,8 +38,13 @@ import { registerSymbol, Symbols } from '@antv/g2/esm/utils/marker'
|
||||
import G2TooltipCarousel from '@/views/chart/components/js/G2TooltipCarousel'
|
||||
import {
|
||||
createTooltipWrapper,
|
||||
getSeriesTooltipFormatter,
|
||||
getSeriesTooltipFormatterMap,
|
||||
getStackTooltipGroupName,
|
||||
getTooltipItemFormatter,
|
||||
renderGroupedTooltipItems,
|
||||
isSeriesTooltipFormatterShown,
|
||||
isTooltipItemShown,
|
||||
tooltipCss,
|
||||
tooltipMaxHeight
|
||||
} from '../bar/barUtil'
|
||||
@@ -608,12 +613,7 @@ export class Area extends G2ChartView {
|
||||
defaultsDeep(lineMark, { tooltip: false })
|
||||
return options
|
||||
}
|
||||
const formatterMap = tooltipAttr.seriesTooltipFormatter
|
||||
?.filter(i => i.show)
|
||||
.reduce((pre, next) => {
|
||||
pre[next.id] = next
|
||||
return pre
|
||||
}, {}) as Record<string, SeriesFormatter>
|
||||
const formatterMap = getSeriesTooltipFormatterMap(tooltipAttr)
|
||||
const yAxis = chart.yAxis
|
||||
const tooltipOptions: G2Spec = {
|
||||
tooltip: d => d,
|
||||
@@ -623,11 +623,14 @@ export class Area extends G2ChartView {
|
||||
mount: createTooltipWrapper(chart),
|
||||
css: tooltipCss(tooltipAttr),
|
||||
enterable: true,
|
||||
render: (e, { title, items: originalItems }) => {
|
||||
render: (_e, { title, items: originalItems }) => {
|
||||
const titleHtml = TOOLTIP_TITLE_TPL.replace('{title}', title)
|
||||
let tooltipItems = originalItems
|
||||
if (tooltipAttr.seriesTooltipFormatter?.length) {
|
||||
tooltipItems = originalItems.filter(item => formatterMap[item.quotaList[0].id])
|
||||
// 只隐藏明确配置为不展示的字段,避免过期 formatter 漏掉新指标。
|
||||
tooltipItems = originalItems.filter(item =>
|
||||
isTooltipItemShown(formatterMap, item, 'yAxis')
|
||||
)
|
||||
}
|
||||
const result = []
|
||||
const head = originalItems[0]
|
||||
@@ -635,13 +638,20 @@ export class Area extends G2ChartView {
|
||||
if (item.value === null || item.value === undefined) {
|
||||
return
|
||||
}
|
||||
const formatter = formatterMap[item.quotaList[0].id] ?? yAxis[0]
|
||||
const value = valueFormatter(item.value, formatter.formatterCfg)
|
||||
const formatter = getTooltipItemFormatter(formatterMap, item, yAxis, 'yAxis')
|
||||
const value = valueFormatter(
|
||||
item.value,
|
||||
formatter?.formatterCfg ?? tooltipAttr.tooltipFormatter
|
||||
)
|
||||
result.push({ ...item, name: item.category, value })
|
||||
})
|
||||
head.dynamicTooltipValue?.forEach(item => {
|
||||
const formatter = formatterMap[item.fieldId]
|
||||
if (formatter) {
|
||||
const formatter = getSeriesTooltipFormatter(
|
||||
formatterMap,
|
||||
item.fieldId,
|
||||
chart.extTooltip
|
||||
)
|
||||
if (formatter && isSeriesTooltipFormatterShown(formatterMap, item.fieldId)) {
|
||||
const value = valueFormatter(parseFloat(item.value), formatter.formatterCfg)
|
||||
const name = isEmpty(formatter.chartShowName)
|
||||
? formatter.name
|
||||
|
||||
Reference in New Issue
Block a user