TL;DR: Discover how to create a Real-Time Cloud Monitoring Interface with Syncfusion® WPF Charts that visualize live cloud metrics like CPU, memory, and network usage. These charts enable dynamic updates, offering instant insights into system performance. Learn to bind real-time data streams and configure responsive chart types for effective monitoring.
Welcome to the Chart of the Week blog series!
Cloud monitoring is the process of continuously observing, tracking, and analyzing the performance, availability, and health of cloud-based infrastructure, applications, and services. It enables organizations to detect real-time issues, optimize resource usage, and ensure seamless user experiences. With the rise of distributed systems and hybrid cloud environments, real-time visibility has become more critical. By leveraging automated tools and dashboards, cloud monitoring provides actionable insights that help maintain system reliability and support proactive decision-making.
In this blog, we’ll explore how to build a Cloud Monitoring dashboard using Syncfusion® WPF controls and the WPF framework to effectively visualize cloud performance metrics. This dashboard will enable users to continuously observe, track, and analyze the performance, availability, and health of cloud-based infrastructure, applications, and services.
Before creating the cloud monitoring dashboard, install Syncfusion.SfChart.WPF and Syncfusion.SfGrid.WPF by following the official WPF Documentation and setting up the necessary dependencies.
Create data models to represent cloud-related information. Here’s a breakdown of its properties:
C#
public class CloudMetricsDataModel
{
// Represents the Circular Chart Data Model
}
public class CloudPerformanceDataModel
{
// Represents the Cartesian Chart Data Model
}
public class InstanceInfo
{
// Represents the Data grid Model
} The ViewModel class implements INotifyPropertyChanged to support dynamic UI updates in a WPF application. It manages observable collections for real-time chart data, circular chart datasets (CPU, memory, disk), disk usage, and instance information. Additionally, it holds formatted text values for CPU, memory, and disk usage, and initializes sample data for visualization and monitoring purposes.
C#
public class ViewModel : INotifyPropertyChanged
{
private string[] diskusageItems = ["Downloads", "Documents", "RootGB", "MediaGB"];
private const int MaxPoints = 10;
private ObservableCollection<CloudPerformanceDataModel> realtimechartData = new();
public ObservableCollection<CloudPerformanceDataModel> RealTimeChartData
{
get { return realtimechartData; }
set
{
if(realtimechartData != value)
{
realtimechartData = value;
OnPropertyChanged(nameof(RealTimeChartData));
}
}
}
private ObservableCollection<CloudMetricsDataModel> cpuDatasets = new();
public ObservableCollection<CloudMetricsDataModel> CPUDatasets
{
get { return cpuDatasets; }
set
{
if(cpuDatasets != value)
{
cpuDatasets = value;
OnPropertyChanged(nameof(CPUDatasets));
}
}
}
private ObservableCollection<CloudMetricsDataModel> memoryDatasets = new();
public ObservableCollection<CloudMetricsDataModel> MemoryDatasets
{
get { return memoryDatasets; }
set
{
if(memoryDatasets != value)
{
memoryDatasets = value; OnPropertyChanged(nameof(MemoryDatasets));
}
}
}
private ObservableCollection<CloudMetricsDataModel>diskspaceData = new();
public ObservableCollection<CloudMetricsDataModel>DiskSpaceData
{
get { return diskspaceData; }
set
{
if(diskspaceData != value)
{
diskspaceData = value; OnPropertyChanged(nameof(DiskSpaceData));
}
}
}
private ObservableCollection<CloudPerformanceDataModel> diskUsageDatasets = new();
public ObservableCollection<CloudPerformanceDataModel> DiskUsageDatasets
{
get { return diskUsageDatasets; }
set
{
if( diskUsageDatasets != value)
{
diskUsageDatasets = value; OnPropertyChanged(nameof(DiskUsageDatasets));
}
}
}
private Random _random = new Random();
private ObservableCollection<InstanceInfo>? _instanceList;
public ObservableCollection<InstanceInfo>? InstanceList
{
get { return _instanceList; }
set { _instanceList = value; }
}
public ViewModel()
{
InstanceList = GetInstanceDataCollection();
RealTimeChartData = new ObservableCollection<CloudPerformanceDataModel>();
CPUDatasets = new ObservableCollection<CloudMetricsDataModel>
{
...
};
MemoryDatasets = new ObservableCollection<CloudMetricsDataModel>
{
...
};
DiskSpaceData = new ObservableCollection<CloudMetricsDataModel>
{
...
};
DiskUsageDatasets = new ObservableCollection<CloudPerformanceDataModel>()
{
...
};
for (int i = 0; i < MaxPoints; i++)
{
RealTimeChartData.Add(new CloudPerformanceDataModel
{
...
});
}
}
private ObservableCollection<InstanceInfo> GetInstanceDataCollection()
{
return new ObservableCollection<InstanceInfo>()
{
...
};
}
} This XAML code creates a horizontal header with a cloud icon and the title “Cloud Performance Monitoring”, styled for clarity and visual appeal. The image and text are aligned side by side for a clean dashboard introduction.
XAML
<StackPanel Orientation="Horizontal">
<Image Source="/Images/cloudcomputing.png" Width="60" Height="60" Margin="0,0,10,0"/>
<TextBlock Text="Cloud Performance Monitoring" FontSize="25" FontWeight="Medium" VerticalAlignment="Center"/>
</StackPanel> This XAML snippet creates a control panel with a checkbox to toggle data polling and a horizontally aligned layout displaying instance details like type, zone, AMI, and OS using styled borders, icons, and labels.
XAML
<CheckBox Content="Activate Data Polling" FontSize="15" FontWeight="Medium" VerticalContentAlignment="Center" VerticalAlignment="Center" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" HorizontalAlignment="Right" Margin="10"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<Border Background="#FFFBFE" Margin="0,0,15,0" Style="{StaticResource instanceinfoborderStyle}">
<StackPanel Orientation="Vertical">
<TextBlock Text="Instance Type" Style="{StaticResource headerlabelStyle}"/>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Border Background="#EAEFFE" Style="{StaticResource instanceinfovaluesborderStyle}">
<Path Data="M11.000003,10.999997L11.000003,20.999997.….." Stretch="Uniform" Fill="#2485FA" Width="30" Height="30"/>
</Border>
<TextBlock Text="t2.micro" VerticalAlignment="Center" Margin="10,0,0,0" FontSize="14"/>
</StackPanel>
</StackPanel>
</Border>
...
</StackPanel> Let’s configure the Syncfusion® WPF DataGrid control using the provided documentation.
This XAML code defines a styled section for displaying a list of cloud instances using the Syncfusion® SfDataGrid inside a bordered container. The grid is bound to the InstanceList from the ViewModel and displays columns for instance ID, type, public IP, state, and health status. The health column uses a GridTemplateColumn to visually represent the health of each instance with a colored icon and background, enhancing readability and quick status recognition.
XAML
<Border Height="345" Background="#FFFBFE" Width="738" HorizontalAlignment="Left" CornerRadius="8" Margin="0,0,7.5,0" VerticalAlignment="Top" Padding="15">
<StackPanel Orientation="Vertical">
<TextBlock Text="Instances" Style="{StaticResource headerlabelStyle}" Margin="0,0,0,10"/>
<dataGrid:SfDataGrid ItemsSource="{Binding InstanceList}"
AutoGenerateColumns="False" HeaderStyle="{StaticResource headerStyle}"
ColumnSizer="Star" RowHeight="40" HeaderRowHeight="40">
<dataGrid:SfDataGrid.Columns>
<dataGrid:GridTextColumn MappingName="InstanceID" HeaderText="ID" TextAlignment="Center"/>
<dataGrid:GridTextColumn MappingName="Type" HeaderText="Type" TextAlignment="Center"/>
<dataGrid:GridTextColumn MappingName="PublicIP" HeaderText="PublicIP" TextAlignment="Center"/>
<dataGrid:GridTextColumn MappingName="State" HeaderText="State" TextAlignment="Center"/>
<dataGrid:GridTemplateColumn HeaderText="Health" MappingName="Health">
<dataGrid:GridTemplateColumn.CellTemplate>
<DataTemplate>
<Border Background="{Binding HealthBackground}" CornerRadius="4" Padding="5" Width="30" Height="30">
<Path Data="{Binding HealthIconPath}" Fill="{Binding HealthColor}" Stretch="Uniform" Width="17" Height="17" StrokeThickness="2"/>
</Border>
</DataTemplate>
</dataGrid:GridTemplateColumn.CellTemplate>
</dataGrid:GridTemplateColumn>
</dataGrid:SfDataGrid.Columns>
</dataGrid:SfDataGrid>
</StackPanel>
</Border> Let’s configure the Syncfusion® WPF Chart control using the provided documentation.
This XAML layout displays four visually styled borders using Syncfusion® Doughnut Charts and icons to represent key cloud performance metrics. Each border is bound to ViewModel properties and provides a clean, animated visualization of system health and resource usage.
XAML
<Border Height="165" Width="361" Margin="0,0,7.5,0" CornerRadius="8" Background="#FFFBFE" Padding="5">
<chart:SfChart>
<chart:DoughnutSeries ItemsSource="{Binding CPUDatasets}"
XBindingPath="Name"
YBindingPath="Value"
EnableAnimation="True"
Palette="Custom"
DoughnutCoefficient="0.5">
<chart:DoughnutSeries.ColorModel>
<chart:ChartColorModel>
<chart:ChartColorModel.CustomBrushes>
<SolidColorBrush Color="#2196F3"/>
<SolidColorBrush Color="#F2F2F2"/>
</chart:ChartColorModel.CustomBrushes>
</chart:ChartColorModel>
</chart:DoughnutSeries.ColorModel>
<chart:DoughnutSeries.CenterView>
<ContentControl HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding CPUText}" FontSize="12" HorizontalAlignment="Center" Margin="0,0,0,1" FontWeight="Bold"/>
<TextBlock Text="CPU" FontSize="14" FontWeight="Medium" HorizontalAlignment="Center" Foreground="Gray"/>
</StackPanel>
</ContentControl>
</chart:DoughnutSeries.CenterView>
</chart:DoughnutSeries>
</chart:SfChart>
</Border>
Let’s configure the Syncfusion® WPF Chart control using the provided documentation.
This XAML layout features two visually distinct charts using Syncfusion® WPF controls: a bar chart for visualizing disk usage, a column chart for tracking disk read/write operations, and a spline chart for tracking CPU utilization and monitoring network traffic (in/out) over time. Both charts are enhanced with custom color palettes, axis configurations, and interactive elements like tooltips and data labels for better user insight.
XAML
<Border Height="345" Background="#FFFBFE" Width="737" HorizontalAlignment="Left" Margin="0,0,8,0" Padding="16" CornerRadius="8">
<StackPanel Orientation="Vertical">
<TextBlock Text="Disk Usage" Style="{StaticResource headerlabelStyle}" Margin="0,0,0,10"/>
<chart:SfChart Margin="0,0,10,20">
<chart:SfChart.PrimaryAxis>
<chart:CategoryAxis/>
</chart:SfChart.PrimaryAxis>
<chart:SfChart.SecondaryAxis>
<chart:NumericalAxis Header="GB" PlotOffsetEnd="20"/>
</chart:SfChart.SecondaryAxis>
<chart:BarSeries ItemsSource="{Binding DiskUsageDatasets}"
XBindingPath="Name"
YBindingPath="Value"
EnableAnimation="True"
Palette="Custom" chart:ChartSeriesBase.Spacing="0.5">
<chart:BarSeries.ColorModel>
<chart:ChartColorModel>
<chart:ChartColorModel.CustomBrushes>
<SolidColorBrush Color="#2196F3"/>
<SolidColorBrush Color="#CDDE1F"/>
<SolidColorBrush Color="#FF477E"/>
<SolidColorBrush Color="#8854D9"/>
</chart:ChartColorModel.CustomBrushes>
</chart:ChartColorModel>
</chart:BarSeries.ColorModel>
<chart:BarSeries.CustomTemplate>
<DataTemplate>
<Canvas>
<Rectangle Fill="{Binding Interior}" Canvas.Left="{Binding RectX}" Canvas.Top="{Binding RectY}" Width="{Binding Width}" Height="{Binding Height}" RadiusY="1.5" RadiusX="1.5"/>
</Canvas>
</DataTemplate>
</chart:BarSeries.CustomTemplate>
<chart:BarSeries.AdornmentsInfo>
<chart:ChartAdornmentInfo ShowLabel="True" UseSeriesPalette="False" LabelPosition="Outer"/>
</chart:BarSeries.AdornmentsInfo>
</chart:BarSeries>
</chart:SfChart>
</StackPanel>
</Border>
This code sets up a DispatcherTimer in the ViewModel to simulate real-time cloud monitoring by updating CPU, memory, disk, and network metrics every 2 seconds. It dynamically refreshes chart-bound collections and text values, ensuring the UI reflects the latest system performance data. The UpdateRealTimeData method maintains a rolling window of time-series data for live charting.
C#
public class ViewModel : INotifyPropertyChanged
{
internal DispatcherTimer dispatcherTimer;
private Random _random = new Random();
public ViewModel()
{
...
dispatcherTimer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(2)
};
dispatcherTimer.Tick += UpdateData;
dispatcherTimer.Start();
}
private void UpdateData(object? sender, EventArgs e)
{
double cpuUsed = _random.Next(0, 100);
double cpuFree = 100 - cpuUsed;
CPUDatasets.Clear();
CPUDatasets.Add(new CloudMetricsDataModel() { Name = "Used", Value = cpuUsed });
CPUDatasets.Add(new CloudMetricsDataModel() { Name = "Free", Value = cpuFree });
CPUText = cpuUsed.ToString() + "%";
double memoryUsed = _random.Next(20, 100);
double memoryFree = 1024 - memoryUsed;
MemoryDatasets.Clear();
MemoryDatasets.Add(new CloudMetricsDataModel() { Name = "Used", Value = memoryUsed });
MemoryDatasets.Add(new CloudMetricsDataModel() { Name = "Free", Value = memoryFree });
MemoryText = memoryUsed.ToString() + " MB";
double diskUsed = 0;
DiskUsageDatasets.Clear();
foreach (var item in diskusageItems)
{
double value = _random.Next(5, 15);
DiskUsageDatasets.Add(new CloudPerformanceDataModel() { Name = item, Value = value });
diskUsed += value;
}
DiskText = diskUsed.ToString() + " GB";
double diskFree = 100 - diskUsed;
DiskSpaceData.Clear();
DiskSpaceData.Add(new CloudMetricsDataModel() { Name = "Used", Value = diskUsed });
DiskSpaceData.Add(new CloudMetricsDataModel() { Name = "Free", Value = diskFree });
UpdateRealTimeData();
}
private void UpdateRealTimeData()
{
if (RealTimeChartData.Count >= MaxPoints)
RealTimeChartData.RemoveAt(0);
RealTimeChartData.Add(new CloudPerformanceDataModel
{
Time = DateTime.Now,
CPUUsage = _random.Next(10, 85),
NetworkIn = _random.Next(10, 85),
NetworkOut = _random.Next(20, 70),
Read = _random.Next(10, 80),
Write = _random.Next(10, 95)
});
}
} Finally, arrange all controls in the main layout for a seamless, intuitive, and visually balanced user experience.
XAML
<ScrollViewer x:Name="scrollViewer" VerticalScrollBarVisibility="Visible">
<StackPanel Margin="15">
<!--Title-->
<StackPanel Orientation="Horizontal">
...
</StackPanel>
<!--Instance Configuration Details-->
<StackPanel Orientation="Horizontal">
...
</StackPanel>
<Grid Margin="0,15,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<!--Instance Types listed Details in SfGrid-->
<Border>
...
</Border>
<!--Cloud Metrics and Status Details-->
<StackPanel Orientation="Vertical" Grid.Column="1">
<StackPanel Orientation="Horizontal">
...
</StackPanel>
<StackPanel Orientation="Horizontal">
...
</StackPanel>
</StackPanel>
</Grid>
<!—Disk and CPU utilization Details in bar and spline charts-->
<Grid Margin="0,15,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<Border>
...
</Border>
<Border Grid.Column="1">
...
</Border>
</Grid>
<!—Network and disk operation details in spline and column charts -->
<Grid Margin="0,15,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<Border>
...
</Border>
<Border Grid.Column="1">
...
</Border>
</Grid>
</StackPanel>
</ScrollViewer> When you execute these code examples, the resulting dashboard will resemble the visualization below, featuring a modern and thoughtfully designed layout.
For more details, refer to the Cloud Performance Monitoring GitHub demo.
Q1: What is cloud monitoring?
Cloud monitoring tracks the performance, availability, and health of cloud infrastructure and applications in real time.
Q2: Why use Syncfusion WPF Charts for cloud monitoring?
Syncfusion WPF Charts provide dynamic, customizable visualizations for real-time data like CPU, memory, and disk usage.
Q3: How do I install Syncfusion WPF controls?
Install Syncfusion.SfChart.WPF and Syncfusion.SfGrid.WPF via NuGet, as outlined in the documentation.
Q4: Can I integrate this dashboard with AWS or Azure?
Yes, replace the simulated data in the ViewModel with API calls to AWS CloudWatch or Azure Monitor for real cloud metrics.
Q5: How often does the dashboard update?
The dashboard updates every 2 seconds using a DispatcherTimer for real-time visualization.
Thanks for reading! In this blog, we’ve explored how to build a Cloud Monitoring using Syncfusion® WPF Charts. We encourage you to follow the steps outlined in this blog and share your feedback in the comments section below.
For existing Syncfusion® customers, the latest version of Essential Studio® is available from the license and downloads page. If you are not a customer, try our 30-day free trial to check out these new features.
If you require assistance, please don’t hesitate to contact us via our support forums, support portal, or feedback portal. We are always eager to help you! Stay tuned for next week’s featured Chart of the Week.