Skip to content

Canvas reference

pak edited this page Aug 15, 2026 · 4 revisions

Canvas reference

The page to keep open while you work: every key, what the panels do, how selection behaves, which handle starts which kind of link, and what undo actually covers.

The application ships a shortcut sheet under the ? key, rendered from the table in frontend/src/shortcuts.ts. That file only describes: the listeners live in the components that watch the keyboard, and nothing derives them from the table. The sheet and the table can never disagree with each other, but neither is tied to the handlers. This page carries more than the sheet: the keys the sheet leaves out (? itself, the canvas search bar, the dialog Esc), the scope of each key, the cases where a key deliberately does nothing, and the reasoning behind the layout.

What STIX objects and relationships mean is not here. That lives in the in-app guide: https://app.drawmeastix.io/guide

Keyboard shortcuts

The listeners test ctrlKey || metaKey, so on macOS Cmd works everywhere Ctrl is written below. Only the display changes.

Everywhere on the canvas

Keys What it does
Ctrl K Open or close the command palette
Ctrl Z Undo the last deletion
Ctrl B Fold or unfold the left panel

Ctrl+K toggles: pressing it again on an open palette closes it.

Ctrl+B folds whichever left panel is showing. If ATT&CK or Scenarios was open, the first press folds it and the second opens Objects, because the unfold target is always Objects.

Canvas, when the caret is not in a text field

Keys What it does
/ Open the canvas search bar
? Open or close the shortcut sheet
Del Delete the selection
Ctrl click or Shift click Add an object to the selection
drag Start a relationship from an object's bottom handle onto another object
Ctrl V Paste a screenshot from the clipboard as a capture pinned on the canvas

Del only. Backspace is not bound (deleteKeyCode={['Delete']}), which is deliberate on a canvas that sits one tab away from text entry.

Both Ctrl+click and Shift+click are wired for multi-selection because some window managers swallow Ctrl+click before the page ever sees it (this was seen under Hyprland). Shift+click always gets through.

? is matched on the character produced, not on a physical key code, so it works the same on AZERTY and QWERTY.

Canvas search, once the bar is open

Keys What it does
Enter Jump to the next hit and centre on it
Shift Enter Jump to the previous hit
Esc Close the search and clear it

The search matches an entity's name, its type label, its labels, its aliases, and the content of pinned notes. Matching objects keep their colour, the rest are dimmed. The counter reads 3 / 12, current position over total, because on a dense graph how many are left matters as much as how many there are.

Triage tray

The tray sits at the bottom of the canvas and takes these keys only when it holds focus. Click it once to give it focus.

Keys What it does
j or Next candidate
k or Previous candidate
y or Enter Accept: the object goes on the canvas
n or Del Reject: the object is dropped

The keys are bound to the panel and not to the window on purpose: an n listened for globally would reject a candidate while you were working on the canvas.

The cursor does not move when you accept or reject. The next candidate slides into its place, so you can hold y down to clear a batch. Full walkthrough: Triage-walkthrough.

Command palette, once it is open

Keys What it does
Move through the list (it wraps at both ends)
Enter Run the highlighted line
Esc Step back one stage, then close

In relate mode Esc drops the target stage, then the source, then closes. Picking the wrong source should not force you to start over from a closed palette.

Dialogs

Every dialog closes on Esc and gives focus back to whatever opened it. Two dialogs can be stacked, because the command palette is not one of them: Ctrl+K still fires over an open dialog, and the action you run from it opens a second box on top. One Esc closes only the topmost.

When a shortcut deliberately does nothing

This is the part a cheat sheet cannot carry, and the part that looks like a bug when you do not know it.

Situation Ctrl K Ctrl B Ctrl Z / and ?
Caret in an input, textarea or contenteditable fires fires ignored ignored
A dialog is open fires fires fires unless the caret is in a field ignored

Ctrl+Z stands down inside a field so that it stays the browser's own undo of typing. Undoing a deletion while fixing a typo is not what anyone means.

/ and ? stand down under a dialog because they used to fire anyway: search opened behind an opaque backdrop, and the cheat sheet landed on top of a half-filled form.

Ctrl+K is the exception that is meant to be one. It is the only route back to the index of everything, so it stays reachable wherever the caret is.

The command palette

Ctrl+K opens a single index over the canvas objects, object creation, ATT&CK, scenarios, relationships and actions. Before it existed, every capability lived behind its own panel, so you had to know where to look before you could look.

The filter is a subsequence match: crx finds Corax, expc2 finds Exfiltration Over C2 Channel. It indexes names and identifiers only, never prose. When scenario descriptions were indexed, corax surfaced four unrelated scenarios, because in a long text almost any short sequence appears in order.

Groups, in order:

Group Holds Cap
On this canvas Every object on the canvas, jump and select 6
Create One line per SDO then SCO type 6
ATT&CK Techniques and the rest of the dataset, from 2 characters typed 6
Scenarios The built-in scenario templates 6
Relationships A single entry, reading Relate two objects… until something is selected 6
Actions The list below 6

Six per group is a readability cap, not a completeness one: type more to narrow.

The ATT&CK dataset is several hundred entries and is fetched on the first open of the palette, never at startup. The palette must open instantly, offline included, even if that means having no techniques yet in that first second. If the fetch fails, the palette works without them and says nothing.

Relating from the keyboard

Pick that entry and the palette turns into a two-step picker: source, then target. Whatever is already selected on the canvas is used as the source, one object or ten, so the common case saves a step.

At the target step, the palette lists only objects that can really be linked, in either direction, plus those reachable through a canonical bridge (single source only). Offering an impossible target helps no one: you pick it, and you get a refusal. When the list comes back empty with no search typed, it says so plainly: no object on this canvas can be linked to that selection, in either direction.

Once source and target are picked, the verb dialog opens, exactly as it does for a mouse drag. The matrix and the bridge fallback live in one place, so keyboard and mouse never validate different things.

Actions

Action Hint shown
Export STIX bundle… export
Export image / PDF / Markdown… share
Paste IOCs… import
Re-layout the graph canvas
Toggle the objects panel Ctrl B
Toggle the inspector panel
Undo the last deletion Ctrl Z
Search the canvas /
Keyboard shortcuts ?
STIX guide: what links to what help
Your data: what stays here, what leaves help
Enrichment endpoints… settings
Back to investigations navigate

The two help entries are the ones that open a new tab: the STIX guide on the #/guide route, and https://app.drawmeastix.io/about. Enrichment endpoints… opens a dialog in place, and Back to investigations takes you to the investigation list. Endpoint configuration is covered by Enrichment-sidecar, export by Exporting.

What a name field suggests

The name field of an object offers what it can from two characters typed, from three corpora that never overlap. Nothing is ever filled in for you: a suggestion is picked or ignored.

Object being named What is offered Where it comes from
Intrusion set, threat actor ATT&CK groups, then about 850 more adversary names ATT&CK Enterprise, plus the MISP threat-actor galaxy
Malware, tool, technique The matching ATT&CK entries ATT&CK Enterprise
Location The ISO 3166-1 countries, by name or by code the iso-codes standard
Everything else Nothing, it is a plain field

The right-hand column of the list names the source: a MITRE identifier (G0016, T1566) for an ATT&CK entry, misp for a name MITRE does not carry, the two-letter code for a country. That is not decoration. Picking an ATT&CK entry writes a mitre-attack external reference into the exported bundle; picking a misp one writes none, because there is no MITRE number to point at and inventing one would be a lie in somebody else's platform.

Why countries are worth a list of their own. A location identifier is computed from its name, so FR, France and French Republic are three different objects that will never merge, here or in the platform that reads the bundle. Type FR, pick France, and the country code and the type are filled in with it.

Why the actor list stops where it does. MITRE and the MISP galaxy disagree about where an actor ends: MITRE folds UNC2452 into APT29, the galaxy keeps it separate. Offering both would hand you two canonical names for one adversary. So every galaxy actor whose name ATT&CK already resolves is dropped when the dataset is built, and ATT&CK wins. Typing Midnight Blizzard offers you APT29, as it should.

The corpora are fetched on demand, never at startup, and a fetch that fails leaves the field working as a plain text input without saying anything.

