Solved

Plot Graph from Textbox

Posted on 2003-12-11
9
532 Views
Last Modified: 2010-05-01
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
Comment
Question by:nchondro
  • 7
  • 2
9 Comments
 
LVL 17

Expert Comment

by:inthedark
Comment Utility
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
 
LVL 17

Accepted Solution

by:
inthedark earned 500 total points
Comment Utility
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
 
LVL 17

Assisted Solution

by:inthedark
inthedark earned 500 total points
Comment Utility
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
 
LVL 17

Assisted Solution

by:inthedark
inthedark earned 500 total points
Comment Utility
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
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 3

Author Comment

by:nchondro
Comment Utility
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
 
LVL 17

Assisted Solution

by:inthedark
inthedark earned 500 total points
Comment Utility
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
 
LVL 17

Assisted Solution

by:inthedark
inthedark earned 500 total points
Comment Utility
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
 
LVL 17

Assisted Solution

by:inthedark
inthedark earned 500 total points
Comment Utility
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
 
LVL 3

Author Comment

by:nchondro
Comment Utility
Thanks a lot for the help. You've been very helpful  You're the best.  :)
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now