Imports System.Drawing
Imports System.Windows.Forms
Imports System.ComponentModel
Imports System.Collections

Public Class BarPlot
  Inherits Form
  Private xmin As Single, xmax As Single
  Protected xfactor As Single, xpmin As Single, xpmax As Single
  Protected ymin As Single, ymax As Single
  Protected yfactor As Single, ypmin As Single, ypmax As Single
  Private w As Integer, h As Integer
  Private colors As ArrayList
  Protected x() As Single, y() As Single
  Protected bPen As Pen
  Protected hasData As Boolean
  Const max As Single = 1.0E+38
  '-----    
  Public Sub New()
    MyBase.New()
    BarPlot = Me
    InitializeComponent()
  End Sub
  '-----    
  Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    If disposing Then
      If Not (components Is Nothing) Then
        components.Dispose()
      End If
    End If
    MyBase.Dispose(disposing)
  End Sub
  '----- 
  Public Sub setPenColor(ByVal c As Color)
    bPen = New Pen(c)
  End Sub
  '----- 
  Private Sub findBounds()
    Dim i As Integer
    xmin = max
    xmax = -max
    ymin = max
    ymax = -max

    For i = 0 To x.Length - 1
      If x(i) > xmax Then xmax = x(i)
      If x(i) < xmin Then xmin = x(i)
      If y(i) > ymax Then ymax = y(i)
      If y(i) < ymin Then ymin = y(i)
    Next i

  End Sub
  '-----    
  Public Overridable Sub setPlotBounds()
    findBounds()
    'Wylicz współczynniki przeskalowania
    h = Pic.Height
    w = Pic.Width
    xfactor = 0.8F * w / (xmax - xmin)
    xpmin = 0.05F * w
    xpmax = w - xpmin

    yfactor = 0.9F * h / (ymax - ymin)
    ypmin = 0.05F * h
    ypmax = h - ypmin
    'Utwórz tablicę kolorów dla słupków wykresu
    colors = New ArrayList()
    colors.Add(New SolidBrush(Color.Red))
    colors.Add(New SolidBrush(Color.Green))
    colors.Add(New SolidBrush(Color.Blue))
    colors.Add(New SolidBrush(Color.Magenta))
    colors.Add(New SolidBrush(Color.Yellow))
  End Sub
  '-----    
  Public Function calcx(ByVal xp As Single) As Integer
    Dim ix As Integer
    ix = ((xp - xmin) * xfactor + xpmin)
    Return ix
  End Function
  '-----    
  Public Function calcy(ByVal yp As Single) As Integer
    Dim iy As Integer
    yp = ((yp - ymin) * yfactor)
    iy = h - (ypmax - yp)
    Return iy
  End Function
  '-----    
  Public Sub plot(ByVal xp() As Single, ByVal yp() As Single)
    x = xp
    y = yp
    setPlotBounds()    'Wylicz współczynniki przeskalowania
    hasData = True
    Pic.Refresh()
  End Sub
#Region " Windows Form Designer generated code "

  'Required by the Windows Form Designer
  Private components As System.ComponentModel.Container
  Protected WithEvents Pic As System.Windows.Forms.PictureBox

  Dim WithEvents BarPlot As System.Windows.Forms.Form

  'NOTE: The following procedure is required by the Windows Form Designer
  'It can be modified using the Windows Form Designer.  
  'Do not modify it using the code editor.
  Private Sub InitializeComponent()
    Me.Pic = New System.Windows.Forms.PictureBox()
    Me.SuspendLayout()
    '
    'Pic
    '
    Me.Pic.BackColor = System.Drawing.SystemColors.ActiveCaptionText
    Me.Pic.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
    Me.Pic.Location = New System.Drawing.Point(8, 8)
    Me.Pic.Name = "Pic"
    Me.Pic.Size = New System.Drawing.Size(280, 256)
    Me.Pic.TabIndex = 0
    Me.Pic.TabStop = False
    '
    'BarPlot
    '
    Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
    Me.ClientSize = New System.Drawing.Size(296, 269)
    Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.Pic})
    Me.Name = "BarPlot"
    Me.Text = "BarPlot"
    Me.ResumeLayout(False)

  End Sub

#End Region
  '-----    
  Public Overridable Sub Pic_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Pic.Paint
    Dim g As Graphics = e.Graphics
    Dim i, ix, iy As Integer
    Dim br As Brush
    If hasData Then
      For i = 0 To x.Length - 1
        ix = calcx(x(i))
        iy = calcy(y(i))
        br = CType(colors(i), Brush)
        g.FillRectangle(br, ix, h - iy, 20, iy)
      Next
    End If
  End Sub

End Class
