clear_output improvements #1563

Merged
merged 4 commits into from Apr 14, 2012

Projects

None yet

4 participants

@minrk
Member
minrk commented Apr 9, 2012

This was a part of PR #1548, but as I kept finding issues, I decided this should be a separate PR. That PR does depend on this one, and should not be merged before this one.

Changes:

  • clear_output() clears the line, even in terminal IPython, the QtConsole and plain Python as well, by printing \r to streams.
  • clear_output() avoids the flicker in the notebook by adding a delay, and firing immediately upon the next actual display message.
  • display_javascript hides its output_area element, so using display to run a bunch of javascript doesn't result in ever-growing vertical space.
@ellisonbg ellisonbg and 1 other commented on an outdated diff Apr 9, 2012
IPython/frontend/html/notebook/static/js/codecell.js
@@ -683,6 +690,9 @@ var IPython = (function (IPython) {
// We just eval the JS code, element appears in the local scope.
var element = $("<div/>").addClass("box_flex1 output_subarea");
e.append(element);
+ // Div for js shouldn't be drawn, as it will add empty height to the area.
@ellisonbg
ellisonbg Apr 9, 2012 IPython member

Are you hiding the entire output_area for that cell? If so, won't the javascript be unable to append things to the output area and have them show up on the screen?

@minrk
minrk Apr 9, 2012 IPython member

Yes I am. The js can call e.show() if it wants to draw. But it is certainly true that if there is nothing to draw, the height should be zero (right now it's ~15 px, so running a series of js calls results in infinitely growing vertical space).

@ellisonbg
ellisonbg Apr 9, 2012 IPython member

OK, we should document the fact that the users needs to call the show method. Not sure where to put that documentation. I agree that this is a good idea though.

@minrk
minrk Apr 9, 2012 IPython member

Documented in the Javascript object docstring.

@ellisonbg ellisonbg and 1 other commented on an outdated diff Apr 9, 2012
IPython/frontend/html/notebook/static/js/codecell.js
@@ -730,7 +740,31 @@ var IPython = (function (IPython) {
CodeCell.prototype.clear_output = function (stdout, stderr, other) {
+ var that = this;
+ if (this.clear_out_timeout != null){
+ // fire previous pending clear *immediately*
+ clearTimeout(this.clear_out_timeout);
+ this.clear_out_timeout = null;
+ this.clear_output_callback(this._clear_stdout, this._clear_stderr, this._clear_other);
+ }
+ // store flags for flushing the timeout
+ this._clear_stdout = stdout;
+ this._clear_stderr = stderr;
+ this._clear_other = other;
+ this.clear_out_timeout = setTimeout(function(){
+ // really clear timeout only after a short delay
+ // this reduces flicker in 'clear_output; print' cases
+ console.log("clear_out_timeout");
@ellisonbg
ellisonbg Apr 9, 2012 IPython member

Let's remove the console.log before merging.

@minrk
minrk Apr 9, 2012 IPython member

removed.

@ellisonbg
Member

These are clear improvements to the clear_output logic. Have not tested it, but the code looks good.

minrk added some commits Apr 4, 2012
@minrk minrk [notebook] clear_output is handled after a delay
This reduces flicker during common loops like:

for step in stuff:
    clear_output()
    print something

the timeout is flushed *immediately* on any subsequent output.
0960f3b
@minrk minrk hide output_area for js
prevents growing vertical space from adding empty output_areas.
e169ad6
@minrk minrk document initially hidden javascript container 24972e2
@minrk
Member
minrk commented Apr 9, 2012

Here is a notebook with text progress bar using clear_output improvements and simple javascript progress bar using js changes.

Writing a javascript progress bar is really trivial:

import uuid
from IPython.core.display import HTML, Javascript, display

divid = str(uuid.uuid4())

display(HTML(
"""
<div style="border: 1px solid black; width:500px">
  <div id="%s" style="background-color:blue; width:0%%">&nbsp;</div>
</div> 
""" % divid)
)

for i in range(1,101):
    time.sleep(0.1)
    display(Javascript("$('div#%s').width('%i%%')" % (divid, i)))
@ellisonbg
Member

This is extremely cool!

@Carreau
Member
Carreau commented Apr 10, 2012

I came across this article :
http://www.alsacreations.com/article/lire/1416-html5-meter-progress.html
I just learn that it seems that HTML5 support 'native' progress bar (not all browser implement it yet).

Just for the record of course. A div with a width is perfectly fine with me. :-)

@fperez
Member
fperez commented Apr 14, 2012

The code looks good to me and the functionality is fantastic, great job! I'll merge now, but I want to make a suggestion: @minrk, with just adding a tiny bit of explanatory text (a title and a short paragraph before each cell should suffice), your progressbar notebook should really go into the doc examples! It's a great little illustration of how to use the system which I'm sure many people will find useful.

I won't delay this PR on that alone, esp. since #1548 depends on this one, so I'll merge now. Great work!!

@fperez fperez merged commit d66ece6 into ipython:master Apr 14, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment