WPFのChart作成ライブラリーOxyPlotの使い方

WPFでChartグラフを表示するためのライブラリーに OxyPlot があります。その使い方について書いておきたいと思います。

OxyPlot のダウンロード

OxyPlot は NuGetで OxyPlot.WPF を検索してインストールすれば使えるようになりますが、使い方がよくわからない人が多いのではないでしょうか。
一応ドキュメントが下記にあります。

Welcome to OxyPlot’s documentation! — OxyPlot 2015.1 documentation

手っ取り早いのはソースコード一式を取得し、その中のサンプルソフトを見ることです。
下記からソースコードを一式ダウンロードしましょう。

github.com

Source フォルダーの中に OxyPlot.WPF.sln があるので Visual Studio で開きます。

f:id:feynman911:20190304215520j:plain

この中の ExampleBrowser と WpfExamples が参考になります。

ExampleBrowser

ExampleBrowserを実行すると、下記のようなアプリが起動し左側のリストを選択するとその使用サンプルが右側に表示されます。右側には Plot と Code のタブがあり、Plot が表示結果、Code がそれを表示する時の使い方になります。どんなことができるのかを、要素ごとにこれで確認し、使いたいものの Code を確認して真似をするという事ができます。

f:id:feynman911:20190304222654j:plain

Code タブを選ぶとコードが表示されます。

f:id:feynman911:20190304222718j:plain

WpfExamples

WpfExamplesを起動すると、もう少し高度なアプリケーションレベルのサンプルを見ることができます。これも同じで、とにかくサンプルを見て、自分がやりたい事に近いものを探して真似をするという事ができます。

f:id:feynman911:20190304223321j:plain

例えば、 AnimationDemo を起動すると下記のようなウインドウが開きます。パラメータを変えて Animate ボタンを押すと Chart のアニメーションが見れます。
気に入ったら、どうやったら同じことができるのかをコードを見ながら真似をします。

f:id:feynman911:20190304223343j:plain

バインドの方法

バインドのやり方としては2通りがあります。
一つは PlotView というコントロールをView に貼り付けて、その Model というプロパティーを ViewModel とバインドします。画面内の表示エリアのみを指定して、あとはすべて ViewModel からコードでコントロールする方法です。
もう一つは、Plot というコントロールを View に貼り付けて、表示するデータのみをバインドする方法です。Chart の見た目は XAML 側で作りこみます。

バインド用ラインデータの準備

表示で使用するxyデータの点のリストを2個 ViewModel で作成しておきます。

        //表示用のラインデータを2本作成
        public void MakeLineData()
        {
            var points1 = new List<DataPoint>();
            for (int i = 0; i < dataNumber; i++)
            {
                points1.Add(new DataPoint((double)i, amplitude 
                   * Math.Sin(2.0 * Math.PI * i / frequency)));
            }
            DataPoints1 = points1;

            var points2 = new List<DataPoint>();
            for (int i = 0; i < dataNumber; i++)
            {
                points2.Add(new DataPoint((double)i, amplitude 
                  / 2 * Math.Sin(2.0 * Math.PI * i * 2 / frequency)));
            }
            DataPoints2 = points2;
        }

        //1本目のラインデータ
        private List<DataPoint> dataPoints1;
        public List<DataPoint> DataPoints1
        {
            get { return dataPoints1; }
            set { SetProperty(ref dataPoints1, value); }
        }

        //2本目のラインデータ
        private List<DataPoint> dataPoints2;
        public List<DataPoint> DataPoints2
        {
            get { return dataPoints2; }
            set { SetProperty(ref dataPoints2, value); }
        }

Blend で Chart 作成する方法 (Plot)

Blend で View を開きます。OxyPlot のコントロールである Plot を 貼り付けます。

f:id:feynman911:20190307214957j:plain

Plot のプロパティ(その他の指定)には Chart の詳細を作るための項目があります。

f:id:feynman911:20190307215015j:plain

まずはX軸とY軸を作りましょう。Axes の 四角...をクリックすると次のような Axis コレクションエディターが開くので、追加の左側のドロップダウンリストから その他を選択すると、オブジェクトの選択ダイアログが開くので、使いたい軸を選択してOKを押すとドロップダウンリストに表示されるので 追加 を押してコレクションに追加します。

f:id:feynman911:20190307215032j:plain

X軸Y軸用に LinearAxis を2軸追加しておきます。
この2軸がX軸なのかY軸なのかを決めるのは、軸のプロパティの Position になります。1軸目を Bottom 2軸目を Left にします。

f:id:feynman911:20190307215045j:plain

プロパティには目盛りの表示の仕方とか色々とあるので、デフォルトから変更してみると面白いと思います。

表示するデータは、Plot のプロパティ Series にバインドします。
先ほどの軸の追加と同じ用に、Series の右の 四角...をクリックしてダイアログを開き、同様に追加の左のドロップダウンリストで<その他の型>から LineSeries を選択して追加します。ViewModelに2本分データを作成したので2本追加してください。
ItemSource に ViewModel の DataPoints1 と DataPoint2 にバインドします。

f:id:feynman911:20190307215123j:plain

Legendを表示したり、いろいろと可能ですので、これも遊んでみると面白いです。

ViewModel から Chart を作成する方法 (PlotView)

View に Chart を表示するエリアだけ指定して、Chart の作成は ViewModel 側で行う方法です。
View には、OxyPlot のコントロールである PlotView を貼り付けます。
ViewModel には PlotView とバインドするためのオブジェクトを作り、Chart の詳細をコードで作成します。

        public MainWindowViewModel()
        {
            MakeLineData();
            MakeChart();
        }

        private PlotModel pModel = new PlotModel();
        public PlotModel PModel
        {
            get { return pModel; }
            set { SetProperty(ref pModel, value); }
        }

        public void MakeChart()
        {
            PModel.Title = "Line Series (PlotView & Code)";

            var series1 = new LineSeries
            {
                Title = "line1",
                ItemsSource = DataPoints1,
                DataFieldX = "X",
                DataFieldY = "Y",
                Color = OxyColor.Parse("#4CAF50"),
                MarkerSize = 1,
                MarkerFill = OxyColor.Parse("#F55FFFFF"),
                MarkerStroke = OxyColor.Parse("#4CAF50"),
                MarkerStrokeThickness = 1.5,
                MarkerType = MarkerType.Cross,
                StrokeThickness = 1,
            };
            PModel.Series.Add(series1);

            var series2 = new LineSeries
            {
                Title = "line2",
                ItemsSource = DataPoints2,
                DataFieldX = "X",
                DataFieldY = "Y",
                Color = OxyColor.Parse("#FF0000"),
                MarkerSize = 1,
                MarkerFill = OxyColor.Parse("#00FFFFFF"),
                MarkerStroke = OxyColor.Parse("#FF0000"),
                MarkerStrokeThickness = 0.0,
                MarkerType = MarkerType.Cross,
                StrokeThickness = 1,
            };
            PModel.Series.Add(series2);
        }


PlotView のモデルから、ViewModel の PModel にバインドします。

f:id:feynman911:20190307222219j:plain


実行すると、次のような Chart を表示する事ができます。

f:id:feynman911:20190307224032j:plain


作成したソースコードを下記に置いておきます。

github.com

参考

  • View から ViewModel にBlendのダイアログで選択してバインドするためには、View のデザイン時の DataContext にViewModel が設定されていることが必要です。

(メニューの [形式]-[デザイン時のDataContextの設定] から設定できます)