Skip to content

Control ​

Main controller class for managing annotations. It manages rendering and editing of annotations.

Extends ​

Constructors ​

Constructor ​

ts
new Control(ogma, options): Control;

Parameters ​

ogma ​

Ogma

options ​

Partial<ControllerOptions> = {}

Returns ​

Control

Properties ​

prefixed ​

ts
static prefixed: string | boolean;

Methods ​

add() ​

ts
add(annotation): this;

Add an annotation to the controller

Parameters ​

annotation ​

The annotation to add

Annotation | AnnotationCollection

Returns ​

this


addListener() ​

ts
addListener<T>(
   event, 
   fn, 
   context?): this;

Type Parameters ​

T ​

T extends keyof FeatureEvents

Parameters ​

event ​

T

fn ​

(...args) => void

context? ​

any

Returns ​

this

cancelDrawing() ​

ts
cancelDrawing(): Control;

Cancel the current drawing operation

Returns ​

Control

this for chaining


canRedo() ​

ts
canRedo(): boolean;

Check if there are changes to redo

Returns ​

boolean

true if redo is possible


canUndo() ​

ts
canUndo(): boolean;

Check if there are changes to undo

Returns ​

boolean

true if undo is possible


clearHistory() ​

ts
clearHistory(): void;

Clear the undo/redo history

Returns ​

void


destroy() ​

ts
destroy(): void;

Destroy the controller and its elements

Returns ​

void


disableEraseMode() ​

ts
disableEraseMode(): this;

Turn erase mode off. No-op if it isn't active.

Returns ​

this


editFeature() ​

ts
editFeature(id): this;

(Re-)apply id's handler attachment (drag/resize/text-edit) to match isEditable right now, instead of waiting for a deselect/reselect - this is the same call a selection change makes internally. Call it directly after changing whatever external state your isEditable predicate depends on (e.g. a locked flag kept outside the annotation - see the lock-toolbar-item.ts example): closes any open text editor and detaches the handler if id just became non-editable, or attaches it if id is selected and just became editable again.

Parameters ​

id ​

Id

Returns ​

this


emit() ​

ts
emit<T>(event, ...args): boolean;

Calls each of the listeners registered for a given event.

Type Parameters ​

T ​

T extends keyof FeatureEvents

Parameters ​

event ​

T

args ​

...ArgumentMap<FeatureEvents>[Extract<T, keyof FeatureEvents>]

Returns ​

boolean

enableArrowDrawing() ​

ts
enableArrowDrawing(style?): this;

Enable arrow drawing mode - the recommended way to add arrows.

Call this method when the user clicks an "Add Arrow" button. The control will:

  1. Wait for the next mousedown event
  2. Create an arrow at that position with the specified style
  3. Start the interactive drawing process
  4. Clean up automatically when done

This is the recommended API for 99% of use cases. Only use startArrow() if you need to implement custom mouse handling or positioning logic.

Parameters ​

style? ​

Partial<ArrowStyles | undefined>

Arrow style options

Returns ​

this

this for chaining

Example ​

ts
addArrowButton.addEventListener('click', () => {
  control.enableArrowDrawing({ strokeColor: '#3A03CF', strokeWidth: 2 });
});

See ​

startArrow for low-level programmatic control


enableBoxDrawing() ​

ts
enableBoxDrawing(style?): this;

Enable box drawing mode - the recommended way to add boxes.

Call this method when the user clicks an "Add Box" button. The control will:

  1. Wait for the next mousedown event
  2. Create a box at that position with the specified style
  3. Start the interactive drawing process (drag to size)
  4. Clean up automatically when done

This is the recommended API for 99% of use cases. Only use startBox() if you need to implement custom mouse handling or positioning logic.

Parameters ​

style? ​

Partial<BoxStyle | undefined>

Box style options

Returns ​

this

this for chaining

Example ​

ts
addBoxButton.addEventListener('click', () => {
  control.enableBoxDrawing({ background: '#EDE6FF', borderRadius: 8 });
});

See ​

startBox for low-level programmatic control


enableCommentDrawing() ​

