FlexChart for WinForms
カスタム凡例アイコン
チュートリアル > カスタム凡例アイコン

デフォルトでは、FlexChart コントロールは、各系列に色を割り当て、対応する系列に割り当てられた色に基づいて凡例アイコンを作成します。ただし、カスタムの凡例アイコンを作成することもできます。たとえば、さまざまな国のデータを表示しているときに、凡例アイコンとして国旗が表示されると、ユーザーがデータを読みやすくなります。 

カスタム凡例アイコン

チャートの作成後に凡例アイコンをカスタマイズするには、Series クラスと ISeries インタフェースを継承するカスタム系列を作成する必要があります。このインタフェースは、凡例アイコンのソースにアクセスするための GetLegendItemImageSource メソッドを提供し、そこから凡例アイコンボックス内に国旗の画像を設定することで、凡例アイコンをカスタマイズできます。 このウォークスルーでは、カスタム凡例アイコンを作成する手順を詳細に説明します。

カスタム凡例アイコンの作成手順

アプリケーションの設定

  1. 新しい Windows フォームアプリを作成します。
  2. FlexChart コントロールをツールボックスからフォームにドラッグアンドドロップします。
    注意:縦棒タイプのグラフがデフォルトデータを使用して描画されます。

FlexChart コントロールのデータソースへの連結

  1. データソースを作成します。
    /// <summary>
    /// FlexChartのデータを作成するメソッド
    /// </summary>
    public static List<SmartPhoneVendor> SmartPhoneVendors()
    {
        List<SmartPhoneVendor> vendors = new List<SmartPhoneVendor>();
        vendors.Add(new SmartPhoneVendor()
        {
            Name = "Apple",
            Sales = 215.2
        });
        vendors.Add(new SmartPhoneVendor()
        {
            Name = "Huawei",
            Sales = 139
        });
        vendors.Add(new SmartPhoneVendor()
        {
            Name = "Lenovo",
            Sales = 50.7
        });
        vendors.Add(new SmartPhoneVendor()
        {
            Name = "LG",
            Sales = 55.1,
        });
        vendors.Add(new SmartPhoneVendor()
        {
            Name = "Oppo",
            Sales = 92.5
        });
        vendors.Add(new SmartPhoneVendor()
        {
            Name = "Samsung",
            Sales = 310.3
        });
        vendors.Add(new SmartPhoneVendor()
        {
            Name = "Vivo",
            Sales = 71.7
        });
        vendors.Add(new SmartPhoneVendor()
        {
            Name = "Xiaomi",
            Sales = 61
        });
        vendors.Add(new SmartPhoneVendor()
        {
            Name = "ZTE",
            Sales = 61.9
        });
    
        return vendors;
    }
    
    ''' <summary>
    ''' FlexChartのデータを作成するメソッド
    ''' </summary>
    Public Shared Function SmartPhoneVendors() As List(Of SmartPhoneVendor)
        Dim vendors As New List(Of SmartPhoneVendor)()
        vendors.Add(New SmartPhoneVendor() With {
              .Name = "Apple",
              .Sales = 215.2
        })
        vendors.Add(New SmartPhoneVendor() With {
              .Name = "Huawei",
              .Sales = 139
        })
        vendors.Add(New SmartPhoneVendor() With {
              .Name = "Lenovo",
              .Sales = 50.7
        })
        vendors.Add(New SmartPhoneVendor() With {
              .Name = "LG",
              .Sales = 55.1
        })
        vendors.Add(New SmartPhoneVendor() With {
              .Name = "Oppo",
              .Sales = 92.5
        })
        vendors.Add(New SmartPhoneVendor() With {
              .Name = "Samsung",
              .Sales = 310.3
        })
        vendors.Add(New SmartPhoneVendor() With {
              .Name = "Vivo",
              .Sales = 71.7
        })
        vendors.Add(New SmartPhoneVendor() With {
              .Name = "Xiaomi",
              .Sales = 61
        })
        vendors.Add(New SmartPhoneVendor() With {
              .Name = "ZTE",
              .Sales = 61.9
        })
    
        Return vendors
    End Function
    
  2. DataSource プロパティを設定して、FlexChart をこのデータソースに連結します。
  3. BindingX プロパティと Binding プロパティを設定して、X 軸と Y 軸を構成します。
  4.  ChartType などの必要なプロパティを設定して、チャートを構成します。
    // FlexChartのヘッダーを設定します
    flexChart1.Header.Content = "Top Smartphone Vendors in USA";
    
    // データをFlexChartに渡します
    flexChart1.DataSource = vendors;
    
    // FlexChartのX軸を「Name」にバインドして、ベンダー名が横軸に表示されるようにします
    flexChart1.BindingX = "Name";
    
    // FlexChartを「Sales」にバインドして、市場シェアが縦軸に表示されるようにします
    flexChart1.Binding = "Sales";
    
    ' FlexChartのヘッダーを設定します
    flexChart1.Header.Content = "Top Smartphone Vendors in USA"
    
    ' データをFlexChartに渡します
    flexChart1.DataSource = vendors
    
    ' FlexChartのX軸を「Name」にバインドして、ベンダー名が横軸に表示されるようにします
    flexChart1.BindingX = "Name"
    
    ' FlexChartを「Sales」にバインドして、市場シェアが縦軸に表示されるようにします
    flexChart1.Binding = "Sales"
    

カスタム系列の作成

  1. Series クラスと ISeries インタフェースを継承するカスタムタイプの系列を作成します。この例では、SeriesWithPointLegendItems という名前のクラスを作成しました。
  2. ISeries.GetLegendItemImageSource メソッドを実装して、凡例のサイズにアクセスし、凡例ポイントの Graphics.DrawImage メソッドを使用してアイコンを描画します。
  3. ウィンドウサイズに合わせて凡例アイコンのサイズを設定することもできます。
    public class SeriesWithPointLegendItems : Series, ISeries
    {
        object ISeries.GetLegendItemImageSource(int index, ref C1.Chart._Size imageSize)
        {
            {
                imageSize.Height = 80;
                imageSize.Width = 130;
    
     
    
                SmartPhoneVendor vendor = vendors.ElementAt(index);
                Bitmap bm = new Bitmap(Properties.Resources.US);
                Image LegendIconImage = bm;
                if (LegendIconImage != null && LegendIconImage.Width != 130)
                {
                    Bitmap bmp = new Bitmap(130, 80);
                    using (SolidBrush sb = new SolidBrush(Color.White))
                    {
                        using (Graphics g = Graphics.FromImage(bmp))
                        {
                            Rectangle r = new Rectangle(0, 0, (int)imageSize.Width, (int)imageSize.Height);
                            using (Pen p = new Pen(sb))
                            {
                                g.DrawRectangle(p, r);
                            }
                            g.FillRectangle(new SolidBrush(Color.SkyBlue), r);
                            Point ci = new Point((int)(0.5 * Math.Abs(imageSize.Width - LegendIconImage.Width)),
                                (int)(0.5 * Math.Abs(imageSize.Height - LegendIconImage.Height)));
                            
                            g.DrawImage(LegendIconImage, ci);
                        }
                    }
                    LegendIconImage = bmp;
                }
    
                Size bounds = this.Chart.ClientSize;
                double divadj = (bounds.Height > 700) ? 5 : 11;
                double fracHeight = bounds.Height / divadj;
                if (fracHeight < imageSize.Height)
                    imageSize.Width = imageSize.Height = fracHeight;
                return LegendIconImage;
            }
        }
    }
    
    Public Class SeriesWithPointLegendItems
        Inherits Series
        Implements ISeries
        Private Function ISeries_GetLegendItemImageSource(index As Integer, ByRef imageSize As C1.Chart._Size) As Object Implements ISeries.GetLegendItemImageSource
            If True Then
                imageSize.Height = 80
                imageSize.Width = 130
    
     
    
                Dim vendor As SmartPhoneVendor = vendors.ElementAt(index)
                Dim bm As New Bitmap(Sample10.Resources.US)
                Dim LegendIconImage As Image = bm
                If LegendIconImage IsNot Nothing AndAlso LegendIconImage.Width <> 130 Then
                    Dim bmp As New Bitmap(130, 80)
                    Using sb As New SolidBrush(Color.White)
                        Using g As Graphics = Graphics.FromImage(bmp)
                            Dim r As New Rectangle(0, 0, CInt(Math.Truncate(imageSize.Width)), CInt(Math.Truncate(imageSize.Height)))
                            Using p As New Pen(sb)
                                g.DrawRectangle(p, r)
                            End Using
                            g.FillRectangle(New SolidBrush(Color.SkyBlue), r)
    
     
    
                            Dim ci As Point = New Point(CInt((0.5 * Math.Abs(imageSize.Width - LegendIconImage.Width))), CInt((0.5 * Math.Abs(imageSize.Height - LegendIconImage.Height))))
                            g.DrawImage(LegendIconImage, ci)
                        End Using
                    End Using
                    LegendIconImage = bmp
                End If
    
                Dim bounds As Size = Me.Chart.ClientSize
                Dim divadj As Double = If((bounds.Height > 700), 5, 11)
                Dim fracHeight As Double = bounds.Height / divadj
                If fracHeight < imageSize.Height Then
                    imageSize.Width = InlineAssignHelper(imageSize.Height, fracHeight)
                End If
                Return LegendIconImage
            End If
        End Function
        Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
            target = value
            Return value
        End Function
    End Class
    

系列コレクションへのカスタム系列の追加

  1. チャートに表示されるデフォルトの系列をクリアします。
  2. カスタム系列クラス(この場合は、SeriesWithPointLegendItems)のオブジェクトを作成します。
  3. Add メソッドを使用して、このオブジェクトをチャートの Series コレクションに追加します。
    // デフォルトの系列をクリアします
    flexChart1.Series.Clear();
    
    // 凡例を画像で表示し、色で塗りつぶし、グループに分類するカスタム系列を作成します
    _customSeries = new SeriesWithPointLegendItems
    {
        Name = "Sales",
    };
    
    // FlexChartにカスタム系列を追加します
    flexChart1.Series.Add(_customSeries);
    
    ' デフォルトの系列をクリアします
    flexChart1.Series.Clear()
                
    ' 凡例を画像で表示し、色で塗りつぶし、グループに分類するカスタム系列を作成します
    _customSeries = New SeriesWithPointLegendItems() With {
         .Name = "Sales"
    }
    
    ' FlexChartにカスタム系列を追加します
    flexChart1.Series.Add(_customSeries)
    

アプリケーションを実行して、系列色の境界線で囲まれた国旗がカスタム凡例アイコンとしてチャートに表示されることを確認します。系列やチャートが複数ある場合も、同様にして複数の凡例アイコンをカスタマイズできます。カスタム凡例アイコンの実装の詳細については、コントロールに同梱されている FlexChartExplorer サンプルを参照してください。この機能の実際の動作を見るには、Mescius Web サイトから FlexChartExplorer デモをダウンロードしてください。

関連トピック