May 04, 2024, 01:35:38 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Graphs and calculating zero position

Started by Andy, April 21, 2015, 01:40:34 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Andy

Hi,

I'm trying to draw a line in a graph at the zero value position.

My maths are probably not the best, can anyone help me calculate where the zero line show be drawn.

In the attached graph:

The range is 255, from +215 to -40.

The vertical bar is a rectangle 150 in depth (so a scale to 1.5 for values) and starts at 20 down.

The zero line should be between +51 and -40, but I just can't seem to calculate it's position correctly.

Can anyone help please...

Thanks,
Andy.



Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Egil

Each pixel in the y-axis of your graph has a value of 150/255.

So Zero is 40 such units up from the bottom: (150/255) * 40 = 23.529.  Which  rounds to 24, since you can not draw decomals of pixels.

Since I assume the upper left of your drawing has the coordinate 0,0 , the line representing zero should start at coordinate 0,126.  


Good luck!

Egil
Support Amateur Radio  -  Have a ham  for dinner!

Andy

Thanks Egil - nice to chat to you again - hope things are ok?

The value 126 was what I was expecting, but when I use the formula:

       SETPRECISION 4
       int xxxx = (150.00 / 255.00) * LeastValue
       SETPRECISION 0

       RECT dy7,10,170-xxxx,10,2, rgb(0,0,0), rgb(0,0,0)
       SETCAPTION dy7, STR$(xxxx)

      Where LeastValue = 40.00

The windows caption does say 24 (23 point something rounded up)
and yet the line is still "just" under the +51 marker.

I know for a fact the first value on the drawn graph is 42 - so I know that's correctly drawn.

I would expect Zero to be somewhere (but not exactly half way) between +51 and -40, and certainly under the first drawn value.

Please Note - I start at 20 down, so the bottom of the graph is not at 150, but 170.

See attached screenshot.

Any ideas?

Thanks,
Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

billhsln

How are the other lines calculated?

Bill
When all else fails, get a bigger hammer.

LarryMc

QuoteI know for a fact the first value on the drawn graph is 42 - so I know that's correctly drawn.
Maybe/maybe not.

Looking at your graph the range is from -40 to 215 and you have  divided it into 5 sections

-40 to 51  = 91 units
51 to 102  = 51 "
102 to 153 = 51 "
153 to 204 = 51  "
204 to 215 = 11   "

so you have your y axis labelled wrong
it should be
215
164
113
62
11
-40

and "0" is being drawn under your "51" marker which is really 11.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Egil

April 21, 2015, 11:22:56 AM #5 Last Edit: April 21, 2015, 02:10:48 PM by Egil
I checked my laptop, and found some code I had to modify slightly to match your needs. Maybe you can use it?

Egil


'
' graph.iwb
'
AutoDefine "Off"
def win:window 
def run,value,maxval,offset,g_height,gval:int 

OpenWindow win,0,0,600,400,@minbox,0,"  Andy's Graph",&messages 


maxval   = 150
g_height = 170
offset   = -40

' This sub an also be used to make bargraph poles:
Pole(win,150,200,270,g_height,128,128,128,250,250,250)


value = -40
GLine(win,151,200,268,value+abs(offset),maxval,offset,200,200,200)

value = 11
GLine(win,151,200,268,value+abs(offset),maxval,offset,200,200,200)

value = 62
GLine(win,151,200,268,value+abs(offset),maxval,offset,200,200,200)

value = 113
GLine(win,151,200,268,value+abs(offset),maxval,offset,200,200,200)

value = 164
GLine(win,151,200,268,value+abs(offset),maxval,offset,200,200,200)

value = 215
GLine(win,151,200,268,value+abs(offset),maxval,offset,200,200,200)


Pole(win,155,200,4,100,128,128,128,128,222,128)
Pole(win,161,200,4,80,128,128,128,128,222,128)

run = 1 
WAITUNTIL run = 0 
CLOSEWINDOW win
END 

'
SUB messages(),int
'---------------------------------------------------------------------------------------------
' Main Loop
'---------------------------------------------------------------------------------------------
SELECT @class

