Hello everyone, I am Wolf at the End of the Desert. Today I will introduce a WPF open-source project - NodeNetwork, which can help us quickly build and customize network topology diagrams.
1. Introduction
In modern software development, data visualization and interactivity are getting more and more attention. To achieve this, various controls such as charts, tables, and network topology diagrams are usually needed. However, for some special scenarios, these controls may not meet the requirements, and we need a custom way to display and process data. NodeNetwork is such a custom approach. It is an open-source project based on C# WPF that helps us quickly build and customize network topology diagrams.
NodeNetwork's code is hosted on GitHub, created and maintained by a Dutch developer named Wouterdek. In this article, we will introduce and analyze NodeNetwork. We hope readers can understand the core concepts, application scenarios, and usage methods of NodeNetwork through this article, and also grasp some tips and experiences for developing NodeNetwork.
Repository address: https://github.com/Wouterdek/NodeNetwork
Repository screenshot:

Repository source code structure:

2. Examples
1. Calculator Example
This example allows users to create mathematical expressions using a node editor. When a node is modified, the result value is automatically calculated and updated. This application includes node validation, custom node subclasses, value inputs/outputs, custom input editors, node lists, ...
Below is a demonstration of the Calculator example application:

2. Code Generator Example
In this example, users can create LUA code. Similar to blueprints in Unreal Engine, the editor has execution flow and data flow. Custom input/output ports and node editor provide a more intuitive experience.
Below is a screenshot of the Code generator application:

3. Shader Editor Example
A more practical example of this library could be a shader editor.
Below is a demonstration of the shader editor example made with NodeNetwork:

These example applications can be downloaded here, their source code is included in the repository, and binary versions of the library are available on NuGet.
3. Features
- Built for .NET Framework 4.7.2 and .NET Core 3.1 or higher.
- Open, permissive license - Apache-2.0 license.
- Interactive, reliable controls built with modern reactive MVVM code.
- Smooth panning and zooming controls.
- Automatic layout system.
- Highly customizable, yet easy to use by default.
- Powerful node and connection validation support.
- Backed by extensive unit tests.
- ...
4. Core Concepts of NodeNetwork
The following content can refer to the repository's component documentation page.
1. Node
A node is the most basic element in NodeNetwork and can represent any data source or processing unit. Each node can contain one or more input ports and output ports, representing the data received and output by the node. NodeNetwork includes several commonly used node types, such as constant nodes, calculation nodes, input/output nodes, etc., and also supports custom node types.

2. Connection
A connection is a core concept in NodeNetwork, used to represent the data transfer relationship between nodes. Each connection has a source port and a target port. The source port indicates the source of the data, and the target port indicates the destination of the data. Connections can also carry some metadata to describe additional information about the connection, such as color, line width, etc.