ts
enableCommentDrawing(options): this;

Enable comment drawing mode - the recommended way to add comments.

Call this method when the user clicks an "Add Comment" button. The control will:

  1. Wait for the next mousedown event
  2. Create a comment with an arrow pointing to that position
  3. Smart positioning: automatically finds the best placement for the comment box
  4. Start the interactive editing process
  5. Clean up automatically when done

This is the recommended API for 99% of use cases. Only use startComment() if you need to implement custom mouse handling or positioning logic.

Parameters ​

options ​

Drawing options including offsets and styles

arrowStyle? ​

Partial<ArrowProperties>

Style options for the arrow

commentStyle? ​

Partial<CommentProps>

Style options for the comment box

offsetX? ​

number

Manual X offset for comment placement (overrides smart positioning)

offsetY? ​

number

Manual Y offset for comment placement (overrides smart positioning)

Returns ​

this

this for chaining

Example ​

ts
addCommentButton.addEventListener('click', () => {
  control.enableCommentDrawing({
    commentStyle: { color: '#3A03CF', background: '#EDE6FF' },
    arrowStyle: { strokeColor: '#3A03CF', head: 'halo-dot' }
  });
});

See ​

startComment for low-level programmatic control


enableEraseMode() ​

ts
enableEraseMode(): this;

Enable erase mode: every click on an annotation deletes it immediately. Stays armed across multiple clicks until disableEraseMode() is called, or another drawing tool is enabled / cancelDrawing() is called.

Returns ​

this

this for chaining

See ​

disableEraseMode to turn erase mode off


enablePlacement() ​

ts
enablePlacement(annotation): this;

Place a pre-created annotation by moving it with the cursor. The annotation follows the mouse until the user clicks to place it. Press Escape to cancel.

Parameters ​

annotation ​

The text or box annotation to place

Box | Text

Returns ​

this

this for chaining


enablePolygonDrawing() ​

ts
enablePolygonDrawing(style?): this;

Enable polygon drawing mode - the recommended way to add polygons.

Call this method when the user clicks an "Add Polygon" button. The control will:

  1. Wait for the next mousedown event
  2. Create a polygon starting at that position with the specified style
  3. Start the interactive drawing process (click points to draw shape)
  4. Clean up automatically when done

This is the recommended API for 99% of use cases. Only use startPolygon() if you need to implement custom mouse handling or positioning logic.

Parameters ​

style? ​

Partial<PolygonStyle | undefined>

Polygon style options

Returns ​

this

this for chaining

Example ​

ts
addPolygonButton.addEventListener('click', () => {
  control.enablePolygonDrawing({ strokeColor: '#3A03CF', background: 'rgba(58, 3, 207, 0.15)' });
});

See ​

startPolygon for low-level programmatic control


enableStickyNoteDrawing() ​

ts
enableStickyNoteDrawing(style?): this;

Enable sticky note drawing mode - drops a plain, resizable text box (empty content, "Quick note…" ghost placeholder, no connector arrow) like a Miro sticky note, unlike enableCommentDrawing. It's a regular text annotation, so it's placed the same interactive way as enableBoxDrawing/enableTextDrawing: click for a default-size square, or drag to size it - either way it keeps the usual corner/edge drag handles to resize it afterward.

Call this method when the user clicks an "Add sticky note" button. The control will:

  1. Wait for the next mousedown event
  2. Create the note at that position and start the interactive corner-drag, already selected
  3. On release: a plain click (no drag) gets a default square size, a drag gets sized to match instead - either way it drops straight into editing (the placeholder is just ghost text, so typing immediately replaces it)
  4. Clean up automatically when done

Parameters ​

style? ​

Partial<TextStyle | undefined>

Sticky note style options (merged over the sticky note defaults)

Returns ​

this

this for chaining

Example ​

ts
addStickyNoteButton.addEventListener('click', () => {
  control.enableStickyNoteDrawing({ background: '#FFEB99' });
});

See ​

startStickyNote for low-level programmatic control


enableTextDrawing() ​

ts
enableTextDrawing(style?): this;

