Xamarin.Formsで円グラフを描画する2

前回の記事はこちら

公式の解説はこちらを見ればいいかなと思います。
ただ、上記公式の解説だと表示するデータがなかったりするので、動くもので確認したければ、ここの解説を見ながら手を動かしてもらえればと思います。
っで、実際に動くソースとなるとGitHubのリポジトリに置いてます。

まずはゴールの確認

完成イメージはこちら
・それぞれのデータの内訳( Target )が数値として出る→円グラフのセグメントの値
・凡例が出ている→上部のJan,Febという部分

・タップした際にカスタマイズしたToolTipを表示させる。

ツールチップをカスタマイズしない場合は、Targetの値が表示されるだけ。
これだとデータの内訳と違いが出ないので、カスタマイズしていきます。

ソースの確認

App.xamlで表示するMainPageを変更しておく。

        public App()
        {
            Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("");
            InitializeComponent();
            MainPage = new PieSample2();
        }

PieSample2.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:HowToUseSyncfusionXamarin"
             xmlns:chart="clr-namespace:Syncfusion.SfChart.XForms;assembly=Syncfusion.SfChart.XForms"
			x:Class="HowToUseSyncfusionXamarin.PieSample2">
    <chart:SfChart>
        <chart:SfChart.Legend>
            <chart:ChartLegend/>
        </chart:SfChart.Legend>
        <chart:SfChart.Series>
            <chart:PieSeries ItemsSource="{Binding Data}"
                             XBindingPath="Month" YBindingPath="Target" 
                             EnableTooltip="True" 
                             DataMarkerPosition="OutsideExtended"
                             >
                <!--ツールチップで表示する内容をカスタマイズ-->
                <chart:PieSeries.TooltipTemplate>
                    <DataTemplate>
                        <StackLayout Orientation="Vertical">
                            <StackLayout Orientation="Horizontal">
                                <Label Text="月 :" />
                                <Label Text="{Binding Month}"/>
                            </StackLayout>
                            <StackLayout Orientation="Horizontal">
                                <Label Text="値   :" />
                                <Label Text="{Binding Target}"/>
                            </StackLayout>
                        </StackLayout>
                    </DataTemplate>
                </chart:PieSeries.TooltipTemplate>
                <!--凡例を表示する-->
                <chart:PieSeries.DataMarker>
                    <chart:ChartDataMarker LabelContent="YValue" />
                </chart:PieSeries.DataMarker>
            </chart:PieSeries>
        </chart:SfChart.Series>
    </chart:SfChart>
</ContentPage>

PieSample2.xaml .cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Syncfusion.SfChart.XForms;
using Xamarin.Forms;

namespace HowToUseSyncfusionXamarin
{
    public partial class PieSample2 : ContentPage
    {
        public PieSample2()
        {
            InitializeComponent();
        }

        protected override async void OnAppearing()
        {
            this.BindingContext = new PieChartViewModel();
        }


    }
}

今回もほぼXAML側で円グラフの描画を整えた。
もちろん、c#のコードで上記描画を実現することも可能です。

ソース解説

描画データの取得と反映

まずは、描画するデータをBindingContextに詰めているところから見ていきます。
PieSample2.xaml .csの
this.BindingContext = new PieChartViewModel();
の部分がそれになります。
PieChartViewModelは、 描画するデータを保持していて前回の記事にソースコードを載せていますが再掲しておきます。

using System.Collections.ObjectModel;
 
namespace HowToUseSyncfusionXamarin
{
    public class PieChartViewModel
    {
        public ObservableCollection<PieChartModel> Data { get; set; }
 
        public PieChartViewModel()
        {
            Data = new ObservableCollection<PieChartModel>()
            {
                new PieChartModel("Jan", 50),
                new PieChartModel("Feb", 70),
                new PieChartModel("Mar", 1),
                new PieChartModel("Apr", 57),
                new PieChartModel("May", 48),
            };
        }
    }
}

