Articles in this section
Category / Section

How to Embed Diagrams Inside Panels of a Dashboard Layout in Blazor?

12 mins read

This guide explains how to embed Syncfusion® SfDiagramComponent inside panels of a Dashboard layout in a Blazor application. This enables developers to create dynamic dashboards with interactive diagrams for better visualization.

Prerequisites:
Before proceeding, ensure you have a Blazor Server application set up. If you need assistance, you can follow the instructions here: Create Blazor Server application

Implementation Steps:

Step 1: Define the Diagram Component
To begin, set up the DiagramComponent Razor component which integrates the SfDiagramComponent in the Blazor application. Configure it to display nodes in a hierarchical layout and define spacing, gridlines, and the data source settings.

@using System.Text.Json
@using Syncfusion.Blazor.Diagram

<SfDiagramComponent @ref="DInstance" Width="@PanelWidth.ToString()" InteractionController="DiagramInteractions.ZoomPan" Created="Created"~~~~
NodeCreating="@OnNodeCreating" ConnectorCreating="@OnConnectorCreating">
   <SnapSettings Constraints="SnapConstraints.None"/> 
   <DataSourceSettings Id="@nameof(DataModel.Id)" ParentId="@nameof(DataModel.ParentId)" DataSource="@DataSource" />
   <Layout @bind-Type="@Type" @bind-HorizontalSpacing="@horizontalSpacing" @bind-VerticalSpacing="@verticalSpacing">
       <LayoutMargin @bind-Left="@Left" @bind-Right="@Right" @bind-Top="@Top"></LayoutMargin>
   </Layout>
   <ScrollSettings ScrollLimit="ScrollLimitMode.Infinity"></ScrollSettings>
   <PageSettings Width="@PageWidth" Height="@PageHeight" Orientation="PageOrientation.Portrait">
       <PageMargin Top="0" Bottom="0" Left="0" Right="0" />
   </PageSettings>
</SfDiagramComponent>

@code {
   [Parameter] public object DataSource { get; set; }
   [Parameter] public double PanelWidth { get; set; }
   [Parameter] public LayoutType Layout { get; set; }
   private int horizontalSpacing = 15;
   private int verticalSpacing = 50;
   private double Left = 10;
   private double Right = 10;
   private double Top = 10;
   private double PageWidth = 250;
   private double PageHeight = 300;

   SfDiagramComponent DInstance;
   
   // Defines default values for Node object
   
   private void Created()
   {
       DInstance.FitToPage(new FitOptions() { Mode = FitMode.Both, Region = DiagramRegion.PageSettings,  });
   }
   private void OnNodeCreating(IDiagramObject obj)
   {
       var node = obj as Node;

       if (node.Data is JsonElement jsonElement)
       {
           node.Data = jsonElement.Deserialize<DataModel>();
       }

       var data = node.Data as DataModel;

       node.MinWidth = 95;
       node.MinHeight = 30;
       node.MaxWidth = 195;
               if(Layout == LayoutType.RadialTree)
       {
           if (data.Content.Contains("Managing Director"))
           {
               node.Shape = new BasicShape()
               {
                   Type = NodeShapes.Basic,
                   Shape = NodeBasicShapes.Ellipse,
                   CornerRadius = 10
               };
               node.Width = 150;
               node.Height = 150;
               node.Style.Fill = "6495ED";
           }
           else if (data.Content.Contains("Project Manager"))
           {
               node.Width = 65;
               node.Height = 65;
               node.Style.Fill = "#6495ED";
           }
           else
           {
               node.Shape = new BasicShape()
               {
                   Type = NodeShapes.Basic,
                   Shape = NodeBasicShapes.Ellipse,
                   CornerRadius = 10
               };
               node.Style.Fill = "#6495ED";
               node.Width = 50;
               node.Height = 50;
           }
       }
       else
       {
           node.Shape = new BasicShape() { Type = NodeShapes.Basic, Shape = NodeBasicShapes.Rectangle };
       }~~~~
       node.Tooltip = new DiagramTooltip() { Content = "Prueba tooltip", OpensOn = "Hover" };

       node.Annotations = new DiagramObjectCollection<ShapeAnnotation>()
       {
           new()
           {
               ID = "label1",
               Content = data.Content,
               Style = new TextStyle() { Color = "White", Fill = "Transparent", FontSize = 12, FontFamily = "Segoe UI" }
           }
       };

       node.Ports = new DiagramObjectCollection<PointPort>()
       {
           new()
           {
               ID = "port1",
               Offset = new DiagramPoint() { X = 0, Y = 0.5 },
               Width = 10,
               Height = 10,
               Visibility = PortVisibility.Hidden,
               Style = new ShapeStyle() { Fill = "Black" }
           },
           new()
           {
               ID = "port2",
               Offset = new DiagramPoint() { X = 1, Y = 0.5 },
               Width = 10,
               Height = 10,
               Visibility = PortVisibility.Hidden,
               Style = new ShapeStyle() { Fill = "Black" }
           }
       };
   }

   // Defines default values for Connector object
   private void OnConnectorCreating(IDiagramObject obj)
   {
       if (obj is not Connector connector) return;
       connector.Type = ConnectorSegmentType.Orthogonal;
       connector.TargetDecorator.Shape = DecoratorShape.None;
       connector.SourceDecorator.Shape = DecoratorShape.None;
       connector.Style = new ShapeStyle() { StrokeColor = "#4d4d4d" };
   }

   public class DataModel
   {
       public string Id { get; set; }
       public string ParentId { get; set; }
       public string Content { get; set; }
   }
}

