ComponentOne BulletGraph for WinForms
Walkthrough / Using BulletGraph with FlexGrid
In This Topic
    Using BulletGraph with FlexGrid
    In This Topic

    This walkthrough explains the steps to display the BulletGraph control in FlexGrid cells. The BulletGraph control cannot be directly added to the FlexGrid cells but you can alternatively render it as an image in the FlexGrid cells. To achieve the same, you first need to add an unbound column to the FlexGrid and then use the CellPainting event to render the BulletGraph control as an image in the added unbound column.

    bulletgraph-view

    Note: The BulletGraph control can also be rendered as an image in bound column of the FlexGrid control using similar approach.
    1. Create a new Windows Forms application.
    2. Drag and drop the FlexGrid control from the Toolbox onto your form. From the Properties window, set its Dock property to Fill.
    3. Create a DataTable using the following method ‘CreateDataTable’. This data table will be used as the DataSource for the FlexGrid.
      Private Sub CreateDataTable()
          _dt = New DataTable()
          _dt.Columns.Add("Country", GetType(String))
          _dt.Columns.Add("Sales", GetType(Double))
          _dt.Columns.Add("Target", GetType(Double))
          _dt.Columns.Add("Bad", GetType(Double))
          _dt.Columns.Add("Good", GetType(Double))
          Dim countries As String() = {"US", "Germany", "Japan", "India", "China", "UK", "Denmark", "Indonesia"}
          Dim random As Random = New Random()
      
          For i As Integer = 0 To countries.Length - 1
              Dim totalSales As Integer = random.[Next](0, 500)
              Dim target As Integer = random.[Next](351, 499)
              Dim bad As Integer = random.[Next](50, 200)
              Dim good As Integer = random.[Next](201, 350)
              _dt.Rows.Add(New Object() {countries(i), totalSales, target, bad, good})
          Next
      End Sub
      
      private void CreateDataTable()
      {
          _dt = new DataTable();
          _dt.Columns.Add("Country", typeof(String));
          _dt.Columns.Add("Sales", typeof(Double));
          _dt.Columns.Add("Target", typeof(Double));
          _dt.Columns.Add("Bad", typeof(Double));
          _dt.Columns.Add("Good", typeof(Double));
          string[] countries = { "US", "Germany", "Japan", "India", "China", "UK", "Denmark", "Indonesia" };
          Random random = new Random();
          for (int i = 0; i < countries.Length; i++)
          {
              int totalSales = random.Next(0, 500);
              int target = random.Next(351, 499);
              int bad = random.Next(50, 200);
              int good = random.Next(201, 350);
              _dt.Rows.Add(new object[] { countries[i], totalSales, target, bad, good });
          }
      }
      
      Note: The _dt is declared as a private global variable of type DataTable.
    4. Create a method named ‘SetUpGrid’ to add an unbound column to the FlexGrid control. This column will be used for showing the BulletGraph control as an image. Also, subscribe to the OwnerDrawCell event. This event will be used to render the BulletGraph control as an image in the unbound column ‘SalesV/STarget’ of the FlexGrid.        
      Private Sub SetUpGrid()
          C1FlexGrid1.DataSource = _dt
      
          'Add an unbound column to the FlexGrid. This column will be used to show the BulletGraph control as an image 
          Dim unboundCol As Column = C1FlexGrid1.Cols.Add()
          unboundCol.Name = "SalesV/STarget"
          unboundCol.Caption = "SalesV/STarget"
          unboundCol.AllowEditing = False
      
          'Set additional properties of the FlexGrid (optional)
          C1FlexGrid1.Cols.Fixed = 0
          C1FlexGrid1.AllowEditing = False
          C1FlexGrid1.Rows(0).StyleNew.Font = New Font(FontFamily.GenericSansSerif, 9.0F, FontStyle.Bold)
          C1FlexGrid1.Styles.Normal.Font = New Font(FontFamily.GenericSansSerif, 9.0F, FontStyle.Regular)
          C1FlexGrid1.Rows.DefaultSize = 40
          C1FlexGrid1.Cols.DefaultSize = 90
          C1FlexGrid1.ExtendLastCol = True
          C1FlexGrid1.Cols("Sales").Caption = "Sales" & vbLf & "(in millions)"
          C1FlexGrid1.Cols("Target").Caption = "Target" & vbLf & "(in millions)"
          C1FlexGrid1.Cols("Bad").Caption = "Bad" & vbLf & "(in millions)"
          C1FlexGrid1.Cols("Good").Caption = "Good" & vbLf & "(in millions)"
      
          For i As Integer = 0 To C1FlexGrid1.Cols.Count - 1
              C1FlexGrid1.Cols(i).Format = "$ #,##0"
              C1FlexGrid1.Cols(i).TextAlign = TextAlignEnum.CenterCenter
              C1FlexGrid1.Cols(i).TextAlignFixed = TextAlignEnum.CenterCenter
          Next
      
          C1FlexGrid1.DrawMode = C1.Win.C1FlexGrid.DrawModeEnum.OwnerDraw
      
          'Subscribe to the OwnerDrawCell event
          AddHandler C1FlexGrid1.OwnerDrawCell, AddressOf C1FlexGrid1_OwnerDrawCell
      End Sub
      
      private void SetUpGrid()
      {
          c1FlexGrid1.DataSource = _dt;
      
          //Add an unbound column to the FlexGrid. This column will be used to show the BulletGraph control as an image 
          Column unboundCol =c1FlexGrid1.Cols.Add();
          unboundCol.Name = "SalesV/STarget";
          unboundCol.Caption = "SalesV/STarget";
          unboundCol.AllowEditing = false;
      
          //Set additional properties of the FlexGrid (optional)
          c1FlexGrid1.Cols.Fixed = 0;
          c1FlexGrid1.AllowEditing = false;
          c1FlexGrid1.Rows[0].StyleNew.Font = new Font(FontFamily.GenericSansSerif, 9f, FontStyle.Bold);
          c1FlexGrid1.Styles.Normal.Font= new Font(FontFamily.GenericSansSerif, 9f, FontStyle.Regular);
          c1FlexGrid1.Rows.DefaultSize = 40;
          c1FlexGrid1.Cols.DefaultSize = 90;
          c1FlexGrid1.ExtendLastCol = true;
          c1FlexGrid1.Cols["Sales"].Caption = "Sales\n(in millions)";
          c1FlexGrid1.Cols["Target"].Caption = "Target\n(in millions)";
          c1FlexGrid1.Cols["Bad"].Caption = "Bad\n(in millions)";
          c1FlexGrid1.Cols["Good"].Caption = "Good\n(in millions)";
          for (int i = 0; i < c1FlexGrid1.Cols.Count; i++)
          {
              c1FlexGrid1.Cols[i].Format = "$ #,##0";
              c1FlexGrid1.Cols[i].TextAlign = TextAlignEnum.CenterCenter;
              c1FlexGrid1.Cols[i].TextAlignFixed = TextAlignEnum.CenterCenter;
          }
      
          //Subscribe to the OwnerDrawCell event
          c1FlexGrid1.DrawMode = C1.Win.C1FlexGrid.DrawModeEnum.OwnerDraw;
          c1FlexGrid1.OwnerDrawCell += C1FlexGrid1_OwnerDrawCell;
      }
      
    5. Create a method named ‘ConfigureBulletGraph’ to specify the general settings for the BulletGraph control. These settings will be applied to all the bullet graphs, which will be rendered in the FlexGrid cells.
         
      Private Sub ConfigureBulletGraph()
          'Configure the BulletGraph control
          _bulletGraph = New C1BulletGraph()
          _bulletGraph.Minimum = 0 'Sets the starting value of the quantitative scale
          _bulletGraph.Maximum = 500 'Sets the ending value of the quantitative scale
          _bulletGraph.GraphScale.ShowLabels = False 'Hides the scale labels
          _bulletGraph.GraphScale.ShowMarks = False 'Hides the scale tick marks
      
          'Styling the BulletGraph control
          _bulletGraph.BackColor = Color.White
          _bulletGraph.Styles.Ranges.Value.Color = Color.SteelBlue
          _bulletGraph.Styles.Ranges.Bar.Border.Color = Color.Gray
          _bulletGraph.Styles.Ranges.Bar.Border.LineStyle = C1GaugeBorderStyle.Solid
      End Sub
      
      private void ConfigureBulletGraph()
      {
          //Configure the BulletGraph control
          _bulletGraph = new C1BulletGraph();
          _bulletGraph.Minimum = 0; //Sets the starting value of the quantitative scale
          _bulletGraph.Maximum = 500; //Sets the ending value of the quantitative scale
          _bulletGraph.GraphScale.ShowLabels = false; //Hides the scale labels 
          _bulletGraph.GraphScale.ShowMarks = false; //Hides the scale tick marks
      
          //Styling the BulletGraph control
          _bulletGraph.BackColor = Color.White;
          _bulletGraph.Styles.Ranges.Value.Color = Color.SteelBlue;
          _bulletGraph.Styles.Ranges.Bar.Border.Color = Color.Gray;
          _bulletGraph.Styles.Ranges.Bar.Border.LineStyle = C1GaugeBorderStyle.Solid;
      }
      
    6. To render the BulletGraph control as an image in the ‘SalesV/STarget’ column of the FlexGrid, use the FlexGrid’s OwnerDrawCell event.
      In the OwnerDrawCell event handler, specify the values for the comparative measure, featured measure and qualitative ranges of the BulletGraph that need to be drawn. Then, retrieve an image of the BulletGraph control with the help of GetImage method of the C1BulletGraph class. Finally, draw the retrieved image in the FlexGrid’s cells using the DrawImage method of Graphics class as shown:
          Private Sub C1FlexGrid1_OwnerDrawCell(ByVal sender As Object, ByVal e As C1.Win.C1FlexGrid.OwnerDrawCellEventArgs)
              If e.Row > 0 AndAlso C1FlexGrid1.Cols(e.Col).Name = "SalesV/STarget" Then
                  _bulletGraph.Bounds = e.Bounds
                  _bulletGraph.Value = CDbl(_dt.Rows(e.Row - 1)("Sales")) 'Sets the value of the featured measure
                  _bulletGraph.Target = CDbl(_dt.Rows(e.Row - 1)("Target")) 'Sets the value of the comparative measure
                  _bulletGraph.Bad.To = CDbl(_dt.Rows(e.Row - 1)("Bad"))  'Sets the ending value of the good range
                  _bulletGraph.Good.To = CDbl(_dt.Rows(e.Row - 1)("Good")) 'Sets the ending value of the bad range
      
                  'Retrieve the BulletGraph image and draw the retrieved image in the FlexGrid's cell    
                  Dim bulletGraphImg As Image = _bulletGraph.GetImage()
                  e.Graphics.DrawImage(bulletGraphImg, e.Bounds)
                  e.DrawCell(DrawCellFlags.Border)
                  e.Handled = True
              End If
          End Sub
      End Class
      
      private void C1FlexGrid1_OwnerDrawCell(object sender, C1.Win.C1FlexGrid.OwnerDrawCellEventArgs e)
      {
          if (e.Row > 0 && c1FlexGrid1.Cols[e.Col].Name== "SalesV/STarget")
          {
              _bulletGraph.Bounds = e.Bounds;
              _bulletGraph.Value = (double)_dt.Rows[e.Row - 1]["Sales"]; //Sets the value of the featured measure
              _bulletGraph.Target = (double)_dt.Rows[e.Row - 1]["Target"]; //Sets the value of the comparative measure
              _bulletGraph.Bad.To = (double)_dt.Rows[e.Row - 1]["Bad"]; //Sets the ending value of the good range
              _bulletGraph.Good.To = (double)_dt.Rows[e.Row - 1]["Good"]; //Sets the ending value of the bad range
      
              //Retrieve the BulletGraph image and draw the retrieved image in the FlexGrid's cell
              Image bulletGraphImg = _bulletGraph.GetImage();
              e.Graphics.DrawImage(bulletGraphImg, e.Bounds);
              e.DrawCell(DrawCellFlags.Border);
              e.Handled = true;
          }
      }
      

    7. Call the CreateDataTable, SetUpGrid and ConfigureBulletGraph methods in the Form1_Load event handler.
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
          'Creates DataTable which will be used as the DataSource for the FlexGrid
          CreateDataTable()
          'Adds an unbound column to the FlexGrid and sets the FlexGrid properties
          SetUpGrid()
          'Sets the common properties of the BulletGraph control
          ConfigureBulletGraph()
      End Sub
      
      private void Form1_Load(object sender, EventArgs e)
      {
          //Creates DataTable which will be used as the DataSource for the FlexGrid
          CreateDataTable();
      
          //Adds an unbound column to the FlexGrid and sets the FlexGrid properties
          SetUpGrid();
      
          //Sets the common properties of the BulletGraph control
          ConfigureBulletGraph();
      }
      

    8. Run the application. Observe how the bullet graphs are getting displayed in the ’SalesV/STarget’ column of the FlexGrid control.