Create Flowchart without specifying coordinates in WPF | Syncfusion Blogs
Detailed Blog page Skeleton loader
Creating flow chart

Providing coordinates to every element in the creation of a flowchart is tedious. To help you avoid this tiresome process, the Syncfusion WPF Diagram library does it with just a few configuration settings. In this blog, I will walk you through the creation of a flowchart using the Syncfusion Diagram library without manually specifying coordinates, and instead using the built-in flowchart automatic layout algorithm.

A flowchart is a diagrammatic representation of a process, workflow, system, or computer algorithm. Flowcharts use various symbols to illustrate different types of actions and these symbols are connected by arrows showing the flow direction of the process.

Common flowchart symbols

Different flowchart symbols have different meanings that are used to represent specific states in a flowchart. The following table describes the most common flowchart symbols.

SymbolNameDescription
Terminator - Flow Chart ShapeTerminator/Start/EndIndicates the beginning or end of a process.
Data - Flow Chart ShapeDataIndicates data input or output for a process.
Process - Flow Chart ShapeProcessRepresents an operation or set of operations and data manipulations.
Decision - Flow Chart ShapeDecisionShows a branching point where a decision is made to choose one of two paths.
Document - Flow Chart ShapeDocumentRepresents a single document or report in the process.
SubProcess - Flow Chart ShapeSubprocess/Predefined processRepresents a sequence of actions that combine to perform a specific task that is defined elsewhere.
Database - Flow Chart ShapeDatabaseRepresents a collection of information that allows for searching, sorting, and filtering.
DataStorage - Flow Chart ShapeData storageRepresents a step where data is stored within a process.
Manual Input - Flow Chart ShapeManual inputRepresents the manual input of data into a field or step in a process.
Manual Operation - Flow Chart ShapeManual operationRepresents an operation in a process that must be done manually, not automatically.
Preparation - Flow Chart ShapePreparationRepresents a setup or initialization process for another step in the process.
On Page Reference - Flow Chart ShapeOn-page referenceRepresents a pair of labeled connectors used to link long or confusing lines in a flowchart.
Off Page Reference - Flow Chart ShapeOff-page referenceRepresents a labeled connector used to link two flowcharts on different pages.
Multi Document - Flow Chart ShapeMultidocumentRepresents multiple documents or reports in a process.
Flow Line - Flow Chart ShapeFlowlineRepresents a direction of flow from one step to another.

Getting started with a simple flowchart

Let’s create a simple flowchart like the one shown in the following image using the Syncfusion Diagram library. The Diagram control has a built-in high-performance layout algorithm to arrange every flowchart symbol automatically, and it supports visualizing a flowchart from a data source.Flowchart Built with the Diagram Control’s Automatic Layout Algorithm

Flowchart Built with the Diagram Control’s Automatic Layout Algorithm

  1. Create a WPF application and refer to our help documentation to learn more about the dependent assembly references and namespaces required to integrate the Diagram control.
  2. Define the flowchart information as a data source. The information should contain the flowchart symbol shape data, a short description about each action, and the symbol width and height.
  3. Create an instance of the Diagram control.
  4. Create an instance of FlowchartDataSourceSettings with the data mapping configuration and assign it to the DataSourceSettings property of the created Diagram instance.
  5. Configure the LayoutManager with flowchart layout settings to arrange the flowchart elements automatically. The settings will configure the flowchart orientation, horizontal and vertical spacing between symbols, and decision output branch directions.

