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.
The Parallel Coordinate Plot is a WPF chart type for visualizing and analyzing multi dimensional datasets. For example, it can be used to compare several sets of statistical records (represented by lines) with a combination of different statistical features (each represented by an axis).
This example demonstrates how to create, use and interact with Parallel Coordinates Plot with SciChart WPF v6.
The following interactions are possible:
Toolbar Actions
The C#/WPF source code for the WPF Parallel Coordinate Plot 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.SeeFeaturedApplication.ParallelCoordinatePlot.ParallelCoordinatePlotView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
xmlns:ext="http://schemas.abtsoftware.co.uk/scichart/exampleExternals"
Loaded="ParallelCoordinatePlotView_OnLoaded"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/SciChart.Examples.ExternalDependencies;component/Resources/Styles/MergedResources.xaml"/>
<ResourceDictionary Source="/SciChart.Examples.ExternalDependencies;component/Resources/Styles/ToolbarButtonsCommon.xaml"/>
</ResourceDictionary.MergedDictionaries>
<SolidColorBrush x:Key="DefaultAxisBrush" Color="WhiteSmoke"/>
<SolidColorBrush x:Key="AlternativeAxisBrush" Color="Tan"/>
<!-- Defines a Style that is applied to Axes in code-behind -->
<Style x:Key="DefaultParallelAxisStyle" TargetType="{x:Type s:AxisBase}">
<Setter Property="BorderBrush" Value="{StaticResource DefaultAxisBrush}"/>
<Setter Property="BorderThickness" Value="1,0,0,0"/>
<Setter Property="MajorTickLineStyle">
<Setter.Value>
<Style TargetType="{x:Type Line}">
<Setter Property="Stroke" Value="{StaticResource DefaultAxisBrush}"/>
<Setter Property="X2" Value="9"/>
</Style>
</Setter.Value>
</Setter>
<Setter Property="MinorTickLineStyle">
<Setter.Value>
<Style TargetType="{x:Type Line}">
<Setter Property="Stroke" Value="{StaticResource DefaultAxisBrush}"/>
<Setter Property="X2" Value="3"/>
</Style>
</Setter.Value>
</Setter>
<Setter Property="TickLabelStyle">
<Setter.Value>
<Style TargetType="{x:Type s:DefaultTickLabel}">
<Setter Property="Foreground" Value="{StaticResource DefaultAxisBrush}"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="FontSize" Value="12"/>
</Style>
</Setter.Value>
</Setter>
</Style>
<!-- Defines a Style that is applied to Axes in code-behind -->
<Style x:Key="AlternativeParallelAxisStyle" TargetType="{x:Type s:AxisBase}">
<Setter Property="BorderBrush" Value="{StaticResource AlternativeAxisBrush}"/>
<Setter Property="BorderThickness" Value="1,0,0,0"/>
<Setter Property="MajorTickLineStyle">
<Setter.Value>
<Style TargetType="{x:Type Line}">
<Setter Property="Stroke" Value="{StaticResource AlternativeAxisBrush}"/>
<Setter Property="X2" Value="9"/>
</Style>
</Setter.Value>
</Setter>
<Setter Property="MinorTickLineStyle">
<Setter.Value>
<Style TargetType="{x:Type Line}">
<Setter Property="Stroke" Value="{StaticResource AlternativeAxisBrush}"/>
<Setter Property="X2" Value="3"/>
</Style>
</Setter.Value>
</Setter>
<Setter Property="TickLabelStyle">
<Setter.Value>
<Style TargetType="{x:Type s:DefaultTickLabel}">
<Setter Property="Foreground" Value="{StaticResource AlternativeAxisBrush}"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="FontSize" Value="12"/>
</Style>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ParallelAxisTickLabelStyle" TargetType="{x:Type s:DefaultTickLabel}">
<Setter Property="FontSize" Value="14"/>
</Style>
<Style x:Key="ParallelLineSeriesStyle" TargetType="{x:Type s:BaseRenderableSeries}">
<Setter Property="Stroke" Value="#504678B4"/>
<Setter Property="StrokeThickness" Value="1"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Stroke" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="#FF232426"
BorderBrush="#FF323539"
BorderThickness="0,0,2,0"
Canvas.ZIndex="9999">
<StackPanel Orientation="Vertical">
<ToggleButton x:Name="IsZoomEnabled"
IsChecked="True"
Style="{StaticResource ZoomButtonStyle}"
ToolTipService.ToolTip="Toggle Rubber-Band Zoom"
s:ToggleButtonExtensions.GroupName="ParallelCoordinatePlot_Modifiers" />
<ToggleButton x:Name="IsPanEnabled"
Style="{StaticResource PanButtonStyle}"
ToolTipService.ToolTip="Toggle Zoom-Pan"
s:ToggleButtonExtensions.GroupName="ParallelCoordinatePlot_Modifiers" />
<ToggleButton x:Name="IsReorderEnabled"
Style="{StaticResource ReorderButtonStyle}"
ToolTipService.ToolTip="Toggle Y-Axes Reorder"
s:ToggleButtonExtensions.GroupName="ParallelCoordinatePlot_Modifiers" />
<ToggleButton x:Name="IsSelectionEnabled"
Style="{StaticResource PointerButtonStyle}"
ToolTipService.ToolTip="Toggle Series Selection"
s:ToggleButtonExtensions.GroupName="ParallelCoordinatePlot_Modifiers" />
<ext:FlyoutSeparator />
<ToggleButton x:Name="IsSplineEnabled" Style="{StaticResource SplineButtonStyle}"/>
</StackPanel>
</Border>
<!-- Defines Parallel Coordinates Plot control -->
<s:SciChartParallelCoordinateSurface Grid.Column="1"
x:Name="sciChart"
ChartTitle="Weather"
DrawSplines="{Binding IsChecked, Mode=OneWay, ElementName=IsSplineEnabled}"
LabelStyle="{StaticResource ParallelAxisTickLabelStyle}"
RenderableSeriesStyle="{StaticResource ParallelLineSeriesStyle}">
<s:SciChartParallelCoordinateSurface.ChartModifier>
<s:ModifierGroup>
<s:ZoomPanModifier XyDirection="XDirection" IsEnabled="{Binding IsChecked, Mode=OneWay, ElementName=IsPanEnabled}"/>
<s:RubberBandXyZoomModifier IsXAxisOnly="True" IsEnabled="{Binding IsChecked, Mode=OneWay, ElementName=IsZoomEnabled}"/>
<s:ParallelAxisReorderModifier AxesReordered="OnAxisReordered" IsEnabled="{Binding IsChecked, Mode=OneWay, ElementName=IsReorderEnabled}"/>
<s:SeriesSelectionModifier IsEnabled="{Binding IsChecked, Mode=OneWay, ElementName=IsSelectionEnabled}"/>
<s:MouseWheelZoomModifier XyDirection="XDirection"/>
<s:ZoomExtentsModifier/>
</s:ModifierGroup>
</s:SciChartParallelCoordinateSurface.ChartModifier>
</s:SciChartParallelCoordinateSurface>
</Grid>
</UserControl>
using System;
using System.Windows;
using System.Windows.Controls;
using SciChart.Charting.ChartModifiers;
using SciChart.Charting.Visuals.RenderableSeries;
using SciChart.Examples.ExternalDependencies.Data;
namespace SciChart.Examples.Examples.SeeFeaturedApplication.ParallelCoordinatePlot
{
public partial class ParallelCoordinatePlotView : UserControl
{
private ParallelCoordinateDataSource<WeatherData> _pcSource;
public ParallelCoordinatePlotView()
{
InitializeComponent();
}
private void ParallelCoordinatePlotView_OnLoaded(object sender, RoutedEventArgs e)
{
sciChart.ShowLicensingWarnings = false;
var defaultAxisStyle = (Style)FindResource("DefaultParallelAxisStyle");
var alternativeAxisStyle = (Style)FindResource("AlternativeParallelAxisStyle");
_pcSource = new ParallelCoordinateDataSource<WeatherData>(
new ParallelCoordinateDataItem<WeatherData, DateTime>(p => p.Date)
{
Title = "Time",
AxisStyle = defaultAxisStyle
},
new ParallelCoordinateDataItem<WeatherData, double>(p => p.MinTemp)
{
Title = "Min Temp",
AxisStyle = alternativeAxisStyle
},
new ParallelCoordinateDataItem<WeatherData, double>(p => p.MaxTemp)
{
Title = "Max Temp",
AxisStyle = defaultAxisStyle
},
new ParallelCoordinateDataItemString<WeatherData>(p => p.Forecast)
{
Title = "Forecast",
AxisStyle = alternativeAxisStyle
},
new ParallelCoordinateDataItem<WeatherData, double>(p => p.Rainfall)
{
Title = "Rainfall",
AxisStyle = defaultAxisStyle
},
new ParallelCoordinateDataItem<WeatherData, int>(p => p.UVIndex)
{
Title = "UV Index",
AxisStyle = alternativeAxisStyle
},
new ParallelCoordinateDataItem<WeatherData, double>(p => p.Sunshine)
{
Title = "Sunshine",
AxisStyle = defaultAxisStyle
},
new ParallelCoordinateDataItemString<WeatherData>(p => p.WindDirection.ToString())
{
Title = "Wind Direction",
AxisStyle = alternativeAxisStyle
},
new ParallelCoordinateDataItem<WeatherData, int>(p => p.WindSpeed)
{
Title = "Wind Speed",
AxisStyle = defaultAxisStyle
},
new ParallelCoordinateDataItem<WeatherData, bool>(p => p.LocalStation)
{
Title = "Local Station",
AxisStyle = alternativeAxisStyle
});
_pcSource.SetValues(DataManager.Instance.LoadWeatherData());
sciChart.ParallelCoordinateDataSource = _pcSource;
}
private void OnAxisReordered(object sender, ParallelAxisReorderArgs args)
{
_pcSource?.ReorderItems(args.OldIndex, args.NewIndex);
}
}
}