Page Index Toggle Pages: [1] 2  Send TopicPrint
Hot Topic (More than 10 Replies) Undo & Redo ! (Read 5961 times)
Kannan Thirumal
Senior Member
****
Offline


I Love Mind Fusion Diagram
:-)

Posts: 270
Location: Bangalore, India
Joined: Jan 18th, 2019
Undo & Redo !
Aug 23rd, 2019 at 7:40am
Print Post  
Hi,

     Do we have undo/redo feature in the diagram? If so, may I know how to do that?

Regards,
Kannan
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3147
Joined: Oct 19th, 2005
Re: Undo & Redo !
Reply #1 - Aug 23rd, 2019 at 11:09am
Print Post  
  
Back to top
 
IP Logged
 
Kannan Thirumal
Senior Member
****
Offline


I Love Mind Fusion Diagram
:-)

Posts: 270
Location: Bangalore, India
Joined: Jan 18th, 2019
Re: Undo & Redo !
Reply #2 - Aug 26th, 2019 at 5:00am
Print Post  
Hi,

It works fine when I implemented like this. Thank you !

  ngAfterViewInit(): void {

        this.diagram.setUndoEnabled(true);
   }

  private undoDiagramClick(): void {

    this.diagram.undo();
  }

  private redoDiagramClick(): void {

    this.diagram.redo();
  }

May I know how to receive the notifications when undo/redo is done so that I can update my data objects?

Regards,
Kannan
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3147
Joined: Oct 19th, 2005
Re: Undo & Redo !
Reply #3 - Aug 26th, 2019 at 8:52am
Print Post  
Hi,

Undo and redo are done immediately when you call respective methods. If you need to find which diagram items are affected by the action, try getting the command objects using these methods -

Code
Select All
function nextUndoCmd()
{
	return diagram.undoManager.undoHistory[diagram.undoManager.undoIndex];
}

function nextRedoCmd()
{
	return diagram.undoManager.undoHistory[diagram.undoManager.undoIndex + 1];
} 



calling them before undo() or redo(). The 'item' field of the returned command will point to the affected DiagramItem. If you are using composite commands, you might have to loop over compositeCmd.commands array and check item for each of them.

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
Kannan Thirumal
Senior Member
****
Offline


I Love Mind Fusion Diagram
:-)

Posts: 270
Location: Bangalore, India
Joined: Jan 18th, 2019
Re: Undo & Redo !
Reply #4 - Aug 27th, 2019 at 1:32pm
Print Post  
Hi,

It works fine. Thanks!

I've created nodes (and links). When doing undo, the node (and link) gets deleted.

After creating the node, I'm setting border color for the node dynamically (for example, on context menu click, showing color selector and allowing user to select a color and setting that color as the border color to the node).

But when I do undo, the node is getting deleted instead of just removing the border color. Is there any way to fix this?

Regards,
Kannan
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3147
Joined: Oct 19th, 2005
Re: Undo & Redo !
Reply #5 - Aug 28th, 2019 at 6:59am
Print Post  
Hi,

Use ChangeItemCommand to make property changes undo-able. You can find an example here, replace the text and brush assignment from sample code with stroke one -
https://www.mindfusion.eu/onlinehelp/jsdiagram/index.htm?M_MindFusion_Diagrammin...

Regards,
Slavcho
  
Back to top
 
IP Logged
 
Kannan Thirumal
Senior Member
****
Offline


I Love Mind Fusion Diagram
:-)

Posts: 270
Location: Bangalore, India
Joined: Jan 18th, 2019
Re: Undo & Redo !
Reply #6 - Aug 28th, 2019 at 8:36am
Print Post  
Hi,

I set the composite node border color like this and tried undo, but didn't work. May I know why?

private setNodeBorderColor() {

var selection = this.diagram.getSelection();

if (selection && selection.items && selection.items.length > 0 && selection.items[0] instanceof this.DiagramNode) {

var node = selection.items[0] as CompositeNode;

var change = new ChangeItemCommand(this.diagram, node);

this.setNodeBackgroundColor(node);

this.diagram.executeCommand(change);
}
}

private setNodeBackgroundColor(node: CompositeNode) {

var background = node.getComponent("Background") as any;
background.pen = "#FFFF00";
background.strokeThickness = this.strokeThickness;
background.margin.right = -node.bounds.width + 18;
background.margin.bottom = -node.bounds.height + 12;
node.invalidate();
}

Regards,
Kannan
  
Back to top
 
IP Logged
 
Kannan Thirumal
Senior Member
****
Offline


I Love Mind Fusion Diagram
:-)

