© Utzel-Butzel, Photocase.com
Perl-Skript lässt Google Diagramme zeichnen
Datenmaler
von Michael Schilli
Erschienen im Linux-Magazin
2009/07
Googles Chart-Service zeichnet optisch ansprechende Diagramme, ganz gleich, woher die Daten dafür stammen. Ein CPAN-Modul gibt die Zeichenanweisungen dafür in objektorientiertem Perl weiter, statt vom Programmierer URL-Fitzelei zu verlangen.
Schon geraume Zeit liebäugelte ich heimlich mit einem Ersatz für meinen alten Laptop und als dann neulich die Firma Dell eines dieser putzigen Mini-9-Zoll-Ubuntu-Netbooks (Abbildung 1) zum unschlagbaren Preis von nur 230 Dollar feilbot, gab es kein Halten mehr und ich schlug endlich zu. Mein Arbeitskollege Leif fand dann auch noch einen lustigen Namen für den Winzling: "Mini-Me" - nach dem gleichnamigen winzigen Klon von Dr. Evil aus dem zweiten Austin-Powers-Film.

|
Abbildung 1: Michael Schillis kleines Dell-Netbook mit Ubuntu und ursprünglich nur 512 MByte RAM.
|
Der erste Eindruck war berauschend, es funktionierte sogar alles halbwegs! Als ich dann noch die mageren 512 MByte RAM mit 2 GByte eines Billiganbieters für 9,95 Dollar nachrüstete, war mein Glück perfekt, allerdings schlich sich ein verstörender Gedanke ein: Würde das Netbook mit dem größeren Speicherbaustein im Suspend-Mode vielleicht mehr Strom schlucken, also die Batterie vorzeitig entleeren? Dem Ingenieur ist nichts zu schwör - ich ging der Sache auf den Grund.
Also baute ich zunächst wieder das alte Speichermodul ein, suspendierte den Rechner und las in unregelmäßigen Abständen über die nächsten 36 Stunden auf dem dazu kurz reanimierten Gerät den Ladezustand der Batterie ab. In Abbildung 2 sind die handgeschriebenen Notizzettel zu sehen, die das aktuelle Ergebnis jeweils neben der Uhrzeit auflisten.

