【MantineCharts】ツールチップの表示位置をカスタマイズする

# はじめに
この記事では、MantineCharts でツールチップの表示位置をカスタマイズする方法を記載します。

https://mantine.dev/charts/scatter-chart/

# 開発環境
開発環境は以下の通りです。

- Windows 11
- Next.js 14.2.4
- React 18.3.1
- TypeScript 5.5.2
- @mantine/core 7.15.1
- @mantine/hooks 7.15.1
- @mantine/charts 7.15.1

# デフォルトの挙動を確認する
カスタマイズする前にデフォルトの挙動を確認します。

```data.ts
export const data = [
  {
    color: "blue.5",
    name: "Group 1",
    data: [
      { age: 25, BMI: 20 },
      { age: 30, BMI: 22 },
      { age: 35, BMI: 18 },
      { age: 40, BMI: 25 },
      { age: 45, BMI: 30 },
      { age: 28, BMI: 15 },
      { age: 22, BMI: 12 },
      { age: 50, BMI: 28 },
      { age: 32, BMI: 19 },
      { age: 48, BMI: 31 },
      { age: 26, BMI: 24 },
      { age: 38, BMI: 27 },
      { age: 42, BMI: 29 },
      { age: 29, BMI: 16 },
      { age: 34, BMI: 23 },
      { age: 44, BMI: 33 },
      { age: 23, BMI: 14 },
      { age: 37, BMI: 26 },
      { age: 49, BMI: 34 },
      { age: 27, BMI: 17 },
      { age: 41, BMI: 32 },
      { age: 31, BMI: 21 },
      { age: 46, BMI: 35 },
      { age: 24, BMI: 13 },
      { age: 33, BMI: 22 },
      { age: 39, BMI: 28 },
      { age: 47, BMI: 30 },
      { age: 36, BMI: 25 },
      { age: 43, BMI: 29 },
      { age: 21, BMI: 11 },
    ],
  },
  {
    color: "red.5",
    name: "Group 2",
    data: [
      { age: 26, BMI: 21 },
      { age: 31, BMI: 24 },
      { age: 37, BMI: 19 },
      { age: 42, BMI: 27 },
      { age: 29, BMI: 32 },
      { age: 35, BMI: 18 },
      { age: 40, BMI: 23 },
      { age: 45, BMI: 30 },
      { age: 27, BMI: 15 },
      { age: 33, BMI: 20 },
      { age: 38, BMI: 25 },
      { age: 43, BMI: 29 },
      { age: 30, BMI: 16 },
      { age: 36, BMI: 22 },
      { age: 41, BMI: 28 },
      { age: 46, BMI: 33 },
      { age: 28, BMI: 17 },
      { age: 34, BMI: 22 },
      { age: 39, BMI: 26 },
      { age: 44, BMI: 31 },
      { age: 32, BMI: 18 },
      { age: 38, BMI: 23 },
      { age: 43, BMI: 28 },
      { age: 48, BMI: 35 },
      { age: 25, BMI: 14 },
      { age: 31, BMI: 20 },
      { age: 36, BMI: 25 },
      { age: 41, BMI: 30 },
      { age: 29, BMI: 16 },
    ],
  },
];

```

```page.tsx
import { ScatterChart } from "@mantine/charts";
import { data } from "./data";

export default function Page() {
  return <ScatterChart h={360} data={data} dataKey={{ x: "age", y: "BMI" }} />;
}

```

デフォルトの挙動は以下の通りになります。

- X軸: マウスカーソルに合わせて変わる
- Y軸: 常にチャートの上部

![localhost_3000_charts_mantine-charts_scatter-charts_tooltip-Google-Chrome-2024-12-16-08-00-26.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/79c4ba63-92bd-3f41-87be-2f9d948abf2d.gif)

# 表示位置をカスタマイズする
Y軸もマウスカーソルに合わせて変わるようにカスタマイズします。

## 実装方針
2024年12月時点の v7.15.1 では、Mantine Charts 自体に直接表示位置をカスタマイズできるような props は存在しません。
一方、MantineCharts のベースとなっている Recharts の `Tooltip` コンポーネントでは、以下の props を組み合わせて利用することで表示位置をカスタマイズできます。

- [`coordinate`](https://recharts.org/en-US/api/Tooltip#coordinate): Tooltip の表示位置を設定できる
- [`content`](https://recharts.org/en-US/api/Tooltip#content): Tooltip にカスタマイズした React 要素や関数を設定でき、関数を設定する場合、引数に coordinate を渡すことができる

また、MantineCharts の `tooltipProps` という props を使うことで、Recharts の `Tooltip` コンポーネントの props を渡すことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/8cc7b8ad-995c-05a2-d7f1-695e5d6238fe.png)

https://mantine.dev/charts/scatter-chart/?t=props

そのため、MantineCharts の `tooltipProps` に `content` を渡してカスタマイズします。

## カスタマイズの実装
上記の方針を踏まえた実装が以下の通りです。

```page.tsx
"use client";

import { ScatterChart } from "@mantine/charts";
import { data } from "./data";
import { Paper, Text } from "@mantine/core";

export default function Page() {
  return (
    <ScatterChart
      h={360}
      data={data}
      dataKey={{ x: "age", y: "BMI" }}
      tooltipProps={{
        content: ({ payload, coordinate }) => {
          if (!payload || !coordinate) return null;

          return (
            <Paper
              w={200}
              p="md"
              shadow="md"
              style={{
                position: "absolute",
                top: `${(coordinate.y || 0) + 10}px`,
                left: `${(coordinate.x || 0) + 10}px`,
              }}
            >
              <Text>
                {payload[0]?.name}: {payload[0]?.value}
              </Text>
              <Text>
                {payload[1]?.name}: {payload[1]?.value}
              </Text>
            </Paper>
          );
        },
      }}
    />
  );
}

```

動作確認をします。
X軸、Y軸ともにマウスカーソルの右下に Tooltip が表示されます。

![localhost_3000_charts_mantine-charts_scatter-charts_tooltip-Google-Chrome-2024-12-16-09-09-56.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/728efe36-7d36-16ca-02b2-9d82b8307799.gif)


# 参考
- [ScatterChart](https://mantine.dev/charts/scatter-chart/)
- [Tooltip](https://recharts.org/en-US/api/Tooltip)