[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 547
  • Last Modified:

Plot Graph from Textbox

How to plot a graph from a multiple data set that was available from a textbox.  The dataset is separated by line.  

I have this serial port program that read the data which is display on a text box.  The displayed data show records separated by line in a text box.  I need to use that data to plot a graph.  

Please help ASAP.  THank you.

0
nchondro
Asked:
nchondro
  • 7
  • 2
6 Solutions
 
inthedarkCommented:
1)  Add a picture box to your form
Say called picGraph
change the properties so that AutoRedraw is True
change the scalemode to pixels

2) Add some code to convert the text to values:

Dim sLines() as String
sLines = Split(text1, vbcrlf) ' split all lines into an array

' move the text array into a value array
ReDim Values(Ubound(sLines)) As Single

dim lc as long
dim MaxValue  as Single
For Lc = 0 to Ubound(sLines)
    Values(lc) = csng(sLines(lc))
    If Values(lc)>MaxValue Then
        MaxValue = Values(lc) ' knowing the max value may be a help
    End If
Next

3) Plot the points

' Uplift the max value
Maxvalue = MaxValue * 1.1

' Set some margins
TopGap = 100
BottomGap = 100
LeftGap = 100
RightGap = 100
AvailableHeight = picGraph.ScaleHeight - TopGap - BottomGap
BaseLine = AvailableHeight + TopGap
PlotWidth = (picGraph.ScaleWidth - LeftGap - RightGap)/(Ubound(values)-2)
For lc = 0 To Ubound(Values)-1
    X1 = lc * PlotWidth
    Y1 = BaseLine - (AvailableHeight * Values(lc)/MaxValue)
    X2 = (lc+1) * PlotWidth
    Y2 = BaseLine - (AvailableHeight * Values(lc+1)/MaxValue)
    picGraph.Line (x1,y1)-(x2,y2), rgb(0,0,255)
Next Lc

And thats it.

I hope the above code works without too much debugging.
Declare all values as singles except those already declared
X1,x2,y1,y2 should be longs.

Hope this helps:~)


0
 
inthedarkCommented:
Here is the code with a few tweaks:

Private Sub Command1_Click()
Dim sLines() As String
sLines = Split(Text1, vbCrLf) ' split all lines into an array

' move the text array into a value array
ReDim Values(UBound(sLines)) As Single

Dim lc As Long
Dim MaxValue  As Single

Do
    If Len(sLines(UBound(sLines))) = 0 Then
        ReDim Preserve sLines(UBound(sLines) - 1)
    Else
        Exit Do
    End If
Loop

For lc = 0 To UBound(sLines)
    Values(lc) = CSng(sLines(lc))
    If Values(lc) > MaxValue Then
        MaxValue = Values(lc) ' knowing the max value may be a help
    End If
Next


Dim TopGap As Single
Dim BottomGap  As Single
Dim LeftGap  As Single
Dim RightGap  As Single

Dim AvailableHeight As Single
Dim BaseLine As Single
Dim PlotWidth As Single


' Uplift the max value
MaxValue = MaxValue * 1.1

Dim X1 As Long
Dim X2 As Long
Dim y1 As Long
Dim y2 As Long

' Set some margins
TopGap = 100
BottomGap = 100
LeftGap = 100
RightGap = 100
AvailableHeight = picGraph.ScaleHeight - TopGap - BottomGap
BaseLine = AvailableHeight + TopGap
PlotWidth = (picGraph.ScaleWidth - LeftGap - RightGap) / (UBound(Values))
For lc = 0 To UBound(Values) - 1
    X1 = lc * PlotWidth + LeftGap
    y1 = BaseLine - (AvailableHeight * Values(lc) / MaxValue)
    X2 = (lc + 1) * PlotWidth + LeftGap
    y2 = BaseLine - (AvailableHeight * Values(lc + 1) / MaxValue)
    picGraph.Line (X1, y1)-(X2, y2), RGB(0, 0, 255)
Next lc


End Sub
0
 
inthedarkCommented:
After you print the graph you can add the following for cometic affect

