Neuerstellung

- Quelle: https://github.com/oxyplot/oxyplot
This commit is contained in:
2023-09-02 09:24:59 +02:00
commit 9520c1fa4a
810 changed files with 117869 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
<Application x:Class="ExampleBrowser.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>

View File

@@ -0,0 +1,24 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="App.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for App.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Windows;
namespace ExampleBrowser
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

View File

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;net6.0-windows;net7.0-windows</TargetFrameworks>
<UseWPF>true</UseWPF>
<OutputType>WinExe</OutputType>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\OxyPlot.SkiaSharp.Wpf\OxyPlot.SkiaSharp.Wpf.csproj" />
<ProjectReference Include="..\..\..\OxyPlot.Wpf\OxyPlot.Wpf.csproj" />
<ProjectReference Include="..\..\..\OxyPlot\OxyPlot.csproj" />
<ProjectReference Include="..\..\ExampleLibrary\ExampleLibrary.csproj" />
</ItemGroup>
<ItemGroup>
<Resource Include="..\..\..\..\Icons\OxyPlot_64.png" Link="OxyPlot_64.png" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,133 @@
<Window x:Class="ExampleBrowser.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxyWpf="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf"
xmlns:oxySkia="clr-namespace:OxyPlot.SkiaSharp.Wpf;assembly=OxyPlot.SkiaSharp.Wpf"
xmlns:local="clr-namespace:ExampleBrowser"
Title="OxyPlot.WPF Example Browser"
Height="720" Width="1280" Icon="OxyPlot_64.png">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Window.Resources>
<SolidColorBrush x:Key="HotItemBackground" Color="#e6f3f7"/>
<SolidColorBrush x:Key="SelectedItemBorder" Color="#6dbdd1"/>
<SolidColorBrush x:Key="SelectedItemBackground" Color="#cbe6ef"/>
<SolidColorBrush x:Key="NormalItemBackground" Color="White"/>
<DrawingBrush x:Key="CheckerBoard" TileMode="Tile" ViewboxUnits="Absolute" Viewbox="0,0,2,2" Viewport="0,0,10,10" ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="White">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,2,2" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="LightGray">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0,0,1,1" />
<RectangleGeometry Rect="1,1,1,1" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
<Style x:Key="ListboxItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Background" Value="{StaticResource NormalItemBackground}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<Rectangle Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}"
StrokeThickness="{TemplateBinding BorderThickness}" RadiusX="3" RadiusY="3" SnapsToDevicePixels="True"/>
<ContentPresenter Margin="8,5" />
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background" Value="{StaticResource HotItemBackground}" />
</MultiTrigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource SelectedItemBackground}" />
<Setter Property="BorderBrush" Value="{StaticResource SelectedItemBorder}" />
<Setter Property="BorderThickness" Value="1" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Grid Background="#20000000">
<ListBox ItemsSource="{Binding ExamplesView}" ItemContainerStyle="{DynamicResource ListboxItemStyle}"
SelectedItem="{Binding SelectedExample}" BorderThickness="0,0,0,1">
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="False" ExpandDirection="Down">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock FontWeight="Bold" Text="{Binding Name}" Padding="0 0 8 0"/>
<TextBlock Text="{Binding ItemCount, StringFormat='({0})'}"/>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListBox.GroupStyle>
</ListBox>
</Grid>
<Grid Grid.Column="1">
<TabControl TabStripPlacement="Bottom">
<TabControl.Resources>
<Style TargetType="{x:Type TextBox}" x:Key="CodeTextBox">
<Setter Property="AcceptsReturn" Value="True"></Setter>
<Setter Property="FontFamily" Value="Consolas"></Setter>
<Setter Property="BorderThickness" Value="0"></Setter>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"></Setter>
</Style>
</TabControl.Resources>
<TabItem Header="Plot">
<Grid>
<Grid.Resources>
<local:NotNullVisibilityConverter x:Key="NotNullVisibilityConverter" />
</Grid.Resources>
<oxySkia:PlotView Model="{Binding SkiaModel}" Controller="{Binding SelectedExample.PlotController}" Visibility="{Binding SkiaModel, Converter={StaticResource NotNullVisibilityConverter}}" />
<oxyWpf:PlotView Model="{Binding CanvasModel}" Controller="{Binding SelectedExample.PlotController}" Visibility="{Binding CanvasModel, Converter={StaticResource NotNullVisibilityConverter}}" />
<local:XamlPlotView Model="{Binding CanvasXamlModel}" Controller="{Binding SelectedExample.PlotController}" Visibility="{Binding CanvasXamlModel, Converter={StaticResource NotNullVisibilityConverter}}" />
</Grid>
</TabItem>
<TabItem Header="Code">
<TextBox Text="{Binding Code, Mode=OneWay}" Style="{StaticResource CodeTextBox}" />
</TabItem>
</TabControl>
<StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Right" Orientation="Horizontal">
<TextBlock Text="Renderer:" VerticalAlignment="Center" />
<ComboBox SelectedItem="{Binding Renderer}" ItemsSource="{Binding Renderers}" Margin="3,0,0,0" Width="80" />
<CheckBox IsChecked="{Binding Transposed}" Content="Transposed" VerticalAlignment="Center" Margin="10,0,5,0" IsEnabled="{Binding CanTranspose}" />
<CheckBox IsChecked="{Binding Reversed}" Content="Reversed" VerticalAlignment="Center" Margin="10,0,5,0" IsEnabled="{Binding CanReverse}" />
</StackPanel>
</Grid>
</Grid>
</Window>

View File

@@ -0,0 +1,34 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ExampleBrowser
{
using Microsoft.Win32;
using System.Windows;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
/// <summary>
/// Initializes a new instance of the <see cref="MainWindow" /> class.
/// </summary>
public MainWindow()
{
this.InitializeComponent();
SystemEvents.DisplaySettingsChanged += this.SystemEvents_DisplaySettingsChanged;
}
private void SystemEvents_DisplaySettingsChanged(object sender, System.EventArgs e)
{
(this.DataContext as MainWindowViewModel)?.ActiveModel?.PlotView?.InvalidatePlot(false);
}
}
}

View File

@@ -0,0 +1,165 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindowViewModel.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace ExampleBrowser
{
using ExampleLibrary;
using OxyPlot;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Data;
public class MainWindowViewModel : INotifyPropertyChanged
{
private bool _CanTranspose;
private bool _CanReverse;
private string _Code;
private Renderer _Renderer;
private PlotModel _PlotModel;
private bool _Transposed;
private bool _Reversed;
private IEnumerable<ExampleInfo> examples;
private ExampleInfo selectedExample;
public MainWindowViewModel()
{
this.Examples = ExampleLibrary.Examples.GetList();
this.ExamplesView = CollectionViewSource.GetDefaultView(this.Examples.OrderBy(e => e.Category));
this.ExamplesView.GroupDescriptions.Add(new PropertyGroupDescription("Category"));
}
public event PropertyChangedEventHandler PropertyChanged;
public PlotModel ActiveModel => this.CanvasModel ?? this.SkiaModel;
public bool CanTranspose
{
get => this._CanTranspose;
private set
{
this._CanTranspose = value;
this.RaisePropertyChanged(nameof(this.CanTranspose));
}
}
public bool CanReverse
{
get => this._CanReverse;
private set
{
this._CanReverse = value;
this.RaisePropertyChanged(nameof(this.CanReverse));
}
}
public PlotModel CanvasModel => this.Renderer == Renderer.Canvas ? this._PlotModel : null;
public string Code
{
get => this._Code;
set
{
this._Code = value;
this.RaisePropertyChanged(nameof(this.Code));
}
}
public IEnumerable<ExampleInfo> Examples
{
get => this.examples;
set
{
this.examples = value;
this.RaisePropertyChanged(nameof(this.Examples));
}
}
public ICollectionView ExamplesView { get; set; }
public Renderer Renderer
{
get => this._Renderer;
set
{
this._Renderer = value;
this.CoerceRenderer();
this.RaisePropertyChanged(nameof(this.Renderer));
}
}
private void CoerceRenderer()
{
((IPlotModel)this._PlotModel)?.AttachPlotView(null);
this.RaisePropertyChanged(nameof(this.SkiaModel));
this.RaisePropertyChanged(nameof(this.CanvasXamlModel));
this.RaisePropertyChanged(nameof(this.CanvasModel));
}
public IEnumerable<Renderer> Renderers => Enum.GetValues(typeof(Renderer)).Cast<Renderer>();
public ExampleInfo SelectedExample
{
get => this.selectedExample;
set
{
this.selectedExample = value;
this.CoerceSelectedExample();
this.RaisePropertyChanged(nameof(this.SelectedExample));
}
}
public PlotModel SkiaModel => this.Renderer == Renderer.SkiaSharp ? this._PlotModel : null;
public PlotModel CanvasXamlModel => this.Renderer == Renderer.Canvas_XAML ? this._PlotModel : null;
public bool Transposed
{
get => this._Transposed;
set
{
this._Transposed = value;
this.UpdatePlotModel();
this.RaisePropertyChanged(nameof(this.Transposed));
}
}
public bool Reversed
{
get => this._Reversed;
set
{
this._Reversed = value;
this.UpdatePlotModel();
this.RaisePropertyChanged(nameof(this.Reversed));
}
}
protected void RaisePropertyChanged(string property)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
private void CoerceSelectedExample()
{
this.CanTranspose = this.SelectedExample?.IsTransposable == true;
this.CanReverse = this.SelectedExample?.IsReversible == true;
this.UpdatePlotModel();
}
private void UpdatePlotModel()
{
var flags = ExampleInfo.PrepareFlags(
this.CanTranspose && this.Transposed,
this.CanReverse && this.Reversed);
this._PlotModel = this.SelectedExample?.GetModel(flags);
this.Code = this.SelectedExample?.GetCode(flags);
this.CoerceRenderer();
}
}
}

View File

@@ -0,0 +1,28 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="NotNullVisibilityConverter.cs" company="OxyPlot">
// Copyright (c) 2020 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace ExampleBrowser
{
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
public sealed class NotNullVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value == null
? Visibility.Collapsed
: Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}
}

View File

@@ -0,0 +1,9 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AssemblyInfo.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Windows;
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

View File

@@ -0,0 +1,15 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Renderer.cs" company="OxyPlot">
// Copyright (c) 2020 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace ExampleBrowser
{
public enum Renderer
{
Canvas,
Canvas_XAML,
SkiaSharp
}
}

View File

@@ -0,0 +1,22 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="XamlPlotView.cs" company="OxyPlot">
// Copyright (c) 2020 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace ExampleBrowser
{
using OxyPlot;
using OxyPlot.Wpf;
/// <summary>
/// Represents a PlotView which uses the XamlRenderContext for rendering.
/// </summary>
public class XamlPlotView : PlotView
{
protected override IRenderContext CreateRenderContext()
{
return new XamlRenderContext(this.Canvas);
}
}
}

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="foo"/>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitor</dpiAwareness>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
</assembly>

View File

@@ -0,0 +1,8 @@
<Application x:Class="SimpleDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>

View File

@@ -0,0 +1,25 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="App.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for App.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
namespace SimpleDemo
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

View File

@@ -0,0 +1,59 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainViewModel.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Represents the view-model for the main window.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace SimpleDemo
{
using OxyPlot;
using OxyPlot.Series;
/// <summary>
/// Represents the view-model for the main window.
/// </summary>
public class MainViewModel
{
/// <summary>
/// Initializes a new instance of the <see cref="MainViewModel" /> class.
/// </summary>
public MainViewModel()
{
// Create the plot model
var tmp = new PlotModel { Title = "Simple example", Subtitle = "using OxyPlot" };
// Create two line series (markers are hidden by default)
var series1 = new LineSeries { Title = "Series 1", MarkerType = MarkerType.Circle };
series1.Points.Add(new DataPoint(0, 0));
series1.Points.Add(new DataPoint(10, 18));
series1.Points.Add(new DataPoint(20, 12));
series1.Points.Add(new DataPoint(30, 8));
series1.Points.Add(new DataPoint(40, 15));
var series2 = new LineSeries { Title = "Series 2", MarkerType = MarkerType.Square };
series2.Points.Add(new DataPoint(0, 4));
series2.Points.Add(new DataPoint(10, 12));
series2.Points.Add(new DataPoint(20, 16));
series2.Points.Add(new DataPoint(30, 25));
series2.Points.Add(new DataPoint(40, 5));
// Add the series to the plot model
tmp.Series.Add(series1);
tmp.Series.Add(series2);
// Axes are created automatically if they are not defined
// Set the Model property, the INotifyPropertyChanged event will make the WPF Plot control update its content
this.Model = tmp;
}
/// <summary>
/// Gets the plot model.
/// </summary>
public PlotModel Model { get; private set; }
}
}

View File

@@ -0,0 +1,14 @@
<Window x:Class="SimpleDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf"
xmlns:simpleDemo="clr-namespace:SimpleDemo"
Title="OxyPlot SimpleDemo" Height="480" Width="640">
<Window.DataContext>
<simpleDemo:MainViewModel />
</Window.DataContext>
<Grid>
<!-- The OxyPlot control is binding to a PlotModel in the MainViewModel -->
<oxy:PlotView Model="{Binding Model}" />
</Grid>
</Window>

View File

@@ -0,0 +1,25 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace SimpleDemo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow
{
/// <summary>
/// Initializes a new instance of the <see cref="MainWindow" /> class.
/// </summary>
public MainWindow()
{
this.InitializeComponent();
}
}
}

View File

@@ -0,0 +1,9 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AssemblyInfo.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System.Windows;
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

View File

@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0-windows</TargetFrameworks>
<UseWPF>true</UseWPF>
<OutputType>WinExe</OutputType>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\OxyPlot.Wpf\OxyPlot.Wpf.csproj" />
<ProjectReference Include="..\..\..\OxyPlot\OxyPlot.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup></configuration>

View File

@@ -0,0 +1,8 @@
<Application x:Class="WpfExamples.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>

View File

@@ -0,0 +1,25 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="App.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for App.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
namespace WpfExamples
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

View File

@@ -0,0 +1,24 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="BitmapTools.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace WpfExamples
{
using System.Drawing;
using System.Drawing.Drawing2D;
public static class BitmapTools
{
public static Bitmap Resize(Bitmap bitmap, int newWidth, int newHeight)
{
var resizedBitmap = new Bitmap(newWidth, newHeight);
var g = Graphics.FromImage(resizedBitmap);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(bitmap, 0, 0, newWidth, newHeight);
g.Dispose();
return resizedBitmap;
}
}
}

View File

@@ -0,0 +1,104 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DelegateCommand.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Represents a delegate command.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace WpfExamples
{
using System;
using System.Windows.Input;
/// <summary>
/// Represents a delegate command.
/// </summary>
public class DelegateCommand : ICommand
{
/// <summary>
/// The can execute.
/// </summary>
private readonly Func<bool> canExecute;
/// <summary>
/// The execute.
/// </summary>
private readonly Action execute;
/// <summary>
/// Initializes a new instance of the <see cref="DelegateCommand" /> class.
/// </summary>
/// <param name="execute">The execute.</param>
public DelegateCommand(Action execute)
: this(execute, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="DelegateCommand" /> class.
/// </summary>
/// <param name="execute">The execute.</param>
/// <param name="canExecute">The can execute.</param>
public DelegateCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
this.execute = execute;
this.canExecute = canExecute;
}
/// <summary>
/// Occurs when changes occur that affect whether or not the command should execute.
/// </summary>
public event EventHandler CanExecuteChanged
{
add
{
if (this.canExecute != null)
{
CommandManager.RequerySuggested += value;
}
}
remove
{
if (this.canExecute != null)
{
CommandManager.RequerySuggested -= value;
}
}
}
/// <summary>
/// Defines the method that determines whether the command can execute in its current state.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to <c>null</c>.</param>
/// <returns><c>true</c> if this command can be executed; otherwise, <c>false</c>.</returns>
public bool CanExecute(object parameter)
{
return this.canExecute == null ? true : this.canExecute();
}
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to <c>null</c>.</param>
public void Execute(object parameter)
{
this.execute();
}
/// <summary>
/// Raises the can execute changed.
/// </summary>
public void RaiseCanExecuteChanged()
{
CommandManager.InvalidateRequerySuggested();
}
}
}

View File

@@ -0,0 +1,56 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Example.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace WpfExamples
{
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
public class Example
{
public Example(Type mainWindowType, string title = null, string description = null)
{
this.MainWindowType = mainWindowType;
this.Title = title ?? mainWindowType.Namespace;
this.Description = description;
try
{
this.Thumbnail = new BitmapImage(new Uri("pack://application:,,,/Images/" + this.ThumbnailFileName));
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
public string Title { get; private set; }
public string Description { get; set; }
private Type MainWindowType { get; set; }
public ImageSource Thumbnail { get; set; }
public string ThumbnailFileName
{
get
{
return this.MainWindowType.Namespace + ".png";
}
}
public override string ToString()
{
return this.Title;
}
public Window Create()
{
return Activator.CreateInstance(this.MainWindowType) as Window;
}
}
}

View File

@@ -0,0 +1,28 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ExampleAttribute.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace WpfExamples
{
using System;
public class ExampleAttribute : Attribute
{
public ExampleAttribute(string description)
: this(null, description)
{
}
public ExampleAttribute(string title, string description)
{
this.Title = title;
this.Description = description;
}
public string Title { get; private set; }
public string Description { get; private set; }
}
}

View File

@@ -0,0 +1,16 @@
<Window x:Class="AlignedAxesDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="http://oxyplot.org/wpf"
Title="AlignedAxesDemo" Height="480" Width="640">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label>The plot margins are undefined, and the vertical axes should be adjusted to have the same width.</Label>
<oxy:PlotView Grid.Row="1" Model="{Binding Model0}"/>
<oxy:PlotView Grid.Row="2" Model="{Binding Model1}"/>
</Grid>
</Window>

View File

@@ -0,0 +1,55 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace AlignedAxesDemo
{
using System;
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
using WpfExamples;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
[Example("Aligning plot margins from desired axis widths.")]
public partial class MainWindow
{
/// <summary>
/// Initializes a new instance of the <see cref="MainWindow"/> class.
/// </summary>
public MainWindow()
{
this.InitializeComponent();
this.Model0 = CreatePlotModel(0, 10);
this.Model1 = CreatePlotModel(0, 1e8);
// TODO: align the vertical axis size without setting PlotMargins
this.Model0.PlotMargins = this.Model1.PlotMargins = new OxyThickness(70, 40, 20, 20);
this.DataContext = this;
}
public PlotModel Model0 { get; private set; }
public PlotModel Model1 { get; private set; }
private static PlotModel CreatePlotModel(double min, double max)
{
var model = new PlotModel();
var verticalAxis = new LinearAxis { Position = AxisPosition.Left, Minimum = min, Maximum = max };
model.Axes.Add(verticalAxis);
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
model.Series.Add(new FunctionSeries(x => Math.Sin(x * Math.PI * 4) * Math.Sin(x * Math.PI * 4) * Math.Sqrt(x) * max, 0, 1, 1000));
return model;
}
}
}

View File

@@ -0,0 +1,42 @@
<UserControl x:Class="AnimationsDemo.AnimationSettingsControl"
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"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Label Content="Total duration (ms)" VerticalAlignment="Center" Margin="6,4,6,4" />
<TextBox Text="{Binding AnimationDuration}" Margin="6,4,6,4" Height="25" Width="50" VerticalContentAlignment="Center" />
<Label Content="Frame duration (ms)" VerticalAlignment="Center" Margin="6,4,6,4" />
<TextBox Text="{Binding AnimationFrameDuration}" Margin="6,4,6,4" Height="25" Width="50" VerticalContentAlignment="Center" />
<Label Content="Delay (ms)" VerticalAlignment="Center" Margin="6,4,6,4" />
<TextBox Text="{Binding AnimationDelay}" Margin="6,4,6,4" Height="25" Width="50" VerticalContentAlignment="Center" />
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Label Content="Easing function" VerticalAlignment="Center" Margin="6,4,6,4" />
<ComboBox ItemsSource="{Binding EasingFunctions}" SelectedItem="{Binding SelectedEasingFunction}"
DisplayMemberPath="Name" Margin="6,4,6,4" Height="25" Width="100" VerticalContentAlignment="Center"
IsEnabled="{Binding SupportsEasingFunction}"/>
<Label Content="Horizontal %" VerticalAlignment="Center" Margin="6,4,6,4" />
<TextBox Text="{Binding HorizontalPercentage}" Margin="6,4,6,4" Height="25" Width="50" VerticalContentAlignment="Center" />
<Label Content="Vertical %" VerticalAlignment="Center" Margin="6,4,6,4" />
<TextBox Text="{Binding VerticalPercentage}" Margin="6,4,6,4" Height="25" Width="50" VerticalContentAlignment="Center" />
<Button Content="Animate" Click="OnAnimateClick" Width="75" Margin="6,4,6,4" Height="25" />
</StackPanel>
</Grid>
</UserControl>

View File

@@ -0,0 +1,27 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="LinearBarView.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System.Windows;
public partial class AnimationSettingsControl
{
public AnimationSettingsControl()
{
this.InitializeComponent();
}
private async void OnAnimateClick(object sender, RoutedEventArgs e)
{
var vm = this.DataContext as IAnimationViewModel;
if (vm != null)
{
await vm.AnimateAsync();
}
}
}
}

View File

@@ -0,0 +1,27 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="BackEase.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
public class BackEase : IEasingFunction
{
public BackEase()
{
this.Amplitude = 1d;
}
public double Amplitude { get; set; }
public double Ease(double value)
{
var num = Math.Max(0.0, this.Amplitude);
return Math.Pow(value, 3.0) - value * num * Math.Sin(Math.PI * value);
}
}
}

View File

@@ -0,0 +1,46 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="BounceEase.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
public class BounceEase : IEasingFunction
{
public BounceEase()
{
this.Bounces = 3;
this.Bounciness = 2d;
}
public int Bounces { get; set; }
public double Bounciness { get; set; }
public double Ease(double value)
{
double y1 = Math.Max(0.0, (double)this.Bounces);
double num1 = this.Bounciness;
if (num1 < 1.0 || num1 == 1d)
num1 = 1001.0 / 1000.0;
double num2 = Math.Pow(num1, y1);
double num3 = 1.0 - num1;
double num4 = (1.0 - num2) / num3 + num2 * 0.5;
double y2 = Math.Floor(Math.Log(-(value * num4) * (1.0 - num1) + 1.0, num1));
double y3 = y2 + 1.0;
double num5 = (1.0 - Math.Pow(num1, y2)) / (num3 * num4);
double num6 = (1.0 - Math.Pow(num1, y3)) / (num3 * num4);
double num7 = (num5 + num6) * 0.5;
double num8 = value - num7;
double num9 = num7 - num5;
double num10 = -Math.Pow(1.0 / num1, y1 - y2);
double num11 = num9;
double num12 = num11 * num11;
return num10 / num12 * (num8 - num9) * (num8 + num9);
}
}
}

View File

@@ -0,0 +1,29 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CircleEase.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
using AnimationsDemo;
public class CircleEase : IEasingFunction
{
public double Ease(double value)
{
value = Math.Max(0.0, Math.Min(1.0, value));
var num1 = 1.0;
var num2 = 1.0;
var num3 = value;
var num4 = num3 * num3;
var num5 = Math.Sqrt(num2 - num4);
return num1 - num5;
}
}
}

View File

@@ -0,0 +1,13 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainViewModel.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
public interface IEasingFunction
{
double Ease(double value);
}
}

View File

@@ -0,0 +1,16 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="BackEase.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
public class NoEase : IEasingFunction
{
public double Ease(double value)
{
return 1d;
}
}
}

View File

@@ -0,0 +1,27 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PowerEase.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
public class PowerEase : IEasingFunction
{
public PowerEase()
{
this.Power = 2d;
}
public double Power { get; set; }
public double Ease(double value)
{
double y = Math.Max(0.0, this.Power);
return Math.Pow(value, y);
}
}
}

View File

@@ -0,0 +1,18 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="QuadraticEase.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
public class QuadraticEase : IEasingFunction
{
public double Ease(double value)
{
double num = value;
return num * num;
}
}
}

View File

@@ -0,0 +1,18 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="QuadraticEase.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
public class QuarticEase : IEasingFunction
{
public double Ease(double value)
{
double num = value;
return num * num * value * value;
}
}
}

View File

@@ -0,0 +1,18 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="QuinticEase.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
public class QuinticEase : IEasingFunction
{
public double Ease(double value)
{
double num = value;
return num * num * value * value * value;
}
}
}

View File

@@ -0,0 +1,19 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SineEase.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
public class SineEase : IEasingFunction
{
public double Ease(double value)
{
return 1.0 - Math.Sin(Math.PI / 2.0 * (1.0 - value));
}
}
}

View File

@@ -0,0 +1,85 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AnimationExtensions.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
using System.Collections.Generic;
using System.Linq;
using OxyPlot.Series;
public static partial class AnimationExtensions
{
private static readonly IEasingFunction DefaultEasingFunction = new NoEase();
static AnimationExtensions()
{
DefaultAnimationDelay = 0;
DefaultAnimationDuration = 750;
DefaultAnimationFrameDuration = 10;
}
public static int DefaultAnimationDelay { get; set; }
public static int DefaultAnimationDuration { get; set; }
public static int DefaultAnimationFrameDuration { get; set; }
private static List<double> CalculateEaseValues(double range, int count, IEasingFunction easingFunction, double baseValue = 0d)
{
var items = new List<double>();
var easePhase = 1d / count;
for (var i = 0; i < count; i++)
{
var valueToEase = easePhase * i;
var easeValue = easingFunction.Ease(valueToEase);
items.Add(baseValue + (easeValue * range));
}
return items;
}
private static void InsertDelayAnimationFrame(this List<AnimationFrame> animationFrames, TimeSpan delay)
{
if (animationFrames.Count < 2)
{
return;
}
if (delay <= TimeSpan.Zero)
{
return;
}
var animationFrame = new AnimationFrame
{
Duration = delay
};
animationFrames.Insert(1, animationFrame);
}
private static List<IAnimatablePoint> GetAnimatablePoints(this DataPointSeries series)
{
var points = new List<IAnimatablePoint>();
var itemsSource = series.ItemsSource;
if (itemsSource != null)
{
points.AddRange(from x in itemsSource.Cast<object>()
where x is IAnimatablePoint
select (IAnimatablePoint)x);
}
return points;
}
}
}

View File

@@ -0,0 +1,114 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AnimationExtensions.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using OxyPlot;
using OxyPlot.Series;
public static partial class AnimationExtensions
{
public static AnimationFrame GetFinalAnimationFrame(DataPointSeries series)
{
var animationFrame = new AnimationFrame
{
Duration = TimeSpan.Zero
};
var points = series.GetAnimatablePoints();
foreach (var point in points)
{
animationFrame.AnimationPoints.Add(new AnimationPoint
{
X = point.FinalX,
Y = point.FinalY
});
}
return animationFrame;
}
public static async Task AnimateSeriesAsync(
this PlotModel plotModel,
DataPointSeries series,
List<AnimationFrame> animationFrames)
{
if (animationFrames.Count == 0)
{
return;
}
var finalAnimationFrame = GetFinalAnimationFrame(series);
animationFrames.Add(finalAnimationFrame);
var xAxis = plotModel.DefaultXAxis;
var oldXAxisMinimum = xAxis.Minimum;
var oldXAxisMaximum = xAxis.Maximum;
xAxis.Minimum = xAxis.ActualMinimum;
xAxis.Maximum = xAxis.ActualMaximum;
var yAxis = plotModel.DefaultYAxis;
var oldYAxisMinimum = yAxis.Minimum;
var oldYAxisMaximum = yAxis.Maximum;
yAxis.Minimum = yAxis.ActualMinimum;
yAxis.Maximum = yAxis.ActualMaximum;
var previousDataFieldX = series.DataFieldX;
var previousDataFieldY = series.DataFieldY;
// Always fix up the data fields (we are using IAnimatablePoint from now on)
series.DataFieldX = "X";
series.DataFieldY = "Y";
var points = series.GetAnimatablePoints();
foreach (var animationFrame in animationFrames)
{
// TODO: consider implementing the IsVisible feature
var animationPoints = animationFrame.AnimationPoints;
if (animationPoints.Count > 0)
{
for (var j = 0; j < points.Count; j++)
{
var animatablePoint = points[j];
if (animatablePoint != null)
{
if (j < animationPoints.Count)
{
var animationPoint = animationPoints[j];
animatablePoint.X = animationPoint.X;
animatablePoint.Y = animationPoint.Y;
}
}
}
}
plotModel.InvalidatePlot(true);
await Task.Delay(animationFrame.Duration);
}
xAxis.Minimum = oldXAxisMinimum;
xAxis.Maximum = oldXAxisMaximum;
yAxis.Minimum = oldYAxisMinimum;
yAxis.Maximum = oldYAxisMaximum;
series.DataFieldX = previousDataFieldX;
series.DataFieldY = previousDataFieldY;
plotModel.InvalidatePlot(true);
}
}
}

View File

@@ -0,0 +1,182 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AnimationExtensions.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OxyPlot;
using OxyPlot.Series;
public static partial class AnimationExtensions
{
public static async Task AnimateSeriesAsync(
this PlotModel plotModel,
LinearBarSeries series,
AnimationSettings settings)
{
var points = series.GetAnimatablePoints();
if (points.Count == 0)
{
return;
}
var duration = settings.Duration;
if (duration == default(TimeSpan))
{
duration = TimeSpan.FromMilliseconds(DefaultAnimationDuration);
}
var easingFunction = settings.EasingFunction;
if (easingFunction == null)
{
easingFunction = DefaultEasingFunction;
}
var animationFrameDurationInMs = (int)settings.FrameDuration.TotalMilliseconds;
var minimumValue = settings.MinimumValue;
var animationFrames = new List<AnimationFrame>();
// Animation assumptions:
//
// - Total duration: 300ms (in this example)
// - At least animate each horizontal value separately
// - First animate from left => right (70 % of the time)
// - Second animate from center => end (30 % of the time)
//
// | ^
// | |
// | ___ |
// | | | | 30 % of time
// | ___ | | | 90 ms
// | | | | | |
// | | | ___ | | |
// | | | | | | | |
// |___|_|___|_|___|_|_____________________________ ^
//
// <---------------- 70 % of time ---------------->
// (210 ms)
var horizontalDuration = duration.TotalMilliseconds / 100 * settings.HorizontalPercentage;
var verticalDuration = duration.TotalMilliseconds / 100 * settings.VerticalPercentage;
var animationFrameCount = (int)(duration.TotalMilliseconds / animationFrameDurationInMs);
var animationFrameDuration = TimeSpan.FromMilliseconds(animationFrameDurationInMs);
if (!minimumValue.HasValue)
{
minimumValue = 0d;
var defaultYAxis = plotModel.DefaultYAxis;
if (defaultYAxis != null)
{
if (defaultYAxis.Minimum > 0d)
{
minimumValue = defaultYAxis.Minimum;
}
}
}
var minX = (from point in points orderby point.X select point.X).Min();
var maxX = (from point in points orderby point.X select point.X).Max();
var deltaX = maxX - minX;
for (var i = 0; i < animationFrameCount; i++)
{
var animationFrame = new AnimationFrame
{
Duration = animationFrameDuration
};
var currentTime = animationFrameDurationInMs * i;
var percentage = i * 100d / animationFrameCount;
var horizontalPercentage = currentTime * 100d / horizontalDuration;
if (horizontalPercentage > 100d)
{
horizontalPercentage = 100d;
}
var currentDeltaX = deltaX / 100d * horizontalPercentage;
var currentX = minX + currentDeltaX;
// Get the last visible point. It should not be based on the index (can be really different), but on the X position
// since we want to draw a smooth animation
var lastVisibleHorizontalPoint = 0;
for (int j = 0; j < points.Count; j++)
{
var x = points[j].FinalX;
if (x > currentX)
{
break;
}
lastVisibleHorizontalPoint = j;
}
for (var j = 0; j < points.Count; j++)
{
var point = points[j];
var isVisible = false;
var x = point.FinalX;
var y = 0d;
if (j <= lastVisibleHorizontalPoint)
{
isVisible = true;
y = point.FinalY;
// We know how long an y animation takes. We only have to calculate if this start time of this x animation
// is longer than verticalDuration ago
var localDeltaX = point.FinalX - minX;
var localPercentageX = localDeltaX * 100d / deltaX;
var startTime = horizontalDuration / 100 * localPercentageX;
var endTime = startTime + verticalDuration;
if (endTime > currentTime)
{
var timeDeltaTotal = endTime - startTime;
var timeDeltaCurrent = currentTime - startTime;
var subPercentage = timeDeltaCurrent * 100d / timeDeltaTotal;
// This bar is part of the current animation, calculate the Y relative to 30 % of the time based on the current index
// Calculate the % that offset is based on totalTimeDelta
// Calculate point to animate from
var maxY = point.FinalY;
var minY = minimumValue.Value;
var deltaY = maxY - minY;
// We need to ease against percentage (between 0 and 1)
var ease = easingFunction.Ease(subPercentage / 100);
var currentDeltaY = deltaY * ease;
y = minY + currentDeltaY;
}
}
animationFrame.AnimationPoints.Add(new AnimationPoint
{
IsVisible = isVisible,
X = x,
Y = y
});
}
animationFrames.Add(animationFrame);
}
animationFrames.InsertDelayAnimationFrame(settings.Delay);
await plotModel.AnimateSeriesAsync(series, animationFrames);
}
}
}

View File

@@ -0,0 +1,189 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AnimationExtensions.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OxyPlot;
using OxyPlot.Series;
public static partial class AnimationExtensions
{
public static async Task AnimateSeriesAsync(
this PlotModel plotModel,
LineSeries series,
AnimationSettings settings)
{
var points = series.GetAnimatablePoints();
if (points.Count == 0)
{
return;
}
var duration = settings.Duration;
if (duration == default(TimeSpan))
{
duration = TimeSpan.FromMilliseconds(DefaultAnimationDuration);
}
var easingFunction = settings.EasingFunction;
if (easingFunction == null)
{
easingFunction = DefaultEasingFunction;
}
var animationFrameDurationInMs = (int)settings.FrameDuration.TotalMilliseconds;
var minimumValue = settings.MinimumValue;
var animationFrames = new List<AnimationFrame>();
var horizontalDuration = duration.TotalMilliseconds / 100 * settings.HorizontalPercentage;
var verticalDuration = duration.TotalMilliseconds / 100 * settings.VerticalPercentage;
var animationFrameCount = (int)(duration.TotalMilliseconds / animationFrameDurationInMs);
var animationFrameDuration = TimeSpan.FromMilliseconds(animationFrameDurationInMs);
if (!minimumValue.HasValue)
{
minimumValue = 0d;
var defaultYAxis = plotModel.DefaultYAxis;
if (defaultYAxis != null)
{
if (defaultYAxis.Minimum > 0d)
{
minimumValue = defaultYAxis.Minimum;
}
}
}
var minX = (from point in points orderby point.X select point.X).Min();
var maxX = (from point in points orderby point.X select point.X).Max();
var deltaX = maxX - minX;
for (var i = 0; i < animationFrameCount; i++)
{
var animationFrame = new AnimationFrame
{
Duration = animationFrameDuration
};
var currentTime = animationFrameDurationInMs * i;
var percentage = i * 100d / animationFrameCount;
var horizontalPercentage = currentTime * 100d / horizontalDuration;
if (horizontalPercentage > 100d)
{
horizontalPercentage = 100d;
}
var currentDeltaX = deltaX / 100d * horizontalPercentage;
var currentX = minX + currentDeltaX;
// Get the last visible point. It should not be based on the index (can be really different), but on the X position
// since we want to draw a smooth animation
var lastVisibleHorizontalPoint = 0;
for (int j = 0; j < points.Count; j++)
{
if (points[j].FinalX > currentX)
{
break;
}
lastVisibleHorizontalPoint = j;
}
for (var j = 0; j < points.Count; j++)
{
var point = points[j];
var isVisible = true;
var y = point.FinalY;
var x = point.FinalX;
var nextPointIndex = lastVisibleHorizontalPoint + 1;
if (j > nextPointIndex)
{
isVisible = false;
}
if (j >= nextPointIndex)
{
// Calculate the position the y line is in currently (based on x1 and x2)
var previousPoint = points[lastVisibleHorizontalPoint];
var nextPoint = points[nextPointIndex];
var previousX = previousPoint.FinalX;
var nextX = nextPoint.FinalX;
var totalDeltaX = nextX - previousX;
var subDeltaX = currentX - previousX;
var subPercentage = (subDeltaX * 100) / totalDeltaX;
var previousY = previousPoint.FinalY;
var nextY = nextPoint.FinalY;
var totalDeltaY = nextY - previousY;
var subDeltaY = totalDeltaY / 100 * subPercentage;
y = previousY + subDeltaY;
x = currentX;
}
// Calculate possible ease functions
if (j < nextPointIndex)
{
// We know how long an y animation takes. We only have to calculate if this start time of this x animation
// is longer than verticalDuration ago
var localDeltaX = point.FinalX - minX;
var localPercentageX = localDeltaX * 100d / deltaX;
var startTime = horizontalDuration / 100 * localPercentageX;
var endTime = startTime + verticalDuration;
if (endTime > currentTime)
{
var timeDeltaTotal = endTime - startTime;
var timeDeltaCurrent = currentTime - startTime;
var easePercentage = timeDeltaCurrent * 100d / timeDeltaTotal;
// This bar is part of the current animation, calculate the Y relative to 30 % of the time based on the current index
// Calculate the % that offset is based on totalTimeDelta
// Calculate point to animate from
var maxY = point.FinalY;
var minY = minimumValue.Value;
var deltaY = maxY - minY;
// We need to ease against percentage (between 0 and 1)
var ease = easingFunction.Ease(easePercentage / 100);
var currentDeltaY = deltaY * ease;
y = minY + currentDeltaY;
}
}
animationFrame.AnimationPoints.Add(new AnimationPoint
{
X = x,
Y = y,
IsVisible = isVisible
});
}
animationFrames.Add(animationFrame);
}
animationFrames.InsertDelayAnimationFrame(settings.Delay);
await plotModel.AnimateSeriesAsync(series, animationFrames);
}
}
}

View File

@@ -0,0 +1,30 @@
<Window x:Class="AnimationsDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:AnimationsDemo="clr-namespace:AnimationsDemo"
Title="AnimationsDemo" Height="480" Width="740">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TabControl x:Name="tabControl" Grid.Row="0">
<TabItem Header="Linear Bar Series">
<AnimationsDemo:LinearBarView />
</TabItem>
<TabItem Header="Line Series">
<AnimationsDemo:LineSeriesView />
</TabItem>
<TabItem Header="Area Series">
<AnimationsDemo:AreaSeriesView />
</TabItem>
</TabControl>
<AnimationsDemo:AnimationSettingsControl Grid.Row="1" DataContext="{Binding ElementName=tabControl, Path=SelectedItem.Content.DataContext}" />
</Grid>
</Window>

View File

@@ -0,0 +1,27 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System.Windows;
using WpfExamples;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
[Example(null, "Animations using extension methods on series.")]
public partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
}
}
}

View File

@@ -0,0 +1,26 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AnimationFrame.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
using System.Collections.Generic;
public class AnimationFrame
{
private static readonly TimeSpan DefaultDuration = TimeSpan.FromMilliseconds(15);
public AnimationFrame()
{
AnimationPoints = new List<AnimationPoint>();
Duration = DefaultDuration;
}
public TimeSpan Duration { get; set; }
public List<AnimationPoint> AnimationPoints { get; private set; }
}
}

View File

@@ -0,0 +1,25 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AnimationPoint.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System.Diagnostics;
[DebuggerDisplay("{X} / {Y} (IsVisible = {IsVisible})")]
public class AnimationPoint
{
public AnimationPoint()
{
this.IsVisible = true;
}
public double X { get; set; }
public double Y { get; set; }
public bool IsVisible { get; set; }
}
}

View File

@@ -0,0 +1,38 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AnimationFrame.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
public class AnimationSettings
{
public AnimationSettings()
{
this.HorizontalPercentage = 70;
this.VerticalPercentage = 30;
this.Delay = TimeSpan.FromMilliseconds(AnimationExtensions.DefaultAnimationDelay);
this.Duration = TimeSpan.FromMilliseconds(AnimationExtensions.DefaultAnimationDuration);
this.FrameDuration = TimeSpan.FromMilliseconds(AnimationExtensions.DefaultAnimationFrameDuration);
}
public double? MinimumValue { get; set; }
public double HorizontalPercentage { get; set; }
public double VerticalPercentage { get; set; }
public TimeSpan Delay { get; set; }
public TimeSpan Duration { get; set; }
public TimeSpan FrameDuration { get; set; }
public IEasingFunction EasingFunction { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IAnimatablePoint.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
public interface IAnimatablePoint
{
double FinalX { get; set; }
double FinalY { get; set; }
double X { get; set; }
double Y { get; set; }
}
}

View File

@@ -0,0 +1,50 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Pnl.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
using System.Diagnostics;
using OxyPlot.Axes;
[DebuggerDisplay("X: {X} => {FinalX} | Y: {Y} => {FinalY}")]
public class Pnl : IAnimatablePoint
{
public double FinalX { get; set; }
public double FinalY { get; set; }
public double X { get; set; }
public double Y { get; set; }
public DateTime Time
{
get { return DateTimeAxis.ToDateTime(this.X); }
set
{
var finalX = DateTimeAxis.ToDouble(value);
this.FinalX = finalX;
this.X = finalX;
}
}
public double Value
{
get { return this.Y;}
set
{
this.FinalY = value;
this.Y = value;
}
}
public override string ToString()
{
return String.Format("{0:HH:mm} {1:0.0}", this.Time, this.Value);
}
}
}

View File

@@ -0,0 +1,77 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainViewModel.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OxyPlot;
public abstract class AnimationViewModelBase : IAnimationViewModel
{
protected AnimationViewModelBase()
{
this.EasingFunctions = (from type in typeof(CircleEase).Assembly.GetTypes()
where type.GetInterfaces().Any(x => x == typeof(IEasingFunction)) && !type.IsAbstract
orderby type.Name
select type).ToList();
this.SelectedEasingFunction = this.EasingFunctions.FirstOrDefault();
if (!this.SupportsEasingFunction)
{
this.SelectedEasingFunction = typeof(NoEase);
}
this.AnimationDuration = 1000;
this.AnimationFrameDuration = AnimationExtensions.DefaultAnimationFrameDuration;
this.HorizontalPercentage = 70;
this.VerticalPercentage = 30;
this.PlotModel = new PlotModel();
}
public abstract bool SupportsEasingFunction { get; }
public PlotModel PlotModel { get; private set; }
public List<Type> EasingFunctions { get; private set; }
public Type SelectedEasingFunction { get; set; }
public double HorizontalPercentage { get; set; }
public double VerticalPercentage { get; set; }
public int AnimationDelay { get; set; }
public int AnimationDuration { get; set; }
public int AnimationFrameDuration { get; set; }
public Task AnimateAsync()
{
var easingFunction = (IEasingFunction)Activator.CreateInstance(this.SelectedEasingFunction);
var animationSettings = new AnimationSettings
{
EasingFunction = easingFunction,
Duration = TimeSpan.FromMilliseconds(this.AnimationDuration),
FrameDuration = TimeSpan.FromMilliseconds(this.AnimationFrameDuration),
Delay = TimeSpan.FromMilliseconds(this.AnimationDelay),
HorizontalPercentage = this.HorizontalPercentage,
VerticalPercentage = this.VerticalPercentage
};
return this.AnimateAsync(animationSettings);
}
public abstract Task AnimateAsync(AnimationSettings animationSettings);
}
}

View File

@@ -0,0 +1,98 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AreaSeriesViewModel.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OxyPlot;
using OxyPlot.Annotations;
using OxyPlot.Axes;
using OxyPlot.Series;
public class AreaSeriesViewModel : AnimationViewModelBase
{
public AreaSeriesViewModel()
{
var pnls = new List<Pnl>();
var random = new Random(31);
var dateTime = DateTime.Today.Add(TimeSpan.FromHours(9));
for (var pointIndex = 0; pointIndex < 50; pointIndex++)
{
pnls.Add(new Pnl
{
Time = dateTime,
Value = -200 + random.Next(1000),
});
dateTime = dateTime.AddMinutes(1);
}
var minimum = pnls.Min(x => x.Value);
var maximum = pnls.Max(x => x.Value);
var plotModel = this.PlotModel;
plotModel.Title = "Area Series Animation Demo";
var series = new AreaSeries
{
Title = "P & L",
ItemsSource = pnls,
DataFieldX = "Time",
DataFieldY = "Value",
Color = OxyColor.Parse("#4CAF50"),
Fill = OxyColor.Parse("#454CAF50"),
MarkerSize = 3,
MarkerFill = OxyColor.Parse("#FFFFFFFF"),
MarkerStroke = OxyColor.Parse("#4CAF50"),
MarkerStrokeThickness = 1.5,
MarkerType = MarkerType.Circle,
StrokeThickness = 1,
};
plotModel.Series.Add(series);
var annotation = new LineAnnotation
{
Type = LineAnnotationType.Horizontal,
Y = 0
};
plotModel.Annotations.Add(annotation);
var dateTimeAxis = new DateTimeAxis
{
Position = AxisPosition.Bottom,
IntervalType = DateTimeIntervalType.Hours,
IntervalLength = 50
};
plotModel.Axes.Add(dateTimeAxis);
var margin = (maximum - minimum) * 0.05;
var valueAxis = new LinearAxis
{
Position = AxisPosition.Left,
Minimum = minimum - margin,
Maximum = maximum + margin,
};
plotModel.Axes.Add(valueAxis);
}
public override bool SupportsEasingFunction { get { return true; } }
public override async Task AnimateAsync(AnimationSettings animationSettings)
{
var plotModel = this.PlotModel;
var series = plotModel.Series.First() as AreaSeries;
if (series != null)
{
await plotModel.AnimateSeriesAsync(series, animationSettings);
}
}
}
}

View File

@@ -0,0 +1,20 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IAnimationViewModel.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
using System.Threading.Tasks;
public interface IAnimationViewModel
{
bool SupportsEasingFunction { get; }
Task AnimateAsync();
Task AnimateAsync(AnimationSettings animationSettings);
}
}

View File

@@ -0,0 +1,97 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="LineSeriesViewModel.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OxyPlot;
using OxyPlot.Annotations;
using OxyPlot.Axes;
using OxyPlot.Series;
public class LineSeriesViewModel : AnimationViewModelBase
{
public LineSeriesViewModel()
{
var pnls = new List<Pnl>();
var random = new Random(31);
var dateTime = DateTime.Today.Add(TimeSpan.FromHours(9));
for (var pointIndex = 0; pointIndex < 50; pointIndex++)
{
pnls.Add(new Pnl
{
Time = dateTime,
Value = -200 + random.Next(1000),
});
dateTime = dateTime.AddMinutes(1);
}
var minimum = pnls.Min(x => x.Value);
var maximum = pnls.Max(x => x.Value);
var plotModel = this.PlotModel;
plotModel.Title = "Line Series Animation Demo";
var series = new LineSeries
{
Title = "P & L",
ItemsSource = pnls,
DataFieldX = "Time",
DataFieldY = "Value",
Color = OxyColor.Parse("#4CAF50"),
MarkerSize = 3,
MarkerFill = OxyColor.Parse("#FFFFFFFF"),
MarkerStroke = OxyColor.Parse("#4CAF50"),
MarkerStrokeThickness = 1.5,
MarkerType = MarkerType.Circle,
StrokeThickness = 1,
};
plotModel.Series.Add(series);
var annotation = new LineAnnotation
{
Type = LineAnnotationType.Horizontal,
Y = 0
};
plotModel.Annotations.Add(annotation);
var dateTimeAxis = new DateTimeAxis
{
Position = AxisPosition.Bottom,
IntervalType = DateTimeIntervalType.Hours,
IntervalLength = 50
};
plotModel.Axes.Add(dateTimeAxis);
var margin = (maximum - minimum) * 0.05;
var valueAxis = new LinearAxis
{
Position = AxisPosition.Left,
Minimum = minimum - margin,
Maximum = maximum + margin,
};
plotModel.Axes.Add(valueAxis);
}
public override bool SupportsEasingFunction { get { return true; } }
public override async Task AnimateAsync(AnimationSettings animationSettings)
{
var plotModel = this.PlotModel;
var series = plotModel.Series.First() as LineSeries;
if (series != null)
{
await plotModel.AnimateSeriesAsync(series, animationSettings);
}
}
}
}

View File

@@ -0,0 +1,94 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainViewModel.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OxyPlot;
using OxyPlot.Annotations;
using OxyPlot.Axes;
using OxyPlot.Series;
public class LinearBarViewModel : AnimationViewModelBase
{
public LinearBarViewModel()
{
var pnls = new List<Pnl>();
var random = new Random(31);
var dateTime = DateTime.Today.Add(TimeSpan.FromHours(9));
for (var pointIndex = 0; pointIndex < 50; pointIndex++)
{
pnls.Add(new Pnl
{
Time = dateTime,
Value = -200 + random.Next(1000),
});
dateTime = dateTime.AddMinutes(1);
}
var minimum = pnls.Min(x => x.Value);
var maximum = pnls.Max(x => x.Value);
var plotModel = this.PlotModel;
plotModel.Title = "Linear Bar Series Animation Demo";
var series = new LinearBarSeries
{
Title = "P & L",
ItemsSource = pnls,
DataFieldX = "Time",
DataFieldY = "Value",
FillColor = OxyColor.Parse("#454CAF50"),
StrokeColor = OxyColor.Parse("#4CAF50"),
StrokeThickness = 1,
BarWidth = 5
};
plotModel.Series.Add(series);
var annotation = new LineAnnotation
{
Type = LineAnnotationType.Horizontal,
Y = 0
};
plotModel.Annotations.Add(annotation);
var dateTimeAxis = new DateTimeAxis
{
Position = AxisPosition.Bottom,
IntervalType = DateTimeIntervalType.Hours,
IntervalLength = 50
};
plotModel.Axes.Add(dateTimeAxis);
var margin = (maximum - minimum) * 0.05;
var valueAxis = new LinearAxis
{
Position = AxisPosition.Left,
Minimum = minimum - margin,
Maximum = maximum + margin,
};
plotModel.Axes.Add(valueAxis);
}
public override bool SupportsEasingFunction { get { return true; } }
public override async Task AnimateAsync(AnimationSettings animationSettings)
{
var plotModel = this.PlotModel;
var series = plotModel.Series.First() as LinearBarSeries;
if (series != null)
{
await plotModel.AnimateSeriesAsync(series, animationSettings);
}
}
}
}

View File

@@ -0,0 +1,13 @@
<UserControl x:Class="AnimationsDemo.AreaSeriesView"
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:oxy="http://oxyplot.org/wpf"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<oxy:PlotView Model="{Binding PlotModel}" />
</Grid>
</UserControl>

View File

@@ -0,0 +1,17 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AreaSeriesView.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
public partial class AreaSeriesView
{
public AreaSeriesView()
{
this.InitializeComponent();
this.DataContext = new AreaSeriesViewModel();
}
}
}

View File

@@ -0,0 +1,13 @@
<UserControl x:Class="AnimationsDemo.LineSeriesView"
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:oxy="http://oxyplot.org/wpf"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<oxy:PlotView Model="{Binding PlotModel}" />
</Grid>
</UserControl>

View File

@@ -0,0 +1,17 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="LineSeriesView.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
public partial class LineSeriesView
{
public LineSeriesView()
{
this.InitializeComponent();
this.DataContext = new LineSeriesViewModel();
}
}
}

View File

@@ -0,0 +1,13 @@
<UserControl x:Class="AnimationsDemo.LinearBarView"
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:oxy="http://oxyplot.org/wpf"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<oxy:PlotView Model="{Binding PlotModel}" />
</Grid>
</UserControl>

View File

@@ -0,0 +1,17 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="LinearBarView.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace AnimationsDemo
{
public partial class LinearBarView
{
public LinearBarView()
{
this.InitializeComponent();
this.DataContext = new LinearBarViewModel();
}
}
}

View File

@@ -0,0 +1,11 @@
<Window x:Class="ContextMenuDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf" Title="ContextMenuDemo" Height="480" Width="640">
<oxy:PlotView Model="{Binding Model}">
<oxy:PlotView.ContextMenu>
<ContextMenu>
<MenuItem Header="Reset" Command="{Binding ResetCommand}"></MenuItem>
</ContextMenu>
</oxy:PlotView.ContextMenu>
</oxy:PlotView>
</Window>

View File

@@ -0,0 +1,51 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ContextMenuDemo
{
using System;
using System.Windows;
using System.Windows.Input;
using OxyPlot;
using OxyPlot.Series;
using WpfExamples;
using DelegateCommand = PropertyTools.Wpf.DelegateCommand;
using ICommand = System.Windows.Input.ICommand;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
[Example("Integrate with a ContextMenu")]
public partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
var model = new PlotModel { Title = "ContextMenu" };
model.Series.Add(new FunctionSeries(Math.Sin, 0, 10, 200));
this.Model = model;
this.ResetCommand = new DelegateCommand(() =>
{
this.Model.ResetAllAxes();
this.Model.InvalidatePlot(false);
});
this.DataContext = this;
}
public ICommand ResetCommand { get; set; }
public PlotModel Model { get; set; }
}
}

View File

