Skip to content

Commit b863461

Browse files
author
iexitdev
committed
feat: support top bar tooltip placement
1 parent ef82eb6 commit b863461

4 files changed

Lines changed: 55 additions & 22 deletions

File tree

packages/react-native/src/charts/bar/tooltip.tsx

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@ export const renderDefaultBarChartTooltip = <TData,>(
3232
}
3333

3434
const contentX = x + config.padding;
35+
const hasLabel = bar.xLabel.trim().length > 0;
3536
const labelY = y + config.padding + config.labelFontSize;
36-
const valueY = labelY + tooltipLineHeight;
37+
const valueY = hasLabel
38+
? labelY + tooltipLineHeight
39+
: y + config.padding + config.fontSize;
3740
const hasShadow = config.shadowOpacity > 0;
3841
const { Circle, Group, Rect, Text } = renderer;
3942
const valueText = `${bar.seriesLabel}: ${bar.formattedValue}`;
@@ -62,17 +65,19 @@ export const renderDefaultBarChartTooltip = <TData,>(
6265
strokeOpacity={0.2}
6366
strokeWidth={1}
6467
/>
65-
<Text
66-
x={contentX}
67-
y={labelY}
68-
fill={config.labelColor}
69-
fontSize={config.labelFontSize}
70-
fontWeight="600"
71-
text={bar.xLabel}
72-
{...getFontFamilyProps(config.fontFamily)}
73-
>
74-
{bar.xLabel}
75-
</Text>
68+
{hasLabel ? (
69+
<Text
70+
x={contentX}
71+
y={labelY}
72+
fill={config.labelColor}
73+
fontSize={config.labelFontSize}
74+
fontWeight="600"
75+
text={bar.xLabel}
76+
{...getFontFamilyProps(config.fontFamily)}
77+
>
78+
{bar.xLabel}
79+
</Text>
80+
) : null}
7681
<Circle
7782
cx={contentX + 3}
7883
cy={valueY - config.fontSize * 0.32}

packages/react-native/src/charts/bar/tooltipModel.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,11 @@ export const getBarChartTooltipModel = <TData>({
4242
return undefined;
4343
}
4444

45-
const height =
46-
config.padding * 2 + config.labelFontSize + tooltipLineHeight + 2;
45+
const hasLabel = bar.xLabel.trim().length > 0;
46+
const contentHeight = hasLabel
47+
? config.labelFontSize + tooltipLineHeight
48+
: config.fontSize;
49+
const height = config.padding * 2 + contentHeight + 2;
4750
const pointerAnchor =
4851
config.anchor === "pointer" && pointer?.key === bar.key
4952
? pointer
@@ -60,13 +63,15 @@ export const getBarChartTooltipModel = <TData>({
6063
const aboveY = anchorY - height - config.offset;
6164
const belowY = belowAnchorY + config.offset;
6265
const y =
63-
config.placement === "above"
64-
? clamp(aboveY, minY, maxY)
65-
: config.placement === "below"
66-
? clamp(belowY, minY, maxY)
67-
: aboveY >= minY
68-
? aboveY
69-
: clamp(belowY, minY, maxY);
66+
config.placement === "top"
67+
? minY
68+
: config.placement === "above"
69+
? clamp(aboveY, minY, maxY)
70+
: config.placement === "below"
71+
? clamp(belowY, minY, maxY)
72+
: aboveY >= minY
73+
? aboveY
74+
: clamp(belowY, minY, maxY);
7075

7176
return {
7277
bar,

packages/react-native/src/charts/bar/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export type BarChartTooltipConfig = {
9191
};
9292

9393
export type BarChartTooltipAnchor = "bar" | "pointer";
94-
export type BarChartTooltipPlacement = "auto" | "above" | "below";
94+
export type BarChartTooltipPlacement = "auto" | "above" | "below" | "top";
9595

9696
export type ResolvedBarChartTooltipConfig = {
9797
visible: boolean;

packages/react-native/test/bar-interaction.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,29 @@ describe("BarChart interaction helpers", () => {
303303
});
304304
});
305305

306+
it("supports top-pinned tooltips that still follow the selected bar x", () => {
307+
const tooltip = getBarChartTooltipModel({
308+
bar: { ...bars[0]!, x: 180 },
309+
boxes: {
310+
outer: { x: 0, y: 0, width: 320, height: 220 },
311+
plot: { x: 52, y: 24, width: 240, height: 160 }
312+
},
313+
config: getBarChartTooltipConfig({
314+
themeTooltip,
315+
tooltip: {
316+
edgePadding: 6,
317+
placement: "top",
318+
width: 132
319+
}
320+
})
321+
});
322+
323+
expect(tooltip).toMatchObject({
324+
x: 128,
325+
y: 6
326+
});
327+
});
328+
306329
it("keys tooltip animation targets by selected bar and position", () => {
307330
const tooltip = getBarChartTooltipModel({
308331
bar: bars[0],

0 commit comments

Comments
 (0)