cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
0 Kudos

FrameBox pixmap persistence

I proposed that JMP deal with display elements the same manner as every other GUI framework -- don't redraw any element unless the contents have changed or a specific redraw (or inval) method is invoked.

 

Specifically, can there please be a way to keep frameboxes from redrawing the content (this includes redrawing all data points and re-running any attached script) whenever a window is scrolled?  Like seriously, draw once and keep the bitmap (or pixmap) persistent unless the box has been changed (size change / dt RowState change / inval method)

 

This is an insanely extreme productivity kill when scrolling through graphs that have many thousands of points or complex attached scripts.  The current method of "redraw at every possible opportunity no matter what" is extremely baffling.

 

Here is an example -- the attached scrip merely prints to the log, but scrolling through the graphs shows how it is constantly running every time the scroll box updates (don't propagate the <<inval method to child boxes, ffs)

 

New Window( "Test",
	vlb = V List Box()
);

::global function = Function( {},
	Print( 1 );
);

For( i = 1, i <= 20, i++,
	vlb << Append(
		Graph Box(
			Frame Size( 200, 200 ),
			X Scale( -100, 100 ),
			Y Scale( -100, 100 ),
			::global function
		)
	)
)
2 Comments
danschikore
Staff

Hi @ErraticAttack -

Thanks for the suggestion - performance is definitely important for JMP.  Some reports can be 100k+ pixels tall, so JMP only draws the content that is currently visible in a scroll area.  On Windows, scrolling is optimized for small scroll values to copy pixels where possible and only redraw the content that is "new".

Can you tell us a little more about your use case?  In particular:

  1. Mac or Windows
  2. Does your window consist mostly of platforms or custom graphs?
  3. Is your graphics script doing a lot of drawing, or is it used for other tasks?

If you are drawing a large amount of geometry using JSL, it may be possible to speed things up by using Display Segs (Marker Seg, Line Seg) rather than JSL.

ErraticAttack
Level VI

Thanks for the response!  (sorry for the long-winded response here)

 

In my group we are looking at defects on wafers -- we often will scan entire FOUPs during excursions consisting of 25 wafers.  Because these are excursions, there are often tens or hundreds of thousands of defects per wafer.  Part of our workflow is to check these wafers.

 

I've created a script that only does a little bit of customizations to the plot -- namely, I draw the die below the defect points using the Path() command (using an SVG string), then draw the unclassified defects, then add a marker seg with the classified defects last (to ensure the classified defects are not obscured by the unclassified defects).

 

The initial render of 25 wafers can take several seconds and often we can see them all at once (relatively small on-screen size per wafermap), but if users want bigger wafermaps they will have to scroll through the list.  Scrolling through the wafermaps should be buttery smooth as nothing is changing, but of course it takes several seconds for each frame update.

 

My solution has been to create a picture after drawing the wafermap and only show the picture, but this leads to a lot of overhead to ensure re-drawing of the picture if the table state changes or anything else.  Also this method takes roughly 3x longer to initially render than not using it.

 

I've created GUI api's in my previous work and the default was always lazy evaluation -- admittedly I never had to use any image format larger than a standard JPEG (2^16 pixels per side), but it would routinely handle these maximum size JPEG's with no issue and only use a few MB of ram.

 

What I think would be ideal is to be able to give a FrameBox some sort of message to ensure lazy evaluation of the bitmap for the display engine, and then any RAM issues that potentially could exist due to huge bitmaps (or pixmaps) would be left to the discretion of the user.

 

Here is a good example of the issue I'm dealing with: (note that I use this <<Set Transparency( 0.4 ) method in my wafermap code because of our high number of points -- we wouldn't be able to see the structure without it).  This is a simple plot with only 150,000 points, yet the scrolling is painfully slow, and it's only one GraphBox.  Imagine doing this with 10 - 20 of them showing!

I'm using a pretty decent desktop with 64G of ram and a nice 4-core CPU.  This is JMP16 with hardware rendering (JMP14 also has the same issue) and I'm using a 4k monitor, but users with standard HD monitors have the same issues.  

 

