comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Button_events and data
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Button_events and data [message #10980] Wed, 25 February 1998 00:00 Go to next message
Bernard Puc is currently offline  Bernard Puc
Messages: 65
Registered: January 1998
Member
Hello,

I'm looking for pointers on how to do the following: I have a line
plot in a draw widget. I want to click the pointer on the plot and have
a vertical line drawn at the nearest datapoint to the mouseclick.
widget_draw returns the cursor location in device coordinates and I
need to translate that into dataspace coordinates.
Going one step further, ideally, I'd like to have a vertical line
follow the cursor around the draw widget at all times, jumping from
datapoint to datapoint. I suspect someone has already written such a
thing...

Any help appreciated.

-Bernard Puc
puc@gsfc.nasa.gov
Re: Button_events and data [message #11163 is a reply to message #10980] Thu, 26 February 1998 00:00 Go to previous message
J.D. Smith is currently offline  J.D. Smith
Messages: 214
Registered: August 1996
Senior Member
David Fanning wrote:
>
> Bernard Puc (puc@gsfc.nasa.gov) writes:
>
>> I'm looking for pointers on how to do the following: I have a line
>> plot in a draw widget. I want to click the pointer on the plot and have
>> a vertical line drawn at the nearest datapoint to the mouseclick.
>> widget_draw returns the cursor location in device coordinates and I
>> need to translate that into dataspace coordinates.
>> Going one step further, ideally, I'd like to have a vertical line
>> follow the cursor around the draw widget at all times, jumping from
>> datapoint to datapoint. I suspect someone has already written such a
>> thing...
>
> Well, you hit me in a moment of weakness. :-)
>
> I've been writing a program today that is out there on the
> edge of my knowledge and experience. Writing something I
> *know* how to write seemed kind of relaxing. I did this over
> a couple of beers, so it may not be my *best* work. ;-)
>
> The way I chose to implement your requirements is to draw
> the vertical line as long as you hold the cursor down in the
> draw widget. The program assumes regular "steps" in the
> X direction, but the algorithm could easily be changed
> to accommodate irregular steps.
>
> Here you go. Save the code below as "example.pro". Type
> "example" to see it work.
>
> Cheers,
>
> David
>
> PRO Example_Cleanup, id
> Widget_Control, id, Get_UValue=info, /No_Copy
> IF N_Elements(info) NE 0 THEN WDelete, info.pixID
> END
>
> PRO Draw_Widget_Events, event
>
> ; Deal only with button up, button down, and motion events.
>
> IF event.type GT 2 THEN RETURN
>
> ; What kind of event is this?
>
> Widget_Control, event.top, Get_UValue=info, /No_Copy
> eventType = ['Button Down', 'Button Up', 'Motion Events']
> thisEvent = eventType(event.type)
>
> CASE thisEvent OF
>
> 'Button Down': BEGIN
>
> ; Turn motion events on.
>
> Widget_Control, event.id, Draw_Motion_Events=1
> ENDCASE
>
> 'Button Up': BEGIN
>
> ; Turn motion events off.
>
> Widget_Control, event.id, Draw_Motion_Events=0
>
> ; Erase the last line.
>
> WSet, info.wid
> Device, Copy=[0,0,400,400,0,0,info.pixID]
>
> ENDCASE
>
> 'Motion Events': BEGIN
>
> ; Erase the previous line.
>
> WSet, info.wid
> Device, Copy=[0,0,500,500,0,0,info.pixID]
>
> ; Set up plot and axes scaling.
>
> !P = info.p
> !X = info.x
> !Y = info.y
>
> ; Convert cursor location to data coordinates.
>
> coords = Convert_Coord(event.x, event.y, /Device, /To_Data)
> x = coords[0]
> y = coords[1]
>
> ; Make sure X value is within plot limits.
>
> x = !X.crange[0] > x
> x = !X.crange[1] < x
>
> ; Find the nearest data point.
>
> nearest = WHERE(info.indep GE (x - (info.step/2.0)), count)
> IF count EQ 0 THEN datapt = info.indep[info.last] ELSE BEGIN
> nearest = nearest[0]
> IF nearest EQ 0 THEN datapt = info.indep[0] ELSE $
> datapt = info.indep[nearest]
> ENDELSE

I think perhaps he wants the actual nearest point, not the point at the
nearest x... how about:

