Subscribe Bookmark RSS Feed

Mousetrap and Biviariate Frame Box

msharp

Super User

Joined:

Jul 28, 2015

I have an anaysis that spits out a bivariate plot.  When I added some additional functionality via a Mousetrap operation, I can no select points and I have no idea why.  Is there a way to prevent this or at least to add this functionality back in?

How can I fix this?

dt = Open( "$SAMPLE_DATA/Big Class.jmp" );

nw = new Window("MouseTrap Test", Vlb = vlistbox());

vlb << Append(biv = dt << Bivariate( Y( :height ), X( :weight ) );

rbiv = biv << report;

rbiv[frame box(1)] << Add Graphics Script(Mousetrap(print("test"), print("test test")));

biv2 = dt << Bivariate( Y( :height ), X( :weight ) );)

1 ACCEPTED SOLUTION

Accepted Solutions
Solution

So, #4 then.  For anyone reading along...this script is using a function named "MouseTrap" in a graphics script attached to the upper graph.  When you drag with the mouse on the upper graph, the MouseTrap function captures the mouse movements, preventing the normal selection of points in a "rubber-band rectangle".  To emulate the selection behavior, MouseTrap maintains state variables "scripton" and "startx...othery".  msharp created scripton to know whether or not to run a script that takes too long to run on every additional point added to the rectangle.  MouseTrap also uses scripton to keep track of whether the button was just pressed.  If so, the X,Y is captured in startx,starty, otherwise in otherx,othery.  And if not the first time, MouseTrap uses startx...othery in a where statement to actually select the rows in the table.  The Min and Max functions in the SelectWhere command account for drawing the selection rectangle top-to-bottom, bottom-to-top, and left vs right.

MakeRowStateHandler should probably also do the same eval that MouseTrap does; here it just prints the rows that changed.  There are a couple of other print statements in this code; watch the log to get an idea what's happening.

//Start

dt = Open( "$SAMPLE_DATA/Big Class.jmp" );

script = "\[New Window("Test", Text Box("Hello"));]\";

scripton = 1;

// this is a better way to deal with row state changes (and not needed for the rest of the example)

rs = dt<<MakeRowStateHandler(Function({a},if( scripton, print(a))));

startx = .;

starty = .;

otherx = .;

othery = .;

nw = New Window( "MouseTrap Test", Vlb = V List Box() );

vlb << Append(

  biv = dt << Bivariate( Y( :height ), X( :weight ) );

  rbiv = biv << report;

  rbiv[frame box( 1 )] << Add Graphics Script(

  If( !Is Missing( startx ),

  Line( {startx, starty}, {otherx, starty}, {otherx, othery}, {startx, othery}, {startx, starty} )

  );

  Mousetrap(

  If( scripton,

  write("down\n");

  startx = x;

  starty = y;

  ,

  write("move\n");

  otherx = x;

  othery = y;

  dt << selectwhere(

  Min( starty, othery ) < :height < Max( starty, othery ) & Min( startx, otherx ) < :weight < Max( startx, otherx )

  );

  );

  scripton = 0;

  ,

  write("up\n");

  scripton = 1;

  startx = .; // toggle off

  Eval( Parse( script ) );

  );

  );

  biv2 = dt << Bivariate( Y( :height ), X( :weight ) );

);

Craige
4 REPLIES
Craige_Hales

Staff

Joined:

Mar 21, 2013

three ways:

1) use the brush tool (press B) with the current script (try holding alt while brushing to change the brush size).  When the brush tool is active, the mousetrap is not.

2) modify your script to put the graphic script earlier in the drawing list

dt = Open( "$SAMPLE_DATA/Big Class.jmp" );

nw = new Window("MouseTrap Test", Vlb = vlistbox());

vlb << Append(biv = dt << Bivariate( Y( :height ), X( :weight ) );

rbiv = biv << report;

rbiv[frame box(1)] << Add Graphics Script(  1,  Mousetrap(print("test"), print("test test")));

biv2 = dt << Bivariate( Y( :height ), X( :weight ) );)

The logic is: the script that draws first is painted over by  subsequent graphics scripts.  So the mouse hit tests are done in the opposite order--if it was drawn last it is more visible and should be easier to hit with the mouse.  Now, if you click on a point, the marker seg will take the mouse (and you can drag out a selection rectangle).  If you click off of a point, the mousetrap script takes the click.  You can't get the rectangle select if you click off a point.  You can experiment using rightClick->Customize and move the scripts up and down.