CASE @idcreate 
centerwindow win
CASE @idclosewindow 
run = 0 
ENDSELECT 
RETURN  0
EndSub
'---------------------------------------------------------------------------------------------


'
sub GLine(window wnd,int x,int y,int xlen,int value,int max,int offset,int R,int G,int B)
'---------------------------------------------------------------------------------------------
' HOW TO USE:
'   x,y     = start x,y
'   height = Height of plot area
'   value  = value to plot
'   max    = Max legal graph value
'   offset = Calibration offset
'   R,G,B  = line color
'---------------------------------------------------------------------------------------------
int calc_val

calc_val = offset +y - (value * max/255)   
LINE wnd, x, calc_val-offset, x+xlen, calc_val-offset, RGB(R,G,B)
setfont(wnd, "Tahoma",6,400)
move wnd,x-21,calc_val-offset-5
print wnd,str$(value+offset)
RETURN
ENDSUB
'---------------------------------------------------------------------------------------------

'
'---------------------------------------------------------------------------------------------
' HOW TO USE:
'   x, y   = position
'   width  = bar width in pixels
'   height = bar height in pixels
'   br, bg, bb = bar border color
'   fr, fg, fb = bar fill color
'---------------------------------------------------------------------------------------------
SUB Pole(window wnd,int x,int y,int width,int height,int br,int bg,int bb,int fr,int fg,int fb)
Rect wnd,x,y-height,width,height,RGB(br,bg,bb),RGB(fr,fg,fb)
RETURN
ENDSUB
'---------------------------------------------------------------------------------------------



EDIT: I have been waiting for some people to arrive for several hours tonight. So had time to tidy up the code a little, and reposted it.
         The Pole sub can easily be modified to suit the calibration of the graph.

Good luck!
Support Amateur Radio  -  Have a ham  for dinner!

billhsln

April 21, 2015, 02:15:52 PM #6 Last Edit: April 21, 2015, 02:59:59 PM by billhsln
Sorry, I should have said Egil's code.

***LarryMc's code was a little too hard for me to follow, so I modified it so its calculations can be done easier.  I still used what he started with, but removed lots of the calculations.  This should be easier to deal with.

'
' graph.iwb
'
AutoDefine "Off"
def win:window  
def run,value,maxval,offset,g_height,g_width:int  
def xs,ys,barwidth,barheight,i:int

OpenWindow win,0,0,600,400,@minbox,0,"Graph",&messages  

xs = 30
ys = 350

' Drawing background rectangle using bargraph code:
Pole(win,xs,ys,540,330,128,128,128,250,250,250)

maxval   = 300
g_height = 300
g_width  = 540
offset   = -40

setfont(win, "Tahoma",6,400)
FOR i = 1 to 20
move win,xs+10+(20*(i-1)),ys+3
print win,str$(i)
NEXT i

value = -40
CLine(win,xs,ys,g_height,g_width,value,maxval,offset,200,200,200)

value = 0
CLine(win,xs,ys,g_height,g_width,value,maxval,offset,200,200,200)

value = 50
CLine(win,xs,ys,g_height,g_width,value,maxval,offset,200,200,200)

value = 100
CLine(win,xs,ys,g_height,g_width,value,maxval,offset,200,200,200)

value = 150
CLine(win,xs,ys,g_height,g_width,value,maxval,offset,200,200,200)

value = 200
CLine(win,xs,ys,g_height,g_width,value,maxval,offset,200,200,200)

value = 250
CLine(win,xs,ys,g_height,g_width,value,maxval,offset,200,200,200)

barwidth = 10
barheight = 100
xs += 10
ys -= 40
Pole(win,xs,ys,barwidth,barheight,128,222,128,128,222,128)

barwidth = 10
barheight = -40
xs += 20
Pole(win,xs,ys,barwidth,barheight,128,222,128,128,222,248)

barheight = 200
xs += 20
Pole(win,xs,ys,barwidth,barheight,128,222,128,228,222,228)

run = 1  
WAITUNTIL run = 0  
CLOSEWINDOW win
END  

'
SUB messages(),int
'---------------------------------------------------------------------------------------------
' Main Loop
'---------------------------------------------------------------------------------------------
SELECT @class

