cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Try the Materials Informatics Toolkit, which is designed to easily handle SMILES data. This and other helpful add-ins are available in the JMP® Marketplace
Choose Language Hide Translation Bar
jc510_2
Level III

Progress bars – my personal journey (also questions about manipulating windows in the project environment)

[JMP 17.0.0]

I have a project file I’ve been working on that has many data tables, each with a relatively long-running script I use to generate a journal as output.  I have a separate script in another table that calls each of the individual table scripts, then collates the individual journals into a single journal to create a final report.  [I probably could have made this approach a lot cleaner, but I’m not a full- (or even part-) time coder.]

I wanted to implement some kind of “X of Y completed” update progress bar / message box to keep track of run progress after execution of each individual table script.

This is the story about how I came to my current solution.

 

TL;DR – After spending a day coming up with a clever-to-me-alone approach, I came across Caption(), which would have been the easiest thing to do.

 

But I still have some general questions about how windows can be manipulated within the project environment – so stick with me if you’re interested.

 

There are several great implementation ideas I came across while searching Discussions, including:

https://community.jmp.com/t5/Uncharted/Progress-Bar/ba-p/21160

https://community.jmp.com/t5/Uncharted/Progress-Bar-with-Cancel-Button/ba-p/433560#U433560

https://community.jmp.com/t5/Discussions/Suggestion-on-how-to-script-a-small-update-progress-window-...

 

However, when I try to implement these solutions within a project environment, the new progress bar that gets created is always created as a new tab in the project.  When the next script in the series starts, the progress bar window gets buried by the subsequent data table manipulations associated with the script, so you never see the updated progress message.

General Question #1:  I can’t figure out how to create a “pop-out” window as a message box without it being a modal window.  My understanding is that modal windows pause the script until the user has interacted with the window, which is what I don’t want.  Is there something I’m missing about how I can create a new non-modal window as a “pop-out” instead of as a new tab?

[Again, I realize now that there is such a thing as Caption().  But I still have this general question about whether all new windows in a project have to be opened as new tabs as opposed to a pop-out window.]

General Question #2:  Then I thought…maybe there’s a way to dock this newly created progress bar window to another location in the project layout so that it’s separated from the rest of the action – e.g., New Window() << Dock( “Right”).  But I haven’t been able to find anything like that.  Is there a way to script docking location of a window?

Then I spent a bunch of time learning how project layouts work and how they can be scripted.  I learned a ton from that exercise.  In the end, I came up with a script that temporarily changes the project layout to replace the “Recent Files” window with a custom “Progress Update” window that does what I’m looking for, and then reverts back to the “Recent Files” window.  As you might imagine, it’s a pretty clumsy script, but it gets the job done.  I tried to generalize it as best as I could and have attached it here in case anyone is interested to see how it works.

At some point in the day I realized that maybe there’s a way to make this work by forcing new windows created by the individual scripts to be invisible, so that the progress bar window would stay on top.  But that would have been better done had I thought of it up front.  At this point I would have to make a couple hundred script edits to achieve this option (if it’s possible).

After all that, I came in to work this morning to tell you all this story, and almost immediately came across Caption() – which does basically everything I wanted to do in two succinct lines of code.  I just wish I had realized that earlier.  I guess if you really wanted to have a true progress “bar” and not just text, maybe Caption() wouldn’t work.  But I didn’t really need this to be that fancy.

Thank you for listening.

Joel

2 ACCEPTED SOLUTIONS

Accepted Solutions
jthi
Super User

Re: Progress bars – my personal journey (also questions about manipulating windows in the project environment)

When I attended JMP user experience lab (or something similar) in discovery summit, it was one of the first times of me using projects (I had used them earlier but quickly stopped due to window stealing). I did make few usability suggestions and turned some into wish list items.

Add option to not contain all windows to JMP Project's (related to this topic)

Add grouping option (by data table) to JMP Project's tab/sheet/report selector - JMP User Community

Add option to make new reports in JMP Project's to be opened after the data tabl... - JMP User Commu...

Improve (non)self-contained content management in JMP Projects  (this was created later)

 

That window stealing is still my main reason to not even trying out projects currently.

 

Caption can luckily be used in projects and you can even turn it into fairly usable progress bar. I'm not sure what type of progress bar you did create using Caption() but I quickly modified one my progressbar classes which uses text instead of displayboxes as same idea could be used with caption

Names Default To Here(1);
// https://www.jmp.com/support/help/en/17.2/index.shtml#page/jmp/send-information-to-a-user.shtml

max_iteration = 20;
current_iteration = 1;

update_txt = Expr(
	cur_val = Floor(current_iteration / (max_iteration / 10));
	process_text = "Running...";
	progress_done = Repeat("", cur_val);
	progress_left = Repeat("", 10 - cur_val);
	progress_text_line = Char(Round(100 * cur_val / 10, 2)) || "%";

	progress_text = Eval Insert("^process_text^\!N^progress_done^^progress_left^\!N^progress_text_line^");
);