Scenario forms

A scenario slot holds as many values as your case has. The + next to a field label adds a line, Enter in a line does the same, and each line becomes its own object: three tools give three uses, two C2 addresses give two communicates-with. Typing the same name twice in one slot creates it once, since both would carry the same identifier.

The line under the form is always there, in one of three states. It tells you what will come out unlinked, and which empty slot would connect it if you filled it in. It also tells you when a relationship was not drawn: when both ends of one hold several values, two domains and three addresses do not say which resolves to which, and the six links of every combination would be five false statements and one true one. Draw that pairing yourself on the canvas.

Panels and folding

Element Width How it opens and closes
Rail 44 px Always visible
Left panel: Objects, ATT&CK, Scenarios 180 px One at a time. Click a rail icon to switch, click the active icon to fold. Ctrl+B folds and unfolds
Right column: Inspector and Narrative tabs 300 px The topbar panel icon, the chevron in the tab bar, or the palette action
Minimap 200 px Rendered only while the window is at least 1200 px wide
Triage tray bottom strip Rail tray button, or the tray header. Hidden entirely when there are no candidates

The rail's tray button carries the candidate count as a badge and is disabled at zero, so the curation step announces itself instead of existing only once it is full.

Why the thresholds are what they are

The canvas is the product, and it had ended up at 39 % of the screen on a 1280 px laptop. The thresholds are not arbitrary steps, they follow from one rule: chrome must not exceed 40 % of the window. The constants derive from it, so they track any width change.

Constant Value Meaning
RIGHT_BREAKPOINT 1310 px Below this, the right column starts collapsed
LEFT_BREAKPOINT 560 px Below this, the left panel starts collapsed too
MINIMAP_BREAKPOINT 1200 px Below this, no minimap

One consequence worth knowing, because it looks like the left rule is broken: 560 px is also the width at and under which the application shows its small-screen card instead of the canvas. So unless you took the "Open it anyway" door described below, the left panel starts open on every window you can reach the canvas from, and only the right column folds by itself. It folds on a 1280 px laptop. Behind the opt-in the left rule does apply: under 560 px the left panel starts collapsed.

The minimap is dropped below 1200 px for the reason it exists: at 200 px wide, on an already narrow canvas, it eats the very space it is meant to help you travel.

Your choice wins

Whatever you fold or unfold is written to localStorage under dmas.panels and beats the width rule from then on, permanently. Without that memory the interface would undo on every reload what you had just set, which is the worst failing an adaptive layout can have: feeling like it is fighting you.

If storage is unavailable (private browsing, quota), the width decides and your choice holds for the session only.

One exception the layout makes on its own: selecting anything reopens the right column and switches it to the Inspector tab. That is what makes the automatic folding bearable. On a narrow screen you navigate with the whole canvas, and the panel comes back exactly when you ask to see a record. It switches tab too, because selecting an object is asking to see that object, not to re-read the narrative.

Selection

Gesture Result
Click an object It becomes the single selection, the Inspector shows its record
Ctrl+click or Shift+click another Both are selected
Click a relationship The Inspector shows the verb, the description and the activity window, with a delete button
Click a dashed annotation link The Inspector shows an Unlink panel
Click a pinned note card The Inspector shows the note in full

With more than one entity selected, the Inspector is replaced by the bulk editor, which applies one patch to the whole batch. Non-entity nodes (pinned notes, captures) are filtered out of that batch: only entities go into it.

Multi-selection is also the input to Relate the N selected objects to… in the palette, and to Del.

A caveat that bites in a second tab: if another tab writes to the same data, a banner appears saying what you see may be out of date. A bulk edit made after that would write back properties read before the change. The banner offers a Reload. Nothing merges automatically, and that is a decision, not an omission: the product is single-user.

The handles on a node, and what each one starts

An entity node carries four handles. Two of them build STIX, two of them build annotation, and nothing crosses over.

Handle Position What a drag from it starts Ends up in the bundle
Target Top edge Nothing. It receives a relationship yes
Source Bottom edge A STIX relationship. The verb dialog opens yes
Annotation Right edge An annotation link, and only to a capture no

