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

graphType Network crashed when user shift rendered pictute with LMB #145

Open
glempi opened this issue Mar 2, 2024 · 7 comments
Open

graphType Network crashed when user shift rendered pictute with LMB #145

glempi opened this issue Mar 2, 2024 · 7 comments
Assignees

Comments

@glempi
Copy link

glempi commented Mar 2, 2024

Initially graph rendered ok.
Crash is occured after user holding left mouse button and moving it (to shift rendered picture in viewport)

javascript callstack on crash:

Screenshot_20240303_004227
you can see that node.layout.displaycement field is undefined.

to reproduce you can use python script and json data which python script used

data
network.json

from canvasxpress.canvas import CanvasXpress
import json
import math
from dash import Dash, html
from canvasxpress.render.dash import CXElementFactory


with open("network.json", "r") as f:
    data = json.loads(f.read())

cx = CanvasXpress(
    render_to = "test",
    data = data,
    config = {

        "background": "rgb(100,255,255)",
        "calculateLayout": True,
        "networkLayoutType": "forceDirected",
        "graphType": "Network",

    },

    width = 1400,
    # height = 800
)


g_app = Dash(__name__)

g_app.layout = html.Div(
            id="cx-container",
            style={"textAlign": "center"},
            children=CXElementFactory.render(cx),
        )

if __name__ == "__main__":
    g_app.run_server(debug=True)
@glempi glempi changed the title graphType Network crashed when user move canvas with LMB graphType Network crashed when user shift rendered pictute with LMB Mar 2, 2024
@neuhausi
Copy link
Owner

neuhausi commented Mar 6, 2024

I can't reproduce . I am asking a collaborator to check. Sorry for the delay.

@cb4ds
Copy link
Collaborator

cb4ds commented Mar 7, 2024

@docinfosci can you check - script is in python

@docinfosci
Copy link
Collaborator

docinfosci commented Mar 7, 2024

Thanks! I am confirming that I've seen this and will investigate.

@glempi -- try setting render_to = "" (empty string). This forces CanvasXpress for Python to generate anonymous IDs when passing generated configurations or JavaScript to the Web browser for use by CanvasXpress for JavaScript.

Why?

Dash uses React for its JavaScript, and React requires that UI updates destroy and recreate UI JavaScript objects when updates occur instead of reusing existing objects. But, in this case, an HTML canvas element is also generated using whatever ID is provided. CanvasXpress for JavaScript pays attention to the canvas element ID. There's a moment of opportunity in which CanvasXpress for JavaScript thinks there is still a chart object named the same ID as the canvas element when in fact the DOM/React has disposed of the old object and a new one has yet to be created to take its place—in which case running code can crash. By using anonymous IDs a new ID is assigned to the canvas element with each refresh, so when CanvasXpress for JavaScript attempts to deal with the associated object there is one available and thus avoids the crash. Non-React environments don't have this issue, so in many cases, such as Jupyter Notebooks, using an assigned ID for each chart makes a lot of sense.

Cheers,
@docinfosci

@neuhausi
Copy link
Owner

neuhausi commented Mar 7, 2024

Funny about the React philosophy. Why would you want to reuse/fix an existing/old object if I can buy a brand new one. (Pretty much the American mentality :-) :-) :-)

@docinfosci
Copy link
Collaborator

So true! It's maddening. I've been considering whether chart rendering for a Dash context should force anonymity, or whether a warning should be printed in the logs. For now, education seems the better approach as it avoids other issues like, for example, people not understanding why custom JavaScript can't find their object by ID.

@glempi
Copy link
Author

glempi commented Mar 8, 2024

Thanks! I am confirming that I've seen this and will investigate.

@glempi -- try setting render_to = "" (empty string). This forces CanvasXpress for Python to generate anonymous IDs when passing generated configurations or JavaScript to the Web browser for use by CanvasXpress for JavaScript.

Why?

Dash uses React for its JavaScript, and React requires that UI updates destroy and recreate UI JavaScript objects when updates occur instead of reusing existing objects. But, in this case, an HTML canvas element is also generated using whatever ID is provided. CanvasXpress for JavaScript pays attention to the canvas element ID. There's a moment of opportunity in which CanvasXpress for JavaScript thinks there is still a chart object named the same ID as the canvas element when in fact the DOM/React has disposed of the old object and a new one has yet to be created to take its place—in which case running code can crash. By using anonymous IDs a new ID is assigned to the canvas element with each refresh, so when CanvasXpress for JavaScript attempts to deal with the associated object there is one available and thus avoids the crash. Non-React environments don't have this issue, so in many cases, such as Jupyter Notebooks, using an assigned ID for each chart makes a lot of sense.

Cheers, @docinfosci

Unfortunately render_to="" doesn't help
layout.displacement property still undefined after shifting viewport

Screenshot_20240308_174118

@neuhausi
Copy link
Owner

Is this completed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants