Skip to content

Learn how to add and dynamically update a target line in WPF SfChart using Annotation. Customize its appearance and functionality effortlessly.

Notifications You must be signed in to change notification settings

SyncfusionExamples/How-to-create-and-dynamically-update-target-line-for-WPF-Chart

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 

Repository files navigation

How to create and dynamically update target line for WPF Chart

This article provides a detailed walkthrough on how to create and dynamically update target line in WPF Chart.

The SfChart includes support for Annotations, enabling the addition of various types of annotations to enhance chart visualization. Using HorizontalLineAnnotation, you can create and dynamically adjust the target line.

The Horizontal Line Annotation includes following property:

  • Y1 - Represents the Y1 Coordinate of the horizontal line Annotation.
  • Stroke - Represents the brush for the horizontal line annotation outline.
  • StrokeThickness - Represents the thickness of the horizontal line annotation outline.
  • StrokeDashArray - Represents the DashArray of the horizontal line annotation stroke.
  • Text - Gets or sets the description text for horizontal line Annotation.

Learn step-by-step instructions and gain insights to create and dynamically update the target line.

Step 1: The layout is created using a grid with two columns.

XAML

<Grid>

   <Grid.ColumnDefinitions>
       <ColumnDefinition Width="*"></ColumnDefinition>
       <ColumnDefinition Width="200"></ColumnDefinition>
   </Grid.ColumnDefinitions>

</Grid> 

Step 2: In first column of grid layout, initialize the SfChart and add the axes and series as shown below.

XAML

<chart:SfChart Grid.Column="0">

   <chart:SfChart.PrimaryAxis>
       <chart:CategoryAxis EdgeLabelsDrawingMode="Fit" ShowGridLines="False" Header="Months"/>
   </chart:SfChart.PrimaryAxis>

   <chart:SfChart.SecondaryAxis>
       <chart:NumericalAxis x:Name="Y_Axis" Minimum="0" Maximum="20000" Interval="5000" ShowGridLines="False" Header="Revenue" LabelFormat="'$'0" PlotOffsetEnd="30"/>
   </chart:SfChart.SecondaryAxis>

   <chart:ColumnSeries ItemsSource="{Binding Data}"
                   XBindingPath="Months"
                   YBindingPath="Revenue"
                   Palette="Custom"
                   Opacity="0.7">
       <chart:ColumnSeries.ColorModel>
           <chart:ChartColorModel>
               <chart:ChartColorModel.CustomBrushes>
                   ......
               </chart:ChartColorModel.CustomBrushes>
           </chart:ChartColorModel>
       </chart:ColumnSeries.ColorModel>
   </chart:ColumnSeries>

</chart:SfChart> 

Step 3: The HorizontalLineAnnotation is initialized within the Annotations collection of the SfChart to mark a dynamic target value on the Y-axis. The Y1 property is data-bound to the ViewModel, allowing the target line to adjust dynamically when the value changes.

XAML

<chart:SfChart Grid.Column="0">
  .....
   <chart:SfChart.Annotations>
       <chart:HorizontalLineAnnotation Y1="{Binding Y1}"
                                       Stroke="Black"
                                       StrokeThickness="2"
                                       Text="Target"
                                       ......>
       </chart:HorizontalLineAnnotation>
   </chart:SfChart.Annotations>
  .....
</chart:SfChart> 

C#

internal class ViewModel : INotifyPropertyChanged
{
   private double y1;
   public double Y1
   {
       get => y1;
       set
       {
           if(y1 != value)
           {
               y1 = value;
               OnPropertyChanged(nameof(Y1));
           }
       }
   }

   public event PropertyChangedEventHandler? PropertyChanged;

   protected void OnPropertyChanged(string name)
   {
       PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
   }

   .....
   
   public ViewModel()
   {
       Y1 = 12000;
       .....
   }
} 

Step 4: The second column of the grid layout contains a StackPanel with a Slider, TextBox and TextBlock, allowing the user to change the annotation value dynamically. The TextBox_TextChanged event ensures valid input by clamping values between 0 and the maximum of the Y_Axis.

XAML

<StackPanel Orientation="Vertical" Margin="10" Grid.Column="1">

   <TextBlock Text="Adjust Target Line" FontSize="16" FontWeight="Bold" TextAlignment="Center" HorizontalAlignment="Center" Margin="0,0,0,20"/>
   <TextBox Text="{Binding Y1}" HorizontalAlignment="Stretch" VerticalAlignment="Center" TextChanged="TextBox_TextChanged" Margin="0,0,0,20" Padding="10"/>
   <Slider Minimum="{Binding Minimum, Source={x:Reference Y_Axis}}" 
           Maximum="{Binding Maximum, Source={x:Reference Y_Axis}}" 
           Value="{Binding Y1}" HorizontalAlignment="Stretch"/>

</StackPanel> 

This code handles the TextChanged event for a TextBox, dynamically updating the Y1 property in the ViewModel while ensuring the value stays within the axis’s maximum and minimum bounds. It also manages text formatting and prevents recursive event triggers.

C#

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
   if (Y_Axis == null) return;
   var maxValue = Y_Axis.Maximum;

   if (sender is TextBox textBox)
   {
       textBox.TextChanged -= TextBox_TextChanged;

       if (string.IsNullOrWhiteSpace(textBox.Text))
       {
           viewModel.Y1 = double.MinValue;
           textBox.Text = string.Empty;
       }
       else
       {
           if (int.TryParse(textBox.Text, out int newValue))
           {
               if (newValue > maxValue)
                   newValue = (int)maxValue;
               else if (newValue < 0)
                   newValue = 0;

               viewModel.Y1 = newValue;

               textBox.Text = newValue.ToString();
               textBox.CaretIndex = textBox.Text.Length;
           }
           else
           {
               textBox.Text = ((int)viewModel.Y1).ToString();
               textBox.CaretIndex = textBox.Text.Length;
           }
       }

       textBox.TextChanged += TextBox_TextChanged;
   }
} 

Step 5: This code defines a HorizontalLineAnnotation for a SfChart, representing a horizontal line at a specified Y-axis value. It includes custom styling such as dashed stroke, text with font formatting, and text alignment settings.

XAML

<chart:SfChart Grid.Column="0">

       .....

       <chart:SfChart.Annotations>
           <chart:HorizontalLineAnnotation Y1="{Binding Y1}"
                                       Stroke="Black"
                                       StrokeThickness="2"
                                       StrokeDashArray="5,2,2"
                                       Text="Target"
                                       FontSize="14"
                                       FontWeight="Bold" 
                                       HorizontalTextAlignment="Left"
                                       VerticalTextAlignment="Top">
           </chart:HorizontalLineAnnotation>
       </chart:SfChart.Annotations>

       .....

</chart:SfChart>

Output:

DynamicTargetLine1

Troubleshooting

Path too long exception

If you are facing a path too long exception when building this example project, close Visual Studio and rename the repository to a shorter name before building the project.

For more details, refer to the KB on how to create and dynamically update target line for WPF Chart.

About

Learn how to add and dynamically update a target line in WPF SfChart using Annotation. Customize its appearance and functionality effortlessly.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages