SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, iOS Chart, Android Chart and JavaScript Chart Components
SciChart WPF ships with hundreds of WPF Chart Examples which you can browse, play with, view the source-code and even export each WPF Chart Example to a stand-alone Visual Studio solution. All of this is possible with the new and improved SciChart WPF Examples Suite, which ships as part of the SciChart WPF SDK.
This example shows how to create a Static Axis – where ticks and gridlines do not move – by setting the AxisBase.IsStaticAxis property to true.
The X axis is made static so tick labels on axis are always at the same positions. Instead, axis label values update according to displayed data. On the chart there is also annotation collection with VerticalLineAnnotations.
Tips!
This example looks a lot better using the new HighQualityRenderSurface due to its superior handling of transparency. For maximum performance use the Visual Xccelerator Engine.
Documentation Links
– AxisBase.IsStaticAxis property
– StaticTickCoordinatesProvider type
The C#/WPF source code for the WPF Chart Realtime Series Values on Axis example is included below (Scroll down!).
Did you know you can also view the source code from one of the following sources as well?
<UserControl x:Class="SciChart.Examples.Examples.CreateRealtimeChart.UsingSeriesValueModifier"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
Loaded="OnExampleLoaded"
Unloaded="OnExampleUnloaded"
d:DesignHeight="400"
d:DesignWidth="600"
mc:Ignorable="d">
<UserControl.Resources>
<!-- Converter used by feedback panel below SciChartSurface -->
<s:ColorToBrushConverter x:Key="ColorToBrushConverter" />
<s:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<!-- DataContext is SeriesInfo for each legend row -->
<!-- This is not part of the example, but just to toggle features on and off such as -->
<!-- RenderableSeries.IsVisible and setting the SeriesValueModifier.IsSeriesValueModifierEnabled attached property -->
<DataTemplate x:Key="CustomLegendTemplate" DataType="s:SciChartLegend">
<Grid Margin="2,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Series icon, binds to SeriesInfo.Stroke -->
<Ellipse Grid.Column="0"
Width="10"
Height="10"
Margin="5,0,20,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Fill="{Binding Stroke,
Converter={StaticResource ColorToBrushConverter}}" />
<!-- Series name (SeriesInfo.SeriesName) -->
<TextBlock Grid.Column="1"
Width="90"
HorizontalAlignment="Center"
Text="{Binding SeriesName}" />
<!-- Show or hide the 'Visibility Checkboxes' -->
<Grid Grid.Column="2" Visibility="{Binding DataContext.ShowVisibilityCheckboxes, ElementName=PART_LegendItems, Converter={StaticResource BooleanToVisibilityConverter}}">
<!-- Binds to SeriesInfo.IsVisible to show and hide the series -->
<CheckBox HorizontalAlignment="Left"
VerticalAlignment="Center"
Content="R-Series Visible?"
Foreground="{Binding Stroke,
Converter={StaticResource ColorToBrushConverter}}"
IsChecked="{Binding IsVisible,
Mode=TwoWay}" />
</Grid>
<!-- Binds to SeriesInfo.RenderableSeries, attached property SeriesValueModifier.IsSeriesValueModifierEnabled -->
<!-- This demonstrates how to enable or disable the axis markers per series. If you want to do this you can -->
<!-- just bind to or set SeriesValueModifier.IsSeriesValueModifierEnabled, no need to create the legend, we just do that for demo purposes -->
<CheckBox Grid.Column="3"
Margin="10,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Content="IsSeriesValueModifierEnabled?"
DataContext="{Binding RenderableSeries}"
Foreground="{Binding Stroke,
Converter={StaticResource ColorToBrushConverter}}"
IsChecked="{Binding Path=(s:SeriesValueModifier.IncludeSeries),
Mode=TwoWay}" />
</Grid>
</DataTemplate>
</UserControl.Resources>
<!-- This is where the example starts -->
<Grid>
<s:SciChartSurface x:Name="sciChartSurface">
<s:SciChartSurface.RenderableSeries>
<!-- The three RenderableSeries are controlled from the legend -->
<!-- If you set RenderableSeries.IsVisible = false, it will hide the renderableseries but not the Axis Marker -->
<!-- If you set SeriesValueModifier.IsSeriesValueModifierEnabled=False on the RenderableSeries, it will hide the axis marker but not the series -->
<s:FastLineRenderableSeries x:Name="renderableSeries0"
Stroke="DarkOrange"
StrokeThickness="2" />
<s:FastLineRenderableSeries x:Name="renderableSeries1"
Stroke="SteelBlue"
StrokeThickness="2" />
<s:FastLineRenderableSeries x:Name="renderableSeries2"
Stroke="DarkOliveGreen"
StrokeThickness="2" />
</s:SciChartSurface.RenderableSeries>
<s:SciChartSurface.XAxis>
<s:NumericAxis AutoRange="Always"
AxisTitle="Time (Seconds)"
TextFormatting="0.0" />
</s:SciChartSurface.XAxis>
<s:SciChartSurface.YAxis>
<s:NumericAxis AutoRange="Always"
AxisTitle="Amplitude (Volts)"
DrawMajorBands="True"
GrowBy="0.1, 0.1"
TextFormatting="0.00" />
</s:SciChartSurface.YAxis>
<s:SciChartSurface.ChartModifier>
<s:ModifierGroup>
<s:CursorModifier />
<!-- SeriesValueModifier: This Provides axis markers per series, for each RenderableSeries that -->
<!-- has SeriesValueModifier.IsSeriesValueModifierEnabled=True -->
<s:SeriesValueModifier />
<s:LegendModifier x:Name="legendModifier"
Margin="10"
GetLegendDataFor="AllSeries"
LegendItemTemplate="{StaticResource CustomLegendTemplate}"
ShowLegend="True"
ShowVisibilityCheckboxes="True" />
</s:ModifierGroup>
</s:SciChartSurface.ChartModifier>
</s:SciChartSurface>
</Grid>
</UserControl>
// *************************************************************************************
// SCICHART® Copyright SciChart Ltd. 2011-2021. All rights reserved.
//
// Web: http://www.scichart.com
// Support: support@scichart.com
// Sales: sales@scichart.com
//
// UsingSeriesValueModifier.xaml.cs is part of the SCICHART® Examples. Permission is hereby granted
// to modify, create derivative works, distribute and publish any part of this source
// code whether for commercial, private or personal use.
//
// The SCICHART® examples are distributed in the hope that they will be useful, but
// without any warranty. It is provided "AS IS" without warranty of any kind, either
// expressed or implied.
// *************************************************************************************
using System;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using SciChart.Charting.Model.DataSeries;
namespace SciChart.Examples.Examples.CreateRealtimeChart
{
public partial class UsingSeriesValueModifier : UserControl
{
// Data Sample Rate (sec) - 20 Hz
private const double dt = 0.05;
// FIFO Size is 100 samples, meaning after 100 samples have been appended, each new sample appended
// results in one sample being discarded
private const int FifoSize = 100;
// Timer to process updates
private readonly Timer _timerNewDataUpdate;
// The current time
private double t;
// The dataseries to fill
private readonly IXyDataSeries<double, double> _series0;
private readonly IXyDataSeries<double, double> _series1;
private readonly IXyDataSeries<double, double> _series2;
public UsingSeriesValueModifier()
{
InitializeComponent();
_timerNewDataUpdate = new Timer(dt * 1000) {AutoReset = true};
_timerNewDataUpdate.Elapsed += OnNewData;
// Create new dataseries of type X=double, Y=double
_series0 = new XyDataSeries<double, double> {FifoCapacity = FifoSize, SeriesName = "Orange Series"};
_series1 = new XyDataSeries<double, double> {FifoCapacity = FifoSize, SeriesName = "Blue Series"};
_series2 = new XyDataSeries<double, double> {FifoCapacity = FifoSize, SeriesName = "Green Series"};
// Set the dataseries on the chart's RenderableSeries
renderableSeries0.DataSeries = _series0;
renderableSeries1.DataSeries = _series1;
renderableSeries2.DataSeries = _series2;
}
private void ClearDataSeries()
{
using (sciChartSurface.SuspendUpdates())
{
_series0?.Clear();
_series1?.Clear();
_series2?.Clear();
}
}
private void OnNewData(object sender, EventArgs e)
{
// Compute our three series values
double y1 = 3.0 * Math.Sin(2 * Math.PI * 1.4 * t * 0.02);
double y2 = 2.0 * Math.Cos(2 * Math.PI * 0.8 * t * 0.02);
double y3 = 1.0 * Math.Sin(2 * Math.PI * 2.2 * t * 0.02);
// Suspending updates is optional, and ensures we only get one redraw
// once all three dataseries have been appended to
using (sciChartSurface.SuspendUpdates())
{
// Append x,y data to previously created series
_series0.Append(t, y1);
_series1.Append(t, y2);
_series2.Append(t, y3);
}
// Increment current time
t += dt;
}
private void OnExampleLoaded(object sender, RoutedEventArgs e)
{
ClearDataSeries();
_timerNewDataUpdate.Start();
}
private void OnExampleUnloaded(object sender, RoutedEventArgs e)
{
_timerNewDataUpdate?.Stop();
}
}
}