Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename flamegraph "Invert" button #456

Merged
merged 1 commit into from
Sep 18, 2023
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
Binary file added docs/_static/images/icicle_flame_toggle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/_static/images/invert_button.png
Binary file not shown.
29 changes: 17 additions & 12 deletions docs/flamegraph.rst
Original file line number Diff line number Diff line change
Expand Up @@ -196,19 +196,24 @@ checkbox:
Note that allocations in these frames will still be accounted for
in parent frames, even if they're hidden.

Inverted View
-----------------

Although the flame graphs explained above show the calling functions below
and memory allocating functions above, flame graphs can be inverted
so that the calling functions are at the top, while memory allocating
functions are at the bottom. In this view, look for wide ceilings
instead of wide plateaus to find functions with the largest allocation
of memory.

To invert the flame graph, press the *Invert* button:
Flames versus Icicles
---------------------

.. image:: _static/images/invert_button.png
The flame graphs explained above show each function above its caller,
with the root at the bottom. This is what's traditionally called
a "flame graph", because the wide base with narrowing columns above it
looks sort of like a burning log with flames leaping into the air above
it. Memray also supports what's sometimes called an "icicle graph",
which has the root at the top. In an icicle graph, each function is
below its caller, and there is a wide ceiling that thinner columns
descend from, like icicles hanging from a roof. Whichever of these modes
you choose, the data shown in the table is the same, just mirrored
vertically.

You can switch between showing a flame graph and an icicle graph with
this toggle button:

.. image:: _static/images/icicle_flame_toggle.png
:align: center

.. _memory-leaks-view:
Expand Down
3 changes: 2 additions & 1 deletion src/memray/reporters/assets/flamegraph.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ function main() {
}

// Setup event handlers
document.getElementById("invertButton").onclick = onInvert;
document.getElementById("icicles").onchange = onInvert;
document.getElementById("flames").onchange = onInvert;
document.getElementById("resetZoomButton").onclick = onResetZoom;
document.getElementById("resetThreadFilterItem").onclick = onFilterThread;
let hideUninterestingCheckBox = document.getElementById("hideUninteresting");
Expand Down
5 changes: 4 additions & 1 deletion src/memray/reporters/assets/flamegraph_common.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@ export function handleFragments() {

// For the invert button
export function onInvert() {
chart.inverted(!chart.inverted());
chart.inverted(this === document.getElementById("icicles"));
chart.resetZoom(); // calls onClick

// Hide the tooltip for the radio button that was just clicked.
$('[data-toggle="tooltip"]').tooltip("hide");
}

export function onResetZoom() {
Expand Down
3 changes: 2 additions & 1 deletion src/memray/reporters/assets/temporal_flamegraph.js
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,8 @@ function main() {
}

// Setup event handlers
document.getElementById("invertButton").onclick = onInvert;
document.getElementById("icicles").onchange = onInvert;
document.getElementById("flames").onchange = onInvert;
document.getElementById("resetZoomButton").onclick = onResetZoom;
document.getElementById("resetThreadFilterItem").onclick = onFilterThread;
let hideUninterestingCheckBox = document.getElementById("hideUninteresting");
Expand Down
8 changes: 8 additions & 0 deletions src/memray/reporters/templates/assets/flamegraph.css
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,11 @@
background-color: rgba(0, 0, 0, 0.5); /* semi-transparent black */
z-index: 99; /* make sure it's on top of other elements */
}

.flamegraph-icon {
display: flex;
align-items: center;
justify-content: center;
}

.flipped svg { transform: scale(1,-1); }
2 changes: 1 addition & 1 deletion src/memray/reporters/templates/assets/flamegraph.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

23 changes: 22 additions & 1 deletion src/memray/reporters/templates/flamegraph.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,29 @@
title="Hide frames related to the Python import system" >
<label class="form-check-label text-white bg-dark">Hide Import System Frames</label>
</div>
<div class="btn-group btn-group-toggle mr-3" data-toggle="buttons">
<label class="btn btn-outline-light shadow-none" data-container="body" data-toggle="tooltip" title="Enable flame graph mode: functions above their callers with the root at the bottom">
<input type="radio" name="flames/icicles" id="flames" autocomplete="off">
<div class="flamegraph-icon flipped">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path d="M 1 1 h 22 Z M 11 6 h 10 Z M 1 6 h 7 Z M 11 11 h 7 Z M 1 11 h 4 Z M 11 16 h 4 Z M 1 16 h 2 Z M 11 21 h 2 Z"/>
</svg>
</div>
&nbsp;
Flames
</label>
<label class="btn btn-outline-light active shadow-none" data-container="body" data-toggle="tooltip" title="Enable icicle graph mode: functions below their callers with the root at the top">
<input type="radio" name="flames/icicles" id="icicles" autocomplete="off" checked/>
Icicles
&nbsp;
<div class="flamegraph-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path d="M 1 1 h 22 Z M 11 6 h 10 Z M 1 6 h 7 Z M 11 11 h 7 Z M 1 11 h 4 Z M 11 16 h 4 Z M 1 16 h 2 Z M 11 21 h 2 Z"/>
</svg>
</div>
</label>
</div>
<button id="resetZoomButton" class="btn btn-outline-light mr-3">Reset Zoom</button>
<button id="invertButton" class="btn btn-outline-light mr-3">Invert</button>
{% endblock %}

{% block content %}
Expand Down
Loading