BulletGraph for WinForms
DataGridViewとのBulletGraphの使用
チュートリアル > DataGridViewとのBulletGraphの使用

Consider a scenario where you have data in a tabular format and you want to visualize the same using a visual control. This walkthrough explains how this scenario can be implemented using MS DataGridView as the control for tabular representation of data and BulletGraph as the control for visual representation of the same data.

The BulletGraph control can be rendered as an image in the DataGridView cells. To learn how this can be done, follow the steps given below:
  1. Create Data Source for DataGridView
  2. Configure DataGridView control
  3. Configure BulletGraph control
  4. Rendering BulletGraph In DataGridView
Note: The BulletGraph control can also be rendered as an image in bound column of the DataGridView control using similar approach.

Step 1: Create Data Source for DataGridView

  1. Create a new Windows Forms application.
  2. Drag and drop the MS DataGridView control from the Toolbox onto your form. From the Properties window, set its Dock property to Fill.
  3. To populate the DataGridView with data, create a data table containing relevant data.

The code below defines a method named ‘CreateDataTable’ to create a data table that contains the country-wise sales information of a company.

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 that _dt is declared as a private global variable of type DataTable.

Step 2: Configure DataGridView control

  1. To bind the grid with data, assign the data table created in the previous section to the DataGridView’s DataSource property.
  2. To display BulletGraph in DataGridView cells, add an additional unbound DataGridViewImageColumn to the DataGridView control.
  3. Optionally, customize the DataGridView’s appearance using appropriate properties of the DataGridView control.
  4. To render the BulletGraph control as an image in the added unbound column ‘SalesV/STarget’ of the DataGridView, subscribe to the CellPainting event of the DataGridView class.

The code below creates a method named ‘SetUpGrid’, to configure the above mentioned settings of the DataGridView control.

Private Sub SetUpGrid()
    DataGridView1.DataSource = _dt
    '非連結DataGridViewImageColumnをDataGridViewに追加します
    'この列は、BulletGraphコントロールを画像として表示するために使用されます 
    Dim dataGridViewImageColumn As DataGridViewImageColumn = New DataGridViewImageColumn()
    dataGridViewImageColumn.Name = "SalesV/STarget"
    DataGridView1.Columns.Add(dataGridViewImageColumn)
    'DataGridViewの追加プロパティを設定します(オプション)
    DataGridView1.ColumnHeadersDefaultCellStyle.Font = New Font(FontFamily.GenericSansSerif, 8.5F, FontStyle.Bold)
    DataGridView1.Font = New Font(FontFamily.GenericSansSerif, 9.0F, FontStyle.Regular)
    DataGridView1.Columns(DataGridView1.Columns.Count - 1).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill

    For i As Integer = 0 To DataGridView1.Rows.Count - 1
        DataGridView1.Rows(i).Height = 40
    Next

    DataGridView1.RowHeadersVisible = False
    DataGridView1.AllowUserToAddRows = False
    DataGridView1.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
    DataGridView1.DefaultCellStyle.Format = "$ #,##0"
    DataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
    DataGridView1.Columns("Sales").HeaderText = "Sales" & vbLf & "(millions)"
    DataGridView1.Columns("Target").HeaderText = "Target" & vbLf & "(millions)"
    DataGridView1.Columns("Bad").HeaderText = "Bad" & vbLf & "(millions)"
    DataGridView1.Columns("Good").HeaderText = "Good" & vbLf & "(millions)"
    'DataGridViewのCellPaintingイベントを購読します
    AddHandler DataGridView1.CellPainting, AddressOf DataGridView1_CellPainting
