[Graph builder] Batch pin the hover label for selected rowsDear all,
Currently I use JMP16 to create a graph.
I have a col with picture in it, and I want to pin the picture for each dot I selected so I turn on the "add label" of this col.
But I find that I can only by hover my pointer on the dot, and wait the hover label shown itself, and then click the pin button to pin it one by one,
is there any faster way to achieve this like jsl code? I have million of rows need to show out the pics.
thanks!
Automation and ScriptingRe: [Graph builder] Batch pin the hover label for selected rowsDoes it need to be a hover label? Or could you use the picture as the symbol in your graph? For example, using the Big Class Families sample dataset:

If you only want pictures for selected rows, you could select them and Name Selection in Column, then use that Column to create a Transform column, like this:
// Open Data Table: Big Class Families.jmp
// â Data Table( "Big Class Families" )
Open( "$SAMPLE_DATA/Big Class Families.jmp" );
// Name selection in column: Use Images
Data Table( "Big Class Families" ) << Clear Select <<
Select Rows( [1, 6, 14, 15, 16] ) <<
Name Selection in Column( Column Name( "Use Images" ), Selected( 1 ) );
Graph Builder(
Transform Column( "Transform[height]", Formula( :height * :Use Images ) ),
Size( 648, 551 ),
Show Control Panel( 0 ),
Variables(
X( :weight ),
Y( :height ),
Y( :"Transform[height]"n, Position( 1 ) )
),
Elements(
Points( X, Y( 1 ), Y( 2 ), Legend( 3 ) ),
Points( X, Y( 2 ), Legend( 5 ), Set Shape Column( :picture ) )
)
);
I included the script so you can see the results with one click, but this can all be done within Graph Builder with no scripting. The key functionalities are Transform Columns and Set Shape Column.
Re: [Graph builder] Batch pin the hover label for selected rowsHere's an example pinning the hover labels. Interesting that the selection is zero-based indexing. May want to modify to handle no rows selected.
Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class Families.jmp" );
dt << Select Rows( [1 5 7] );
pin_expr = {};
For Each( {v, i}, dt << Get Selected Rows,
Insert Into(
pin_expr,
Eval(
Eval Expr(
{Add Pin Annotation(
Seg( Marker Seg( 1 ) ),
Index( Expr( v - 1 ) ),
Index Row( Expr( v - 1 ) ),
UniqueID( Expr( v - 1 ) )
)}
)
)
)
);
Eval(
Substitute(
Expr(
dt << Graph Builder(
Size( 658, 556 ),
Show Control Panel( 0 ),
Variables( X( :weight ), Y( :height ) ),
Elements( Points( X, Y, Legend( 5 ) ) ),
SendToReport( Dispatch( {}, "Graph Builder", FrameBox, __pin_expr__ ) )
)
),
Expr( __pin_expr__ ), Name Expr( pin_expr )
)
);

Re: [Graph builder] Batch pin the hover label for selected rowsThanks for the reply! Using Set Shape Column works great, but it would be even better if the points could be displayed as well. This is definitely a convenient approach!
Re: [Graph builder] Batch pin the hover label for selected rows
For Each( {v, i}, row_selection,
local_x = Column( dt, col_x )[v];
local_y = Column( dt, col_y )[v];
Insert Into(
pin_expr,
Eval(
Eval Expr(
{Add Pin Annotation(
Seg( Marker Seg( 1 ) ),
Index( Expr( v - 1 ) ),
Origin( {Expr( local_x ), Expr( local_y )} ),
Index Row( Expr( v - 1 ) ),
UniqueID( Expr( v - 1 ) ),
Offset( {-50, -45} ),
Replace Text( " " ),
Filled( 0 ),
Tag Line( 1 )
)}
)
)
);
);
Great! It works, but all my annotations were pinned at the exact same position without the Origin setting. To fix this, I read out the values of the x/y axes and assigned them to the Origin. While this works perfectly on numeric axes, passing character column values crashes the app. Is there a workaround for character columns? Thanks!
Re: [Graph builder] Batch pin the hover label for selected rowsFor nominal/ordinal columns the axis starts from 0 and each value increases it by 1. You can verify this from axis settings