@@ -0,0 +1,295 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainViewModel.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// The main view model.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ContourDemo
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using OxyPlot;
using OxyPlot.Series;
/// <summary>
/// The main view model.
/// </summary>
public class MainViewModel : INotifyPropertyChanged
{
/// <summary>
/// The selected example.
/// </summary>
private Example selectedExample;
/// <summary>
/// Initializes a new instance of the <see cref="MainViewModel" /> class.
/// </summary>
public MainViewModel()
{
this.Examples = new List<Example>();
this.AddExamples();
this.SelectedExample = this.Examples[0];
}
/// <summary>
/// Occurs when a property value changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Gets or sets the examples.
/// </summary>
/// <value>The examples.</value>
public List<Example> Examples { get; set; }
/// <summary>
/// Gets or sets the plot model.
/// </summary>
/// <value>The plot model.</value>
public PlotModel PlotModel { get; set; }
/// <summary>
/// Gets or sets the selected example.
/// </summary>
/// <value>The selected example.</value>
public Example SelectedExample
{
get
{
return this.selectedExample;
}
set
{
this.selectedExample = value;
this.RaisePropertyChanged("SelectedExample");
}
}
/// <summary>
/// Raises the property changed event.
/// </summary>
/// <param name="property">The property.</param>
protected void RaisePropertyChanged(string property)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(property));
}
}
/// <summary>
/// Adds the examples.
/// </summary>
private void AddExamples()
{
Func<double, double, double> peaks =
(x, y) =>
3 * (1 - x) * (1 - x) * Math.Exp(-(x * x) - (y + 1) * (y + 1))
- 10 * (x / 5 - x * x * x - y * y * y * y * y) * Math.Exp(-x * x - y * y)
- 1.0 / 3 * Math.Exp(-(x + 1) * (x + 1) - y * y);
this.Examples.Add(new Example("peaks", -3, 3, 0.05, -3, 3, 0.05, -6, 10, 1, peaks));
Func<double, double> square = x => x * x;
this.Examples.Add(
new Example(
"Conrec example 1",
-1.5,
1.5,
0.1,
-1.5,
1.5,
0.1,
0,
2.25,
0.25,
(x, y) =>
1.0
/ (square(x * x + (y - 0.842) * (y + 0.842)) + square(x * (y - 0.842) + x * (y - 0.842)))));
// todo: something wrong here?
double c = 0;
this.Examples.Add(
new Example(
"Conrec example 2",
-2 * Math.PI,
2 * Math.PI,
0.25,
-2 * Math.PI,
2 * Math.PI,
0.25,
-1,
1,
0.02,
(x, y) =>
Math.Sin(Math.Sqrt(x * x + y * y)) + y != 0 ? 1.0 / Math.Sqrt((x - c) * (x - c) + y * y) : 0));
this.Examples.Add(
new Example(
"sin(x)*cos(y)",
-Math.PI,
Math.PI,
0.1,
-Math.PI,
Math.PI,
0.1,
-1,
1,
0.1,
(x, y) => Math.Sin(x) * Math.Cos(y)));
this.Examples.Add(new Example("x*y", -1, 1, 0.1, -1, 1, 0.1, -1, 1, 0.1, (x, y) => x * y));
this.Examples.Add(new Example("x^{2}+y^{2}", -1, 1, 0.1, -1, 1, 0.1, -1, 1, 0.1, (x, y) => x * x + y * y));
this.Examples.Add(
new Example(
"atan2(y,x)",
-1,
1,
0.1,
-1,
1,
0.1,
-180,
180,
10,
(x, y) => Math.Atan2(y, x) * 180 / Math.PI,
"0°"));
this.Examples.Add(new Example("y/x", -1, 1, 0.1, -1, 1, 0.1, -1, 1, 0.1, (x, y) => y / x, "0%"));
// http://en.wikipedia.org/wiki/Sinc_function
this.Examples.Add(
new Example(
"sinc(r+0.1)",
-8,
8,
0.2,
-8,
8,
0.2,
-0.2,
1,
0.1,
(x, y) =>
{
double r = Math.Sqrt(x * x + y * y);
return Math.Sin(r + 0.1) / (r + 0.1);
},
"0.0"));
}
/// <summary>
/// Represents an example.
/// </summary>
public class Example
{
/// <summary>
/// The d.
/// </summary>
private readonly double[,] D;
/// <summary>
/// The x.
/// </summary>
private readonly double[] X;
/// <summary>
/// The y.
/// </summary>
private readonly double[] Y;
/// <summary>
/// The z.
/// </summary>
private readonly double[] Z;
/// <summary>
/// Initializes a new instance of the <see cref="Example" /> class.
/// </summary>
/// <param name="title">The title.</param>
/// <param name="minx">The minx.</param>
/// <param name="maxx">The maxx.</param>
/// <param name="dx">The dx.</param>
/// <param name="miny">The miny.</param>
/// <param name="maxy">The maxy.</param>
/// <param name="dy">The dy.</param>
/// <param name="minz">The minz.</param>
/// <param name="maxz">The maxz.</param>
/// <param name="dz">The dz.</param>
/// <param name="f">The f.</param>
/// <param name="formatString">The format string.</param>
public Example(
string title,
double minx,
double maxx,
double dx,
double miny,
double maxy,
double dy,
double minz,
double maxz,
double dz,
Func<double, double, double> f,
string formatString = null)
{
this.Title = title;
this.X = ArrayBuilder.CreateVector(minx, maxx, dx);
this.Y = ArrayBuilder.CreateVector(miny, maxy, dy);
this.Z = ArrayBuilder.CreateVector(minz, maxz, dz);
this.D = ArrayBuilder.Evaluate(f, this.X, this.Y);
this.FormatString = formatString;
}
/// <summary>
/// Gets or sets the format string.
/// </summary>
/// <value>The format string.</value>
public string FormatString { get; set; }
/// <summary>
/// Gets the plot model.
/// </summary>
/// <value>The plot model.</value>
public PlotModel PlotModel
{
get
{
var m = new PlotModel { Title = this.Title };
var cs = new ContourSeries
{
ColumnCoordinates = this.X,
RowCoordinates = this.Y,
Data = this.D,
ContourLevels = this.Z,
LabelFormatString = this.FormatString
};
cs.CalculateContours();
m.Series.Add(cs);
return m;
}
}
/// <summary>
/// Gets or sets the title.
/// </summary>
/// <value>The title.</value>
public string Title { get; set; }
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>A <see cref="System.String" /> that represents this instance.</returns>
public override string ToString()
{
return this.Title;
}
}
}
}

View File

@@ -0,0 +1,19 @@
<Window x:Class="ContourDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf" Title="ContourDemo" Height="480" Width="640">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="File">
<MenuItem Header="E_xit" Click="FileExit"/>
</MenuItem>
<MenuItem x:Name="ExamplesMenu" Header="Examples" ItemsSource="{Binding Examples}">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<EventSetter Event="Click" Handler="ExampleClick"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
</Menu>
<oxy:PlotView Model="{Binding SelectedExample.PlotModel}"/>
</DockPanel>
</Window>

View File

@@ -0,0 +1,51 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ContourDemo
{
using System.Windows;
using System.Windows.Controls;
using WpfExamples;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
[Example("Plotting with contour series.")]
public partial class MainWindow : Window
{
private MainViewModel vm = new MainViewModel();
private MenuItem checkedItem;
public MainWindow()
{
this.InitializeComponent();
this.DataContext = this.vm;
}
private void FileExit(object sender, RoutedEventArgs e)
{
this.Close();
}
private void ExampleClick(object sender, RoutedEventArgs e)
{
var mi = (MenuItem)sender;
if (this.checkedItem != null)
{
this.checkedItem.IsChecked = false;
}
mi.IsChecked = true;
this.checkedItem = mi;
this.vm.SelectedExample = mi.DataContext as MainViewModel.Example;
}
}
}

View File

@@ -0,0 +1,23 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CustomPlotController.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Represents the plot controller for the main window.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ControllerDemo
{
using OxyPlot;
public class CustomPlotController : PlotController
{
public CustomPlotController()
{
this.UnbindAll();
this.BindKeyDown(OxyKey.Left, PlotCommands.PanRight);
this.BindKeyDown(OxyKey.Right, PlotCommands.PanLeft);
}
}
}

View File

@@ -0,0 +1,77 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainViewModel.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Represents the view-model for the main window.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ControllerDemo
{
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
/// <summary>
/// Represents the view-model for the main window.
/// </summary>
public class MainViewModel
{
/// <summary>
/// Initializes a new instance of the <see cref="MainViewModel" /> class.
/// </summary>
public MainViewModel()
{
// Set the Model property, the INotifyPropertyChanged event will make the WPF Plot control update its content
this.Model = CreatePlotModel("Custom PlotController", "Supports left/right keys only");
this.Controller = new CustomPlotController();
this.Model1 = CreatePlotModel("Default controller", null);
this.Model2 = CreatePlotModel("Default controller", "UnbindAll()");
}
private static PlotModel CreatePlotModel(string title, string subtitle)
{
// Create the plot model
var tmp = new PlotModel { Title = title, Subtitle = subtitle };
tmp.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
tmp.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
// Create two line series (markers are hidden by default)
var series1 = new LineSeries { Title = "Series 1", MarkerType = MarkerType.Circle };
series1.Points.Add(new DataPoint(0, 0));
series1.Points.Add(new DataPoint(10, 18));
series1.Points.Add(new DataPoint(20, 12));
series1.Points.Add(new DataPoint(30, 8));
series1.Points.Add(new DataPoint(40, 15));
var series2 = new LineSeries { Title = "Series 2", MarkerType = MarkerType.Square };
series2.Points.Add(new DataPoint(0, 4));
series2.Points.Add(new DataPoint(10, 12));
series2.Points.Add(new DataPoint(20, 16));
series2.Points.Add(new DataPoint(30, 25));
series2.Points.Add(new DataPoint(40, 5));
// Add the series to the plot model
tmp.Series.Add(series1);
tmp.Series.Add(series2);
// Axes are created automatically if they are not defined
return tmp;
}
/// <summary>
/// Gets the plot model.
/// </summary>
public PlotModel Model { get; private set; }
public PlotModel Model1 { get; private set; }
public PlotModel Model2 { get; private set; }
/// <summary>
/// Gets the plot controller.
/// </summary>
public IPlotController Controller { get; private set; }
}
}

View File

@@ -0,0 +1,27 @@
<Window x:Class="ControllerDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf"
xmlns:local="clr-namespace:ControllerDemo"
Title="OxyPlot Controller Demo" Height="480" Width="640">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<TabControl>
<TabItem Header="Custom controller">
<!-- The OxyPlot control is binding to a PlotModel and a PlotController in the MainViewModel -->
<oxy:PlotView Model="{Binding Model}"
Controller="{Binding Controller}" />
</TabItem>
<TabItem Header="Default controllers">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<oxy:PlotView Model="{Binding Model1}" />
<oxy:PlotView Grid.Column="1" x:Name="plotView2" Model="{Binding Model2}" />
</Grid>
</TabItem>
</TabControl>
</Window>

View File

@@ -0,0 +1,29 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ControllerDemo
{
using WpfExamples;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
[Example("Shows how to define a Controller.")]
public partial class MainWindow
{
/// <summary>
/// Initializes a new instance of the <see cref="MainWindow" /> class.
/// </summary>
public MainWindow()
{
this.InitializeComponent();
this.plotView2.ActualController.UnbindAll();
}
}
}

View File

@@ -0,0 +1,14 @@
<Window x:Class="CoupledAxesDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="http://oxyplot.org/wpf"
Title="CoupledAxesDemo" Height="480" Width="640">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<oxy:PlotView Model="{Binding Model1}"/>
<oxy:PlotView Model="{Binding Model2}" Grid.Column="1"/>
</Grid>
</Window>

View File

@@ -0,0 +1,73 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace CoupledAxesDemo
{
using System;
using System.Windows;
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
using WpfExamples;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
[Example("Shows how to keep two axes in sync.")]
public partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
this.DataContext = this;
this.Model1 = new PlotModel { Title = "Model 1" };
this.Model2 = new PlotModel { Title = "Model 2" };
var axis1 = new LinearAxis { Position = AxisPosition.Bottom };
var axis2 = new LinearAxis { Position = AxisPosition.Bottom };
this.Model1.Axes.Add(axis1);
this.Model2.Axes.Add(axis2);
this.Model1.Series.Add(new FunctionSeries(Math.Sin, 0, 10, 1000));
this.Model2.Series.Add(new FunctionSeries(x => Math.Sin(x) / x, 0, 10, 1000));
bool isInternalChange = false;
axis1.AxisChanged += (s, e) =>
{
if (isInternalChange)
{
return;
}
isInternalChange = true;
axis2.Zoom(axis1.ActualMinimum, axis1.ActualMaximum);
this.Model2.InvalidatePlot(false);
isInternalChange = false;
};
axis2.AxisChanged += (s, e) =>
{
if (isInternalChange)
{
return;
}
isInternalChange = true;
axis1.Zoom(axis2.ActualMinimum, axis2.ActualMaximum);
this.Model1.InvalidatePlot(false);
isInternalChange = false;
};
}
public PlotModel Model1 { get; set; }
public PlotModel Model2 { get; set; }
}
}

View File

@@ -0,0 +1,67 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CsvDocument.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// A class for comma-separated value files
// http://en.wikipedia.org/wiki/Comma-separated_values
// Default is "USA/UK CSV" where the separator is ',' and decimal separator is '.'.
// Todo: Support quoted values...
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
namespace CsvDemo
{
/// <summary>
/// A class for comma-separated value files
/// http://en.wikipedia.org/wiki/Comma-separated_values
/// Default is "USA/UK CSV" where the separator is ',' and decimal separator is '.'.
/// Todo: Support quoted values...
/// </summary>
public class CsvDocument
{
public string[] Headers { get; private set; }
public Collection<string[]> Items { get; private set; }
/// <summary>
/// Loads the specified file name.
/// </summary>
/// <param name="fileName">Name of the file.</param>
/// <param name="separator">The separator (auto-detect if not specified).</param>
public void Load(string fileName, char separator = '\0')
{
using (var r = new StreamReader(fileName))
{
var header = r.ReadLine();
if (separator == '\0')
{
// Auto detect
int commaCount = Count(header, ',');
int semicolonCount = Count(header, ';');
separator = commaCount > semicolonCount ? ',' : ';';
}
Headers = header.Split(separator);
Items = new Collection<string[]>();
while (!r.EndOfStream)
{
var line = r.ReadLine();
if (line == null || line.StartsWith("%") || line.StartsWith("//"))
continue;
Items.Add(line.Split(separator));
}
}
}
private int Count(string s, char c)
{
return s.Count(ch => ch == c);
}
}
}

View File

@@ -0,0 +1,130 @@
Year,Annual mean,5-year mean
// GlobalLand+OceanSurfaceTemperatureAnomaly (Base:1951-1980)
1882,-.22,-.24
1883,-.24,-.25
1884,-.30,-.26
1885,-.30,-.29
1886,-.25,-.29
1887,-.35,-.26
1888,-.26,-.28
1889,-.15,-.28
1890,-.37,-.28
1891,-.28,-.29
1892,-.32,-.32
1893,-.32,-.30
1894,-.33,-.28
1895,-.27,-.24
1896,-.17,-.23
1897,-.13,-.20
1898,-.25,-.16
1899,-.17,-.16
1900,-.10,-.19
1901,-.16,-.20
1902,-.27,-.23
1903,-.31,-.26
1904,-.34,-.27
1905,-.25,-.30
1906,-.20,-.30
1907,-.39,-.30
1908,-.34,-.32
1909,-.35,-.35
1910,-.33,-.34
1911,-.34,-.34
1912,-.34,-.29
1913,-.31,-.25
1914,-.15,-.24
1915,-.09,-.25
1916,-.30,-.25
1917,-.40,-.26
1918,-.32,-.28
1919,-.20,-.25
1920,-.19,-.22
1921,-.13,-.19
1922,-.24,-.20
1923,-.21,-.19
1924,-.21,-.17
1925,-.16,-.14
1926,-.01,-.13
1927,-.13,-.13
1928,-.11,-.11
1929,-.25,-.11
1930,-.07,-.10
1931,-.01,-.11
1932,-.06,-.07
1933,-.17,-.08
1934,-.05,-.08
1935,-.10,-.06
1936,-.03,.00
1937,.08,.02
1938,.12,.05
1939,.03,.08
1940,.05,.07
1941,.11,.06
1942,.04,.10
1943,.10,.10
1944,.20,.07
1945,.07,.07
1946,-.04,.04
1947,.01,-.01
1948,-.04,-.06
1949,-.06,-.05
1950,-.15,-.05
1951,-.04,-.02
1952,.03,-.03
1953,.11,-.02
1954,-.10,-.05
1955,-.10,-.04
1956,-.17,-.04
1957,.08,-.01
1958,.08,.01
1959,.06,.06
1960,-.01,.05
1961,.08,.05
1962,.04,.00
1963,.08,-.02
1964,-.21,-.05
1965,-.11,-.06
1966,-.03,-.08
1967,.00,-.02
1968,-.04,.01
1969,.08,-.01
1970,.03,-.01
1971,-.10,.03
1972,.00,.00
1973,.14,-.02
1974,-.08,-.03
1975,-.05,.00
1976,-.16,-.03
1977,.13,.00
1978,.02,.05
1979,.09,.13
1980,.18,.12
1981,.26,.17
1982,.05,.17
1983,.26,.14
1984,.09,.12
1985,.05,.16
1986,.13,.17
1987,.27,.19
1988,.31,.26
1989,.20,.30
1990,.38,.27
1991,.35,.24
1992,.12,.25
1993,.14,.25
1994,.24,.24
1995,.38,.29
1996,.30,.38
1997,.40,.39
1998,.57,.38
1999,.33,.42
2000,.33,.45
2001,.48,.45
2002,.56,.48
2003,.55,.54
2004,.48,.55
2005,.62,.55
2006,.55,.53
2007,.57,*
2008,.44,*
//----------------------------------
1 Year,Annual mean,5-year mean
2 // GlobalLand+OceanSurfaceTemperatureAnomaly (Base:1951-1980)
3 1882,-.22,-.24
4 1883,-.24,-.25
5 1884,-.30,-.26
6 1885,-.30,-.29
7 1886,-.25,-.29
8 1887,-.35,-.26
9 1888,-.26,-.28
10 1889,-.15,-.28
11 1890,-.37,-.28
12 1891,-.28,-.29
13 1892,-.32,-.32
14 1893,-.32,-.30
15 1894,-.33,-.28
16 1895,-.27,-.24
17 1896,-.17,-.23
18 1897,-.13,-.20
19 1898,-.25,-.16
20 1899,-.17,-.16
21 1900,-.10,-.19
22 1901,-.16,-.20
23 1902,-.27,-.23
24 1903,-.31,-.26
25 1904,-.34,-.27
26 1905,-.25,-.30
27 1906,-.20,-.30
28 1907,-.39,-.30
29 1908,-.34,-.32
30 1909,-.35,-.35
31 1910,-.33,-.34
32 1911,-.34,-.34
33 1912,-.34,-.29
34 1913,-.31,-.25
35 1914,-.15,-.24
36 1915,-.09,-.25
37 1916,-.30,-.25
38 1917,-.40,-.26
39 1918,-.32,-.28
40 1919,-.20,-.25
41 1920,-.19,-.22
42 1921,-.13,-.19
43 1922,-.24,-.20
44 1923,-.21,-.19
45 1924,-.21,-.17
46 1925,-.16,-.14
47 1926,-.01,-.13
48 1927,-.13,-.13
49 1928,-.11,-.11
50 1929,-.25,-.11
51 1930,-.07,-.10
52 1931,-.01,-.11
53 1932,-.06,-.07
54 1933,-.17,-.08
55 1934,-.05,-.08
56 1935,-.10,-.06
57 1936,-.03,.00
58 1937,.08,.02
59 1938,.12,.05
60 1939,.03,.08
61 1940,.05,.07
62 1941,.11,.06
63 1942,.04,.10
64 1943,.10,.10
65 1944,.20,.07
66 1945,.07,.07
67 1946,-.04,.04
68 1947,.01,-.01
69 1948,-.04,-.06
70 1949,-.06,-.05
71 1950,-.15,-.05
72 1951,-.04,-.02
73 1952,.03,-.03
74 1953,.11,-.02
75 1954,-.10,-.05
76 1955,-.10,-.04
77 1956,-.17,-.04
78 1957,.08,-.01
79 1958,.08,.01
80 1959,.06,.06
81 1960,-.01,.05
82 1961,.08,.05
83 1962,.04,.00
84 1963,.08,-.02
85 1964,-.21,-.05
86 1965,-.11,-.06
87 1966,-.03,-.08
88 1967,.00,-.02
89 1968,-.04,.01
90 1969,.08,-.01
91 1970,.03,-.01
92 1971,-.10,.03
93 1972,.00,.00
94 1973,.14,-.02
95 1974,-.08,-.03
96 1975,-.05,.00
97 1976,-.16,-.03
98 1977,.13,.00
99 1978,.02,.05
100 1979,.09,.13
101 1980,.18,.12
102 1981,.26,.17
103 1982,.05,.17
104 1983,.26,.14
105 1984,.09,.12
106 1985,.05,.16
107 1986,.13,.17
108 1987,.27,.19
109 1988,.31,.26
110 1989,.20,.30
111 1990,.38,.27
112 1991,.35,.24
113 1992,.12,.25
114 1993,.14,.25
115 1994,.24,.24
116 1995,.38,.29
117 1996,.30,.38
118 1997,.40,.39
119 1998,.57,.38
120 1999,.33,.42
121 2000,.33,.45
122 2001,.48,.45
123 2002,.56,.48
124 2003,.55,.54
125 2004,.48,.55
126 2005,.62,.55
127 2006,.55,.53
128 2007,.57,*
129 2008,.44,*
130 //----------------------------------