Step 2: Define the Dashboard Layout Component
Set up the SfDashboardLayout component, which will contain multiple panels. Each dashboard panel contains a SfDiagramComponent displaying a hierarchical diagram with nodes and connectors.

@page "/"

@using Syncfusion.Blazor.Diagram
@using Syncfusion.Blazor.Layouts
@inject IJSRuntime JS

<div id="component-container">
  <SfDashboardLayout Columns="4" DraggableHandle=".e-panel-header">
    <DashboardLayoutPanels>
        <DashboardLayoutPanel Row="0" Column="0" SizeX="1" SizeY="1">
            <HeaderTemplate>
                <div>BusinessProcessFlow</div>
            </HeaderTemplate>
            <ContentTemplate>
                <DiagramComponent DataSource="@BusinessProcessFlow" Layout="LayoutType.HierarchicalTree" PanelWidth="@PanelWidth"/>
            </ContentTemplate>
        </DashboardLayoutPanel>
        <DashboardLayoutPanel Row="0" Column="1" SizeX="1" SizeY="1">
            <HeaderTemplate>
                <div>MindMapSource</div>
            </HeaderTemplate>
            <ContentTemplate>
                <DiagramComponent DataSource="@MindMapSource" Layout="LayoutType.MindMap" PanelWidth="@PanelWidth" />
            </ContentTemplate>
        </DashboardLayoutPanel>
        <DashboardLayoutPanel Row="0" Column="2" SizeX="1" SizeY="1">
            <HeaderTemplate>
                <div>RadialSource</div>
            </HeaderTemplate>
            <ContentTemplate>
                <DiagramComponent DataSource="@RadialSource" Layout="LayoutType.RadialTree" PanelWidth="@PanelWidth" />
            </ContentTemplate>
        </DashboardLayoutPanel>
    </DashboardLayoutPanels>
</SfDashboardLayout>
</div>

<style>
   .e-panel-header {
   background-color: rgba(0, 0, 0, .1);
   text-align: center;
   }

   .e-panel-content {
   text-align: center;
   margin-top: 10px;
   }
</style>