3. Port
A port is an input or output endpoint of a node, used to connect with other nodes. Each port has a type, indicating the data type that the port can receive or output. Ports can also have other properties, such as labels, descriptions, etc., to describe the function and purpose of the port.
4. Graphical User Interface (GUI)
NodeNetwork is implemented based on the WPF framework, so it has a powerful graphical user interface (GUI) system. In NodeNetwork, each node and connection can be displayed as a graphical element, and users can operate these elements through methods such as dragging and zooming.
5. Layout
Layout is another important concept in NodeNetwork, used to control the position and size of nodes and connections. NodeNetwork provides a variety of layout methods, such as free layout, grid layout, force-directed layout, etc. Users can choose different layout methods according to specific needs and can customize and adjust the layout through code or the graphical interface.
6. Serialization and Deserialization
In practical applications, we need to save nodes and connections to files or databases, or read nodes and connections from files or databases. To achieve this, NodeNetwork provides serialization and deserialization functionality. Serialization is the process of converting nodes and connections into a data stream, while deserialization is the process of converting a data stream into nodes and connections. NodeNetwork supports various serialization formats, such as XML, JSON, binary, etc., and users can choose different formats based on specific needs.
5. Application Scenarios of NodeNetwork
NodeNetwork has a wide range of application scenarios. The following are a few examples:
1. Data Processing and Analysis
NodeNetwork can help us quickly build tools for data processing and analysis. For example, we can create a graphical workflow, connecting different data processing nodes to achieve data preprocessing, transformation, and analysis.
2. Graphical Editor
NodeNetwork can help us quickly build graphical editors. For example, we can create a graphical interface for editing and configuring certain parameters or options. These parameters or options can be interacted with and transferred through nodes and connections.
3. Visualization and Interactive Display
NodeNetwork can help us quickly build visualization and interactive display tools. For example, we can create a graphical network topology diagram to display the connection relationships and status of certain devices or systems. Users can interact with and control through nodes and connections, such as adding, deleting, or modifying nodes and connections.
6. Usage of NodeNetwork
The usage of NodeNetwork is very simple. The following introduces a few steps (refer to Hello world in less than 30 lines of code).
First, create a WPF project using Dotnet 8 and name it NodeNetworkTest. You can use .NET Framework 4.7.2 or higher, or .NET CORE 3.x or higher. The site owner uses .NET 8 just because the preview 2 of .NET 8 was just released and they wanted to try it out.
1. Install NodeNetwork
NodeNetwork can be installed via the NuGet Package Manager. In Visual Studio, open the "Package Manager Console" and enter the following command to install NodeNetwork:
Install-Package NodeNetwork
2. Register NodeNetwork Views
MVVM is consistently used throughout the NodeNetwork library. For an introduction to MVVM, click here. To use the elements in the library, you need to create appropriate views and provide them with corresponding ViewModel instances.
Before using the library, register NodeNetwork's views with their corresponding ViewModels using the NNViewRegistrar.RegisterSplat() method in the OnStartup method of the App.xaml.cs file.
using System.Windows;
using NodeNetwork;
namespace NodeNetworkTest;
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
NNViewRegistrar.RegisterSplat();
}
}
3. Create the View
Open MainWindow.xaml, add the NodeNetwork namespace xmlns:nodenetwork="clr-namespace:NodeNetwork.Views;assembly=NodeNetwork", and add the NetworkView element <nodenetwork:NetworkView x:Name="networkView" />. NetworkView represents the entire network topology diagram:
<Window x:Class="NodeNetworkTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:nodenetwork="clr-namespace:NodeNetwork.Views;assembly=NodeNetwork"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<nodenetwork:NetworkView x:Name="networkView" />
</Grid>
</Window>
4. Create Nodes and Connections
In NodeNetwork, creating nodes and connections is very simple. First, we need to create a NetworkViewModel, which is the ViewModel for the NetworkView. It can be created with the following code:
var network = new NetworkViewModel();
networkView.ViewModel = network;
Then create the first node with the following code:
var node1 = new NodeViewModel();
node1.Name = "Node 1";
network.Nodes.Add(node1);
And create an input port for the first node:
var node1Input = new NodeInputViewModel();
node1Input.Name = "Node 1 Input";
node1.Inputs.Add(node1Input);
Create a second node, and similarly add an output port to it:
var node2 = new NodeViewModel();
node2.Name = "Node 2";
network.Nodes.Add(node2);
var node2Output = new NodeOutputViewModel();
node2Output.Name = "Node 2 Output";
node2.Outputs.Add(node2Output);
Finally, we can connect the input port of node 1 to the output port of node 2 with the following code:
var connection = new ConnectionViewModel(network, node1Input, node2Output);
network.Connections.Add(connection);
Full code is as follows:
using DynamicData;
using NodeNetwork.ViewModels;
using System.Windows;
namespace NodeNetworkTest;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// Create an instance of the NetworkView's ViewModel
var network = new NetworkViewModel();
// Assign the viewmodel (network) to the view (networkView)
networkView.ViewModel = network;
// Create the first node ViewModel, set its name, and add this node to the network
var node1 = new NodeViewModel();
node1.Name = "Node 1";
network.Nodes.Add(node1);
// Create the input port ViewModel of the first node, set its name, and add it to the first node
var node1Input = new NodeInputViewModel();
node1Input.Name = "Node 1 Input";
node1.Inputs.Add(node1Input);
// Create the second node ViewModel, set its name, add it to the network, and add an output in a similar fashion
var node2 = new NodeViewModel();
node2.Name = "Node 2";
network.Nodes.Add(node2);
var node2Output = new NodeOutputViewModel();
node2Output.Name = "Node 2 Output";
node2.Outputs.Add(node2Output);
// Connect the input port of node 1 to the output port of node 2
var connection = new ConnectionViewModel(network, node1Input, node2Output);
network.Connections.Add(connection);
}
}
Run the program to see the effect:

All the example code has been provided; you can also click here to clone.
5. Layout
Layout in NodeNetwork is very flexible and free. We can perform layout through code or the graphical interface. For example, we can place a node at a specified position with the following code:
node.Position = new Point(100, 100);
Adjust the layout of the entire network topology diagram with the following code (refer to layout documentation):
ForceDirectedLayouter layouter = new ForceDirectedLayouter();
var config = new Configuration
{
Network = yourNetwork,
};
layouter.Layout(config, 10000);

6. Serialization and Deserialization
Serialization and deserialization in NodeNetwork are very simple. We can serialize nodes and connections into XML format with the following code:
var serializer = new XmlSerializer(typeof(NodeNetworkViewModel));
var writer = new StringWriter();
serializer.Serialize(writer, nodeNetwork);
Then we can save the XML string to a file or database. Deserialization is also simple. We can deserialize nodes and connections from an XML string with the following code:
var serializer = new XmlSerializer(typeof(NodeNetworkViewModel));
var reader = new StringReader(xmlString);
var nodeNetwork = (NodeNetworkViewModel)serializer.Deserialize(reader);
7. Conclusion
NodeNetwork is a very practical and flexible C# WPF open-source project that helps us quickly build graphical network topology diagrams and achieve interaction and transfer between nodes and connections. NodeNetwork provides rich functionality and features, such as customization of nodes and connections, layout and adjustment, serialization and deserialization, etc., meeting various application needs. The application scenarios of NodeNetwork are very extensive, such as data processing and analysis, graphical editors, visualization and interactive displays, etc. The usage of NodeNetwork is very simple; we only need to install NodeNetwork, create nodes and connections, layout and adjust, serialize and deserialize.
- Getting Started
For a simple quick start guide on using this library, please refer to the cookbook section on this page. The documentation includes setup information, cookbook sections, examples, and API reference.
- License
This library is licensed under the Apache License 2.0. (See choosealicense.com/licenses/apache-2.0 for a brief introduction) A copy of this license is included in the repository under LICENSE.
- Documentation
Documentation is available here. If you want to make changes to the documentation, you can do so by submitting a pull request to the gh-pages branch.
- Contributing
These are very welcome on the GitHub page: bug reports, patches, feature requests, pull requests...
- WeChat technical exchange group: Add WeChat (codewf) and note "join group"
- QQ technical exchange group: 771992300.