View File

@@ -0,0 +1,366 @@
DayOfYear,75 percentile,50 percentile,25 percentile
1,49.193,21.127,8.777
2,46.47,20.869,8.581
3,45.977,20.094,8.5
4,45.953,19.617,8.532
5,46.357,19.744,8.606
6,47.448,19.651,8.568
7,48.23,19.299,8.571
8,48.529,18.909,8.59
9,49.567,18.897,8.675
10,52.336,19.129,8.699
11,53.17,19.522,8.77
12,54.645,19.872,8.79
13,54.698,19.9,8.795
14,53.519,19.814,8.854
15,52.733,19.796,8.948
16,51.173,20.138,9.105
17,49.453,20.507,9.255
18,46.759,20.748,9.42
19,44.397,20.544,9.577
20,40.57,20.177,9.754
21,38.575,19.801,9.898
22,35.808,19.475,10.038
23,33.824,19.217,10.072
24,32.495,18.875,9.966
25,30.669,18.179,9.761
26,29.326,17.06,9.525
27,28.345,16.105,9.297
28,27.846,15.378,9.071
29,27.584,14.954,8.794
30,27.512,14.52,8.494
31,27.603,14.066,8.213
32,29.068,13.747,7.984
33,31.829,13.44,7.79
34,34.463,13.281,7.617
35,36.26,13.312,7.527
36,37.525,13.348,7.455
37,38.225,13.407,7.388
38,38.569,13.478,7.296
39,38.889,13.404,7.217
40,38.975,13.403,7.173
41,38.962,13.346,7.145
42,37.669,13.271,7.083
43,35.134,13.215,7.117
44,32.634,13.133,7.157
45,30.845,12.963,7.127
46,29.479,12.881,7.058
47,28.51,12.787,6.921
48,28.01,12.661,6.783
49,27.669,12.587,6.66
50,27.229,12.587,6.532
51,26.696,12.653,6.462
52,26.756,12.716,6.392
53,26.679,12.759,6.215
54,26.687,12.73,6.132
55,26.785,12.653,6.105
56,26.946,12.598,6.125
57,27.291,12.532,6.222
58,27.375,12.603,6.387
59,27.273,12.637,6.556
60,27.185,12.581,6.736
61,27.019,12.507,6.888
62,26.326,12.464,7.053
63,26.17,12.48,7.264
64,26.625,12.508,7.422
65,26.749,12.763,7.647
66,26.841,12.953,7.847
67,26.897,13.162,8.032
68,27.037,13.206,8.222
69,27.434,13.282,8.367
70,27.752,13.433,8.503
71,28.006,13.554,8.624
72,28.318,13.677,8.754
73,28.576,13.694,8.83
74,28.35,13.7,8.872
75,28.842,13.465,8.82
76,29.285,13.397,8.774
77,30.394,13.268,8.7
78,31.192,13.154,8.587
79,31.438,13.147,8.507
80,31.562,13.253,8.432
81,31.714,13.564,8.391
82,31.73,13.716,8.367
83,32.106,13.959,8.363
84,32.665,14.147,8.397
85,32.852,14.415,8.48
86,33.016,14.544,8.596
87,33.056,14.714,8.68
88,32.932,14.977,8.783
89,33.223,15.212,8.894
90,33.825,15.34,9.061
91,34.711,15.254,9.252
92,35.589,15.303,9.463
93,35.39,15.437,9.654
94,35,15.695,9.851
95,34.656,16.038,10.04
96,34.817,16.403,10.327
97,35.036,16.831,10.658
98,36,17.253,11.081
99,36.718,17.827,11.445
100,37.432,18.644,11.75
101,37.946,19.718,12.112
102,39.376,20.802,12.48
103,41.372,21.973,13.181
104,43.008,23.509,13.951
105,45.043,24.792,14.736
106,47.379,25.897,15.342
107,49.299,27.08,15.958
108,50.707,28.79,16.48
109,52.318,30.232,17.184
110,55.13,31.786,17.957
111,58.003,32.804,18.739
112,60.907,34.23,19.621
113,64.674,36.111,20.225
114,68.404,37.424,20.586
115,71.771,39.136,20.964
116,74.626,40.178,21.829
117,77.831,41.552,22.809
118,81.643,43.802,23.755
119,86.104,47.505,24.691
120,89.915,50.671,26.154
121,94.757,54.61,27.913
122,98.215,58.149,29.779
123,101.479,61.48,33.217
124,105.083,65.993,37.634
125,107.978,70.787,42.251
126,112.088,75.851,45.953
127,119.428,80.009,49.321
128,125.771,83.123,52.868
129,130.095,85.603,56.467
130,133.998,89.331,60.039
131,139.083,92.704,64.18
132,143.678,98.341,67.011
133,147.795,102.776,68.344
134,150.878,106.5,69.96
135,156.997,109.751,72.063
136,162.641,113.178,73.664
137,165.596,117.007,75.62
138,168.151,120.836,77.339
139,172.718,123.137,80.121
140,176.231,124.718,82.69
141,178.121,126.692,84.56
142,183.312,126.519,88.937
143,186.238,128.312,92.33
144,189.062,131.288,93.458
145,191.432,132.109,94.485
146,192.528,131.947,96.669
147,192.066,132.277,98.263
148,191.135,131.868,99.427
149,191.284,133.477,99.427
150,191.852,135.335,99.109
151,192.484,135.73,98.676
152,191.964,136.158,97.838
153,194.231,136.666,98.531
154,197.098,136.991,100.614
155,197.889,139.87,102.729
156,197.52,143.804,104.777
157,199.251,146.414,105.825
158,201.474,148.735,107.062
159,202.064,149.693,107.607
160,201.938,148.492,107.946
161,201.635,147.894,107.678
162,199.866,147.618,105.333
163,194.997,145.941,102.291
164,189.773,141.09,99.417
165,184.611,135.605,95.759
166,182.78,131.006,92.721
167,180.056,127.459,90.276
168,177.459,124.499,87.705
169,174.869,121.753,85.265
170,170.972,120.383,82.665
171,166.876,118.078,80.992
172,163.159,114.606,80.94
173,162.172,111.47,81.102
174,160.582,111.31,80.849
175,160.642,110.768,80.513
176,158.259,109.167,78.764
177,154.502,107.728,77.52
178,152.924,105.909,76.985
179,150.08,103.11,76.471
180,148.698,100.639,76.531
181,146.599,99.12,76.444
182,145.26,98.254,75.395
183,142.886,98.438,74.134
184,141.733,96.765,72.803
185,139.368,95.237,71.534
186,137.482,94.305,70.69
187,136.83,93.008,69.986
188,134.039,92.116,69.199
189,132.275,92.343,68.788
190,130.743,92.631,68.052
191,129.116,93.225,66.872
192,126.396,93.229,65.852
193,124.305,91.615,63.955
194,122.119,90.711,62.514
195,118.93,89.67,61.3
196,115.911,88.349,59.614
197,112.139,86.481,58.36
198,109.512,85.673,56.945
199,107.619,83.724,55.44
200,106.274,81.378,53.462
201,105.839,78.855,52.425
202,105.693,77.058,51.443
203,105.068,76.135,50.985
204,104.686,74.365,49.859
205,103.936,73.04,48.714
206,103.194,71.953,48.183
207,102.506,71.705,47.528
208,101.53,70.56,46.947
209,100.51,70.316,46.683
210,100.126,70.27,47.049
211,99.129,70.111,46.563
212,98.029,69.669,46.439
213,97.43,68.759,45.898
214,96.212,69.047,45.739
215,96.354,68.999,45.31
216,96.157,68.429,44.877
217,95.723,66.994,44.454
218,95.388,65.05,43.462
219,94.61,62.902,42.337
220,92.45,61.18,40.878
221,90.313,59.959,39.366
222,88.812,58.549,37.988
223,88.358,57.512,37.065
224,89.491,55.81,35.993
225,89.089,54.649,34.961
226,88.699,53.436,34.107
227,89.218,52.222,33.158
228,88.901,51.26,32.626
229,88.013,51.19,31.977
230,88.315,50.8,31.526
231,87.98,49.519,31.062
232,86.743,48.69,30.146
233,84.979,47.237,29.417
234,81.895,45.545,28.713
235,79.447,44.75,28.017
236,78.416,44.153,27.103
237,77.39,44.515,26.522
238.0416667,77.173,45.441,26.027
239,76.503,45.582,25.314
240,75.401,45.681,25.232
241,76.363,46.124,25.173
242,78.687,46.126,25.176
243,80.048,47.234,25.611
244,81.396,49.053,25.77
245,84.578,49.62,26.318
246,86.131,50.906,27.086
247,89.214,52.457,27.197
248,93.029,53.698,27.59
249,97.28,54.171,28.505
250,100.011,54.171,28.644
251,101.553,54.203,28.599
252,101.288,54.303,28.388
253,102.147,53.832,27.68
254,103.53,53.615,27.087
255,105.64,53.832,26.14
256,107.098,53.416,25.222
257,109.116,51.939,24.709
258,112.68,52.349,23.983
259,115.509,53.601,23.092
260,120.616,54.7,22.908
261,123.169,58.081,23.099
262,128.822,62.178,23.772
263,132.976,64.461,24.575
264,138.354,65.973,25.47
265,140.369,68.088,25.885
266,142.521,70.353,26.017
267,138.586,71.895,26.294
268,132.316,70.603,27.506
269,129.669,68.695,28.423
270,126.784,67.772,28.573
271,125.359,64.869,28.186
272,123.408,62.712,27.436
273,121.061,61.421,26.559
274,116.681,59.279,26.187
275.0416667,115.366,58.607,26.636
276,114.583,58.147,27.468
277,117.407,58.63,28.187
278,119.265,60.983,27.885
279,119.124,63.361,27.801
280,119.449,64.703,27.661
281,118.991,66.86,28.093
282,115.618,67.154,28.328
283,112.482,67.123,28.517
284,109.191,67.156,28.046
285,104.218,65.69,27.233
286,100.496,63.232,26.819
287,96.72,60.236,26.154
288,94.952,56.19,25.315
289,91.762,53.531,24.307
290,87.324,51.338,23.379
291,85.99,48.048,22.143
292,86.5,44.703,21.405
293,86.704,42.61,21.244
294,89.365,41.504,21.152
295,91.439,39.632,21.193
296,92.438,40.934,20.599
297,94.275,43.341,20.127
298,95.601,45.221,19.643
299,96.71,45.933,19.41
300.0416667,98.883,46.438,19.234
301,101.442,47.49,19.227
302,103.494,48.641,19.067
303,104.085,49.45,18.856
304,104.609,50.671,18.704
305,106.297,52.571,18.678
306,107.735,51.398,18.681
307,105.827,48.694,18.605
308,102.559,46.163,18.753
309,99.539,44.092,18.861
310,97.159,42.238,19.26
311,93.706,40.227,19.461
312,89.754,38.83,19.53
313,87.614,37.25,19.247
314,83.186,35.468,19.139
315,78.874,33.057,18.641
316,74.862,31.157,17.985
317,71.934,29.892,17.319
318,69.052,28.989,16.574
319,66.94,27.857,15.757
320,63.718,26.878,14.879
321,59.431,25.661,14.236
322,56.662,24.598,13.812
323,56.402,24.211,13.487
324,57.857,24.291,13.084
325,59.647,23.748,13.043
326,60.291,24.014,13.094
327,61.47,25.002,13.222
328,64.589,25.813,13.399
329,67.277,26.711,13.553
330,69.793,27.37,13.564
331,71.701,27.857,13.498
332,71.751,28.393,13.592
333,70.524,28.961,13.611
334,69.164,28.674,13.624
335,65.541,28.633,13.366
336,63.893,27.814,13.114
337,65.048,26.589,12.993
338,64.092,25.736,12.732
339,62.418,25.328,12.624
340,61.277,25.924,12.596
341,60.331,26.29,12.484
342,59.47,26.487,12.309
343,58.32,25.883,12.148
344,57.138,25.887,12.078
345,58.127,25.927,12.057
346,58.14,25.97,11.958
347,55.474,26.256,11.713
348,53.294,26.207,11.629
349,52.155,25.583,11.406
350,50.378,24.222,11.315
351,49.456,23.445,11.208
352,48.808,22.573,10.804
353,48.646,22.211,10.471
354,47.987,21.408,10.104
355,47.638,21.036,9.783
356,49.308,20.74,9.597
357,50.824,20.305,9.586
358,51.266,20.68,9.507
359,52.067,21.064,9.445
360,52.68,21.267,9.243
361,53.962,21.318,9.173
362,54.629,21.618,9.125
363,55.772,21.603,9.016
364,55.282,21.691,8.869
365,53.222,21.437,8.807
1 DayOfYear 75 percentile 50 percentile 25 percentile
2 1 49.193 21.127 8.777
3 2 46.47 20.869 8.581
4 3 45.977 20.094 8.5
5 4 45.953 19.617 8.532
6 5 46.357 19.744 8.606
7 6 47.448 19.651 8.568
8 7 48.23 19.299 8.571
9 8 48.529 18.909 8.59
10 9 49.567 18.897 8.675
11 10 52.336 19.129 8.699
12 11 53.17 19.522 8.77
13 12 54.645 19.872 8.79
14 13 54.698 19.9 8.795
15 14 53.519 19.814 8.854
16 15 52.733 19.796 8.948
17 16 51.173 20.138 9.105
18 17 49.453 20.507 9.255
19 18 46.759 20.748 9.42
20 19 44.397 20.544 9.577
21 20 40.57 20.177 9.754
22 21 38.575 19.801 9.898
23 22 35.808 19.475 10.038
24 23 33.824 19.217 10.072
25 24 32.495 18.875 9.966
26 25 30.669 18.179 9.761
27 26 29.326 17.06 9.525
28 27 28.345 16.105 9.297
29 28 27.846 15.378 9.071
30 29 27.584 14.954 8.794
31 30 27.512 14.52 8.494
32 31 27.603 14.066 8.213
33 32 29.068 13.747 7.984
34 33 31.829 13.44 7.79
35 34 34.463 13.281 7.617
36 35 36.26 13.312 7.527
37 36 37.525 13.348 7.455
38 37 38.225 13.407 7.388
39 38 38.569 13.478 7.296
40 39 38.889 13.404 7.217
41 40 38.975 13.403 7.173
42 41 38.962 13.346 7.145
43 42 37.669 13.271 7.083
44 43 35.134 13.215 7.117
45 44 32.634 13.133 7.157
46 45 30.845 12.963 7.127
47 46 29.479 12.881 7.058
48 47 28.51 12.787 6.921
49 48 28.01 12.661 6.783
50 49 27.669 12.587 6.66
51 50 27.229 12.587 6.532
52 51 26.696 12.653 6.462
53 52 26.756 12.716 6.392
54 53 26.679 12.759 6.215
55 54 26.687 12.73 6.132
56 55 26.785 12.653 6.105
57 56 26.946 12.598 6.125
58 57 27.291 12.532 6.222
59 58 27.375 12.603 6.387
60 59 27.273 12.637 6.556
61 60 27.185 12.581 6.736
62 61 27.019 12.507 6.888
63 62 26.326 12.464 7.053
64 63 26.17 12.48 7.264
65 64 26.625 12.508 7.422
66 65 26.749 12.763 7.647
67 66 26.841 12.953 7.847
68 67 26.897 13.162 8.032
69 68 27.037 13.206 8.222
70 69 27.434 13.282 8.367
71 70 27.752 13.433 8.503
72 71 28.006 13.554 8.624
73 72 28.318 13.677 8.754
74 73 28.576 13.694 8.83
75 74 28.35 13.7 8.872
76 75 28.842 13.465 8.82
77 76 29.285 13.397 8.774
78 77 30.394 13.268 8.7
79 78 31.192 13.154 8.587
80 79 31.438 13.147 8.507
81 80 31.562 13.253 8.432
82 81 31.714 13.564 8.391
83 82 31.73 13.716 8.367
84 83 32.106 13.959 8.363
85 84 32.665 14.147 8.397
86 85 32.852 14.415 8.48
87 86 33.016 14.544 8.596
88 87 33.056 14.714 8.68
89 88 32.932 14.977 8.783
90 89 33.223 15.212 8.894
91 90 33.825 15.34 9.061
92 91 34.711 15.254 9.252
93 92 35.589 15.303 9.463
94 93 35.39 15.437 9.654
95 94 35 15.695 9.851
96 95 34.656 16.038 10.04
97 96 34.817 16.403 10.327
98 97 35.036 16.831 10.658
99 98 36 17.253 11.081
100 99 36.718 17.827 11.445
101 100 37.432 18.644 11.75
102 101 37.946 19.718 12.112
103 102 39.376 20.802 12.48
104 103 41.372 21.973 13.181
105 104 43.008 23.509 13.951
106 105 45.043 24.792 14.736
107 106 47.379 25.897 15.342
108 107 49.299 27.08 15.958
109 108 50.707 28.79 16.48
110 109 52.318 30.232 17.184
111 110 55.13 31.786 17.957
112 111 58.003 32.804 18.739
113 112 60.907 34.23 19.621
114 113 64.674 36.111 20.225
115 114 68.404 37.424 20.586
116 115 71.771 39.136 20.964
117 116 74.626 40.178 21.829
118 117 77.831 41.552 22.809
119 118 81.643 43.802 23.755
120 119 86.104 47.505 24.691
121 120 89.915 50.671 26.154
122 121 94.757 54.61 27.913
123 122 98.215 58.149 29.779
124 123 101.479 61.48 33.217
125 124 105.083 65.993 37.634
126 125 107.978 70.787 42.251
127 126 112.088 75.851 45.953
128 127 119.428 80.009 49.321
129 128 125.771 83.123 52.868
130 129 130.095 85.603 56.467
131 130 133.998 89.331 60.039
132 131 139.083 92.704 64.18
133 132 143.678 98.341 67.011
134 133 147.795 102.776 68.344
135 134 150.878 106.5 69.96
136 135 156.997 109.751 72.063
137 136 162.641 113.178 73.664
138 137 165.596 117.007 75.62
139 138 168.151 120.836 77.339
140 139 172.718 123.137 80.121
141 140 176.231 124.718 82.69
142 141 178.121 126.692 84.56
143 142 183.312 126.519 88.937
144 143 186.238 128.312 92.33
145 144 189.062 131.288 93.458
146 145 191.432 132.109 94.485
147 146 192.528 131.947 96.669
148 147 192.066 132.277 98.263
149 148 191.135 131.868 99.427
150 149 191.284 133.477 99.427
151 150 191.852 135.335 99.109
152 151 192.484 135.73 98.676
153 152 191.964 136.158 97.838
154 153 194.231 136.666 98.531
155 154 197.098 136.991 100.614
156 155 197.889 139.87 102.729
157 156 197.52 143.804 104.777
158 157 199.251 146.414 105.825
159 158 201.474 148.735 107.062
160 159 202.064 149.693 107.607
161 160 201.938 148.492 107.946
162 161 201.635 147.894 107.678
163 162 199.866 147.618 105.333
164 163 194.997 145.941 102.291
165 164 189.773 141.09 99.417
166 165 184.611 135.605 95.759
167 166 182.78 131.006 92.721
168 167 180.056 127.459 90.276
169 168 177.459 124.499 87.705
170 169 174.869 121.753 85.265
171 170 170.972 120.383 82.665
172 171 166.876 118.078 80.992
173 172 163.159 114.606 80.94
174 173 162.172 111.47 81.102
175 174 160.582 111.31 80.849
176 175 160.642 110.768 80.513
177 176 158.259 109.167 78.764
178 177 154.502 107.728 77.52
179 178 152.924 105.909 76.985
180 179 150.08 103.11 76.471
181 180 148.698 100.639 76.531
182 181 146.599 99.12 76.444
183 182 145.26 98.254 75.395
184 183 142.886 98.438 74.134
185 184 141.733 96.765 72.803
186 185 139.368 95.237 71.534
187 186 137.482 94.305 70.69
188 187 136.83 93.008 69.986
189 188 134.039 92.116 69.199
190 189 132.275 92.343 68.788
191 190 130.743 92.631 68.052
192 191 129.116 93.225 66.872
193 192 126.396 93.229 65.852
194 193 124.305 91.615 63.955
195 194 122.119 90.711 62.514
196 195 118.93 89.67 61.3
197 196 115.911 88.349 59.614
198 197 112.139 86.481 58.36
199 198 109.512 85.673 56.945
200 199 107.619 83.724 55.44
201 200 106.274 81.378 53.462
202 201 105.839 78.855 52.425
203 202 105.693 77.058 51.443
204 203 105.068 76.135 50.985
205 204 104.686 74.365 49.859
206 205 103.936 73.04 48.714
207 206 103.194 71.953 48.183
208 207 102.506 71.705 47.528
209 208 101.53 70.56 46.947
210 209 100.51 70.316 46.683
211 210 100.126 70.27 47.049
212 211 99.129 70.111 46.563
213 212 98.029 69.669 46.439
214 213 97.43 68.759 45.898
215 214 96.212 69.047 45.739
216 215 96.354 68.999 45.31
217 216 96.157 68.429 44.877
218 217 95.723 66.994 44.454
219 218 95.388 65.05 43.462
220 219 94.61 62.902 42.337
221 220 92.45 61.18 40.878
222 221 90.313 59.959 39.366
223 222 88.812 58.549 37.988
224 223 88.358 57.512 37.065
225 224 89.491 55.81 35.993
226 225 89.089 54.649 34.961
227 226 88.699 53.436 34.107
228 227 89.218 52.222 33.158
229 228 88.901 51.26 32.626
230 229 88.013 51.19 31.977
231 230 88.315 50.8 31.526
232 231 87.98 49.519 31.062
233 232 86.743 48.69 30.146
234 233 84.979 47.237 29.417
235 234 81.895 45.545 28.713
236 235 79.447 44.75 28.017
237 236 78.416 44.153 27.103
238 237 77.39 44.515 26.522
239 238.0416667 77.173 45.441 26.027
240 239 76.503 45.582 25.314
241 240 75.401 45.681 25.232
242 241 76.363 46.124 25.173
243 242 78.687 46.126 25.176
244 243 80.048 47.234 25.611
245 244 81.396 49.053 25.77
246 245 84.578 49.62 26.318
247 246 86.131 50.906 27.086
248 247 89.214 52.457 27.197
249 248 93.029 53.698 27.59
250 249 97.28 54.171 28.505
251 250 100.011 54.171 28.644
252 251 101.553 54.203 28.599
253 252 101.288 54.303 28.388
254 253 102.147 53.832 27.68
255 254 103.53 53.615 27.087
256 255 105.64 53.832 26.14
257 256 107.098 53.416 25.222
258 257 109.116 51.939 24.709
259 258 112.68 52.349 23.983
260 259 115.509 53.601 23.092
261 260 120.616 54.7 22.908
262 261 123.169 58.081 23.099
263 262 128.822 62.178 23.772
264 263 132.976 64.461 24.575
265 264 138.354 65.973 25.47
266 265 140.369 68.088 25.885
267 266 142.521 70.353 26.017
268 267 138.586 71.895 26.294
269 268 132.316 70.603 27.506
270 269 129.669 68.695 28.423
271 270 126.784 67.772 28.573
272 271 125.359 64.869 28.186
273 272 123.408 62.712 27.436
274 273 121.061 61.421 26.559
275 274 116.681 59.279 26.187
276 275.0416667 115.366 58.607 26.636
277 276 114.583 58.147 27.468
278 277 117.407 58.63 28.187
279 278 119.265 60.983 27.885
280 279 119.124 63.361 27.801
281 280 119.449 64.703 27.661
282 281 118.991 66.86 28.093
283 282 115.618 67.154 28.328
284 283 112.482 67.123 28.517
285 284 109.191 67.156 28.046
286 285 104.218 65.69 27.233
287 286 100.496 63.232 26.819
288 287 96.72 60.236 26.154
289 288 94.952 56.19 25.315
290 289 91.762 53.531 24.307
291 290 87.324 51.338 23.379
292 291 85.99 48.048 22.143
293 292 86.5 44.703 21.405
294 293 86.704 42.61 21.244
295 294 89.365 41.504 21.152
296 295 91.439 39.632 21.193
297 296 92.438 40.934 20.599
298 297 94.275 43.341 20.127
299 298 95.601 45.221 19.643
300 299 96.71 45.933 19.41
301 300.0416667 98.883 46.438 19.234
302 301 101.442 47.49 19.227
303 302 103.494 48.641 19.067
304 303 104.085 49.45 18.856
305 304 104.609 50.671 18.704
306 305 106.297 52.571 18.678
307 306 107.735 51.398 18.681
308 307 105.827 48.694 18.605
309 308 102.559 46.163 18.753
310 309 99.539 44.092 18.861
311 310 97.159 42.238 19.26
312 311 93.706 40.227 19.461
313 312 89.754 38.83 19.53
314 313 87.614 37.25 19.247
315 314 83.186 35.468 19.139
316 315 78.874 33.057 18.641
317 316 74.862 31.157 17.985
318 317 71.934 29.892 17.319
319 318 69.052 28.989 16.574
320 319 66.94 27.857 15.757
321 320 63.718 26.878 14.879
322 321 59.431 25.661 14.236
323 322 56.662 24.598 13.812
324 323 56.402 24.211 13.487
325 324 57.857 24.291 13.084
326 325 59.647 23.748 13.043
327 326 60.291 24.014 13.094
328 327 61.47 25.002 13.222
329 328 64.589 25.813 13.399
330 329 67.277 26.711 13.553
331 330 69.793 27.37 13.564
332 331 71.701 27.857 13.498
333 332 71.751 28.393 13.592
334 333 70.524 28.961 13.611
335 334 69.164 28.674 13.624
336 335 65.541 28.633 13.366
337 336 63.893 27.814 13.114
338 337 65.048 26.589 12.993
339 338 64.092 25.736 12.732
340 339 62.418 25.328 12.624
341 340 61.277 25.924 12.596
342 341 60.331 26.29 12.484
343 342 59.47 26.487 12.309
344 343 58.32 25.883 12.148
345 344 57.138 25.887 12.078
346 345 58.127 25.927 12.057
347 346 58.14 25.97 11.958
348 347 55.474 26.256 11.713
349 348 53.294 26.207 11.629
350 349 52.155 25.583 11.406
351 350 50.378 24.222 11.315
352 351 49.456 23.445 11.208
353 352 48.808 22.573 10.804
354 353 48.646 22.211 10.471
355 354 47.987 21.408 10.104
356 355 47.638 21.036 9.783
357 356 49.308 20.74 9.597
358 357 50.824 20.305 9.586
359 358 51.266 20.68 9.507
360 359 52.067 21.064 9.445
361 360 52.68 21.267 9.243
362 361 53.962 21.318 9.173
363 362 54.629 21.618 9.125
364 363 55.772 21.603 9.016
365 364 55.282 21.691 8.869
366 365 53.222 21.437 8.807

