Skip to content

Commit b0937b8

Browse files
authored
Merge pull request #1022 from jcb91/exec_time
[ExecuteTime] menu items & options for clearing timing data
2 parents c4baa93 + 3aa4242 commit b0937b8

File tree

3 files changed

+104
-29
lines changed

3 files changed

+104
-29
lines changed

src/jupyter_contrib_nbextensions/nbextensions/execute_time/ExecuteTime.js

Lines changed: 84 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ define([
3333

3434
// defaults, overridden by server's config
3535
var options = {
36+
clear_timings_on_clear_output: false,
37+
clear_timings_on_kernel_restart: false,
3638
default_kernel_to_utc: true,
3739
display_absolute_format: 'HH:mm:ss YYYY-MM-DD',
3840
display_absolute_timings: true,
@@ -43,7 +45,7 @@ define([
4345
color: '#00bb00',
4446
},
4547
relative_timing_update_period: 10,
46-
template :{
48+
template: {
4749
executed: 'executed in ${duration}, finished ${end_time}',
4850
queued: 'execution queued ${start_time}',
4951
},
@@ -79,60 +81,104 @@ define([
7981
};
8082
}
8183

82-
function toggle_timing_display (cell, vis) {
83-
if (cell instanceof CodeCell) {
84-
var ce = cell.element;
85-
var timing_area = ce.find('.timing_area');
86-
if (timing_area.length > 0) {
87-
if (vis === undefined) {
88-
vis = !timing_area.is(':visible');
89-
}
90-
timing_area.toggle(vis);
91-
return vis;
92-
}
93-
}
84+
function patch_CodeCell_clear_output () {
85+
console.log(log_prefix, 'Patching CodeCell.prototype.clear_output to clear timings also.');
86+
var orig_clear_output = CodeCell.prototype.clear_output;
87+
CodeCell.prototype.clear_output = function () {
88+
var ret = orig_clear_output.apply(this, arguments);
89+
clear_timing_data([this]);
90+
return ret;
91+
};
9492
}
9593

96-
function toggle_timing_display_multiple (cells, vis) {
94+
function toggle_timing_display (cells, vis) {
9795
for (var i = 0; i < cells.length; i++) {
98-
if (cells[i] instanceof CodeCell) {
99-
vis = toggle_timing_display(cells[i], vis);
96+
var cell = cells[i];
97+
if (cell instanceof CodeCell) {
98+
var ce = cell.element;
99+
var timing_area = ce.find('.timing_area');
100+
if (timing_area.length > 0) {
101+
if (vis === undefined) {
102+
vis = !timing_area.is(':visible');
103+
}
104+
timing_area.toggle(vis);
105+
}
100106
}
101107
}
108+
return vis;
109+
}
110+
111+
function clear_timing_data (cells) {
112+
cells.forEach(function (cell, idx, arr) {
113+
delete cell.metadata.ExecuteTime;
114+
cell.element.find('.timing_area').remove();
115+
});
116+
events.trigger('set_dirty.Notebook', {value: true});
102117
}
103118

104-
function toggle_timing_display_selected () {
105-
toggle_timing_display_multiple(Jupyter.notebook.get_selected_cells());
119+
function clear_timing_data_all () {
120+
console.log(log_prefix, 'Clearing all timing data');
121+
clear_timing_data(Jupyter.notebook.get_cells());
106122
}
107123

108124
function create_menu () {
109-
var menu_toggle_timings = $('<li/>')
125+
var timings_menu_item = $('<li/>')
110126
.addClass('dropdown-submenu')
111127
.append(
112-
$('<a/>').text('Toggle timings')
128+
$('<a href="#">')
129+
.text('Execution Timings')
130+
.on('click', function (evt) { evt.preventDefault(); })
113131
)
114132
.appendTo($('#cell_menu'));
115133

116134
var timings_submenu = $('<ul/>')
117135
.addClass('dropdown-menu')
118-
.appendTo(menu_toggle_timings);
136+
.appendTo(timings_menu_item);
119137

120138
$('<li/>')
121139
.attr('title', 'Toggle the timing box for the selected cell(s)')
122140
.append(
123-
$('<a/>')
124-
.text('Selected')
125-
.on('click', toggle_timing_display_selected)
141+
$('<a href="#">')
142+
.text('Toggle visibility (selected)')
143+
.on('click', function (evt) {
144+
evt.preventDefault();
145+
toggle_timing_display(Jupyter.notebook.get_selected_cells());
146+
})
126147
)
127148
.appendTo(timings_submenu);
128149

129150
$('<li/>')
130151
.attr('title', 'Toggle the timing box for all cells')
131152
.append(
132-
$('<a/>')
133-
.text('All')
153+
$('<a href="#">')
154+
.text('Toggle visibility (all)')
155+
.on('click', function (evt) {
156+
evt.preventDefault();
157+
toggle_timing_display(Jupyter.notebook.get_cells());
158+
})
159+
)
160+
.appendTo(timings_submenu);
161+
162+
$('<li/>')
163+
.attr('title', 'Clear the selected cell(s) timing data')
164+
.append(
165+
$('<a href="#">')
166+
.text('Clear (selected)')
167+
.on('click', function (evt) {
168+
evt.preventDefault();
169+
clear_timing_data(Jupyter.notebook.get_selected_cells());
170+
})
171+
)
172+
.appendTo(timings_submenu);
173+
174+
$('<li/>')
175+
.attr('title', 'Clear the timing data from all cells')
176+
.append(
177+
$('<a href="#">')
178+
.text('Clear (all)')
134179
.on('click', function (evt) {
135-
toggle_timing_display_multiple(Jupyter.notebook.get_cells());
180+
evt.preventDefault();
181+
clear_timing_data(Jupyter.notebook.get_cells());
136182
})
137183
)
138184
.appendTo(timings_submenu);
@@ -209,13 +255,13 @@ define([
209255
if (timing_area.length < 1) {
210256
timing_area = $('<div/>')
211257
.addClass('timing_area' + (options.display_right_aligned ? ' text-right' : ''))
212-
.on('dblclick', function (evt) { toggle_timing_display(cell); })
258+
.on('dblclick', function (evt) { toggle_timing_display([cell]); })
213259
.appendTo(cell.element.find('.input_area'));
214260
}
215261

216262
var start_time = moment(cell.metadata.ExecuteTime.start_time),
217263
end_time = cell.metadata.ExecuteTime.end_time;
218-
var msg = options.template[end_time ? 'executed' : 'queued']
264+
var msg = options.template[end_time ? 'executed' : 'queued'];
219265
msg = msg.replace('${start_time}', format_moment(start_time));
220266
if (end_time) {
221267
end_time = moment(end_time);
@@ -277,6 +323,15 @@ define([
277323
update_all_timing_areas();
278324
}
279325

326+
// setup optional clear-data calls
327+
if (options.clear_timings_on_clear_output) {
328+
patch_CodeCell_clear_output();
329+
}
330+
if (options.clear_timings_on_kernel_restart) {
331+
console.log(log_prefix, 'Binding kernel_restarting.Kernel event to clear timings.');
332+
events.on('kernel_restarting.Kernel', clear_timing_data_all);
333+
}
334+
280335
// if displaying relative times, update them at intervals
281336
if (!options.display_absolute_timings) {
282337
var period_ms = 1000 * Math.max(1, options.relative_timing_update_period);

src/jupyter_contrib_nbextensions/nbextensions/execute_time/ExecuteTime.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ Main: ExecuteTime.js
77
Compatibility: 4.x, 5.x
88
Parameters:
99

10+
- name: ExecuteTime.clear_timings_on_clear_output
11+
description: |
12+
When cells' outputs are cleared, also clear their timing data, e.g. when
13+
using the "Kernel > Restart & Clear Output" menu item
14+
input_type: checkbox
15+
default: false
16+
17+
- name: ExecuteTime.clear_timings_on_kernel_restart
18+
description: |
19+
Clear all cells' execution timing data on any kernel restart event
20+
input_type: checkbox
21+
default: false
22+
1023
- name: ExecuteTime.display_absolute_timings
1124
description: |
1225
Display absolute timings for the start time of execution.

src/jupyter_contrib_nbextensions/nbextensions/execute_time/readme.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ ConfigManager().update('notebook', {'ExecuteTime': {
6060

6161
The available options are:
6262

63+
* `ExecuteTime.clear_timings_on_clear_output`: When cells' outputs are cleared,
64+
also clear their timing data, e.g. when using the
65+
`Kernel > Restart & Clear Output` menu item
66+
67+
* `ExecuteTime.clear_timings_on_kernel_restart`: Clear all cells' execution
68+
timing data on any kernel restart event
69+
6370
* `ExecuteTime.display_absolute_timings`: Display absolute timings for the
6471
start/end time of execution. Setting this `false` will result in the display
6572
of a relative timestamp like 'a few seconds ago' (see the moment.js function

0 commit comments

Comments
 (0)