LoginSignup
0
1

VisualStudio2019でLiveCharts2を使う

Posted at

概要

2023/06/21 初稿時点でLiveCharts2は8.00のベータ版です。新機能が随時追加されています。

本記事はLiveCharts2を.NetFrameworkで使うための導入と、その際につまずいた点を纏めたものです。
内容は以下の通り。

項番 タイトル(リンクが上手く動作できず、飛べません)
1 PC環境
2 LiveCharts2のサイトとGithub
3 LiveCharts2の対象フレームワーク
4 プロジェクト作成とパッケージのインストール
5 グラフを作ってみよう
6 Githubに公開されているプロジェクトについて
7 グラフラベルの日本語化)
8 おわりに

PC環境

  • Windows10 Pro 22H2
  • VisualStudio 2019 16.11.23 (Professional)
    VisualStudioには下記画像のチェックがついた2つがインストールされていれば良いでしょう。
    image.png

LiveCharts2の各サイト

  • Github
    "Livecharts2/samples/ViewModelSamples"にViewModelのコードが、"Livecharts2/samples/ViewModelSamples"にViewのサンプルが入っています。ViewModel、Viewが何か分からない方はこちらを参照。

  • LiveCharts2_API
    APIが公開されています。私は見方が分からないのであまり参考になっていませんが、見たい方はどうぞ。

  • LiveCharts2_インストールやサンプルコードなど
    インストール手順などはこちらのサイトを参照しました。また、どのような種類のグラフが作成できるかを概観できるため、自分が作りたいグラフについての記事は一度目を通した方が良いと思います。サンプルコードも載っています。

LiveCharts2の対象フレームワーク

VisualStudioで扱えるフレームワークの内、.NET5.0以上, .NET Core3.1以上, .NET Framework462以上で使えます。
参考
image.png

プロジェクト作成とパッケージのインストール

VisualStudio 2019のインストールは他記事を参照してください。

プロジェクト作成

VisualStudioを起動して、「新しいプロジェクトの作成」をクリックします。
image.png
次に、「Windows フォーム アプリケーション(.NET Framework)」を選択します。
下記のように検索ワードを設定すると見つけやすいかと思います。

  • 言語 = C#
  • プラットフォーム = Windows
  • プロジェクトの種類 = デスクトップ

ない場合は、VisualStudio Installerから必要なパッケージをインストールしてください。
image.png
 構成について、名前や場所は自由にしてください。フレームワークを.NET Framework 4.7.2として、作成します。
image.png

完了です。初期表示は以下のようになります。
image.png

LiveCharts2のインストール

 VSのタブより「ツール」>「NuGetパッケージマネージャー」>「パッケージマネージャーコンソール」の順で選択します。
パッケージマネージャーコンソールが表示されるので、以下のコマンドを入力してください。

NuGet\Install-Package LiveChartsCore.SkiaSharpView.WinForms -Version 2.0.0-beta.801
image.png
ちゃんとインストールされましたね。

CommunityToolkit.MVVMのインストール

 LiveCharts2はMVVMモデルでサンプルコードの実装を行っています。LiveCharts2の公式サイトでおすすめされていたので、取り合えず入れておきましょう。後から拡張するときにここで引っかかるのも嫌なので。
公式サイトの該当ページ

 VSのタブより「ツール」>「NuGetパッケージマネージャー」>「ソリューションのNuGetパッケージの管理」を開きます。
 検索タブに”CommunityToolkit.MVVM”と入力すると、青アイコンのライブラリがヒットします。これの最新版(8.2.0)をインストールしましょう。

image.png

グラフを作ってみよう

準備 - フォルダ構成

 ソリューションエクスプローラーのプロジェクトを選択した状態で右クリックし、「追加」>「新しいフォルダ」を選択。
image.png
追加したフォルダ名を今回は"VM"とします。
image.png
次に、ファイルを2つ追加します。
先程作成したVMフォルダを選択して、「Ctrl+Shift+A」を入力。
新しい項目の追加」画面がポップアップするので、「クラス」をダブルクリックします。
image.png
こちらのファイル名を以下のようにしましょう。

  • ViewModel_Bar
  • ViewModel_Label

最終的に、以下のようなフォルダ構成になれば大丈夫です。
image.png

コード

先ほど作成したファイル2つ(ViewModel_Label.cs、ViewModel_Bar.cs)と、既存のForm1.csに下記のコードを作成しました。そのまま張り付けてみましょう。

Form1.cs
Form1.cs
using ForQiitaLC2.VM;
using LiveChartsCore.SkiaSharpView.Painting;
using LiveChartsCore.SkiaSharpView.WinForms;
using SkiaSharp;
using System.Drawing;
using System.Windows.Forms;
using VM;