View File

@@ -0,0 +1,31 @@
Year,Population
-10000,1.000
-9000,3.000
-8000,5.000
-7000,7.000
-6000,10.000
-5000,15.000
-4000,20.000
-3000,25.000
-2000,35.000
-1000,50.000
-500,100.000
1,200.000
1000,310.000
1750,791.000
1800,978.000
1850,1262.000
1900,1650.000
1950,2518.629
1955,2755.823
1960,2981.659
1965,3334.874
1970,3692.492
1975,4068.109
1980,4434.682
1985,4830.979
1990,5263.593
1995,5674.380
2000,6070.581
2005,6453.628
2008,6706.993
1 Year Population
2 -10000 1.000
3 -9000 3.000
4 -8000 5.000
5 -7000 7.000
6 -6000 10.000
7 -5000 15.000
8 -4000 20.000
9 -3000 25.000
10 -2000 35.000
11 -1000 50.000
12 -500 100.000
13 1 200.000
14 1000 310.000
15 1750 791.000
16 1800 978.000
17 1850 1262.000
18 1900 1650.000
19 1950 2518.629
20 1955 2755.823
21 1960 2981.659
22 1965 3334.874
23 1970 3692.492
24 1975 4068.109
25 1980 4434.682
26 1985 4830.979
27 1990 5263.593
28 1995 5674.380
29 2000 6070.581
30 2005 6453.628
31 2008 6706.993

View File

@@ -0,0 +1,89 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainViewModel.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace CsvDemo
{
using System.Globalization;
using System.IO;
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
using OxyPlot.Legends;
using WpfExamples;
public class MainViewModel : Observable
{
private PlotModel model;
public PlotModel Model
{
get
{
return this.model;
}
set
{
if (this.model != value)
{
this.SetValue(ref this.model, value);
}
}
}
public void Open(string file)
{
var doc = new CsvDocument();
doc.Load(file);
var tmp = new PlotModel
{
Title = Path.GetFileNameWithoutExtension(file),
PlotMargins = new OxyThickness(50, 0, 0, 40)
};
var l = new Legend
{
LegendPosition = LegendPosition.RightTop,
LegendPlacement = LegendPlacement.Outside
};
tmp.Legends.Add(l);
for (int i = 1; i < doc.Headers.Length; i++)
{
var ls = new LineSeries { Title = doc.Headers[i] };
foreach (var item in doc.Items)
{
double x = this.ParseDouble(item[0]);
double y = this.ParseDouble(item[i]);
ls.Points.Add(new DataPoint(x, y));
}
tmp.Series.Add(ls);
}
tmp.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = doc.Headers[0] });
this.Model = tmp;
}
private double ParseDouble(string s)
{
if (s == null)
{
return double.NaN;
}
s = s.Replace(',', '.');
double result;
if (double.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out result))
{
return result;
}
return double.NaN;
}
}
}

View File

@@ -0,0 +1,33 @@
<Window x:Class="CsvDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf"
Title="CsvDemo" Height="480" Width="640"
AllowDrop="True" Drop="Window_Drop">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="File">
<MenuItem Header="Open csv..." Click="OpenCsv_Click"/>
<Separator/>
<MenuItem Header="Save plot..." Click="SavePlot_Click"/>
<!--<MenuItem Header="Save report..." Click="SaveReport_Click"/>-->
<Separator/>
<MenuItem Header="Exit" Click="Exit_Click"/>
</MenuItem>
<MenuItem Header="Edit">
<MenuItem Header="Copy svg" Click="CopySvg_Click"/>
<MenuItem Header="Copy bitmap" Click="CopyBitmap_Click"/>
<MenuItem Header="Copy xaml" Click="CopyXaml_Click"/>
</MenuItem>
<MenuItem Header="Help">
<MenuItem Header="Website" Click="HelpWeb_Click"/>
<MenuItem Header="About" Click="HelpAbout_Click"/>
</MenuItem>
</Menu>
<Grid>
<oxy:PlotView
x:Name="plot1"
Model="{Binding Model}"
Background="White"/>
</Grid>
</DockPanel>
</Window>

View File