|
Abbildung 2: Die gemessenen Daten auf handgeschriebenen Notizzetteln.
|
Vom Zettel zum Diagramm
Das gleiche Verfahren wiederholte ich eineinhalb Tage später noch einmal mit dem dazu wieder eingebauten 2-GByte-Baustein. Beide Messreihen haben wegen des unorthodoxen Verfahrens unterschiedlich Messzeitpunkte. Um die Entladungskurven - wie in Abbildung 3 zu sehen - grafisch nebeneinander darzustellen, muss man die Daten erst mit dem Skript in Listing 1 normalisieren, bevor sie sich anschließend mit dem Skript in Listing 2 durch Googles Chart-Service zeichnen lassen.
Das Ergebnis zeigt, dass die Entladung mit beiden Speichermodulen anfangs in etwa gleich schnell vonstatten geht. Mit schwächerer Batterie saugt das größere Speichermodul später sogar etwas mehr Saft und sorgt für eine schnellere Entladung des Akkus. Kein besorgniserregender Vorgang, aber schön, wenn man harte Daten in einem ansprechend gestalteten Diagramm vorweisen könnte.
01 #!/usr/local/bin/perl -w
02 use strict;
03 use DateTime;
04
05 my @result = ();
06 my $max = {};
07
08 my $data = {
09 "2gb" => [qw(
10 21:33 100 08:18 83 10:52 80
11 18:40 57 08:36 35 12:21 28
12 )],
13 "0.5gb" => [qw(
14 14:44 100 16:09 97 18:08 95
15 20:43 88 22:19 86 08:47 73
16 15:19 65 17:52 61 21:19 56
17 23:04 55 07:35 43
18 )]};
19
20 for my $conf (keys %$data) {
21
22 my $points = $data->{ $conf };
23 my $day_start;
24 my $day_current;
25
26 while( my($time, $charge) =
27 splice( @$points, 0, 2 ) ) {
28
29 my($hour, $minute) = split /:/, $time;
30
31 if(!defined $day_start) {
32 $day_start = DateTime->today();
33 $day_start->set_hour( $hour );
34 $day_start->set_minute( $minute );
35 $day_current = $day_start->clone();
36 }
37
38 my $time_current =
39 $day_current->clone();
40 $time_current->set_hour( $hour );
41 $time_current->set_minute( $minute );
42
43 if($time_current < $day_current) {
44 $time_current->add( days => 1 );
45 $day_current->add( days => 1 );
46 }
47
48 $day_current = $time_current->clone();
49
50 my $x = (($time_current->epoch() -
51 $day_start->epoch()) / 60);
52
53 push @result, [ $conf, $x, $charge ];
54
55 if(!exists $max->{x} or
56 $max->{x} < $x) {
57 $max->{x} = $x;
58 }
59 if(!exists $max->{y} or
60 $max->{y} < $charge) {
61 $max->{y} = $charge;
62 }
63 }
64 }
65
66 my $margin = 2;
67
68 for my $result (@result) {
69 my($symbol, $x, $y) = @$result;
70 print "$symbol ",
71 int($x*(100-2*$margin)/
72 $max->{x})+$margin,
73 " ",
74 int($y*(100-2*$margin)/
75 $max->{y})+$margin,
76 "n";
77 }
|
001 #!/usr/local/bin/perl -w
002 use strict;
003 use Google::Chart;
004 use Google::Chart::Marker;
005
006 my $data = {};
007
008 open PIPE, "./data-normalize |" or die;
009 while(<PIPE>) {
010 chomp;
011 my($symbol, $x, $y) = split ' ', $_;
012 next unless $y;
013 push @{ $data->{ $symbol }->{x} }, $x;
014 push @{ $data->{ $symbol }->{y} }, $y;
015 }
016 close PIPE or die;
017
018 my $graph = Google::Chart->new(
019 type => 'XY',
020
021 data => [$data->{"0.5gb"}->{x},
022 $data->{"0.5gb"}->{y},
023 $data->{"2gb"}->{x},
024 $data->{"2gb"}->{y},
025 ],
026
027 size => '750x400',
028
029 title => {
030 text => "Dell Mini Standby Discharge"
031 },
032
033 fill => {
034 module => "LinearGradient",
035 args => {
036 target => "c",
037 angle => 45,
038 color1 => "abbaab",
039 offset1 => 1,
040 color2 => "FFFFFF",
041 offset2 => 0,
042 }
043 },
044
045 grid => {
046 x_step_size => 33,
047 y_step_size => 20,
048 },
049
050 axis => [
051 { location => 'x',
052 labels => [1..36],
053 },
054 { location => 'y',
055 labels => [0,25,50,75,100],
056 },
057 ],
058
059 color => ['E6E9FD', '4D89F9'],
060
061 legend => ['0.5gb', '2gb'],
062
063 margin => [50, 50, 50, 50, 100, 100],
064
065 marker => Google::Chart::Marker->new(
066 markerset => [
067 { marker_type => 'x',
068 color => 'FFCC33',
069 dataset => 0,
070 datapoint => -1,
071 size => 15,
072 priority => 1,
073 },
074 { marker_type => 'x',
075 color => 'FF0000',
076 dataset => 1,
077 datapoint => -1,
078 size => 15,
079 priority => 1,
080 },
081 { marker_type => 'D',
082 color => 'E6E9FD', # light blue
083 dataset => 0,
084 datapoint => -1,
085 size => 4,
086 priority => -1,
087 },
088 { marker_type => 'D',
089 color => '4D89F9', # blue
090 dataset => 1,
091 datapoint => -1,
092 size => 4,
093 priority => -1,
094 },
095 ]),
096 );
097
098 $graph->render_to_file(filename =>
099 "chart.png");
100 system("xv chart.png");
101
|
Diagrammgestaltung outsourcen
Kein Programm auf dem lokalen Rechner erzeugt in diesem Fall das Diagramm, sondern ein Clusterrechner der Firma Google. Das Perl-Skript baut lediglich eine URL nach Abbildung 4 zusammen, schickt sie an den Google-Chart-Service, und zurück kommt ein Bild im PNG-Format, das der Abbildung 3 entspricht. Google beschränkt die Zugriffe auf maximal 50000 pro Tag, das sollte aber für private Spielereien fürs Erste noch reichen. Ein anderer Perl-Snapshot [5] benutzte den gleichen Service schon einmal, um Spammer auf einer Weltkarte einzuzeichnen.

|
Abbildung 3: Google Charts zeichnet die Entladung des Netbooks mit den verschieden großen Speicherbausteinen.
|

|
Abbildung 4: Die an Google geschickte URL, nach deren Angaben der Chart-Service das Diagramm in Abbildung 3 zeichnet. Manuell wäre sie nur mit großem Aufwand zu konstruieren.
|
| Whitepaper |
|
The Role of Open Source in Data Integration
Obwohl in den letzten Jahren viele technische Fortschritte erzielt werden konnten, verfügen die meisten Datenintegrationsprozesse nach wie vor nur über eine sehr begrenzte Automatisierung. Das vorliegende White Paper von dem Industry Analyst Mark Madson wird zunächst ein grundlegendes Verständnis von Daten Integration vermitteln, die Vorzüge von Open Source Lösungen für Daten Integration erläutern und Ihnen professionelle Empfehlungen geben, damit Sie Ihre Integrationsjobs noch einfacher und produktiver gestalten können.
Download PDF (Registrierung erforderlich)
|
|
Open Source Datenintegration in der Praxis: Fallstudien und Anwendungsbeispiele (Folge 2)
Der zweite Teil des Open Source Datenintegration in der Praxis: Fallstudien und Anwendungsbeispiele White Papers beleuchtet anhand weiterer ausgewählter Case Studies die Implementierung von Open Source Datenintegration in der Praxis und benennt die daraus resultierenden Vorteile.
Download PDF (Registrierung erforderlich)
|
Dieser Online-Artikel kann Links enthalten, die auf nicht mehr vorhandene Seiten verweisen. Wir ändern solche "broken links"
nur in wenigen Ausnahmefällen. Der Online-Artikel soll möglichst unverändert der gedrucken Fassung entsprechen.
|