Example of changing the annotator state
Example of changing the annotator state |
---|
Check the following link to review the demo of changing the states.
This demo provides the following features:
- A basic
DashPictureAnnotation
allowing- Creating, modify, or removing annotation boxes by dragging and dropping.
- Modify the annotation label by an input box.
- Every time the annotation data is changed, the changed results will be reflected by the text below the annotator window.
- Three controlling buttons:
- Toggle disabled: Toggle the
disabled
property. When this property is enabled, the annotator is not usable. - Toggle image: Toggle the currently displayed image.
- Reset data: Reset the annotation data to the initial state.
- Toggle disabled: Toggle the
Define the layout
Compared to the minimal demo, there are three additional buttons.
(
dpa.DashPictureAnnotation(...),
html.Div(
html.Button(
children="Toggle disabled", id="btn-disabled", style=styles["mr1"]
),
html.Button(
children="Toggle image", id="btn-image", style=styles["mr1"]
),
html.Button(children="Reset data", id="btn-data"),
),
)
By clicking different buttons, the different callbacks will be triggered for changing the annotator states.
Define the callbacks
The first button toggles the state of the disabled
property. It just read and flip
the current disabled
property.
@app.callback(
Output("annotator", "disabled"),
Input("btn-disabled", "n_clicks"),
State("annotator", "disabled"),
prevent_initial_call=True,
)
def toggle_disabled(n_clicks: Optional[int], is_disabled: Optional[bool]):
if n_clicks:
return not bool(is_disabled)
return dash.no_update
The second callback read and roll the current image. It read the current image address, get the name of the image from the address, and use the image name to query the next image address that should be displayed.
@app.callback(
Output("annotator", "image"),
Input("btn-image", "n_clicks"),
State("annotator", "image"),
prevent_initial_call=False,
)
def toggle_image(n_clicks: Optional[int], prev_image: Optional[str]) -> str:
if n_clicks:
if isinstance(prev_image, str):
try:
idx = image_list.index(os.path.split(prev_image)[-1])
except ValueError:
return "/assets/test_image.svg"
next_idx = (idx + 1) % len(image_list)
return "/assets/{0}".format(image_list[next_idx])
return "/assets/test_image.svg"
The third callback reset the current annotation data to the initial value.
@app.callback(
Output("annotator", "data"),
Input("btn-data", "n_clicks"),
prevent_initial_call=False,
)
def reset_data(n_clicks: Optional[int]):
if n_clicks:
return default_data
return dash.no_update