Seamlessly Create a Mind Map Using the Blazor Diagram Component
Tags: blazor, webdev, diagram, ui
Published: 2023-03-09 05:51:22

---
title: Seamlessly Create a Mind Map Using the Blazor Diagram Component
published: true
date: 2023-03-08 11:00:00 UTC
tags: blazor, webdev, diagram, ui
canonical_url: https://www.syncfusion.com/blogs/post/mind-map-using-blazor-diagram.aspx
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5hcvm4jolz1h0bio42c2.png
---
Mind mapping is a powerful technique that helps you represent tasks, words, concepts, or items related to and arranged around a central idea. It is the perfect tool for strategy mapping and formulation, problem-solving, brainstorming, and conceptualizing, as it displays various ideas associated with a specific concept. Mind mapping boosts creativity, productivity, and teamwork.

The [Syncfusion Blazor Diagram component](https://www.syncfusion.com/blazor-components/blazor-diagram "Syncfusion Blazor Diagram Component") is a fast and powerful library for visualizing, creating and editing interactive diagrams.

In this article, we’ll see how to create a mind map diagram using the features of the Syncfusion Blazor Diagram component.

**Note:** Before proceeding, refer to the [getting started with the Blazor Diagram component](https://blazor.syncfusion.com/documentation/diagram/getting-started "Getting Started with Blazor Diagram component") documentation.

## Add the Blazor Diagram component to an application

First, add the Syncfusion Blazor Diagram component to a Blazor WebAssembly app:

1.Create a [Blazor WebAssembly app](https://blazor.syncfusion.com/documentation/getting-started/blazor-webassembly-dotnet-cli#create-a-blazor-webassembly-project-using-net-cli "Create a Blazor WebAssembly project using .NET CLI").
2.Then, install the NuGet package [Syncfusion.Blazor.Diagram](https://www.nuget.org/packages/Syncfusion.Blazor.Diagram/ "Syncfusion.Blazor.Diagram NuGet Package") in the app using the NuGet package manager.
3.Add the style resources through CDN or from the NuGet package in the **head** element of the **~/wwwroot/index.html** page.
```xml
<head>
    ………
    ………
    <link href="_content/Syncfusion.Blazor.Themes/bootstrap5.css" rel="stylesheet" />
    <script src="https://cdn.syncfusion.com/blazor/20.4.38/syncfusion-blazor.min.js" type="text/javascript"></script>
</head>
```

4.Open the **~/\_Imports.Blazor** file and import the **Blazor.Diagram** package in it.
```csharp
@using Syncfusion.Blazor.Diagram
```

5.In the **Program.cs** file, add the services required for the Syncfusion Blazor components using the **builder.Services.AddSyncfusionBlazor()** method.
```csharp
using Syncfusion.Blazor;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
. . . . .
. . . . .
builder.Services.AddSyncfusionBlazor();

await builder.Build().RunAsync();
```

6.Finally, add the Blazor Diagram component to the **Pages** folder in the **Razor** file.
```xml
<SfDiagramComponent @ref="@diagram" Width="100%" Height="600px" InteractionController="@DiagramInteractions.ZoomPan" NodeCreating="@NodeCreating" ConnectorCreating="@ConnectorCreating"/>
```

Thus, we have added the Syncfusion Blazor Diagram component to the Blazor WebAssembly app.

## Create a mind map diagram

Next, we are going to create a mind map diagram for business planning in the Blazor WebAssembly app.

### Step #1: Define the data source

We need a data source or node collection to populate the mind map on the diagram canvas.

Create a model class to construct the [data source](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Diagram.DataSourceSettings.html#Syncfusion_Blazor_Diagram_DataSourceSettings_DataSource "DataSource property of Blazor Diagram component"). Define the **Id** , **ParentId** , and **Branch** details in the mind map model class. Then, add a **fill** property to improve the UI’s design. You can specify your custom properties, if necessary.

Refer to the following code.

```csharp
// Create a model class for the data source.
public class MindMapItem
{
   public string Id { get; set; }
   public string Label { get; set; }
   public string ParentId { get; set; }
   public BranchType Branch { get; set; }
   public string Fill { get; set; }
}
```

Next, create a data source for the mind map and populate the records as nodes. Each record in the data source will be created as a separate node in the mind map layout.

Specify the parent and child relationship between the nodes.

Refer to the following code.

```csharp
//Defining the dataSource.
public List<MindMapItem> DataSource = new List<MindMapItem>()
{
   new MindMapItem(){Id="1",Label="Business Planning",ParentId ="",Branch= BranchType.Root, Fill="#034d6d" },
   new MindMapItem(){Id="2",Label= "Expectation",ParentId = "1",Branch= BranchType.Left,Fill= "#1b80c6" },
   new MindMapItem(){Id="3",Label= "Requirements", ParentId="1",Branch= BranchType.Right,Fill= "#1b80c6" },
   new MindMapItem(){Id="4",Label= "Marketing", ParentId="1",Branch= BranchType.Left,Fill= "#1b80c6" },
   new MindMapItem(){Id="5",Label= "Budgets",ParentId= "1",Branch= BranchType.Right,Fill= "#1b80c6" },
   new MindMapItem(){ Id="6", Label="Situation in Market", ParentId= "1", Branch = BranchType.Left, Fill= "#1b80c6" },
   new MindMapItem(){ Id="7", Label="Product Sales", ParentId= "2", Branch = BranchType.SubLeft, Fill= "#3dbfc9" },
   new MindMapItem() { Id = "8", Label= "Strategy", ParentId="2", Branch = BranchType.SubLeft, Fill="#3dbfc9" },
   new MindMapItem() { Id = "9", Label="Contacts", ParentId="2", Branch = BranchType.SubLeft, Fill="#3dbfc9" },
   new MindMapItem() { Id = "10", Label="Customer Groups", ParentId= "4", Branch = BranchType.SubLeft,Fill= "#3dbfc9" },
   new MindMapItem() { Id = "11", Label= "Branding", ParentId= "4", Branch = BranchType.SubLeft, Fill= "#3dbfc9" },
   new MindMapItem() { Id = "12", Label= "Advertising", ParentId= "4", Branch = BranchType.SubLeft, Fill= "#3dbfc9" },
   new MindMapItem() { Id = "13", Label= "Competitors", ParentId= "6", Branch = BranchType.SubLeft, Fill="#3dbfc9" },
   new MindMapItem() { Id = "14", Label="Location", ParentId="6", Branch = BranchType.SubLeft, Fill= "#3dbfc9" },
   new MindMapItem() { Id = "15", Label= "Director", ParentId= "3", Branch = BranchType.SubRight, Fill="#3dbfc9" },
   new MindMapItem() { Id = "16", Label="Accounts Department", ParentId= "3", Branch = BranchType.SubRight, Fill= "#3dbfc9" },
   new MindMapItem() { Id = "17", Label="Administration", ParentId= "3", Branch = BranchType.SubRight, Fill="#3dbfc9" },
   new MindMapItem() { Id = "18", Label= "Development", ParentId="3", Branch = BranchType.SubRight, Fill= "#3dbfc9" },
   new MindMapItem() { Id = "19", Label= "Estimation", ParentId= "5", Branch = BranchType.SubRight, Fill="#3dbfc9" },
   new MindMapItem() { Id = "20", Label= "Profit", ParentId= "5", Branch = BranchType.SubRight, Fill= "#3dbfc9" },
   new MindMapItem(){ Id="21", Label="Funds", ParentId= "5", Branch = BranchType.SubRight, Fill= "#3dbfc9" }
};
```

**Note:** For more details, refer to the documentation on how to create [Blazor Diagram nodes](https://blazor.syncfusion.com/documentation/diagram-component/nodes/nodes "Nodes in Blazor Diagram component") and [connectors](https://blazor.syncfusion.com/documentation/diagram-component/connectors/connectors "Connectors in Blazor Diagram component") with labels.

### Step #2: Binding the data source to the Diagram component

Bind the data source with the Blazor Diagram component, as shown in the following code.

```xml
<SfDiagramComponent>
    <DataSourceSettings ID="Id" ParentID="ParentId" DataSource="DataSource"></DataSourceSettings>
</SfDiagramComponent>
```

Once the data source is bound and the parent-child relationships are configured, define the layout type as **MindMap** to automatically arrange the nodes’ positions.

```xml
<Layout Type="LayoutType.MindMap" HorizontalSpacing="80" VerticalSpacing="30">
</Layout>
```

Finally, the Razor file will look like the following.

```csharp
@page "/"
@using Syncfusion.Blazor.Diagram
@using Syncfusion.Blazor.Diagram.Internal

<SfDiagramComponent @ref="@diagram" Height="690px" InteractionController="@DiagramInteractions.ZoomPan" NodeCreating="@NodeCreating" ConnectorCreating="@ConnectorCreating">
 <DataSourceSettings ID="Id" ParentID="ParentId" DataSource="DataSource"></DataSourceSettings>
  <Layout Type="LayoutType.MindMap" HorizontalSpacing="80" VerticalSpacing="30">
   <LayoutMargin Top="10" Bottom="10" Right="10" Left="10"></LayoutMargin>
  </Layout>
  <SnapSettings Constraints="SnapConstraints.None" />
</SfDiagramComponent>

@code
{
    SfDiagramComponent diagram;

    // Create a model class for the data source.
    public class MindMapItem
    {
        public string Id { get; set; }
        public string Label { get; set; }
        public string ParentId { get; set; }
        public BranchType Branch { get; set; }
        public string Fill { get; set; }
    }

    //Defining the dataSource.
    public List<MindMapItem> DataSource = new List<MindMapItem>()
    {
        new MindMapItem(){Id="1",Label="Business Planning",ParentId ="",Branch= BranchType.Root, Fill="#034d6d" },
        new MindMapItem(){Id="2",Label= "Expectation",ParentId = "1",Branch= BranchType.Left,Fill= "#1b80c6" },
        new MindMapItem(){Id="3",Label= "Requirements", ParentId="1",Branch= BranchType.Right,Fill= "#1b80c6" },
        new MindMapItem(){Id="4",Label= "Marketing", ParentId="1",Branch= BranchType.Left,Fill= "#1b80c6" },
        new MindMapItem(){Id="5",Label= "Budgets",ParentId= "1",Branch= BranchType.Right,Fill= "#1b80c6" },
        new MindMapItem(){ Id="6", Label="Situation in Market", ParentId= "1", Branch = BranchType.Left, Fill= "#1b80c6" },
        new MindMapItem(){ Id="7", Label="Product Sales", ParentId= "2", Branch = BranchType.SubLeft, Fill= "#3dbfc9" },
        new MindMapItem() { Id = "8", Label= "Strategy", ParentId="2", Branch = BranchType.SubLeft, Fill="#3dbfc9" },
        new MindMapItem() { Id = "9", Label="Contacts", ParentId="2", Branch = BranchType.SubLeft, Fill="#3dbfc9" },
        new MindMapItem() { Id = "10", Label="Customer Groups", ParentId= "4", Branch = BranchType.SubLeft,Fill= "#3dbfc9" },
        new MindMapItem() { Id = "11", Label= "Branding", ParentId= "4", Branch = BranchType.SubLeft, Fill= "#3dbfc9" },
        new MindMapItem() { Id = "12", Label= "Advertising", ParentId= "4", Branch = BranchType.SubLeft, Fill= "#3dbfc9" },
        new MindMapItem() { Id = "13", Label= "Competitors", ParentId= "6", Branch = BranchType.SubLeft, Fill="#3dbfc9" },
        new MindMapItem() { Id = "14", Label="Location", ParentId="6", Branch = BranchType.SubLeft, Fill= "#3dbfc9" },
        new MindMapItem() { Id = "15", Label= "Director", ParentId= "3", Branch = BranchType.SubRight, Fill="#3dbfc9" },
        new MindMapItem() { Id = "16", Label="Accounts Department", ParentId= "3", Branch = BranchType.SubRight, Fill= "#3dbfc9" },
        new MindMapItem() { Id = "17", Label="Administration", ParentId= "3", Branch = BranchType.SubRight, Fill="#3dbfc9" },
        new MindMapItem() { Id = "18", Label= "Development", ParentId="3", Branch = BranchType.SubRight, Fill= "#3dbfc9" },
        new MindMapItem() { Id = "19", Label= "Estimation", ParentId= "5", Branch = BranchType.SubRight, Fill="#3dbfc9" },
        new MindMapItem() { Id = "20", Label= "Profit", ParentId= "5", Branch = BranchType.SubRight, Fill= "#3dbfc9" },
        new MindMapItem(){ Id="21", Label="Funds", ParentId= "5", Branch = BranchType.SubRight, Fill= "#3dbfc9" }
    };

    private void NodeCreating(IDiagramObject obj)
    {
        Node node = obj as Node;
        MindMapItem data = node.Data is MindMapItem ? node.Data as MindMapItem : null;
        node.Height = 50;
        node.Width = 100;
        node.Shape = new BasicShape() { Type = NodeShapes.Basic, Shape = NodeBasicShapes.Ellipse };

        PointPort portLeft = new PointPort()
        {
            ID = "left",
            Offset = new DiagramPoint() { X = 0, Y = 0.5 },
            Height = 10,
            Width = 10,
        };

        PointPort portRight = new PointPort()
        {
            ID = "right",
            Offset = new DiagramPoint() { X = 1, Y = 0.5 },
            Height = 10,
            Width = 10,
        };

        if (data != null)
        {
            node.Style.Fill = data.Fill;
            node.Style.StrokeColor = data.Fill;
            node.Ports = new DiagramObjectCollection<PointPort>()
            {
                portLeft,portRight
            };
        }

        string content = data != null ? data.Label : "New Child";

        node.Annotations = new DiagramObjectCollection<ShapeAnnotation>()
        {
            new ShapeAnnotation()
            {
                Content = content,
                Style=new TextStyle(){Color="White",FontSize = 12,FontFamily="Segoe UI"},
                Offset=new DiagramPoint(){X=0.5,Y=0.5}
            }
        };
        node.Constraints &= ~NodeConstraints.Rotate;
    }

    private void ConnectorCreating(IDiagramObject obj)
    {
        Connector connector = obj as Connector;
        connector.Type = ConnectorSegmentType.Bezier;
        connector.Constraints = ConnectorConstraints.Default & ~ConnectorConstraints.Select;
        connector.Style = new ShapeStyle() { StrokeColor = "#4f4f4f", StrokeWidth = 1 };
        connector.TargetDecorator = new DecoratorSettings() { Shape = DecoratorShape.None };
        connector.SourceDecorator.Shape = DecoratorShape.None;
        Node sourceNode = diagram.GetObject(connector.SourceID) as Node;
        Node targetNode = diagram.GetObject(connector.TargetID) as Node;
        if (targetNode != null && targetNode.Data != null)
        {
            MindMapItem nodeInfo = (targetNode.Data as MindMapItem);
            if (nodeInfo.Branch == BranchType.Right || nodeInfo.Branch == BranchType.SubRight)
            {
                connector.SourcePortID = sourceNode.Ports[0].ID;
                connector.TargetPortID = targetNode.Ports[1].ID;
            }
            else if (nodeInfo.Branch == BranchType.Left || nodeInfo.Branch == BranchType.SubLeft)
            {
                connector.SourcePortID = sourceNode.Ports[1].ID;
                connector.TargetPortID = targetNode.Ports[0].ID;
            }
        }
    }
}
```

Refer to the following image.
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/02/Mind-Map-Diagram-Created-Using-Blazor-Diagram-Component.jpg" alt="Mind Map Diagram Created Using Blazor Diagram Component" style="width:100%">

  <figcaption>Mind Map Diagram Created Using Blazor Diagram Component</figcaption>

</figure>

We have created the mind map. Let’s now look at the user-friendly features available in the Blazor Diagram component.

## Interactivity using keyboard and mouse

We can interactively build mind map diagrams using mouse, touch, and keyboard interfaces. Let’s see how to do so with code examples.

### Quick commands

The Blazor Diagram component allows us to show frequently used commands as buttons near a selector. While creating a mind map, you can define actions like adding or removing a node as a command for a button and perform that action by just clicking the button.

Refer to the following code example.

```xml
<SfDiagramComponent ...... GetCustomTool="@GetCustomTool" SelectionSettings="@selectionSettings" SelectionChanging="OnSelectionChanging" Created="OnCreated">
  ........
  ........
</SfDiagramComponent>

@code
{
    SfDiagramComponent diagram;
    DiagramSelectionSettings selectionSettings = new DiagramSelectionSettings();
    DiagramObjectCollection<UserHandle> handles = new DiagramObjectCollection<UserHandle>();
    ........
    ........
    ........

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);
        if (firstRender)
        {
            UpdateHandle();
        }
    }

    private void UpdateHandle()
    {
        UserHandle deleteLeftHandle = AddHandle("DeleteRight", "delete", Direction.Right);

        UserHandle addRightHandle = AddHandle("AddLeft", "add", Direction.Left);

        UserHandle addLeftHandle = AddHandle("AddRight", "add", Direction.Right);

        UserHandle deleteRightHandle = AddHandle("DeleteLeft", "delete", Direction.Left);

        handles.Add(deleteLeftHandle);
        handles.Add(deleteRightHandle);
        handles.Add(addLeftHandle);
        handles.Add(addRightHandle);

        selectionSettings.UserHandles = handles;
    }

    private UserHandle AddHandle(string name, string path, Direction direction)
    {
        UserHandle handle = new UserHandle()
            {
                Name = name,
                Visible = true,
                Offset = 0.5,
                Side = direction,
                Margin = new DiagramThickness() { Top = 0, Bottom = 0, Left = 0, Right = 0 }
            };
        if (path == "delete")
        {
            handle.PathData = "M1.0000023,3 L7.0000024,3 7.0000024,8.75 C7.0000024,9.4399996 6.4400025,10 5.7500024,10 L2.2500024,10 C1.5600024,10 1.0000023,9.4399996 1.0000023,8.75 z M2.0699998,0 L5.9300004,0 6.3420029,0.99999994 8.0000001,0.99999994 8.0000001,2 0,2 0,0.99999994 1.6580048,0.99999994 z";
        }
        else
        {
            handle.PathData = "M4.0000001,0 L6,0 6,4.0000033 10,4.0000033 10,6.0000033 6,6.0000033 6,10 4.0000001,10 4.0000001,6.0000033 0,6.0000033 0,4.0000033 4.0000001,4.0000033 z";
        }
        return handle;
    }

    private void OnSelectionChanging(SelectionChangingEventArgs args)
    {
        if (args.NewValue.Count > 0)
        {
            if (args.NewValue[0] is Node && (args.NewValue[0] as Node).Data != null)
            {
                BranchType type = ((args.NewValue[0] as Node).Data as MindMapItem).Branch;
                if (type == BranchType.Root)
                {
                    selectionSettings.UserHandles[0].Visible = false;
                    selectionSettings.UserHandles[1].Visible = false;
                    selectionSettings.UserHandles[2].Visible = true;
                    selectionSettings.UserHandles[3].Visible = true;
                }
                else if (type == BranchType.Left || type == BranchType.SubLeft)
                {
                    selectionSettings.UserHandles[0].Visible = false;
                    selectionSettings.UserHandles[1].Visible = true;
                    selectionSettings.UserHandles[2].Visible = true;
                    selectionSettings.UserHandles[3].Visible = false;
                }
                else if (type == BranchType.Right || type == BranchType.SubRight)
                {
                    selectionSettings.UserHandles[0].Visible = true;
                    selectionSettings.UserHandles[1].Visible = false;
                    selectionSettings.UserHandles[2].Visible = false;
                    selectionSettings.UserHandles[3].Visible = true;
                }
            }
        }
    }
    // Method to customize the tool.
    public InteractionControllerBase GetCustomTool(DiagramElementAction action, string id)
    {
        InteractionControllerBase tool = null;
        if (id == "AddLeft")
        {
            tool = new AddRightTool(diagram);
        }
        else if (id == "AddRight")
        {
            tool = new AddLeftTool(diagram);
        }
        else
        {
            tool = new DeleteTool(diagram);
        }
        return tool;
    }

    // Custom tool to add the node.
    public class AddLeftTool : DragController
    {
        SfDiagramComponent diagram;
        public AddLeftTool(SfDiagramComponent Diagram) : base(Diagram)
        {
            diagram = Diagram;
        }
        public override async void OnMouseDown(DiagramMouseEventArgs args)
        {
            int newChildID = diagram.Nodes.Count + 1;
            string newchildColor = "";
            BranchType type = (diagram.SelectionSettings.Nodes[0].Data as MindMapItem).Branch;
            BranchType childType = BranchType.Left;

            switch (type.ToString())
            {
                case "Root":
                    childType = BranchType.Left;
                    break;
                case "Left":
                    childType = BranchType.SubLeft;
                    break;
                case "SubLeft":
                    childType = BranchType.SubLeft;
                    break;
            }

            if (diagram.SelectionSettings.Nodes[0].Style.Fill == "#034d6d")
            {
                newchildColor = "#1b80c6";
            }
            else
            {
                newchildColor = "#3dbfc9";
            }

            MindMapItem childNode = new MindMapItem ()
            {
               Id = newChildID.ToString(),
               ParentId = (diagram.SelectionSettings.Nodes[0].Data as MindMapItem).Id,
               Fill = newchildColor,
               Branch = childType,
               Label = "New Child"
            };
            diagram.BeginUpdate();
            await UpdatePortConnection(childNode, diagram);
            await diagram.EndUpdate();
            MindmapData.Add(childNode);
            diagram.ClearSelection();
            base.OnMouseDown(args);
            diagram.Select(new ObservableCollection<IDiagramObject>() { diagram.Nodes[diagram.Nodes.Count - 1] });
            diagram.StartTextEdit(diagram.Nodes[diagram.Nodes.Count - 1]);
            this.InAction = true;
        }
    }
    private static async Task UpdatePortConnection(MindMapItem childNode, SfDiagramComponent diagram)
    {
        Node node = new Node()
        {
           Data = childNode,
        };
        Connector connector = new Connector()
        {
           TargetID = node.ID,
           SourceID = diagram.SelectionSettings.Nodes[0].ID
        };
        await diagram.AddDiagramElements(new DiagramObjectCollection<NodeBase>() { node, connector });
        Node sourceNode = diagram.GetObject(connector.SourceID) as Node;
        Node targetNode = diagram.GetObject(connector.TargetID) as Node;
        if (targetNode != null && targetNode.Data != null)
        {
            MindMapItem nodeInfo = (targetNode.Data as MindMapItem);
            if (nodeInfo.Branch == BranchType.Right || nodeInfo.Branch == BranchType.SubRight)
            {
                connector.SourcePortID = sourceNode.Ports[0].ID;
                connector.TargetPortID = targetNode.Ports[1].ID;
            }
            else if (nodeInfo.Branch == BranchType.Left || nodeInfo.Branch == BranchType.SubLeft)
            {
                connector.SourcePortID = sourceNode.Ports[1].ID;
                connector.TargetPortID = targetNode.Ports[0].ID;
            }
        }
        await diagram.DoLayout();
    }
    // Custom tool to add the node.
    public class AddRightTool : DragController
    {
        SfDiagramComponent diagram;
        public AddRightTool(SfDiagramComponent Diagram) : base(Diagram)
        {
            diagram = Diagram;
        }
        public override async void OnMouseDown(DiagramMouseEventArgs args)
        {
            int newChildID = diagram.Nodes.Count + 1;
            string newchildColor = "";
            BranchType type = (diagram.SelectionSettings.Nodes[0].Data as MindMapItem).Branch;
            BranchType childType = BranchType.Left;

            switch (type.ToString())
            {
                case "Root":
                    childType = BranchType.Right;
                    break;
                case "Right":
                    childType = BranchType.SubRight;
                    break;
                case "SubRight":
                    childType = BranchType.SubRight;
                    break;
            }

            if (diagram.SelectionSettings.Nodes[0].Style.Fill == "#034d6d")
            {
                newchildColor = "#1b80c6";
            }
            else
            {
                newchildColor = "#3dbfc9";
            }

            MindMapItem childNode = new MindMapItem ()
            {
                Id = newChildID.ToString(),
                ParentId = (diagram.SelectionSettings.Nodes[0].Data as MindMapItem).Id,
                Fill = newchildColor,
                Branch = childType,
                Label = "New Child"
            };
            diagram.BeginUpdate();
            await UpdatePortConnection(childNode, diagram);
            await diagram.EndUpdate();
            MindmapData.Add(childNode);
            diagram.ClearSelection();
            base.OnMouseDown(args);
            diagram.Select(new ObservableCollection<IDiagramObject>() { diagram.Nodes[diagram.Nodes.Count - 1] });
            diagram.StartTextEdit(diagram.Nodes[diagram.Nodes.Count - 1]);
            this.InAction = true;
        }
    }

    public class DeleteTool : DragController
    {
        SfDiagramComponent sfDiagram;
        Node deleteObject = null;
        public DeleteTool(SfDiagramComponent Diagram) : base(Diagram)
        {
            sfDiagram = Diagram;
        }
        public override void OnMouseDown(DiagramMouseEventArgs args)
        {
            deleteObject = (sfDiagram.SelectionSettings.Nodes[0]) as Node;
        }
        public override void OnMouseUp(DiagramMouseEventArgs args)
        {
            if (deleteObject != null)
            {
                sfDiagram.BeginUpdate();
                RemoveData(deleteObject, sfDiagram);
                sfDiagram.Nodes.Remove(deleteObject);
                _ = sfDiagram.EndUpdate();
                _ = sfDiagram.RefreshDataSource();
            }
            base.OnMouseUp(args);
            this.InAction = true;
        }
    }

    private static void RemoveData(Node node, SfDiagramComponent diagram)
    {
        if (node.OutEdges.Count > 0)
        {
            for (int i = 0; i < node.OutEdges.Count; i++)
            {
                Connector connector = diagram.GetObject(node.OutEdges[i]) as Connector;
                Node targetnode = diagram.GetObject(connector.TargetID) as Node;
                if (targetnode.OutEdges.Count > 0)
                {
                    RemoveData(targetnode, diagram);
                }
                else
                {
                    MindmapData.Remove(targetnode.Data as MindMapItem);
                }
            }
            MindmapData.Remove(node.Data as MindMapItem);
        }
        else
        {
            MindmapData.Remove(node.Data as MindMapItem);
        }
    }
```
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/02/Quickly-Create-a-Mind-Map-Using-Commands-in-Blazor-Diagram-Component.gif" alt="Quickly Create a Mind Map Using Commands in Blazor Diagram Component" style="width:100%">

  <figcaption>Quickly Create a Mind Map Using Commands in Blazor Diagram Component</figcaption>

</figure>

### Shortcut keys

Shortcut keys help us quickly create mind map diagrams. You can specify the action that should be executed based on the specific key gestures.

For example, you can specify the **Tab** key to add a new node to the right, **Shift+Tab** to the left, and the **Delete** key to delete a node.

Refer to the following code example.

```xml
<SfDiagramComponent @ref="@diagram" ........>
    ........
    ........
    ........

    <CommandManager Commands="commands" Execute="@ExecuteCommand" CanExecute="@CanExecute" />
</SfDiagramComponent>

@code
{
    SfDiagramComponent diagram;
    DiagramObjectCollection<KeyboardCommand> commands;
    ........
    ........
    ........
    ........
    protected override void OnInitialized()
    {
    ........
    ........

        commands = new DiagramObjectCollection<KeyboardCommand>()
        {
            CreateCustomCommand("AddLeftChild",DiagramKeys.Tab,ModifierKeys.None),
            CreateCustomCommand("AddRightChild",DiagramKeys.Tab,ModifierKeys.Shift),
            CreateCustomCommand("DeleteChild",DiagramKeys.Delete,ModifierKeys.None),
        };
    }

    // Method to determine whether this command can execute or not.
    public void CanExecute(CommandKeyArgs args)
    {
        args.CanExecute = true;
    }
    
    // Method to execute the custom command.
    public void ExecuteCommand(CommandKeyArgs obj)
    {
        Node node = (diagram.SelectionSettings.Nodes[0]) as Node;
        if(node != null)
        {
            BranchType type = (node.Data as MindMapItem).Branch;
            if(type == BranchType.Root)
            {
                switch (obj.Name)
                {
                    case "AddLeftChild":
                        _ = this.AddLeftChild();
                        break;
                    case "AddRightChild":
                        _ = this.AddRightChild();
                        break;
                }                
            }
            else
            {
                switch (obj.Name)
                {
                    case "AddRightChild":
                    case "AddLeftChild":
                        _ = (type == BranchType.Left || type == BranchType.SubLeft) ? this.AddLeftChild() : this.AddRightChild();
                        break;
                    case "DeleteChild":
                        _ = this.DeleteChild();
                        break;
                }
            }
        }
    }
    
    // Method to create custom command.
    private KeyboardCommand CreateCustomCommand(string name, DiagramKeys key, ModifierKeys modifierkey)
    {
        KeyboardCommand command = new KeyboardCommand()
        {
           Name = name,
           Gesture = new KeyGesture() { Key = key, Modifiers = modifierkey }
        };
        return command;
    }

    private async Task AddLeftChild()
    {

        int newChildID = diagram.Nodes.Count + 1;
        string newchildColor = "";
        BranchType type = (diagram.SelectionSettings.Nodes[0].Data as MindMapItem).Branch;
        BranchType childType = BranchType.Left;

        switch (type.ToString())
        {
            case "Root":
                childType = BranchType.Left;
                break;
            case "Left":
            case "SubLeft":
                childType = BranchType.SubLeft;
                break;
        }

        if (diagram.SelectionSettings.Nodes[0].Style.Fill == "#034d6d")
        {
            newchildColor = "#1b80c6";
        }
        else
        {
            newchildColor = "#3dbfc9";
        }

        MindMapItem childNode = new MindMapItem()
        {
            Id = newChildID.ToString(),
            ParentId = (diagram.SelectionSettings.Nodes[0].Data as MindMapItem).Id,
            Fill = newchildColor,
            Branch = childType,
            Label = "New Child"
        };
        diagram.BeginUpdate();
        await UpdatePortConnection(childNode, diagram);
        await diagram.EndUpdate();
        MindmapData.Add(childNode);
        diagram.ClearSelection();
        diagram.Select(new ObservableCollection<IDiagramObject>() { diagram.Nodes[diagram.Nodes.Count - 1] });
        diagram.StartTextEdit(diagram.Nodes[diagram.Nodes.Count - 1]);
    }

    private async Task AddRightChild()
    {
        int newChildID = diagram.Nodes.Count + 1;
        string newchildColor = "";
        BranchType type = (diagram.SelectionSettings.Nodes[0].Data as MindMapItem).Branch;
        BranchType childType = BranchType.Left;

        switch (type.ToString())
        {
            case "Root":
                childType = BranchType.Right;
                break;
            case "Right":
            case "SubRight":
                childType = BranchType.SubRight;
                break;
        }

        if (diagram.SelectionSettings.Nodes[0].Style.Fill == "#034d6d")
        {
            newchildColor = "#1b80c6";
        }
        else
        {
            newchildColor = "#3dbfc9";
        }

        MindMapItem childNode = new MindMapItem()
        {
            Id = newChildID.ToString(),
            ParentId = (diagram.SelectionSettings.Nodes[0].Data as MindMapItem).Id,
            Fill = newchildColor,
            Branch = childType,
            Label = "New Child"
        };
        diagram.BeginUpdate();
        await UpdatePortConnection(childNode, diagram);
        await diagram.EndUpdate();
        MindmapData.Add(childNode);
        diagram.ClearSelection();
        diagram.Select(new ObservableCollection<IDiagramObject>() { diagram.Nodes[diagram.Nodes.Count - 1] });
        diagram.StartTextEdit(diagram.Nodes[diagram.Nodes.Count - 1]);
    }

    private async Task DeleteChild()
    {
        Node deleteObject = (diagram.SelectionSettings.Nodes[0]) as Node;
        if (deleteObject != null)
        {
            BranchType type = (deleteObject.Data as MindMapItem).Branch;
            if (type != BranchType.Root)
            {
                diagram.BeginUpdate();
                RemoveData(deleteObject, diagram);
                diagram.Nodes.Remove(deleteObject);
                _ = diagram.EndUpdate();
                _ = diagram.RefreshDataSource();
            }
        }
    }

```
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/02/Interactively-Creating-a-Mind-Map-Diagram-Using-Keyboard-Shortcut-Keys-in-the-Blazor-Diagram-Component.gif" alt="Interactively Creating a Mind Map Diagram Using Keyboard Shortcut Keys in the Blazor Diagram Component" style="width:100%">

  <figcaption>Interactively Creating a Mind Map Diagram Using Keyboard Shortcut Keys in the Blazor Diagram Component</figcaption>

</figure>

## Expand and collapse child nodes

You can expand and collapse the child nodes in the mind map using the **ExpandIcon** and **CollapseIcon** properties.

Refer to the following code example.

```csharp
private void NodeCreating(IDiagramObject obj)
{
   Node node = obj as Node;
   ........
   ........
   ........

    node.ExpandIcon = new DiagramExpandIcon()
    {
       Shape = DiagramExpandIcons.Minus,
       Height = 15,
       Width = 15,
       CornerRadius = 10,
       OffsetX = (branch == BranchType.Root) ? 0.5 : (branch == BranchType.Right || branch == BranchType.SubRight) ? 0 : 1,
       OffsetY = (branch == BranchType.Root) ? 1 : (branch == BranchType.Right || branch == BranchType.SubRight) ? 0.5 : 0.5
     };
     node.CollapseIcon = new DiagramCollapseIcon()
     {
          Shape = DiagramCollapseIcons.Plus,
          Height = 15,
          Width = 15,
          CornerRadius = 10,
          OffsetX = (branch == BranchType.Root) ? 0.5 : (branch == BranchType.Right || branch == BranchType.SubRight) ? 0 : 1,
          OffsetY = (branch == BranchType.Root) ? 1 : (branch == BranchType.Right || branch == BranchType.SubRight) ? 0.5 : 0.5
      };
}
```
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/02/Expanding-and-Collapsing-Nodes-in-Blazor-Mind-Map-Diagram.gif" alt="Expanding and Collapsing Nodes in Blazor Mind Map Diagram" style="width:100%">

  <figcaption>Expanding and Collapsing Nodes in Blazor Mind Map Diagram</figcaption>

</figure>

## Drag and drop

You can edit the mind map tree structure by dragging the nodes to the required destination. To allow this, add the following code to the Blazor Diagram component’s **drop** method.

```xml
<SfDiagramComponent ........ DragDrop="@Drop">
    ........
    ........
    ........
</SfDiagramComponent>

@code
{
    SfDiagramComponent diagram;
    ........
    ........
    ........

    private async Task Drop(DropEventArgs args)
    {
        diagram.BeginUpdate();
        diagram.StartGroupAction();
        Node element = (args.Element as DiagramSelectionSettings).Nodes[0] as Node;
        Node targetNode = args.Target as Node;
        bool isParent = false;
        List<string> edges = element.OutEdges;
        if (edges != null && edges.Count > 0)
        {
            for (int i = 0; i < edges.Count; i++)
            {
                Connector connector = GetConnector(diagram.Connectors, edges[i]);
                Node childNode = GetNode(diagram.Nodes, connector.TargetID);
                if (targetNode != null && targetNode.ID == childNode.ID)
                    isParent = true;
            }
        }
        if (!isParent)
        {
            Connector connector = GetConnector(diagram.Connectors, element.InEdges[0]);
            Node childNode = GetNode(diagram.Nodes, connector.TargetID);
            diagram.BeginUpdate();
            connector.SourceID = targetNode.ID;
            (element.Data as MindMapItem).Branch = (targetNode.Data as MindMapItem).Branch;
            GetOrientation(targetNode, connector);
            if (edges != null && edges.Count > 0)
            {
                UpdateLayout(edges, targetNode);
            }
            _ = diagram.EndUpdate();
            await diagram.DoLayout();
        }
        else { _ = diagram.DoLayout(); }
        diagram.EndGroupAction();
        _ = diagram.EndUpdate();
    }

    private void UpdateLayout(List<string> edges, Node Target)
    {
        for (int i = 0; i < edges.Count; i++)
        {
            Connector childconnector = GetConnector(diagram.Connectors, edges[i]);
            Node node = GetNode(diagram.Nodes, childconnector.TargetID);
            (node.Data as MindMapItem).Branch = (Target.Data as MindMapItem).Branch;
            List<string> childEdges = node.OutEdges;
            if (childEdges != null && childEdges.Count > 0)
            {
                UpdateLayout(childEdges, Target);
            }
            GetOrientation(Target, childconnector);
        }
    }
    private void GetOrientation(Node node, Connector connector)
    {
        BranchType branch = (node.Data as MindMapItem).Branch;
        if (branch == BranchType.Left || branch == BranchType.SubLeft)
        {
            connector.SourcePortID = "right";
            connector.TargetPortID = "left";
        }
        else if (branch == BranchType.Right || branch == BranchType.SubRight)
        {
            connector.SourcePortID = "left";
            connector.TargetPortID = "right";
        }
    }

    private Connector GetConnector(DiagramObjectCollection<Connector> diagramConnectors, string name)
    {
        for (int i = 0; i < diagramConnectors.Count; i++)
        {
            if (diagramConnectors[i].ID == name)
            {
                return diagramConnectors[i];
            }
        }
        return null;
    }

    private Node GetNode(DiagramObjectCollection<Node> diagramNodes, string name)
    {
        for (int i = 0; i < diagramNodes.Count; i++)
        {
            if (diagramNodes[i].ID == name)
            {
                return diagramNodes[i];
            }
        }
        return null;
    }

```
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/02/Dragging-and-Dropping-Nodes-in-the-Blazor-Mind-Map.gif" alt="Dragging and Dropping Nodes in the Blazor Mind Map" style="width:100%">

  <figcaption>Dragging and Dropping Nodes in the Blazor Mind Map</figcaption>

</figure>

## Shape customization

We can easily customize the appearance of each level of nodes by adding backgrounds, border styles, and text styles and visualizing them with a custom UI design.

The **NodeCreating** and **ConnectorCreating** methods help specify the custom shape and style for each node and connector based on its level value.

Refer to the following code example.

```csharp
private void NodeCreating(IDiagramObject obj)
{
   Node node = obj as Node;
   MindMapItem data = node.Data is MindMapItem? node.Data as MindMapItem: null;
   node.Height = 50;
   node.Width = 120;
   if (data is MindMapItem && data.Branch == BranchType.Root)
   {
       node.Shape = new PathShape() { Type = NodeShapes.Path, Data = "M55.7315 17.239C57.8719 21.76 54.6613 27.788 47.1698 26.0787C46.0997 32.309 33.2572 35.323 28.9764 29.2951C25.7658 35.323 10.7829 33.816 10.7829 26.0787C3.29143 30.802 -0.989391 20.253 2.22121 17.239C-0.989317 14.2249 2.22121 6.68993 10.7829 8.39934C13.9935 -0.845086 25.7658 -0.845086 28.9764 5.18301C32.187 0.661909 45.0294 0.661908 47.1698 8.39934C52.5209 5.18301 60.0123 12.7179 55.7315 17.239Z" };
   }
   else if (data is MindMapItem && (data.Branch == BranchType.Left || data.Branch == BranchType.Right))
   {
      node.Shape = new BasicShape() { Type = NodeShapes.Basic, Shape = NodeBasicShapes.Rectangle };
   }
   else
       node.Shape = new BasicShape() { Type = NodeShapes.Basic, Shape = NodeBasicShapes.Ellipse }; ........
        
        ........
        ........
        ........

}

private void ConnectorCreating(IDiagramObject obj)
{
    Connector connector = obj as Connector;
    connector.Type = ConnectorSegmentType.Bezier;
    connector.Constraints = ConnectorConstraints.Default & ~ConnectorConstraints.Select;
    connector.TargetDecorator = new DecoratorSettings() { Shape = DecoratorShape.None };
    connector.SourceDecorator.Shape = DecoratorShape.None;
    Node sourceNode = diagram.GetObject(connector.SourceID) as Node;
    if (sourceNode != null && sourceNode.Data is MindMapItem)
    {
       MindMapItem data = sourceNode.Data as MindMapItem;
       if (data is MindMapItem && data.Branch == BranchType.Root)
       {
           connector.Style = new ShapeStyle() { StrokeColor = "#8E44AD", StrokeWidth = 5 };
       }data
       else if (data is MindMapItem && (data.Branch == BranchType.Left || data.Branch == BranchType.Right))
       {
           connector.Style = new ShapeStyle() { StrokeColor = "#3498DB", StrokeWidth = 5 };
       }
       else
           connector.Style = new ShapeStyle() { StrokeColor = "#3dbfc9", StrokeWidth = 5 };
    }

    ........
    ........
    ........

}
```
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/02/Customizing-Node-Shapes-in-a-Blazor-Mind-Map.jpg" alt="Customizing Node Shapes in a Blazor Mind Map" style="width:100%">

  <figcaption>Customizing Node Shapes in a Blazor Mind Map</figcaption>

</figure>

## Spacing and margin

We can adjust the space between each level horizontally and vertically and define a margin around the mind map diagram.

Refer to the following code example.

```xml
<SfDiagramComponent @ref="@diagram" Height="690px" InteractionController="@DiagramInteractions.ZoomPan" NodeCreating="@NodeCreating" ConnectorCreating="@ConnectorCreating">
 <DataSourceSettings ID="Id" ParentID="ParentId" DataSource="DataSource"></DataSourceSettings>
 <Layout Type="LayoutType.MindMap" HorizontalSpacing="90" VerticalSpacing="50">
   <LayoutMargin Top="10" Bottom="10" Right="10" Left="10"></LayoutMargin>
 </Layout>
 <SnapSettings Constraints="SnapConstraints.None"/>
</SfDiagramComponent>
```
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/02/Customizing-Node-Shapes-in-a-Blazor-Mind-Map-1.jpg" alt="Customizing Node Spacing in Blazor Mind Map" style="width:100%">

  <figcaption>Customizing Node Spacing in Blazor Mind Map</figcaption>

</figure>

## Zooming and panning

Viewing a large mind map on a small screen can be challenging. To solve this, we’ll use the zooming and panning features to get a detailed view.

You can zoom in and out of the mind map diagram using the **Ctrl + mouse wheel** shortcut key.

Refer to the following code example to enable zooming and panning support in the Blazor Diagram component.

```xml
<SfDiagramComponent @ref="@Diagram" InteractionController="@DiagramInteractions.ZoomPan">
    ………..
    ………..
</SfDiagramComponent>
```

## Exporting

You can easily export the mind map to different image formats such as PNG, JPEG, and SVG. Refer to the following code example.

```csharp
@using Syncfusion.Blazor.Diagram

<input type="button" @onclick="@ExportBase64" />
<input type="button" @onclick="@ExportPng" />
<SfDiagramComponent Height="600px" @ref="@diagram">
</SfDiagramComponent>

@code {
    SfDiagramComponent diagram;

    //To export the diagram as a base64 string.
    private async Task ExportBase64()
    {
        DiagramExportSettings export = new DiagramExportSettings();
        string[] base64 = await diagram.ExportAsync(DiagramExportFormat.PNG, export);
    }

    //To export the diagram as pngPNG.
    private async Task ExportPng()
    {
        DiagramExportSettings export = new DiagramExportSettings();
        await diagram.ExportAsync("diagram", DiagramExportFormat.PNG, export);
    }
}

```

**Note:** For complete details, refer to the [creating a mind map using the Blazor Diagram component documentation](https://blazor.syncfusion.com/documentation/diagram/layout/mind-map "Mind Map Layout in Blazor Diagram Component").

## GitHub reference

Check out the demo for creating a mind map using the Blazor Diagram component in a WebAssembley app on [GitHub](https://github.com/SyncfusionExamples/Blazor-Diagram-Examples/tree/master/Samples/AutomaticLayout/Mindmap%20diagram/WASM "Creating mind map using the Syncfusion Blazor Diagram GitHub Demo") or [Syncfusion’s website](https://blazor.syncfusion.com/demos/diagramcomponent/mindmap?theme=bootstrap5 "Example of Mind Map Layout in Blazor Diagram Component").

## Conclusion

Thanks for reading! We have learned how to create and customize a mind map using the [Syncfusion Blazor Diagram component](https://www.syncfusion.com/blazor-components/blazor-diagram/blazor-library-mind-map "Syncfusion Blazor Diagram Component"). You can also create flowcharts, organizational charts, and more with the Diagram component. Try it out and leave your feedback in the comments section.

For existing customers, the new version of Essential Studio is available for download from the [License and Downloads](https://www.syncfusion.com/account/downloads "License and downloads page of Essential Studio") page. If you are not a Syncfusion customer, you can try our 30-day [free trial](https://www.syncfusion.com/downloads "Free evaluation of the Syncfusion Essential Studio") to check out our available features.

For questions, you can contact us through our [support forum](https://www.syncfusion.com/forums "Syncfusion Support Forum"), [support portal](https://support.syncfusion.com/ "Syncfusion Support Portal"), or [feedback portal](https://www.syncfusion.com/feedback "Syncfusion Feedback Portal"). We are always happy to assist you!

## Related blogs

- [Building an Application for Microsoft Teams with Blazor](https://www.syncfusion.com/blogs/post/building-an-application-for-microsoft-teams-with-blazor.aspx "Blog: Building an Application for Microsoft Teams with Blazor")
- [Task Scheduling and Markers in Blazor Gantt Chart](https://www.syncfusion.com/blogs/post/task-scheduling-and-markers-in-blazor-gantt-chart.aspx "Blog: Task Scheduling and Markers in Blazor Gantt Chart")
- [Implement User Tagging in Blazor Rich Text Editor with Mention Component](https://www.syncfusion.com/blogs/post/user-tagging-in-blazor-rich-text-editor.aspx "Blog: Implement User Tagging in Blazor Rich Text Editor with Mention Component")
- [Azure Maps as a Source to Syncfusion Maps](https://www.syncfusion.com/blogs/post/azure-maps-as-a-source-to-syncfusion-maps.aspx "Blog: Azure Maps as a Source to Syncfusion Maps")