@@ -0,0 +1,149 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace CsvDemo
{
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
using OxyPlot;
using OxyPlot.Wpf;
using WpfExamples;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
[Example("Plotting data from CSV files.")]
public partial class MainWindow
{
private readonly MainViewModel vm = new MainViewModel();
public MainWindow()
{
this.InitializeComponent();
this.DataContext = this.vm;
// vm.Open("Examples\CsvDemo\Data\GlobalTemperatureAnomaly.csv");
// vm.Open("Examples\CsvDemo\Data\WorldPopulation.csv");
this.vm.Open(@"Examples\CsvDemo\Data\RiverFlow.csv");
}
private void Window_Drop(object sender, DragEventArgs e)
{
var data = e.Data as DataObject;
if (data != null && data.ContainsFileDropList())
{
foreach (var file in data.GetFileDropList())
{
this.vm.Open(file);
}
}
}
private void Exit_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
private void OpenCsv_Click(object sender, RoutedEventArgs e)
{
var dlg = new OpenFileDialog();
dlg.Filter = ".csv files|*.csv";
dlg.DefaultExt = ".csv";
if (dlg.ShowDialog(this).Value)
{
this.vm.Open(dlg.FileName);
}
}
private void SavePlot_Click(object sender, RoutedEventArgs e)
{
var dlg = new SaveFileDialog
{
Filter = ".svg files|*.svg|.png files|*.png|.pdf files|*.pdf|.xaml files|*.xaml",
DefaultExt = ".svg"
};
if (dlg.ShowDialog(this).Value)
{
var ext = Path.GetExtension(dlg.FileName).ToLower();
switch (ext)
{
case ".png":
plot1.SaveBitmap(dlg.FileName, 0, 0);
break;
case ".svg":
var rc = new CanvasRenderContext(new Canvas());
var svg = OxyPlot.SvgExporter.ExportToString(this.vm.Model, plot1.ActualWidth, plot1.ActualHeight, false, rc);
File.WriteAllText(dlg.FileName, svg);
break;
case ".pdf":
using (var s = File.Create(dlg.FileName))
{
PdfExporter.Export(vm.Model, s, plot1.ActualWidth, plot1.ActualHeight);
}
break;
case ".xaml":
plot1.SaveXaml(dlg.FileName);
break;
}
this.OpenContainingFolder(dlg.FileName);
}
}
private void OpenContainingFolder(string fileName)
{
// var folder = Path.GetDirectoryName(fileName);
var psi = new ProcessStartInfo("Explorer.exe", "/select," + fileName);
Process.Start(psi);
}
//private void SaveReport_Click(object sender, RoutedEventArgs e)
//{
// var dlg = new SaveFileDialog { Filter = ".html files|*.html", DefaultExt = ".html" };
// if (dlg.ShowDialog(this).Value)
// {
// this.vm.SaveReport(dlg.FileName);
// this.OpenContainingFolder(dlg.FileName);
// }
//}
private void CopySvg_Click(object sender, RoutedEventArgs e)
{
var rc = new CanvasRenderContext(null);
var svg = OxyPlot.SvgExporter.ExportToString(this.vm.Model, plot1.ActualWidth, plot1.ActualHeight, true, rc);
Clipboard.SetText(svg);
}
private void CopyBitmap_Click(object sender, RoutedEventArgs e)
{
Clipboard.SetImage(plot1.ToBitmap());
}
private void CopyXaml_Click(object sender, RoutedEventArgs e)
{
Clipboard.SetText(plot1.ToXaml());
}
private void HelpAbout_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("by OxyPlot");
}
private void HelpWeb_Click(object sender, RoutedEventArgs e)
{
Process.Start("http://oxyplot.org");
}
}
}

View File

@@ -0,0 +1,171 @@
<Window x:Class="CustomTrackerDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf" xmlns:oxyshared="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf.Shared"
Title="CustomTrackerDemo" Height="480" Width="640">
<Window.Resources>
<oxyshared:OxyColorConverter x:Key="OxyColorConverter" />
</Window.Resources>
<TabControl Margin="4">
<TabItem Header="Custom background brush">
<oxy:PlotView Model="{Binding Model}">
<oxy:PlotView.DefaultTrackerTemplate>
<ControlTemplate>
<oxyshared:TrackerControl Position="{Binding Position}" LineExtents="{Binding PlotModel.PlotArea}">
<oxyshared:TrackerControl.Background>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Color="#f0e0e0ff" />
<GradientStop Offset="1" Color="#f0ffffff" />
</LinearGradientBrush>
</oxyshared:TrackerControl.Background>
<oxyshared:TrackerControl.Content>
<TextBlock Text="{Binding}" Margin="7" />
</oxyshared:TrackerControl.Content>
</oxyshared:TrackerControl>
</ControlTemplate>
</oxy:PlotView.DefaultTrackerTemplate>
</oxy:PlotView>
</TabItem>
<TabItem Header="Border by series color">
<oxy:PlotView Model="{Binding Model}">
<oxy:PlotView.DefaultTrackerTemplate>
<ControlTemplate>
<oxyshared:TrackerControl Position="{Binding Position}" LineExtents="{Binding PlotModel.PlotArea}" BorderBrush="{Binding Series.ActualColor, Converter={StaticResource OxyColorConverter}}" BorderThickness="3">
<oxyshared:TrackerControl.Content>
<TextBlock Text="{Binding}" Margin="7" />
</oxyshared:TrackerControl.Content>
</oxyshared:TrackerControl>
</ControlTemplate>
</oxy:PlotView.DefaultTrackerTemplate>
</oxy:PlotView>
</TabItem>
<TabItem Header="No tracker">
<oxy:PlotView Model="{Binding Model}" DefaultTrackerTemplate="{x:Null}" />
</TabItem>
<TabItem Header="Rounded box">
<oxy:PlotView Model="{Binding Model}">
<oxy:PlotView.DefaultTrackerTemplate>
<ControlTemplate>
<oxyshared:TrackerControl Position="{Binding Position}" ShowPointer="False" CornerRadius="8" BorderEdgeMode="Unspecified" LineExtents="{Binding PlotModel.PlotArea}">
<oxyshared:TrackerControl.Content>
<TextBlock Text="{Binding}" Margin="7" />
</oxyshared:TrackerControl.Content>
</oxyshared:TrackerControl>
</ControlTemplate>
</oxy:PlotView.DefaultTrackerTemplate>
</oxy:PlotView>
</TabItem>
<TabItem Header="No vertical line">
<oxy:PlotView Model="{Binding Model}">
<oxy:PlotView.DefaultTrackerTemplate>
<ControlTemplate>
<oxyshared:TrackerControl Position="{Binding Position}" VerticalLineVisibility="Collapsed" LineExtents="{Binding PlotModel.PlotArea}">
<oxyshared:TrackerControl.Content>
<TextBlock Text="{Binding}" Margin="7" />
</oxyshared:TrackerControl.Content>
</oxyshared:TrackerControl>
</ControlTemplate>
</oxy:PlotView.DefaultTrackerTemplate>
</oxy:PlotView>
</TabItem>
<TabItem Header="Border">
<oxy:PlotView Model="{Binding Model}">
<oxy:PlotView.DefaultTrackerTemplate>
<ControlTemplate>
<Canvas>
<Border CornerRadius="0 6 6 6" BorderBrush="Black" BorderThickness="1" Background="White" Canvas.Left="{Binding Position.X}" Canvas.Top="{Binding Position.Y}" Padding="5" Margin="0">
<TextBlock Text="{Binding}" />
</Border>
</Canvas>
</ControlTemplate>
</oxy:PlotView.DefaultTrackerTemplate>
</oxy:PlotView>
</TabItem>
<TabItem Header="TextBlock">
<oxy:PlotView Model="{Binding Model}">
<oxy:PlotView.DefaultTrackerTemplate>
<ControlTemplate>
<Canvas>
<TextBlock Canvas.Left="{Binding Position.X}" Canvas.Top="{Binding Position.Y}" Padding="5" Margin="10" Background="#a0ffffff" Text="{Binding}" />
</Canvas>
</ControlTemplate>
</oxy:PlotView.DefaultTrackerTemplate>
</oxy:PlotView>
</TabItem>
<TabItem Header="Circle">
<oxy:PlotView Model="{Binding Model}">
<oxy:PlotView.DefaultTrackerTemplate>
<ControlTemplate>
<Canvas>
<Grid Canvas.Left="{Binding Position.X}" Canvas.Top="{Binding Position.Y}">
<Ellipse Fill="Black" Width="12" Height="12" HorizontalAlignment="Left" VerticalAlignment="Top">
<Ellipse.RenderTransform>
<TranslateTransform X="-6" Y="-6" />
</Ellipse.RenderTransform>
</Ellipse>
<TextBlock Text="{Binding DataPoint.Y, StringFormat='{}{0:0.00}'}" Margin="6 6 0 0" />
</Grid>
</Canvas>
</ControlTemplate>
</oxy:PlotView.DefaultTrackerTemplate>
</oxy:PlotView>
</TabItem>
<TabItem Header="UniformPanel">
<oxy:PlotView Model="{Binding Model}">
<oxy:PlotView.DefaultTrackerTemplate>
<ControlTemplate>
<oxyshared:TrackerControl Position="{Binding Position}" LineExtents="{Binding PlotModel.PlotArea}">
<oxyshared:TrackerControl.Content>
<UniformGrid Columns="2" Canvas.Left="{Binding Position.X}" Canvas.Top="{Binding Position.Y}" Margin="6">
<TextBlock Text="X:" FontWeight="Bold" />
<TextBlock Text="{Binding DataPoint.X, StringFormat='{}{0:0.000}'}" />
<TextBlock Text="Y:" FontWeight="Bold" />
<TextBlock Text="{Binding DataPoint.Y, StringFormat='{}{0:0.000}'}" />
<TextBlock Text="Dataset:" FontWeight="Bold" />
<TextBlock Text="{Binding Series.Title}" />
</UniformGrid>
</oxyshared:TrackerControl.Content>
</oxyshared:TrackerControl>
</ControlTemplate>
</oxy:PlotView.DefaultTrackerTemplate>
</oxy:PlotView>
</TabItem>
<TabItem Header="Different trackers">
<oxy:PlotView Model="{Binding Model}">
<oxy:PlotView.TrackerDefinitions>
<oxyshared:TrackerDefinition TrackerKey="Tracker1">
<oxyshared:TrackerDefinition.TrackerTemplate>
<ControlTemplate>
<Canvas>
<TextBlock Canvas.Left="{Binding Position.X}" Canvas.Top="{Binding Position.Y}" Padding="5" Margin="10" Background="LightBlue" Text="{Binding}" />
</Canvas>
</ControlTemplate>
</oxyshared:TrackerDefinition.TrackerTemplate>
</oxyshared:TrackerDefinition>
<oxyshared:TrackerDefinition TrackerKey="Tracker2">
<oxyshared:TrackerDefinition.TrackerTemplate>
<ControlTemplate>
<Canvas>
<TextBlock Canvas.Left="{Binding Position.X}" Canvas.Top="{Binding Position.Y}" Padding="5" Margin="10" Background="LightGreen" Text="{Binding}" />
</Canvas>
</ControlTemplate>
</oxyshared:TrackerDefinition.TrackerTemplate>
</oxyshared:TrackerDefinition>
</oxy:PlotView.TrackerDefinitions>
</oxy:PlotView>
</TabItem>
<TabItem Header="Bind to Item">
<oxy:PlotView Model="{Binding Model}">
<oxy:PlotView.DefaultTrackerTemplate>
<ControlTemplate>
<oxyshared:TrackerControl Position="{Binding Position}" LineExtents="{Binding LineExtents}">
<oxyshared:TrackerControl.Content>
<!-- We can bind to the items from the ItemsSource -->
<TextBlock Text="{Binding Item, StringFormat='Item={0}'}" Margin="8"/>
</oxyshared:TrackerControl.Content>
</oxyshared:TrackerControl>
</ControlTemplate>
</oxy:PlotView.DefaultTrackerTemplate>
</oxy:PlotView>
</TabItem>
</TabControl>
</Window>

View File

@@ -0,0 +1,43 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace CustomTrackerDemo
{
using System.Collections.Generic;
using System.Windows;
using OxyPlot;
using OxyPlot.Series;
using WpfExamples;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
[Example("Demonstrates a custom tracker.")]
public partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
this.DataContext = this;
}
public PlotModel Model
{
get
{
var model = new PlotModel();
model.Series.Add(new LineSeries { Title = "Series 1", TrackerKey = "Tracker1", ItemsSource = new List<DataPoint> { new DataPoint(0, 0), new DataPoint(10, 20), new DataPoint(20, 18) } });
model.Series.Add(new LineSeries { Title = "Series 2", TrackerKey = "Tracker2", ItemsSource = new List<DataPoint> { new DataPoint(0, 10), new DataPoint(10, 10), new DataPoint(20, 16) } });
return model;
}
}
}
}

View File

@@ -0,0 +1,21 @@
<Window x:Class="DataTemplateDemo.PlotViewDataTemplateWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf"
Title="PlotView in DataTemplate"
Height="480"
Width="640">
<TabControl ItemsSource="{Binding Models}">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding PlotModel.Title}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<oxy:PlotView Model="{Binding PlotModel}" Controller="{Binding PlotController}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Window>

View File

@@ -0,0 +1,68 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PlotViewDataTemplateWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for PlotViewDataTemplateWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace DataTemplateDemo
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using OxyPlot;
using OxyPlot.Series;
using WpfExamples;
/// <summary>
/// Interaction logic for PlotViewDataTemplateWindow.xaml
/// </summary>
[Example("Demonstrates a PlotView in a DataTemplate.")]
public partial class PlotViewDataTemplateWindow : Window
{
public PlotViewDataTemplateWindow()
{
this.InitializeComponent();
this.Models = CreateModels().ToArray();
this.DataContext = this;
}
public IList<Model> Models { get; private set; }
private static Random r = new Random(13);
private static IEnumerable<Model> CreateModels()
{
for (var i = 0; i < 3; i++)
{
var pm = new PlotModel { Title = string.Format("Plot {0}", i + 1) };
var series = new LineSeries();
for (var j = 0; j < 10; j++)
{
series.Points.Add(new DataPoint(j, r.NextDouble()));
}
pm.Series.Add(series);
var pc = new PlotController();
pc.UnbindAll();
pc.BindKeyDown(OxyKey.Left, PlotCommands.PanRight);
pc.BindKeyDown(OxyKey.Right, PlotCommands.PanLeft);
yield return new Model { PlotModel = pm, PlotController = pc };
}
}
public class Model
{
public PlotModel PlotModel { get; set; }
public IPlotController PlotController { get; set; }
}
}
}

View File

@@ -0,0 +1,18 @@
<Window x:Class="HistogramDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf"
Title="HistogramDemo" Height="480" Width="640">
<DockPanel Margin="10">
<StackPanel DockPanel.Dock="Bottom" Width="300">
<TextBlock Name="instructions" Text="Use the mouse to 'drag' a line across the image below ..." FontSize="10" Foreground="#333333" Margin="5" TextWrapping="Wrap"/>
<Grid Name="grid" MouseLeftButtonUp="Grid_MouseLeftButtonUp" MouseLeftButtonDown="Grid_MouseLeftButtonDown">
<Image Width="300" Height="200" x:Name="image" Source="/Examples/HistogramDemo/hare.jpg"/>
<Line Stroke="Black" StrokeThickness="3" x:Name="line"/>
</Grid>
</StackPanel>
<Grid>
<oxy:PlotView x:Name="chart"/>
</Grid>
</DockPanel>
</Window>

View File

@@ -0,0 +1,148 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace HistogramDemo
{
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
using WpfExamples;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
[Example("Plots a histogram of RGB components.")]
public partial class MainWindow
{
private readonly LineSeries blueLine;
private readonly LineSeries greenLine;
private readonly LineSeries redLine;
private bool leftButtonDown;
private int[] pixelData;
public MainWindow()
{
this.InitializeComponent();
this.LoadPixelData();
var throttledEvent = new ThrottledMouseMoveEvent(image);
throttledEvent.ThrottledMouseMove += this.ThrottledEvent_ThrottledMouseMove;
var pm = new PlotModel { Title = "RGB histogram" };
this.redLine = new LineSeries { Color = OxyColors.Red };
this.greenLine = new LineSeries { Color = OxyColors.Green };
this.blueLine = new LineSeries { Color = OxyColors.Blue };
this.redLine.InterpolationAlgorithm = InterpolationAlgorithms.CanonicalSpline;
this.greenLine.InterpolationAlgorithm = InterpolationAlgorithms.CanonicalSpline;
this.blueLine.InterpolationAlgorithm = InterpolationAlgorithms.CanonicalSpline;
pm.Series.Add(this.redLine);
pm.Series.Add(this.greenLine);
pm.Series.Add(this.blueLine);
pm.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 0, Maximum = 1, MajorStep = 0.2, MinorStep = 0.05, Title = "Frequency" });
pm.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = 0, Maximum = 100, Title = "Lightness" });
chart.Model = pm;
}
/// <summary>
/// Obtains the image data once it is loaded
/// </summary>
private void LoadPixelData()
{
var bitmapImage = new BitmapImage(new Uri("pack://application:,,,/Examples/HistogramDemo/hare.jpg"));
int stride = ((bitmapImage.PixelWidth * bitmapImage.Format.BitsPerPixel) + 7) / 8;
var pixelByteArray = new byte[bitmapImage.PixelHeight * stride];
bitmapImage.CopyPixels(pixelByteArray, stride, 0);
this.pixelData = new int[pixelByteArray.Length / 4];
Buffer.BlockCopy(pixelByteArray, 0, this.pixelData, 0, pixelByteArray.Length);
}
/// <summary>
/// Handles mouse move to draw the line and intensity histograms
/// </summary>
private void ThrottledEvent_ThrottledMouseMove(object sender, MouseEventArgs e)
{
if (!this.leftButtonDown)
{
return;
}
line.X2 = e.GetPosition(grid).X;
line.Y2 = e.GetPosition(grid).Y;
// compute distance between the points
double distance = Math.Sqrt((line.X1 - line.X2) * (line.X1 - line.X2) + (line.Y1 - line.Y2) * (line.Y1 - line.Y2));
this.redLine.Points.Clear();
this.greenLine.Points.Clear();
this.blueLine.Points.Clear();
int b = 16;
var histoR = new int[256 / b];
var histoG = new int[256 / b];
var histoB = new int[256 / b];
// build the charts
int n = 0;
for (double pt = 0; pt < distance; pt++)
{
double xPos = line.X1 + (line.X2 - line.X1) * pt / distance;
double yPos = line.Y1 + (line.Y2 - line.Y1) * pt / distance;
var xIndex = (int)xPos;
var yIndex = (int)yPos;
int pixel = this.pixelData[xIndex + (yIndex * 300)];
// the RGB values are 'packed' into an int, here we unpack them
var blue = (byte)(pixel & 0xFF);
pixel >>= 8;
var green = (byte)(pixel & 0xFF);
pixel >>= 8;
var red = (byte)(pixel & 0xFF);
histoR[red / b]++;
histoG[green / b]++;
histoB[blue / b]++;
n++;
}
double xScale = 100.0 / histoR.Length;
for (int i = 0; i < histoR.Length; i++)
{
double x = i * xScale;
this.redLine.Points.Add(new DataPoint(x, (double)histoR[i] / n));
this.greenLine.Points.Add(new DataPoint(x, (double)histoG[i] / n));
this.blueLine.Points.Add(new DataPoint(x, (double)histoB[i] / n));
}
chart.InvalidatePlot();
}
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
instructions.Visibility = Visibility.Collapsed;
this.leftButtonDown = true;
line.X1 = line.X2 = e.GetPosition(grid).X;
line.Y1 = line.Y2 = e.GetPosition(grid).Y;
}
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
this.leftButtonDown = false;
}
}
}

