Click and Hover Callbacks

It’s possible to create callbacks based on user clicks and hovering. First, you need to specify the pickingModes prop in
vtk_view to be a list of modes you want to capture. The following values are accepted: * "click" * "hover"

Afterwards, you need to create callbacks where the inputs and states include one of the following read-only properties of vtk_view. * clickInfo: Called when the user clicks on an object. * hoverInfo: Called when the user hovers over an object.

The full documentation for vtk_view can be found in the API reference.

Callback structure

You can notice that the clickInfo or hoverInfo data will be a dictionary with various keys describing the picked object. The keys include: * displayPosition: The x,y,z coordinate with on the user’s screen. * ray: A line between two points in 3D space (xyz1, xyz2) that represent the mouse position. It covers the full space under the 2D mouse position. * representationId: The ID assigned to the vtk_geometryrepresentation containing your object. * worldPosition: The x, y, z coordinates in the 3D environment that you are rendering where the ray hit the object. It corresponds to the 3D coordinate on the surface of the object under your mouse.

Output clickInfo to html_pre

The following example shows you how to concisely display the output of clickInfo inside an html_pre:

View full code

using JSON3, DashVtk, DashHtmlComponents, Dash

filepath = download("https://github.com/plotly/dash-vtk/blob/master/demos/data/cow-nonormals.obj");
txt_content = read(filepath, String);

view = vtk_view(
    id="click-info-view",
    pickingModes=["click"],
    children=[
        vtk_geometryrepresentation(id="cow-geometry", children=[
            vtk_reader(
                vtkClass="vtkOBJReader",
                parseAsText=txt_content,
            ),
        ]),
    ],
);

# Dash setup
app = dash()

app.layout = html_div([
    html_div(view, style=Dict("width" => "100%", "height" => "300px")),
    html_b("Output of clickInfo (try clicking on the object above):"),
    html_pre(
        id="click-info-output",
        style=Dict("overflowX" => "scroll")
    )
]);

# Dash setup
app = dash()

callback!(
    app,
    Output("click-info-output", "children"),
    Input("click-info-view", "clickInfo")
) do click_info
    return JSON3(click_info, indent=2)
end

run_server(app, "0.0.0.0", debug = true)
Output of clickInfo (try clicking on the object above):

Update representation state with hoverInfo

You can also construct more complex hover callbacks, which would affect the actor and state of your geometry representations.
In the terrain mesh demo, whenever you hover
over the surface, a callback is fired and the output is displayed on your screen:

terrain-following-mesh-hover

The full code can be found here, but the
following snippet summarizes what is needed to capture hover events in the image above:

# ...

vtk_view = vtk_view(
    id="vtk-view",
    pickingModes=["hover"],
    children=[
        vtk_geometryrepresentation(id="vtk-representation", ...),
        vtk_geometryrepresentation(
            id="pick-rep",
            children=[
                dash_vtk.Algorithm(id="pick-sphere", ...)
            ],
            # ...
        ),
    ],
)

app.layout = html_div([
  # ...,
  vtk_view,
  # ...
])

callback!(
    app,
    Output("tooltip", "children"),
    Output("pick-sphere", "state"),
    Output("pick-rep", "actor"),
    Input("vtk-view", "clickInfo"), Input("vtk-view", "hoverInfo"),
) do (clickData, hoverData)
    info = hoverData ? hoverData : clickData
    if info
        if (
            "representationId" in info &&
                info["representationId"] == "vtk-representation"
        )
            return (
                [JSON3.write(info, indent=2)],
                Dict("center" => info["worldPosition"]),
                Dict("visibility" => true),
            )
        end
        return no_update, no_update, no_update
    end
    return [""], Dict(), Dict("visibility" => false)
end

You can also use hoverInfo to update the state of another geometry representation. The image below shows how to update a cone position, orientation and size in order to probe the race car object:

terrain-following-mesh-hover

Learn more by reading the Python source code or trying out the Vehicle Geometry app