Enable text drawing mode - the recommended way to add text annotations.

Call this method when the user clicks an "Add Text" button. The control will:

  1. Wait for the next mousedown event
  2. Create a text box at that position with the specified style
  3. Start the interactive drawing/editing process
  4. Clean up automatically when done

This is the recommended API for 99% of use cases. Only use startText() if you need to implement custom mouse handling or positioning logic.

Parameters ​

style? ​

Partial<TextStyle | undefined>

Text style options

Returns ​

this

this for chaining

Example ​

ts
addTextButton.addEventListener('click', () => {
  control.enableTextDrawing({ color: '#3A03CF', fontSize: 24 });
});

See ​

startText for low-level programmatic control


eventNames() ​

ts
eventNames(): keyof FeatureEvents[];

Return an array listing the events for which the emitter has registered listeners.

Returns ​

keyof FeatureEvents[]

getAnnotation() ​

ts
getAnnotation<T>(id): T | undefined;

Get a specific annotation by id

Type Parameters ​

T ​

T = Annotation

Parameters ​

id ​

Id

The id of the annotation to retrieve

Returns ​

T | undefined

The annotation with the given id, or undefined if not found


getAnnotations() ​

ts
getAnnotations(): AnnotationCollection;

Get all annotations in the controller

Returns ​

AnnotationCollection

A FeatureCollection containing all annotations


getOgma() ​

ts
getOgma(): Ogma;

The underlying Ogma instance this controller was created with. Needed by UI built on top of Control's public API (e.g. TextAnnotationToolbar) that must mount its own ogma.layers.addOverlay(...) layer rather than going through a renderer/handler internal to Control.

Returns ​

Ogma


getRotation() ​

ts
getRotation(): number;

Current global annotation-rotation angle (radians) - see TextStyle/Handles' counterRotation. Needed alongside getZoom() by TextAnnotationToolbar to anchor its pill above a (possibly rotated) Text box's world-space bounds.

Returns ​

number


getSelected() ​

ts
getSelected(): Annotation | null;

Get the first selected annotation (for backwards compatibility)

Returns ​

Annotation | null

The currently selected annotation, or null if none selected


getSelectedAnnotations() ​

ts
getSelectedAnnotations(): AnnotationCollection;

Get the currently selected annotations as a collection

Returns ​

AnnotationCollection

A FeatureCollection of selected annotations


getZoom() ​

ts
getZoom(): number;

Current zoom level - needed by TextAnnotationToolbar to convert a fixedSize Text annotation's screen-pixel dimensions back to graph units for its anchor-point math (same conversion Handles does).

Returns ​

number


isAnnotationEditable() ​

ts
isAnnotationEditable(id): boolean;

Can id be dragged/resized/restyled/text-edited/deleted/re-linked right now, per the isEditable option? false for an unknown id.

Parameters ​

id ​

Id

Returns ​

boolean


isAnnotationVisible() ​

ts
isAnnotationVisible(id): boolean;

Is id rendered and hit-testable right now, per the isVisible option? false for an unknown id.

Parameters ​

id ​

Id

Returns ​

boolean


isDrawing() ​

ts
isDrawing(): boolean;

Returns ​

boolean


isEraseModeActive() ​

ts
isEraseModeActive(): boolean;

Whether erase mode is currently active.

Returns ​

boolean


Call Signature ​

ts
link(
   arrowId, 
   targetNode, 
   side): this;

Attach an arrow to a node at the specified side

Parameters ​
arrowId ​

Id

targetNode ​

Node$1

side ​

Side

Returns ​

this

Call Signature ​

ts
link(
   arrowId, 
   target, 
   side): this;

Attach an arrow to an annotation at the specified side

Parameters ​
arrowId ​

Id

target ​

Id

side ​

Side

Returns ​

this


listenerCount() ​

ts
listenerCount(event): number;

Return the number of listeners listening to a given event.

Parameters ​

event ​

keyof FeatureEvents

Returns ​

number

listeners() ​

ts
listeners<T>(event): (...args) => void[];