Posts: 270
Location: Bangalore, India
Joined: Jan 18th, 2019
Re: Undo & Redo !
Reply #7 - Aug 28th, 2019 at 9:26am
Print Post  
Hi,

It works fine with ShapeNode like this,

private setNodeBorderColor() {

var selection = this.diagram.getSelection();

if (selection && selection.items && selection.items.length > 0) {

if (selection.items[0] instanceof this.DiagramNode) {

var node = selection.items[0] as CompositeNode;

var change = new ChangeItemCommand(this.diagram, node);

this.setCompositeNodeBorderColor(node);

this.diagram.executeCommand(change);
}
else if (selection.items[0] instanceof ShapeNode) {

var shapeNode = selection.items[0] as ShapeNode;

var change = new ChangeItemCommand(this.diagram, shapeNode);

this.setShapeNodeBorderColor(shapeNode);

this.diagram.executeCommand(change);
}
}
}

private setShapeNodeBorderColor(node: ShapeNode) {

var borderColor = "Yellow";
var diagramElement = node.getTag().Data as DiagramElement;
diagramElement.borderColor = borderColor;
node.setStroke(borderColor);
node.setStrokeThickness(5);
}

private setCompositeNodeBorderColor(node: CompositeNode) {

var borderColor = "Orange";
var diagramElement = node.getTag().Data as DiagramElement;
diagramElement.borderColor = borderColor;
var background = node.getComponent("Background") as any;
background.pen = borderColor;
background.strokeThickness = this.strokeThickness;
background.margin.right = -node.bounds.width + 18;
background.margin.bottom = -node.bounds.height + 12;
node.invalidate();
}

May I know what is the issue with composite node?

Regards,
Kannan
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3147
Joined: Oct 19th, 2005
Re: Undo & Redo !
Reply #8 - Aug 28th, 2019 at 11:33am
Print Post  
ChangeItemCommand does not automatically track dynamic changes you do to components loaded from a CompositeNode template, except for ones done via auto-properties (for Shape, Text and Image components, so nothing built-in for strokes at this time). The way we'd expect you to implement that is shown in this tutorial -
https://www.mindfusion.eu/onlinehelp/jsdiagram/index.htm?Tutorial_4__Custom_Node...

e.g. you could create your own BorderColor property, override toJson/fromJson methods to serialize it, and override saveState/restoreState methods to enable undoing it. If you prefer not to create a custom node class, you could still replace saveState and restoreState in CompositeNode.prototype, something like this (not tested) -

Code
Select All
var baseSaveState = CompositeNode.prototype.saveState;
CompositeNode.prototype.saveState = function()
{
  var state = baseSaveState.apply(this);
  state.borderColor = getShapeNodeBorderColor(this);
  return state;
}

var baseRestoreState = CompositeNode.prototype.restoreState;
CompositeNode.prototype.restoreState = function(state)
{
  baseRestoreState.apply(this, [state]);
  setShapeNodeBorderColor(this, state.borderColor);
}

// getShapeNodeBorderColor and setShapeNodeBorderColor implementations
// ...
 



Regards,
Slavcho
  
Back to top
 
IP Logged
 
Kannan Thirumal
Senior Member
****
Offline


I Love Mind Fusion Diagram
:-)

Posts: 270
Location: Bangalore, India
Joined: Jan 18th, 2019
Re: Undo & Redo !
Reply #9 - Aug 28th, 2019 at 12:33pm
Print Post  
Hi,

In case of ShapeNode, during undo operation, I'm able to get the diagram element in the 'item' field of ChangeItemCommand. May I know whether there is any way to find which value (text or border color or etc) has changed?

private getUndoRedoItem(index: number): Array<any> {

var undo: Array<any> = [];
if (this.diagram) {
var undoManager = (this.diagram as any).undoManager;
if (undoManager.undoHistory) {
var nextUndoCommmand = undoManager.undoHistory[undoManager.undoIndex + index];
if (nextUndoCommmand) {
if (nextUndoCommmand instanceof CompositeCommand) {
nextUndoCommmand.getCommands().forEach(f => {
if (f instanceof AddItemCommand) {

var cmd = f as AddItemCommand;
undo.push(cmd.item.getTag());
}
});
}
else if (nextUndoCommmand instanceof AddItemCommand) {

var cmd = nextUndoCommmand as AddItemCommand;
undo.push(cmd.item.getTag());
}
else if (nextUndoCommmand instanceof ChangeItemCommand) {

var cmd = nextUndoCommmand as ChangeItemCommand;
undo.push(cmd.item.getTag());
}
else {
var cmd2 = nextUndoCommmand;
var c = cmd2;
}
}
}
}
return undo;
}

Regards,
Kannan

Kannan Thirumal wrote on Aug 28th, 2019 at 9:26am:
Hi,

