Graphing with Glee

Graphing with Glee

  • Comments 9

Doug Finke has a blog HERE which shows you how to use PowerShell to program GLEE - Graph Layout Execution Engine.  GLEE is a .NET tool for graph layout and viewing developed by Lev Nachmanson of Microsoft Research.  You can read more about GLEE HERE.

I got pretty excited about this and grabbed Doug's example and hacked up a few functions to explore the GLEE a little bit more.  I'm happy with the direction these are going because it is much more PowerShell like in that it operates against sets of objects and utilizes metaprogramming which allows you to do a ton of work with a tiny amount of specification.  For instance, I defined an OBJECT Map which says how to graph objects based upon what type of object you have.  I also wrote a Set-GleeNodeAttribute which takes a graph and then a SCRIPTBLOCK where clause to select which nodes work against and then what attribute to apply.  It would have been better if it took a hash table of values so I could change the font, the fontsize, the fillcolor, etc all with one pass.  Here is an example of coloring all the nodes that have handles -ge 800 to RED.

Set-GleeNodeAttribute -Graph $g2 -where {$_.handles -ge 800} -Property FillColor -Value ([Microsoft.Glee.Drawing.Color]::Red)

If you follow the GLEE link, you'll see that it is a very rich surface.  My examples do not do it justice.  The first example shows a set of processes which map to their modules which map to their Products.  The second example shows a Dependency graph for a set of SERVICES.

image

image