BindingContextにデータをセットしたことで、 PieSample2.xamlで値を使用することができるようになりました。

<chart:PieSeries ItemsSource="{Binding Data}"
XBindingPath="Month" YBindingPath="Target" 
EnableTooltip="True" 
DataMarkerPosition="OutsideExtended"
>

BindingContext( PieChartViewModel )のどのデータを円グラフにセットするのか指定しているのが、ItemsSource="{Binding Data}"という部分です。
今回の場合だとViewModel内にDataしかないのでそれをセットしています。
このDataの型はObservableCollection<PieChartModel>となっており、 PieChartModelが複数集まってできたものと考えてもらっていいです。
PieChartModelのソースも前回記事に載せてますが、再掲します。

namespace HowToUseSyncfusionXamarin
{
    public class PieChartModel
    {
        public string Month { get; set; }
 
        public double Target { get; set; }
 
        public PieChartModel(string xValue, double yValue)
        {
            Month = xValue;
            Target = yValue;
        }
    }
}

XBindingPath="Month" YBindingPath="Target" の部分がPieChartModelと紐づけている部分となります。

EnableTooltip="True" は、ツールチップの表示制御をしています。

DataMarkerPosition="OutsideExtended"は、円グラフのデータ値をどこに表示するかを指定しています。このオプションの詳細については、その他オプションのDataMarkerPositionの項目で確認してください。

ツールチップの表示内容をカスタマイズ

ツールチップをカスタマイズしない場合は、Targetの値が表示されるだけ。
というのを冒頭でも書きましたが、以下の部分をコメントアウトすると冒頭で表示したイメージが出ます。

<!--ツールチップで表示する内容をカスタマイズ-->
<chart:PieSeries.TooltipTemplate>
    <DataTemplate>
        <StackLayout Orientation="Vertical">
            <StackLayout Orientation="Horizontal">
                <Label Text="月 :" />
                <Label Text="{Binding Month}"/>
            </StackLayout>
            <StackLayout Orientation="Horizontal">
                <Label Text="値   :" />
                <Label Text="{Binding Target}"/>
            </StackLayout>
        </StackLayout>
    </DataTemplate>
</chart:PieSeries.TooltipTemplate>

上記ソースコードを追加することで以下ようなツールチップが表示されます。
PieSeries.TooltipTemplateタグの中にDataTemplateを置いてその中にStackLayout で中身の位置を調整しています。

ツールチップの大きさを変更したい場合は、DataTemplate直下のStackLayout にHeightRequestとWidthRequestを指定します。

<StackLayout Orientation="Vertical" HeightRequest="100" WidthRequest="100">

もちろん、StackLayout以外にも以下のようにGridで中身を調整することもできます。

                <chart:PieSeries.TooltipTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*" />
                                <RowDefinition Height="*" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Label Text="月 :" Grid.Row="0" Grid.Column="0"/>
                            <Label Text="{Binding Month}" Grid.Row="0" Grid.Column="1"/>
                            <Label Text="値   :" Grid.Row="1" Grid.Column="0"/>
                            <Label Text="{Binding Target}" Grid.Row="1" Grid.Column="1"/>
                        </Grid>
                    </DataTemplate>
                </chart:PieSeries.TooltipTemplate>

凡例の記述方法比較

以下では、GettingStarted3の記述方法と少し違うやり方で凡例を出してみました。差異はchart:PieSeriesのプロパティにLabel=”YValue”を設定することで、chart:ChartDataMarker側でLabelContent=”YValue”を記述しなくてよくなるというものです。

上記内容を試した動機としては、 GettingStarted3 をやっていた記憶が残っていたので、同じやり方にしたら円グラフと棒グラフで変わったりするのか?くらいの気持ちでやりました。