Return the listeners registered for a given event.

Type Parameters ​

T ​

T extends keyof FeatureEvents

Parameters ​

event ​

T

Returns ​

(...args) => void[]

off() ​

ts
off<T>(
   event, 
   fn?, 
   context?, 
   once?): this;

Type Parameters ​

T ​

T extends keyof FeatureEvents

Parameters ​

event ​

T

fn? ​

(...args) => void

context? ​

any

once? ​

boolean

Returns ​

this

on() ​

ts
on<T>(
   event, 
   fn, 
   context?): this;

Add a listener for a given event.

Type Parameters ​

T ​

T extends keyof FeatureEvents

Parameters ​

event ​

T

fn ​

(...args) => void

context? ​

any

Returns ​

this

once() ​

ts
once<T>(
   event, 
   fn, 
   context?): this;

Add a one-time listener for a given event.

Type Parameters ​

T ​

T extends keyof FeatureEvents

Parameters ​

event ​

T

fn ​

(...args) => void

context? ​

any

Returns ​

this

redo() ​

ts
redo(): boolean;

Redo the last undone change

Returns ​

boolean

true if redo was successful, false if no changes to redo


remove() ​

ts
remove(annotation): this;

Remove an annotation or an array of annotations from the controller

Parameters ​

annotation ​

The annotation(s) to remove

Annotation | AnnotationCollection

Returns ​

this


removeAllListeners() ​

ts
removeAllListeners(event?): this;

Remove all listeners, or those of the specified event.

Parameters ​

event? ​

keyof FeatureEvents

Returns ​

this

removeListener() ​

ts
removeListener<T>(
   event, 
   fn?, 
   context?, 
   once?): this;

Remove the listeners of a given event.

Type Parameters ​

T ​

T extends keyof FeatureEvents

Parameters ​

event ​

T

fn? ​

(...args) => void

context? ​

any

once? ​

boolean

Returns ​

this

select() ​

ts
select(annotations): this;

Select one or more annotations by id

Parameters ​

annotations ​

The id(s) of the annotation(s) to select

Id | Id[]

Returns ​

this

this for chaining


setOptions() ​

ts
setOptions(options): object;

Set the options for the controller

Parameters ​

options ​

Partial<ControllerOptions> = {}

new Options

Returns ​

object

the updated options

authorStyle? ​
ts
optional authorStyle: Partial<AuthorLineStyle>;
detectMargin ​
ts
detectMargin: number;
editButtonIcon ​
ts
editButtonIcon: string;
isEditable() ​
ts
isEditable: (annotation) => boolean;
Parameters ​
annotation ​

Annotation

Returns ​

boolean

isVisible() ​
ts
isVisible: (annotation) => boolean;
Parameters ​
annotation ​

Annotation

Returns ​

boolean

magnetHandleRadius ​
ts
magnetHandleRadius: number;
magnetRadius ​
ts
magnetRadius: number;
maxArrowHeight ​
ts
maxArrowHeight: number;
minArrowHeight ​
ts
minArrowHeight: number;
minReadableFontSize ​
ts
minReadableFontSize: number;
sendButtonIcon ​
ts
sendButtonIcon: string;
showEditButton ​
ts
showEditButton: boolean;
showSendButton ​
ts
showSendButton: boolean;
textPlaceholder ​
ts
textPlaceholder: string;

setScale() ​

ts
setScale(
   id, 
   scale, 
   ox, 
   oy): this;

Scale an annotation by a given factor around an origin point

Parameters ​

id ​

Id

The id of the annotation to scale

scale ​

number

The scale factor

ox ​

number

Origin x coordinate

oy ​

number

Origin y coordinate

Returns ​

this

this for chaining


startArrow() ​

ts
startArrow(
   x, 
   y, 
   arrow?): Control;

Advanced API: Programmatically start drawing an arrow at specific coordinates.

This is a low-level method that gives you full control over the drawing process. You must handle mouse events and optionally create the arrow object yourself.

For most use cases, use enableArrowDrawing() instead - it handles all mouse events and annotation creation automatically.