' box round graph
picGraph.Line (LeftGap, TopGap)-Step(picGraph.ScaleWidth - LeftGap - RightGap, AvailableHeight), RGB(255, 0, 0), B
Dim hscale As Single

' draw hlines
hscale = MaxValue * 0.1
Do While hscale < MaxValue
    y1 = BaseLine - (AvailableHeight * hscale / MaxValue)
    picGraph.Line (LeftGap + 1, y1)-(picGraph.ScaleWidth - RightGap - 1, y1), RGB(0, 255, 0)
    hscale = hscale + MaxValue * 0.1
Loop
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
inthedarkCommented:
if you want some spots.....

For lc = 0 To UBound(Values) - 1
    X1 = lc * PlotWidth + LeftGap
    y1 = BaseLine - (AvailableHeight * Values(lc) / MaxValue)
    X2 = (lc + 1) * PlotWidth + LeftGap
    y2 = BaseLine - (AvailableHeight * Values(lc + 1) / MaxValue)
    picGraph.Line (X1, y1)-(X2, y2), RGB(0, 0, 255)
    picGraph.Circle (X1, y1), 2, RGB(100, 100, 0) 'add this line
Next lc
picGraph.Circle (X2, y2), 2, RGB(100, 100, 0) ' and this
0
 
nchondroAuthor Commented:
Thanks for the code, but how can I add additional cosmetic such as the X-Bar title, Y-Bar title, plus their range.  Plus a way so I can change the default starting point instead of 0 but other number.  Currently, I saw that the graph kinda crunch small in the middle can we make it bigger?  

Thanks a lot.
0
 
inthedarkCommented:
Hi nchondro, I knew you would ask these questions which is why I added margins.

In the code you can see how the program scans for the highest value, you can do the same for the lowest value.

In your case you are probably doing some kind of QA on a device so you know then max and min values that you are expecting. So it would be better to set them manually.

Private Sub Command1_Click()

Dim sLines() As String
sLines = Split(Text1, vbCrLf) ' split all lines into an array

' move the text array into a value array


Dim lc As Long
Dim MaxValue  As Single
Dim MinValue As Single

Do
    If Len(sLines(UBound(sLines))) = 0 Then
        ReDim Preserve sLines(UBound(sLines) - 1)
    Else
        Exit Do
    End If
Loop

ReDim Values(UBound(sLines)) As Single ' this was moved

MinValue = 9999999999#
For lc = 0 To UBound(sLines)
    Values(lc) = CSng(sLines(lc))
    If Values(lc) > MaxValue Then
        MaxValue = Values(lc) ' knowing the max value may be a help
    End If
    If Values(lc) < MinValue Then
        MinValue = Values(lc)
    End If
Next


Dim TopGap As Single
Dim BottomGap  As Single
Dim LeftGap  As Single
Dim RightGap  As Single

Dim AvailableHeight As Single
Dim BaseLine As Single
Dim PlotWidth As Single


' Uplift the max value
MaxValue = MaxValue * 1.1

' drop then minvalue
MinValue = MinValue * 0.9

' Or set the max/min value manually
MaxValue = 100
MinValue = 50

Dim Range As Single

Range = MaxValue - MinValue


Dim X1 As Long
Dim X2 As Long
Dim y1 As Long
Dim y2 As Long

' Set some margins
TopGap = 30
BottomGap = 25
LeftGap = 35
RightGap = 10

AvailableHeight = picGraph.ScaleHeight - TopGap - BottomGap
BaseLine = AvailableHeight + TopGap
PlotWidth = (picGraph.ScaleWidth - LeftGap - RightGap) / (UBound(Values))

For lc = 0 To UBound(Values) - 1
    X1 = lc * PlotWidth + LeftGap
    y1 = BaseLine - (AvailableHeight * (Values(lc) - MinValue) / Range)
    X2 = (lc + 1) * PlotWidth + LeftGap
    y2 = BaseLine - (AvailableHeight * (Values(lc + 1) - MinValue) / Range)
    picGraph.Line (X1, y1)-(X2, y2), RGB(0, 0, 255)
    picGraph.Circle (X1, y1), 2, RGB(100, 100, 0) 'add this line
Next lc

