i need on how to draw a simple bar chat on my form like the picture below. for A B C D. Each time it draw at random. all % should be equal to 100%.

Recommended Answers

All 4 Replies

Im confused. Is the thumbnail a picture of your program or is that what you want to achieve?

Also are you using a random integer generator to create the values?

thanks for your reply. thats what i want to achieve . though am able to draw something similar with the below code. what i need now is how to generate four random numbers that will be equall to 100 and assign each to 1 data.

Dim Red As Brush = Brushes.Red
        Dim Green As Brush = Brushes.Green
        Dim Blue As Brush = Brushes.Blue
        Dim Brown As Brush = Brushes.Brown
        Dim BlueViolet As Brush = Brushes.BlueViolet
        Dim DarkMagenta As Brush = Brushes.DarkMagenta
        Dim White As Brush = Brushes.White

        Dim Black As Pen = New Pen(Color.Black, 3)
        Dim total As Decimal
        Dim data(4) As Decimal
        Dim percentage(4) As Decimal

        data(0) = 20
        data(1) = 10
        data(2) = 40
        data(3) = 30


        total = data(0) + data(1) + data(2) + data(3)
        percentage(0) = data(0) / total
        percentage(1) = data(1) / total
        percentage(2) = data(2) / total
        percentage(3) = data(3) / total
       

        Dim BChart As Graphics = PictureBox5.CreateGraphics()

        PictureBox5.Refresh()
        BChart.FillRectangle(Red, 30, (150 - (300 * percentage(0))), 30, 300 * percentage(0))
        BChart.DrawString("", New Font("Arial", 10), Red, New Point(20, 150))
        BChart.DrawString(data(0) & "%", New Font("Arial", 8, FontStyle.Bold), White, New Point(36, 130))


        BChart.FillRectangle(Green, 80, (150 - (300 * percentage(1))), 30, 300 * percentage(1))
        BChart.DrawString("", New Font("Arial", 10), Green, New Point(70, 150))
        BChart.DrawString(data(1) & "%", New Font("Arial", 8, FontStyle.Bold), White, New Point(86, 130))

        BChart.FillRectangle(Blue, 130, (150 - (300 * percentage(2))), 30, 300 * percentage(2))
        BChart.DrawString("", New Font("Arial", 10), Blue, New Point(140, 150))
        BChart.DrawString(data(2) & "%", New Font("Arial", 8, FontStyle.Bold), White, New Point(136, 130))

        BChart.FillRectangle(Brown, 180, (150 - (300 * percentage(3))), 30, 300 * percentage(3))
        BChart.DrawString("", New Font("Arial", 10), Brown, New Point(198, 150))
        BChart.DrawString(data(3) & "%", New Font("Arial", 8, FontStyle.Bold), White, New Point(186, 130))


        BChart.Dispose()
Member Avatar for Unhnd_Exception

Here's an example.

Its relatively debugged.

Maybe you can at least get a few things out of it.

Attached is the image output of this code.

Add a picturebox and a button to a form and paste this code.

Imports System.Drawing.Drawing2D