You can write logic which takes care of this based on the data table or if you have point plot, you can get the values from markers
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(Variables(X(:age), Y(:height)), Elements(Points(X, Y, Legend(3))));
ms = report(gb)[framebox(1)] << find seg(markerseg(1));
Show(ms << Get X Values, ms << Get Y Values);
Re: [Graph builder] Batch pin the hover label for selected rowsThanks! It seems to return all the X/Y values, but how can I read-out the selected rows x/y? I tried code below but the x/y returned is not where I selected.
r = dt << Get Selected Rows();
ms = Report(gb)[framebox(1)] << Find Seg( Marker Seg( 1 ) );
For Each( {v, i}, r,
t = ms << Get Point( v );
x = t[1];
y = t[2];
show(x,y);
);Re: [Graph builder] Batch pin the hover label for selected rowsFor me this seems to return correct values
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(Variables(X(:age), Y(:height)), Elements(Points(X, Y, Legend(3))));
dt << Select Rows([1, 10, 16, 20, 30]);
ms = Report(gb)[framebox(1)] << Find Seg(Marker Seg(1));
selrows = dt << Get Selected Rows();
For Each({currow}, selrows,
coord = ms << Get Point(currow);
Show(coord);
);

coord = {0, 59};
coord = {1, 61};
coord = {1, 65};
coord = {1, 63};
coord = {2, 61};
coord = {2, 62};
coord = {3, 67};Re: [Graph builder] Batch pin the hover label for selected rowsOh I see the issue now: hiding or excluding rows causes an index mismatch for the remaining data.
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(Variables(X(:age), Y(:height)), Elements(Points(X, Y, Legend(3))));
dt << Select Rows([1, 10, 16, 20, 30]);
ms = Report(gb)[framebox(1)] << Find Seg(Marker Seg(1));
selrows = dt << Get Selected Rows();
pin_expr = {};
For Each({v}, selrows,
coord = ms << Get Point(v);
Show(coord);
Insert Into(
pin_expr,
Eval(
Eval Expr(
{Add Pin Annotation(
Seg( Marker Seg( 1 ) ),
Index Row( Expr( v - 1 ) ),
Origin( Expr(coord)),
UniqueID( Expr( v - 1 ) )
)}
)
)
)
);
Eval(
Substitute(
Expr( Report(gb)[framebox(1)] << __pin_expr__ ),
Expr( __pin_expr__ ), Name Expr( pin_expr )
)
);
By using this code, when row 17 hidden/excluded, it will cause the annotations of rows 20/30 to shift to the wrong positions.
Is there a way to prevent this from happening? I mean for sure I have data points to be excluded..
Re: [Graph builder] Batch pin the hover label for selected rowsThis works, thanks guys!
ex = dt << Get Excluded Rows;
pin_expr = {};
For Each( {v}, dt << Get Selected Rows,
offset = N Rows(Loc(ex < v));
coord = ms << Get Point(v - offset);Re: [Graph builder] Batch pin the hover label for selected rowsI would drop the excluded rows already from selrows
selrows = dt << Get Rows Where(Selected() & !Excluded())
Re: [Graph builder] Batch pin the hover label for selected rowsBad news if the graph builder has local data filter the index is mismatched.
Is there a way to deal with graphs with local filter active?
Re: [Graph builder] Batch pin the hover label for selected rowsYou can get the rows which local data filter will show by sending message
<< Get Filtered Rows;
to the local data filter
Re: [Graph builder] Batch pin the hover label for selected rowsThanks for your help! I am almost there!
By the way, is there a way to batch remove the annotation added by the scripts?
gb << SendToReport( Dispatch( {}, "Graph Builder", FrameBox(__which__), __pin_expr__ ) )Re: [Graph builder] Batch pin the hover label for selected rowsIf you can get references to all of those, I think you could set << Close or << Delete message to the list to remove them all at the same time. You might also want to utilize << inval before deletion and << update window after.
Re: [Graph builder] Batch pin the hover label for selected rowsMy code is designed for an existing graph builder obtained by gb = (Current Report() << Find( "Graph Builder" )) << Get Scriptable Object;
then I created an Eval loop as mmarchandFSLR's way:
it looks like I can only get access to the gb itself, but nowhere to define the Add Pin Annotation list from the code below:
is there a way to read the Unique ID or something of each one and assign << delete to it then?
pin_expr = {};
For Each( {v, i}, dt << Get Selected Rows,
Insert Into(
pin_expr,
Eval(
Eval Expr(
{Add Pin Annotation(
Seg( Marker Seg( 1 ) ),
Index( Expr( v - 1 ) ),
Index Row( Expr( v - 1 ) ),
UniqueID( Expr( v - 1 ) )
)}
)
)
)
);
.....
If( N Items( pin_expr ) > 0,
Eval(
Substitute(
Expr(
gb << SendToReport( Dispatch( {}, "Graph Builder", FrameBox(__which__), __pin_expr__ ) )
),
Expr( __pin_expr__ ), Name Expr( pin_expr ),
)
)
);
Re: [Graph builder] Batch pin the hover label for selected rowsNames Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
dt << select rows([1, 10, 21, 30, 40]);
gb = dt << Graph Builder(
Size(658, 556),
Show Control Panel(0),
Variables(X(:age), Y(:height)),
Elements(Points(X, Y, Legend(3)))
);
pins = {};
gb << inval;
frame = Report(gb)[FrameBox(1)];
For Each({currow}, dt << Get Selected Rows,
Eval(EvalExpr(
Insert Into(pins, frame << Add Pin Annotation(
Seg(Marker Seg(1)),
Index(Expr(currow - 1)),
Index Row(Expr(currow - 1)),
UniqueID(Expr(currow - 1))
));
));
);
gb << update window;
wait(1); // demo purposes
pins << Delete;Re: [Graph builder] Batch pin the hover label for selected rowsOh I see the issue now: hiding or excluding rows causes an index mismatch for the remaining data.
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(Variables(X(:age), Y(:height)), Elements(Points(X, Y, Legend(3))));
dt << Select Rows([1, 10, 16, 20, 30]);
ms = Report(gb)[framebox(1)] << Find Seg(Marker Seg(1));
selrows = dt << Get Selected Rows();
pin_expr = {};
For Each({v}, selrows,
coord = ms << Get Point(v);
Show(coord);
Insert Into(
pin_expr,
Eval(
Eval Expr(
{Add Pin Annotation(
Seg( Marker Seg( 1 ) ),
Index Row( Expr( v - 1 ) ),
Origin( Expr(coord)),
UniqueID( Expr( v - 1 ) )
)}
)
)
)
);
Eval(
Substitute(
Expr( Report(gb)[framebox(1)] << __pin_expr__ ),
Expr( __pin_expr__ ), Name Expr( pin_expr )
)
);
By using this code, when row 17 hidden/excluded, it will cause the annotations of rows 20/30 to shift to the wrong positions.
Is there a way to prevent this from happening? I mean for sure I have data points to be excluded.
Re: [Graph builder] Batch pin the hover label for selected rowsThanks jthi! really appreciate it!
Re: [Graph builder] Batch pin the hover label for selected rows@jthi Sorry but is there a sample way like current report / current data table to get current frame user selected?
I use this but only if the graph has the script added.
For Each( {f, n}, frames,
Eval( Eval Expr( f << AddGraphicsScript( Handle( ::currentFrame = Expr( f ) ) ) ) )
);Re: [Graph builder] Batch pin the hover label for selected rowsYou can use XPath to look for selected attribute (with true value)
Names Default To Here(1);
//This message applies to all display box objects
dt = Open("$SAMPLE_DATA/Big Class.jmp");
biv = dt << Run Script("Bivariate");
Report(biv)[FrameBox(1)] << Select(1);
report(biv) << XPath("//FrameBox[@selected='true']");Re: [Graph builder] Batch pin the hover label for selected rowsThanks! I actually need to get the frame under the mouse cursor (either hovered or clicked). I considered using S + Click for selection, but is there a simpler way to do this?
Re: [Graph builder] Batch pin the hover label for selected rowsDoing those is much more difficult in JMP as there is not easy access to the cursor location (in most of the cases) and even if you did, you would still have to calculate which frame happens to be under the coordinates. You can get the click but you have to first add graphic script to each of the frame boxes (graphic scripts trigger on mouse click/hovering over points/holding and dragging/...). Depending on what your script is supposed to do, there might be other options, for example you could provide user list of frameboxes, let them select which to add graphic script to and then prompt user to press OK.