Use this method only when you need:

  • Custom mouse event handling (e.g., custom cursors, right-click menus)
  • Programmatic placement without user interaction
  • Integration with custom UI frameworks

Parameters ​

x ​

number

X coordinate for the arrow start

y ​

number

Y coordinate for the arrow start

arrow? ​

Arrow

The arrow annotation to add (optional, will be created if not provided)

Returns ​

Control

this for chaining

Example ​

ts
// Custom cursor example
ogma.setOptions({ cursor: { default: 'crosshair' } });
ogma.events.once('mousedown', (evt) => {
  const { x, y } = ogma.view.screenToGraphCoordinates(evt);
  const arrow = createArrow(x, y, x, y, { strokeColor: '#3A03CF' });
  control.startArrow(x, y, arrow);
});

See ​

enableArrowDrawing for the recommended high-level API


startBox() ​

ts
startBox(
   x, 
   y, 
   box?): Control;

Advanced API: Programmatically start drawing a box at specific coordinates.

This is a low-level method that gives you full control over the drawing process. You must handle mouse events and optionally create the box object yourself.

For most use cases, use enableBoxDrawing() instead - it handles all mouse events and annotation creation automatically.

Use this method only when you need:

  • Custom mouse event handling (e.g., custom cursors, right-click menus)
  • Programmatic placement without user interaction
  • Integration with custom UI frameworks

Parameters ​

x ​

number

X coordinate for the box origin

y ​

number

Y coordinate for the box origin

box? ​

Box

The box annotation to add (optional, will be created if not provided)

Returns ​

Control

this for chaining

Example ​

ts
// Custom cursor example
ogma.setOptions({ cursor: { default: 'crosshair' } });
ogma.events.once('mousedown', (evt) => {
  const { x, y } = ogma.view.screenToGraphCoordinates(evt);
  const box = createBox(x, y, 100, 50, { background: '#EDE6FF' });
  control.startBox(x, y, box);
});

See ​

enableBoxDrawing for the recommended high-level API


startComment() ​

ts
startComment(
   x, 
   y, 
   comment, 
   options?): this;

Advanced API: Programmatically start drawing a comment at specific coordinates.

This is a low-level method that gives you full control over the drawing process. You must handle mouse events and create the comment object yourself.

For most use cases, use enableCommentDrawing() instead - it handles all mouse events and annotation creation automatically.

Use this method only when you need:

  • Custom mouse event handling (e.g., custom cursors, right-click menus)
  • Programmatic placement without user interaction
  • Integration with custom UI frameworks

Parameters ​

x ​

number

X coordinate to start drawing

y ​

number

Y coordinate to start drawing

comment ​

Comment

The comment annotation to add

options? ​

Drawing options including offsets and styles

arrowStyle? ​

Partial<ArrowProperties>

commentStyle? ​

Partial<CommentProps>

offsetX? ​

number

offsetY? ​

number

Returns ​

this

this for chaining

Example ​

ts
// Custom cursor example
ogma.setOptions({ cursor: { default: 'crosshair' } });
ogma.events.once('mousedown', (evt) => {
  const { x, y } = ogma.view.screenToGraphCoordinates(evt);
  const comment = createComment(x, y, 'My comment', { color: '#3A03CF' });
  control.startComment(x, y, comment);
});

See ​

enableCommentDrawing for the recommended high-level API


startPolygon() ​

ts
startPolygon(
   x, 
   y, 
   polygon): this;

Advanced API: Programmatically start drawing a polygon at specific coordinates.

This is a low-level method that gives you full control over the drawing process. You must handle mouse events and create the polygon object yourself.

For most use cases, use enablePolygonDrawing() instead - it handles all mouse events and annotation creation automatically.

Use this method only when you need:

  • Custom mouse event handling (e.g., custom cursors, right-click menus)
  • Programmatic placement without user interaction
  • Integration with custom UI frameworks

Parameters ​

x ​

number

X coordinate to start drawing

y ​

number

Y coordinate to start drawing

polygon ​

Polygon

The polygon annotation to add

Returns ​

this

this for chaining

