Skip to content
Open
39 changes: 39 additions & 0 deletions docs/components/tooltips.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,45 @@ See [Events and callbacks](/docs/xy/api-reference/events-and-callbacks/) for
hover payloads and [Marks and components reference](/docs/xy/api-reference/marks-and-components/)
for the exact tooltip signature.

## Shared Tooltip Along an Axis

`xy.tooltip(mode="x")` turns the tooltip into an axis tooltip, the model
Recharts uses by default and Plotly calls `hovermode="x unified"`. The pointer
only has to be inside the plot: its horizontal position snaps to the nearest x
value and every series' point at that x is listed at once, while the vertical
position is ignored. The plot divides into full-height bands with boundaries
halfway between adjacent points, a cursor line marks the selected x, each
series shows an active dot, and the tooltip follows the pointer. Bars join by
their footprint: a grouped bar chart lists every series of the category under
the pointer, with one cursor on the category centre — and no active dots, since
the bar is already the mark. `mode="y"` does the same along
the y axis — useful for horizontal layouts, but available on any Cartesian
chart. The default, `mode="nearest"`, keeps the 12 px nearest-point behavior.

~~~python demo exec
import reflex_xy
import xy

pages = ["Page A", "Page B", "Page C", "Page D", "Page E", "Page F", "Page G"]
shared_tooltip_chart = xy.line_chart(
xy.line(pages, [2400, 1398, 9800, 3908, 4800, 3800, 4300], name="pv", color="#8884d8", width=2),
xy.line(pages, [4000, 3000, 2000, 2780, 1890, 2390, 3490], name="uv", color="#82ca9d", width=2),
xy.tooltip(mode="x"),
xy.legend(loc="upper right"),
title="Hover anywhere above a page",
)


def shared_tooltip_demo():
return reflex_xy.chart(shared_tooltip_chart, height="320px")
~~~

`fields=`, `format=`, and `title=` keep their meaning: the title template
resolves against the first series' row, and each series row shows the
requested fields (minus the band axis, which is already the title). Style the
cursor line through the `tooltip_cursor` slot or the `--chart-crosshair`
token it shares with the crosshair.

## FAQ

### How do I show values on hover in a Python chart?
Expand Down
3 changes: 2 additions & 1 deletion docs/styling/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ and *does the change survive where I need it*. This page answers both from the
registry the implementation is checked against.

- **11** mark style properties across **22** mark kinds, drawn by all three renderers.
- **48** stable chrome slots for CSS and Tailwind in the browser.
- **49** stable chrome slots for CSS and Tailwind in the browser.
- **1** way to add a mark kind XY does not ship, without forking it.

## Mark style properties
Expand Down Expand Up @@ -79,6 +79,7 @@ token bag or in mark and axis `style=`, which every renderer reads.
| `tooltip_row` | full | none | none |
| `tooltip_label` | full | none | none |
| `tooltip_value` | full | none | none |
| `tooltip_cursor` | full | none | none |
| `modebar` | full | none | none |
| `modebar_drag_handle` | full | none | none |
| `modebar_control_group` | full | none | none |
Expand Down
5 changes: 3 additions & 2 deletions docs/styling/chrome-slots.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ primitive or structural descendant is a separate DOM element.
| `tooltip_row` | One tooltip field row |
| `tooltip_label` | One tooltip field label |
| `tooltip_value` | One formatted tooltip value |
| `tooltip_cursor` | Line across the plot at the shared-tooltip band coordinate — vertical for `xy.tooltip(mode="x")`, horizontal for `mode="y"` |
| `modebar` | Mode/tool bar container |
| `modebar_drag_handle` | Draggable grip revealed beside the toolbar |
| `modebar_control_group` | Selection, pan, and export control group |
Expand Down Expand Up @@ -358,8 +359,8 @@ apply it with. Rather than leave that to be discovered, it is a contract:
| --- | --- | --- | --- |
| mark / axis `style=` | yes | yes | yes |
| chart-level `style=` (design tokens) | yes | yes | yes |
| `styles={slot: {...}}` | yes, all 48 slots | text subset, 9 slots | text subset, 9 slots |
| `class_names={slot: "..."}` | yes, all 48 slots | dropped | dropped |
| `styles={slot: {...}}` | yes, all 49 slots | text subset, 9 slots | text subset, 9 slots |
| `class_names={slot: "..."}` | yes, all 49 slots | dropped | dropped |
| `custom_css=` | yes | raises | raises |
| `xy.legend(style=...)` | yes | 6 keys | 6 keys |
| `xy.colorbar(style=...)` | yes | dropped | dropped |
Expand Down
1 change: 1 addition & 0 deletions js/src/20_theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ export const XY_CHROME_CSS = `
:where(.xy [data-xy-selection-lasso-handle]){fill:var(--chart-bg,#fff);stroke:var(--chart-selection,var(--xy-selection));stroke-width:1.5;cursor:grab;pointer-events:all}
:where(.xy [data-xy-selection-lasso-handle][data-xy-active]){cursor:grabbing;fill:var(--chart-selection,var(--xy-selection))}
:where(.xy [data-xy-slot="crosshair_x"],.xy [data-xy-slot="crosshair_y"]){background:var(--chart-crosshair,rgba(15,23,42,.42))}
:where(.xy [data-xy-slot="tooltip_cursor"]){background:var(--chart-crosshair,rgba(15,23,42,.42))}
:where(.xy [data-xy-slot="axis_band"]){cursor:var(--xy-axis-band-cursor)}
:where(.xy [data-xy-slot="axis_line"],.xy [data-xy-slot="tick_mark"]){width:var(--xy-axis-rule-width);height:var(--xy-axis-rule-height);background:var(--xy-axis-rule-paint)}
:where(.xy [data-xy-slot="tick_label"]){color:var(--chart-text,inherit)}
Expand Down
Loading
Loading