STIX flows top to bottom, the same axis the Re-layout button arranges the graph along, so an edge that points upwards on the canvas is telling you something.

The annotation handle is a pair of overlapping handles, one in each direction, so a capture can be linked from either end. onConnect drops any STIX relationship that would start from there, which is why you cannot accidentally create a relationship by aiming at the wrong edge.

Capture nodes (a screenshot pasted with Ctrl+V) carry their pair of annotation handles on their left edge. Drag from there onto an entity, or from an entity's right handle onto the capture. Double-click a capture to open it full screen.

Pinned note cards carry a handle on the left too, but it is not connectable. A note's dashed link follows the entity the note belongs to; it is not something you draw, and it cannot be deleted on its own.

The two kinds of edge are drawn so they cannot be confused: a STIX relationship is a solid line with an arrowhead and a verb label, an annotation link is dashed, unarrowed, and labelled annotation at most. Annotation links never reach the bundle, see Exporting.

Which way the relationship goes

The direction of your drag is not the direction of the relationship. The matrix decides.

  1. It tries your direction: are there verbs valid from the source type to the target type?
  2. If not, it tries the reverse.
  3. If neither works and you dragged a single object, it looks for a canonical bridge and offers the intermediate object instead of failing.
  4. If nothing holds, it says so: no valid STIX relationship between these two types, in either direction.

This exists so you can think "link these IPs to this infrastructure" without knowing that an observable is never the source of a relationship towards an SDO, and that the correct reading is infrastructure consists-of ip.

For a batch, only the verbs valid for every type in the selection are offered. A mixed batch with no verb in common will tell you so rather than create half the links.

Deleting

Del on the selection, the small button at a node's top right, or the delete button in the Inspector: all three take exactly the same path, so cleanup and undo behave identically whichever you use.

That top-right button is understated at rest and shows itself when the node is hovered, when it is selected, and when it takes keyboard focus. The last case is not cosmetic: at opacity 0 it was still in the tab order, so keyboard navigation could delete an entity with nothing on screen announcing it.

What each one removes:

Node kind What Del does
Entity Deletes the entity, its relationships and its notes
Capture Deletes the capture
Pinned note Unpins it from the canvas. The note itself stays in the notes panel; deleting it for real is done from there

The note card's button is a minus and not a cross for that reason: it takes the card off the canvas, it does not destroy the note.

Undo

Ctrl+Z undoes deletions, and nothing else. That is a decision: a typo in a name gets retyped, but three quarters of an hour of linking does not come back on its own. Property edits, renames and creations are not on the stack.

Property Value
Depth 25 entries, oldest dropped
Coalescing window 400 ms
Restores Entities (with their properties), relationships, deleted notes
Fallback With an empty stack, Ctrl+Z restores the positions from before the last Re-layout
Empty Says "Nothing to undo."

The coalescing window is the detail that makes it usable. Deleting a node makes its edges vanish, and the canvas library reports the edges and the node as two separate events. Without coalescing, one gesture would need two Ctrl+Z, and the first would leave a node stripped of every relationship, which is worse than no undo at all. Everything pushed within 400 ms of the previous entry is undone as one block.

Order matters on restore: entities come back first, then relationships, then notes. A relationship whose endpoint is gone cannot be restored, and you get told how many were dropped rather than a silent partial result.

The entry is only popped once the restores have gone through, so a failure leaves you able to retry. Restores write back on the original identifier, so pressing Ctrl+Z twice during a slow restore breaks nothing.

Re-layout has its own Undo button next to the Re-layout button, and it appears only when there is a layout to go back to. Ctrl+Z falls back to it when the deletion stack is empty, because a Ctrl+Z that does nothing while an Undo button sits on screen is not defensible.

Small screens

At 560 px wide and under, or on a coarse pointer at 820 px and under, the application shows a presentation card rather than the canvas. There is an "Open it anyway" button, and taking it is remembered under dmas.smallscreen, so a tablet with a keyboard is not asked twice.

The canvas genuinely needs a mouse and a keyboard: relating is a drag, and multi-selection is a modifier click.

See also

Clone this wiki locally