10157_graphicScriptPosition.PNG

(I saved the script and peeked to see how to do the "1" above.)

3) use Handle instead of Mousetrap.  Unless you really need the mousetrap to catch all the mouse activity.  Handle only captures clicks on the square handle.

4) I suppose you could re-implement the selection logic in the mousetrap if you really had to.  1-3 seem way better though.

Craige
msharp

Super User

Joined:

Jul 28, 2015

All of these are OR statements.  I need an AND statement.  How can I select points AND run the script?  Everything you listed either selects points OR runs the script.

A little more information, I have a script that runs every time a point is selected.  When dragging and selecting multiple points, if the user is slow, the script will run multiple times.  I want to prevent the script from running until the user releases the mouse.  See example below.

//Start

dt = Open( "$SAMPLE_DATA/Big Class.jmp" );

script = "\[New Window("Test", Text Box("Hello"));]\";

scripton = 1;

//Selected Script

dt << New Column( "Selected Script",

  numeric,

  Formula(

  If( Selected( Row State()) & scripton == 1 ,

  Eval(Parse(script))

  )

  )

);

Column( dt, "Selected Script" ) << Hide;

//FIX?!?!?

nw = new Window("MouseTrap Test", Vlb = vlistbox());

vlb << Append(biv = dt << Bivariate( Y( :height ), X( :weight ) );

  rbiv = biv << report;

  rbiv[frame box(1)] << Add Graphics Script( Mousetrap(scripton =0, scripton =1));

  biv2 = dt << Bivariate( Y( :height ), X( :weight ) );

)

Solution

So, #4 then.  For anyone reading along...this script is using a function named "MouseTrap" in a graphics script attached to the upper graph.  When you drag with the mouse on the upper graph, the MouseTrap function captures the mouse movements, preventing the normal selection of points in a "rubber-band rectangle".  To emulate the selection behavior, MouseTrap maintains state variables "scripton" and "startx...othery".  msharp created scripton to know whether or not to run a script that takes too long to run on every additional point added to the rectangle.  MouseTrap also uses scripton to keep track of whether the button was just pressed.  If so, the X,Y is captured in startx,starty, otherwise in otherx,othery.  And if not the first time, MouseTrap uses startx...othery in a where statement to actually select the rows in the table.  The Min and Max functions in the SelectWhere command account for drawing the selection rectangle top-to-bottom, bottom-to-top, and left vs right.

MakeRowStateHandler should probably also do the same eval that MouseTrap does; here it just prints the rows that changed.  There are a couple of other print statements in this code; watch the log to get an idea what's happening.

//Start

dt = Open( "$SAMPLE_DATA/Big Class.jmp" );

script = "\[New Window("Test", Text Box("Hello"));]\";

scripton = 1;

// this is a better way to deal with row state changes (and not needed for the rest of the example)

rs = dt<<MakeRowStateHandler(Function({a},if( scripton, print(a))));

startx = .;

starty = .;

otherx = .;

othery = .;

nw = New Window( "MouseTrap Test", Vlb = V List Box() );

vlb << Append(

  biv = dt << Bivariate( Y( :height ), X( :weight ) );

  rbiv = biv << report;

  rbiv[frame box( 1 )] << Add Graphics Script(

  If( !Is Missing( startx ),

  Line( {startx, starty}, {otherx, starty}, {otherx, othery}, {startx, othery}, {startx, starty} )

  );

  Mousetrap(

  If( scripton,

  write("down\n");

  startx = x;

  starty = y;

  ,

  write("move\n");

  otherx = x;

  othery = y;

  dt << selectwhere(

  Min( starty, othery ) < :height < Max( starty, othery ) & Min( startx, otherx ) < :weight < Max( startx, otherx )

  );

  );

  scripton = 0;

  ,

  write("up\n");

  scripton = 1;

  startx = .; // toggle off

  Eval( Parse( script ) );

  );

  );

  biv2 = dt << Bivariate( Y( :height ), X( :weight ) );

);

Craige
msharp

Super User

Joined:

Jul 28, 2015

Thank you, thank you, thank you.  This has been driving me crazy.

And I'm pretty sure you mean "\!n".  Your C#/C++ is showing.