@code {
    double PanelWidth;
    // 1. Business Process Flow - Order Processing
    private List<DiagramComponent.DataModel> BusinessProcessFlow = new List<DiagramComponent.DataModel>()
    {
        new DiagramComponent.DataModel() { Id = "1", Content = "Board" },
        new DiagramComponent.DataModel() { Id = "2", ParentId = "1", Content = "General Manager" },
        new DiagramComponent.DataModel() { Id = "3", ParentId = "1", Content = "Human Resource Manager" },
        new DiagramComponent.DataModel() { Id = "4", ParentId = "2", Content = "Design Manager" },
        new DiagramComponent.DataModel() { Id = "5", ParentId = "3", Content = "Recruiting Team" },
        new DiagramComponent.DataModel() { Id = "6", ParentId = "3", Content = "Trainers" }
    };
    public List<DiagramComponent.DataModel> MindMapSource = new List<DiagramComponent.DataModel>()
    {
        new DiagramComponent.DataModel() { Id = "1", Content = "Creativity" },
        new DiagramComponent.DataModel() { Id = "2", ParentId = "1", Content = "Brainstorming" },
        new DiagramComponent.DataModel() { Id = "3", ParentId = "1", Content = "Complementing" },
        new DiagramComponent.DataModel() { Id = "4", ParentId = "2", Content = "Sessions" },
        new DiagramComponent.DataModel() { Id = "5", ParentId = "2", Content = "Complementing" },
        new DiagramComponent.DataModel() { Id = "6", ParentId = "3", Content = "Local" },
        new DiagramComponent.DataModel() { Id = "7", ParentId = "3", Content = "Remote" },
        new DiagramComponent.DataModel() { Id = "8", ParentId = "3", Content = "Individual" },
        new DiagramComponent.DataModel() { Id = "9", ParentId = "3", Content = "Teams" },
        new DiagramComponent.DataModel() { Id = "10", ParentId = "5", Content = "Ideas" },
        new DiagramComponent.DataModel() { Id = "11", ParentId = "5", Content = "Engagement" }
    };
    public List<DiagramComponent.DataModel> RadialSource = new List<DiagramComponent.DataModel>()
    {
        new DiagramComponent.DataModel() { Id = "1", Content = "Maria Anders (Managing Director)" },
        new DiagramComponent.DataModel() { Id = "2", ParentId = "1", Content = "Ana Trujillo (Project Manager)" },
        new DiagramComponent.DataModel() { Id = "3", ParentId = "1", Content = "Lino Rodri (Project Manager)" },
        new DiagramComponent.DataModel() { Id = "4", ParentId = "1", Content = "Philip Cramer (Project Manager)" },
        new DiagramComponent.DataModel() { Id = "5", ParentId = "2", Content = "Anto Moreno (Project Lead)" },
        new DiagramComponent.DataModel() { Id = "6", ParentId = "2", Content = "Elizabeth Roel (Project Lead)" },
        new DiagramComponent.DataModel() { Id = "7", ParentId = "3", Content = "Aria Cruz (Project Lead)" },
        new DiagramComponent.DataModel() { Id = "8", ParentId = "3", Content = "Eduardo Roel (Project Lead)" },
        new DiagramComponent.DataModel() { Id = "9", ParentId = "4", Content = "Daniel Tonini (Project Lead)" },
        new DiagramComponent.DataModel() { Id = "10", ParentId = "4", Content = "Liz Nixon (Project Lead)" }
    };

   protected override async Task OnAfterRenderAsync(bool firstRender)
   {
       if (firstRender)
       {
           PanelWidth = await JS.InvokeAsync<double>("getPanelWidth", "component-container");
       }
   }
}

Step 3: Implement JavaScript to Get the Panels Width
Define a JavaScript function to dynamically calculate and set the PanelWidth. Add this function within script tags in your “wwwroot/index.html” file.

window.getPanelWidth = function (divId) {
   let div = document.getElementById(divId);
   if (div) {
       let rect = div.getBoundingClientRect();
       return (rect.width / 3) - 5;
   }
   return null;
}

Explanation:

  • Dashboard Layout: Using SfDashboardLayout allows laying out multiple components in a grid-like system. We’re defining three panels, each with one DiagramComponent.
  • DiagramComponent: Each DiagramComponent is bound to a data source, which is defined in the @code block and specifies a hierarchy using Id and ParentId.
  • Dynamic Sizing: A JavaScript function updates the PanelWidth dynamically, and it’s invoked when the component is rendered (OnAfterRenderAsync).

Output:

image.png

You can download the complete working sample from here.

Conclusion:

We hope you enjoyed learning how to embed SfDiagramComponent inside panels of a SfDashboardLayout in Blazor

You can refer to our Blazor Diagram feature tour page to learn about its other groundbreaking features, documentation, and how to quickly get started with configuration specifications. You can also explore our Blazor Diagram example to understand how to create and manipulate data.

For current customers, our Blazor components are available on the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to evaluate our Blazor Diagram and Blazor components.

If you have any questions or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac,, or feedback portal. We are always happy to assist you!

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please  to leave a comment
Access denied
Access denied