Ruby on Rails: Grafiken
Zahlen sind wie Worte. Im Prinzip vielsagend aber Bilder sind anschaulicher. Hier wollen wir zeigen, wie wir mit Grafikbibliotheken Zahlen in anschauliche Grafiken verwandeln können. Ein besonderes Augenmerk werfen wir auf
- Tortengrafiken für Verteilungen
- Liniendiagramme für Zeitverläufe und
- XY-Diagramme für komplexe Sachverhalte
Grafikbibliotheken
[Bearbeiten]Eine erste Recherche ergibt viele Bibliotheken. Nach einer Sichtung bleiben:
Macht ansprechende Grafiken und ist einfach zu benutzen. Auch die Dokumentation ist ok. Allerdings bietet Gruff momentan keine XY-Diagramme (scatterplots) an. Außerdem setzt Gruff RMagick voraus. Und die Installation von RMagick ist etwas kompliziert, wenn auch nicht wirklich schwierig. Gruff selbst ist danach schnell installiert. Dafür ist Gruff open-source, d.h. wir können Gruff erweitern.
- Google Chart API - http://code.google.com/apis/chart/
Google Charts ist ein Service von Google. D.h. wir benötigen keine Bibliothek, die die Grafiken rendert. Das macht Google. Dafür müssen wir online sein, was bei einer Webapplikation oft der Fall ist. Für die Auswertung von sensitiven Daten ist diese Lösung natürlich nicht praktikabel (Datenschutz, Firmendaten, etc.). Wir müssen dann nur die richtige URL entsprechend der Goole API erzeugen und Googe liefert die Grafik. Am einfachsten geht das mit einem kleinen Wrapper-Plugin. Aber ggf. können wir diese URL auch direkt (also ohne Plugin) erzeugen.
- Google Chart Wrapper und Plugins:
- http://googlecharts.rubyforge.org/ - Ruby Wrapper von Matt Aimonetti
- http://code.google.com/p/google-charts-on-rails/ - Rails Plugin (Tortendiagramme funktionieren, XY-Diagramme werden zwar erzeugt aber sie zeigen die Daten nicht an.)
Google liefert sehr ansprechende und übersichtliche Grafiken. Das Layout lässt sich weitgehend konfigurieren (Größe, Farben, Beschriftungen, ..). Die Dokumentation der Google API ist über weite Strecken gut. Das gilt leider nicht für die Wrapper-Plugins. Speziell die XY-Diagramme (scatter_plot) bleiben da unklar.
- Gnuplot - http://gnuplot.sourceforge.net/
Gnuplot ist ein Programm zum Darstellen von Daten und Funktionen. Gnuplot wird über die Kommandozeile oder über Scripte gesteuert und kann die Ergebnisse nicht nur auf dem Bildschirm ausgeben, sondern auch in Dateien (zum Beispiel PNG oder SVG). Die Ansteuerung geht auch über einen Ruby Wrapper.
- weitere Informationen:
- http://rgplot.rubyforge.org/ - Ruby Gnuplot, Ruby Wrapper für Gnuplot
- http://www.oreillynet.com/ruby/blog/2008/03/cruisecontrol_charts.html - Beispiel für den Einsatz von Gnuplot unter Rails
Mit Gnuplot lassen sich nicht nur Daten sondern auch Funktionen visualisieren. Und es sind komplexe Diagramme möglich, beispielsweise 2D-Diagramme mit mehreren Datensätzen und Funktionen oder 3D Diagramme mit Flächendarstellungen von Funktionen.
- Einige weitere Bibliotheken, meist flash basiert. Links dazu:
- Übersicht über einige Chart-Bibliotheken für Rails und Einführung in FusionCharts http://www.infoq.com/articles/sharma-charts-in-rails
- FusionCharts http://www.fusioncharts.com/ bzw. http://www.fusioncharts.com/free/, dazu FusionCharts Free Dokumentation http://www.fusioncharts.com/free/docs/?gMenuItemId=19
- Ezgraphix - Rals Plugin, basiert auf FusionCharts Free http://pemberthy.blogspot.com/2009/01/ezgraphix-rails-plugin-to-easily-render.html
- Open Flash Chart I und II http://pullmonkey.com/projects/open_flash_chart, http://pullmonkey.com/projects/open_flash_chart2
- ZiYa Ruby Wrapper für XML/SWF Charts http://ziya.liquidrail.com/
- TODO: (was benutzt eigentlich new Relic - http://railstips.org/2008/9/17/rails-app-monitoring)
Google Chart API
[Bearbeiten]Google Charts ist ein Service von Google. D.h. wir benötigen keine Bibliothek, die Grafiken rendert, das macht Google. Wir müssen nur die richtige URL entsprechend der Goole API liefern, so dass Googe die Grafik bereitstellen kann. Ggf. können wir diese URL sogar ohne Plugin direkt in Rails berechnen.
Vorteile
[Bearbeiten]- Es wird keine schwer zu installierende Grafikbibliothek benötigt
- gelungenes Layout, viele Anpassungsmöglichkeiten
- Wrapper-Plugins verfügbar, es geht aber auch ohne.
- stabil und dokumentiert (allerdings die XY-Diagramme nicht ausreichend!)
Nachteile
[Bearbeiten]- funktioniert nur online.
- keine Veränderungen am Quellcode möglich, also keine eigenen Erweiterungen.
- Abhängigkeit von einem Service, der sich ändern kann (Technik und Lizenzbedingungen).
Wie geht's?
[Bearbeiten]Zuächst installieren wir die Wrapper-Plugins, die wir verwenden wollen ..
# console
$> ruby script/plugin install http://google-charts-on-rails.googlecode.com/svn/google_charts_on_rails/
$> ruby script/plugin install git://github.com/mattetti/googlecharts.git
.. und starten den Server neu, damit die Plugins auch angezogen werden. Für eine kurze Demo rufen wir dann den Wrapper direkt vom view aus auf. (Wenn wir das Plugin professionell einsetzen, erzeugen wir die url natürlich im passenden Modell und reichen sie über den Controller an die View durch.) Schauen wir uns ein paar erläuterte Beispiele an.
Tortendiagramme mit google-charts-on-rails
[Bearbeiten]Da Tortendiagrame in der Dokumentation von google-charts-on-rails als Beispiele benutzt werden, ist der Umgang mit ihnen gut dokumentiert.
# view
<img src="<%=GoogleChart.pie(['1997',10],['1998',20],['1999',40],['2000',30]).to_url%>">
Tortendiagramme mit mattetti/googlecharts
[Bearbeiten]Tortendiagramme direkt mit der Google API
[Bearbeiten]<img src="http://chart.apis.google.com/chart?
chs=250x100
&chd=t:60,40
&cht=p3
&chl=Hello|World"
alt="Sample chart" />
Liniendiagramme
[Bearbeiten]XY-Diagramme
[Bearbeiten]Direkt mit der Google API ..
[Bearbeiten].. sieht eine scatterplot url beispielsweise so aus:
http://chart.apis.google.com/chart?chs=400x200&cht=s&chd=t:10,22,30,35,40,70,90%7C30,21,20,35,75,80,70%7C60,60,60,60,60,100,80
chs=200x200 gibt die Größe an chd=t:.. gibt die x-Koordinae, die Y-Koordinae und die Größe der Punkte an.
Bei google charts on rails ..
[Bearbeiten].. sind Scatterplots nicht klar dokumentiert. Ein Versuch mit
<img src="<%=GoogleChart.scatter_plot(1, 2, 3 | 3, 2, 1 | 2, 2, 2 ).to_url%>">
Stellt zwar eine Grafik dar, aber die Punkte werden nicht ausgegeben. Es wird folgende Url erzeugt: <img src="http://chart.apis.google.com/chart?chs=200x200&cht=s&chd=t:1,2,3,2,3,2,2"> D.h. die Trennung der Blöcke für die x-Koordinate, die y-Koordinate und die Punktgröße mit dem "|"-Zeichen funktioniert nicht.
Mit mattetti/googlecharts ..
[Bearbeiten].. wird zwar eine korrekte Grafik erzeugt, aber die url ist merkwürdig. Bei zu großen Koordinaten für einen Punkt wird der Punkt nicht an den Rad gesetzt - wie sonst bei der Google API - sondern es werden überhaupt keine Punkte dargestellt. Auch nicht die Punkte die im Wertebereich liegen.
Gnuplot
[Bearbeiten]Wie gesagt Gnuplot ist ein Programm zum Darstellen von Daten und Funktionen. Um Gnuplot zu nutzen benötigen wir also Gnuplot selbst und zusätzlich einen Ruby Wrapper.
Wie geht's?
[Bearbeiten]Installation
[Bearbeiten]- Gnuplot lässt sich unter Windows, Mac OS X und Unix (alle gängigen Versionen) installieren. Für Mac OS X ist ein MacPort-Paket verfügbar.
- Das Gnuplot Modul für Ruby können wir entweder von http://rubyforge.org/projects/rgplot/ als *.tar.bz2 File herunterladen und manuell als Plugin installieren oder einfacher wir können das gnuplot-gem installieren ..
$> sudo gem install gnuplot
.. und mit ..
require 'gnuplot'
.. einbinden. Danach konnen wir gnuplot benutzen.
Einsatz
[Bearbeiten]Kopieren wir zunächst das Beispiel aus der rgplot Dokumentation http://rgplot.rubyforge.org/ in einen Controller.
require 'gnuplot'
class DemosController < ApplicationController
def index
# tryout gnuplot
Gnuplot.open do |gp|
Gnuplot::Plot.new( gp ) do |plot|
plot.xrange "[-10:10]"
plot.title "Sin Wave Example"
plot.ylabel "x"
plot.xlabel "sin(x)"
plot.data << Gnuplot::DataSet.new( "sin(x)" ) do |ds|
ds.with = "lines"
ds.linewidth = 4
end
end
end
respond_to do |format|
format.html # index.html.erb
end
end
end
Dann macht Gnuplot beim Aufruf quasi defaultmäßig ein Terminal auf dem Server auf. Wenn wir auf dem localhost entwickeln sehen wir das auch. Aber für eine Webanwendung müssen wir mit Gnuplot eine SVG oder PNG Datei schreiben und die dann im View anzeigen. Dazu setzen wir im Plot-Objekt das Terminal auf das Bildformat "png" und die Ausgabedatei.
plot.term 'png' # Augabe-Testminal: png (statt Standard / Default)
plot.output "#{RAILS_ROOT}/public/images/charts/random_plot.png" # Ausgabedatei
Zusammenfassung
[Bearbeiten]Wir haben viele Möglichkeiten Grafiken aus Rails zu erzeugen. Besonders eignen sich
- Google Charts - wenn wir schnell schöne vorkonfigurierte Diagramme benötigen und der Zugang zum Internet bzw. zu Google für den Benutzer ok ist.
- Gruff - wenn wir schöne vorkonfigurierte Diagramme benötigen, auf XY-Diagramme verzichten können und unabhängig von Google sein wollen.
- GnuPlot - wenn wir komplexe Diagramme benötigen, z.Bsp. große 2D- bzw. XY-Diagramme, 3D Diagramme oder Diagramme mit Funktionen.
Weitere Alternative sind ..