BoldDeskWe are launching BoldDesk on Product Hunt soon. Learn more & follow us.
I created a Diagram following example at https://ej2.syncfusion.com/aspnetcore/Diagram/Swimlane#/fluent
Which looks like following
Now my requirement is that Bind "Source" Palette items with Source Phase inside of Swimlane. Means only Source Items should be dropped in source, input item in inphut phase and so on.
Code for adding Palette
ListPalette = new List ();
SymbolsVM symbolsVM;
string webRootPath = _webHostEnvironment.WebRootPath;
var path = Path.Combine(webRootPath, "symbols.json");
using (StreamReader sr = new StreamReader(path)) {
symbolsVM = JsonConvert.DeserializeObject(sr.ReadToEnd());
}
if (symbolsVM != null) {
Palette.Add(new SymbolPalettePalette() {
Id = "Source",
Expanded = true,
Symbols = GetDiagramNodes(symbolsVM.Source),
Title = "Source"
});
Palette.Add(new SymbolPalettePalette() {
Id = "Input",
Expanded = true,
Symbols = GetDiagramNodes(symbolsVM.Input),
Title = "Input"
});
Palette.Add(new SymbolPalettePalette() {
Id = "ModificationLogical",
Expanded = true,
Symbols = GetDiagramNodes(symbolsVM.ModificationLogical),
Title = "Modification (Logical)"
});
Palette.Add(new SymbolPalettePalette() {
Id = "ModificationPhysical",
Expanded = true,
Symbols = GetDiagramNodes(symbolsVM.ModificationPhysical),
Title = "Modification (Physical)"
});
Palette.Add(new SymbolPalettePalette() {
Id = "Output",
Expanded = true,
Symbols = GetDiagramNodes(symbolsVM.Output),
Title = "Output"
});
Palette.Add(new SymbolPalettePalette() {
Id = "MappingLogical",
Expanded = true,
Symbols = GetDiagramNodes(symbolsVM.MappingLogical),
Title = "Mapping (Logical)"
});
Palette.Add(new SymbolPalettePalette() {
Id = "MappingPhysical",
Expanded = true,
Symbols = GetDiagramNodes(symbolsVM.MappingPhysical),
Title = "Mapping (Physical)"
});
Palette.Add(new SymbolPalettePalette() {
Id = "Target",
Expanded = true,
Symbols = GetDiagramNodes(symbolsVM.Target),
Title = "Target"
});
}
ViewBag.Palette = Palette;
Following is the code for creating Swimlane
ListNodes = new List ();
//Create swimlane
DiagramNode swimlane = new DiagramNode();
swimlane.Id = "swimlane";
swimlane.Width = 900;
swimlane.Height = 600;
swimlane.OffsetX = 450;
swimlane.OffsetY = 300;
//Create lanes
ListLanes = new List ();
Lanes.Add(new Lane() {
Id = "stackCanvas1",
Height = 100,
Header = new Header() {
Annotation = new DiagramNodeAnnotation() { Content = "Function" },
Width = 50,
}
});
//Create phases
ListPhases = new List ();
Phases.Add(new Phase() {
Id = "phase1",
Offset = 200,
Header = new Header() {
Annotation = new DiagramNodeAnnotation() { Content = "Source" },
},
});
Phases.Add(new Phase() {
Id = "phase2",
Offset = 325,
Header = new Header() {
Annotation = new DiagramNodeAnnotation() { Content = "Input" },
},
});
Phases.Add(new Phase() {
Id = "phase3",
Offset = 450,
Header = new Header() {
Annotation = new DiagramNodeAnnotation() { Content = "Modification" },
},
});
Phases.Add(new Phase() {
Id = "phase4",
Offset = 575,
Header = new Header() {
Annotation = new DiagramNodeAnnotation() { Content = "Output" },
},
});
Phases.Add(new Phase() {
Id = "phase5",
Offset = 700,
Header = new Header() {
Annotation = new DiagramNodeAnnotation() { Content = "Mapping" },
},
});
Phases.Add(new Phase() {
Id = "phase6",
Offset = 825,
Header = new Header() {
Annotation = new DiagramNodeAnnotation() { Content = "Target" },
},
});
swimlane.Shape = new SwimLane() {
Type = "SwimLane",
PhaseSize = 20,
Header = new Header() {
Annotation = new DiagramNodeAnnotation() { Content = "Translation" },
Height = 50,
Orientation = "Horizontal",
Style = new DiagramTextStyle() { FontSize = 11 }
},
Lanes = Lanes,
Phases = Phases
};
Nodes.Add(swimlane);
ViewBag.Nodes = Nodes;
You can prevent the node from being dropped by using the drop event. Here, you can restrict the nodes and apply your logic. Refer to the below-mentioned code example and sample.
Code Snippet:
function drop(args) { var diagram = document.getElementById("container").ej2_instances[0]; var nodeElement = diagram.selectedItems.nodes[0].id; //getting swimlane node from the diagram var swimlane = diagram.getObject(diagram.nodes[1].parentId); //Checking whether the selected nodes are in the particular palette item or not if( nodeElement.includes('source')){ //Checking particular phase position to drop a node or not if(args.position.x > swimlane.shape.phases[0].offset){ //If it is greater than the particular phase position than cancel from dropping the node into diagram args.cancel = true; } } else if(nodeElement.includes('input')){ if (args.position.x > swimlane.shape.phases[1].offset || args.position.x < swimlane.shape.phases[0].offset){ args.cancel = true; } } else if(nodeElement.includes('logical')){ if (args.position.x > swimlane.shape.phases[2].offset || args.position.x < swimlane.shape.phases[1].offset){ args.cancel = true; } } else if(nodeElement.includes('physical')){ if(args.position.x > swimlane.shape.phases[3].offset || args.position.x < swimlane.shape.phases[2].offset){ args.cancel = true; } } else{ args.cancel = false; } } |
Thanks, it working as per requirements. there is just one issue. After placing it I can drag symbols to any phase. Is there a way to stop that as well?
Use the PositionChange event to prevent the node dragging within the phase in swimlane. Refer to the below-mentioned code example and sample.
Code Snippet:
function positionChange(args){ var diagram = document.getElementById("container").ej2_instances[0]; var nodeElement = diagram.selectedItems.nodes[0].id; var swimlane = diagram.getObject(diagram.nodes[1].parentId); if (nodeElement.includes('source')) { if (args.newValue.offsetX > swimlane.shape.phases[0].offset - args.source.width/2) { args.cancel = true; } } else if (nodeElement.includes('input')) { if (args.newValue.offsetX > swimlane.shape.phases[1].offset - args.source.width / 2 || args.newValue.offsetX < swimlane.shape.phases[0].offset + args.source.width / 2) { args.cancel = true; } } else if (nodeElement.includes('logical')) { if (args.newValue.offsetX > swimlane.shape.phases[2].offset - args.source.width / 2 || args.newValue.offsetX < swimlane.shape.phases[1].offset + args.source.width / 2) { args.cancel = true; } } else if (nodeElement.includes('physical')) { if (args.newValue.offsetX > swimlane.shape.phases[3].offset - args.source.width / 2 || args.newValue.offsetX < swimlane.shape.phases[2].offset + args.source.width / 2) { args.cancel = true; } } else { args.cancel = false; } } |