This demonstrates how to combine line series to produce a term structure chart.
Zooming has been enabled - click and drag with the mouse on the plot area or use the mouse wheel to zoom, double click to unzoom.
Trackballs have been used to show more detailed information when hovering over a point.
Note that this example uses data from an external data source not included in the code snippets - download the examples source code in full to view the data.
XAML + CODE +
<UserControl x:Class="Visiblox.Charts.Examples.TermStructure.TermStructureExample"
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:charts="clr-namespace:Visiblox.Charts;assembly=Visiblox.Charts"
xmlns:local="clr-namespace:Visiblox.Charts.Examples.TermStructure"
xmlns:prims="clr-namespace:Visiblox.Charts.Primitives;assembly=Visiblox.Charts"
mc:Ignorable="d">
<UserControl.Resources>
<prims:UIPointConverter x:Key="UIPointConverter" />
<Style x:Key="NoBorder" TargetType="Border">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="Black" />
</Style>
<Style x:Key="TrackballStyle" TargetType="Ellipse">
<Setter Property="Width" Value="13" />
<Setter Property="Height" Value="13" />
<Setter Property="Stroke" Value="Red" />
<Setter Property="StrokeThickness" Value="1" />
<Setter Property="Fill" Value="#44FFC3AD" />
</Style>
<ControlTemplate x:Key="TrackballTemplate" TargetType="charts:Trackball">
<prims:ZoomCanvas x:Name="LayoutRoot">
<Ellipse Style="{TemplateBinding TrackballStyle}" prims:ZoomCanvas.ElementPosition="{Binding Path=RenderPoint, RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource UIPointConverter}}">
<Ellipse.RenderTransform>
<TranslateTransform X="-7" Y="-7" />
</Ellipse.RenderTransform>
</Ellipse>
</prims:ZoomCanvas>
</ControlTemplate>
<charts:Palette x:Key="LargePointsPalette">
<Style TargetType="charts:LineSeries">
<Setter Property="PointFill" Value="Blue"/>
<Setter Property="Opacity" Value="0.6" />
<Setter Property="PointSize" Value="7"/>
</Style>
</charts:Palette>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="95*" />
<RowDefinition Height="5*" />
</Grid.RowDefinitions>
<!-- Ultimate Trial users should add 'ValidationKey="ENTER TRIAL LICENSE KEY HERE"' to each Chart declaration. -->
<charts:Chart Width="600" Height="350" Name="TermStructureChart" Grid.Row="0" Title="US Government Benchmark" HorizontalAlignment="Center" Background="transparent"
LegendVisibility="Collapsed" Palette="{StaticResource LargePointsPalette}" PlotAreaBorderStyle="{StaticResource NoBorder}">
<charts:Chart.Behaviour>
<charts:BehaviourManager AllowMultipleEnabled="True">
<charts:ZoomBehaviour/>
<charts:TrackballBehaviour x:Name="TrackballBehaviour" />
</charts:BehaviourManager>
</charts:Chart.Behaviour>
<charts:Chart.XAxis>
<charts:LinearAxis Title="Maturity (Years)" MajorTickInterval="5" ShowMinorTicks="False" ShowMajorGridlines="False" >
<!-- Set the range of the charts manually to avoid margins being added -->
<charts:LinearAxis.Range>
<charts:DoubleRange Minimum="0" Maximum="31"/>
</charts:LinearAxis.Range>
</charts:LinearAxis>
</charts:Chart.XAxis>
<charts:Chart.YAxis>
<charts:LinearAxis ShowMinorTicks="False" Title="Yield" ShowMajorGridlines="False" LabelFormatString="0.00'%">
<charts:LinearAxis.Range>
<charts:DoubleRange Minimum="0" Maximum="5.1"/>
</charts:LinearAxis.Range>
</charts:LinearAxis>
</charts:Chart.YAxis>
<charts:Chart.Series>
<charts:LineSeries ShowLine="False" ShowPoints="True" ShowArea="False" TrackballTemplate="{StaticResource TrackballTemplate}"
TrackballStyle="{StaticResource TrackballStyle}"/>
<charts:LineSeries ShowLine="True" ShowArea="False" LineStroke="Black" LineStrokeThickness="1.5"/>
</charts:Chart.Series>
</charts:Chart>
<Border Margin="0, 0, 20, 60" CornerRadius="7" BorderBrush="Black" BorderThickness="1" Width="210" Height="50" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Border.Background>
<LinearGradientBrush EndPoint="0.5, 1" StartPoint="0.5,0">
<GradientStop Color="White" Offset="0.05"/>
<GradientStop Color="#FFEFEFEF" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<Grid Margin="0" >
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding ElementName=TermStructureChart, Path=Behaviour.Behaviours[1].CurrentPoints[0].Model.InstrumentName}"
HorizontalAlignment="Center" FontWeight="Bold" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="130"/>
<ColumnDefinition Width="15"/>
<ColumnDefinition Width="55"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="Years to Maturity" HorizontalAlignment="Right" />
<TextBlock Grid.Column="1" Grid.Row="0" Text=":" Margin="5,0" />
<TextBlock Grid.Column="2" Grid.Row="0" Text="{Binding ElementName=TermStructureChart, Path=Behaviour.Behaviours[1].CurrentPoints[0].X, StringFormat='F02'}" />
<TextBlock Grid.Column="0" Grid.Row="1" Text="Yield" HorizontalAlignment="Right" />
<TextBlock Grid.Column="1" Grid.Row="1" Text=":" Margin="5,0" />
<StackPanel Orientation="Horizontal" Grid.Column="2" Grid.Row="1">
<TextBlock Text="{Binding ElementName=TermStructureChart, Path=Behaviour.Behaviours[1].CurrentPoints[0].Y, StringFormat='F02'}" />
<TextBlock Text="%" />
</StackPanel>
</Grid>
</StackPanel>
</Grid>
</Border>
</Grid>
</UserControl>
^ Back To Top
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Data;
using System.Xml.Linq;
namespace Visiblox.Charts.Examples.TermStructure
{
/// <summary>
/// An example to demonstrate multiple points with a best fit curve
/// drawn through them with trackball behaviour
/// </summary>
public partial class TermStructureExample : UserControl
{
public TermStructureExample()
{
InitializeComponent();
// Assign the first data series and the best fit curve
TermStructureChart.Series[0].DataSeries = GenerateBindableDataSeries();
TermStructureChart.Series[1].DataSeries = GenerateBestFitDataSeries();
// Add the trackball onto the individual points (not the best fit curve)
BehaviourManager behaviourManager = TermStructureChart.Behaviour as BehaviourManager;
(behaviourManager.Behaviours[1] as TrackballBehaviour).Series.Add(TermStructureChart.Series.First());
}
private IDataSeries GenerateBindableDataSeries()
{
BindableDataSeries bindableDataSeries = new BindableDataSeries();
bindableDataSeries.XValueBinding = new Binding("X");
bindableDataSeries.YValueBinding = new Binding("Y");
bindableDataSeries.ItemsSource = CreateYieldCurvePoints();
return bindableDataSeries;
}
private List<YieldPoint> CreateYieldCurvePoints()
{
List<YieldPoint> points = new List<YieldPoint>();
XDocument doc = XDocument.Load("TermStructure/Data/Yield.xml");
IEnumerable<XElement> dataPoints = doc.Descendants("val");
foreach (XElement dataPoint in dataPoints)
{
var xValue = Double.Parse(dataPoint.Attribute("x").Value);
var yValue = Double.Parse(dataPoint.Attribute("y").Value);
var instrumentName = dataPoint.Attribute("label").Value;
points.Add(new YieldPoint(xValue, yValue, instrumentName));
}
return points;
}
private IDataSeries GenerateBestFitDataSeries()
{
DataSeries<double, double> curve = new DataSeries<double, double>();
curve.Title = "Best Fit";
curve.Add(new DataPoint<double, double>(00.00, 0.00));
curve.Add(new DataPoint<double, double>(01.25, 0.50));
curve.Add(new DataPoint<double, double>(02.50, 1.16));
curve.Add(new DataPoint<double, double>(03.75, 1.80));
curve.Add(new DataPoint<double, double>(05.00, 2.30));
curve.Add(new DataPoint<double, double>(06.25, 2.78));
curve.Add(new DataPoint<double, double>(07.50, 3.05));
curve.Add(new DataPoint<double, double>(08.75, 3.35));
curve.Add(new DataPoint<double, double>(10.00, 3.58));
curve.Add(new DataPoint<double, double>(11.25, 3.73));
curve.Add(new DataPoint<double, double>(12.50, 3.88));
curve.Add(new DataPoint<double, double>(13.75, 3.95));
curve.Add(new DataPoint<double, double>(15.00, 4.02));
curve.Add(new DataPoint<double, double>(16.25, 4.07));
curve.Add(new DataPoint<double, double>(17.50, 4.13));
curve.Add(new DataPoint<double, double>(18.75, 4.20));
curve.Add(new DataPoint<double, double>(20.00, 4.25));
curve.Add(new DataPoint<double, double>(21.25, 4.27));
curve.Add(new DataPoint<double, double>(22.50, 4.29));
curve.Add(new DataPoint<double, double>(24.75, 4.30));
curve.Add(new DataPoint<double, double>(26.00, 4.31));
curve.Add(new DataPoint<double, double>(27.25, 4.32));
curve.Add(new DataPoint<double, double>(28.50, 4.33));
curve.Add(new DataPoint<double, double>(30.75, 4.34));
return curve;
}
}
// Data Model
public class YieldPoint
{
public YieldPoint(double xValue, double yValue, string instrumentName)
{
X = xValue;
Y = yValue;
InstrumentName = instrumentName;
}
public double X { get; private set; }
public double Y { get; private set; }
public string InstrumentName { get; private set; }
}
}
^ Back To Top