Caption({800, 900}, progress_text, Font("Arial Black"), Font Size(20), Text Color("blue"), Back Color("yellow"));

For(i = 1, i <= max_iteration, i++,
	current_iteration = i;
	update_txt;
	Caption(progress_text, Font("Arial Black"), Font Size(20), Text Color("blue"), Back Color("yellow"));
	wait(0.1);
);
Caption(remove);

jthi_0-1700199991012.png

 

Most likely I will use something like this next year, when I have to do a script which uses JMP projects.

-Jarmo

View solution in original post

jc510_2
Level III

Re: Progress bars – my personal journey (also questions about manipulating windows in the project environment)

Haha - my original Caption attempt was as simple as this:

jc510_2_0-1700254043192.png

@jthi - Your solution is definitely more elegant, and I have already abandoned all of my prior approaches in favor of yours.  Thank you for the suggestion Jarmo!

I had to make a couple of edits to your script to get it to work for me - I changed the string for the Caption() parameter from progress_text to update_txt, and replaced the "black/white_large_square"s with unicode characters.  I also added some lines to approximately center the caption box in the project window.  I posted the revised script below.

Also thank you for pointing me to the "Send Inrofmation to a User" section of the documentation library.  Now I see there is also a way to send messages to the status bar with StatusMsg().  By replacing the calls to Caption() with calls to StatusMsg(), you can get the same effect without needing a pop-up window or messing around with the project layout as I had been doing.  I also posted that version below.

