Skip to content

Editing Annotations

  • How to resize a box, change the assigned animal, change category, change side, or delete
  • The three different ways to set side, and which one to use
  • What happens when you commit a label change on an unconfirmed machine annotation
  • The guard rails the editor enforces

Select an annotation by clicking it. The Konva transformer attaches with eight resize anchors at the corners and edges. Drag any anchor to resize.

Two constraints are enforced at the transformer level:

  • Aspect ratio is locked (keepRatio: true)
  • Rotation is disabled (rotateEnabled: false)

Anchors are 7px with 3px of padding around the box. When you finish dragging, the box’s new dimensions are written back to the annotation store via the updateBox mutation, which carries both the new and previous box for undo.

You can also drag the box itself to move it (when canAnnotate is true; when read-only, dragging is disabled).

Click an annotation, then the row’s pencil-icon Edit button. The label-box-panel opens with:

  • Identifier autocomplete — type to search existing animals in the population
  • Category buttons — toggle which body feature this annotation represents
  • A Save action that commits both

When you save with an existing animal selected, the workspace calls updateAnimal(imageKey, id, animal, currentUser). Because the current user is passed in, this single action also sets confirmed: true and records you as the annotatedByUser. So relabelling a machine annotation in one step both reassigns it and confirms it.

If you type an identifier that doesn’t exist, two things happen:

  1. Permission check — the canSuggestNewAnimals flag must be true. Otherwise you get an error toast and the new animal isn’t created.
  2. Identifier validation — if the population has the ProIdVerifier feature active and the verifier config is enabled, the identifier you typed is validated against the population’s rule. Invalid identifiers produce an error toast and the animal isn’t created.

If both checks pass, a new (provisional) animal is created via the animal API, and the annotation is then committed against that new animal.

Categories represent the body feature the box outlines (dorsal-fin, eye-patch, etc., as configured per population). Two ways to change it:

  • From the label-box-panel when you’re relabelling — click the category button before saving.
  • Directly on a selected annotationonPanelCategoryChange updates the existing record by emitting updateMeta(imageKey, id, { category }) and recolours the on-canvas box stroke to match.

A duplicate-category guard prevents two annotations on the same image from having both the same animal and the same category. If you try to create such a duplicate, the change is rejected.

Side is one of Left, Right, or Unknown. There are three places the side can be changed, each with different scope:

WhereScopeWhat it calls
Label-box-panel (relabel flow)Single annotationupdateSide(imageKey, id, side)updateSide mutation
Image Info tab → “lock side” toggleEvery annotation on the current imageupdateSideForAll(imageKey, side)updateSideAll mutation
Image Info tab → per-individual overridesEvery annotation tagged with a given identifier on this imageupdateSideForIdentifier(imageKey, identifier, side)updateSideByIdentifier mutation

Use the per-annotation control when one box was assigned the wrong side. Use lock-side when every animal in the photo was shot from the same angle. Use the per-individual override when one animal in a multi-animal photo needs its side overridden specifically.

Click the row’s warn-coloured trash icon, or select an annotation on the canvas and press Delete / Backspace. The deletion calls removeWithReason(imageKey, id, 'user_deleted') and emits a remove mutation carrying the removed record plus the reason.

Deletes are undoable while the workspace is open — Ctrl/Cmd+Z restores the annotation. Undo history is kept per workspace session.

Every change in the annotator boils down to one of seven mutation kinds the annotation store emits. The persistence service batches and ships them to the server.

Mutation kindTriggered by
addCreating a new annotation (manual draw, see Manual Annotations)
updateBoxResize complete on an existing annotation
updateMetaConfirm; relabel; category change; arbitrary metadata update
updateSidePer-annotation side change
updateSideAllImage-wide side lock
updateSideByIdentifierPer-individual side override
removeDelete (carries the previous record and a reason)

Server-side translation of these mutations into evidence-tier promotion or revision records is not documented here — see the Evidence Tiers and ML Center metrics pages for the conceptual model.