In the Diagram control, the different shapes shown in the previous screenshot represent nodes, and lines represent connectors. The text inside the shapes and lines represent annotations. The following code example includes all the previous steps. The complete sample is available from the Syncfusion website.

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        //Initialize new instance of Diagram control
        SfDiagram diagram = new SfDiagram();
        //Initialize Nodes with Observable Collection of NodeViewModel.
        diagram.Nodes = new NodeCollection();
        //Initialize Connectors with Observable Collection of ConnectorViewModel
        diagram.Connectors = new ConnectorCollection();
        RootGrid.Children.Add(diagram);
        // Initialize DataSourceSettings for SfDiagram
        diagram.DataSourceSettings = new FlowchartDataSourceSettings()
        {
            //Set the unique field from data source
            Id = "Id",
            //Field used to identify the previous flowchart element
            ParentId = "ParentId",
            //Define the flowchart information
            DataSource = GetData(),
            //Field used to identify the line text
            ConnectorTextMapping = "LineText",
            //Field used to identify the symbol description
            ContentMapping = "Description",
            //Field used to identify the symbol shape
            ShapeMapping = "Shape",
            //Field used to identify the symbol width
            WidthMapping = "Width",
            //Field used to identify the symbol height
            HeightMapping = "Height"
        };

        // Initialize LayoutSettings for SfDiagram
        diagram.LayoutManager = new LayoutManager()
        {
            Layout = new FlowchartLayout()
            {
                //Set the flowchart flow direction
                Orientation = FlowchartOrientation.TopToBottom,
                //Set the decision yes branch direction
                YesBranchDirection = BranchDirection.LeftInFlow,
                //Set the decision no branch direction
                NoBranchDirection = BranchDirection.RightInFlow,
                //Set the custom yes branch values
                YesBranchValues = new List<string> { "Yes", "Existing" },
                //Set the custom no branch values
                NoBranchValues = new List<string> { "No", "New" },
                //Set the horizontal spacing between node
                HorizontalSpacing = 60,
                //Set the vertical spacing between node
                VerticalSpacing = 40,
                Margin = new Thickness(10),
            },
        };
    }
    /// <summary>
    /// Method to Get Data for DataSource
    /// </summary>
    /// <param name="data"></param>
    private SymbolInfoCollection GetData()
    {
        SymbolInfoCollection symbolInfoCollection = new SymbolInfoCollection();
        #region Gmail
        symbolInfoCollection.Add(new SymbolInfo() { Id = "1", Description = "Start", Shape = App.Current.Resources["StartOrEnd"] as string, Width = 100, Height = 30, Color = "#8E44CC" });

        symbolInfoCollection.Add(new SymbolInfo() { Id = "2", Description = "Open Gmail site in browser", ParentId = new List<string> { "1" }, Shape = App.Current.Resources["Rectangle"] as string, Width = 120, Height = 50, Color = "#1759B7" });

        symbolInfoCollection.Add(new SymbolInfo() { Id = "3", Description = "Existing \nor \nnew user?", ParentId = new List<string> { "2" }, Shape = App.Current.Resources["Decision"] as string, Width = 130, Height = 80, Color = "#2F95D8" });

        symbolInfoCollection.Add(new SymbolInfo() { Id = "4", LineText = new List<string> { "New" }, Description = "Create an account", ParentId = new List<string> { "3" }, Shape = App.Current.Resources["Rectangle"] as string, Width = 120, Height = 50, Color = "#1759B7" });

        symbolInfoCollection.Add(new SymbolInfo() { Id = "5", Description = "Sign in", LineText = new List<string> { "Existing" }, ParentId = new List<string> { "3" }, Shape = App.Current.Resources["Rectangle"] as string, Width = 120, Height = 50, Color = "#1759B7" });

        symbolInfoCollection.Add(new SymbolInfo() { Id = "6", Description = "Enter username \nand password", LineText = new List<string> { "", "No" }, ParentId = new List<string> { "5", "7" }, Shape = App.Current.Resources["Data"] as string, Width = 150, Height = 50, Color = "#70AF16" });

        symbolInfoCollection.Add(new SymbolInfo() { Id = "7", Description = "Authorized?", ParentId = new List<string> { "6" }, Shape = App.Current.Resources["Decision"] as string, Width = 120, Height = 70, Color = "#2F95D8" });

        symbolInfoCollection.Add(new SymbolInfo() { Id = "8", Description = "Login successful!!", LineText = new List<string> { "Yes" }, ParentId = new List<string> { "7" }, Shape = App.Current.Resources["Rectangle"] as string, Width = 120, Height = 50, Color = "#1759B7" });

        symbolInfoCollection.Add(new SymbolInfo() { Id = "9", Description = "Enter first name \nand last name", ParentId = new List<string> { "4" }, Shape = App.Current.Resources["Data"] as string, Width = 150, Height = 50, Color = "#70AF16" });

        symbolInfoCollection.Add(new SymbolInfo() { Id = "10", Description = "Enter username \nand password", LineText = new List<string> { "", "Yes" }, ParentId = new List<string> { "9", "11" }, Shape = App.Current.Resources["Data"] as string, Width = 150, Height = 50, Color = "#70AF16" });

        symbolInfoCollection.Add(new SymbolInfo() { Id = "11", Description = "Username \nalready\n exists?", ParentId = new List<string> { "10" }, Shape = App.Current.Resources["Decision"] as string, Width = 130, Height = 80, Color = "#2F95D8" });

        symbolInfoCollection.Add(new SymbolInfo() { Id = "12", Description = "Registration Successful!!", LineText = new List<string> { "No" }, ParentId = new List<string> { "11" }, Shape = App.Current.Resources["Process"] as string, Width = 120, Height = 50, Color = "#1759B7" });

        symbolInfoCollection.Add(new SymbolInfo() { Id = "13", Description = "Open inbox", ParentId = new List<string> { "8", "12" }, Shape = App.Current.Resources["Process"] as string, Width = 120, Height = 50, Color = "#1759B7" });

        symbolInfoCollection.Add(new SymbolInfo() { Id = "14", Description = "End", ParentId = new List<string> { "13" }, Shape = App.Current.Resources["StartOrEnd"] as string, Width = 100, Height = 30, Color = "#8E44CC" });
        #endregion

        return symbolInfoCollection;
    }
}

