Inzwischen scheint sich die Visualisierung von Blogseiten und deren Beiträge bei mir zu einer Art Marotte entwickelt zu haben. Daher hat sich aus dem angekündigten "Tutorial light" doch etwas Größeres entwickelt.
Wie ich bereits im ersten Teil dieses Beitrags geschrieben habe, ist es möglich, mit Hilfe des GraphViz Site Map Generator seine Seiten bzw. Beiträge grafisch darstellen zu lassen. Voraussetzung war allerdings eine kleine Textdatei, aus der GraphViz die entsprechenden Daten ausliest.
Die Größe der Darstellung wird offensichtlich durch die generierte Grafik begrenzt, deren Grenze bei mehr als 50 Einträge in dieser Textdatei erreicht zu sein scheint. Die meisten Blogs verfügen jedoch über mehr als 50 Beiträge, so dass man sich in diesem Fall auf die letzten 50 Blogbeiträge beschränken muss.
Ein weiteres Problem ist die Verlinkung der einzelnen Beiträge untereinander, z.B. wenn via Ähnliche Artikel auf einen anderen Beitrag verwiesen wird.
Auf der Seite ashitani.jp/gv/ habe ich eine Lösung gefunden, die ebenfalls auf der Basis von GraphViz basiert. Auf dieser Seite werden übergroße Darstellungen sowie abnormale Notation ignoriert. Weitere Informationen zur Bedienung könnt Ihr unter dem Punkt Usage nachlesen.
Ich möchte Euch anhand des dargestellten Diagramms erklären, wie Ihr bspw. Beiträge oder ähnliches visualisieren könnt. Dabei werde ich Schritt für Schritt dieses Diagramm erstellen und dabei die verwendeten Attribute und deren Eigenschaften genauer erläutern.
Die Eingabe auf dieser Seite erfolgt im linken Textfeld in der sogenannten DOT-Notation und die dazugehörige visuelle Ausgabe erhält man rechts daneben. Es sieht zunächst sehr kompliziert aus, aber wenn man einmal den Bogen raus hat, ist es nicht mehr so wild.
Grundsätzliches
Ich werde abschnittsweise vorgehen, d.h. ich fange beim Titel an und arbeite mich Ebene für Ebene nach unten. Auf diese Weise verliert Ihr nicht den Überblick und habt auch etwas Struktur in der Sache.
Natürlich werden sich im Laufe der Zeit viele Attribute und Eigenschaften wiederholen, so dass man sie eigentlich zusammenfassen könnte. Das Zusammenfassen macht sich zum Schluss am Besten, wenn sichergestellt ist, dass das Diagramm auch tatsächlich das ist, was man haben will.
Bevor es losgeht noch einige Hinweise.
GraphViz verfügt eigentlich über drei Objekte:
graph/digraph(ungerichteter/gerichteter Graph),node(Knoten) undedge(Kante)
mit entsprechenden Attributen und deren Eigenschaften.
Die Objekte graph/digraph brauchen auf der Seite ashitani.jp/gv/ nicht wie sonst üblich notiert werden.
Die verwendete Notation erfolgt in der Regel nach folgendem Schema:
Knoten1 [Knotenattribute="Eigenschaften"];
Knoten2 [Knotenattribute="Eigenschaften"];
...
Knoten1 Verknüpfungsoperator Knoten2;
bzw.
Kante [Kantenattribute="Eigenschaften"];.
Die Verbindung zweier Knoten, ohne den Einsatz weiterer Attribute, erfolgt durch diese beiden Verknüpfungsoperatoren:
--für einen ungerichteten Graphen oder->für einen gerichteten Graphen.
Diese beiden Codebeispiele sollen das mal veranschaulichen.
Ungerichteter Graph: A--B; und gerichteter Graph: 1->2;. Die Grafik zeigt das Ergebnis.