<chart:SfChart.Series>
            <!--GettingStarted3の記述方法ですが、Label="YValue"を設定することで、chart:ChartDataMarker側で
            LabelContent="YValue"を記述しなくてよくなります-->
            <chart:PieSeries ItemsSource="{Binding Data}"
                             XBindingPath="Month" YBindingPath="Target" 
                             EnableSmartLabels="True" 
                             EnableTooltip="True" 
                             DataMarkerPosition="OutsideExtended"
                             Label="YValue"
            >
                <!--ツールチップで表示する内容をカスタマイズ-->
                <chart:PieSeries.TooltipTemplate>
                    <DataTemplate>
                        <StackLayout Orientation="Vertical">
                            <StackLayout Orientation="Horizontal">
                                <Label Text="月 :" />
                                <Label Text="{Binding Month}"/>
                            </StackLayout>
                            <StackLayout Orientation="Horizontal">
                                <Label Text="値   :" />
                                <Label Text="{Binding Target}"/>
                            </StackLayout>
                        </StackLayout>
                    </DataTemplate>
                </chart:PieSeries.TooltipTemplate>
                <!--凡例を表示する-->
                <chart:PieSeries.DataMarker>
                    <chart:ChartDataMarker />
                </chart:PieSeries.DataMarker>
            </chart:PieSeries>
        </chart:SfChart.Series>

他オプションについて

公式のオプションの説明を見ると

円グラフをレンダリングするには、PieSeries のインスタンスを作成し、SfChart の Series コレクション プロパティに追加します。以下のプロパティを使用して、パイセグメントの外観をカスタマイズすることができます。

Color – 系列の色を変更するために使用します。
Opacity  – チャートシリーズの透明度を制御するために使用します。
StrokeWidth – シリーズのストローク幅を変更するために使用します。
StrokeColor – 系列のストロークの色を変更するために使用します。
DataMarkerPosition – データマーカの位置をInside、Outside、OutsideExtendedのいずれかで変更するために使用します。
ConnectorLinePosition – 自動および中央のコネクタ線の位置を変更するために使用します。

Color(色の調整)

チャート系列の色を取得または設定します。これはバインド可能なプロパティです。以下では、Colorに直接色を指定しているので赤一色になっていますが、本来はBindingして使います。例えば、 PieChartModel にColorプロパティを追加して、それぞれの色データを持たせれば自動ではなく円グラフの各セグメントの色を任意に調整することができます。

            <chart:PieSeries ItemsSource="{Binding Data}"
                             XBindingPath="Month" YBindingPath="Target" 
                             EnableTooltip="True" 
                             DataMarkerPosition="OutsideExtended" 
                             Color="#FC0423"

Opacity(透明度調整)

0~1 の間の値を取得または設定し、系列色の透明度を調整することができます。これはバインド可能なプロパティです。以下のように使います。

<chart:PieSeries ItemsSource="{Binding Data}"
                             XBindingPath="Month" YBindingPath="Target" 
                             EnableTooltip="True" 
                             DataMarkerPosition="OutsideExtended" 
                             Opacity="0.5" 
                             >

StrokeWidthとStrokeColor(ストロークとその色調整)

ストロークの幅を取得または設定します。これはバインド可能なプロパティです。ストロークがどこを指すのかは以下のイメージを見ればわかるかと思います。ただし、StrokeColorを指定しないと、セグメントの色でストロークが塗られているので判別できません。なのでStrokeWidthだけでは効果がわからないと思います。(実際に見てみたい方はStrokeColor=”Black”の部分を消してみてください)

<chart:PieSeries ItemsSource="{Binding Data}"
XBindingPath="Month" YBindingPath="Target" 
EnableTooltip="True" 
DataMarkerPosition="OutsideExtended" 
StrokeWidth="10"
StrokeColor="Black"
>

DataMarkerPosition(チャートデータマーカの位置調整)

円系列のチャートデータマーカの位置を取得・設定します。これはバインド可能なプロパティです。
以下では指定できるDataMarkerPositionの種類とそれに伴う変化をみていきます。

  • OutsideExtended:円グラフ外に数値を表示する
  • OutSide:円の線上に数値を表示する
  • Inside

