Walkthrough / Create Chart Callouts
Create Chart Callouts

Chart callouts are visual tools that help in emphasizing a specific series or data point on a chart, through a line or arrow from the point to be highlighted to a box with information text. These callouts not only supplement charts with additional information but also help in easy comprehension as they are directly connected to the point of emphasis. For instance, chart callouts can make it easy to indicate the values corresponding to maximum and minimum cost as shown in the example below.

chart callout tool

In FlexChart, you can create chart callouts using the Polygon type annotations by carrying out the following simple steps. In this example, we have demonstrated two type of callouts, one with simple line connector and other one with the arrow connector.

Steps to create chart callout

Set up the Application

  1. Create a new Windows Forms app.
  2. Drag and drop the FlexChart control from the toolbox onto the form.
    Observe: A column type chart is drawn with a default data.

Bind the FlexChart Control to a Data Source

  1. Create a data source.
    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;
        }
    }
    
  2. Bind the FlexChart to this data source by setting the DataSource property.
  3. Clear the default series getting displayed in the chart and add a new series using the Add method.
  4. Configure the X and Y axes by setting the BindingX and Binding property.
  5. Configure the chart by setting the ChartType and other required properties.
  6. Initialize the Rendering event of FlexChart to call the custom method SetupAnnotations which is implemented in the following steps to create the callouts.
     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; 
         
     }
    

Create and Add the Annotations

  1. Create an annotation layer by creating an instance of the AnnotationLayer class.
  2. Create a line callout by creating an instance of the Polygon class.
  3. Specify the points to create the line callout and set the related properties to attach and style the annotation.
  4. Create a custom method, GetArrowCalloutPoints in this case, to measure the size of annotation text and calculate the coordinates for arrow callout annotation accordingly.
  5. Create an arrow callout by creating another instance of the Polygon class.
  6. Call the GetArrowCalloutPoints method and specify other related properties to attach and style the annotation.
  7. Add the two annotations in the annotation layer using the Add method.
    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);
    }
    
Note that the custom method GetArrowCalloutPoints used in the step above to get the size of the annotation text and to calculate the polygon coordinates based on that can be implemented as follows.

Render the Callouts

  1. Invoke the SetupAnnotations method in the Rendering event of the FlexChart class.
    private void FlexChart1_Rendering(object sender, RenderEventArgs e)
    {
        if (_renderEngine == null)
        {
            _renderEngine = e.Engine;
            SetupAnnotations();
        }
    }
    
  2. Run the sample to render the chart with callouts.

Observe that a chart displaying a simple line callout and an arrow callout is displayed to indicate the data points related to minimum and maximum cost. Similarly, you can create callouts in the form of other polygons by measuring the size of text to be used and calculating the coordinates of the Polygon annotations accordingly. For detailed implementation, see FlexChartExplorer sample which is shipped with the control. To see this feature in action, you can also download the FlexChartExplorer demo from our website.

See Also

Elements