Beide Vernüpfungsoperatoren können allerding nicht gleichzeitig in einer Anweisung eingesetzt werden, wie folgendes Beispiel zeigt: X--Y->Z;.
Um dennoch die Möglichkeit zu erhalten unterschiedliche Pfeiltypen zu nutzen, müssen die Pfeile entsprechend formatiert werden. Dazu später an anderer Stelle mehr.
Knoten und Kanten können aber auch in Gruppen, den sogenannten Clustern zusammengefasst werden. Die Notation erfolgt dabei nach folgendem Schema:
subgraph id {
Clusterattribute="Eigenschaften";
...
Knoten1 [Knotenattribute="Eigenschaften"];
Knoten2 [Knotenattribute="Eigenschaften"];
...
Kante [Kantenattribute="Eigenschaften"];
Knoten1 Verknüpfungsoperator Knoten2;
...
}.
Im Grunde genommen wird der Cluster wie ein großer Knoten behandelt und auch so mit anderen Knoten verknüpft.
Das Semikolon am Ende der Zeile sollte gesetzt werden, auch wenn es nicht immer zwingend notwendig ist. Dadurch erspart man sich aber eine unnötige Suche nach Fehlern.
Jede Eingabe bzw. Veränderung des Codes im Textfeld dieser Seite ist immer mit der ENTER-Taste abzuschließen. Umlaute wie ä, ö, ü und ß sollten vermieden werden, da sonst das Diagramm nicht erstellt wird.
Außerdem sind Texte die Leerzeichen und folgende Satzzeichen: Komma, Punkt, Unterstrich, Semikolon, Bindestrich sowie spitze, eckige und geschweifte Klammern enthalten in Anführungszeichen "..." zu setzten.
Abschließend sei noch gesagt, dass ich Attribute und Eigenschaften sofort bei ihrem ersten Auftreten erläutern werde, im weiteren Verlauf jedoch nicht mehr darauf eingehe.
Okay jetzt aber genug geredet, dann fangen wir mal an.
Diagrammtitel der ersten Ebene
Als erstes geben wir unserem Diagramm einen Namen. Dazu geben wir folgendes ein:
compound="true";remincross="true";// Diagrammtitel der ersten Ebene"Kleines GraphViz Tutorial - Teil 1" [shape="box",
width="5.0",
height="0.7",
peripheries="1",
fontcolor="0.6,0.9,0.8",
fontsize="18",
color="#A0522D",
style="dashed,diagonals,filled",
fillcolor="lavenderblush"];// Hinweis"Liste unvollstaendig" [shape="box",
width="2.0",
height="0.2",
peripheries="1",
fontcolor="black",
fontsize="9",
fontname="Courier",
color="navy",
style="filled",
fillcolor="white"];
Die erste Ebene
Hinter dem Knotennamen "Kleines GraphViz Tutorial - Teil 1" folgen in eckigen Klammern die Knotenattribute. Diese bedeuten im einzelnen:
- Bindung:
compounderlaubt Kanten zwischen Clustern, Wertetrueoderfalse - Kantenkreuzung:
remincrossminimiert die Kreuzung von Kanten bei mehreren Clustern, Wertetrueoderfalse - Knotenform:
shapemit den Werten (box|polygon|ellipse|point|egg|triangle|diamond|trapezium|parallelogram|hexagon|octagon|doublecircle|tripleoctagon|invtriangle|invtrapezium) - Größe:
widthundheightmit Zahlenwerte in inch - Anzahl der Rahmen:
peripheriesmit einem Zahlenwert - Rahmenfarbe, Schriftfarbe und Füllfarbe:
color,fontcolorundfillcolormit Werten als Farbname, als HSB-Tripel mit Werten zwischen0und1oder als RGB-Tripel mit Hexadezimalwerten zwischen00undFF - Schriftgröße:
fontsizemit einem Zahlenwert - Aussehen:
stylemit den Werten (solid|dashed|dotted|bold|diagonals|rounded)
Wie beim style-Attribut (Listingzeile 3) zu sehen ist, können Eigenschaften auch kombiniert werden. Wenn fillcolor nicht vorhanden ist und Ihr style="filled" gesetzt habt, dann wird dem Knoten die Farbe von color zugewiesen.
Zur Bindung und Kantenkreuzung findet Ihr am Ende des letzten Listings weitere Informationen. Ich wollte sie an dieser Stelle nur schon mal erwähnt haben.
Kante und Knoten der zweiten Ebene
Für die erste Ebene geben wir nachstehenden Code ein:
// Kante erste Ebene - Knoten zweite Ebeneedge [color="slateblue",
arrowhead="invodot",
arrowtail="invodot",
arrowsize="0.7"];// Knoten der zweiten Ebenenode [shape="box",
width="15.0",
peripheries="2",
fontcolor="black",
fontsize="12",
color="powderblue",
style="filled"];"Kleines GraphViz Tutorial - Teil 1"--"Knoten-Attribute\nnode [attributes]";
Die zweite Ebene
Um die logische Reihenfolge beizubehalten, habe ich zunächst mit der Kante begonnen. Sie wird durch edge eingeleitet und enthält neben der Kantenfarbe color noch diese zusätzlichen Kantenattribute:
- Kanten- bzw. Pfeilkopf:
arrowheadmit den Werten (none|normal|dot|odot|inv|invdot|invodot) - Kanten- bzw. Pfeilende:
arrowtailmit den Werten (none|normal|dot|odot|inv|invdot|invodot) - Kanten-/Pfeilgröße:
arrowsizeals skalierbarer Wert
Nachdem die Kante definiert wurde, wird nun ein zweiter Knoten gesetzt. Er wird durch node festgelegt und enthält alle dazugehörigen Attribute in eckigen Klammern. Anschließend wird der Knoten der ersten Ebene durch den Verknüpfungsoperator -- mit dem Knoten der zweiten Ebene "Knoten-Attribute\nnode" verknüpft, wie in Listingzeile 10 zu sehen ist.
Im zweiten Knotennamen ist zu erkennen, das mittels einer Escape-Sequenz \n ein Zeilenumbruch erzwungen wurde. Außerdem gibt es noch \l für eine linke sowie \r für eine rechte Textausrichtung.
Kante und Knoten der dritten Ebene
Für die dritte Ebene geben wir folgenden Code ein:
// Kante zweite Ebene - Knoten dritte Ebeneedge [color="saddlebrown",
arrowhead="dot",
arrowtail="odot",
arrowsize="0.7"];// Knoten der dritten Ebenenode [shape="ellipse",
width="1.3",
peripheries="2",
fontcolor="black",
color="lavender",
style="filled"];"Knoten-Attribute\nnode [attributes]"--"shape";"Knoten-Attribute\nnode [attributes]"--"peripheries";"Knoten-Attribute\nnode [attributes]"--"style";"Knoten-Attribute\nnode [attributes]"--"color";"Knoten-Attribute\nnode [attributes]"--"fillcolor";"Knoten-Attribute\nnode [attributes]"--"fontcolor";"Knoten-Attribute\nnode [attributes]"--"fontsize";"Knoten-Attribute\nnode [attributes]"--"fontname";"Knoten-Attribute\nnode [attributes]"--"width";"Knoten-Attribute\nnode [attributes]"--"height";
Die dritte Ebene
Ich denke das ich hierzu nichts weiter erklären muss, da die Attribute oben alle schon mal aufgetaucht sind. Anschließend werden die Verknüpfungen zu den zehn Knoten der dritten Ebene hergestellt (Listingzeilen 10 bis 19).
Hinweis!
Attributnamen, die als Knotennamen verwendet werden, müssen zwingend in Anführungsstriche "..." gesetzt werden, da GraphViz sonst versucht, sie zu verarbeiten.
Kante und Knoten der vierten Ebene
Der Code der vierten Ebene ist etwas umfangreicher. Für Cluster1 lautet er folgendermaßen:
// Cluster1 als Knoten der vierten Ebene// Gruppierung der Knoten zur Flaechendarstellungsubgraph cluster1 {fontsize="10";
label="Die Flaechen" [
fontcolor="darkgreen"
];
style="filled";
fillcolor="#FFF5E6";// Knoten zur Flaechendarstellungnode [peripheries="1",
fontcolor="#990000",
fontsize="9",
fontname="Courier",
color="coral",
style="filled",
fillcolor="#F5FFF5"];"box" [shape="box"];"polygon" [shape="polygon",
sides="9",
skew="1.0",
distortion="0.2"];"ellipse" [shape="ellipse"];"point" [shape="point",
width="0.15"];"egg" [shape="egg"];"triangle" [shape="triangle"];"diamond" [shape="diamond"];"trapezium" [shape="trapezium"];"parallelogram" [shape="parallelogram"];"hexagon" [shape="hexagon"];"octagon" [shape="octagon"];"doublecircle" [shape="doublecircle",
peripheries="2"];"tripleoctagon" [shape="tripleoctagon",
peripheries="3"];"invtriangle" [shape="invtriangle"];"invtrapezium" [shape="invtrapezium"];edge [color="royalblue",
arrowhead="none",
arrowtail="none"];"box"--"polygon"--"ellipse"--"point"--"egg"--"triangle"--
"diamond"--"trapezium"--"parallelogram"--"hexagon"--
"octagon"--"doublecircle"--"tripleoctagon"--"invtriangle"--
"invtrapezium";}
Die vierte Ebene – Cluster1
Cluster werden, wie in Listingzeile 3 zu sehen ist, mit subgraph id {...} eingeleitet, wobei die id dem Clusternamen entspricht. Die im Cluster befindlichen Objekte, wie Knoten und Kanten, stehen innerhalb geschweiften Klammern. Vor Abschluss des Clusters werden noch die 15 Knoten angelegt.
Nun zu den neu hinzugekommenen Attributen.
- Beschriftung:
labelmit einen Namen - Anzahl der Seiten:
sidesmit einem Zahlenwert (nur beishape="polygon") - Schräge:
skewmit Werte zwischen -1.0 und 1.0 (nur beishape="polygon") - Verzerrung:
distortionmit einem Zahlenwert (nur beishape="polygon")
Hier der Code für Cluster2:
// Cluster2 als Knoten der vierten Ebene// Gruppierung der Knoten zum Aussehensubgraph cluster2 {fontsize="10";label="Das Aussehen" [fontcolor="darkgreen"];style="filled";fillcolor="#FFF5E6";// Knoten zum Aussehennode [shape="box",
peripheries="1",
fontcolor="#990000",
fontsize="9",
fontname="Courier",
color="coral",
fillcolor="#F5FFF5"];"solid" [style="solid,filled"];"dashed" [style="dashed,filled"];"dotted" [style="dotted,filled"];"bold" [style="bold,filled"];"diagonals" [style="diagonals,filled"];"rounded" [style="rounded,filled"];edge [color="royalblue",
arrowhead="none",
arrowtail="none"];"solid"--"dashed"--"dotted"--"bold"--"diagonals"--
"rounded";}
Die vierte Ebene – Cluster2
Weitere Erklärungen erübrigen sich, da ich bereits beim ersten Cluster alles wichtige genannt habe. Vor der schließenden geschweiften Klammer legen wir noch die sechs Knoten an.
Der Vollständigkeit halber hier noch der Code für Cluster3:
// Cluster3 als Knoten der vierten Ebene// Gruppierung der Knoten zur Schriftartsubgraph cluster3 {fontsize="10";label="Die Schriftart" [fontcolor="darkgreen"];style="filled";fillcolor="#FFF5E6";// Knoten zur Schriftartnode [shape="box",
peripheries="1",
fontcolor="#990000",
fontsize="9",
color="coral",
style="filled",
fillcolor="#F5FFF5"];"Standardschrift";"Times" [fontname="Times"];"Helvetica" [fontname="Helvetica"];"Courier" [fontname="Courier"];"Symbol" [fontname="Symbol"];edge [color="royalblue",
arrowhead="none",
arrowtail="none"];"Standardschrift"--"Times"--"Helvetica"--"Courier"--
"Symbol";}
Die vierte Ebene – Cluster3
Die fünf Knoten am Ende bilden den Abschluss des dritten Cluster.
Hinweis!
Ich habe in den Listings für Cluster1 in Zeile 60, für Cluster2 in Zeile 38 sowie für Cluster3 in Zeile 33 aufgrund der Länge Zeilenumbrüche eingefügt. Diese Zeileneinträge müssen komplett hintereinander geschrieben werden!
Abschließend folgt noch der restliche Code:
// Kante dritte Ebene - Cluster1, 2, 3 und Knoten der vierten Ebeneedge [color="darkseagreen",
arrowhead="none",
arrowtail="inv",
arrowsize="0.7"];"shape"--"box" [lhead="cluster1"];"style"--"solid" [lhead="cluster2"];"fontname"--"Standardschrift" [lhead="cluster3"];// Knoten der vierten Ebenenode [shape="box",
peripheries="1",
fontcolor="#990000",
fontsize="9",
fontname="Courier",
color="black",
style="filled",
fillcolor="#FFF5E6"];"peripheries"--"Zahlenwert, z.B. 5";"color"--"Farbname, RGB- oder HSB-Tripel\nroyalblue, #FF0000 oder 0.6,0.9,0.8";"fillcolor"--"Farbname, RGB- oder HSB-Tripel\nroyalblue, #FF0000 oder 0.6,0.9,0.8";"fontcolor"--"Farbname, RGB- oder HSB-Tripel\nroyalblue, #FF0000 oder 0.6,0.9,0.8";"fontsize"--"Zahlenwert, z.B. 5";"width"--"Zahlenwert in inch, z.B. 2.5";"height"--"Zahlenwert in inch, z.B. 2.5";
Die vierte Ebene
Die zwei neuen Attribute lauten.
- Kantenansatz:
lheadName des Clusters der den Kopf der Kante verwendet - Kantenansatz:
ltailName des Clusters der das Ende der Kante verwendet
In Verbindung mit dem Befehl compound="true";, in der Grafik rechts, erfolgt der Ansatz direkt am Rand des Clusters. Ist dieser auf false gesetzt, links in der Grafik, erfolgt der Ansatz in diesem Fall am Knoten "box", am Knoten "solid" bzw. am Knoten "Standardschrift".
Der Befehl remincross="true"; verhindert bei Verwenden mehrerer Cluster eine unnötige Überkreuzung von Kanten.
Damit Ihr nicht alles mühsam abtippen zu müssen, stelle ich Euch mal die dazugehörige Textdatei graphviz_tutorial_node zur Verfügung.
Eine Einführung in die DOT-Notation findet Ihr in diesem PDF-Dokument dot_guide. Auch jene Kanten-Attribute, die ich Euch unterschlagen habe. Außerdem erhaltet Ihr auf der Seite von GraphViz viele weitere Informationen.
Der zweite Teil wird sich dann mit den Kanten-Attributen (edge attributes) befassen. Bis dahin viel Spaß beim experimentieren.
Weiterführende Links:





Habe Ihren Blog durch Eingabe der Schlagworte "Graphviz compound" gefunden und dann entdeckt, dass sie auch aus Neubrandenburg sind. Danke für dieses wunderbare Tutorial! Es war mir sehr hilfreich. Grüße, Jensen
Schön das ich einen "Landsmann" helfen konnte. Grüße zurück!
danke für das tut. endlich habe ich da was gefunden
Keine Ursache. Ich helfe gern und Grüße nach Leipzig.