A jómúltkori csomagos post óta elkezdett rendesen foglalkoztatni az AT&T által fejlesztett Graphviz csomag, annak is a dot nevű programja. Ez az okos kis parancssoros alkalmazás egy nagyon egyszerű nyelven megfogalmazott szöveges fájlból képes grafikus formátumokat készíteni. Hogy rögtön belecsapjak a lecsóba, egy példával indítok:
A fenti rajz elkészítéséhez szükséges kód:
Egyszerűségében is zseniális. A sallangokat elhagyva koncentráljunk a lényegre:
digraph elso_pelda {
rankdir=LR;
node [shape = doublecircle]; Alma Körte Szilva;
node [shape = circle];
Alma -> Körte [ label = "Almától körtéig" ];
Alma -> Szilva [ label = "Almától szilváig" ];
Szilva -> Körte [ label = "Szilvától körtéig" ];
Narancs -> Banán;
Banán -> Alma;
}
1. Ha éleket akarunk definiálni (gráfot nem ismerőknek: a nyilak), akkor "a -> b" alakban lehetséges.
2. A csomópontokat egyszerűen felsoroljuk. A példa picit túl bonyolult, hogy az ábra szebb legyen. Mindjárt egyszerűsítem.
3. A "rankdir" mutatja, hogy nem felülről lefelé, hanem balról jobbra szeretném vezetni a diagramot.
4. A kapcsos zárójelekben tulajdonságokat adunk meg. Ezek öröklődhetnek is, és addig érvényesek, ameddig felül nem definiáljuk őket. Ahogyan látjátok, először duplakör (doublecircle) alakú csomópontokat (node) határoztam meg, az utána megadott 3 node ilyen lett. Ezek után felüldefiniáltam szimpla körre, a maradék kettő már ilyen lett. Természetesen egyesével is megadhattam volna: "Alma [shape = doublecircle];".
5. A pontosvessző jelenti a sor/utasítás végét.digraph basic {
Mindenféle kavarás nélkül itt egy egyszerű kód. Így már gondolom, nem kell semmilyen magyarázat. A kódot mentsük el egy .dot kiterjesztésű fájlba, tegyük fel a graphviz csomagot, és adjuk ki:
Alma Körte Szilva;
Alma -> Körte;
Alma -> Szilva;
Szilva -> Körte;
}bagoj@aranyhal~$ dot -o 0.svg -T svg pelda.dot
Ha egyszerűbb a PNG, akkorbagoj@aranyhal~$ dot -o pelda.png -T png pelda.dot
Tud még Postscript, PCL, JPG és GIF kimeneteket is. Jöhet egy bonyolultabb dolog?
Ahhoz, hogy átlássam az algoritmust, ami szerint a dot dolgozik, még keveset foglalkoztam a témával. Ami a lényeg, hogy el tudja helyezni a csomópontokat és az éleket úgy, hogy azok között a legkevesebb átfedés legyen. Ha bekerül egy új csomópont, akkor átalakítja az ábrát (én ezt dinamikus fának hívom, majd matematikusok kiporolják a tollamat ezért). Ehhez a dinamikus ábra felépítéshez súlyozást állít fel a node-ok és az edge-ek alapján. Alapértelmezésben mindegyik node 1-nek számít, az edge-ek súlyozása többféle algoritmussal történhet, a legrövidebb út (shortest path) az alapértelmezett. Mindezt azért írom, mert az ábra felépítése (éppen azért, mert dinamikus) eléggé összevisszának tűnhet, ha az ember jobban belemélyed és felvisz nagy hirtelen vagy 500 csomópontot. Ilyenkor úgy látszik, mintha nem lenne beleszólásunk az ábra alakulásába. Pedig képezhetünk csoportokat és megadhatjuk azokat a node-okat, amelyek kihagyhatók a súlyozásból. Az első példánál maradva, csak épp egy picit változtatok és máris más az ábra:
A kód:digraph elso_pelda {
Megadtam, hogy a Banán - Alma kapcsolat "alacsonyabb rendű", mint a többiek. Nézzünk a csoportosításra példát! Annyit kell megjegyezni, hogy a csoportok nevei "cluster"-rel kell kezdődjenek, különben nem fog működni! Ez a gyári működés, nem hiba. Beleteszek még pár apróságot is, saját örömömre... :-)
rankdir=LR;
node [shape = doublecircle]; Alma Körte Szilva;
node [shape = circle];
Alma -> Körte [ label = "Almától körtéig" ];
Alma -> Szilva [ label = "Almától szilváig" ];
Szilva -> Körte [ label = "Szilvától körtéig" ];
Narancs -> Banán;
Banán -> Alma [constraint = false];
}digraph basic {
Ugye, milyen egyszerű? És mert ilyen egyszerű, nagyon jól lehet programból is ilyen kimeneteket írni, ráadásul hierarchia megjelenítésére ideális, miközben nem hozza zavarba a körgráf sem, sőt ahogyan látható, több nyíl is mutathat ugyanazon két node között.
node [shape = egg];
Alma Körte Szilva;
subgraph cluster_Alcsoport {
label="Alcsoport";
style=filled;
color=lightgrey;
Narancs [shape = box,style=filled,fillcolor=yellow,color="#CC9933"];
Barack [shape = doublecircle];
}
Alma -> Körte [dir=both color="red:black"];
Alma -> Szilva;
Szilva -> Körte;
Narancs -> Körte;
Barack -> Narancs;
}
Innentől a lehetőségek végtelenek. Majd nekilátok szép ábrákat összehozni! Egyelőre a legnagyobb fegyvertény, hogy a kis tűzfalunk szabályrendszeréből sikerült egy ábrát előállítani, amin látszik, hogy ki honnan hova mehet. :-)
Graphviz, pöttyözés
2008.06.09. 16:47 bagoj ur
2 komment
Címkék: linux grafika hogyan dot gráf parancssor dotty graphviz
A bejegyzés trackback címe:
https://bagojur.blog.hu/api/trackback/id/tr13612291
Kommentek:
A hozzászólások a vonatkozó jogszabályok értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a Felhasználási feltételekben és az adatvédelmi tájékoztatóban.
béla 2008.06.09. 23:03:00
Szia, tudnál egy példát írni? Például olyan programot, ami kilistázza a könyvtárakat?
bagoj.ur 2008.06.10. 17:27:03
Oké, ha perlben jó lesz... mindjárt postolom