End Sub
private void SetUpGrid()
{
    dataGridView1.DataSource = _dt;

    //非連結DataGridViewImageColumnをDataGridViewに追加します
    //この列は、BulletGraphコントロールを画像として表示するために使用されます
    DataGridViewImageColumn dataGridViewImageColumn = new DataGridViewImageColumn();
    dataGridViewImageColumn.Name = "SalesV/STarget";
    dataGridView1.Columns.Add(dataGridViewImageColumn);

    //DataGridViewの追加プロパティを設定します(オプション)
    dataGridView1.ColumnHeadersDefaultCellStyle.Font= new Font(FontFamily.GenericSansSerif, 8.5f, FontStyle.Bold);
    dataGridView1.Font = new Font(FontFamily.GenericSansSerif, 9f, FontStyle.Regular);
    dataGridView1.Columns[dataGridView1.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    for (int i = 0; i < dataGridView1.Rows.Count; i++)
    {
        dataGridView1.Rows[i].Height = 40;
    }
    dataGridView1.RowHeadersVisible = false;
    dataGridView1.AllowUserToAddRows = false;
    dataGridView1.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
    dataGridView1.DefaultCellStyle.Format = "$ #,##0";
    dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
    dataGridView1.Columns["Sales"].HeaderText = "Sales\n(millions)";
    dataGridView1.Columns["Target"].HeaderText = "Target\n(millions)";
    dataGridView1.Columns["Bad"].HeaderText = "Bad\n(millions)";
    dataGridView1.Columns["Good"].HeaderText = "Good\n(millions)";

    //DataGridViewのCellPaintingイベントを購読します
    dataGridView1.CellPainting += DataGridView1_CellPainting;
}

Step 3: Configure BulletGraph control

  1. Now create a global instance of the BulletGraph control and configure the general settings of the control. These settings will be applied to all the bullet graphs, which will be rendered in the DataGridView cells.
    Note that although we need to display the BulletGraph in each row of the unbound column, we require only one instance of the BulletGraph control. This is because as we have already rendered the BulletGraph control’s image in the appropriate row, the same BulletGraph instance can be reconfigured to obtain the image for other bullet graphs.

    The code given below defines a method named ‘ConfigureBulletGraph’ to instantiate the BulletGraph control and specify its general properties:

    Private Sub ConfigureBulletGraph()
        'BulletGraphコントロールを構成します
        _bulletGraph = New C1BulletGraph()
        _bulletGraph.Minimum = 0 '定量的スケールの開始値を設定します
        _bulletGraph.Maximum = 500 '定量的スケールの終了値を設定します
        _bulletGraph.GraphScale.ShowLabels = False 'スケールのラベルを非表示にします 
        _bulletGraph.GraphScale.ShowMarks = False 'スケールの目盛りを非表示にします
    
    
        'BulletGraphコントロールをスタイルします
        _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()
    {
        //BulletGraphコントロールを構成します
        _bulletGraph = new C1BulletGraph();
        _bulletGraph.Minimum = 0; //定量的スケールの開始値を設定します
        _bulletGraph.Maximum = 500; //定量的スケールの終了値を設定します
        _bulletGraph.GraphScale.ShowLabels = false; //スケールのラベルを非表示にします
        _bulletGraph.GraphScale.ShowMarks = false; //スケールの目盛りを非表示にします
    
        //BulletGraphコントロールをスタイルします
        _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;
    }
    
    Note:The _bulletGraph is declared as a private global variable of type C1BulletGraph.

Step 4: Rendering BulletGraph In DataGridView

  1. To render the BulletGraph control as an image in the ‘SalesV/STarget’ column of the DataGridView, use the DataGridView’s CellPainting event. In the CellPainting event handler, specify the values for the comparative measure, featured measure and qualitative ranges of the BulletGraph that needs to be drawn. We are setting these values in this event because for each bullet graph that is drawn in a specific row of the unbound column, these values will be different.
  2. Once the BulletGraph is fully configured, retrieve an image of the BulletGraph control with the help of the GetImage method of C1BulletGraph class.
  3. Draw the retrieved image in the DataGridView’s cell using the DrawImage method of Graphics class as shown:
    Private Sub DataGridView1_CellPainting(ByVal sender As Object, ByVal e As DataGridViewCellPaintingEventArgs)
        If e.RowIndex >= 0 AndAlso DataGridView1.Columns(e.ColumnIndex).Name = "SalesV/STarget" Then
            _bulletGraph.Bounds = e.CellBounds
            _bulletGraph.Value = CDbl(_dt.Rows(e.RowIndex)("Sales")) '注目のメジャーの値を設定します
            _bulletGraph.Target = CDbl(_dt.Rows(e.RowIndex)("Target")) '比較メジャーの値を設定します
            _bulletGraph.Bad.To = CDbl(_dt.Rows(e.RowIndex)("Bad")) 'Good範囲の終了値を設定します
            _bulletGraph.Good.To = CDbl(_dt.Rows(e.RowIndex)("Good")) 'Bad範囲の終了値を設定します
    
            'BulletGraph画像を取得し、取得した画像をDataGridViewのセルに描画します
            Dim bulletGraphImg As Image = _bulletGraph.GetImage()
            e.Graphics.DrawImage(bulletGraphImg, e.CellBounds)
            e.Paint(e.CellBounds, DataGridViewPaintParts.Border)
            e.Handled = True
        End If
    End Sub
    
    private void DataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
    {
        if (e.RowIndex >= 0 && dataGridView1.Columns[e.ColumnIndex].Name == "SalesV/STarget")
        {
            _bulletGraph.Bounds = e.CellBounds;
            _bulletGraph.Value = (double)_dt.Rows[e.RowIndex]["Sales"]; //注目のメジャーの値を設定します
            _bulletGraph.Target = (double)_dt.Rows[e.RowIndex]["Target"]; //比較メジャーの値を設定します
            _bulletGraph.Bad.To = (double)_dt.Rows[e.RowIndex]["Bad"]; //Good範囲の終了値を設定します
            _bulletGraph.Good.To = (double)_dt.Rows[e.RowIndex]["Good"]; //Bad範囲の終了値を設定します
    
            //BulletGraph画像を取得し、取得した画像をDataGridViewのセルに描画します
            Image bulletGraphImg = _bulletGraph.GetImage();
            e.Graphics.DrawImage(bulletGraphImg, e.CellBounds);
            e.Paint(e.CellBounds,DataGridViewPaintParts.Border);
            e.Handled = true;
        }
    }
    
  4. 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
        'DataGridViewのDataSourceとして使用されるDataTableを作成します
        CreateDataTable()
        '非連結列をDataGridViewに追加し、DataGridViewプロパティを設定します
        SetUpGrid()
        'BulletGraphコントロールの共通プロパティを設定します
        ConfigureBulletGraph()
    End Sub
    
    private void Form1_Load(object sender, EventArgs e)
    {
        //DataGridViewのDataSourceとして使用されるDataTableを作成します
        CreateDataTable();
    
        //非連結列をDataGridViewに追加し、DataGridViewプロパティを設定します
        SetUpGrid();
    
        //BulletGraphコントロールの共通プロパティを設定します
        ConfigureBulletGraph();
    }
    
  5. Run the application. Observe how the bullet graphs are getting displayed in the ’SalesV/STarget’ column of the DataGridView control.