【WPF】ScottPlot 4.1でY2軸に対応した複合グラフのユーザーコントロールを作る!

当ページのリンクには広告が含まれています。

ScottPlotが Ver4.1 になって、グラフの左右にY軸(つまりY軸が2個)が表示できるようになりました。

今回は、以前公開した「【WPF】C#+ScottPlotで複合グラフのユーザーコントロールを作る!」のソースコードを ScottPlot 4.1 に対応させ、ついでにY2軸が使えるように修正しましたので、紹介したいと思います。

目次

複合グラフの表示例

このユーザーコントロールを使うと、次のようなY2軸の複合グラフが表示できます。

赤い線がY2軸のスケール(0~2250)で表示され、それ以外はY1軸のスケール(0~200)で表示されています。

ユーザーコントロールの使い方

では、ユーザーコントロールの使い方は、各グラフ(折線、棒)ごとに左右どちらのY軸を使うかが指定できるようになった以外は前回の記事と全く同じです。

メソッド

メソッドは下記の2つのみです。

メソッド名引数の説明内容
void Clear()グラフの消去
void Draw(string title)title:グラフのタイトルグラフの描画

プロパティ一覧

プロパティは以下の通りです。

前回との違いは、Yの1,2軸を指定するための YAxisNo と、Y2軸のタイトルを設定する YAxis2Title が追加されています。

string[] LabelsnullX軸に表示するラベル
List<string[]> YValuesnullY軸のデータ
string[] Colorsnull棒グラフ、折れ線グラフの色
int BarStyleDataNonullListに登録されたYValuesにおいて、棒グラフとして表示させたいList上の番号
bool ShowValuesfalsetrue にすると棒グラフに値を表示
bool ShowLegendtruetrueにすると凡例を表示
string[] Legendsfalse凡例として表示する各データのタイトル(YValuesに登録した数だけ用意)
string XAxisTitlenullX軸のタイトル
string YAxisTitlenullY軸のタイトル
int[] YAxisNonullY軸の指定
YValuesの登録順に0か1を配列で指定(0:左のY軸、1:右のY軸)
例えば、3個のグラフを描画する際、1つ目のY2軸に表示するには
new int[]{1,0,0} 

使い方とサンプルソース

呼び出し手順は次の通りです。

  1. LabelsにX軸に表示したいラベルを登録、YValuesにはY軸に表示したいデータを指定します。
  2. Y軸に表示したいデータの中で、棒グラフとして描画したいものについて、その番号をBarStyleDataNoプロパティに指定します。
  3. Y軸に表示したいデータの中で、Y1軸(左)に表示したいものは、0を、Y2軸(右)に表示したいものは1 を YAxisNo に指定します。
  4. 最後に、Draw プロパティを呼び出せば、複合グラフが表示されます。

Drawプロパティにはグラフのタイトルを指定します。

尚、YValues に折れ線の値を Add メソッドで追加していく仕様なので、最初にClear メソッドを呼んで Listの中身をクリアしていて下さい。

クリアを忘れると、同じ処理を実行する度に前回にAddしたYValuse の内容も合わせて表示されるため、グラフが線だらけになります。

uxLineBarChart.Clear();

uxLineBarChart.ShowValues = true;
uxLineBarChart.Labels = new string[] { "2019年", "2020年", "2021年", "2022年", "2023年" };
uxLineBarChart.Legends = new string[] { "予測台数", "実績台数", "顧客数", "在庫数" };
uxLineBarChart.YValues.Add(new double[] { 100, 100, 200, 50, 50 });
uxLineBarChart.YValues.Add(new double[] { 110, 150, 120, 150, 130 });
uxLineBarChart.YValues.Add(new double[] { 120, 140, 160, 120, 140 });
uxLineBarChart.YValues.Add(new double[] { 2000, 1000,1600, 2200, 1800 });
uxLineBarChart.YAxisNo = new int[] { 0,0,0,1 };
//uxLineBarChart.Colors = new string[] { "orange","red","gray","pink","magenta"};
uxLineBarChart.BarStyleDataNo = 0;
uxLineBarChart.XAxisTitle = "年度";
uxLineBarChart.YAxisTitle = "台数";
uxLineBarChart.YAxis2Title = "在庫数";

uxLineBarChart.Draw("折れ線と棒グラフ");

ユーザーコントロールの解説

事前準備

あらかじめ NuGet を使って、 ScottPlot.WPF をインストールしておいてください。

ScottPlotのインストールについて詳しい情報を知りたい方は、「 【wpf】いちばんやさしいscottplot-の使い方(windowsform共通) 」の記事をご覧ください。

また、ユーザーコントロールの作り方が知りたい方は、「【WPF】一番やさしいユーザーコントロールの作り方・使い方」の記事をご覧ください。

レイアウトの作成

【WPF】C#+ScottPlotで複合グラフのユーザーコントロールを作る」と全く同じです。

というか、前回のソースを修正しただけなので、プロジェクト名は WpfLineBarChartTest ユーザーコントロール名は ScottLineBarChartControl になっています。

ちなみに、ユーザーコントロールにScottPlotを張り付けると、下記の様になります。

XAMLのソースコード

以下がXAMLのソースコードです。

単に最新版のScottPlot を張り付け直しただけなので手を加えていません。

前回と全く同じです。

<UserControl x:Class="WpfLineBarChartTest.ScottLineBarChartControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfLineBarChartTest"
             mc:Ignorable="d" 
             d:DesignHeight="400" d:DesignWidth="400">
    <Grid>
        <WpfPlot x:Name="uxScottPlot"/>

    </Grid>
