初心者が悩んだOxyPlotによるLineSeriesの描画とWPFコントロールのStyleの継承
インフルエンザや風邪は、まだまだ流行っているようです。皆さんもお気をつけてください。
さて、XYデータでX軸の重複チェックが出来るようになると、Chartを描いてみたくなる。
IoTも見こして、将来的にはセンサデータなどのリアルタイムプロットもやりたいので、多点プロットでも問題のなさそうなChartコントロールを使いたいところ。
その点で、WPF ToolkitのChartコントロールは消えるので、マルチプラットフォームに対応したものがないかNuGetで探すと、3つほどよさそうなものが見つかった。
- OxyPlot.Wpf
- NuGet: OxyPlot.Wpf
- OxyPlot.org
- Silverlightデモ
- ずーっとunstableですが活発にメンテナンスされていて人気も高そう
- コレクションを更新したら自動で再描画とかはないが、ReactivePropertyを使うなら更新は問題にはならない
- Sparrow.Chart.Wpf
- Eternal.DataVisualization.WPF
まず、OxyPlotを試してみたが、Styleの継承のせいで、表示が上手くいかず何日か悩んだので、今回はそのネタ。
「百聞は一見にしかず」
ということで、画面を公開・・・
デモを見るとデフォルトでかなり見栄えが良いのだが、
- 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>
取りあえず打ち消すと・・・
きれいに揃った!!
「ElementHostを使ったWindows Formとの相互運用の時は、Styleの継承のおかげでDPIやフォントなどの調整を自動でやってくれるのが楽できたが、今回はStyle設定のスコープを考える上でも、良い意味で勉強になった」