CASE @idcreate  
centerwindow win
CASE @idclosewindow  
run = 0  
ENDSELECT  
RETURN  0
EndSub
'---------------------------------------------------------------------------------------------

'
sub CLine(window wnd,int x,int y,int height,int xlen,int value,int max,int offset,int R,int G,int B)
'---------------------------------------------------------------------------------------------
' HOW TO USE:
'   x, y   = position
'   width  = bar width in pixels
'   height = bar height in pixels
'   br, bg, bb = bar border color
'   fr, fg, fb = bar fill color
'---------------------------------------------------------------------------------------------
int calc_val

'calc_val = offset + y - (value * max/255)  '- graph_height
calc_val = y - value + offset
'LINE wnd, x, calc_val-offset, x + xlen, calc_val-offset, RGB(R,G,B)
LINE wnd, x, calc_val, x + xlen, calc_val, RGB(R,G,B)
setfont(wnd, "Tahoma",6,400)
move wnd,x-18,calc_val-5
print wnd,str$(value)
RETURN
ENDSUB
'---------------------------------------------------------------------------------------------

'
SUB Pole(window wnd,int x,int y,int width,int height,int br,int bg,int bb,int fr,int fg,int fb)
'---------------------------------------------------------------------------------------------
' HOW TO USE:
'   x, y   = position
'   width  = bar width in pixels
'   height = bar height in pixels
'   br, bg, bb = bar border color
'   fr, fg, fb = bar fill color
'---------------------------------------------------------------------------------------------
Rect wnd,x,y-height,width,height,RGB(br,bg,bb),RGB(fr,fg,fb)
RETURN
ENDSUB
'---------------------------------------------------------------------------------------------
'


Using the above code should be a little easier to modify.  I was having problems getting things to line up.  Changing the code made it easier for me to follow.

Bill
When all else fails, get a bigger hammer.

LarryMc

Quote from: billhsln on April 21, 2015, 02:15:52 PM
LarryMc's code was a little too hard for me to follow,
wasn't my code Bill ;)
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Egil

I like the way you think Bill. So going to save your code in my snippets collection.

In the meantime I have updated the bar-pole code, so it will accept real values passed to it.
The example use the dimensions given by Andy.

So now Andy can choose which method suits him best. :D

Now the family members I have waited for all night, have arrived, so better stop coding.


Egil


'
' graph.iwb
'
AutoDefine "Off"
def win:window 
def run,value,maxval,offset,g_height:int 

OpenWindow win,0,0,600,400,@minbox,0,"  Andy's Graph",&messages 


maxval   = 150
g_height = 170
offset   = -40

' This sub an also be used to make bargraph poles:
Pole(win,150,200,270,g_height,128,128,128,250,250,250)

' draw calibration lines
value = -40
value = value+abs(offset)
GLine(win,151,200,268,value,maxval,offset,200,200,200)

value = 11
value = value+abs(offset)
GLine(win,151,200,268,value,maxval,offset,200,200,200)

value = 62
value = value+abs(offset)
GLine(win,151,200,268,value,maxval,offset,200,200,200)

value = 113
value = value+abs(offset)
GLine(win,151,200,268,value,maxval,offset,200,200,200)

value = 164
value = value+abs(offset)
GLine(win,151,200,268,value,maxval,offset,200,200,200)

value = 215
value = value+abs(offset)
GLine(win,151,200,268,value,maxval,offset,200,200,200)


'Poles
value=11
value = value+abs(offset)
GPole(win,155,200,4,value,maxval,offset,128,128,128,128,222,128)

value=113
value = value+abs(offset)
GPole(win,161,200,4,value,maxval,offset,128,128,128,128,222,128)

value=164
value = value+abs(offset)
GPole(win,167,200,4,value,maxval,offset,128,128,128,255,128,128)

value=62
value = value+abs(offset)
GPole(win,174,200,4,value,maxval,offset,128,128,128,255,128,128)

value=215
value = value+abs(offset)
GPole(win,180,200,4,value,maxval,offset,128,128,128,255,128,128)

run = 1 
WAITUNTIL run = 0 
CLOSEWINDOW win
END 