picGraph.Circle (X2, y2), 2, RGB(100, 100, 0) ' and this
' box round graph
picGraph.Line (LeftGap, TopGap)-Step(picGraph.ScaleWidth - LeftGap - RightGap, AvailableHeight), RGB(255, 0, 0), B
Dim hscale As Single

' draw hlines

Dim ScaleIncrement As Single

ScaleIncrement = MaxValue * 0.1

' or set a manual increment
ScaleIncrement = 10

hscale = MinValue + ScaleIncrement
picGraph.ForeColor = RGB(0, 0, 0)
Dim sText As String
For hscale = MinValue To MaxValue Step ScaleIncrement
   
    y1 = BaseLine - (AvailableHeight * (hscale - MinValue) / Range)
   
    ' minvalue is the bottom of the graph
    ' maxvalue is the top og graph
    ' so we don't need mim & max just the lines between
   
    If hscale > MinValue And hscale < MaxValue Then
        picGraph.Line (LeftGap + 1, y1)-(picGraph.ScaleWidth - RightGap - 1, y1), RGB(0, 255, 0)
    End If
       
    sText = CStr(hscale)
    picGraph.CurrentY = y1 - (picGraph.TextHeight(sText) * 0.5)
    picGraph.CurrentX = LeftGap - picGraph.TextWidth(sText) - 2 ' reduce by a small gap
    picGraph.Print sText;
Next

' Now do a title
sText = "Time vs Value"
picGraph.CurrentX = (picGraph.ScaleWidth * 0.5) - (picGraph.TextWidth(sText) * 0.5)
picGraph.CurrentY = 2
picGraph.Print sText;

' x Comment
sText = "Time"
picGraph.CurrentX = (picGraph.ScaleWidth * 0.5) - (picGraph.TextWidth(sText) * 0.5)
picGraph.CurrentY = picGraph.ScaleHeight - picGraph.TextHeight(sText)
picGraph.Print sText;

' y Comment
sText = "Values"
Dim ypos As Long

ypos = picGraph.ScaleHeight * 0.5 - (picGraph.TextHeight(sText) * Len(sText) * 0.5)
For lc = 1 To Len(sText)
    picGraph.CurrentX = 2
    picGraph.CurrentY = ypos
    picGraph.Print Mid(sText, lc, 1);
    ypos = ypos + picGraph.TextHeight(Mid(sText, lc, 1))
Next

End Sub




0
 
inthedarkCommented:
You can also add affects like text shadow

' Now do a title
dim StoreSize as single

storesize=picGraph.font.size

picGraph.Font.Size = 18 ' increate font size
sText = "Time vs Value"
Dim lx As Long
Dim ly As Long
lx = (picGraph.ScaleWidth * 0.5) - (picGraph.TextWidth(sText) * 0.5) + 2
ly = 2
picGraph.ForeColor = RGB(5, 5, 10)
picGraph.CurrentX = lx + 2 ' movedown a bit
picGraph.CurrentY = ly + 2
picGraph.Print sText;

picGraph.ForeColor = RGB(0, 0, 255)
picGraph.CurrentX = lx
picGraph.CurrentY = ly
picGraph.Print sText;

picGraph.font.size = storesize
0
 
inthedarkCommented:
Autoscaling.......

If you don't know what type of data you are getting then after you calculate min/max values you can autoscale like this:


sText = CStr(MinValue)
If Len(sText) > 1 Then
    sText = Left(sText, 1) + String(Len(sText) - 1, "0")
    MinValue = Val(sText)
End If

sText = CStr(MaxValue)
If Len(sText) > 1 Then
    sText = CStr(Val(Left(sText, 1)) + 1) + String(Len(sText) - 1, "0")
    MaxValue = Val(sText)
End If

Range = MaxValue - MinValue
ScaleIncrement = Int(Range / 10) ' /5 for smaller graphs or /20 for very large graphs


Another tip, if your device provides small decimal values then convert all of the points by dividing them by the minimum value. The graph should look the same.
0
 
nchondroAuthor Commented:
Thanks a lot for the help. You've been very helpful  You're the best.  :)
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

  • 7
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now