Skip to content

Commit d0c319c

Browse files
committed
add id to tooltip main element - and add a basic tooltip test
1 parent 6275d60 commit d0c319c

File tree

2 files changed

+87
-2
lines changed

2 files changed

+87
-2
lines changed

components/dash-core-components/src/components/Tooltip.react.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import _JSXStyle from 'styled-jsx/style'; // eslint-disable-line no-unused-vars
66
* A tooltip with an absolute position.
77
*/
88
const Tooltip = props => {
9-
const {bbox, border_color, background_color, loading_state} = props;
9+
const {bbox, border_color, background_color, id, loading_state} = props;
1010
const is_loading = loading_state?.is_loading;
1111
const show = props.show && bbox;
1212

1313
return (
1414
<>
15-
<div className="dcc-tooltip-bounding-box">
15+
<div id={id} className="dcc-tooltip-bounding-box">
1616
<span
1717
data-dash-is-loading={is_loading || undefined}
1818
className={`hover hover-${props.direction}`}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
from multiprocessing import Lock
2+
from selenium.webdriver.common.action_chains import ActionChains
3+
from dash.testing.wait import until
4+
5+
from dash import Dash, Input, Output, dcc, html, no_update
6+
7+
8+
def test_ttbs001_canonical_behavior(dash_dcc):
9+
lock = Lock()
10+
11+
loading_text = "Waiting for Godot"
12+
13+
fig = dict(
14+
data=[
15+
dict(
16+
x=[11, 22, 33], y=[333, 222, 111], mode="markers", marker=dict(size=40)
17+
)
18+
],
19+
layout=dict(width=400, height=400, margin=dict(l=100, r=100, t=100, b=100)),
20+
)
21+
app = Dash(__name__)
22+
23+
app.layout = html.Div(
24+
className="container",
25+
children=[
26+
dcc.Graph(id="graph", figure=fig, clear_on_unhover=True),
27+
dcc.Tooltip(id="graph-tooltip", loading_text=loading_text),
28+
],
29+
style=dict(position="relative"),
30+
)
31+
32+
# This callback is executed very quickly
33+
app.clientside_callback(
34+
"""
35+
function show_tooltip(hoverData) {
36+
if(!hoverData) {
37+
return [false, dash_clientside.no_update];
38+
}
39+
var pt = hoverData.points[0];
40+
return [true, pt.bbox];
41+
}
42+
""",
43+
Output("graph-tooltip", "show"),
44+
Output("graph-tooltip", "bbox"),
45+
Input("graph", "hoverData"),
46+
)
47+
48+
# This callback is executed after 1s to simulate a long-running process
49+
@app.callback(
50+
Output("graph-tooltip", "children"),
51+
Input("graph", "hoverData"),
52+
)
53+
def update_tooltip_content(hoverData):
54+
if hoverData is None:
55+
return no_update
56+
57+
with lock:
58+
# Display the x0 and y0 coordinate
59+
bbox = hoverData["points"][0]["bbox"]
60+
return [
61+
html.P(f"x0={bbox['x0']}, y0={bbox['y0']}"),
62+
]
63+
64+
dash_dcc.start_server(app)
65+
66+
until(lambda: not dash_dcc.find_element("#graph-tooltip").is_displayed(), 3)
67+
68+
elem = dash_dcc.find_element("#graph .nsewdrag")
69+
70+
with lock:
71+
# hover on the center of the graph
72+
ActionChains(dash_dcc.driver).move_to_element_with_offset(
73+
elem, elem.size["width"] / 2, elem.size["height"] / 2
74+
).click().perform()
75+
dash_dcc.wait_for_text_to_equal("#graph-tooltip", loading_text)
76+
77+
dash_dcc.wait_for_contains_text("#graph-tooltip", "x0=")
78+
tt_text = dash_dcc.find_element("#graph-tooltip").text
79+
coords = [float(part.split("=")[1]) for part in tt_text.split(",")]
80+
assert 175 < coords[0] < 180, "x0 is about 200 minus half a marker size"
81+
assert 175 < coords[1] < 185, "y0 is about 200 minus half a marker size"
82+
83+
ActionChains(dash_dcc.driver).move_to_element_with_offset(elem, 0, 0).perform()
84+
85+
until(lambda: not dash_dcc.find_element("#graph-tooltip").is_displayed(), 3)

0 commit comments

Comments
 (0)