function New-GleeViewer
{
    Param(
    [Drawing.Size]$size = $(New-Object Drawing.Size @(600,600))
    )
    [void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    [void] [Reflection.Assembly]::LoadFrom("C:\Program Files\Microsoft Research\GLEE\samples\WindowsApplication\WindowsApplication\bin\Debug\Microsoft.GLEE.GraphViewerGDI.dll")
    [void] [Reflection.Assembly]::LoadFrom("C:\Program Files\Microsoft Research\GLEE\samples\WindowsApplication\WindowsApplication\bin\Debug\Microsoft.GLEE.Drawing.dll")
    [void] [Reflection.Assembly]::LoadFrom("C:\Program Files\Microsoft Research\GLEE\samples\WindowsApplication\WindowsApplication\bin\Debug\Microsoft.GLEE.dll")

    $form = New-Object Windows.Forms.Form
    $form.Size = $size

    $viewer = New-Object Microsoft.Glee.GraphViewerGdi.GViewer
    $viewer.Dock = "Fill"
    $form.Controls.Add($viewer)
    $form.Add_Shown( { $form.Activate() } )
    return $form
}

function New-GleeGraph()
{
    $g = New-Object Microsoft.Glee.Drawing.Graph("graph");
    return $g
}

function Show-GleeGraph
{
    param(
    [Windows.Forms.Form]$viewer,
    [Microsoft.Glee.Drawing.Graph]$Graph
    )
    $viewer.Controls[0].Graph = $graph
    $result = $viewer.ShowDialog()
    $viewer.Controls[0].Graph = $null
}

function Graph-Object
{
    param(
        [Microsoft.Glee.Drawing.Graph]$graph,
        $inputObject,
        [HashTable]$objectMap
    )
    foreach ($o in @($inputObject))
    {  
        $oMap = $ObjectMap.$($o.PsTypenames[0])
        if ($oMap)
        {
            $node = $graph.AddNode($o.$($oMap.Label_Property))
            $node.UserData = $o
            foreach ($property in  @($o.$($oMap.Follow_Property)) |WHERE {$_})
            {  
                $pMap = $ObjectMap.$($property.PsTypeNames[0])
                if ($pmap)
                {
                    [void]$graph.AddEdge($o.$($oMap.Label_Property), $oMap.Follow_Label, $Property.$($pMap.Label_Property))
                    if ($pMap.Follow_Property)
                    {
                        Graph-Object -graph $graph -inputObject $Property -ObjectMap $ObjectMap
                    }
                }else
                {
                    [Void]$graph.AddEdge($o.$($oMap.Label_Property), $oMap.Follow_Label, $Property.ToString())
                }
            }
        }
    }
}

function Set-GleeNodeAttribute
{
    param(
    [Microsoft.Glee.Drawing.Graph]$Graph,
    [ScriptBlock]$Where,
    $Property,
    $Value
    )
    foreach ($node in ($graph.NodeMap.Keys | %{$graph.NodeMap.$_}))
    {
     if ($Node.UserData |where $where)
        {   $Node.Attr.$Property = $Value
        }
    }
}

###################################################
# now Let's ahve some fun!
##################################################
$ObjectMap = @{
    "System.ServiceProcess.ServiceController" = @{
        Follow_Property = "ServicesDependedOn"
        Follow_Label = "DependsUpon"
        Label_Property = "Name"
        }
     "System.Diagnostics.Process" = @{
        Follow_Property = "MainModule"
        Follow_Label = "Module"
        Label_Property = "ProcessName"
     }
     "System.Diagnostics.ProcessModule" = @{
        Follow_Property = "FileVersionInfo"
        Follow_Label = "Product"
        Label_Property = "ModuleName"
     }
     "System.Diagnostics.FileVersionInfo" = @{
        Label_Property = "ProductName"
     }
     "System.DateTime" = @{
        Label_Property = "Day"
     }
}

$viewer = New-GleeViewer

$g1 = New-GleeGraph
Graph-Object -Graph $g1 -InputObject (gsv net*p*) -ObjectMap $ObjectMap
$g2 = New-GleeGraph
Graph-Object -Graph $g2 -InputObject (gps *power*,*ss) -ObjectMap $ObjectMap

Show-GleeGraph $viewer $g1
Show-GleeGraph $viewer $g2
# NOW Let's color some of the elements
Set-GleeNodeAttribute -Graph $g2 -where {$_.handles -ge 800} -Property FillColor -Value ([Microsoft.Glee.Drawing.Color]::Red)
Show-GleeGraph $viewer $g2

Cheers!

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Attachment: show-ServiceDependencies.ps1
Leave a Comment
  • Please add 3 and 8 and type the answer here:
  • Post
  • Interesting point at blogs.msdn.com

  • Instead of illeagally using a "no commercial use" thing at work I will continue to use 'dot' from http://www.graphviz.org

    It takes in a simple text file and does the same kind of graph.

  • But does Dot leave you with a structure/tree .net objects that a wiley programmer can attach his own data structures to... and maniplulate on the fly?

    What! You save the data to a flat txt file? ;->

    Been using Glee with Powershell for a month or so now... arranges things nicely though the Microsoft Research guys could do with better documentation for their product... Would love to know how to draw graphs inside of graphs, for example...

    Try playing round with the aspect ratio option, as this can affect the layouts...

    Am still using REBOL "parse" to extract data from my code though....

    Still waiting for the powershell equivalent of awk, sed, REBOL parse, or BNF parser... ;-)

    Cheers,

    Rob Lancaster

  • Rob;

    Check this out for AWK: http://www.leeholmes.com/blog/parsetextObjectAWKWithAVengeance.aspx.

    As for SED, the -replace operator does most of what you want.

    It looks like most of the REBOL parse syntax boils down to a wordy type of regular expression, so those may be avenues for you too.

    Lee

  • GLEE, renamed as Microsoft Automatic Graph Layout can be purchased now at Windows Markeplace : http://www.windowsmarketplace.com/details.aspx?view=info&itemid=6002737. The link could be wrong, if it points nowhere please look for "graph layout".

  • comment url: http://blogs.msdn.com/powershell/archive/2007/11/27/graphing-with-glee.aspx#6545700

  • Re: GraphViz and WPF: http://www.codeproject.com/WPF/Dot2Wpf.asp

  • hi, I need some documentation, the link above ("You can read more about GLEE HERE") does not work. Can anyone give me another link where I can find Glee's documentation? Thanks a lot

  • Oh my god, why does Microsoft design everything so much more complicated than necessary...

    Let's hope this concept can stand the first and second real-world requirement...

    btw: I know "Graphviz/dot", too. It's really simple and does only what one expects it to do: It calculates the layout of graphs (.dot/.svg/.ps/....) - of course: no ".NET objects" ;-).

Page 1 of 1 (9 items)