読者です 読者をやめる 読者になる 読者になる

tmori3y2のブログ

主にWindowsのプログラムなど

初心者が悩んだOxyPlotによるLineSeriesの描画とWPFコントロールのStyleの継承

C# MVVM WPF Chart

インフルエンザや風邪は、まだまだ流行っているようです。皆さんもお気をつけてください。

tmori3y2.hatenablog.com

さて、XYデータでX軸の重複チェックが出来るようになると、Chartを描いてみたくなる。

IoTも見こして、将来的にはセンサデータなどのリアルタイムプロットもやりたいので、多点プロットでも問題のなさそうなChartコントロールを使いたいところ。

その点で、WPF ToolkitのChartコントロールは消えるので、マルチプラットフォームに対応したものがないかNuGetで探すと、3つほどよさそうなものが見つかった。

まず、OxyPlotを試してみたが、Styleの継承のせいで、表示が上手くいかず何日か悩んだので、今回はそのネタ。

「百聞は一見にしかず」

ということで、画面を公開・・・

f:id:tmori3y2:20160310235621p:plain

デモを見るとデフォルトでかなり見栄えが良いのだが、

  • Y軸の目盛のラベルが上から下に行くにつれて右にずれている
  • X軸の目盛のラベルが右にずれている

コードは軸設定と空のLineSeriesで、こんな感じ・・・

<Grid HorizontalAlignment="Left">
    <oxy:PlotView Model="{Binding MotorSpeedChart.Model}" Width="500" Height="300"/>
</Grid>
public MyPlotViewModel MotorSpeedChart { get; private set; }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using OxyPlot;
using OxyPlot.Annotations;
using OxyPlot.Axes;
using OxyPlot.Series;

using MyCollectionControls.Models;

namespace MyCollectionControls.ViewModels
{
    public class MyPlotViewModel
    {
        public PlotModel Model { get; private set; }
        public LinearAxis AxisX { get; private set; }
        public LinearAxis AxisY { get; private set; }
        public LineSeries Data { get; private set; }

        public MyPlotViewModel()
        {
            Model = new PlotModel()
            {
                Title = "Motor Speed Chart"
            };

            AxisX = new LinearAxis()
            {
                Title = "Time",
                Unit = "minutes",
                Position = AxisPosition.Bottom,
                TickStyle = TickStyle.Inside,
                AbsoluteMinimum = 0.00,
                Maximum = 100.00,
                StringFormat = "0.00",
            };
            Model.Axes.Add(AxisX);

            AxisY = new LinearAxis()
            {
                Title = "Motor Speed",
                Unit = "rpm",
                Position = AxisPosition.Left,
                TickStyle = TickStyle.Inside,
                AbsoluteMinimum = 0,
                Maximum = 1000,
                StringFormat = "0",
            };
            Model.Axes.Add(AxisY);

            Data = new LineSeries()
            {
                Title = "Motor A"
            };
            Model.Series.Add(Data);
        }
    }
}

デモのコードとかと比べてもズレる理由が分からず唸っていたが、ハタとTextBlockとTextBoxのコントロールの見栄えを揃えるために、UserControlレベルでTextBlockのStyleを定義していたのを思い出す。

<Grid HorizontalAlignment="Left">
    <Grid.Resources>
        <Style TargetType="TextBlock" />
    </Grid.Resources>
    <oxy:PlotView Model="{Binding MotorSpeedChart.Model}" Width="500" Height="300"/>
</Grid>

取りあえず打ち消すと・・・

f:id:tmori3y2:20160311000827p:plain

きれいに揃った!!

「ElementHostを使ったWindows Formとの相互運用の時は、Styleの継承のおかげでDPIやフォントなどの調整を自動でやってくれるのが楽できたが、今回はStyle設定のスコープを考える上でも、良い意味で勉強になった」