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

Window resize using dash_breakpoints #117

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions assets/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,3 @@ function changeFilters(js_path, brightness, contrast) {



window.dash_clientside = Object.assign({}, window.dash_clientside, {
clientside: {
get_container_size: function(url) {
let W = window.innerWidth;
let H = window.innerHeight;
if(W == 0 || H == 0){
return dash_clientside.no_update
}
return {'W': W, 'H':H}
},
}
});
72 changes: 17 additions & 55 deletions callbacks/image_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,7 @@
downscale_view,
get_view_finder_max_min,
resize_canvas,
)

clientside_callback(
ClientsideFunction(namespace="clientside", function_name="get_container_size"),
Output("screen-size", "data"),
Input("url", "href"),
resize_canvas_with_zoom,
)


Expand All @@ -41,21 +36,25 @@
Output("image-viewer-loading", "zIndex", allow_duplicate=True),
Output("image-metadata", "data"),
Input("image-selection-slider", "value"),
Input("window-resize", "width"),
Input("window-resize", "height"),
Input("reset-view", "n_clicks"),
State({"type": "annotation-class-store", "index": ALL}, "data"),
State("project-name-src", "value"),
State("annotation-store", "data"),
State("image-metadata", "data"),
State("screen-size", "data"),
State("current-class-selection", "data"),
prevent_initial_call=True,
)
def render_image(
image_idx,
screen_width,
screen_height,
reset_view,
all_annotation_class_store,
project_name,
annotation_store,
image_metadata,
screen_size,
current_color,
):
if image_idx:
Expand Down Expand Up @@ -86,24 +85,22 @@ def render_image(

fig["layout"]["shapes"] = all_annotations
view = annotation_store["view"]

if screen_size:
if view:
image_center_coor = annotation_store["image_center_coor"]
patched_annotation_store = Patch()
if screen_width and screen_height:
if view and ctx.triggered_id != "reset-view":
# we have a zoom + window size to take into account
if "xaxis_range_0" in view:
fig.update_layout(
xaxis=dict(range=[view["xaxis_range_0"], view["xaxis_range_1"]]),
yaxis=dict(range=[view["yaxis_range_0"], view["yaxis_range_1"]]),
fig, view = resize_canvas_with_zoom(
view, screen_height, screen_width, fig
)
else:
# no zoom level to take into account, window size only
fig, image_center_coor = resize_canvas(
tf.shape[0], tf.shape[1], screen_size["H"], screen_size["W"], fig
# no zoom level to take into account, window size only, also used for reset view case
fig = resize_canvas(
tf.shape[0], tf.shape[1], screen_height, screen_width, fig
)
patched_annotation_store["view"] = {}
view = {}

patched_annotation_store = Patch()
patched_annotation_store["image_center_coor"] = image_center_coor
patched_annotation_store["active_img_shape"] = list(tf.shape)
fig_loading_overlay = -1

Expand Down Expand Up @@ -387,38 +384,3 @@ def update_selection_and_image(
disable_next_image,
f"Slice {new_slider_value}",
)


@callback(
Output("image-viewer", "figure", allow_duplicate=True),
Output("image-viewer", "relayoutData"),
Input("reset-view", "n_clicks"),
State("annotation-store", "data"),
prevent_initial_call=True,
)
def reset_figure_view(n_clicks, annotation_store):
"""
This callback will reset the view of the image to the center of the screen (no zoom, no pan).
RelayoutData is updated too, which then triggers callback that updates viewfinder box
"""
image_center_coor = annotation_store["image_center_coor"]
if image_center_coor is None:
raise PreventUpdate

new_figure = Patch()
new_figure["layout"]["yaxis"]["range"] = [
image_center_coor["y1"],
image_center_coor["y0"],
]
new_figure["layout"]["xaxis"]["range"] = [
image_center_coor["x0"],
image_center_coor["x1"],
]

relayout_data = {
"xaxis.range[0]": image_center_coor["x0"],
"yaxis.range[0]": image_center_coor["y0"],
"xaxis.range[1]": image_center_coor["x1"],
"yaxis.range[1]": image_center_coor["y1"],
}
return new_figure, relayout_data
5 changes: 4 additions & 1 deletion components/control_bar.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import dash_bootstrap_components as dbc
import dash_mantine_components as dmc
from dash import dcc, html
from dash_breakpoints import WindowBreakpoints
from dash_extensions import EventListener
from dash_iconify import DashIconify

Expand Down Expand Up @@ -683,7 +684,6 @@ def drawer_section(children):
"visible": True,
"view": {},
"active_img_shape": [],
"image_center_coor": {},
},
),
create_reset_view_affix(),
Expand All @@ -702,6 +702,9 @@ def drawer_section(children):
],
id="keybind-event-listener",
),
WindowBreakpoints(
id="window-resize",
),
]
)

Expand Down
1 change: 0 additions & 1 deletion components/image_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ def layout():
style=COMPONENT_STYLE,
children=[
dcc.Store("image-metadata", data={"name": None}),
dcc.Store("screen-size"),
dcc.Location("url"),
dmc.LoadingOverlay(
id="image-viewer-loading",
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ svgpathtools
matplotlib
scipy
dash-extensions==1.0.1
dash-bootstrap-components==1.5.0
dash-bootstrap-components==1.5.0
dash-breakpoints==0.1.0
20 changes: 16 additions & 4 deletions utils/plot_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,20 @@ def resize_canvas(h, w, H, W, figure):
y1 = h
y0 = 0

figure.update_yaxes(range=[y1, y0])
figure.update_xaxes(range=[x0, x1])
figure.update_layout(
xaxis=dict(range=[x0, x1]),
yaxis=dict(range=[y1, y0]),
)

return figure


image_center_coor = {"y1": y1, "y0": y0, "x0": x0, "x1": x1}
return figure, image_center_coor
def resize_canvas_with_zoom(view, H, W, fig):
x0 = view["xaxis_range_0"]
y0 = view["yaxis_range_0"]
x1 = view["xaxis_range_1"]
y1 = view["yaxis_range_1"]
y1 = y0 - H / W * (x1 - x0)
fig.update_layout(xaxis=dict(range=[x0, x1]), yaxis=dict(range=[y0, y1]))
view["yaxis_range_1"] = y1
return fig, view
Loading