Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tooltip bbox position is incorrect when inside a dcc.Loading component #3015

Open
TenteEEEE opened this issue Sep 24, 2024 · 2 comments
Open
Labels
bug something broken P3 not needed for current cycle

Comments

@TenteEEEE
Copy link

First of all, I want to express my appreciation for this excellent product.

Context

I have a graph that takes a long time to render, and I want to display a loading indicator before it renders.

dash                      2.18.1
dash-bootstrap-components 1.6.0
dash-core-components      2.0.0
dash-html-components      2.0.0
dash-table                5.0.0
  • OS: Windows 11 Pro 23H2
  • Browser: Chrome
  • Version: 128.0.6613.139

Bug

When the graph is nested inside a dcc.Loading component, the tooltip's bbox position is misaligned with the plot when displayed.
From my investigation, in Dash 2.17.0, the tooltip's bbox position is correct regardless of whether it's nested inside a loading component.
However, starting from Dash 2.17.1, the tooltip's bbox position becomes incorrect when nested.

Expected behavior

The tooltip's bbox position should be correct regardless of whether the graph is nested inside a dcc.Loading component.

Screenshots

Here I show the tooltip's bbox position problem using my minimal reproduction example.

Dash 2.17.0

スクリーンショット 2024-09-24 105542

Dash 2.17.1

スクリーンショット 2024-09-24 105634

Dash 2.18.1

スクリーンショット 2024-09-24 105734

Minimal Reproduction Example

poetry install
poetry run python main.py

poetry.lock

[tool.poetry]
name = "dash-tooltip-test"
version = "0.1.0"
description = ""
authors = ["Your Name <[email protected]>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.12"
dash = "=2.18.1"
plotly = "^5.24.1"
pandas = "^2.2.3"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

main.py

from typing import Optional

import plotly.express as px
from dash import Dash, Input, Output, dcc, html, no_update

APP = Dash()
APP.title = "Tooltip Test"
APP.layout = html.Div(
    [
        html.H1("Tooltip Test (Dash 2.18.1)"),
        html.H2("With Loading"),
        dcc.Loading(
            id="loading",
            type="default",
            children=[
                dcc.Graph(
                    id="graph-with-loading",
                    figure=px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16]),
                ),
            ],
        ),
        dcc.Tooltip(id="tooltip-with-loading"),
        html.H2("Without Loading"),
        dcc.Graph(
            id="graph-without-loading",
            figure=px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16]),
        ),
        dcc.Tooltip(id="tooltip-without-loading"),
    ]
)


@APP.callback(
    Output("tooltip-with-loading", "show"),
    Output("tooltip-with-loading", "bbox"),
    Output("tooltip-with-loading", "children"),
    Input("graph-with-loading", "hoverData"),
)
def display_tooltip_with_loading(hoverData: Optional[dict]) -> tuple[bool, dict, str]:
    if hoverData is None:
        return False, no_update, no_update

    bbox = hoverData["points"][0]["bbox"]
    return (
        True,
        bbox,
        f"x: {hoverData['points'][0]['x']}, y: {hoverData['points'][0]['y']}",
    )


@APP.callback(
    Output("tooltip-without-loading", "show"),
    Output("tooltip-without-loading", "bbox"),
    Output("tooltip-without-loading", "children"),
    Input("graph-without-loading", "hoverData"),
)
def display_tooltip_without_loading(
    hoverData: Optional[dict],
) -> tuple[bool, dict, str]:
    if hoverData is None:
        return False, no_update, no_update

    bbox = hoverData["points"][0]["bbox"]
    return (
        True,
        bbox,
        f"x: {hoverData['points'][0]['x']}, y: {hoverData['points'][0]['y']}",
    )


if __name__ == "__main__":
    APP.run_server(debug=True)
@AnnMarieW
Copy link
Collaborator

AnnMarieW commented Sep 24, 2024

Hi @TenteEEEE

Thanks for the great write-up and the sample app! 🏆

I was able to reproduce the issue. I would have expected to see this issue in 2.17.0 as well, because the dcc.Tooltip should be included as child of the dcc.Loading component.

This worked as expected in the current version of Dash. I'm not sure if this should be consider a bug.

    dcc.Loading(
            id="loading",
            type="default",
            delay_show=1000,
            children=[
                dcc.Graph(
                    id="graph-with-loading",
                    figure=px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16]),
                ),
                dcc.Tooltip(id="tooltip-with-loading"),
            ],
        ),

Update - it should probably work both ways, so the above might just be considered a workaround.

@TenteEEEE
Copy link
Author

@AnnMarieW

Thank you for your response!

I sincerely appreciate your guidance on the appropriate workaround.
In my application, displaying the tooltip is also a time-consuming process that involves loading images.
If the dcc.Tooltip is placed inside the dcc.Loading, it displays an excessive loading overlay, so I placed the dcc.Tooltip outside the dcc.Loading.
My understanding is that the correct approach would be to use target_components and implement it as shown below.

        dcc.Loading(
            id="loading",
            type="default",
            children=[
                dcc.Graph(
                    id="graph-with-loading",
                    figure=px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16]),
                ),
                dcc.Tooltip(
                    id="tooltip-with-loading",
                ),
            ],
            target_components={"graph-with-loading": "children"},
        ),

Is this correct?

My personal issue has been completely resolved with the above solution, so I now understand that this issue is not a bug but a specification.
If the maintainers also consider this issue to be a specification, I would appreciate it if the issue could be closed.

Once again, thank you for your support!

@gvwilson gvwilson changed the title [BUG] Tooltip bbox position is incorrect when inside a dcc.Loading component Tooltip bbox position is incorrect when inside a dcc.Loading component Sep 27, 2024
@gvwilson gvwilson added bug something broken P3 not needed for current cycle labels Sep 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken P3 not needed for current cycle
Projects
None yet
Development

No branches or pull requests

3 participants