</UserControl>

C#のソースコード

以下がC#側のソースコードになります。

using ScottPlot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;

namespace WpfPiChartTest
{
    /// <summary>
    /// ScottLineBarChartControl.xaml の相互作用ロジック
    /// </summary>
    public partial class ScottLineBarChartControl : UserControl
    {
        public string[] Labels { get; set; }                                //X軸のラベル(省略すると0から始まる連番)
        public List<double[]> YValues { get; set; } = new List<double[]>(); //Y軸のデータ
        public string[] Colors { get; set; }                                //棒グラフ、折れ線グラフの色
        public int? BarStyleDataNo { get; set; }                            //縦棒のグラフとして表示したいデータの番号
        public bool ShowValues { get; set; } = false;                       //棒グラフに値を表示
        public bool ShowLegend { get; set; } = true;                        //凡例の表示
        public string[] Legends { get; set; }                               //凡例の表示 
        public string XAxisTitle { get; set; }                              //X軸のタイトル
        public string YAxisTitle { get; set; }                              //Y軸のタイトル
        public string YAxis2Title { get; set; }                             //Y2軸のタイトル
        public int[] YAxisNo { get; set; }                                  //Y軸の指定


        //コンストラクタ
        public ScottLineBarChartControl()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 描画処理
        /// </summary>
        /// <param name="title"></param>
        public void Draw(string title)
        {
            //描画エリアのクリア
            uxScottPlot.Plot.Clear();
            //グラフタイトルの表示
            uxScottPlot.Plot.Title(title);
            //線の色が指定されていた場合、配列に格納
            var colors = Colors?.Select(i => System.Drawing.Color.FromName(i)).ToArray();
            //X軸様に0から始まる連番を作成
            double[] xvalue = DataGen.Consecutive(YValues[0].Length);

            //X軸に表示するラベルを取得
            string[] labels = Labels ?? xvalue.Select(i => i.ToString()).ToArray();

            //描画データを取り出してグラフを作成
            for (int no = 0; no < YValues.Count; no++)
            {
                //棒又は線の色を取得
                System.Drawing.Color? color = null;
                if (Colors != null) color = colors[no];

                //凡例を取得
                var legend = (Legends == null) ? null : Legends[no];

                //棒グラフ対象のデータであれば棒グラフを、そうでなければ折れ線グラフを作成
                if (BarStyleDataNo == no)
                {
                    //棒グラフの作成
                    var bar = uxScottPlot.Plot.AddBar(YValues[no], xvalue);
                    bar.Label = legend;
                    bar.ShowValuesAboveBars = ShowValues;
                    if (color != null) bar.FillColor = color ?? System.Drawing.Color.Empty;
                    if (YAxisNo != null) bar.YAxisIndex = YAxisNo[no];
                }
                else
                {
                    //折れ線グラフの作成
                    var scat = uxScottPlot.Plot.AddScatter(xvalue, YValues[no], lineWidth: 2, markerSize: 10, lineStyle: LineStyle.Solid, color: color, label: legend);
                    if (YAxisNo != null)  scat.YAxisIndex = YAxisNo[no];
                }
            }

            //X軸に表示するラベルを設定
            uxScottPlot.Plot.XTicks(labels);
            //グリッド線の表示
            uxScottPlot.Plot.Grid(true);
            //フレーム(外枠)の表示
            //uxScottPlot.Plot.Frameless(false);
            //凡例の表示
            if (ShowLegend) uxScottPlot.Plot.Legend(true);
            //X軸のタイトルを設定
            uxScottPlot.Plot.XLabel(XAxisTitle);
            //Y軸のタイトルを設定
            uxScottPlot.Plot.YLabel(YAxisTitle);
            //軸の指定があれば、Y2軸番号を表示
            uxScottPlot.Plot.YAxis2.Ticks(YAxisNo != null ? true : false);
            //Y2軸のタイトルを表示
            uxScottPlot.Plot.YAxis2.Label(YAxis2Title);

            //グラフを描画
            uxScottPlot.Render();
        }

        /// <summary>
        /// グラフ表示エリアとデータのクリア
        /// </summary>
        public void Clear()
        {
            uxScottPlot.Plot.Clear();
            YValues.Clear();
        }
    }
}

今回は「【WPF】C#+ScottPlotで複合グラフのユーザーコントロールを作る!」のソースコード をScottPlot 4.1で動くように修正しているだけなので、詳細については上記の記事をご覧ください。

また、旧バージョンから移行を考えている方は、下記の記事に詳細を載せていますのでご一読ください。

まとめ

フリーのチャートライブラリ ScottPlot が 2021年7月に 大幅なバージョンアップが行われ、Y2軸対応になりました。

今回は、以前公開した「複合グラフのユーザーコントロール」をScottPlotに対応させ、更にY2軸が使えるように修正致しました。

とはいえ、このユーザーコントロールはシンプルな構成であり、皆さんが実際に使うには機能が不足していると思います。

あくまでも参考情報としての位置づけですが、皆様のプログラミングの一助になれば幸いです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメント一覧 (2件)

  • お世話になります。
    Y2軸の最大値設定は、ScottPlot Ver4.1では出来ないですよね?
    よろしくお願いします。

    • 最大値設定とは、y軸の上限のことでしょうか?
      であれば、SetAxisLimitsメソッドで軸のインデックスを指定することで、上限下限の設定が可能です。
      例:uxScottPlot.Plot.SetAxisLimits(yMin: -200, yMax: 200, yAxisIndex: 1);

コメントする

目次