58
Create an Org Chart to Elegantly Visualize Hierarchical Data in Blazor WebAssembly
An organizational chart (also known as “org chart”) is a graphic representation of the internal structure of an organization or any other data collection. Employees can utilize org charts to learn about their department’s structure, as well as the structure of other departments.
The Syncfusion Blazor Diagram component is a feature-rich component for creating or visualizing interactive diagrams. It allows users to create organizational charts using either C# code or a visual interface with seamless interaction and editing capabilities.
In this blog, we will learn how to create an interactive org chart to visualize your hierarchical data using the Blazor Diagram component.
Here, we are going to include the Blazor Diagram component in a Blazor WebAssembly application.
Note: Before proceeding, refer to the getting started with the Blazor Diagram component documentation.
- First, install the Syncfusion.Blazor.Diagram NuGet package in the app using the NuGet package manager.
- Now, add the style resources through CDN or from the NuGet package in the *HEAD * element of the *~/wwwroot/index.cshtml * page.
<head>
....
....
<link href="_content/Syncfusion.Blazor/styles/bootstrap4.css" rel="stylesheet" />
</head>
- Then, open the ~/_Imports.Blazor ** file and import the **Syncfusion. Blazor.Diagram package in it.
@using Syncfusion.Blazor.Diagram
- Open the Startup.** cs file and add the services required for the Syncfusion components using the services.AddSyncfusionBlazor() method. Before that, add the ** services.AddSyncfusionBlazor() **method in the ConfigureServices** function, like in the following code example.
@using Syncfusion.Blazor;
namespace BlazorApplication
{
public class Startup
{
....
....
public void ConfigureServices(IServiceCollection services)
{
....
....
services.AddSyncfusionBlazor();
}
}
}
- Next, add the Blazor Diagram Component to the *Pages * folder of your Razor file. Refer to the following code example.
<SfDiagramComponent Width="100%" Height="600px"/>
Note: For more details, refer to the documentation for creating Blazor diagram nodes and the documentation for creating Blazor diagram connectors with labels.
Let’s see how to create a simple org chart in your Blazor WebAssembly application.
We need a data source or node collection to populate the organization chart on the diagram canvas.
First, let’s create a model class to construct the data source. Define the employee’s ID, role, and reporting person in your organization in the model class. You can add a color property to improve the UI’s design. Also, you can specify your custom properties if necessary.
Refer to the following code.
// Create a model class for the data source.
public class EmployeeData
{
public string ID { get; set; }
public string Role { get; set; }
public string Color { get; set; }
public string Manager { get; set; }
}
Now, create a data source for the org chart and populate the data source records as nodes. We should specify the parent and child relationships in the organization while giving the records. In the organizational layout, each record in the data source will be created as a separate node.
Refer to the following code.
//Define the dataSource.
public List<EmployeeData> DataSource = new List<EmployeeData>()
{
new EmployeeData(){ID= "parent", Role= "Board", Color = "#71AF17", Manager = "" },
new EmployeeData() { ID = "1",Role= "General manager", Color = "#71AF17", Manager = "parent" },
new EmployeeData() { ID = "2", Role= "Human resource manager", Color = "#1859B7", Manager = "1", },
new EmployeeData() { ID = "3", Role= "Trainers", Color = "#2E95D8", Manager = "2" },
// ...
// .. .
};
Now, bind the data source with the Blazor Diagram component, as seen in the following code.
<SfDiagramComponent>
<DataSourceSettings ID="ID" ParentID="Manager" DataSource="DataSource"></DataSourceSettings> </SfDiagramComponent>
Once the data source is bound and the parent-child relationships are configured, define the automatic layout properties to create the organization chart.
<Layout @bind-Type="@type" @bind-Orientation="@orientation" GetLayoutInfo="GetLayoutInfo" >
</Layout>
You can do the following customization in the org chart:
The HorizontalSpacing and VerticalSpacing properties of the layout allow you to set the horizontal and vertical spacing between the nodes, respectively.
The Layout’s Margin property allows you to set blank space. All these parameters are supported by two-way binding to modify the default or current values.
<Layout @bind-Type="@type" HorizontalSpacing="30" VerticalAlignment="30" >
<LayoutMargin Bottom="10" Top="10" Right="10" Left="10"></LayoutMargin>
</Layout>
The GetLayoutInfo callback method will be triggered for each node during the layout process. This method helps us to provide instructions to the automatic-layout process regarding how to generate the org chart.
In an org chart, the employees are often represented directly below a representation of the person to whom they report. And although reporting to the same person, some employees may have less authority than others. In our Blazor Diagram Component, we can assign only one assistant in the entire org chart layout.
Refer to the following code.
private TreeInfo GetLayoutInfo(IDiagramObject obj, TreeInfo options)
{
Node node = obj as Node;
// Add an assistant to the root node.
if ((node.Data as OrganizationalDetails).Role == "General manager")
{
options.Assistants.Add(options.Children[0]);
options.Children.RemoveAt(0);
}
options.Type = SubTreeAlignments.Balanced;
options.Orientation = SubTreeOrientation.Horizontal;
return options;
}
Finally, the Razor file will look like the following.
@using Syncfusion.Blazor.Diagram
@using Syncfusion.Blazor.Diagram.Internal
<SfDiagramComponent @ref="@Diagram" Height="690px" InteractionController="@InteractionController.ZoomPan" NodeCreating="@NodeCreating" ConnectorCreating="@ConnectorCreating">
<DataSourceSettings ID="ID" ParentID="Manager" DataSource="DataSource"></DataSourceSettings>
<Layout @bind-Type="@type" @bind-HorizontalSpacing="@HorizontalSpacing" @bind-Orientation="@orientation" @bind-VerticalSpacing="@VerticalSpacing" @bind-HorizontalAlignment="@horizontalAlignment" @bind-VerticalAlignment="@verticalAlignment" GetLayoutInfo="GetLayoutInfo">
<LayoutMargin @bind-Top="@top" @bind-Bottom="@bottom" @bind-Right="@right" @bind-Left="@left"></LayoutMargin>
</Layout>
<SnapSettings Constraints="SnapConstraints.None"></SnapSettings>
</SfDiagramComponent>
@code
{
SfDiagramComponent Diagram;
LayoutOrientation orientation = LayoutOrientation.TopToBottom;
LayoutType type = LayoutType.OrganizationalChart;
HorizontalAlignment horizontalAlignment = HorizontalAlignment.Auto;
VerticalAlignment verticalAlignment = VerticalAlignment.Auto;
int HorizontalSpacing = 30;
int VerticalSpacing = 30;
double top = 50;
double bottom = 50;
double right = 50;
double left = 50;
double offset = 20;
// Create a class for the data source recorded as a new type.
public class EmployeeData
{
public string ID { get; set; }
public string Role { get; set; }
public string Color { get; set; }
public string Manager { get; set; }
}
//DataSource Items.
public List<EmployeeData> DataSource = new List<EmployeeData>()
{
new EmployeeData(){ID= "parent", Role= "Board", Color = "#71AF17", Manager = "" },
new EmployeeData() { ID = "1",Role= "General manager", Color = "#71AF17", Manager = "parent" },
new EmployeeData() { ID = "11", Role= "Assistant general manager",Color = "#71AF17", Manager = "1" },
new EmployeeData() { ID = "2", Role= "Human resource manager", Color = "#1859B7", Manager = "1", },
new EmployeeData() { ID = "3", Role= "Trainers", Color = "#2E95D8", Manager = "2" },
new EmployeeData() { ID = "4", Role= "Recruiting team",Color = "#2E95D8", Manager = "2" },
new EmployeeData() { ID = "5", Role= "Finance asst. manager", Color = "#2E95D8", Manager = "2" },
new EmployeeData() { ID = "6", Role= "Design manager", Color = "#1859B7", Manager = "1" },
new EmployeeData() { ID = "7",Role= "Design supervisor",Color = "#2E95D8", Manager = "6" },
new EmployeeData() { ID = "8",Role= "Development supervisor",Color = "#2E95D8", Manager = "6" },
new EmployeeData() { ID = "9",Role= "Drafting supervisor", Color = "#2E95D8", Manager = "6" },
new EmployeeData() { ID = "10",Role= "Operations manager",Color = "#1859B7", Manager = "1" },
new EmployeeData() { ID = "11",Role= "Statistics department",Color = "#2E95D8", Manager = "10" },
new EmployeeData() { ID = "12",Role= "Logistics department",Color = "#2E95D8", Manager = "10" },
new EmployeeData() { ID = "16", Role= "Logistics department", Color = "#1859B7", Manager = "1" },
new EmployeeData() { ID = "17",Role= "Overseas sales manager",Color = "#2E95D8", Manager = "16" },
new EmployeeData() { ID = "18", Role= "Petroleum manager", Color = "#2E95D8", Manager = "16" },
new EmployeeData() { ID = "20",Role= "Service department manager",Color = "#2E95D8", Manager = "16" },
new EmployeeData() { ID = "21", Role= "Quality control department", Color = "#2E95D8", Manager = "16" },
};
private TreeInfo GetLayoutInfo(IDiagramObject obj, TreeInfo options )
{
Node node = obj as Node;
options.Offset = -50;
if ((node.Data as EmployeeData).Role == "General manager")
{
options.Assistants.Add(options.Children[0]);
options.Children.RemoveAt(0);
}
options.AlignmentType = SubTreeAlignmentType.Balanced;
options.Orientation = Orientation.Horizontal;
options.Offset = offset;
return options;
}
private void NodeCreating(IDiagramObject obj)
{
Node node = obj as Node;
if (node.Data is System.Text.Json.JsonElement)
{
node.Data = System.Text.Json.JsonSerializer.Deserialize<EmployeeData>(node.Data.ToString());
}
EmployeeData organizationData = node.Data as EmployeeData;
node.Width = 120;
node.Height = 50;
node.Style.Fill = organizationData.Color;
ShapeAnnotation annotation = new ShapeAnnotation()
{
Content = organizationData.Role,
Offset = new DiagramPoint(0.5, 0.5),
Style = new TextStyle() { Color = "white" }
};
node.Annotations = new DiagramObjectCollection<ShapeAnnotation>() { annotation };
}
// Define the default values for the Connector object.
private void ConnectorCreating(IDiagramObject DiagramObject)
{
Connector connector = (DiagramObject as Connector);
connector.Type = ConnectorSegmentType.Orthogonal;
connector.TargetDecorator.Shape = DecoratorShape.None;
connector.SourceDecorator.Shape = DecoratorShape.None;
}
}
After executing the previous code, you will get an org chart that looks like the following image.
In an organization, employees’ designations and departments may change frequently. You can modify the org chart interactively by dragging and dropping child (employee) nodes or parent (department) nodes to desired locations. To enable editing of the org chart’s hierarchical structure, add the following code in the drop method of the Blazor Diagram component.
<SfDiagramComponent DragDrop="Drop">
@*// ...
// ...*@
</SfDiagramComponent>
private async Task Drop(DropEventArgs args)
{
DiagramSelectionSettings selector = args.Element as DiagramSelectionSettings;
if (selector.Nodes.Count > 0)
{
string id = selector.Nodes[0].InEdges[0];
Connector conn = diagram.GetObject(id) as Connector;
// Source connection has changed for dropped connector.
conn.SourceID = (args.Target as Node).ID;
await diagram.DoLayout();
}
}
The previous code snippet directly modifies the connectors’ source ID alone. But the data source will not be updated automatically. Refer to the following code to update the data source while dragging and dropping the nodes in the org chart.
<SfDiagramComponent DragDrop="Drop">
@*// ...
// ...*@
</SfDiagramComponent>
private async Task Drop(DropEventArgs args)
{
DiagramSelectionSettings selector = args.Element as DiagramSelectionSettings;
if (selector.Nodes.Count > 0)
{
// Refresh the data source when dragging and dropping the shape over another shape.
Node targetNode = args.Target as Node;
EmployeeData targetNodeData = DataSource.Find(data => data.ID == (targetNode.Data as EmployeeData).ID);
EmployeeData drogNodeData = DataSource.Find(data => data.ID == (selector.Nodes[0].Data as EmployeeData).ID);
drogNodeData.Manager = targetNodeData.ID;
diagram.ClearSelection();
await diagram.RefreshDataSource();
}
}
Refer to the following GIF image.
![](https://res.cloudinary.com/practicaldev/image/fetch/s--4kRA8Wf---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.syncfusion.com/blogs/wp-content/uploads/2021/12/Dragging-and-dropping-nodes-in-org-chart.gif)
It is difficult to visualize a huge organization chart on a small screen. In such a scenario, zooming and panning support helps provide a better view of chart data. Use the following code to enable zooming and panning support in the Blazor Diagram component.
<SfDiagramComponent Tool="@DiagramTools.ZoomPan">
</SfDiagramComponent>
Then, use the Ctrl + mouse wheel operation to zoom in and out on the org chart.
Note: For complete details, refer to the Create Org Chart using the Blazor Diagram Component documentation.
Refer to the examples for creating an org chart using the Blazor Diagram Component in WebAssembley on GitHub and Syncfusion’s website.
Thanks for reading! In this blog, we have seen how to create an org chart using the Syncfusion Blazor Diagram component. Try out the steps given in this blog and elegantly visualize the hierarchical structure of any data!
If you would like to try Syncfusion components, you can download our free trial. Also, check out our other Blazor demos and documentation for detailed explanations and the facts you need to proceed further.
You can also contact us through our support forum, support portal, or feedback portal. We are always happy to assist you!
58