Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion doc/changes/latest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ Enhancements
~~~~~~~~~~~~
- Update the ``notebook`` 3d backend to use ``ipyvtk_simple`` for a better integration within ``Jupyter`` (:gh:`8503` by `Guillaume Favelier`_)

- Speed up :func:`mne.inverse_sparse.tf_mixed_norm` using STFT/ISTFT linearity by `Eric Larson`_
- Add toggle-all button to :class:`mne.Report` HTML (:gh:`8723` by `Eric Larson`_)

- Speed up :func:`mne.inverse_sparse.tf_mixed_norm` using STFT/ISTFT linearity (:gh:`8697` by `Eric Larson`_)

Bugs
~~~~
Expand Down
53 changes: 0 additions & 53 deletions examples/visualization/plot_make_report.py

This file was deleted.

93 changes: 64 additions & 29 deletions mne/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,32 +526,60 @@ def _build_html_slider(slices_range, slides_klass, slider_id,
{{include}}
<script type="text/javascript">

var toggle_state = false;
function getAllOnOff() {
const all = $('.has_toggle');
const on = all.parent('.active').children('.has_toggle');
const off = all.not(on);
return [all, on, off];
}

function toggleAll(){
const [all, on, off] = getAllOnOff();
if (all.length == on.length)
on.trigger('click');
else
off.trigger('click');
updateToggleAllButton();
}

function updateToggleAllButton() {
const [all, on, off] = getAllOnOff();
const a = $('.mnetoggleall-btn').children();
if (all.length == on.length)
a.html('☒')
else
a.html('☑')
}

$(document).on('keydown', function (event) {
if (event.which == 84){
if (!toggle_state)
$('.has_toggle').trigger('click');
else if (toggle_state)
$('.has_toggle').trigger('click');
toggle_state = !toggle_state;
toggleAll();
}
});

function togglebutton(class_name){
$(class_name).toggle();

if ($(class_name + '-btn').hasClass('active'))
$(class_name + '-btn').removeClass('active');
else
$(class_name + '-btn').addClass('active');
function toggleButton(class_name){
if (class_name.includes('mnetoggleall'))
toggleAll();
else {
$(class_name).toggle();
if ($(class_name + '-btn').hasClass('active'))
$(class_name + '-btn').removeClass('active');
else
$(class_name + '-btn').addClass('active');
updateToggleAllButton();
}
}

/* Scroll down on click to #id so that caption is not hidden
by navbar */
/* Scroll down on click to #id so that caption is not hidden by navbar */
var shiftWindow = function() { scrollBy(0, -60) };
if (location.hash) shiftWindow();
window.addEventListener("hashchange", shiftWindow);

/* Update things when document is ready */
$( document ).ready(function() {
updateToggleAllButton();
});

</script>
<style type="text/css">

Expand Down Expand Up @@ -628,6 +656,13 @@ def _build_html_slider(slices_range, slides_klass, slider_id,
text-align: right;
}

.navbar-toggle:after {
content: "▲";
}
.navbar-toggle.collapsed:after {
content: "▼";
}

</style>
</head>
<body>
Expand All @@ -636,30 +671,30 @@ def _build_html_slider(slices_range, slides_klass, slider_id,
<div class="container-fluid">
<div class="navbar-header navbar-left">
<ul class="nav nav-pills"><li class="active">
<a class="navbar-btn" data-toggle="collapse"
data-target="#viewnavbar" href="javascript:void(0)">
></a></li></ul>
<a class="navbar-toggle" data-toggle="collapse" data-target="#viewnavbar" href="javascript:void(0)"></a>
</li></ul>
</div>
<h3 class="navbar-text" style="color:white">{{title}}</h3>
<ul class="nav nav-pills navbar-right" style="margin-top: 7px;"
id="viewnavbar">
<ul class="nav nav-pills navbar-right in" style="margin-top: 7px;" id="viewnavbar">

{{for section in sections}}

<li class="active {{sectionvars[section]}}-btn">
<a href="javascript:void(0)"
onclick="togglebutton('.{{sectionvars[section]}}')"
class="has_toggle">
{{section if section != 'mri' else 'MRI'}}
<a href="javascript:void(0)" onclick="toggleButton('.{{sectionvars[section]}}')" class="has_toggle">
{{section}}
</a>
</li>

{{endfor}}

<li class="active mnetoggleall-btn">
<a href="javascript:void(0)" onclick="toggleButton('.mnetoggleall')"> </a>
</li>

</ul>
</div>
</nav>
""")
""") # noqa: E501

footer_template = HTMLTemplate(u"""
</div></body>
Expand Down Expand Up @@ -871,9 +906,7 @@ class Report(object):

Notes
-----
See :ref:`tut-report` for an introduction to using ``mne.Report``, and
:ref:`this example <ex-report>` for an example of customizing the report
with a slider.
See :ref:`tut-report` for an introduction to using ``mne.Report``.

.. versionadded:: 0.8.0
"""
Expand Down Expand Up @@ -1723,9 +1756,11 @@ def _render_toc(self, verbose=None):
self._sectionlabels = sectionlabels

lang = getattr(self, 'lang', 'en-us')
sections = [section if section != 'mri' else 'MRI'
for section in self.sections]
html_header = header_template.substitute(
title=self.title, include=self.include, lang=lang,
sections=self.sections, sectionvars=self._sectionvars)
sections=sections, sectionvars=self._sectionvars)
self.html.insert(0, html_header) # Insert header at position 0
self.html.insert(1, html_toc) # insert TOC

Expand Down
26 changes: 20 additions & 6 deletions tutorials/misc/plot_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"""

import os
import matplotlib.pyplot as plt
import mne

###############################################################################
Expand Down Expand Up @@ -176,7 +177,8 @@
#
# The python interface has greater flexibility compared to the :ref:`command
# line interface <mne report>`. For example, custom plots can be added via
# the :meth:`~mne.Report.add_figs_to_section` method:
# the :meth:`~mne.Report.add_figs_to_section` method, and sliders with the
# :meth:`~mne.Report.add_slider_to_section`:

# generate a custom plot:
fname_evoked = os.path.join(path, 'MEG', 'sample', 'sample_audvis-ave.fif')
Expand All @@ -188,6 +190,17 @@

# add the custom plot to the report:
report.add_figs_to_section(fig, captions='Left Auditory', section='evoked')

# Add a custom section with an evoked slider:
figs = list()
times = evoked.times[::30]
for t in times:
figs.append(evoked.plot_topomap(t, vmin=-300, vmax=300, res=100,
show=False))
plt.close(figs[-1])
report.add_slider_to_section(figs, times, 'Evoked Response',
image_format='png') # can also use 'svg'

report.save('report_custom.html', overwrite=True)

###############################################################################
Expand All @@ -200,13 +213,14 @@
# :meth:`~mne.Report.add_figs_to_section` command. Each section is identified
# by a toggle button in the top navigation bar of the report which can be used
# to show or hide the contents of the section. To toggle the show/hide state of
# all sections in the HTML report, press :kbd:`t`.
# all sections in the HTML report, press :kbd:`t`, or press the toggle-all
# button in the upper right.
#
# .. note::
# .. sidebar:: Structure
#
# Although we've been generating separate reports in each example, you could
# easily create a single report for all :file:`.fif` files (raw, evoked,
# covariance, etc) by passing ``pattern='*.fif'``.
# Although we've been generating separate reports in each of these examples,
# you could easily create a single report for all :file:`.fif` files (raw,
# evoked, covariance, etc) by passing ``pattern='*.fif'``.
#
#
# Editing a saved report
Expand Down