Example ​

ts
// Custom cursor example
ogma.setOptions({ cursor: { default: 'crosshair' } });
ogma.events.once('mousedown', (evt) => {
  const { x, y } = ogma.view.screenToGraphCoordinates(evt);
  const polygon = createPolygon([[[x, y]]], { strokeColor: '#3A03CF' });
  control.startPolygon(x, y, polygon);
});

See ​

enablePolygonDrawing for the recommended high-level API


startStickyNote() ​

ts
startStickyNote(
   x, 
   y, 
   style?): this;

Advanced API: Programmatically start drawing a sticky note at specific coordinates - same interactive corner-drag as startBox. You must handle mouse events yourself (or immediately release/complete it via the same events enableStickyNoteDrawing would).

For most use cases, use enableStickyNoteDrawing() instead.

Parameters ​

x ​

number

X coordinate for the note's top-left corner

y ​

number

Y coordinate for the note's top-left corner

style? ​

Partial<TextStyle | undefined>

Sticky note style options

Returns ​

this

this for chaining

See ​

enableStickyNoteDrawing for the recommended high-level API


startText() ​

ts
startText(
   x, 
   y, 
   text?): Control;

Advanced API: Programmatically start drawing a text annotation at specific coordinates.

This is a low-level method that gives you full control over the drawing process. You must handle mouse events and optionally create the text object yourself.

For most use cases, use enableTextDrawing() instead - it handles all mouse events and annotation creation automatically.

Use this method only when you need:

  • Custom mouse event handling (e.g., custom cursors, right-click menus)
  • Programmatic placement without user interaction
  • Integration with custom UI frameworks

Parameters ​

x ​

number

X coordinate for the text

y ​

number

Y coordinate for the text

text? ​

Text

The text annotation to add (optional, will be created if not provided)

Returns ​

Control

this for chaining

Example ​

ts
// Custom cursor example
ogma.setOptions({ cursor: { default: 'crosshair' } });
ogma.events.once('mousedown', (evt) => {
  const { x, y } = ogma.view.screenToGraphCoordinates(evt);
  const text = createText(x, y, 0, 0, 'Hello', { color: '#3A03CF' });
  control.startText(x, y, text);
});

See ​

enableTextDrawing for the recommended high-level API


toggleComment() ​

ts
toggleComment(id): this;

Toggle a comment between collapsed and expanded mode

Parameters ​

id ​

Id

The id of the comment to toggle

Returns ​

this

this for chaining


undo() ​

ts
undo(): boolean;

Undo the last change

Returns ​

boolean

true if undo was successful, false if no changes to undo


unselect() ​

ts
unselect(annotations?): this;

Unselect one or more annotations, or all if no ids provided

Parameters ​

annotations? ​

The id(s) of the annotation(s) to unselect, or undefined to unselect all

Id | Id[]

Returns ​

this

this for chaining


update() ​

ts
update<A>(annotation): this;

Update an annotation with partial updates

This method allows you to update any properties of an annotation, including geometry, properties, and style. Updates are merged with existing data.

Type Parameters ​

A ​

A extends Annotation

Parameters ​

annotation ​

DeepPartial<A> & object

Partial annotation object with id and properties to update

Returns ​

this

this for chaining

Example ​

ts
// Update arrow geometry
controller.update({
  id: arrowId,
  geometry: {
    type: 'LineString',
    coordinates: [[0, 0], [200, 200]]
  }
});

// Update text content and position
controller.update({
  id: textId,
  geometry: {
    type: 'Point',
    coordinates: [100, 100]
  },
  properties: {
    content: 'Updated text'
  }
});

// Update style only (prefer updateStyle for style-only updates)
controller.update({
  id: boxId,
  properties: {
    style: {
      background: '#ff0000'
    }
  }
});

updateStyle() ​

ts
updateStyle<A>(id, style): this;

Update the style of the annotation with the given id

Type Parameters ​

A ​

A extends Annotation

Parameters ​

id ​

Id

The id of the annotation to update

style ​

A["properties"]["style"]

The new style

Returns ​

this