'
SUB messages(),int
'---------------------------------------------------------------------------------------------
' Main Loop
'---------------------------------------------------------------------------------------------
SELECT @class

CASE @idcreate 
centerwindow win
CASE @idclosewindow 
run = 0 
ENDSELECT 
RETURN  0
EndSub
'---------------------------------------------------------------------------------------------


'
'---------------------------------------------------------------------------------------------
' HOW TO USE:
'   x, y   = position
'   width  = bar width in pixels
'   value  = value to plot
'   br, bg, bb = bar border color
'   fr, fg, fb = bar fill color
'---------------------------------------------------------------------------------------------
SUB GPole(window wnd,int x,int y,int width,int value,int max,int offset,int br,int bg,int bb,int fr,int fg,int fb)
int calc_val
calc_val = y-(y - (value * max/255))
Rect wnd,x,y,width,-calc_val,RGB(br,bg,bb),RGB(fr,fg,fb)
RETURN
ENDSUB
'---------------------------------------------------------------------------------------------


'
sub GLine(window wnd,int x,int y,int xlen,int value,int max,int offset,int R,int G,int B)
'---------------------------------------------------------------------------------------------
' HOW TO USE:
'   x,y     = start x,y
'   height = Height of plot area
'   value  = value to plot
'   max    = Max legal graph value
'   offset = Calibration offset
'   R,G,B  = line color
'---------------------------------------------------------------------------------------------
int calc_val
calc_val = offset +y - (value * max/255)   
LINE wnd, x, calc_val-offset, x+xlen, calc_val-offset, RGB(R,G,B)
setfont(wnd, "Tahoma",6,400)
move wnd,x-21,calc_val-offset-5
print wnd,str$(value+offset)
RETURN
ENDSUB
'---------------------------------------------------------------------------------------------

'
'---------------------------------------------------------------------------------------------
' HOW TO USE:
'   x, y   = position
'   width  = bar width in pixels
'   height = bar height in pixels
'   br, bg, bb = bar border color
'   fr, fg, fb = bar fill color
'---------------------------------------------------------------------------------------------
SUB Pole(window wnd,int x,int y,int width,int height,int br,int bg,int bb,int fr,int fg,int fb)
Rect wnd,x,y-height,width,height,RGB(br,bg,bb),RGB(fr,fg,fb)
RETURN
ENDSUB
'---------------------------------------------------------------------------------------------


Support Amateur Radio  -  Have a ham  for dinner!

Andy

Thanks so much Bill and Egil!

I got up early this morning, couldn't sleep so I got on with adding the code into my program.

See attached.

The graphs are really looking good now - thanks again.

Just one question about the graph code:

This post I started was for a graph who's range was 255, some of my graphs have a different range...
so should I be changing:

calc_val = offset +y - (value * max/255)  - the 255 value to the actual range of each graph?

Thanks,
Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Egil

QuoteThis post I started was for a graph who's range was 255, some of my graphs have a different range...
so should I be changing:

calc_val = offset +y - (value * max/255)  - the 255 value to the actual range of each graph?

That's correct.


Did some more tidying up on my code last night, now it should be easier to follow.


Good Luck!

Egil



'
' graph.iwb
'
AutoDefine "Off"
def win:window 
def run,value,maxval,offset,g_height:int 

OpenWindow win,0,0,600,400,@minbox,0,"  Andy's Graph",&messages 

maxval   = 150
g_height = 170
offset   = -40

' This sub an also be used to make bargraph poles:
Pole(win,150,200,270,g_height,128,128,128,250,250,250)

' draw calibration lines
value = -40
GLine(win,151,200,268,value,maxval,offset,200,200,200)

value = 11
GLine(win,151,200,268,value,maxval,offset,200,200,200)

value = 62
GLine(win,151,200,268,value,maxval,offset,200,200,200)

value = 113
GLine(win,151,200,268,value,maxval,offset,200,200,200)

value = 164
GLine(win,151,200,268,value,maxval,offset,200,200,200)

value = 215
GLine(win,151,200,268,value,maxval,offset,200,200,200)


'Poles
value=11
GPole(win,155,200,8,value,maxval,offset,128,128,128,128,222,128)

