TL;DR: Connector overlapping in Blazor diagrams can lead to visual clutter and a poor user experience. This guide walks developers through optimizing Blazor Diagram Connector routing using smart constraints like AvoidLineOverlapping and orthogonal paths. Learn how to enhance diagram clarity, improve connector flow, and build more readable interfaces in your Blazor applications.
Creating clear and readable diagrams is crucial for effective communication in both development and business contexts. Overlapping connectors in diagrams can often lead to visual confusion, making it difficult for users to accurately interpret the intended flows or processes. The Blazor Diagram component provides a solution to this problem with its Avoid Line Overlapping feature.
In this post, we’ll explore how to optimize Blazor Diagram Connector routing using smart constraints to avoid line overlapping and improve readability.
What is line overlapping?
Line overlapping occurs when two or more connectors or lines in a diagram use the exact same path, causing them to stack directly on top of one another. This results in visual confusion because it becomes challenging to distinguish between the separate connections, making it difficult for users to accurately interpret the relationships or flows being represented in the diagram.
How the AvoidLineOverlapping fixes it
The Avoid Line Overlapping feature addresses line overlapping by automatically detecting when connectors overlap and moving them apart. It does this by creating small detours or offsets, ensuring each line has its own visible path.
When does it activate?
The overlap resolution activates automatically under several conditions:
- New connectors: When new connectors are added, they would overlap with existing ones.
- Node movement: When nodes are moved, the connector paths change.
- Shared diagram areas: When multiple connectors need to travel through the same area of the diagram.
- Diagram updates: When the diagram layout is updated or refreshed.
This ensures that your diagrams always maintain clear, non-overlapping connector paths without the need for manual intervention.
Configuration requirements checklist
Before implementing the Avoid Line Overlapping feature, ensure:
- Routing is enabled in diagram constraints:
DiagramConstraints diagramConstraints = DiagramConstraints.Default
| DiagramConstraints.Routing
- All connectors are of orthogonal type:
Type = ConnectorSegmentType.Orthogonal
Prevent line overlapping
To enable the Avoid Line Overlapping feature, set the Constraints property of your SfDiagramComponent to include the AvoidLineOverlapping Enum value. This configuration ensures that your diagrams automatically manage connector paths to prevent overlapping without manual intervention. Here’s how you can do it:
@using Syncfusion.Blazor.Diagram
<SfDiagramComponent @ref="diagram"
Height="700px"
Width="100%"
@bind-Nodes="@nodes"
@bind-Connectors="@connectors"
Constraints="@diagramConstraints">
</SfDiagramComponent>
@code {
SfDiagramComponent diagram;
DiagramObjectCollection<Node> nodes = new DiagramObjectCollection<Node>();
DiagramObjectCollection<Connector> connectors = new DiagramObjectCollection<Connector>();
SnapConstraints snapConstraints = SnapConstraints.All;
DiagramConstraints diagramConstraints = DiagramConstraints.Default | DiagramConstraints.AvoidLineOverlapping;
}
Benefit
- Enhanced readability: By preventing connectors from overlapping, diagrams become much easier to read and understand. Each connector’s path is distinct, making it straightforward to follow the flow from one node to another.
Example
The following example demonstrates how to integrate the Avoid Line Overlapping feature within a Blazor Diagram:
@using Syncfusion.Blazor
@using Syncfusion.Blazor.Diagram
<SfDiagramComponent @ref="diagram" Height="700px" Width="100%" @bind-Nodes="@nodes" LineRoutingSettings="@LineRoutingSettings" @bind-Connectors="@connectors" Constraints="@diagramConstraints">
</SfDiagramComponent>
@code {
SfDiagramComponent diagram;
DiagramObjectCollection<Node> nodes = new DiagramObjectCollection<Node>();
DiagramObjectCollection<Connector> connectors = new DiagramObjectCollection<Connector>();
DiagramConstraints diagramConstraints = DiagramConstraints.Default | DiagramConstraints.Routing | DiagramConstraints.AvoidLineOverlapping;
LineRoutingSettings LineRoutingSettings = new LineRoutingSettings()
{
RoutingType = RoutingTypes.Classic
};
protected override void OnInitialized()
{
InitDiagramModel();
}
private void InitDiagramModel()
{
Create1to16Node("node1", 205, 180, 80, 240);
Create1to16Node("node2", 205, 427.5, 80, 240);
Create9to5Node("node3", 415, 127.5, 100, 135);
Create9to5Node("node4", 415, 367.5, 100, 135);
Create9to5Node("node5", 615, 127.5, 100, 135);
Create9to5Node("node6", 615, 367.5, 100, 135);
Create16to1Node("node7", 820, 240, 80, 240);
CreateInputNode("node8", 70, 40, 80, 30, "Cin");
CreateInputNode("node9", 70, 180, 80, 30, "A");
CreateInputNode("node10", 70, 427.5, 80, 30, "B");
CreateOutputNode("node11", 950, 240, 80, 30, "S");
CreateOutputNode("node12", 950, 367.5, 80, 30, "Cout");
}
public void Create1to16Node(string id, double x, double y, double width, double height)
{
Node node = CreateNode(id, x, y, width, height);
AddShape(node, 1, 16);
var inPorts = AddPorts(node, 1, "in");
var outPorts = AddPorts(node, 16, "out");
AddPortsLabels(node, 16, "out");
}
public void Create16to1Node(string id, double x, double y, double width, double height)
{
Node node = CreateNode(id, x, y, width, height);
AddShape(node, 16, 1);
var inPorts = AddPorts(node, 16, "in");
var outPorts = AddPorts(node, 1, "out");
AddPortsLabels(node, 16, "in");
}
public void Create9to5Node(string id, double x, double y, double width, double height)
{
List<string> leftLabels = new List<string> { "A_0", "A_1", "A_2", "A_3", "B_0", "B_1", "B_2", "B_3", "Cin" };
List<string> rightLabels = new List<string> { "S_0", "S_1", "S_2", "S_3", "Cout" };
Node node = CreateNode(id, x, y, width, height, "4 Bit\nRCA");
AddShape(node, 9, 5);
var inPorts = AddPorts(node, 9, "in");
var outPorts = AddPorts(node, 5, "out", 9);
AddPortsLabels(node, 9, "in", leftLabels);
AddPortsLabels(node, 5, "out", rightLabels, 9);
}
public void CreateInputNode(string id, double x, double y, double width, double height, string label)
{
Node node = CreateNode(id, x, y, width, height, label);
AddShape(node, 0, 1);
var outPorts = AddPorts(node, 1, "out");
if (node.Annotations.Count > 0)
{
var annotation = node.Annotations[0];
annotation.Offset = new DiagramPoint
{
X = (width - 25) / (2 * width),
Y = 0.5
};
}
}
public DiagramObjectCollection<PointPort> AddPorts(Node node, int count, string side, double factor = 0)
{
if (factor == 0)
{
factor = count;
}
DiagramObjectCollection<PointPort> Ports = new DiagramObjectCollection<PointPort>();
if (count > 1)
{
for (int i = 1; i <= count; i++)
{
var port = new PointPort
{
ID = $"{node.ID}{side}{i - 1}",
Offset = new DiagramPoint
{
X = side == "out" ? 1 : 0,
Y = (i / (double)factor) - (1 / (2.0 * factor))
},
Visibility = PortVisibility.Visible,
Shape = PortShapes.Circle,
Style = new ShapeStyle { Fill = "black" },
Constraints = PortConstraints.Default | PortConstraints.Draw,
Width = 8,
Height = 8
};
node.Ports.Add(port);
}
}
else
{
var port = new PointPort
{
ID = $"{node.ID}{side}0",
Offset = new DiagramPoint
{
X = side == "out" ? 1 : 0,
Y = 0.5
},
Visibility = PortVisibility.Visible,
Shape = PortShapes.Circle,
Style = new ShapeStyle { Fill = "black" },
Constraints = PortConstraints.Default | PortConstraints.Draw,
Width = 8,
Height = 8,
};
node.Ports.Add(port);
}
return Ports;
}
public Node CreateNode(string id, double x, double y, double width, double height, string label = null)
{
var shapeStyle = new ShapeStyle { StrokeColor = "black", StrokeWidth = 2 };
var diagramNode = new Node
{
ID = id,
OffsetX = x,
OffsetY = y,
Width = width,
Height = height,
Style = shapeStyle,
Shape = new BasicShape { Type = NodeShapes.Basic },
};
if (!string.IsNullOrEmpty(label))
{
var annotation = new ShapeAnnotation
{
Content = label,
Style = new TextStyle { FontSize = 14 }
};
diagramNode.Annotations.Add(annotation);
}
nodes.Add(diagramNode);
return diagramNode;
}
}
GitHub reference
You can find the complete working sample here in the GitHub demo.
FAQs
Q1. Does the Blazor Diagram avoid the overlapping feature of connectors when working with all connector types?
No, it primarily supports orthogonal connectors in Blazor. Ensure your connectors are set to ConnectorSegmentType.Orthogonal for the feature to enable properly.
Q2. What happens if I enable Blazor connector routing but forget to include routing constraints?
The avoid overlapping feature requires both Routing and AvoidLineOverlapping constraints. Without Routing, connectors may still overlap, as the base path calculation won’t adjust dynamically.
Q3. Can I customize the detour offsets in line routing Blazor for more control?
Yes, but the automatic detours are handled internally. For finer control, adjust LineRoutingSettings like RoutingType to Classic or Advanced to influence how paths avoid overlaps.
Q4. Why does connector overlapping persist in complex diagrams even after enabling the feature?
In dense layouts, ensure all prerequisites like orthogonal types and diagram updates are met. If issues remain, check for viewport limitations or use bridging to further enhance diagram clarity in Blazor.
Conclusion
By leveraging features to avoid connector overlapping in Blazor Diagram component, developers can create diagrams that are not only visually appealing but also functionally superior in terms of readability and user comprehension. This is particularly useful for complex setups where diagram clarity in Blazor is paramount.
For more details and examples, refer to the official Blazor Diagram documentation. Dive in and enhance your projects today. Try implementing Blazor connector routing in your next diagram!
Existing customers can download the latest version of Essential Studio® from the license and downloads page. If you are not yet a customer, you can try our 30-day free trial to check out these new features.
If you have questions, you can contact us through our support forums, support portal, or feedback portal. We are always happy to assist you!
Related Blogs
- Automate Flowchart Creation from External Data with Blazor Diagram
- Easily Create Multi-Parent Hierarchical Trees with Blazor Diagram Component
- Boost Your Diagram Clarity with Line Routing in Blazor
- Crafting Interactive Digital Logic Circuits Made Easy with Blazor Diagram Component
This article was originally published at Syncfusion.com.
Top comments (0)