[EDIT: After playing around with the StatusMsg() option some more, I'm finding that it may be difficult to keep the progress bar persistently displayed depending on how many other script-associated (but not scripted) messages are sent to the status bar while your script runs.  The Caption() approach still works fine and is likely the best of the two approaches in most scenarios.]

For me, I have been working with projects for a while now.  I guess I subconsciously know that it isn't a requirement to work in projects, but I like the table/tab organization aspect.  This is the first time I ran into a significant issue working with projects, but after looking at the other potential improvements you have raised, I agree there are things that can be improved.

Revised Caption() script:

Names Default To Here(1);

proj = This Project();

projWidth = proj << Get Width;
projHeight = proj << Get Height;
windowPos = proj << Get Window Position();

capPos_h = windowPos[1] + ( projWidth / 2) - 75;
capPos_v = windowPos[2] + ( projHeight / 2);

max_iteration = 20;
current_iteration = 1;

update_txt = Expr(
	cur_val = Floor(current_iteration / (max_iteration / 10));
	process_text = "Running...";
	progress_done = Repeat("\!U2B1B", cur_val);
	progress_left = Repeat("\!U2B1C", 10 - cur_val);
	progress_text_line = " " || Char(Round(100 * cur_val / 10, 2)) || "%";

	progress_text = Eval Insert("^process_text^\!N^progress_done^^progress_left^\!N^progress_text_line^");
);

Caption({capPos_h, capPos_v}, update_txt, Font("Arial Black"), Font Size(20), Text Color("blue"), Back Color("yellow"));

For(i = 1, i <= max_iteration, i++,
	current_iteration = i;
	Caption( update_txt, Font("Arial Black"), Font Size(20), Text Color("blue"), Back Color("yellow"));
	Wait(0.1);
);

Caption(remove);

StatusMsg() script:

Names Default To Here(1);

max_iteration = 20;
current_iteration = 1;

update_txt = Expr(
	cur_val = Floor(current_iteration / (max_iteration / 10));
	process_text = "Running...";
	progress_done = Repeat("\!U2B1B", cur_val);
	progress_left = Repeat("\!U2B1C", 10 - cur_val);
	progress_text_line = " " || Char(Round(100 * cur_val / 10, 2)) || "%";

	progress_text = Eval Insert("^process_text^\!N^progress_done^^progress_left^\!N^progress_text_line^");
);

For(i = 1, i <= max_iteration, i++,
	current_iteration = i;
	StatusMsg( update_txt);
	Wait(0.1);
);

StatusMsg( "Done!         " || progress_done || progress_left || progress_text_line);
Wait(2);
StatusMsg( " ");

-Joel

View solution in original post

3 REPLIES 3
jthi
Super User

Re: Progress bars – my personal journey (also questions about manipulating windows in the project environment)

When I attended JMP user experience lab (or something similar) in discovery summit, it was one of the first times of me using projects (I had used them earlier but quickly stopped due to window stealing). I did make few usability suggestions and turned some into wish list items.

Add option to not contain all windows to JMP Project's (related to this topic)

Add grouping option (by data table) to JMP Project's tab/sheet/report selector - JMP User Community

Add option to make new reports in JMP Project's to be opened after the data tabl... - JMP User Commu...

Improve (non)self-contained content management in JMP Projects  (this was created later)

 

That window stealing is still my main reason to not even trying out projects currently.

 

Caption can luckily be used in projects and you can even turn it into fairly usable progress bar. I'm not sure what type of progress bar you did create using Caption() but I quickly modified one my progressbar classes which uses text instead of displayboxes as same idea could be used with caption

Names Default To Here(1);
// https://www.jmp.com/support/help/en/17.2/index.shtml#page/jmp/send-information-to-a-user.shtml

max_iteration = 20;
current_iteration = 1;

update_txt = Expr(
	cur_val = Floor(current_iteration / (max_iteration / 10));
	process_text = "Running...";
	progress_done = Repeat("", cur_val);
	progress_left = Repeat("", 10 - cur_val);
	progress_text_line = Char(Round(100 * cur_val / 10, 2)) || "%";

	progress_text = Eval Insert("^process_text^\!N^progress_done^^progress_left^\!N^progress_text_line^");
);

Caption({800, 900}, progress_text, Font("Arial Black"), Font Size(20), Text Color("blue"), Back Color("yellow"));

For(i = 1, i <= max_iteration, i++,
	current_iteration = i;
	update_txt;
	Caption(progress_text, Font("Arial Black"), Font Size(20), Text Color("blue"), Back Color("yellow"));
	wait(0.1);
);
Caption(remove);

jthi_0-1700199991012.png

 

Most likely I will use something like this next year, when I have to do a script which uses JMP projects.

-Jarmo
jc510_2
Level III

Re: Progress bars – my personal journey (also questions about manipulating windows in the project environment)

Haha - my original Caption attempt was as simple as this:

jc510_2_0-1700254043192.png

@jthi - Your solution is definitely more elegant, and I have already abandoned all of my prior approaches in favor of yours.  Thank you for the suggestion Jarmo!

I had to make a couple of edits to your script to get it to work for me - I changed the string for the Caption() parameter from progress_text to update_txt, and replaced the "black/white_large_square"s with unicode characters.  I also added some lines to approximately center the caption box in the project window.  I posted the revised script below.

Also thank you for pointing me to the "Send Inrofmation to a User" section of the documentation library.  Now I see there is also a way to send messages to the status bar with StatusMsg().  By replacing the calls to Caption() with calls to StatusMsg(), you can get the same effect without needing a pop-up window or messing around with the project layout as I had been doing.  I also posted that version below.

[EDIT: After playing around with the StatusMsg() option some more, I'm finding that it may be difficult to keep the progress bar persistently displayed depending on how many other script-associated (but not scripted) messages are sent to the status bar while your script runs.  The Caption() approach still works fine and is likely the best of the two approaches in most scenarios.]

For me, I have been working with projects for a while now.  I guess I subconsciously know that it isn't a requirement to work in projects, but I like the table/tab organization aspect.  This is the first time I ran into a significant issue working with projects, but after looking at the other potential improvements you have raised, I agree there are things that can be improved.

Revised Caption() script:

Names Default To Here(1);

proj = This Project();

projWidth = proj << Get Width;
projHeight = proj << Get Height;
windowPos = proj << Get Window Position();

capPos_h = windowPos[1] + ( projWidth / 2) - 75;
capPos_v = windowPos[2] + ( projHeight / 2);

max_iteration = 20;
current_iteration = 1;

update_txt = Expr(
	cur_val = Floor(current_iteration / (max_iteration / 10));
	process_text = "Running...";
	progress_done = Repeat("\!U2B1B", cur_val);
	progress_left = Repeat("\!U2B1C", 10 - cur_val);
	progress_text_line = " " || Char(Round(100 * cur_val / 10, 2)) || "%";

	progress_text = Eval Insert("^process_text^\!N^progress_done^^progress_left^\!N^progress_text_line^");
);

Caption({capPos_h, capPos_v}, update_txt, Font("Arial Black"), Font Size(20), Text Color("blue"), Back Color("yellow"));

For(i = 1, i <= max_iteration, i++,
	current_iteration = i;
	Caption( update_txt, Font("Arial Black"), Font Size(20), Text Color("blue"), Back Color("yellow"));
	Wait(0.1);
);

Caption(remove);

StatusMsg() script:

Names Default To Here(1);

max_iteration = 20;
current_iteration = 1;

update_txt = Expr(
	cur_val = Floor(current_iteration / (max_iteration / 10));
	process_text = "Running...";
	progress_done = Repeat("\!U2B1B", cur_val);
	progress_left = Repeat("\!U2B1C", 10 - cur_val);
	progress_text_line = " " || Char(Round(100 * cur_val / 10, 2)) || "%";

	progress_text = Eval Insert("^process_text^\!N^progress_done^^progress_left^\!N^progress_text_line^");
);

For(i = 1, i <= max_iteration, i++,
	current_iteration = i;
	StatusMsg( update_txt);
	Wait(0.1);
);

StatusMsg( "Done!         " || progress_done || progress_left || progress_text_line);
Wait(2);
StatusMsg( " ");

-Joel

pmroz
Super User

Re: Progress bars – my personal journey (also questions about manipulating windows in the project environment)

Sounds like you're making good progress