tmp=min((info.indep-x)^2+(info.data-y)^2,near)
nearpt=[info.indep[near],info.data[near]]

This would also relieve the need for a regular grid of x values.

JD

--
J.D. Smith |*| WORK: (607) 255-5842
Cornell University Dept. of Astronomy |*| (607) 255-4083
206 Space Sciences Bldg. |*| FAX: (607) 255-5875
Ithaca, NY 14853 |*|
Re: Button_events and data [message #11177 is a reply to message #10980] Wed, 25 February 1998 00:00 Go to previous message
davidf is currently offline  davidf
Messages: 2866
Registered: September 1996
Senior Member
Bernard Puc (puc@gsfc.nasa.gov) writes:

> I'm looking for pointers on how to do the following: I have a line
> plot in a draw widget. I want to click the pointer on the plot and have
> a vertical line drawn at the nearest datapoint to the mouseclick.
> widget_draw returns the cursor location in device coordinates and I
> need to translate that into dataspace coordinates.
> Going one step further, ideally, I'd like to have a vertical line
> follow the cursor around the draw widget at all times, jumping from
> datapoint to datapoint. I suspect someone has already written such a
> thing...

Well, you hit me in a moment of weakness. :-)

I've been writing a program today that is out there on the
edge of my knowledge and experience. Writing something I
*know* how to write seemed kind of relaxing. I did this over
a couple of beers, so it may not be my *best* work. ;-)

The way I chose to implement your requirements is to draw
the vertical line as long as you hold the cursor down in the
draw widget. The program assumes regular "steps" in the
X direction, but the algorithm could easily be changed
to accommodate irregular steps.

Here you go. Save the code below as "example.pro". Type
"example" to see it work.

Cheers,

David

PRO Example_Cleanup, id
Widget_Control, id, Get_UValue=info, /No_Copy
IF N_Elements(info) NE 0 THEN WDelete, info.pixID
END


PRO Draw_Widget_Events, event

; Deal only with button up, button down, and motion events.

IF event.type GT 2 THEN RETURN

; What kind of event is this?

Widget_Control, event.top, Get_UValue=info, /No_Copy
eventType = ['Button Down', 'Button Up', 'Motion Events']
thisEvent = eventType(event.type)

CASE thisEvent OF

'Button Down': BEGIN

; Turn motion events on.

Widget_Control, event.id, Draw_Motion_Events=1
ENDCASE

'Button Up': BEGIN

; Turn motion events off.

Widget_Control, event.id, Draw_Motion_Events=0

; Erase the last line.

WSet, info.wid
Device, Copy=[0,0,400,400,0,0,info.pixID]

ENDCASE

'Motion Events': BEGIN

; Erase the previous line.

WSet, info.wid
Device, Copy=[0,0,500,500,0,0,info.pixID]

; Set up plot and axes scaling.

!P = info.p
!X = info.x
!Y = info.y

; Convert cursor location to data coordinates.

coords = Convert_Coord(event.x, event.y, /Device, /To_Data)
x = coords[0]
y = coords[1]

; Make sure X value is within plot limits.

x = !X.crange[0] > x
x = !X.crange[1] < x

; Find the nearest data point.

nearest = WHERE(info.indep GE (x - (info.step/2.0)), count)
IF count EQ 0 THEN datapt = info.indep[info.last] ELSE BEGIN
nearest = nearest[0]
IF nearest EQ 0 THEN datapt = info.indep[0] ELSE $
datapt = info.indep[nearest]
ENDELSE

; Draw a vertical line through the nearest datapoint.

PlotS, [datapt, datapt], !Y.CRange, Color=info.color
format = '(F4.1)'
XYOutS, datapt, 0.85, '(' + $
String(info.indep[datapt],Format=format) + $
',' + String(info.data[datapt],Format=format) + ')', $
Color=info.color
ENDCASE

ENDCASE

Widget_Control, event.top, Set_UValue=info, /No_Copy
END


PRO Example

; Fake data.

data = Findgen(11)
data = Sin(data*360*!RaDeg)
indep = Findgen(11)

; Create the widgets.

tlb = Widget_Base(Title='Example Program', Column=1)
drawID = Widget_Draw(tlb, XSize=500, YSize=500, $
Event_Pro='Draw_Widget_Events', Button_Events=1)

; Get the window index number.

Widget_Control, tlb, /Realize
Widget_Control, drawID, Get_Value=wid
WSet, wid