Public Class FormBarChart

    'Images for the background and bar
    Private BitmapBar As Bitmap
    Private BitmapBackground As Bitmap

    'Total number of bars
    Private Const Columns As Integer = 5
    'A fixed amount of spacing
    Private Const ColumnSpacing As Integer = 20
    'The height of the two border lines
    Private Const HorizontalLineHeight As Integer = 3

    'Variables to hold precalculated bar dimensions
    Private ColumnWidth As Integer
    Private ColumnHeight As Integer
    Private ColumnBottom As Integer

    'The fonts for the letters and percentages
    Private PercentageFont As Font
    Private LetterFont As Font

    'Variables to hold the percentages and letters
    Private BarValues(Columns - 1) As Double
    Private BarNames(Columns - 1) As String

    'Format object to draw strings centered
    Private StringFormat As StringFormat

    Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.


        'Create a letter for each column
        'Chr(65) = A so Chr(65 + 1) = B and So on.
        For i = 0 To UBound(BarNames)
            BarNames(i) = CStr(Chr(65 + i))
        Next

        'Intialize a String Format object to center drawn text
        'here and in the picture boxes paint event.
        StringFormat = New StringFormat
        StringFormat.Alignment = StringAlignment.Center
        StringFormat.LineAlignment = StringAlignment.Center
        StringFormat.FormatFlags = StringFormatFlags.NoWrap Or StringFormatFlags.NoClip

        'Initialize the Fonts
        PercentageFont = New Font("Times New Roman", 12.0!)
        LetterFont = New Font("Times New Roman", 14.0!)

        'Initialize the bar chart variables and bitmaps
        'Bitmap and fonts
        InializeBarChart()

        'Set the initial values of the bars
        ComputeBarValues()

    End Sub

    Private Sub InializeBarChart()
        'Calculate the bar widths height and the column bottom
        'the column bottom will be the picturebox's height 
        'minus the height of the letter font minus the 2 
        'border lines.

        'Set the minimum width of the picturebox so the bar charts 
        'will be at least 1 pixel.
        PictureBox1.MinimumSize = New Size(Columns + ColumnSpacing * (Columns + 1), 100)


        ColumnWidth = (PictureBox1.Width - ((Columns + 1) * ColumnSpacing)) / Columns

        If BitmapBar IsNot Nothing Then BitmapBar.Dispose()
        If BitmapBackground IsNot Nothing Then BitmapBackground.Dispose()

        BitmapBar = New Bitmap(ColumnWidth, 50)
        BitmapBackground = New Bitmap(PictureBox1.Width, PictureBox1.Height)

        ColumnHeight = PictureBox1.Height - PercentageFont.Height - LetterFont.Height - (HorizontalLineHeight * 2)
        ColumnBottom = PictureBox1.Height - LetterFont.Height - (HorizontalLineHeight * 2)

        CreateBackgroundImage()
        CreateBarImage()

    End Sub

    Private Sub CreateBackgroundImage()
        '***************************
        '
        'Draw the background image
        'This will consist of a navy background
        'The letters for each columns
        'and a silver and black border
        '
        '***************************
        Dim BackgroundGraphics As Graphics = Graphics.FromImage(BitmapBackground)

        'Fill the background
        BackgroundGraphics.Clear(Color.Navy)

        BackgroundGraphics.FillRectangle(Brushes.Silver, New Rectangle(0, PictureBox1.Height - LetterFont.Height - (HorizontalLineHeight * 2), PictureBox1.Width, HorizontalLineHeight))
        BackgroundGraphics.FillRectangle(Brushes.Black, New Rectangle(0, PictureBox1.Height - LetterFont.Height - HorizontalLineHeight, PictureBox1.Width, HorizontalLineHeight))

        'Create a rectangle the size of the column widths and the height
        'of the Letter font and position it starting at the column spacing
        Dim LetterRectangle As New Rectangle(ColumnSpacing / 2, PictureBox1.Height - LetterFont.Height, ColumnWidth + ColumnSpacing, LetterFont.Height)

        'Draw each Letter
        For i = 0 To UBound(BarNames)
            BackgroundGraphics.DrawString(BarNames(i), LetterFont, Brushes.White, LetterRectangle, StringFormat)
            'Shift the rectangle over the width of a column and spacing
            LetterRectangle.Offset(ColumnSpacing + ColumnWidth, 0)
        Next

        PictureBox1.BackgroundImage = BitmapBackground

        BackgroundGraphics.Dispose()

        'Background image is now complete and set as the Picture Boxes
        'Background
    End Sub

    Private Sub CreateBarImage()
        '*****************************
        '
        'Create a Bitmap for the Bar
        'The width of the bitmap will be the column width
        'The height will be an arbitrary value of 50
        'This image will be drawn strecthed up and down in the
        'Picturebox's paint event.
        '
        '****************************
        Dim BarGraphics As Graphics = Graphics.FromImage(BitmapBar)
        Dim HalfRectangle As New Rectangle(0, 0, BitmapBar.Width, BitmapBar.Height)
        Dim LinearBrush As New LinearGradientBrush(HalfRectangle, Color.Gold, Color.White, LinearGradientMode.Horizontal)
        Dim LinearBlend As New Blend

        'Set the blend factors and positions
        'These values where actually copied from a
        'code example in the MSDN library.  They worked
        'well so didn't change
        LinearBlend.Factors = New Single() {0.2F, 0.4F, 0.8F, 0.8F, 0.4F, 0.2F}
        LinearBlend.Positions = New Single() {0.0F, 0.2F, 0.4F, 0.6F, 0.8F, 1.0F}

        LinearBrush.Blend = LinearBlend

        'Draw the bar with the custom gradient
        BarGraphics.FillRectangle(LinearBrush, HalfRectangle)

        BarGraphics.Dispose()
        LinearBrush.Dispose()

        'The bitmap representing the bar is complete and ready to be drawn.
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        ComputeBarValues()

        'Redraw the bars
        PictureBox1.Invalidate()
    End Sub

    Private Sub ComputeBarValues()
        'Calculate a random value for each bar.
        'The total percentage will be equal to 100.

        Dim TotalPercentage As Double

        For i = 0 To UBound(BarValues) - 1
            BarValues(i) = Math.Round(Rnd() * (1 - TotalPercentage), 2)
            TotalPercentage += BarValues(i)
        Next

        BarValues(UBound(BarValues)) = Math.Round(1 - TotalPercentage, 2)

        'Each bar value will now be between 0 and 1 and the sum of all
        'will be 1
    End Sub

    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint

        Dim X, Y As Integer
        Dim BarHeight As Integer
        Dim HalfSpacing = ColumnSpacing / 2

        'set the variable so the image is not drawn 
        'with any aliasing and will hit at the right pixel
        'comment them out to see what happens
        e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor
        e.Graphics.PixelOffsetMode = PixelOffsetMode.Half

        'start the x at the spacing
        X = ColumnSpacing

        For i = 0 To UBound(BarValues)

            'reset the y value
            Y = 0

            'calculate the height of the bar based on the percentage
            BarHeight = CInt(ColumnHeight * BarValues(i))

            'draw the percentage above the bar.
            'ToString P will show a % 
            'PO will round to 0 with a %
            e.Graphics.DrawString(BarValues(i).ToString("P0"), PercentageFont, Brushes.White, New Rectangle(X - HalfSpacing, ColumnBottom - BarHeight - PercentageFont.Height, ColumnWidth + ColumnSpacing, PercentageFont.Height), StringFormat)

            'Draw the bar at the height with the bar image
            'created.
            e.Graphics.DrawImage(BitmapBar, X, ColumnBottom - BarHeight, ColumnWidth, BarHeight)

            'Slide the x position over the width of the column
            'and spacing
            X += ColumnWidth + ColumnSpacing
        Next

    End Sub

    Private Sub PictureBox1_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.SizeChanged
        'if the form is not created then don't initialize anything
        'it will be initialized in the constructor
        If Not Me.Created Then Exit Sub

        'Resize the bar chart.
        'If the picture box is going to be fixed this
        'will do nothing.

        'If its docked or anchored then the bar chart
        'will resize dynamically.
        InializeBarChart()

    End Sub

End Class
commented: great help +1

wow...thanks a million. i figured out that the initial values of the bar is same. how do i randomize the initial values. because i have this on timer tick event. not a button.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.