Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[pie] linkify pie arcs

  • Loading branch information...
commit 3a66db4d724c9cc2d520778851222793378ecef6 1 parent 5f85d7c
Moritz Lenz authored September 06, 2009
6  lib/SVG/Plot.pm
@@ -284,15 +284,15 @@ multi method apply-coordinate-transform(*@things) {
284 284
     ];
285 285
 }
286 286
 
287  
-method linkify($key, $thing) {
  287
+method linkify($key, *@things) {
288 288
     my $link = @.links[$key];
289 289
     defined($link)
290 290
         ?? ('a' => [
291 291
                 'xlink:href' => $link,
292 292
                 :target<_top>,
293  
-                $thing
  293
+                @things
294 294
             ])
295  
-        !! $thing;
  295
+        !! @things;
296 296
 }
297 297
 
298 298
 method wrap-in-svg-header-if-necessary(*@things, :$wrap) {
78  lib/SVG/Plot/Pie.pm
@@ -11,55 +11,61 @@ multi method plot(:$full = True, :$pie!) {
11 11
     }
12 12
     my @d         := @( @.values[0]);
13 13
     my $step       = 2.0 * pi / [+] @d;
  14
+    if 0 > [min] @d {
  15
+        die "ERROR: can't plot pie chart with negative values";
  16
+    }
14 17
     my $prev-angle = 0;
15 18
     my $cr         = 0.35 * ($.plot-width min $.plot-height);
16 19
     my $cx         = 0.5 * $.plot-width;
17 20
     my $cy         = 0.5 * $.plot-height;
18 21
     my @svg = gather for @d.kv -> $i, $v {
19 22
         my $angle = $prev-angle + $v * $step;
20  
-        take $.arc(
21  
-            :start($prev-angle),
22  
-            :end($angle),
23  
-            :r($cr),
24  
-            :stroke<black>,
25  
-            :color(@.colors[$i % *]),
26  
-        );
27  
-        my $legend-angle = 0.5 * ($prev-angle + $angle);
  23
+        my @items = gather {
  24
+            take $.arc(
  25
+                :start($prev-angle),
  26
+                :end($angle),
  27
+                :r($cr),
  28
+                :stroke<black>,
  29
+                :color(@.colors[$i % *]),
  30
+            );
  31
+            my $legend-angle = 0.5 * ($prev-angle + $angle);
28 32
 
29  
-        my $incr = $i % 2 ?? 0.3 !! 0;
  33
+            my $incr = $i % 2 ?? 0.3 !! 0;
30 34
 
31  
-        take 'line' => [
32  
-            :style('stroke: grey; stroke-width: 1.2'),
33  
-            :x1($cx + 1.1  * $cr * cos($legend-angle)),
34  
-            :y1($cy + 1.1  * $cr * sin($legend-angle)),
35  
-            :x2($cx + (1.35 + $incr) * $cr * cos($legend-angle)),
36  
-            :y2($cy + (1.35 + $incr) * $cr * sin($legend-angle)),
37  
-        ];
  35
+            take 'line' => [
  36
+                :style('stroke: grey; stroke-width: 1.2'),
  37
+                :x1($cx + 1.1  * $cr * cos($legend-angle)),
  38
+                :y1($cy + 1.1  * $cr * sin($legend-angle)),
  39
+                :x2($cx + (1.35 + $incr) * $cr * cos($legend-angle)),
  40
+                :y2($cy + (1.35 + $incr) * $cr * sin($legend-angle)),
  41
+            ];
38 42
 
39  
-        my ($text-anchor, $base-alignment);
40  
-        given cos($legend-angle) {
41  
-            if .abs < 0.4 {
42  
-                $text-anchor = 'middle';
43  
-            } else {
44  
-                $text-anchor = $_ > 0 ?? 'start' !! 'end';
  43
+            my ($text-anchor, $base-alignment);
  44
+            given cos($legend-angle) {
  45
+                if .abs < 0.4 {
  46
+                    $text-anchor = 'middle';
  47
+                } else {
  48
+                    $text-anchor = $_ > 0 ?? 'start' !! 'end';
  49
+                }
45 50
             }
46  
-        }
47  
-        given sin($legend-angle) {
48  
-            if .abs < 0.4 {
49  
-                $base-alignment = 'cenral';
50  
-            } else {
51  
-                $base-alignment = $_ < 0 ?? 'top' !! 'bottom';
  51
+            given sin($legend-angle) {
  52
+                if .abs < 0.4 {
  53
+                    $base-alignment = 'cenral';
  54
+                } else {
  55
+                    $base-alignment = $_ < 0 ?? 'top' !! 'bottom';
  56
+                }
52 57
             }
53  
-        }
54 58
 
55 59
 
56  
-        take 'text' => [
57  
-            :x($cx + (1.5 + $incr) * $cr * cos($legend-angle)),
58  
-            :y($cy + (1.5 + $incr) * $cr * sin($legend-angle)),
59  
-            :text-anchor($text-anchor),
60  
-            :dominant-baseline($base-alignment),
61  
-            @.labels[$i],
62  
-        ] if defined @.labels[$i];
  60
+            take 'text' => [
  61
+                :x($cx + (1.5 + $incr) * $cr * cos($legend-angle)),
  62
+                :y($cy + (1.5 + $incr) * $cr * sin($legend-angle)),
  63
+                :text-anchor($text-anchor),
  64
+                :dominant-baseline($base-alignment),
  65
+                @.labels[$i],
  66
+            ] if defined @.labels[$i];
  67
+        }
  68
+        take $.linkify($i, @items);
63 69
 
64 70
         $prev-angle = $angle;
65 71
     }
6  plot.pl
@@ -6,17 +6,17 @@
6 6
 use SVG::Plot;
7 7
 use SVG::Plot::Pie;
8 8
 
9  
-my @data1   = 5, 6, 4, -3, -7, 12, 1, 1, 3, 7;
  9
+my @data1   = map *.abs, 5, 6, 4, -3, -7, 12, 1, 1, 3, 7;
10 10
 my @data2   = 2, 8, 0, 5, 6, 7,  8, -1, -1, -3;
11 11
 my @labels  = <the quick brown fox jumps over the lazy red dog>;
12  
-my $svg = SVG::Plot.new(
  12
+my $svg = SVG::Plot::Pie.new(
13 13
             width      => 400,
14 14
             height     => 350,
15 15
             values     => ([@data1], [@data2]),
16 16
             title      => 'Some data',
17 17
             :@labels,
18 18
             links => <http://en.wikipedia.org/wiki/The_quick_brown_fox_jumps_over_the_lazy_dog>,
19  
-        ).plot(:lines);
  19
+        ).plot(:pie);
20 20
 
21 21
 say SVG.serialize($svg);
22 22
 

0 notes on commit 3a66db4

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