Skip to content
Open
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
2 changes: 2 additions & 0 deletions src/flamegraph/flamegraph.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#matched { text-anchor:end; }
#search { text-anchor:end; opacity:0.1; cursor:pointer; }
#search:hover, #search.show { opacity:1; }
#ignorecase { text-anchor:end; opacity:0.1; cursor:pointer; }
#ignorecase:hover, #ignorecase.show { opacity:1; }
#subtitle { text-anchor:middle; font-color:rgb(160,160,160); }
#unzoom { cursor:pointer; }
#frames > *:hover { stroke:black; stroke-width:0.5; cursor:pointer; }
Expand Down
57 changes: 51 additions & 6 deletions src/flamegraph/flamegraph.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
"use strict";
var details, searchbtn, unzoombtn, matchedtxt, svg, searching, frames, known_font_width;
var details, searchbtn, ignorecasebtn, unzoombtn, matchedtxt, svg, searching, frames, known_font_width, case_insensitive, current_search_term;
function init(evt) {
details = document.getElementById("details").firstChild;
searchbtn = document.getElementById("search");
ignorecasebtn = document.getElementById("ignorecase");
unzoombtn = document.getElementById("unzoom");
matchedtxt = document.getElementById("matched");
svg = document.getElementsByTagName("svg")[0];
frames = document.getElementById("frames");
known_font_width = get_monospace_width(frames);
total_samples = parseInt(frames.attributes.total_samples.value);
searching = 0;
case_insensitive = 0;
current_search_term = null;

// Use GET parameters to restore a flamegraph's state.
var restore_state = function() {
var params = get_params();
if (params.x && params.y)
zoom(find_group(document.querySelector('[*|x="' + params.x + '"][y="' + params.y + '"]')));
if (params.s)
if (params.s) {
if (params.ic) {
case_insensitive = 1;
ignorecasebtn.classList.add("show");
}
current_search_term = params.s;
search(params.s);
}
};

if (fluiddrawing) {
Expand All @@ -41,7 +50,8 @@ function init(evt) {

// Keep search elements at a fixed distance from right edge.
var svgWidth = svg.width.baseVal.value;
searchbtn.attributes.x.value = svgWidth - xpad;
ignorecasebtn.attributes.x.value = svgWidth - xpad;
searchbtn.attributes.x.value = svgWidth - xpad - fontsize * fontwidth * 4;
matchedtxt.attributes.x.value = svgWidth - xpad;
};
window.addEventListener('resize', function() {
Expand Down Expand Up @@ -87,6 +97,7 @@ window.addEventListener("click", function(e) {
history.replaceState(null, null, parse_params(params));
}
else if (e.target.id == "search") search_prompt();
else if (e.target.id == "ignorecase") toggle_ignorecase();
}, false)
// mouse-over for info
// show
Expand All @@ -106,6 +117,13 @@ window.addEventListener("keydown",function (e) {
search_prompt();
}
}, false)
// ctrl-I to toggle case-insensitive search
window.addEventListener("keydown",function (e) {
if (e.ctrlKey && e.keyCode === 73) {
e.preventDefault();
toggle_ignorecase();
}
}, false)
// functions
function get_params() {
var params = {};
Expand Down Expand Up @@ -371,26 +389,30 @@ function reset_search() {
}
var params = get_params();
delete params.s;
delete params.ic;
history.replaceState(null, null, parse_params(params));
}
function search_prompt() {
if (!searching) {
var casemsg = case_insensitive ? ", ignoring case" : "";
var term = prompt("Enter a search term (regexp " +
"allowed, eg: ^ext4_)", "");
"allowed, eg: ^ext4_)" + casemsg + "\nPress Ctrl+i to toggle case sensitivity", "");
if (term != null) {
current_search_term = term;
search(term)
}
} else {
reset_search();
searching = 0;
current_search_term = null;
searchbtn.classList.remove("show");
searchbtn.firstChild.nodeValue = "Search"
matchedtxt.classList.add("hide");
matchedtxt.firstChild.nodeValue = ""
}
}
function search(term) {
var re = new RegExp(term);
var re = new RegExp(term, case_insensitive ? "i" : "");
var el = frames.children;
var matches = new Object();
var maxwidth = 0;
Expand Down Expand Up @@ -425,10 +447,20 @@ function search(term) {
searching = 1;
}
}
if (!searching)
if (!searching) {
searchbtn.classList.remove("show");
searchbtn.firstChild.nodeValue = "Search";
matchedtxt.classList.add("hide");
matchedtxt.firstChild.nodeValue = "";
return;
}
var params = get_params();
params.s = term;
if (case_insensitive) {
params.ic = "1";
} else {
delete params.ic;
}
history.replaceState(null, null, parse_params(params));

searchbtn.classList.add("show");
Expand Down Expand Up @@ -465,6 +497,19 @@ function search(term) {
if (pct != 100) pct = pct.toFixed(1);
matchedtxt.firstChild.nodeValue = "Matched: " + pct + "%";
}
function toggle_ignorecase() {
case_insensitive = !case_insensitive;
if (case_insensitive) {
ignorecasebtn.classList.add("show");
} else {
ignorecasebtn.classList.remove("show");
}
if (current_search_term != null) {
reset_search();
searching = 0;
search(current_search_term);
}
}
function format_percent(n) {
return n.toFixed(4) + "%";
}
21 changes: 20 additions & 1 deletion src/flamegraph/svg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,30 @@ text {{ font-family:{}; font-size:{}px }}
},
)?;

{
let x = write!(buf, "{:.2}", image_width as usize - super::XPAD);
let y = write!(buf, "{:.2}", (opt.font_size * 2) as f64);
svg.write_event(Event::Start(BytesStart::new("text").with_attributes(
args!(
"id" => "ignorecase",
"fill" => &*style_options.uicolor,
"x" => &buf[x],
"y" => &buf[y]
),
)))?;
svg.write_event(Event::Start(BytesStart::new("title")))?;
svg.write_event(Event::Text(BytesText::new("ignore case")))?;
svg.write_event(Event::End(BytesEnd::new("title")))?;
svg.write_event(Event::Text(BytesText::new("ic")))?;
svg.write_event(Event::End(BytesEnd::new("text")))?;
}

let ic_offset = (opt.font_size as f64 * opt.font_width * 4.0) as usize;
write_str(
svg,
&mut buf,
TextItem {
x: Dimension::Pixels(image_width as usize - super::XPAD),
x: Dimension::Pixels(image_width as usize - super::XPAD - ic_offset),
y: (opt.font_size * 2) as f64,
text: "Search".into(),
extra: vec![("id", "search"), ("fill", &style_options.uicolor)],
Expand Down