Names Default to Here( 1 );
table = New Table( "test table",
	Add Rows( 150000 ),
	<<New Column( "X", "Numeric", <<Set Each Value( Random Normal() ) ),
	<<New Column( "Y", "Numeric", <<Set Each Value( Random Normal() ) )
);
Eval( Eval Expr(
New Window( "Test",
	<<On Close( Close( Expr( table ), No Save ) )
,
	vlb1 = V List Box()
,
	ob = Outline Box( "",
		gb = Graph Box(
			Frame Size( 200, 200 ),
			X Scale( -8, 8 ),
			Y Scale( -8, 8 ),
			Marker Seg(
				Expr( table:X << Get Values )
			,
				Expr( table:Y << Get Values )
			,
				Row States( Expr( table ) )
			);
		)
	)
,
	vlb2 = V List Box()
);
) );
(ob[Frame Box( 1 )] << Find Seg( Marker Seg( 1 ) )) << Set Transparency( 0.4 );


For Each( {i, _}, 1::100,
	{vlb1, vlb2} << Append( Text Box( "FILLER" ) )
)

 

 

 

To summarize:

  1. Can you provide a method for lazy evaluation of the Display Manager bitmap?  You already know when a RowState changes and you already provide a <<Inval method to manually re-draw if we want
  2. Can you provide a method to disable any attempt at hover-text?  This eats up a lot of cycles and is also completely unhelpful in this situation (or even a little harmful as it draws a box above the points)

 

And, because I've been frustrated with these other minor issues for a very long time, let me just put in a few other requests (ofc I am by no means expecting you guys to work on these issues, it would just be great if you did

  1. In JMP12, the order of objects was obeyed in the FrameBox -> Customize... (the right-click menu).  Specifically, when having rows selected, those selected points could be drawn over by any added graphics scripts that were listed after them in the list.  Starting with JMP14 (I never used JMP13, so I can't speak for it), selected points are drawn on top of every other thing.  This is problematic when dealing with many thousands of points and not being able to show trendlines or any other object above the points if they are selected.
    1. This really comes into play when a user selects a category in the legend and the points become selected -- suddenly the user cannot see the lines!!
    2. see below for some code showing this
  2. Also when drawing a grid (I do this for displaying die within a wafermap) on a GraphBox the grid is not anti-aliased.  When copying the image to a clipboard, again the image is not anti-aliased.  JMP12 would do the anti-aliasing and the images looked much better!
    1. see below for a comparison of JMP12 and JMP14/16 anti-aliasing

 

Example issue with selected points above all other possible elements:

 

Names Default to Here( 1 );
table = New Table( "test table",
	Add Rows( 150000 ),
	<<New Column( "X", "Numeric", <<Set Each Value( Random Normal() ) ),
	<<New Column( "Y", "Numeric", <<Set Each Value( Random Normal() ) )
);
Eval( Eval Expr(
New Window( "Test",
	<<On Close( Close( Expr( table ), No Save ) )
,
	Platform( table,
		ob = Outline Box( "",
			Bivariate(
				X( :x ),
				Y( :y )
			)
		)
	)
);
) );
(ob[Frame Box( 1 )] << Find Seg( Marker Seg( 1 ) )) << Set Transparency( 0.4 );
ob[Frame Box( 1 )] << Add Graphics Script(
	"FAKE_LINE_OF_FIT";
	Pen Color( "Black" );
	Pen Size( 4 );
	Line( [-5, 5], [-5, 5] );
	Pen Color( "Red" );
	Pen Size( 3 );
	Line( [-5, 5], [-5, 5] );
);

picture of issue:

 

ErraticAttack_4-1654888516417.png

Line should be drawn on-top of the data points.

ErraticAttack_5-1654888622055.png

JMP12 would draw in the correct order:

ErraticAttack_6-1654888697127.png

 

 

 

 

Anti-Aliasing examples:  (note that these are fake wafermaps that demonstrate my point)

JMP14/16: PrintScreen:

ErraticAttack_0-1654889154287.png

 

JMP14/16 CopyPicture:

ErraticAttack_1-1654888322124.png

 

JMP12 PrintScreen:

ErraticAttack_1-1654889173816.png

 

JMP12 CopyPicture:

ErraticAttack_3-1654888403359.png

 

Thanks!!