Todd, JMP / JSL is a bit weird when compared to more typical programming languages -- in particular, you pretty much have to do all scope control yourself.
I've got an example here that illustrates what you're dealing with -- one might think that the below script will create a "Red"
then "Blue"
triangle in the graphics script, but instead only two blue triangles are created.
Names Default To Here( 1 );
Open( "$SAMPLE_DATA/Big Class.jmp" );
biv = Bivariate( Y( :weight ), X( :height ), FitLine );
rbiv = biv << report;
framebox = rbiv[frame box( 1 )];
/**** Make a red triangle??? ****/
color = "Red";
framebox << Add Graphics Script(
Transparency( 0.5 );
Fill Color( color );
Polygon( [60, 72, 57], [75, 120, 120] );
);
/**** Make a blue triangle??? ****/
color = "Blue";
framebox << Add Graphics Script(
Transparency( 0.5 );
Fill Color( color );
Polygon( [60, 72, 57], [85, 130, 130] );
);
This happens because of how JSL handles scope -- when you use the <<Add Graphics Script()
function then it is added as a set of unevaluated statements (actually it is an unevaluated Glue()
function). Any variable that exists within the <<Add Graphics Script()
script will get evaluated only during execution of the script. When the graphics script is running (remember, it is attached to the Frame Box
which is embedded in the display tree of the window) it will need to resolve each variable. The scope resolution rules dictate that it will look into the Local
scope (if it exists), the Here
scope (if it exists), then the Global
scope -- if it cannot find them in any of these scopes it will get replaced by an Empty()
value.
So the scripts get added to the Frame Box
inside of the main script, but only executed later. At this later point, the color variable is "Blue"
, thus both triangles are blue.
The way to resolve this is to have any variables of interest get resolved when adding the graphics script, not when executing it. To do this use the Eval( Eval Expr() )
methodology, as shown here.
Names Default To Here( 1 );
Open( "$SAMPLE_DATA/Big Class.jmp" );
biv = Bivariate( Y( :weight ), X( :height ), FitLine );
rbiv = biv << report;
framebox = rbiv[frame box( 1 )];
/**** Make a red triangle!!! ****/
color = "Red";
Eval( Eval Expr(
framebox << Add Graphics Script(
Transparency( 0.5 );
Fill Color( Expr( color ) );
Polygon( [60, 72, 57], [75, 120, 120] );
);
) );
/**** Make a blue triangle!!! ****/
color = "Blue";
Eval( Eval Expr(
framebox << Add Graphics Script(
Transparency( 0.5 );
Fill Color( Expr( color ) );
Polygon( [60, 72, 57], [85, 130, 130] );
);
) );
You need to use this method for all of your variables within the <<Add Graphics Script()
function in order for them to hold the value at the time the <<Add Graphics Script()
was called.
Jordan