logo

X6

  • Tutorials
  • API
  • Examples
  • Q&A
  • Change Log
  • XFlow
  • Productsantv logo arrow
  • 2.x
  • Introduction
  • Quickstart
  • Basic
    • Graph
    • Nodes
    • Edges
    • Connection Pile
    • Interaction
    • Events
    • Data Serialization
  • Intermediate
    • Connection Points
    • Tools
    • Group
    • React Nodes
    • Vue Nodes
    • Angular Nodes
    • HTML Nodes
  • Plugin
    • Graphic Transformations
    • Snapline
    • Clipboard
    • Keyboard
    • History
    • Selection Box
    • Scroller
    • Dnd
    • Mini Map
    • Stencil
    • Export
  • Upgrade to Version 2.x
  • Developer Tools

History

Previous
Keyboard
Next
Selection Box

Resource

Ant Design
Galacea Effects
Umi-React Application Framework
Dumi-Component doc generator
ahooks-React Hooks Library

Community

Ant Financial Experience Tech
seeconfSEE Conf-Experience Tech Conference

Help

GitHub
StackOverflow

more productsMore Productions

Ant DesignAnt Design-Enterprise UI design language
yuqueYuque-Knowledge creation and Sharing tool
EggEgg-Enterprise-class Node development framework
kitchenKitchen-Sketch Tool set
GalaceanGalacean-Interactive solution
xtechLiven Experience technology
© Copyright 2025 Ant Group Co., Ltd..备案号:京ICP备15032932号-38

Loading...

This chapter mainly introduces knowledge related to undo and redo. By reading, you can learn about

  • How to implement undo and redo for element operations

Usage

We provide a standalone plugin package @antv/x6-plugin-history to use the undo and redo functionality.

# npm
$ npm install @antv/x6-plugin-history --save
# yarn
$ yarn add @antv/x6-plugin-history

Then we use it in the code like this:

import { History } from '@antv/x6-plugin-history'
const graph = new Graph({
background: {
color: '#F2F7FA',
},
})
graph.use(
new History({
enabled: true,
}),
)

Demo

  • After moving a node freely, the Undo button becomes available.
  • Clicking the Undo button restores the node's position, and then the Redo button becomes available.
  • Clicking the Redo button updates the node's position.

Configuration

Property NameTypeDefault ValueRequiredDescription
stackSizenumber0A stackSize of 0 means there is no limit on the length of the history stack; setting it to another number means it will only record that many history entries.
ignoreAddbooleanfalseIf ignoreAdd is true, adding elements will not be recorded in the history.
ignoreRemovebooleanfalseIf ignoreRemove is true, removing elements will not be recorded in the history.
ignoreChangebooleanfalseIf ignoreChange is true, changes to element properties will not be recorded in the history.
beforeAddCommand(event, args) => any-Called before a command is added to the Undo queue; if this method returns false, the command will not be added to the Undo queue.
afterAddCommand(event, args, cmd) => any-Called after a command is added to the Undo queue.
executeCommand(cmd, revert, options) => any-Called when a command is undone or redone; revert is true if the command is undone, otherwise it indicates the command is redone.

Tip

In actual projects, we often need to undo or redo multiple changes at once. X6 provides the concept of batch, which allows multiple changes to be merged into a single history entry. Here’s how to use it:

// Method 1
graph.startBatch('custom-batch-name')
// Changing the border color of the node and modifying its position will be merged into a single record, allowing for a single undo.
node.attr('body/stroke', 'red')
node.position(30, 30)
graph.stopBatch('custom-batch-name')
// Method 2
graph.batchUpdate(() => {
node.prop('zIndex', 10)
node.attr('label/text', 'hello')
node.attr('label/fill', '#ff0000')
})

API

graph.undo(...)

undo(options?: KeyValue): this

Undo. options will be passed to the event callback.

graph.undoAndCancel(...)

undoAndCancel(options?: KeyValue): this

Undo and do not add to the redo queue, so this undone command cannot be redone. options will be passed to the event callback.

graph.redo(...)

redo(options?: KeyValue): this

Redo. options will be passed to the event callback.

graph.canUndo()

canUndo(): boolean

Check if it can be undone.

graph.canRedo()

canRedo(): boolean

Check if it can be redone.

graph.cleanHistory(...)

cleanHistory(options?: KeyValue): this

Clear the history queue. options will be passed to the event callback.

graph.getHistoryStackSize(...)

getHistoryStackSize(): number

Get the size of the history stack.

graph.getUndoRemainSize(...)

getUndoRemainSize(): number

Get the remaining size of the history undo stack.

graph.getUndoStackSize(...)

getUndoStackSize(): number

Get the size of the history undo stack.

graph.getRedoStackSize(...)

getRedoStackSize(): number

Get the size of the history redo stack.

graph.isHistoryEnabled()

isHistoryEnabled(): boolean

Check if history state is enabled.

graph.enableHistory()

enableHistory(): this

Enable history state.

graph.disableHistory()

disableHistory(): this

Disable history state.

graph.toggleHistory(...)

toggleHistory(enabled?: boolean): this

Toggle the enabled state of history. Parameters are as follows:

NameTypeRequiredDefault ValueDescription
enabledboolean-Whether to enable history state; defaults to toggling the enabled state of history.

Events

Event NameParameter TypeDescription
history:undo{ cmds: Command[], options: KeyValue }Triggered when a command is undone.
history:redo{ cmds: Command[], options: KeyValue }Triggered when a command is redone.
history:cancel{ cmds: Command[], options: KeyValue }Triggered when a command is canceled.
history:add{ cmds: Command[], options: KeyValue }Triggered when a command is added to the queue.
history:clean{ cmds: Command[] | null, options: KeyValue }Triggered when the history queue is cleared.
history:change{ cmds: Command[] | null, options: KeyValue }Triggered when the history queue changes.
history:batch{ cmds: Command, options: KeyValue }Triggered when a batch command is received.
graph.on('history:undo', ({ cmds }) => {
console.log(cmds)
})
// We can also listen to events on the plugin instance
history.on('undo', ({ cmds }) => {
console.log(cmds)
})