wtorek, 11 lutego 2014

PowerShell i GraphViz

Już wcześniej pisałem o grafie w Power Shellu, a tym razem o przedstawieniu połączeń w grafie na obrazie. Do przedstawienia grafu użyjemy darmowego narzędzia GraphViz. Użyjemy grafu z poprzedniego wpisu.


$graph  = Create-Graph | 
    Add-Edge -edge (Create-Edge A B  1 ) |
    Add-Edge -edge (Create-Edge A C  5) |
    Add-Edge -edge (Create-Edge A D  3) |
    Add-Edge -edge (Create-Edge A E  11) |
    Add-Edge -edge (Create-Edge B C  9) |
    Add-Edge -edge (Create-Edge B D  1) |
    Add-Edge -edge (Create-Edge B E  2) |
    Add-Edge -edge (Create-Edge C D  6) |
    Add-Edge -edge (Create-Edge C E  4) |
    Add-Edge -edge (Create-Edge D E  3) 



Rozdzielimy to zadanie na 2 części. Pierwsza część będzie translacja grafu do języka dot używanego w GraphVizie (w praktyce jest to zapis danych w podobnej postaci co przykład z galerii GraphViz).
function ConvertTo-GraphViz
{
        param(
        [Parameter(Mandatory=$true, Position=1,ValueFromPipeline=$true)]  
        [ValidateNotNull()]  
        $graph,

        [ValidateNotNullOrEmpty()] 
        [string]$name='G',

        [ValidateRange(8, 52)]
        [int]$fontSize =12,

        [ValidateNotNullOrEmpty()] 
        [string]$label='Graph from PowerShell',
        
        [ValidateNotNullOrEmpty()] 
        [string]$arrowSign = '->',

        [ValidateNotNullOrEmpty()] 
        [ValidateSet('LR','RL')]
        [string]$rankdir='LR'
    )
    begin{
#region Strings
        $templateBegin ="digraph $name {
rankdir=$rankdir;
"
        $templateEnd = "
fontsize=$fontSize;
}"
        $templateBody= ''
        $format = "{0} $arrowSign {1} [label = {2} ];
"
#endregion
        }
    process{
        $graph.Edges | %{ 
             $templateBody += $format -f $_.From, $_.To, $_.Weight
            }

        }
    
    end{
        return $templateBegin + $templateBody + $templateEnd 
    }
}



Drugą częścią zadania będzie zapisanie kodu dot do pliku i uruchomienie aplikacji, która przekonwertuje do obrazu przedstawiającego ten graf:
function Out-GraphViz
{
    param(
    [Parameter(Mandatory=$true, Position=1,ValueFromPipeline=$true)] 
    [ValidateNotNullOrEmpty()] 
    $graphVizDot,
    
    [ValidateNotNullOrEmpty()]
    [string]$fiepath='PsGraphViz.png',
    [ValidateNotNullOrEmpty()]

    [stinrg]$dotFilePath ='PsGraphViz.dot',
    
    [ValidateNotNullOrEmpty()]
    [ValidateSet('bmp', 'canon', 'cmap', 'cmapx', 'cmapx_np', 'dot', 'emf', 'emfplus', 'eps', 'fig', 'gd', 'gd2', 'gif', 'gv', 'imap', 'imap_np', 'ismap', 'jpe', 'jpeg', 'jpg', 'metafile', 'pdf', 'pic', 'plain', 'plain-ext', 'png', '
pov', 'ps', 'ps2', 'svg', 'svgz', 'tif', 'tiff', 'tk', 'vml', 'vmlz', 'vrml', 'wbmp', 'xdot', 'xdot1.2', 'xdot1.4')]
    [string]$format='png'
    )
    process{

        $graphVizDot| Out-File -FilePath $dotFilePath -Encoding ascii 

        $cmdpath  ="~\Programs\graphviz\bin\dot.exe"
        Write-Verbose "Running app from $cmdpath"
        Invoke-Expression "& `"$cmdpath`" -T$format -o $fiepath $dotFilePath" 
    }
}



Wywołanie wygląda następująco:
$graph | ConvertTo-GraphViz  | Out-GraphViz

A po tej komendzie zostaną wygenerowane 2 pliki (dot plik oraz obraz grafu):

Brak komentarzy:

Prześlij komentarz