Skip to content
Browse files

Merge pull request #11 from timbunce/linking

Use <g> to simplify SVG and fix styling. Make functions clickable etc.
  • Loading branch information...
2 parents 0bc421a + 912c724 commit b7250daaf1a0664eaca17e923390e99eb70fabf1 @brendangregg committed Mar 18, 2013
Showing with 56 additions and 6 deletions.
  1. +56 −6 flamegraph.pl
View
62 flamegraph.pl
@@ -64,6 +64,7 @@
my $titletext = "Flame Graph"; # centered heading
my $nametype = "Function:"; # what are the names in the data?
my $countname = "samples"; # what are the counts in the data?
+my $nameattrfile; # file holding function attributes
GetOptions(
'fonttype=s' => \$fonttype,
@@ -74,6 +75,7 @@
'title=s' => \$titletext,
'nametype=s' => \$nametype,
'countname=s' => \$countname,
+ 'nameattr=s' => \$nameattrfile,
) or exit 1;
@@ -84,6 +86,19 @@
my $timemax = 0;
my $depthmax = 0;
my %Events;
+my %nameattr;
+
+if ($nameattrfile) {
+ # The name-attribute file format is a function name followed by a tab then
+ # a sequence of tab separated name=value pairs.
+ open my $attrfh, $nameattrfile or die "Can't read $nameattrfile: $!\n";
+ while (<$attrfh>) {
+ chomp;
+ my ($funcname, $attrstr) = split /\t/, $_, 2;
+ die "Invalid format in $nameattrfile" unless defined $attrstr;
+ $nameattr{$funcname} = { map { split /=/, $_, 2 } split /\t/, $attrstr };
+ }
+}
# SVG functions
{ package SVG;
@@ -99,7 +114,7 @@
$self->{svg} .= <<SVG;
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" width="$w" height="$h" onload="init(evt)" viewBox="0 0 $w $h" xmlns="http://www.w3.org/2000/svg" >
+<svg version="1.1" width="$w" height="$h" onload="init(evt)" viewBox="0 0 $w $h" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
SVG
}
@@ -113,6 +128,34 @@
return "rgb($r,$g,$b)";
}
+ sub group_start {
+ my ($self, $attr) = @_;
+
+ my @g_attr = map {
+ exists $attr->{$_} ? sprintf(qq/$_="%s"/, $attr->{$_}) : ()
+ } qw(class style onmouseover onmouseout);
+ push @g_attr, $attr->{g_extra} if $attr->{g_extra};
+ $self->{svg} .= sprintf qq/<g %s>\n/, join(' ', @g_attr);
+
+ $self->{svg} .= sprintf qq/<title>%s<\/title>/, $attr->{title}
+ if $attr->{title}; # should be first element within g container
+
+ if ($attr->{href}) {
+ my @a_attr;
+ push @a_attr, sprintf qq/xlink:href="%s"/, $attr->{href} if $attr->{href};
+ # default target=_top else links will open within SVG <object>
+ push @a_attr, sprintf qq/target="%s"/, $attr->{target} || "_top";
+ push @a_attr, $attr->{a_extra} if $attr->{a_extra};
+ $self->{svg} .= sprintf qq/<a %s>/, join(' ', @a_attr);
+ }
+ }
+
+ sub group_end {
+ my ($self, $attr) = @_;
+ $self->{svg} .= qq/<\/a>\n/ if $attr->{href};
+ $self->{svg} .= qq/<\/g>\n/;
+ }
+
sub filledRectangle {
my ($self, $x1, $y1, $x2, $y2, $fill, $extra) = @_;
$x1 = sprintf "%0.1f", $x1;
@@ -215,8 +258,7 @@ sub flow {
</linearGradient>
</defs>
<style type="text/css">
- rect[rx]:hover { stroke:black; stroke-width:1; }
- text:hover { stroke:black; stroke-width:1; stroke-opacity:0.35; }
+ .func_g:hover { stroke:black; stroke-width:0.5; }
</style>
<script type="text/ecmascript">
<![CDATA[
@@ -267,7 +309,14 @@ sub flow {
$escaped_func =~ s/>/&gt;/g;
$info = "$escaped_func ($samples_txt $countname, $pct%)";
}
- $im->filledRectangle($x1, $y1, $x2, $y2, color("hot"), 'rx="2" ry="2" onmouseover="s(' . "'$info'" . ')" onmouseout="c()"');
+
+ my $nameattr = $nameattr{$func} || {};
+ $nameattr->{class} ||= "func_g";
+ $nameattr->{onmouseover} ||= "s('".$info."')";
+ $nameattr->{onmouseout} ||= "c()";
+ $im->group_start($nameattr);
+
+ $im->filledRectangle($x1, $y1, $x2, $y2, color("hot"), 'rx="2" ry="2"');
if ($width > 50) {
my $chars = int($width / (0.7 * $fontsize));
@@ -276,9 +325,10 @@ sub flow {
$text =~ s/&/&amp;/g;
$text =~ s/</&lt;/g;
$text =~ s/>/&gt;/g;
- $im->stringTTF($black, $fonttype, $fontsize, 0.0, $x1 + 3, 3 + ($y1 + $y2) / 2, $text, "",
- 'onmouseover="s(' . "'$info'" . ')" onmouseout="c()"');
+ $im->stringTTF($black, $fonttype, $fontsize, 0.0, $x1 + 3, 3 + ($y1 + $y2) / 2, $text, "");
}
+
+ $im->group_end($nameattr);
}
print $im->svg;

0 comments on commit b7250da

Please sign in to comment.
Something went wrong with that request. Please try again.