It would be exceptionally great if JMP would allow frame boxes to have a sample-and-hold type of display. Specifically, they should be rendered once and only re-rendered for such things as resize events, row-state changes (for any marker seg's that are linked to a table's row-state) or by sending the <<Inval or <<Dirty message.
What I'd like to see is for the below example script to not print any number more than once while scrolling -- during the initial render and that's it (this would also apply to marker segs if present).
The main reason for this is that if I'm plotting many graphs with millions of data points, I don't mind waiting several seconds for the initial render (that is expected) but it is unacceptable that every scroll event requires multiple seconds of rendering -- render only once and just repaint the bitmap at a different location when scrolling.
NOTE: If the devs are worried about the memory consumption of holding bitmaps in ram -- DO NOT WORRY. Let the user worry about that when setting up the boxes. For example, if I try to create a plot that would be 1,000,000,000 x 1,000,000,000 pixels to render then let me attempt it and crash JMP. You shouldn't prevent us from having the necessary feature simply for the reason that it might allow us to crash JMP under stupid circumstances. Allow it to be opt-in only (i.e., only by calling the <<Lazy method will this new feature be invoked).
Just to reiterate, it would be great if a FrameBox had a method (such as <<Lazy) that would do the absolute minimum number of renders possible to keep the painted bitmap current and no more -- thus allowing scrolling to be fluid and fast for FrameBoxes with either very complicated Graphics Scripts or millions of data points or both.
Here is an example of the bad behavior currently -- the numbers are printed multiple times indicating that the rendering pass happens each scroll event:
Names Default to Here( 1 );
New Window( "Test",
V Scroll Box(
vlb = V List Box()
)
);
For( i = 1, i <= 100, i++,
Eval( Eval Expr(
vlb << Append(
Graph Box(
X Scale( 0, 1 ),
Y Scale( 0, 1 ),
Pen Color( "Blue" );
Line( [1 0], [0 1] );
Print( Expr( i ) )
)
)
) )
)
Here is an example of the unacceptable wait-time associated with this "re-render-at-every-scroll-event" / "re-render at every possible opportunity" (just try scrolling through here...)
Names Default to Here( 1 );
ns = New Namespace();
ns:table = New Table( "TEST",
New Column( "X", "Numeric", <<Formula( Random Normal() ) ),
New Column( "Y", "Numeric", <<Formula( Random Normal() ) ),
<<Add Rows( 100000 )
);
ns:func = Function( {_i},
Print( _i )
);
Eval( Eval Expr(
New Window( "Test",
<<On Close(
ns = Namespace( Expr( ns << Get Name ) );
Close( ns:table, No Save );
ns << Delete Namespace;
)
,
V Scroll Box(
vlb = V List Box()
)
)
) );
For( i = 1, i <= 100, i++,
Eval( Eval Expr(
vlb << Append(
box = Outline Box( "",
Graph Box(
Frame Size( 300, 300 ),
Y Scale( -3, 3 ),
X Scale( -3, 3 ),
Marker Seg( Expr( ns:table:X << Get Values ), Expr( ns:table:Y << Get Values ), Row States( Expr( ns:table ) ) );
)
)
);
seg = box[Frame Box( 1 )] << Find Seg( "Marker Seg" );
seg << Transparency( 0.4 );
box[Frame Box( 1 )] << Add Graphics Script(
Local( {ns = Namespace( Expr( ns << Get Name ) )},
ns:func( Expr( i ) )
)
);
) );
)