TL;DR: Learn how to build a real-time patient health monitoring dashboard using Syncfusion® WinUI Charts to visualize vital signs such as heart rate, blood pressure, and oxygen saturation. Implement dynamic chart updates for continuous tracking, bind live medical data streams, and configure responsive chart types to support timely clinical decisions and enhance patient care outcomes.
Welcome to this week’s edition of the Chart of the Week series!
Creating real-time dashboards for healthcare applications isn’t just technically demanding; it’s mission-critical. Developers face challenges in visualizing fast-changing medical data, ensuring UI responsiveness, and maintaining clarity under pressure. In this blog, you’ll learn how to build a real-time patient health monitoring dashboard using Syncfusion® WinUI Charts to track vital signs like heart rate, blood pressure, and oxygen saturation.
Patient health monitoring systems integrate a wide range of physiological data to provide a comprehensive view of a patient’s health status. By combining real-time data with historical trends, these systems support early diagnosis, personalized care, and improved patient engagement, ultimately enhancing the quality and efficiency of healthcare delivery.
Lets build a Patient Health Monitoring dashboard using Syncfusion® WinUI controls and the WinUI framework to effectively visualize key health metrics. This dashboard will enable healthcare providers to continuously observe, track, and analyze vital signs such as heart rate, blood pressure, oxygen saturation, glucose levels, and more. By integrating real-time data visualization and interactive components, the dashboard supports timely clinical decisions, enhances patient engagement, and promotes proactive health management.
Before creating the patient health monitoring dashboard, install the Syncfusion.Chart.WinUI, Syncfusion.Editors.WinUI, Syncfusion.Gauge.WinUI and Syncfusion.Grid.WinUI by following the official WinUI Documentation and setting up the necessary dependencies.
Create a data model to represent patient health information. Here’s a breakdown of its components:
C#
public class PatientInfo
{
// Represents the Patient Info List
}
public class BloodVitalMetrics
{
// Represents the Blood Vital Metrics
}
public class MedicationAdherence
{
// Represents the Medication Adherence
}
public class StepCount
{
// Represents the Step Count
}
public class ECGPoint
{
// Represents the ECG Point
}
public class HealthConditionInfo
{
// Represents the Patient Health Condition Info
}
ViewModel implements INotifyPropertyChanged to enable dynamic UI updates in a WinUI-based patient health monitoring dashboard. It manages observable collections for ECG data, patient details, vital metrics, medication adherence, and step counts. It also holds individual health parameters like body temperature, cholesterol, heart rate, and respiratory rate. The HealthConditionInfos collection provides clinical status indicators with color-coded severity. Sample patient data is initialized through the GeneratePatientDetails() method for visualization.
XAML
public class ViewModel:INotifyPropertyChanged
{
public ObservableCollection<ECGPoint> ECGData { get; set; } = new ObservableCollection<ECGPoint>();
public ObservableCollection<PatientInfo> Patients { get; set; }
public List<Brush> CustomPalettes { get; set; }
private ObservableCollection<BloodVitalMetrics> bloodVitalMetrics = new();
public ObservableCollection<BloodVitalMetrics> BloodVitalMetrics
{
get => bloodVitalMetrics;
set
{
bloodVitalMetrics = value;
OnPropertyChanged(nameof(BloodVitalMetrics));
}
}
private ObservableCollection<MedicationAdherence> medication = new();
public ObservableCollection<MedicationAdherence> Medications
{
get => medication;
set
{
medication = value;
OnPropertyChanged(nameof(Medications));
}
}
private ObservableCollection<StepCount> stepCounts = new();
public ObservableCollection<StepCount> StepCounts
{
get => stepCounts;
set
{
stepCounts = value;
OnPropertyChanged(nameof(StepCounts));
}
}
private double bodyTemperature;
public double BodyTemperature
{
get => bodyTemperature;
set
{
bodyTemperature = value;
OnPropertyChanged(nameof(BodyTemperature));
}
}
private double bloodCholesterol;
public double BloodCholesterol
{
get => bloodCholesterol;
set
{
bloodCholesterol = value;
OnPropertyChanged(nameof(BloodCholesterol));
}
}
private double heartRate;
public double HeartRate
{
get => heartRate;
set
{
heartRate = value;
OnPropertyChanged(nameof(HeartRate));
}
}
private double respiratoryRate;
public double RespiratoryRate
{
get => respiratoryRate;
set
{
respiratoryRate = value;
OnPropertyChanged(nameof(RespiratoryRate));
}
}
private PatientInfo? _selectedPatient;
public PatientInfo? SelectedPatient
{
get => _selectedPatient;
set
{
if(value != null)
{
_selectedPatient = value;
OnPropertyChanged(nameof(SelectedPatient));
DynamicUpdateData(SelectedPatient!);
SelectionChangedData(SelectedPatient!);
}
}
}
private ObservableCollection<HealthConditionInfo> healthConditionInfos = new();
public ObservableCollection<HealthConditionInfo> HealthConditionInfos
{
get => healthConditionInfos;
set
{
healthConditionInfos = value;
OnPropertyChanged(nameof(HealthConditionInfos));
}
}
…….
public ViewModel()
{
random = new Random();
Patients = GeneratePatientDetails();
SelectedPatient = Patients[2];
……
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
………
}
This XAML code creates a horizontal header with a patient monitor icon and the title Patient Health Monitoring. The image and text are aligned side by side using a StackPanel. It provides a clean and visually appealing introduction to the dashboard.
XAML
<StackPanel Orientation="Horizontal">
<Image Source="/Assets/patient_monitor.png" Width="50" Height="50"/>
<TextBlock Text="Patient Health Monitoring”/>
</StackPanel>
Refer to the following image.
Let’s configure the Syncfusion® WinUI DataGrid control using the provided documentation.
This WinUI XAML code defines two bordered sections for displaying patient data in a health monitoring dashboard. It uses SfDataGrid controls to present structured patient information and health conditions with visual indicators.
XAML
<StackPanel Orientation="Horizontal">
<Border>
<StackPanel Orientation="Vertical">
<TextBlock Text="Patient List"/>
<dataGrid:SfDataGrid AutoGenerateColumns="False" ItemsSource="{Binding Patients}" SelectedItem="{Binding SelectedPatient, Mode=TwoWay}" AllowSorting="False" AllowRowHoverHighlighting="True">
<dataGrid:SfDataGrid.Columns>
<dataGrid:GridTextColumn MappingName="PatientID" HeaderText="ID" TextAlignment="Center" Width="70"/>
………
</dataGrid:SfDataGrid.Columns>
</dataGrid:SfDataGrid>
</StackPanel>
</Border>
<Border>
<StackPanel Orientation="Vertical">
<TextBlock Text="Patient Health Condition"/>
<dataGrid:SfDataGrid AutoGenerateColumns="False" ItemsSource="{Binding HealthConditionInfos}" SelectedItem="{Binding SelectedPatient, Mode=TwoWay}" AllowSorting="False">
<dataGrid:SfDataGrid.Columns>
<dataGrid:GridTextColumn MappingName="Metrics" HeaderText="Metrics" TextAlignment="Center" Width="170"/>
………
</dataGrid:SfDataGrid.Columns>
</dataGrid:SfDataGrid>
</StackPanel>
</Border>
</StackPanel>
Refer to the following image.
Let’s configure the Syncfusion® WinUI Gauges control using the provided Linear gauges and Radial gauges documentation.
This XAML layout displays four key patient vitals using Syncfusion gauges in a clean, vertical and horizontal arrangement. Each gauge is data-bound to a ViewModel property for real-time visualization of health metrics.
XAML
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<Border>
<StackPanel Orientation="Vertical">
<TextBlock Text="Body Temperature (°F)"/>
<gauge:SfLinearGauge Width="270">
<gauge:SfLinearGauge.Axis>
<gauge:LinearAxis Maximum="120">
<gauge:LinearAxis.BarPointers>
<gauge:BarPointer Value="{Binding BodyTemperature}" PointerSize="30" />
</gauge:LinearAxis.BarPointers>
</gauge:LinearAxis>
</gauge:SfLinearGauge.Axis>
</gauge:SfLinearGauge>
</StackPanel>
</Border>
<Border>
<StackPanel Orientation="Vertical">
<TextBlock Text="Blood Cholesterol"/>
<gauge:SfRadialGauge >
……………..
</gauge:SfRadialGauge>
</StackPanel>
</Border>
</StackPanel>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<Border>
<StackPanel Orientation="Vertical">
<TextBlock Text="Heart Rate"/>
<gauge:SfRadialGauge>
…………………….
</gauge:SfRadialGauge>
</StackPanel>
</Border>
<Border>
<StackPanel Orientation="Vertical">
<TextBlock Text="Respiratory Rate"/>
<gauge:SfRadialGauge>
………………….
</gauge:SfRadialGauge>
</StackPanel>
</Border>
</StackPanel>
</StackPanel>
Refer to the following image.
Let’s configure the Syncfusion® WinUI Chart control using the provided documentation.
This XAML layout presents three interactive charts using SfCartesianChart to visualize patient health data. It includes vital metrics, ECG monitoring, and step count tracking, all bound to real-time ViewModel properties.
Displays blood pressure, oxygen saturation, and glucose levels across weekdays.
A Syncfusion® SegmentedControl allows switching between metrics, dynamically updating the chart view.
Plots ECG waveform data using a FastLineSeries for smooth, high-speed rendering.
It visualizes voltage over time to monitor cardiac activity in real time.
Compares actual and target steps count over the past 7 days. Uses column and line series with tooltips and legends for clear activity tracking.
XAML
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Border>
<StackPanel Orientation="Vertical">
<editors:SfSegmentedControlSelectedIndex="0" SelectionChanged="segmentedControl_SelectionChanged">
<x:String>Blood Pressure</x:String>
<x:String>Oxygen Saturation</x:String>
<x:String>Blood Glucose</x:String>
</editors:SfSegmentedControl>
<! —Represents the Major Vital Metrics chart-- >
<chart:SfCartesianChart>
<chart:SfCartesianChart.XAxes>
<chart:CategoryAxis Header="Days"/>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis Header="{Binding AxisTitle}"/>
</chart:SfCartesianChart.YAxes>
<chart:SfCartesianChart.Legend>
<chart:ChartLegend ItemTemplate="{StaticResource labelTemplate}"/>
</chart:SfCartesianChart.Legend>
<chart:SfCartesianChart.TooltipBehavior>
<chart:ChartTooltipBehavior/>
</chart:SfCartesianChart.TooltipBehavior>
<chart:LineSeries ItemsSource="{Binding BloodVitalMetrics}" XBindingPath="Day" YBindingPath="SystolicBP" EnableTooltip="True"/>
<chart:LineSeries ItemsSource="{Binding BloodVitalMetrics}" XBindingPath="Day" EnableTooltip="True" YBindingPath="DiastolicBP"/>
<chart:StepLineSeries ItemsSource="{Binding BloodVitalMetrics}" XBindingPath="Day" YBindingPath="OxygenSaturation" EnableTooltip="True"/>
<chart:ColumnSeries ItemsSource="{Binding BloodVitalMetrics}" XBindingPath="Day" YBindingPath="Glucoselevel" EnableTooltip="True"/>
</chart:SfCartesianChart>
</StackPanel>
</Border>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<Border>
<!—Represents the ECG chart-- >
<chart:SfCartesianChart>
………
</chart:SfCartesianChart>
</Border>
<Border>
<!—Represents the Step Count chart-- >
<chart:SfCartesianChart>
………………..
</chart:SfCartesianChart>
</Border>
</StackPanel>
Refer to the following image.
Let’s configure the Syncfusion® WinUI Chart control using the provided documentation.
This XAML code creates a circular chart to visualize medication adherence using a doughnut series. It displays categories like Taken and Missed with data labels and a legend for clarity.
The chart includes a header titled Medication Adherence and binds to a data source for dynamic updates. Each segment is labeled and color-coded to represent adherence levels effectively.
XAML
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Border>
<chart:SfCircularChart>
<chart:SfCircularChart.Header>
<TextBlock Text="Medication Adherence"/>
</chart:SfCircularChart.Header>
<chart:SfCircularChart.Legend>
<chart:ChartLegend temTemplate="{StaticResource labelTemplate}"/>
</chart:SfCircularChart.Legend>
<chart:DoughnutSeries ItemsSource="{Binding Medications}"
XBindingPath="Name" ShowDataLabels="True" YBindingPath="Value"/>
</chart:SfCircularChart>
</Border>
</StackPanel>
Refer to the following image.
This ViewModel code dynamically updates patient health data in a WinUI dashboard based on the selected patient. It calculates and binds vitals like blood pressure, glucose, heart rate, and respiratory rate to UI components.
It uses methods like SelectionChangedData and DynamicUpdateData to simulate patient-specific values and health conditions. The UpdateHealthCondition method evaluates clinical states and assigns visual indicators for real-time monitoring.
C#
public class ViewModel : INotifyPropertyChanged
{
private PatientInfo? _selectedPatient;
public PatientInfo? SelectedPatient
{
get => _selectedPatient;
set
{
if (value != null)
{
_selectedPatient = value;
OnPropertyChanged(nameof(SelectedPatient));
DynamicUpdateData(SelectedPatient!);
SelectionChangedData(SelectedPatient!);
}
}
}
public ViewModel()
{
// Initialization logic
………
}
// Select the patient in the patients listed data grid
private void SelectionChangedData(PatientInfo patient)
{
………
}
// Set the Person Details
private void SetPersonDetails(
int tempMin, int tempMax,
int cholMin, int cholMax,
int sysMin, int sysMax,
int diaMin, int diaMax,
int satMin, int satMax,
int gluMin, int gluMax,
int medTaken, int medMissed)
{
………..
}
// Get the Health Condition Status
private ObservableCollection<HealthConditionInfo> UpdateHealthCondition()
{
……
}
// Get the Step Counts data
private ObservableCollection UpdateStepCountsData()
{
return new ObservableCollection
{
………
};
}
// Get the ECG wave form data
private double GenerateECGWave(double t)
{
………….
}
// Dynamically Update Heart Rate and Respiratory Rate data
private void DynamicUpdateData(PatientInfo patient)
{
………….
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Finally, arrange all controls in the main layout for a seamless, intuitive, and visually balanced user experience.
XAML
<ScrollViewer HorizontalScrollBarVisibility="Visible">
<StackPanel Orientation="Vertical">
<!--Title-->
<StackPanel Orientation="Horizontal">
...
</StackPanel>
<Grid Padding="15" RowSpacing="15" Margin="0,-5,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="3*"/>
<RowDefinition Height="4*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Grid.DataContext>
<local:ViewModel x:Name="viewModel"/>
</Grid.DataContext>
<StackPanel Orientation="Horizontal" Spacing="15">
<!--Patient List-->
<Border>
...
</Border>
<StackPanel Orientation="Vertical" Spacing="15">
<!--Body Temperature-->
<Border>
...
</Border>
<!--Blood Cholesterol-->
<Border>
...
</Border>
</StackPanel>
<!--Patient Health Condition-->
<Border>
...
</Border>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<!--Major Vital Health Metrics-->
<Border>
...
</Border>
<!--Medical Adherence-->
<Border>
...
</Border>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal" Spacing="15">
<!--ECG Monitor-->
<Border>
...
</Border>
<StackPanel Orientation="Vertical">
<!--Heart Rate-->
<Border>
...
</Border>
<!--Respiratory Rate-->
<Border>
...
</Border>
</StackPanel>
<!--Steps Count-->
<Border>
...
</Border>
</StackPanel>
</Grid>
</StackPanel>
</ScrollViewer>
When you execute these examples, the resulting dashboard will resemble the visualization below, featuring a modern and thoughtfully designed layout.
For more details, refer to the GitHub demo.
Thanks for reading! In this blog, we’ve explored how to build Patient Health Monitoring using Syncfusion® WinUI Controls. By combining Syncfusion® WinUI Charts with real-time data binding, you can create powerful health monitoring dashboards that support clinical decisions and improve patient outcomes. Try it out, explore the GitHub demo, and let us know how Syncfusion® helps you build smarter healthcare solutions in the comments section below.
Explore the new features of Essential Studio® from the license and downloads page or take advantage of our 30-day free trial to transform your data narratives. If you’ve any questions or need support, contact us through our support forum, support portal, or feedback portal. We are always eager to help you! Stay tuned for next week’s featured Chart of the Week.