Open
Description
Describe the bug / 问题描述
给图表设置了联动 tooltip 后,再界面上用鼠标反复划过多个图表,一段时间后,界面就崩溃卡死了。
20250422-174813.mp4
const ChartCard: FC<IChartCard> = ({
params,
dateFrom,
dateTo,
chartMapRef
}) => {
const { name, sourceData } = params;
const {
data: cardData,
loading,
error,
run: queryData
} = useQueryPrometheusData(sourceData ?? [], dateFrom, dateTo);
useRefreshEvent(EventEmitterKey.Refresh_Real_Time_Market, queryData);
const timeSet = useMemo(() => {
if (!cardData?.length) {
return [];
}
const set = new Set<number>();
cardData.forEach((item) => {
set.add(item.time);
});
return Array.from(set.values());
}, [cardData]);
const showTooltip = (time?: number) => {
chartMapRef.current?.forEach((chart) => {
chart.emit('tooltip:show', {
data: { data: { x: time } }
});
});
};
const hideTooltip = () => {
chartMapRef.current?.forEach((chart) => {
chart.emit('tooltip:hide');
});
};
return (
<CardWrapper
apiLoading={loading}
apiError={
error && (
<Typography.Paragraph
type="danger"
ellipsis={{ rows: 2, tooltip: getErrorMessage(error ?? '') }}
>
{getErrorMessage(error ?? '')}
</Typography.Paragraph>
)
}
title={name}
headBordered={false}
className="chart-card-wrapper"
emptyStatus={!cardData?.length}
height={320}
>
<Line
data={cardData}
xField="time"
yField="value"
colorField="type"
shapeField="smooth"
height={280}
marginLeft={0}
marginRight={0}
legend={false}
area={{ style: { opacity: 0.2 } }}
style={{ opacity: 0.6, lineWidth: 2 }}
axis={{
y: {
tick: false,
labelFormatter: (val: number) => {
return renderValue(val, sourceData?.[0].unit);
}
},
x: {
line: true,
lineStroke: 'gray',
tickStroke: 'gray',
labelAutoRotate: false,
labelAutoHide: true,
labelFormatter: (t: number) => moment(t).format('MM/DD HH:mm')
}
}}
tooltip={{
title: (d) => moment(d.time).format(dateDefaultFormat),
items: [
(d) => {
return {
name: d.type,
value: renderValue(d.value, d.unit)
};
}
]
}}
interaction={{
tooltip: {
render: (
_: any,
{
title,
items
}: {
title: string;
items: { name: string; value: string; color: string }[];
}
) => {
// 图表库bug:会出现重复的值,需要手动去重一下
const map = new Map();
items.forEach((item: any) => {
map.set(item.name, item);
});
const liStr = Array.from(map.values())
.map((item) => {
return `<div style="display: flex;justify-content: space-between;align-items: center;white-space: nowrap; line-height: 2em;">
<div style="display: flex; align-items: center; max-width: 216px;"><span style="background: ${item.color};width:8px;height:8px;display: inline-block; border-radius: 50%; margin-right:4px"></span><span style="flex: 1 1 0%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">${item.name}:</span></div>
<div style="display: inline-block; float: right; flex: 1 1 0%; text-align: right; min-width: 28px; margin-left: 30px; color: rgba(0, 0, 0, 0.85); overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">${item.value}</div>
</div>`;
})
.join('');
return `<div>
<div>${title}</div>
<div>${liStr}</div>
</div>`;
}
}
}}
onReady={({ chart }) => {
chartMapRef.current?.push(chart);
chart.on('plot:pointermove', (evt: any) => {
const { x } = evt;
const { layout } = chart.getView();
const paddingLeft = layout.width - layout.innerWidth;
const coordinatesX = x - paddingLeft;
// 根据位置粗略计算出 tooltip data
const percent = coordinatesX / layout.innerWidth;
showTooltip(timeSet?.[Math.floor(percent * timeSet.length)] ?? 0);
});
chart.on('plot:pointerout', hideTooltip);
}}
/>
</CardWrapper>
);
};
Reproduction link / 复现链接
No response
Steps to Reproduce the Bug or Issue / 重现步骤
No response
Version / 版本
Please select / 请选择
OS / 操作系统
- macOS
- Windows
- Linux
- Others / 其他
Browser / 浏览器
- Chrome
- Edge
- Firefox
- Safari (Limited support / 有限支持)
- IE (Nonsupport / 不支持)
- Others / 其他