OxyPlot を使い WPF アプリケーションでグラフを表示する。

背景

Microsoft Visual C# 2010 Express Edition を使って Windows アプリケーションの開発を行っています。

C# を使って Windows アプリケーションを開発する場合、大きく分けて以下2つの選択肢があります。

  • Windows フォームアプリケーション
  • WPF アプリケーション(Windows Presentation Foundation アプリケーション)

今回は後者の WPF で Windows アプリケーションの開発を行っています。

Windows フォームには Chart コントロールというものが存在し、これを使うことで簡単にグラフが描けます。

しかし、WPF には Chart コントロールが無く、外部のライブラリを利用する必要があるということがわかってきました。

今回描きたいグラフは線グラフです。以下の要件を満たしてくれれば良いという程度のものです。

  • 目盛り表示がある。
  • 1つのグラフに複数の線が描ける。
  • 線の色が指定できる。
  • 横軸の目盛りに日付(DateTime 型)が使える。
  • 縦軸の目盛りは線型で良い。

加えて無料であることもポイントになります。

グラフ描画ライブラリに何を利用するか?

インターネット上で情報を収集してよく見かけるのが以下のライブラリです。

しかし、重要な Chart Controls の機能は Stable ではなく Preview となったまま開発が 2010 年 の 2 月で止まっているように見えます。

他に無いかと探して見つけたのが以下のライブラリです。

最終バージョンが 2014 年の 1 月と比較的新しく、WPF Toolkit よりは信頼に足ると判断しました。

ライセンスは MIT License で無料で比較的自由に使えます。

線グラフしか試していませんが、棒グラフ・円グラフにも対応しているように見えます。

OxyPlot を利用する準備

Visual Studio の Professional Edition で開発を行っている人は NuGet を使ってインストールできるようですが、 Express Edition を使っている人は以下の操作を手動で行いましょう。

  1. OxyPlot のバイナリーをダウンロードする。
    1. CodePlex のページからダウンロードする。
  2. OxyPlot.dll と OxyPlot.Wpf.dll をプロジェクトに参照として追加する。

準備はこれだけです。

サンプル紹介

線グラフを表示する簡単なサンプルを紹介します。

以下、関連するコードです。

MainWindow.xaml

<Window x:Class="OxyPlotExample1.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="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <oxy:PlotView>
        <oxy:PlotView.Series>
            <oxy:LineSeries oxy:Name="line1" />
        </oxy:PlotView.Series>
    </oxy:PlotView>
</Window>

名前空間 oxy として OxyPlot.Wpf アセンブリを組み込んでいます。

oxy:PlotView はグラフを描画するビューです。

oxy:PlotView.Series にグラフに表示する要素(今回は線を引くために LineSeries というのを使っている)を追加します。複数の線を引きたい場合はその数だけ追加しましょう。

標準では XY 座標ともに線形のグラフ表示となります。

MainWindow.xaml.cs

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.Navigation;
using System.Windows.Shapes;

using OxyPlot;

namespace OxyPlotExample1
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            IList<DataPoint> data = new List<DataPoint>
            {
                new DataPoint(0, 1),
                new DataPoint(1, 5),
                new DataPoint(2, 3),
            };
            line1.ItemsSource = data;
        }
    }
}

DataPoint クラスは OxyPlot 標準の座標を表すデータクラスです。

oxy:LineSeries の ItemsSource プロパティにリストとして渡すことでグラフを描画できます。

備考

今回は Loaded イベントで ItemsSource プロパティに値を設定していますが、xaml 上で ItemsSource にデータをバインドすることもできます。

また、DataPoint クラスではなく独自のデータクラスを利用することもできます。その場合は oxy:LineSeries の DataFieldX, DataFieldY プロパティに X, Y 座標値となるデータクラスのプロパティ名を指定します。

例えば以下のような感じです。

// MainWindow.xaml.cs
// ...
public class ExampleData {
    // ...
    public double XPoint { get; set; }
    public double YPoint { get; set; }
}

<!-- MainWindow.xaml -->
    <oxy:PlotView>
        <oxy:PlotView.Series>
            <oxy:LineSeries oxy:Name="line1" DataFieldX="XPoint" DataFieldY="YPoint" />
        </oxy:PlotView.Series>
    </oxy:PlotView>

また、X と Y の座標系を変更することもできます。例えば今回は横軸の目盛りに日付(DateTime 型)にしたいのですが、その場合はデータクラスのプロパティを DateTime にした上で横軸の目盛りに DateTimeAxes というのを指定します。

例えば以下のような感じです。

// MainWindow.xaml.cs
// ...
public class ExampleData {
    // ...
    public DateTime XPoint { get; set; }
    public double YPoint { get; set; }
}

<!-- MainWindow.xaml -->
    <oxy:PlotView>
            <oxy:PlotView.Axes>
                <oxy:DateTimeAxis Position="Bottom" />
            </oxy:PlotView.Axes>
            <oxy:PlotView.Series>
            <oxy:LineSeries oxy:Name="line1" DataFieldX="XPoint" DataFieldY="YPoint" />
        </oxy:PlotView.Series>
    </oxy:PlotView>

後はドキュメント読みましょう!!!