namespace ForQiitaLC2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitializeBar();
        }

        private void InitializeBar()
        {
            Size = new System.Drawing.Size(1454, 677);

            var viewModelBar = new ViewModel_Bar();
            var C1 = new CartesianChart
            {

                Series = viewModelBar.Series,
                // out of livecharts properties...
                Location = new Point(0, 0),
                Size = new Size(1000, 600),
                Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom,

            };

            C1.Name = "LayeredBar";

            var viewModel_Label = new ViewModel_Label();

            C1.XAxes = viewModel_Label.XAxes;
            C1.YAxes = viewModel_Label.YAxes;

            C1.LegendTextPaint = new SolidColorPaint
            {
                Color = SKColors.Black,
            };
            C1.LegendPosition = LiveChartsCore.Measure.LegendPosition.Right;

            Controls.Add(C1);
        }
    }
}

ViewModel_Bar.cs
ViewModel_Bar.cs
using LiveChartsCore;
using LiveChartsCore.Kernel;
using LiveChartsCore.Kernel.Sketches;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
using SkiaSharp;

namespace ForQiitaLC2.VM
{
    public partial class ViewModel_Bar 
    {
        public ViewModel_Bar()
        {
            LiveChartsSkiaSharp.DefaultSKTypeface = SKFontManager.Default.MatchCharacter('あ');

            var series1 = new ColumnSeries<double>
            {
                Name = "目標",
                Values = new[] { 6.0, 3.0, 5.0, 7.0, 3.0, 4.0, 6.0, 3.0 },
                Stroke = null,
                MaxBarWidth = 50,
                IgnoresBarPosition = true,
            };

            var series2 = new ColumnSeries<double>
            {
                Name = "比較対象",
                Values = new[] { 2.0, 4.0, 8.0, 9.0, 5.0, 2.0, 4.0, 7.0 },
                Stroke = null,
                MaxBarWidth = 27,
                IgnoresBarPosition = true,
            };

            series1.ChartPointPointerDown += OnPointerDown; 
            series1.ChartPointPointerHover += OnPointerHover; 
            series1.ChartPointPointerHoverLost += OnPointerHoverLost; 
            series1.PointCreated += Series1_PointCreated;

            Series = new ISeries[] {series1, series2};
        }

        private void Series1_PointCreated(ChartPoint<double, RoundedRectangleGeometry, LabelGeometry> obj)
        {
            obj.Visual.Opacity = 0.5f;
        }

        public ISeries[] Series { get; set; }

        private void OnPointerDown(IChartView chart, ChartPoint<double, RoundedRectangleGeometry, LabelGeometry> point)
        {
            if (point.Visual is null) return;
            chart.Invalidate(); 
        }

        public void OnPointerHover(IChartView chart, ChartPoint<double, RoundedRectangleGeometry, LabelGeometry> point)
        {
            if (point.Visual is null) return;
            //point.Visual.Fill = new SolidColorPaint(SKColors.Yellow);
            point.Visual.Opacity = 0.5f;
            chart.Invalidate();
        }

        private void OnPointerHoverLost(IChartView chart, ChartPoint<double, RoundedRectangleGeometry, LabelGeometry> point)
        {
            if (point.Visual is null) return;
            //point.Visual.Fill = null;
            point.Visual.Opacity = 0.5f;
            chart.Invalidate();
        }
    }
}
ViewModel_Label.cs
ViewModel_Label.cs
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
using LiveChartsCore.SkiaSharpView.Painting.Effects;
using SkiaSharp;

namespace VM
{
    public partial class ViewModel_Label 
    {
        public ViewModel_Label()
        {
            LiveChartsSkiaSharp.DefaultSKTypeface = SKFontManager.Default.MatchCharacter('あ');
        }


        public Axis[] XAxes { get; set; } =
        {
            new Axis
            {

                Labels = new string[] { "1", "2", "3", "4", "5","6", "7", "8", "9", "10" },

                Name = "X軸",
                NamePaint = new SolidColorPaint
                {
                    Color = SKColors.Black,
                },

                LabelsPaint = new SolidColorPaint(SKColors.Blue),
                TextSize = 10,

                SeparatorsPaint = new SolidColorPaint(SKColors.LightSlateGray) { StrokeThickness = 2 },
            }
        };

