FlexChart for WinForms
チャート吹き出しの作成
チュートリアル > チャート吹き出しの作成

チャート吹き出しは、強調表示したいポイントから情報テキストを含むボックスまで線または矢印を引くことで、チャート上の特定の系列またはデータポイントを強調することができるビジュアルツールです。このような吹き出しは、追加情報でチャートを補完するだけでなく、強調したいポイントに直接接続されるため、チャートの理解を助けることにも役立ちます。たとえば、チャート吹き出しを使用すると、次の例に示すように、最大コストと最小コストに対応する値を簡単に示すことができます。

チャート吹き出しツール

FlexChart では、以下の簡単な手順を実行することで、多角形タイプの注釈を使用してチャート吹き出しを作成できます。この例では、2 種類の吹き出しを示しています。1 つは単純な直線の接続線が付いた吹き出し、もう 1 つは矢印型の接続線が付いた吹き出しです。

チャート吹き出しの作成手順

アプリケーションの設定

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

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

  1. データソースを作成します。
    public class DataService
    {
        static Random rnd = new Random();
        public static List<UnitsCost> GetUnitCostData()
        {
            var data = new List<UnitsCost>();
            var date = new DateTime(2017, 1, 1);
            int cost = 900;
            for (int i = 10; i <= 180; i += 10)
            {
                cost += i <= 100 ? -rnd.Next(20, 70) : rnd.Next(20, 50);
                data.Add(new UnitsCost
                {
                    Units = i,
                    Cost = cost,
                });
            }
            return data;
        }
    }
    
    Public Class DataService
         Shared rnd As New Random()
         Public Shared Function GetUnitCostData() As List(Of UnitsCost)
              Dim data As List(Of UnitsCost) = New List(Of UnitsCost)()
              Dim [date] As DateTime = New DateTime(2017, 1, 1)
              Dim cost As Integer = 900
              For i As Integer = 10 To 180 Step 10
                   cost += If(i <= 100, -rnd.[Next](20, 70), rnd.[Next](20, 50))
                   data.Add(New UnitsCost() With {
                    .Units = i,
                    .Cost = cost
                   })
              Next
              Return data
         End Function
    End Class
    
  2. DataSource プロパティを設定して、FlexChart をこのデータソースに連結します。
  3. チャートに表示されているデフォルトの系列をクリアし、Add メソッドを使用して新しい系列を追加します。
  4. BindingX プロパティと Binding プロパティを設定して、X 軸と Y 軸を構成します。
  5. ChartType などの必要なプロパティを設定して、チャートを構成します。
  6. FlexChart の Rendering イベントを初期化して、カスタムメソッド SetupAnnotations を呼び出します。このメソッドを次の手順で実装して、吹き出しを作成します。
     protected void SetupChart()
     {
            _data = DataService.GetUnitCostData();
    //     this.flexChart1.Header.Content = "Relationship between Production and Cost";
    
         this.flexChart1.Binding = "Cost";
         this.flexChart1.BindingX = "Units";
         this.flexChart1.DataSource = _data;
         this.flexChart1.ChartType = ChartType.LineSymbols;
         this.flexChart1.Series.Add(new Series() { Name = "Cost" });
    
         this.flexChart1.AxisX.Title = "Quantity";
         this.flexChart1.AxisY.Title = "Per Unit Cost";
    
         this.flexChart1.Rendering += FlexChart1_Rendering; 
         
     }
    
    Protected Sub SetupChart()
         _data = DataService.GetUnitCostData()
         '     this.flexChart1.Header.Content = "Relationship between Production and Cost";
    
         Me.flexChart1.Binding = "Cost"
         Me.flexChart1.BindingX = "Units"
         Me.flexChart1.DataSource = _data
         Me.flexChart1.ChartType = ChartType.LineSymbols
         Me.flexChart1.Series.Add(New Series() With {
          .Name = "Cost"
         })
    
         Me.flexChart1.AxisX.Title = "Quantity"
         Me.flexChart1.AxisY.Title = "Per Unit Cost"
    
         AddHandler Me.flexChart1.Rendering, AddressOf FlexChart1_Rendering
    
    End Sub
    

