Recharts:如何在工具提示中仅显示一个数据点的值?

Recharts: how is it possible to show only the value of ONE data point inside a Tooltip?

我正在尝试在 Recharts LineChart 中实现以下示例:Tooltip 值是相对于蓝点的,因为我的鼠标恰好靠近它,而远离具有相同 x 值的灰点.如果我将鼠标移近灰色点,工具提示内容会发生变化。

但是,所有可用的示例都表明,Recharts 工具提示接收有关正在绘制的所有数据系列的数据,并且似乎无法区分离鼠标最近的点,因此工具提示可能仅提供其值。

有没有办法指定我要将数据发送到工具提示的点?

经过长时间的无果搜索,我决定自己解决这个问题。 最小代码发布在 this Github gist.

要解决的基本问题是任何标准 Recharts 工具提示都会收到以下信息:

  • 此时鼠标指针所在的 x 值,在图表上以像素表示 canvas
  • 最接近鼠标 x 值的所有数据系列的 y 值,以 y 轴真实世界单位(欧元、千克等)表示

因此,有必要为自定义工具提示提供图表上以像素表示的 y 轴鼠标位置信息 canvas。 工具提示然后可以计算哪个数据系列最接近垂直鼠标位置并仅显示属于该数据系列的值。

以像素为单位提取 y 位置很棘手,因为 Recharts 每次重绘图表时都会更改像素值和纵坐标值之间的映射。但是有一个图表组件必须非常了解这个映射,以便将自己放置在正确的垂直位置并显示相应的真实世界纵坐标值:that's every tick on the y-axis.

问题是:我们如何插入 Recharts 绘图工作流程以了解映射?

方法如下:Recharts YAxis 组件的 tick 属性 允许提供自定义 React 组件,尽管没有示例记录。 对于 Recharts 决定放置在 y 轴上的每个刻度,此自定义组件实例化一次。 通过反复试验,我发现我的自定义 Tick 组件具有以下属性:

{ x, y, payload, ...anyCustomPropertyAddedByMe }

其中xy是tick的笛卡尔坐标(canvas像素),payload是这样一个对象:

{ coordinates, isShow, offset, tickCoord, value }

其中 value 以真实世界的 y 轴单位表示。

思路是找出每张图中最低和最高刻度的一对(y, value),并计算像素与实际值之间的转换系数。 这将允许自定义工具提示执行上述计算。 (严格来说,从每次图表重绘时实例化的前两个刻度中收集两对就足够了,但选择最远的两个可以提供更高的精度)

整个算法分为三个部分:

  • a tooltipCollector: this is a JavaScript module 提供两种方法:

    1. collect(value, y),由自定义报价调用,将所有对 (y, value) 存储在私有数组 _collection
    2. maxAndMin(),由自定义工具提示调用,它读取 _collection 数组和 returns 集合中代表最低和最高刻度的一对项目(注意canvas 中的垂直像素值是颠倒测量的!)
  • 一个 CustomizedTick React 组件:

    1. 在其自定义属性中接收工具提示收集器
    2. 通过调用其 collect(y, value) 方法将其 ypayload.value 发送到收集器
    3. returns 一个非常简单的 JSX 刻度标记,它使用 y(将自身置于正确的垂直位置)和 payload.value(向用户显示真实世界勾号表示的值)
  • 一个 CustomTooltip React 组件:

    1. 在其自定义属性中接收工具提示收集器并调用其 maxAndMin() 方法
    2. 使用阈值验证(通过考虑其支持 coordinate.y)它是否足够接近图表数据系列之一;这可确保仅当鼠标光标非常接近图表上的某个点时才绘制工具提示
    3. 修改其返回的 JSX 标记以仅包含与鼠标最接近的数据系列相关的值;如果图表中有更多点比阈值更近,工具提示将显示多个值

我的要点中的代码已经过简化,删除了所有不必要的 JSX 标记。它提供了一个 chart component,可以使上述所有组件发挥作用。

请注意,突出显示工具提示横坐标所指向的所有数据系列的点 的标准 Recharts 行为并未更改。因此,最好在工具提示内容中放置颜色代码,以清楚地说明显示的值属于哪个数据系列。