        public Axis[] YAxes { get; set; } =
        {
            new Axis
            {
                Name = "Y軸",
                NamePaint = new SolidColorPaint
                {
                    Color = SKColors.Red,
                },
                MinLimit = 0,
                LabelsPaint = new SolidColorPaint(SKColors.Green),
                TextSize = 20,

                SeparatorsPaint = new SolidColorPaint(SKColors.LightSlateGray)
                {
                    StrokeThickness = 2,
                    PathEffect = new DashEffect(new float[] { 3, 3 })
                }
            }
        };
    }
}
貼り付け後、デバッグを行うと以下の画像が表示されます。

image.png
棒グラフ、X-Y軸、凡例、メモリが表示されています。

Githubに公開されているプロジェクトについて

1. プロジェクトはVisualStudio 2022で開発されている

最初、VisualStudio 2019でもGithubから持ってきたプロジェクトを開けるかと思っていました。しかし、プロジェクトにアンドロイド用の開発環境が含まれており、この開発環境が2019だと対象外なようで、開けませんでした。もし開きたい場合は、VisualStudio 2022をインストールして、そちらから開きましょう。

 ※ プロジェクトの開発環境を2022に出来るなら、そちらがベターかと思います。
 ※ エラーがたくさん出てきたので、筆者はコンパイル出来ませんでした。

2. namespaceの宣言

Livecharts2のGithubに公開されているサンプルコードで、namespaceの宣言が以下のようにされているファイルがあります。

namespace ViewModelsSamples.Axes.ColorsAndPosition;

C#10の新機能を見てみると、global using ディレクティブという機能が追加されています。これは「ほかのファイルからそのnamespace空間で宣言された全てを扱える」というもので、グローバル変数のnamespace版のようなものです。

しかしながら、.NetFramework472ではC#7.3を対象としているため、Gitのサンプルコードをそのまま移植しようとするとエラーが発生します。次に述べるnull許容参照型とともに、変更をしてください。
 ※C#のバージョンと.NET関連フレームワークの対応

次のように変更すると当該エラーは消えます。従来の宣言になります。

namespace ViewModelsSamples.Axes.ColorsAndPosition
{
   ...
}

3. null許容参照型

null許容参照型C#8.0で追加された機能です。
型"T"を宣言する時に、「"T"+"?"」と記述します。

string notNull = "Hello";   // 1
string? nullable = default; // 2

1がnull非許容参照型であり、逆参照が可能です。2はnull許容参照型で、逆参照をする場合は先にnullかどうかをチェックする必要があります。
null許容参照型は既存の型に対する注釈(nullかもしれないよ!という宣言)です。コンパイラはこの注釈を利用して、ユーザがコード内で発生する可能性のあるnull参照エラーを検出しやすくなります。

これも移植するときにエラーが出てしまうので、サンプルコードから持ってきたときは"?"を削除してあげましょう。削除した場合でも、筆者環境では特にエラーは発生していませんでした。

LiveCharts2インストール時の失敗

最初、LiveCharts2の公式サイトから下記のコマンドを引っ張ってきて、パッケージマネージャーコンソールに入力しました。

Install-Package LiveChartsCore.SkiaSharpView.WinForms

しかしながら、このコマンドでは失敗します。
どうやらバージョンを指定していないせいでエラーが出るようです。
image.png
image.png
バージョンまで指定してあげると、インストールが出来ました。
ここから最新版のコマンドが取得できます。

グラフの日本語化

ViewModel_Bar.cs, ViewModel_Label.csのコンストラクタの中に、日本語化のコードがあります。これらを一度コメントアウトして実行すると、下記の画像のようになります。

//LiveChartsSkiaSharp.DefaultSKTypeface = SKFontManager.Default.MatchCharacter('あ');

image.png
コンストラクタの中で宣言すると、色々なところで宣言する必要がないので楽です。

LayeredBarの透明度調整

ViewModel_Bar.csの中に、下記の宣言があります。

 series1.ChartPointPointerDown += OnPointerDown;  // ポインタクリック時 
 series1.ChartPointPointerHover += OnPointerHover;  // ポインタホバー時
 series1.ChartPointPointerHoverLost += OnPointerHoverLost; // ポインタホバーロスト時
 series1.PointCreated += Series1_PointCreated;  // ポインタ作成時

各メソッドに割り当てた関数の中では、不透明度の操作、操作内容の適用を行っています。
各メソッドに対して何も定義しない場合、LiveCharts2デフォルトの動作を行います。筆者の場合はいちいち不透明度が変わるのが邪魔だったため、不透明度を一律0.5としています。

series2には何も割り当てていないので、series1とseries2で何がデフォルトの動作か比較してみてください。

おわりに

随時詰まったところがあれば追記していこうと思います。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1