Skip to content

Commit b36a04b

Browse files
[flamegraph] Add diff modes
1 parent c0c4115 commit b36a04b

File tree

2 files changed

+77
-12
lines changed

2 files changed

+77
-12
lines changed

res/flamegraph/script.js

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const qString = new URLSearchParams(window.location.search)
1010
const transformFilterTemplate = document.getElementById('transformFilterTemplate');
1111
const transformReplaceTemplate = document.getElementById('transformReplaceTemplate');
1212
const minSamplesToShow = 0; // Don't hide any frames for now.
13+
const diffModeBtns = [diffModeBtn1, diffModeBtn2, diffModeBtn3, diffModeBtn4, diffModeBtn5];
1314
const profileId = "<<<profileId>>>";
1415

1516
/// Config handling
@@ -91,6 +92,8 @@ updateSidebarState();
9192

9293
var graphTitle = <<<graphTitle>>> || "Flamegraph";
9394
var isDiffgraph = <<<isDiffgraph>>>;
95+
var diffModes = ['bidi_diff', 'a_diff', 'b_diff', 'a', 'b'];
96+
var currentDiffModeIdx = 0;
9497
var b_scale_factor;
9598
var reverseGraph = false;
9699
var initialStacks = [];
@@ -104,8 +107,7 @@ if (isDiffgraph) {
104107
maxTooltipWidth = 350;
105108
} else {
106109
isNormalizedDiv.remove();
107-
tooltipSep2.remove();
108-
tooltipPctTotalSpan.remove();
110+
diffModeRow.remove();
109111
}
110112
tooltip.style['max-width'] = maxTooltipWidth + 'px';
111113
graphTitleSpan.innerText = graphTitle;
@@ -182,6 +184,7 @@ function applyConfig(config) {
182184
if (config.highlight) applyHighlight(config.highlight, true);
183185
if (config.reverse) setReverseGraph(true);
184186
if (config['sort-by'] == 'name') sortByNameRadio.checked = true;
187+
if (config.currentDiffModeIdx) currentDiffModeIdx = config.currentDiffModeIdx;
185188
if (config.transforms) {
186189
userTransforms = [];
187190
for (let configTransform of config.transforms) {
@@ -197,6 +200,8 @@ async function constructPackedConfig() {
197200
if (highlightState.pattern) config.highlight = _maybeRegexToString(highlightState.pattern);
198201
if (reverseGraph) config.reverse = true;
199202
if (sortByNameRadio.checked) config['sort-by'] = 'name';
203+
if (currentDiffModeIdx != 0)
204+
config.currentDiffModeIdx = currentDiffModeIdx;
200205

201206
let transformsData = [];
202207
for (let t of userTransforms) {
@@ -503,8 +508,37 @@ function generateLevelsDiffgraph(levels, node, title, level, x) {
503508

504509
levels[level] = levels[level] || [];
505510
var change = (node.total_samples_a == 0) ? 1.0 : node.total_delta / node.total_samples_a;
506-
var color = getDiffColor(change);
507-
levels[level].push({left: left, width: node.delta_abs,
511+
let width, self_offset, color;
512+
switch (diffModes[currentDiffModeIdx]) {
513+
case 'bidi_diff':
514+
width = node.delta_abs;
515+
self_offset = Math.abs(node.self_delta);
516+
color = getDiffColor(change);
517+
break;
518+
case 'a_diff':
519+
width = node.total_samples_a;
520+
self_offset = node.self_samples_a;
521+
color = getDiffColor(change);
522+
break;
523+
case 'b_diff':
524+
width = node.total_samples_b;
525+
self_offset = node.self_samples_b;
526+
color = getDiffColor(change);
527+
break;
528+
case 'a':
529+
width = node.total_samples_a;
530+
self_offset = node.self_samples_a;
531+
color = frameColor(title);
532+
break;
533+
case 'b':
534+
width = node.total_samples_b;
535+
self_offset = node.self_samples_b;
536+
color = frameColor(title);
537+
break;
538+
}
539+
540+
levels[level].push({left: left,
541+
width: width,
508542
self_samples_a: node.self_samples_a,
509543
self_samples_b: node.self_samples_b,
510544
self_delta: node.self_delta,
@@ -514,7 +548,7 @@ function generateLevelsDiffgraph(levels, node, title, level, x) {
514548
color: color,
515549
title: title});
516550

517-
left += Math.abs(node.self_delta);
551+
left += self_offset;
518552

519553
let children = Object.entries(node.children);
520554
if (sortByNameRadio.checked)
@@ -525,9 +559,17 @@ function generateLevelsDiffgraph(levels, node, title, level, x) {
525559
for (let i in children) {
526560
let title = children[i][0];
527561
let child = children[i][1];
528-
generateLevelsDiffgraph(levels, child, title, level+1, left);
529-
left += child.delta_abs;
562+
left += generateLevelsDiffgraph(levels, child, title, level+1, left);
530563
}
564+
return width;
565+
}
566+
567+
function setDiffMode(mode) {
568+
currentDiffModeIdx = mode;
569+
for (let btn of diffModeBtns)
570+
btn.classList.remove("toggled");
571+
diffModeBtns[mode].classList.add("toggled");
572+
fullRedraw();
531573
}
532574

533575
function generateLevels(node, title) {
@@ -782,7 +824,9 @@ function canvasOnMouseMove(e) {
782824
tooltip.style.animation = null;
783825

784826
var hoverTipText;
785-
if (isDiffgraph) {
827+
if (isDiffgraph && currentDiffModeIdx <= 2) {
828+
tooltipSep2.style.display = 'inline-block';
829+
tooltipPctTotalSpan.style.display = 'inline-block';
786830
var rel_change = (f.total_samples_a == 0) ? 1.0 : f.total_delta / f.total_samples_a;
787831
var total_change = f.total_delta / tree.total_samples_a;
788832
tooltipSamplesSpan.innerHTML = samples(f.total_delta, true, true);
@@ -791,9 +835,22 @@ function canvasOnMouseMove(e) {
791835
hoverTipText = `${f.title}\n(${samples(f.total_delta, true)}, ${ratioToPct(rel_change)} self, ${ratioToPct(total_change)} total)`;
792836
// , self_samples_a: ${f.self_samples_a}, self_samples_b: ${f.self_samples_b}, self_delta: ${f.self_delta}, total_samples_a: ${f.total_samples_a}, total_samples_b: ${f.total_samples_b}, total_delta: ${f.total_delta})`;
793837
} else {
794-
tooltipSamplesSpan.innerHTML = samples(f.width, false, true);
795-
tooltipPctSelfSpan.innerHTML = bold(pct(f.width, levels[0][0].width));
796-
hoverTipText = f.title + '\n(' + samples(f.width) + ', ' + pct(f.width, levels[0][0].width) + ')';
838+
tooltipSep2.style.display = 'none';
839+
tooltipPctTotalSpan.style.display = 'none';
840+
let width, total_width;
841+
if (isDiffgraph && currentDiffModeIdx == 3) {
842+
width = f.total_samples_a;
843+
total_width = levels[0][0].total_samples_a;
844+
} else if (isDiffgraph && currentDiffModeIdx == 4) {
845+
width = f.total_samples_b;
846+
total_width = levels[0][0].total_samples_b;
847+
} else {
848+
width = f.width;
849+
total_width = levels[0][0].width;
850+
}
851+
tooltipSamplesSpan.innerHTML = samples(width, false, true);
852+
tooltipPctSelfSpan.innerHTML = bold(pct(width, total_width));
853+
hoverTipText = f.title + '\n(' + samples(width) + ', ' + pct(width, total_width) + ')';
797854
}
798855

799856
let cursor_x = e.clientX + window.pageXOffset;

res/flamegraph/template.html

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
.toggle:hover {background-color: #e6f2ff; border-radius: 5px;}
5353
.toggle.arcs:hover svg {fill:#e6f2ff;}
5454
.toggle:active {transform:scale(0.90);}
55-
.toggle.toggled {background-color: #006d5b; border-radius: 5px;}
55+
.toggle.toggled {background-color:#006d5b; border-radius:5px; color:white;}
5656
.toggle.toggled svg {stroke:#fff; fill:#fff;}
5757
.toggle.toggled.arcs svg {fill:#006d5b;}
5858
.toggle.inversed svg { transform: scaleY(-1); }
@@ -164,6 +164,14 @@
164164
<svg><use href="#reverse-icon"/></svg>
165165
</button>
166166
</div>
167+
<div class="sidebar-row" id="diffModeRow">
168+
<div class="w-100"><strong>Diff mode</strong></div>
169+
<button id="diffModeBtn1" class="toggle toggled" onclick="setDiffMode(0)" title="Bidirectional diff">A|B</button>
170+
<button id="diffModeBtn2" class="toggle" onclick="setDiffMode(1)" title="Overlay diff over A">Aᴮ</button>
171+
<button id="diffModeBtn3" class="toggle" onclick="setDiffMode(2)" title="Overlay diff over B">ᴬB</button>
172+
<button id="diffModeBtn4" class="toggle" onclick="setDiffMode(3)" title="Just A">A</button>
173+
<button id="diffModeBtn5" class="toggle" onclick="setDiffMode(4)" title="Just B">B</button>
174+
</div>
167175
<div class="sidebar-row" id="isNormalizedDiv">
168176
<div class="w-100"><strong>Normalized</strong></div>
169177
<input type="checkbox" id="isNormalized" name="isNormalized" onchange="onTransformsChangedDontRecreate()">

0 commit comments

Comments
 (0)