View File

@@ -0,0 +1,68 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ThrottledMouseEvent.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Creates a 'throttled' MouseMove event which ensures that the UI
// rendering is not starved.
// see: http://www.scottlogic.co.uk/blog/colin/2010/06/throttling-silverlight-mouse-events-to-keep-the-ui-responsive/
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace HistogramDemo
{
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
/// <summary>
/// Creates a 'throttled' MouseMove event which ensures that the UI
/// rendering is not starved.
/// see: http://www.scottlogic.co.uk/blog/colin/2010/06/throttling-silverlight-mouse-events-to-keep-the-ui-responsive/
/// </summary>
public class ThrottledMouseMoveEvent
{
private bool awaitingRender;
private readonly UIElement element;
public ThrottledMouseMoveEvent(UIElement element)
{
this.element = element;
element.MouseMove += this.ElementMouseMove;
}
public event MouseEventHandler ThrottledMouseMove;
private void ElementMouseMove(object sender, MouseEventArgs e)
{
if (!this.awaitingRender)
{
// if we are not awaiting a render as a result of a previously handled event
// raise a ThrottledMouseMove event, and add a Rendering handler so that
// we can determine when this event has been acted upon.
this.OnThrottledMouseMove(e);
this.awaitingRender = true;
CompositionTarget.Rendering += this.CompositionTargetRendering;
}
}
private void CompositionTargetRendering(object sender, EventArgs e)
{
this.awaitingRender = false;
CompositionTarget.Rendering -= this.CompositionTargetRendering;
}
/// <summary>
/// Raises the ThrottledMouseMove event
/// </summary>
protected void OnThrottledMouseMove(MouseEventArgs args)
{
if (this.ThrottledMouseMove != null)
{
this.ThrottledMouseMove(this.element, args);
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -0,0 +1,33 @@
<Window x:Class="InterpolationDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf"
Title="PerformanceDemo" Height="480" Width="640">
<ItemsControl ItemsSource="{Binding PlotModels}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<ItemsControl.Template>
<ControlTemplate>
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True">
<ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsVirtualizing="True" IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<oxy:PlotView Model="{Binding}" Height="200" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>

View File

@@ -0,0 +1,125 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace InterpolationDemo
{
using System.Collections.Generic;
using System.Linq;
using OxyPlot;
using OxyPlot.Series;
using WpfExamples;
using System;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
[Example("Shows different types of interpolation including a custom one.")]
public partial class MainWindow
{
private readonly Random r = new Random(13);
public MainWindow()
{
this.InitializeComponent();
List<DataPoint> points = this.GeneratePoints(50);
this.PlotModels = new List<PlotModel>
{
this.GenerateRandomPlotModel(points, "None", null),
this.GenerateRandomPlotModel(points, "Canonical aka Cardinal",
new Entry("0.5 (default)", InterpolationAlgorithms.CanonicalSpline),
new Entry("0.1", new CanonicalSpline(0.1)),
new Entry("1.0", new CanonicalSpline(1.0))),
this.GenerateRandomPlotModel(points, "CatmullRom",
new Entry("Standard", InterpolationAlgorithms.CatmullRomSpline),
new Entry("Uniform", InterpolationAlgorithms.UniformCatmullRomSpline),
new Entry("Chordal", InterpolationAlgorithms.ChordalCatmullRomSpline))
};
this.DataContext = this;
}
private class Entry
{
public Entry(string title, IInterpolationAlgorithm algorithm)
{
this.Title = title;
this.Algorithm = algorithm;
}
public string Title { get; }
public IInterpolationAlgorithm Algorithm { get; }
}
private List<DataPoint> GeneratePoints(int numberOfPoints)
{
var result = new List<DataPoint>(numberOfPoints);
for (int i = 0; i < numberOfPoints; i++)
{
if (i < 5)
{
result.Add(new DataPoint(i, 0.0));
}
else if (i < 10)
{
result.Add(new DataPoint(i, 1.0));
}
else if (i < 12)
{
result.Add(new DataPoint(i, 0.0));
}
else
{
result.Add(new DataPoint(i, this.r.NextDouble()));
}
}
return result;
}
public List<PlotModel> PlotModels { get; set; }
private PlotModel GenerateRandomPlotModel(List<DataPoint> points, string title, params Entry[] entries)
{
var plotModel = new PlotModel
{
Title = title,
TitleToolTip = title
};
if (entries == null)
{
var lineSeries = new LineSeries();
lineSeries.Points.AddRange(points);
plotModel.Series.Add(lineSeries);
}
else
{
foreach (var entry in entries.Reverse())
{
var lineSeries = new LineSeries
{
Title = entry.Title,
InterpolationAlgorithm = entry.Algorithm,
StrokeThickness = 1.0
};
lineSeries.Points.AddRange(points);
plotModel.Series.Add(lineSeries);
}
}
return plotModel;
}
}
}

View File

@@ -0,0 +1,184 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainViewModel.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace LegendsDemo
{
using System;
using OxyPlot;
using OxyPlot.Series;
using OxyPlot.Legends;
using PropertyTools.DataAnnotations;
using WpfExamples;
using HorizontalAlignment = OxyPlot.HorizontalAlignment;
public class MainViewModel : Observable
{
private HorizontalAlignment legendItemAlignment = HorizontalAlignment.Left;
private LegendItemOrder legendItemOrder;
private LegendOrientation legendOrientation;
private LegendPlacement legendPlacement;
private LegendPosition legendPosition;
private LegendSymbolPlacement legendSymbolPlacement;
private PlotModel model;
private int numberOfSeries = 20;
private double maxHeight = double.NaN;
private double maxWidth = double.NaN;
public MainViewModel()
{
this.PropertiesChanged();
}
[DisplayName("Position"), Category("Legend properties")]
public LegendPosition LegendPosition
{
get { return this.legendPosition; }
set
{
this.SetValue(ref this.legendPosition, value);
this.PropertiesChanged();
}
}
[DisplayName("Placement")]
public LegendPlacement LegendPlacement
{
get { return this.legendPlacement; }
set
{
this.SetValue(ref this.legendPlacement, value);
this.PropertiesChanged();
}
}
[DisplayName("Orientation")]
public LegendOrientation LegendOrientation
{
get { return this.legendOrientation; }
set
{
this.SetValue(ref this.legendOrientation, value);
this.PropertiesChanged();
}
}
[DisplayName("ItemOrder")]
public LegendItemOrder LegendItemOrder
{
get { return this.legendItemOrder; }
set
{
this.SetValue(ref this.legendItemOrder, value);
this.PropertiesChanged();
}
}
[DisplayName("ItemAlignment")]
public HorizontalAlignment LegendItemAlignment
{
get { return this.legendItemAlignment; }
set
{
this.SetValue(ref this.legendItemAlignment, value);
this.PropertiesChanged();
}
}
[DisplayName("SymbolPlacement")]
public LegendSymbolPlacement LegendSymbolPlacement
{
get { return this.legendSymbolPlacement; }
set
{
this.SetValue(ref this.legendSymbolPlacement, value);
this.PropertiesChanged();
}
}
[DisplayName("MaxWidth"), Optional]
public double LegendMaxWidth
{
get { return this.maxWidth; }
set
{
this.SetValue(ref this.maxWidth, value);
this.PropertiesChanged();
}
}
[DisplayName("MaxHeight"), Optional]
public double LegendMaxHeight
{
get { return this.maxHeight; }
set
{
this.SetValue(ref this.maxHeight, value);
this.PropertiesChanged();
}
}
[DisplayName("Curves"), Slidable(1, 32)]
public int NumberOfSeries
{
get { return this.numberOfSeries; }
set
{
this.SetValue(ref this.numberOfSeries, value);
this.PropertiesChanged();
}
}
[Browsable(false)]
public PlotModel Model
{
get { return this.model; }
set
{
this.SetValue(ref this.model, value);
}
}
private void PropertiesChanged()
{
this.Model = this.CreateModel(this.NumberOfSeries);
}
private PlotModel CreateModel(int n)
{
var newModel = new PlotModel
{
Title = "LineSeries"
};
var l = new Legend
{
LegendBorder = OxyColors.Black,
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
LegendPosition = this.LegendPosition,
LegendPlacement = this.LegendPlacement,
LegendOrientation = this.LegendOrientation,
LegendItemOrder = this.LegendItemOrder,
LegendItemAlignment = this.LegendItemAlignment,
LegendSymbolPlacement = this.LegendSymbolPlacement,
LegendMaxWidth = this.LegendMaxWidth,
LegendMaxHeight = this.LegendMaxHeight
};
newModel.Legends.Add(l);
for (int i = 1; i <= n; i++)
{
var s = new LineSeries { Title = "Series " + i };
newModel.Series.Add(s);
for (double x = 0; x < 2 * Math.PI; x += 0.1)
s.Points.Add(new DataPoint(x, Math.Sin(x * i) / i + i));
}
return newModel;
}
}
}

View File

@@ -0,0 +1,11 @@
<Window x:Class="LegendsDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf" xmlns:pt="clr-namespace:PropertyTools.Wpf;assembly=PropertyTools.Wpf"
Title="LegendsDemo" Height="720" Width="1280">
<DockPanel>
<pt:PropertyGrid SelectedObject="{Binding}" DockPanel.Dock="Left" Width="300" TabVisibility="Collapsed" Margin="8"/>
<Grid>
<oxy:PlotView Model="{Binding Model}" Background="White"/>
</Grid>
</DockPanel>
</Window>

View File

@@ -0,0 +1,29 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace LegendsDemo
{
using WpfExamples;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
[Example("Demonstrates legend box capabilities.")]
public partial class MainWindow
{
/// <summary>
/// Initializes a new instance of the <see cref="MainWindow"/> class.
/// </summary>
public MainWindow()
{
this.InitializeComponent();
this.DataContext = new MainViewModel();
}
}
}

View File

@@ -0,0 +1,39 @@
<Window x:Class="MathBlockDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="clr-namespace:OxyPlot.Wpf"
Title="MathBlock demo" Height="480" Width="720">
<Window.Resources>
<Style TargetType="{x:Type oxy:MathBlock}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type oxy:MathBlock}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Canvas x:Name="PART_Canvas"></Canvas>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<GroupBox Header="MathBlock" Margin="8" Padding="8">
<StackPanel>
<oxy:MathBlock FontSize="40" Foreground="DarkRed" Background="Lavender" FontStyle="Italic" FontWeight="ExtraBold" HorizontalAlignment="Left" Padding="40 0 0 0" ToolTip="HorizontalAlignment=Left">E=mc^{2}</oxy:MathBlock>
<oxy:MathBlock FontSize="64" FontFamily="Times New Roman" Background="LemonChiffon" HorizontalAlignment="Right" ToolTip="HorizontalAlignment=Right">x^{2}_{i}</oxy:MathBlock>
<oxy:MathBlock FontSize="36" FontWeight="Bold" Background="LightGreen" HorizontalAlignment="Center" ToolTip="HorizontalAlignment=Center">H_{2}O</oxy:MathBlock>
<oxy:MathBlock FontSize="12" Background="CornflowerBlue" ToolTip="Default HorizontalAlignment (Stretch)">ABC</oxy:MathBlock>
<oxy:MathBlock HorizontalContentAlignment="Center" Background="LightYellow" ToolTip="HorizontalContentAlignment=Center, HorizontalAlignment=Stretch">x_{0}^{2n}</oxy:MathBlock>
<WrapPanel Orientation="Horizontal">
<TextBlock Text="The contents of MathBlock and TextBlock should be aligned: "/>
<oxy:MathBlock Content="x^{2}_{i}"/>
<TextBlock Text=", "/>
<oxy:MathBlock Content="H_{2}O"/>
<TextBlock Text=", "/>
<oxy:MathBlock Content="5^{th}"/>
<TextBlock Text="."/>
</WrapPanel>
</StackPanel>
</GroupBox>
</Window>

View File

@@ -0,0 +1,13 @@
namespace MathBlockDemo
{
using WpfExamples;
[Example(null, "MathBlock control")]
public partial class MainWindow
{
public MainWindow()
{
this.InitializeComponent();
}
}
}

View File

@@ -0,0 +1,164 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MathBlock.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Provides a control for displaying simple math.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace OxyPlot.Wpf
{
using System.Windows;
using System.Windows.Controls;
/// <summary>
/// Provides a control for displaying simple math.
/// </summary>
[TemplatePart(Name = PartCanvas, Type = typeof(Canvas))]
public class MathBlock : ContentControl
{
/// <summary>
/// The canvas template part.
/// </summary>
private const string PartCanvas = "PART_Canvas";
/// <summary>
/// The canvas
/// </summary>
private Canvas canvas;
/// <summary>
/// The render context
/// </summary>
private IRenderContext renderContext;
/// <summary>
/// Initializes static members of the <see cref="MathBlock" /> class.
/// </summary>
static MathBlock()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(MathBlock),
new FrameworkPropertyMetadata(typeof(MathBlock)));
ContentProperty.OverrideMetadata(
typeof(MathBlock),
new FrameworkPropertyMetadata(typeof(MathBlock), (s, e) => ((MathBlock)s).ContentChanged()));
}
/// <summary>
/// Handles changes in the Content property.
/// </summary>
private void ContentChanged()
{
this.UpdateContent();
}
/// <summary>
/// Called to measure a control.
/// </summary>
/// <param name="constraint">The maximum size that the method can return.</param>
/// <returns>The size of the control, up to the maximum specified by <paramref name="constraint" />.</returns>
protected override Size MeasureOverride(Size constraint)
{
if (this.Content == null)
{
return base.MeasureOverride(constraint);
}
var text = this.Content.ToString();
double fontWeight = this.FontWeight.ToOpenTypeWeight();
string fontFamily = null;
if (this.FontFamily != null)
{
fontFamily = this.FontFamily.Source;
}
var size = this.renderContext.MeasureMathText(text, fontFamily, this.FontSize, fontWeight);
return new Size(size.Width + this.Padding.Left + this.Padding.Right, size.Height + this.Padding.Top + this.Padding.Bottom);
}
/// <summary>
/// When overridden in a derived class, is invoked whenever application code or internal processes call <see cref="M:System.Windows.FrameworkElement.ApplyTemplate" />.
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.canvas = this.GetTemplateChild(PartCanvas) as Canvas;
this.renderContext = new CanvasRenderContext(this.canvas);
this.SizeChanged += this.HandleSizeChanged;
}
/// <summary>
/// Handles changes in control size.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="SizeChangedEventArgs" /> instance containing the event data.</param>
private void HandleSizeChanged(object sender, SizeChangedEventArgs e)
{
this.UpdateContent();
}
/// <summary>
/// Updates the content.
/// </summary>
private void UpdateContent()
{
if (this.canvas == null)
{
return;
}
this.canvas.Children.Clear();
if (this.Content == null)
{
return;
}
var text = this.Content.ToString();
var horizontalAlignment = this.HorizontalContentAlignment.ToHorizontalAlignment();
var verticalAlignment = this.VerticalContentAlignment.ToVerticalAlignment();
double fontWeight = this.FontWeight.ToOpenTypeWeight();
double x = this.Padding.Left;
switch (horizontalAlignment)
{
case OxyPlot.HorizontalAlignment.Right:
x = this.ActualWidth - this.Padding.Right;
break;
case OxyPlot.HorizontalAlignment.Center:
x = this.Padding.Left + ((this.ActualWidth - this.Padding.Left - this.Padding.Right) * 0.5);
break;
}
double y = this.Padding.Top;
switch (verticalAlignment)
{
case OxyPlot.VerticalAlignment.Bottom:
y = this.ActualHeight - this.Padding.Bottom;
break;
case OxyPlot.VerticalAlignment.Middle:
y = this.Padding.Top + ((this.ActualWidth - this.Padding.Bottom - this.Padding.Top) * 0.5);
break;
}
var p = new ScreenPoint(x, y);
string fontFamily = null;
if (this.FontFamily != null)
{
fontFamily = this.FontFamily.Source;
}
this.renderContext.DrawMathText(
p,
text,
this.Foreground.ToOxyColor(),
fontFamily,
this.FontSize,
fontWeight,
0,
horizontalAlignment,
verticalAlignment);
}
}
}

View File

@@ -0,0 +1,15 @@
<Window x:Class="MemoryTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MemoryTest="clr-namespace:MemoryTest"
Title="MemoryTest" Height="350" Width="240">
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Margin" Value="8"/>
<EventSetter Event="Click" Handler="OpenWindow_Click"/>
</Style>
</Window.Resources>
<StackPanel>
<Button Content="Test 1" Tag="{x:Type MemoryTest:Window1}"/>
<Button Content="Test 2" Tag="{x:Type MemoryTest:Window2}"/>
</StackPanel>
</Window>

View File

@@ -0,0 +1,36 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace MemoryTest
{
using System;
using System.Windows;
using System.Windows.Controls;
using WpfExamples;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
[Example(null, "Memory test")]
public partial class MainWindow
{
public MainWindow()
{
this.InitializeComponent();
}
private void OpenWindow_Click(object sender, RoutedEventArgs e)
{
var type = ((Button)sender).Tag as Type;
var win = Activator.CreateInstance(type) as Window;
win.Show();
}
}
}

View File

@@ -0,0 +1,8 @@
<Window x:Class="MemoryTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf" Title="Window1" Height="300" Width="300">
<Grid>
<oxy:PlotView Model="{Binding Model}"/>
</Grid>
</Window>

View File

@@ -0,0 +1,43 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Window1.xaml.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Interaction logic for Window1.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace MemoryTest
{
using OxyPlot;
using OxyPlot.Series;
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public PlotModel Model { get; set; }
public Window1()
{
InitializeComponent();
DataContext = this;
Model = new PlotModel { Title = "Test 1" };
Model.Series.Add(new FunctionSeries(Math.Cos, 0, 10, 0.01));
}
}
}

View File

@@ -0,0 +1,21 @@
<Window x:Class="MemoryTest.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf" Title="Window2" Height="480" Width="640">
<Grid>
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Plots}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<oxy:PlotView Model="{Binding}" Height="300"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</Window>

Some files were not shown because too many files have changed in this diff Show More