Maintaining UndoManager after changing diagram.div


In our application, we have multiple Diagrams but only have one visible to the user at a time. The HTML corresponding to a diagram looks something like

<div className="container">
  <div id="diagram-component" />

and we hide non-active diagrams by applying CSS to the container; we also disassociate non-active diagrams (diagram.div = null) to help with the performance of the rest of the app. To make a diagram active again, we set diagram.div back to the diagram-component div and change the display CSS property of the container back. This implementation was partly based off what we saw in Replacing Diagrams and Models.

With this, we’re able to maintain parts of the diagram state we want like the current selection, but not the UndoManager, which seems to be cleared when the diagram is associated with the div again. To maintain the undo history, I’ve tried making a deep copy of the UndoManager before associating a diagram div:

const undoManager = clonedeep(diagram.model.undoManager);

diagram.div = div;

if (undoManager) {
  diagram.model.undoManager = undoManager;

but when I switch back to a diagram with an undo history (in this case moving a node) and try to undo, I see errors like the following

undo error: Error: unknown ChangedEvent: !dEnumValue.Property position: -18  old: Point(-550,-232.5)  new: Point(-551,-232.5)

The !d seems to refer to this being a diagram change, but I’m not sure what to make of the error.

If you have any insight into this issue or pointers on how to maintain an UndoManager for each diagram, particularly when the diagrams will be disassociated and re-associated with their divs, I would greatly appreciate it. Thank you in advance!

So you are maintaining references to multiple Diagrams, and at any time at most one of them will have Diagram.div non-null. Do you replace the Diagram.model at any time when swapping HTMLDivElements? Or do you ever call Diagram.clear? If not, I would expect the UndoManager state of each Model to be maintained in memory. The UndoManager is not naturally serializable, so you should not be trying to do so.

I’ll try some experiments later today.

Yes that’s right. We aren’t replacing Diagram.model when swapping the divs and don’t call Diagram.clear.

Thanks for taking a look.

There does seem to be a problem. It requires further investigation.

The loss of UndoManager history has been fixed for v2.3.2, which should be coming out in a few days. Thanks for reporting the bug.

So you don’t need to try to save any UndoManager state yourself – just set the Diagram.div of the Diagram that you want to use a particular HTMLDivElement as a host.

Thank you Walter. We’ll try again after the v2.3.2 release.