ConnectorLinePosition

こちらは実際に書いてみましたが特に変化はなかったです。

コネクタの直線を自動利用可能な空間に描画するかどうかを示す型を取得または設定します。

とのことですが、コネクタって何?って感じでした。
他のグラフで試したりして詳細がわかれば書きたいと思います。

CircularCoefficient(円グラフのサイズ調整)

CircularCoefficient プロパティを使用して、円グラフの直径を変更することができます。0から1までの範囲で、デフォルト値は0.8です。

<chart:PieSeries ItemsSource="{Binding Data}"
 XBindingPath="Month" YBindingPath="Target" 
 EnableTooltip="True" 
 DataMarkerPosition="OutsideExtended" 
 CircularCoefficient="1"

Exploding(セグメントの強調)

セグメントの強調のためのいくつかのプロパティがあります。

ExplodeIndex

ExplodeIndexでは、指定したIndexのセグメントを強調することができます。

<chart:PieSeries ItemsSource="{Binding Data}"
 XBindingPath="Month" YBindingPath="Target" 
 EnableTooltip="True" 
 DataMarkerPosition="OutsideExtended" 
 ExplodeIndex = "0"
 >

ExplodeRadius

ExplodeRadiusプロパティを使ってセグメントの距離を定義する値を取得または設定します。これはバインド可能なプロパティです。

<chart:PieSeries ItemsSource="{Binding Data}"
 XBindingPath="Month" YBindingPath="Target" 
 EnableTooltip="True" 
 DataMarkerPosition="OutsideExtended" 
 ExplodeRadius="40"
 ExplodeIndex = "0"

ExplodeOnTouch

セグメントのタップ時に強調させるかどうかを示す値を取得または設定します。これはバインド可能なプロパティです。このプロパティのデフォルト値は false です。

<chart:PieSeries ItemsSource="{Binding Data}"
 XBindingPath="Month" YBindingPath="Target" 
 EnableTooltip="True" 
 DataMarkerPosition="OutsideExtended" 
 ExplodeOnTouch="True"
 >

ExplodeAll

ExplodeAllプロパティを使うと、すべてのパイセグメントを強調させることができます。これはバインド可能なプロパティです。

<chart:PieSeries ItemsSource="{Binding Data}"
 XBindingPath="Month" YBindingPath="Target" 
 EnableTooltip="True" 
 DataMarkerPosition="OutsideExtended" 
 ExplodeAll="True"

StartAngle と EndAngle

StartAngle と EndAngle プロパティを使用して、すべてのデータポイント/セグメントをセミパイ、クォーターパイ、または任意のセクターでレンダリングすることができます。

<chart:PieSeries ItemsSource="{Binding Data}"
 XBindingPath="Month" YBindingPath="Target" 
 EnableTooltip="True" 
 DataMarkerPosition="OutsideExtended" 
 StartAngle = "180"
 EndAngle = "360"
 >

Grouping(小さなセグメントをまとめる)

円グラフ内の小さなセグメントは、 GroupModeプロパティとGroupToプロパティとを使用して「その他」カテゴリにグループ化することができます。GroupModeプロパティに設定できる値は以下です。
Angle:セグメントの角度
Value:実際のデータの値
Percentage: 実際のデータのパーセンテージ値
フォルト値はValueです。

GroupToプロパティにはデータを1つのスライスにグループ化するための閾値を設定します。
今回のデータで例示すると、実際の値が90以下となるセグメントをOtherというセグメントに集約するというものになります。

<chart:PieSeries ItemsSource="{Binding Data}"
 XBindingPath="Month" YBindingPath="Target" 
 EnableTooltip="True" 
 DataMarkerPosition="OutsideExtended" 
 GroupMode="Value"
 GroupTo="90"
 >

グループ化されたセグメントは、凡例では「Other」とラベル付けされ、他のセグメントと同様に表記されます。