value=113
GPole(win,165,200,8,value,maxval,offset,128,128,128,128,222,128)

value=164
GPole(win,175,200,8,value,maxval,offset,128,128,128,255,128,128)

value=62
GPole(win,185,200,8,value,maxval,offset,128,128,128,255,128,128)

value=215
GPole(win,195,200,8,value,maxval,offset,128,128,128,255,128,128)

run = 1 
WAITUNTIL run = 0 
CLOSEWINDOW win
END 

'
SUB messages(),int
'---------------------------------------------------------------------------------------------
' Main Loop
'---------------------------------------------------------------------------------------------
SELECT @class

CASE @idcreate 
centerwindow win
CASE @idclosewindow 
run = 0 
ENDSELECT 
RETURN  0
EndSub
'---------------------------------------------------------------------------------------------


'
'---------------------------------------------------------------------------------------------
' HOW TO USE:
'   x, y   = position
'   width  = bar width in pixels
'   value  = value to plot
'   br, bg, bb = bar border color
'   fr, fg, fb = bar fill color
'---------------------------------------------------------------------------------------------
SUB GPole(window wnd,int x,int y,int width,int value,int max,int offset,int br,int bg,int bb,int fr,int fg,int fb)
int calc_val
value = value+abs(offset)
calc_val = y-(y - (value * max/255))
Rect wnd,x,y,width,-calc_val,RGB(br,bg,bb),RGB(fr,fg,fb)
RETURN
ENDSUB
'---------------------------------------------------------------------------------------------


'
sub GLine(window wnd,int x,int y,int xlen,int value,int max,int offset,int R,int G,int B)
'---------------------------------------------------------------------------------------------
' HOW TO USE:
'   x,y     = start x,y
'   height = Height of plot area
'   value  = value to plot
'   max    = Max legal graph value
'   offset = Calibration offset
'   R,G,B  = line color
'---------------------------------------------------------------------------------------------
int calc_val
value = value+abs(offset)
calc_val = offset +y - (value * max/255)   
LINE wnd, x, calc_val-offset, x+xlen, calc_val-offset, RGB(R,G,B)
setfont(wnd, "Tahoma",6,400)
move wnd,x-21,calc_val-offset-5
print wnd,str$(value+offset)
RETURN
ENDSUB
'---------------------------------------------------------------------------------------------

'
'---------------------------------------------------------------------------------------------
' HOW TO USE:
'   x, y   = position
'   width  = bar width in pixels
'   height = bar height in pixels
'   br, bg, bb = bar border color
'   fr, fg, fb = bar fill color
'---------------------------------------------------------------------------------------------
SUB Pole(window wnd,int x,int y,int width,int height,int br,int bg,int bb,int fr,int fg,int fb)
Rect wnd,x,y-height,width,height,RGB(br,bg,bb),RGB(fr,fg,fb)
RETURN
ENDSUB
'---------------------------------------------------------------------------------------------


Support Amateur Radio  -  Have a ham  for dinner!

Andy

Thanks Egil!

I now have all the graphs I have worked on perfectly formed and to scale no matter what the scale is.

See attached.

Thanks,
Andy.

:)
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Andy

Just one question - advice really...

Some of my data tests return not 1 value but 2 or more.

Does anyone have any suggestions on how I might show the 2 values?

The 2 possible values, have different scales.

Should I do 2 graphs, or is there a way to combine them?

Thanks,
Andy.

:)




Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

LarryMc

If you display 2 values on the same graph you have a couple of options
If they have the same scale you can plot them as side by side bars of different colors or as different color line graphs.

If they have different scales then you plot them them as different color line graphs.
on the left you display the y axis value's scale in the color of the 1st value's range
and on the right you display the y axis value's scale in the color of the 2nd value's range

or you can put all the y scales on the left (side by side) in different colors and have 2,3,4.... plots on the same graph if you are really hurting for space but the scale numbers themselves take up space also.

Just depends on how important it is to show the relationship of the parameters being plotted.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Andy

Thanks Larry for the advice,

Will give it go over this weekend.

Will post a screenshot when I've had a go.

Andy.

:)
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.