HTML

Bagoj úr blogja

Kíváncsi Bagoj befigyel a Linux belsejébe, illetve különféle Linux terjesztéseket próbál ki. Ha jó napja van, scriptet ír Neked.

Friss topikok

Graphviz, pöttyözés

2008.06.09. 16:47 bagoj ur

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:
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;
}
Egyszerűségében is zseniális. A sallangokat elhagyva koncentráljunk a lényegre:

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 {
    Alma Körte Szilva;
    Alma -> Körte;
    Alma -> Szilva;
    Szilva -> Körte;
}
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:

bagoj@aranyhal~$ dot -o 0.svg -T svg pelda.dotHa egyszerűbb a PNG, akkor
bagoj@aranyhal~$ dot -o pelda.png -T png pelda.dotTud 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 {
    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];
}
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... :-)
























digraph basic {
    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;
}
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.
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. :-)

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/tr22612291

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