Good day everyone!
I try to rewrite my original callback that updates graph components through time (and it works just fine) to the client-side callback. I don’t really know JS, so I’ve just tried to write my JS code regarding similar examples. The problem is that after the first initial update - my graph becomes completely cleared and such an error appears:
I suggest, maybe I’ve made some kind of mistakes in my js file, but I don’t really see them… I would be very happy if you can spot where am I wrong!
My original Python callback
@callback(
Output("heatmap", "figure"),
Input("interval-graph-update", "n_intervals"),
State("x_store", "data"),
State("y_store", "data"),
State("z_store", "data"),
State("heatmap", "figure"),
State("y_scatter", "data"),
State("yz_scatter", "data"),
State("x_scatter", "data"),
State("xz_scatter", "data"),
Input("x_click", "data"),
Input("y_click", "data"),
Input("heatmap", "clickData"),
State("line-switches", "on"),
)
def update_graph(
i,
x,
y,
z,
fig,
y_scatter,
yz_scatter,
x_scatter,
xz_scatter,
x_click,
y_click,
click,
line_switch,
):
triggered_id = ctx.triggered_id
if i == 0:
raise PreventUpdate
if x_click is None:
fig["layout"]["shapes"][0].update({"visible": False})
fig["layout"]["shapes"][1].update({"visible": False})
else:
fig["layout"]["shapes"][0].update({"visible": line_switch})
fig["layout"]["shapes"][1].update({"visible": line_switch})
if triggered_id == "interval-graph-update":
fig["data"][0].update({"x": x, "y": y, "z": z})
return fig
elif triggered_id == "heatmap":
fig["data"][1].update({"x": yz_scatter, "y": y_scatter})
fig["data"][2].update({"x": x_scatter, "y": xz_scatter})
fig["layout"]["shapes"][0].update(
{
"x0": x_click,
"x1": x_click,
}
)
fig["layout"]["shapes"][1].update({"y0": y_click, "y1": y_click})
return fig
My JS script in the /assets folder
window.dash_clientside = Object.assign({}, window.dash_clientside, {
clientside: {
refresh_graph: function (
i,
x_click,
y_click,
click,
x,
y,
z,
fig,
y_scatter,
yz_scatter,
x_scatter,
xz_scatter,
line_switch
) {
const triggered_id = dash_clientside.callback_context.triggered.map(
(t) => t.prop_id
);
if (x_click === null) {
fig["layout"]["shapes"][0]["visible"] = false;
fig["layout"]["shapes"][1]["visible"] = false;
} else {
fig["layout"]["shapes"][0]["visible"] = line_switch;
fig["layout"]["shapes"][1]["visible"] = line_switch;
}
if (triggered_id === "interval-graph-update") {
fig["data"][0]["x"] = x;
fig["data"][0]["y"] = y;
fig["data"][0]["z"] = z;
return fig;
} else if (triggered_id === "heatmap") {
fig["data"][1]["x"] = yz_scatter;
fig["data"][1]["y"] = y_scatter;
fig["data"][2]["x"] = x_scatter;
fig["data"][2]["y"] = xz_scatter;
fig["layout"]["shapes"][0]["x0"] = x_click;
fig["layout"]["shapes"][0]["x1"] = x_click;
fig["layout"]["shapes"][1]["y0"] = y_click;
fig["layout"]["shapes"][1]["y1"] = y_click;
return fig;
}
},
},
});
Python implementation of this code
clientside_callback(
ClientsideFunction(namespace="clientside", function_name="refresh_graph"),
Output("heatmap", "figure"),
Input("interval-graph-update", "n_intervals"),
Input("x_click", "data"),
Input("y_click", "data"),
Input("heatmap", "clickData"),
State("x_store", "data"),
State("y_store", "data"),
State("z_store", "data"),
State("heatmap", "figure"),
State("y_scatter", "data"),
State("yz_scatter", "data"),
State("x_scatter", "data"),
State("xz_scatter", "data"),
State("line-switches", "on"),
)