It works fine with ShapeNode like this,

private setNodeBorderColor() {

var selection = this.diagram.getSelection();

if (selection && selection.items && selection.items.length > 0) {

if (selection.items[0] instanceof this.DiagramNode) {

var node = selection.items[0] as CompositeNode;

var change = new ChangeItemCommand(this.diagram, node);

this.setCompositeNodeBorderColor(node);

this.diagram.executeCommand(change);
}
else if (selection.items[0] instanceof ShapeNode) {

var shapeNode = selection.items[0] as ShapeNode;

var change = new ChangeItemCommand(this.diagram, shapeNode);

this.setShapeNodeBorderColor(shapeNode);

this.diagram.executeCommand(change);
}
}
}

private setShapeNodeBorderColor(node: ShapeNode) {

var borderColor = "Yellow";
var diagramElement = node.getTag().Data as DiagramElement;
diagramElement.borderColor = borderColor;
node.setStroke(borderColor);
node.setStrokeThickness(5);
}

private setCompositeNodeBorderColor(node: CompositeNode) {

var borderColor = "Orange";
var diagramElement = node.getTag().Data as DiagramElement;
diagramElement.borderColor = borderColor;
var background = node.getComponent("Background") as any;
background.pen = borderColor;
background.strokeThickness = this.strokeThickness;
background.margin.right = -node.bounds.width + 18;
background.margin.bottom = -node.bounds.height + 12;
node.invalidate();
}

May I know what is the issue with composite node?

Regards,
Kannan

  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3147
Joined: Oct 19th, 2005
Re: Undo & Redo !
Reply #10 - Aug 28th, 2019 at 8:05pm
Print Post  
The cmd.state object contains all fields shown below (along with ones added by subclasses). You could compare fields you are interested in with item's current values to find out if a specific property has changed.

Regards,
Slavcho

Code
Select All
saveState: function ()
{
	var state = {};

	state.zIndex = this.getZIndex();
	state.tag = this.tag;
	state.text = this.getText();
	state.textColor = this.textColor;
	state.font = this.font;
	state.ignoreLayout = this.ignoreLayout;
	state.brush = this.brush;
	state.pen = this.pen;
	state.strokeThickness = this.strokeThickness;
	state.selected = this.selected;
	state.visible = this.getVisible();
	state.locked = this.getLocked();
	state.tooltip = this.tooltip;
	state.hyperLink = this.hyperLink;
	state.shadowColor = this.shadowColor;
	state.shadowOffsetX = this.getShadowOffsetX();
	state.shadowOffsetY = this.getShadowOffsetY();
	state.style = this.style;
	state.textAlignment = this.getTextAlignment();
	state.lineAlignment = this.getLineAlignment();

	return state;
}, 

  
Back to top
 
IP Logged
 
Kannan Thirumal
Senior Member
****
Offline


I Love Mind Fusion Diagram
:-)

Posts: 270
Location: Bangalore, India
Joined: Jan 18th, 2019
Re: Undo & Redo !
Reply #11 - Aug 18th, 2020 at 9:15am
Print Post  
Hi,

I add an element to the diagram.

When I do undo, Event.nodeDeleted is notified and I update my data objects in this event handler. If I do redo again, Event.nodeCreated is not called. May I know how I can handle this scenario?

Regards,
Kannan
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3147
Joined: Oct 19th, 2005
Re: Undo & Redo !
Reply #12 - Aug 18th, 2020 at 2:35pm
Print Post  
Hi,

nodeDeleted is more of an exception being raised for non-interactive operations, and we'll likely stop that when we get to a major API revision. Try handling these through itemAdded and itemRemoved events instead, they should always be raised for both interactive and programmatic operations.

Regards,
Slavcho
  
Back to top
 
IP Logged
 
Kannan Thirumal
Senior Member
****
Offline


I Love Mind Fusion Diagram
:-)

Posts: 270
Location: Bangalore, India
Joined: Jan 18th, 2019
Re: Undo & Redo !
Reply #13 - Aug 18th, 2020 at 2:47pm
Print Post  
Hi Slavcho,

Ok Thank you. I think you mean interactive operation is the one which user do and programmatic operations is the one which we add elements when loading diagram.

If so, in this ItemAdded event, is there any way to differentiate these two or I've to write my own logic?

Regards,
Kannan
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3147
Joined: Oct 19th, 2005
Re: Undo & Redo !
Reply #14 - Aug 18th, 2020 at 3:15pm
Print Post  
I don't think there is; you could keep logic for interactive creation in nodeCreated handler and use itemAdded only for common logic of interactive/programmatic cases.

Regards,
Slavcho
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: [1] 2 
Send TopicPrint