注釈の作成と追加

  1. AnnotationLayer クラスのインスタンスを作成して、注釈レイヤを作成します。
  2.  Polygon クラスのインスタンスを作成して、直線吹き出しを作成します。
  3. 直線吹き出しを作成するポイントを指定し、関連するプロパティを設定して、注釈をアタッチおよびスタイル設定します。
  4. 注釈テキストのサイズを測定し、それに応じて矢印吹き出しの注釈の座標を計算するカスタムメソッド GetArrowCalloutPoints を作成します。
  5. Polygon クラスのインスタンスをもう 1 つ作成して、矢印吹き出しを作成します。
  6. GetArrowCalloutPoints メソッドを呼び出し、他の関連するプロパティを指定して、注釈をアタッチおよびスタイル設定します。
  7. Add メソッドを使用して、注釈レイヤに 2 つの注釈を追加します。
    private void SetupAnnotations()
    {
        var annotationLayer = new AnnotationLayer(this.flexChart1);
        var orderedCost = _data.OrderBy(x => x.Cost).ToList();
        var arrowCallout = new Polygon("Maximum Cost")
        {
            Attachment = AnnotationAttachment.DataIndex,
            SeriesIndex = 0,
            PointIndex = _data.IndexOf(orderedCost[_data.Count - 1]),
        };
    
        arrowCallout.Style.FillColor = Color.FromArgb(100, Color.Pink);
        arrowCallout.Style.StrokeColor = Color.Red;
        arrowCallout.ContentStyle.StrokeColor = Color.Red;
        foreach (PointF point in GetArrowCalloutPoints(arrowCallout, orderedCost[_data.Count - 1]))
        {
            arrowCallout.Points.Add(point);
        }
    
        var lineCallout = new Polygon("Minimum Cost")
        {
            Attachment = AnnotationAttachment.DataIndex,
            SeriesIndex = 0,
            PointIndex = _data.IndexOf(orderedCost[0]),
            ContentCenter = new PointF(30, -60),
            Points = { new PointF(0, 0), new PointF(30, -40), new PointF(-30, -40), new PointF(-30, -80), new PointF(90, -80), new PointF(90, -40), new PointF(30, -40) }
        };
        lineCallout.Style.FillColor = Color.FromArgb(100, Color.Aqua);
        lineCallout.Style.StrokeColor = Color.Blue;
        lineCallout.ContentStyle.StrokeColor = Color.Blue;
    
        annotationLayer.Annotations.Add(arrowCallout);
        annotationLayer.Annotations.Add(lineCallout);
    }
    
    Private Sub SetupAnnotations()
         Dim annotationLayer As AnnotationLayer = New AnnotationLayer(Me.flexChart1)
         Dim orderedCost As List(Of UnitsCost) = _data.OrderBy(Function(x) x.Cost).ToList()
         Dim arrowCallout As Polygon = New Polygon("Maximum Cost") With {
          .Attachment = AnnotationAttachment.DataIndex,
          .SeriesIndex = 0,
          .PointIndex = _data.IndexOf(orderedCost(_data.Count - 1))
         }
    
         arrowCallout.Style.FillColor = Color.FromArgb(100, Color.Pink)
         arrowCallout.Style.StrokeColor = Color.Red
         arrowCallout.ContentStyle.StrokeColor = Color.Red
         For Each point As PointF In GetArrowCalloutPoints(arrowCallout, CType(orderedCost(_data.Count - 1), UnitsCost))
              arrowCallout.Points.Add(point)
         Next
         Dim lineCallout As Polygon = New Polygon("Minimum Cost") With {
          .Attachment = AnnotationAttachment.DataIndex,
          .SeriesIndex = 0,
          .PointIndex = _data.IndexOf(CType(orderedCost(0), UnitsCost)),
          .ContentCenter = New PointF(30, -60)
         }
         lineCallout.Points.Add(New PointF(0, 0))
         lineCallout.Points.Add(New PointF(30, -40))
         lineCallout.Points.Add(New PointF(-30, -40))
         lineCallout.Points.Add(New PointF(-30, -80))
         lineCallout.Points.Add(New PointF(-30, -80))
         lineCallout.Points.Add(New PointF(90, -80))
         lineCallout.Points.Add(New PointF(90, -40))
         lineCallout.Points.Add(New PointF(30, -40))
    
         lineCallout.Style.FillColor = Color.FromArgb(100, Color.Aqua)
         lineCallout.Style.StrokeColor = Color.Blue
         lineCallout.ContentStyle.StrokeColor = Color.Blue
    
         annotationLayer.Annotations.Add(arrowCallout)
         annotationLayer.Annotations.Add(lineCallout)
    End Sub
    
上記の手順で、注釈テキストのサイズを取得し、それに基づいて多角形の座標を計算するために使用されるカスタムメソッド GetArrowCalloutPoints は、次のように実装できます。

吹き出しのレンダリング

  1. SetupAnnotations メソッドを FlexChart クラスの Rendering イベントで呼び出します。
    private void FlexChart1_Rendering(object sender, RenderEventArgs e)
    {
        if (_renderEngine == null)
        {
            _renderEngine = e.Engine;
            SetupAnnotations();
        }
    }
    
    Private Sub FlexChart1_Rendering(sender As Object, e As RenderEventArgs)
         If _renderEngine Is Nothing Then
              _renderEngine = e.Engine
              SetupAnnotations()
         End If
    End Sub
    
  2. サンプルを実行して、吹き出し付きのチャートをレンダリングします。

単純な直線吹き出しと矢印吹き出しを表示するチャートが表示され、最小コストと最大コストに関連するデータポイントが示されていることを確認します。同様に、使用するテキストのサイズを測定し、それに応じて多角形注釈の座標を計算することで、他の形式の多角形で吹き出しを作成できます。実装の詳細については、コントロールに同梱されている FlexChartExplorer サンプルを参照してください。この機能の実際の動作を見るには、Mescius Web サイトから FlexChartExplorer デモをダウンロードしてください。

関連トピック