Features

Flowchart orientation customization

You can customize the flowchart orientation to be vertical (from top to bottom) or horizontal (from left to right).

Use the Orientation property of the FlowchartLayout class to define the flow direction either as TopToBottom or LeftToRight. Refer to the following code example for details.

LayoutManager = new LayoutManager()
{
    Layout = new FlowchartLayout()
    {
        //Set the flowchart flow direction
        Orientation = FlowchartOrientation.LeftToRight
    },
};

Horizontal Flowchart

Horizontal Flowchart

Customize the decision symbol output directions

The decision symbol shows a branching point where a decision is made to choose one of two paths. The YesBranchDirection and NoBranchDirection properties of FlowchartLayout controls the direction of the Yes and No branches. The following code example illustrates this.

LayoutManager = new LayoutManager()
{
    Layout = new FlowchartLayout()
    {
        //Set the decision yes branch direction
        YesBranchDirection = BranchDirection.SameAsFlow,
        //Set the decision no branch direction
        NoBranchDirection = BranchDirection.RightInFlow,
    },
};

Flowchart with Decision Branch

Flowchart with Decision Branch

Customize Yes and No branch line text

The decision symbol will produce two branches as output: a Yes branch and a No branch. If the output branch connector text value matches the values in the YesBranchValues property of the FlowchartLayout class, it will be considered a Yes branch. Similarly, if a connector text value matches the values in the NoBranchValues property, it will be considered a No branch. By default, the YesBranchValues property will contain Yes and True string values and the NoBranchValues property will contain No and False string values.

Provide any text value to the connector text to describe the flow. Also, provide any string value in the YesBranchValues and NoBranchValues. To decide the flow based on if or else, the connector text should match the values in the YesBranchValues and NoBranchValues. The following code example illustrates this.

//Add the custom yes branch values
(LayoutManager.Layout as FlowchartLayout).YesBranchValues.Add("Existing");
//Add the custom no branch values
(LayoutManager.Layout as FlowchartLayout).NoBranchValues.Add("New");

Custom Branch Line Text

Summary

In this blog post, we have seen how to create and customize flowcharts from data without specifying coordinates using the Syncfusion WPF Diagram library. You can also use the library to create an interactive flowchart maker application. More built-in automatic layouts, such as hierarchical and radial tree, are also available in the Diagram control. To explore more in-depth features, refer to our help documentation on automatic layouts.

If you’re already a Syncfusion user, you can download the product setup from our website. Otherwise, you can download a free, 30-day trial here.

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

Be the first to get updates

Sarathkumar V

Meet the Author

Sarathkumar V

Sarathkumar is a Product Manager for Diagram and HeatMap products at Syncfusion. He has been a .NET developer since 2013. He is specialized in WPF, UWP, Xamarin and other .Net frameworks.