From 9fd17d6c804444e1f515500c1c939443759caead Mon Sep 17 00:00:00 2001 From: Shiar Date: Mon, 12 Nov 2007 21:06:05 +0100 Subject: [PATCH] screp -a to write an SVG file with apm history per player Uses SVG::TT::Graph::TimeSeries to draw a (very) nice graph of average action speeds per user over the course of the game. --- apm.css | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ screp | 58 +++++++++++++++++++ 2 files changed, 234 insertions(+) create mode 100644 apm.css diff --git a/apm.css b/apm.css new file mode 100644 index 0000000..0d534c7 --- /dev/null +++ b/apm.css @@ -0,0 +1,176 @@ +.svgBackground { + fill: #000; +} + +/* graphs titles */ +.mainTitle { + text-anchor: middle; + fill: #CCC; + font-size: 14px; + font-family: "Arial", sans-serif; + font-weight: normal; +} +.subTitle { + text-anchor: middle; + fill: #888; + font-size: 12px; + font-family: "Arial", sans-serif; + font-weight: normal; +} + +.graphBackground { + fill: #121; +} +.axis { + stroke: #8A8; + stroke-width: 1px; +} +.guideLines { + stroke: #242; + stroke-width: 1px; + stroke-dasharray: 5 5; +} + +.xAxisLabels, .yAxisLabels { + fill: #CCC; + text-anchor: middle; + font-size: 12px; + font-family: "Arial", sans-serif; + font-weight: normal; +} +.yAxisLabels { + text-anchor: end; +} +.keyText { + fill: #CCC; + text-anchor: start; + font-size: 18px; + font-family: "Arial", sans-serif; + font-weight: normal; +} + +.xAxisTitle, .yAxisTitle { + fill: #FF0; + text-anchor: middle; + font-size: 14px; + font-family: "Arial", sans-serif; + font-weight: normal; +} + +.dataPointLabel { + fill: #CCC; + text-anchor:middle; + font-size: 10px; + font-family: "Arial", sans-serif; + font-weight: normal; +} +.staggerGuideLine { + fill: none; + stroke: #000000; + stroke-width: 0.5px; +} + +/* default fill styles */ +.fill1 { + fill: #cc0000; + fill-opacity: 0.2; + stroke: none; +} +.fill2 { + fill: #0000cc; + fill-opacity: 0.2; + stroke: none; +} +.fill3 { + fill: #00cc00; + fill-opacity: 0.2; + stroke: none; +} +.fill4 { + fill: #ffcc00; + fill-opacity: 0.2; + stroke: none; +} +.fill5 { + fill: #00ccff; + fill-opacity: 0.2; + stroke: none; +} +.fill6 { + fill: #ff00ff; + fill-opacity: 0.2; + stroke: none; +} +.fill7 { + fill: #00ffff; + fill-opacity: 0.2; + stroke: none; +} +.fill8 { + fill: #ffff00; + fill-opacity: 0.2; + stroke: none; +} + +/* default line styles */ +.line1, .line2, .line3, .line4, .line5, .line6, .line7, .line8 { + fill: none; + stroke-width: 1px; +} +.line1 { + stroke: #3C3; +} +.line2 { + stroke: #CC0; +} +.line3 { + stroke: #C60; +} +.line4 { + stroke: #C30; +} +.line5 { + stroke: #2C9; +} +.line6 { + stroke: #1C5; +} +.line7 { + stroke: #6C0; +} +.line8 { + stroke: #C90; +} + +/* default line styles */ +.key1, .key2, .key3, .key4, +.key5, .key6, .key7, .key8, +.fill1 { + stroke: none; + stroke-width: 1px; +} +.key1, .fill1 { + fill: #3C3; +} +.key2, .fill2 { + fill: #CC0; +} +.key3, .fill3 { + fill: #C60; +} +.key4, .fill4 { + fill: #C30; +} +.key5, .fill5 { + fill: #2C9; +} +.key6, .fill6 { + fill: #1C5; +} +.key7, .fill7 { + fill: #6C0; +} +.key8, .fill8 { + fill: #C90; +} + diff --git a/screp b/screp index 910f3d2..93eb14f 100755 --- a/screp +++ b/screp @@ -4,10 +4,12 @@ use warnings; use Data::Dumper; my $SHOWWARN = 0; +my $APMSVG = undef; use Getopt::Long; GetOptions( "verbose|v!" => \$SHOWWARN, + "apm|a=s" => \$APMSVG, ); use constant { APM_FIRSTFRAME => 80 / .042 }; @@ -557,3 +559,59 @@ for my $player (sort keys %stats) { ) if 0; } +if ($APMSVG) { + my @seq; # player => time (s) => actions + $seq[$_->[1]][$_->[0] * .042]++ for @$map; + my $flatten = 120; + my @apm; + for my $player (0 .. $#seq) { + my $range = 0; + $range += $seq[$player][$_] || 0 for 0 .. $flatten - 1; + my $leadfill = $range / $flatten; + for my $frame (0 .. $#{$seq[$player]}) { + $range += $seq[$player][$frame] || 0; + $range -= $frame < $flatten ? $leadfill : + $seq[$player][$frame - $flatten] || 0; + $apm[$player][$frame] = $range / $flatten; + } + } + + BEGIN { unshift @INC, '.' } + use SVG::TT::Graph::TimeSeries; + my $graph = SVG::TT::Graph::TimeSeries->new({ + height => 1200, + width => 1600, + style_sheet => "apm.css", + show_data_values => 0, + show_data_points => 0, + x_label_format => '%k:%M', + key => 1, + timescale_divisions => "5 minutes", + # compress => 1, + }); + + for my $player (0 .. $#apm) { + $graph->add_data({ + data => [map { + time2str('%Y-%m-%d %X', 946681200 + $_), + $apm[$player][$_] * 60 + } 0 .. $#{$apm[$player]} ], + title => showplayer($player), + }); + } + + my ($name) = $APMSVG =~ /([^.]+)/; + my $title = "APM timeline" . ($name && " for $name"); + my $lead = sprintf "\n%s", $title; + + my $svg = $graph->burn(); + s/^[ \t\r]+\n//gm, # remove lines with only whitespace (many useless ^M) + s/[ \t\r]+$//gm, # trailing whitespace + s/ {4}\r*/\t/g, # tabs for indenting + s/^(]*>)/${1}100%${2}100%$3$lead/m, + for $svg; # cleanup xml + + open my $apmfile, '>', "$APMSVG.svg"; + print $apmfile $svg; +} + -- 2.30.0