; Plot the data.

Plot, indep, data, PSym=-4, Position=[0.2, 0.2, 0.8, 0.8]

; Create a pixmap.

Window, /Free, /Pixmap, XSize=500, YSize=500
pixID = !D.Window
Plot, indep, data, PSym=-4, Position=[0.2, 0.2, 0.8, 0.8]

; The data step in the X direction. Assume regular steps.

step = indep[1] - indep[0]
TVLCT, 255, 255, 0, 1
color = 1

; Save information to run the program.

info = { indep:indep, $ ; Independent data.
data:data, $ ; Dependent data.
p:!P, $ ; Plotting system variable.
x:!X, $ ; X Axis system variable.
y:!Y, $ ; Y Axis system variable
wid:wid, $ ; Window index number.
pixID:pixID, $ ; The pixmap index number.
step:step, $ ; The step in independent data.
color:color, $ ; The line color.
last:N_Elements(indep)-1 $ ; Last element in array.
}

Widget_Control, tlb, Set_UValue=info, /No_Copy
XManager, 'example', tlb, /No_Block, Cleanup='Example_Cleanup'
END

-----------------------------------------------------------
David Fanning, Ph.D.
Fanning Software Consulting
E-Mail: davidf@dfanning.com
Phone: 970-221-0438
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Re: Button_events and data [message #11179 is a reply to message #10980] Wed, 25 February 1998 00:00 Go to previous message
David L. Windt is currently offline  David L. Windt
Messages: 9
Registered: June 1997
Junior Member
<HTML>
&nbsp;

<P>Bernard Puc wrote:
<BLOCKQUOTE TYPE=CITE>Hello,

<P> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; I'm looking for pointers
on how to do the following:&nbsp; I have a line
<BR>plot in a draw widget.&nbsp; I want to click the pointer on the plot
and have
<BR>a vertical line drawn at the nearest datapoint to the mouseclick.
<BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; widget_draw returns the
cursor location in device coordinates and I
<BR>need to translate that into dataspace coordinates.
<BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; Going one step further,
ideally, I'd like to have a vertical line
<BR>follow the cursor around the draw widget at all times, jumping from
<BR>datapoint to datapoint.&nbsp; I suspect someone has already written
such a
<BR>thing...

<P>Any help appreciated.

<P>-Bernard Puc
<BR>puc@gsfc.nasa.gov</BLOCKQUOTE>
&nbsp; Assuming you're plotting X vs Y, and have captured a draw widget
event
<BR>called EVENT...

<P>You can use CONVERT_COORD to first convert the draw widget event to
<BR>data coordinates:

<P>CC=CONVERT_COORD(EVENT.X,EVENT.Y,/DEVICE,/TO_DATA)

<P>You might then try my VALUE_TO_INDEX function to get the x data index
<BR>corresponding to the x value closest to the widget event (i.e., the
<BR>mouse click):

<P>X_INDEX=VALUE_TO_INDEX(X,CC(0))

<P>and then plot the vertical line using PLOTS:

<P>PLOTS,[0,0]+X(X_INDEX),!Y.CRANGE

<P>(Or if you like, this can all be done in one line, as in:
<BR>PLOTS,[0,0]+ $
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; X(VALUE_TO_INDEX(X,(CONVERT_COORD(EVENT.X,EVENT.Y,
$
<BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
/DEVICE,/TO_DATA))(0))), $
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !Y.CRANGE
<BR>)

<P>To have a vertical line that follows the mouse around will require
<BR>a bit more work, but it could make use of the same methods as above.

<P>VALUE_TO_INDEX, as well as all my other thrilling idl programs can be
<BR>found at <A HREF="http://www.bell-labs.com/user/windt/idl">www.bell-labs.com/user/windt/idl</A>.&nbsp;
In particular, you might
<BR>also be interested in TRACK_PLOT - it doesn't draw lines, but it
<BR>provides live X and Y values in a text widget as you move the mouse
<BR>over an x,y plot.&nbsp; It might make a reasonable starting point for
<BR>doing what you want to do with vertical lines.

<P>David Windt
<BR>windt@bell-labs.com
<BR>&nbsp;</HTML>
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: read a .PCD file
Next Topic: How much for new PV-WAVE package for Win95.

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 18:40:12 PDT 2025

Total time taken to generate the page: 0.07036 seconds