VS2017 で Xamarin.Forms + OxyPlot【再掲】

(こちらの記事は以前書いたものを大幅に修正しております。また、本記事は2017/11/20時点での情報ですのでご了承ください。)



最終的にはCocosSharpの加速度センサの値をリアルタイムでグラフにしたいのですが、OxyPlotを使うのが初めてなので、まずはOxyPlotのサイトの「Getting Started」の通りにやってみることにしました↓


  1. Create the project
    Cross Platform Appを選択します。
    新しいプロジェクトを作ります。

    Blank App、PCLを選択します。
    Blank App、PCLを選択します。

  2. Update and add references
    Tools>NuGet Package Manager>Manage NuGet Pakages for Solution…でNuGetを起動します。
    NuGetを起動します。

    NuGetでOxyPlot.Xamarin.Formsを探し出し、インストールします。
    ここ注意。ソリューションにUWPプロジェクトを含む場合は「include prerelease」チェックボックスをONにし、プレリリース版「v1.1.0-unstable0011」をインストールしましょう。安定版の「v1.0.0」はUWPにバグがあってうまく動かないんですよ…AndroidとiOSだけなら「v1.0.0」で大丈夫なんですけどね。
    プレビュー版でも良かですか?

    ソリューション全体にインストールします。
    インストール先をチェックしますよ

    インストールできたようです。
    インストール完了!

  3. Initialize renderers
    各プラットフォームのプロジェクト内でOxyPlot rendererを初期化します。「Xamarin.Forms.Forms.Init()」を探し、その次の行に以下のコードを入れて下さい。

    Android:MainActivity.cs
     OxyPlot.Xamarin.Forms.Platform.Android.PlotViewRenderer.Init();

    iOS:AppDelegate.cs
     OxyPlot.Xamarin.Forms.Platform.iOS.PlotViewRenderer.Init();

    UWP:App.xaml.cs
     OxyPlot.Xamarin.Forms.Platform.UWP.PlotViewRenderer.Init();

  4. Add the PlotView to a page
    ページにPlotViewを追加します。コードビハインドで追加する場合は以下の1.in code、XAMLで追加する場合は2.XAMLをご覧ください。VerticalOptionsとHorizo​​ntalOptionsを設定しないと、PlotViewの幅と高さが0になってしまうらしいので注意。なんのこっちゃ(ここら辺のお話は後で詳しく書きたいと思います…)?!

    1. in code
      省略w

    2. XAML
      MainPage.xamlにOxyPlotの名前空間宣言を追加し、PlotViewを配置します。名前空間宣言って何よ?という方はこちらの記事「そもそもXAMLって何よ?」をご覧ください。

      コントロールとデータを結びつけることを「バインド」といいます。9行目でバインド先/バインド元の指定、12~14行目でバインド先のコントロールのBindingContextプロパティにソースとなるオブジェクトを設定しています。

      次に、バインドするPlotModel(上のXamlの13行目に書いたLineChartクラス)を作ります。
      Solution ExplorerでPCLプロジェクトを右クリック>Add>New Item…を選択します。
      新しいアイテムを追加します。

      折れ線グラフのデータのクラスを作ってみることにします。
      新しいクラスを作ります。



      これでコーディングは完成です。実行するとこんな感じ↓
      左からAndroid/iOSシミュレータ/UWP(Windows10 PC)です。
      実行するとこんな感じ


  • VerticalOptionsとHorizo​​ntalOptions、WidthRequestとHeightRequestのお話

    OxyPlotのPlotViewやXamarinのImage/BoxView/Label等々のコントロールはXamarin.Forms.Viewを継承しているので、HorizontalOptions/VerticalOptionsのデフォルト値はLayoutOptions.Fillです。なので、HorizontalOptions/VerticalOptionsを指定しなかった場合はFill = 領域いっぱいに表示されます。

    また、WidthRequestを発動させたいときはHorizontalOptionsを指定しましょう。同じくHeightRequestで高さを指定したい場合はVerticalOptionsの指定が必須です。

    そして、配置されている親要素のパラメータも考慮しなければなりません。例えばStackLayoutの場合、StackLayout自身のHorizontalOptions/VerticalOptionsに加えOrientationというパラメータもあり、結構フクザツです。

    要するにまとめますと、コントロールのサイズを期待通りに表示させるには、親要素の制約などをクリアする+各プラットフォームのレイアウトのライフサイクルを正しく理解する=うわ面倒臭ぇ難しい('A`)ウヘァ…ということで、Gridで幅を調整しておいてその中に子要素を配置するのが分かりやすいと思います。

    よく使いそうな折れ線グラフ、円グラフ、棒グラフやBoxViewなどをStackLayout(1ページ目:画像左)とGrid(2ページ目:画像右)に置いて色んなパラメータで表示してみました。ソースを置いておきますのでよろしければご自由にお使い下さい。

    Github : https://github.com/oishiikurigohan/OxyPlotTest

    GithubのソースをAndroidで実行するとこんな感じ


  • OxyPlot気になったところ

    実践ではあまりないパターンかも知れませんがちょっと気づいたのでメモ。
    OxyPlotのPlotViewは、親要素無しで直置きするとプラットフォームによって動作が異なりました。
    Android:画面いっぱいにグラフが表示される
    iOS:画面いっぱいにグラフが表示される
    UWP:画面いっぱいにグラフが表示される


    Android:画面いっぱいにグラフが表示される
    iOS:表示されない
    UWP:表示されない


  • 参考サイト様

    いつもお世話になっております。
    Xamarin.Forms で画像のサイズを指定するには(本家田淵様)
    Xamarin.Forms の StackLayout を活用するには(同上)
    Understanding WidthRequest(stackoverflow)
    Plot doesn't display until Window resize on Xamarin.Forms UWP #34(oxyplot - Xamarin Issues)


…ということで、なんとなくOxyPlotの使い方が分かりました。次回「VS2017 で Xamarin.Forms + CocosSharp -part5 加速度を取得しOxyPlotでグラフにする-」で、CocosSharpの加速度センサの値をリアルタイムでOxyPlotのグラフにしてみたいと思います。

この記事へのコメント