Skip to content

Instantly share code, notes, and snippets.

@Nora-Ballard
Created July 27, 2014 13:54
Show Gist options
  • Select an option

  • Save Nora-Ballard/96b1d4fd4026ff410843 to your computer and use it in GitHub Desktop.

Select an option

Save Nora-Ballard/96b1d4fd4026ff410843 to your computer and use it in GitHub Desktop.
Functions for creating Dot (graphviz) diagrams from Powershell.
function New-DotGraph {
param(
[Parameter(Mandatory)]
[string]$Name,
[Parameter()]
[ValidateSet('Letter','Legal','11x17')]
$PageSize,
[Parameter()]
[ValidateSet('Portrait','Landscape')]
$PageOrientation = "Portrait",
[Parameter()]
[ValidateSet('TB','LR','BT','RL')]
$RankDirection = 'TB',
[Parameter()]
[switch]$Concentrate,
[Parameter()]
[ValidateSet('BreadthFirst','NodesFirst','EdgesFirst')]
$OutputOrder
)
$Output = [pscustomobject]@{
'Name' = $Name
'Nodes' = @()
'Edges' = @()
'Ranks' = @()
'Options' = [pscustomobject]@{}
}
if ($RankDirection -in @('TB','LR','BT','RL')) {
Add-Member -InputObject $Output.Options -MemberType NoteProperty -Name 'rankdir' -Value $RankDirection.ToUpper()
}
if ($Concentrate) {
Add-Member -InputObject $Output.Options -MemberType NoteProperty -Name 'concentrate' -Value $Concentrate.ToString().ToLower()
}
if ($OutputOrder) {
Add-Member -InputObject $Output.Options -MemberType NoteProperty -Name 'outputorder' -Value $OutputOrder.ToLower()
}
if ($PageSize -in @('Letter','Legal','11x17')) {
switch ($PageSize) {
'Letter' {$PageWidth = 8.5 ; $PageHeight = 11}
'Legal' {$PageWidth = 8.5 ; $PageHeight = 14}
'11x17' {$PageWidth = 11 ; $PageHeight = 17}
}
$PageString = if ($PageOrientation -eq 'Landscape') {'{1},{0}'} else {'{0},{1}'}
Add-Member -InputObject $Output.Options -Name 'autosize' -MemberType NoteProperty -Value 'false'
Add-Member -InputObject $Output.Options -Name 'page' -MemberType NoteProperty -Value $($PageString -f @($PageWidth, $PageHeight))
Add-Member -InputObject $Output.Options -Name 'size' -MemberType NoteProperty -Value $($PageString -f ($PageWidth-1), ($PageHeight-1))
}
Add-Member -InputObject $Output -Name 'GetDotString' -MemberType ScriptMethod -Value {
$dot = @()
$dot += 'digraph {0} {{' -f $this.Name
if (@($this.Options.psobject.properties).Count -gt 0) {
$dot += ' graph['
$this.Options.psobject.properties | ForEach-Object {
$dot += ' {0}="{1}"' -f $_.Name, $_.Value
}
$dot += ' ];'
}
if ($this.Nodes.Count -gt 0) {
$dot += $this.Nodes | ForEach-Object {$_.GetDotString()}
}
if ($this.Ranks.Count -gt 0) {
$dot += $this.Ranks | ForEach-Object {$_.GetDotString()}
}
if ($this.Edges.Count -gt 0) {
$dot += $this.Edges | Sort-Object Node,ParentNode -Unique| ForEach-Object {$_.GetDotString()}
}
$dot += '}'
Write-Output $dot
}
Write-Output $Output
}
function New-DotRank {
param(
[Parameter()]
[ValidateSet('same','min','source','max','sink')]
$RankType,
[Parameter()]
[array]$NodeNames
)
$Output = [pscustomobject]@{
'RankType' = $RankType
'Nodes' = $NodeNames
}
Add-Member -InputObject $Output -Name 'GetDotString' -MemberType ScriptMethod -Value {
$dot = ' {{rank = {0}; {1};}}' -f $this.RankType, $(($this.Nodes | %{'"{0}"' -f $_}) -join ';')
Write-Output $dot
}
Write-Output $Output
}
function New-DotNode {
param(
[Parameter(Mandatory)]
$Name,
$Shape,
$Label,
$Color
)
$Output = [pscustomobject]@{
'Name' = $Name
'Options' = [pscustomobject]@{
'Label' = $Name
}
}
if ($Shape) {
Add-Member -InputObject $Output.Options -MemberType NoteProperty -Name 'Shape' -Value $Shape
}
if ($Label) { $Output.Options.Label = $Label }
if ($Color) {
Add-Member -InputObject $Output.Options -MemberType NoteProperty -Name 'Color' -Value $Color
}
Add-Member -InputObject $Output -Name 'GetDotString' -MemberType ScriptMethod -Value {
$Parameters = @(
$this.Name
if (@($this.Options.psobject.properties).Count -gt 0) {
@($this.Options.psobject.properties | ForEach-Object {
if ($_ -ne $null) {'{0} = "{1}"' -f $_.Name, $_.Value}
}) -join ','
}
)
$dot = @(' "{0}" ' -f $this.Name)
if (@($this.Options.psobject.properties).Count -gt 0) {
$dot += ' ['
$Options = @($this.Options.psobject.properties | Where {$_ -ne $null} | ForEach-Object {
if ($_.Value -is [string]) {
$dot += '{0,8}{1} = {2}' -f ' ', $_.Name.ToLower(), $_.Value
}
elseif ($_.Value -is [array]) {
$dot += '{0,8}{1} = <' -f ' ', $_.Name.ToLower()
$_.Value | ForEach-Object { $dot += '{0,12}{1}' -f ' ', $_ }
$dot += '{0,8}>' -f ' '
}
})
$Options | ForEach-Object { $dot += $_ }
$dot += ' ];'
}
Write-Output $dot
}
Write-Output $Output
}
function New-DotEdge {
param(
$Node,
$Port,
$ParentNode,
$ParentPort,
$Color
)
$Output = [pscustomobject]@{
'Node' = $Node
'Port' = $Port
'ParentNode' = $ParentNode
'ParentPort' = $ParentPort
}
if ($Color) {
Add-Member -InputObject $Output -MemberType NoteProperty -Name 'Options' -Value $([pscustomobject]@{'Color' = $Color})
}
Add-Member -InputObject $Output -Name 'GetDotString' -MemberType ScriptMethod -Value {
$Parameters = @(
$this.Node
if ($this.Port) {':"{0}"' -f $this.Port} else {""}
$this.ParentNode
if ($this.ParentPort) {':"{0}"' -f $this.ParentPort} else {""}
if ($this.Options.psobject.properties -ne $null) {
$dot = '['
$Options = @($this.Options.psobject.properties | ForEach-Object {
if ($_ -ne $null) {'{1}="{2}"' -f ' ', $_.Name, $_.Value}
}) -join ','
$dot += $Options
$dot += ']'
if ($dot -ne '[]') {$dot} else {''}
} else {''}
)
$dot = ' "{0}"{1} -> "{2}"{3} {4};' -f $Parameters
Write-Output $dot
}
Write-Output $Output
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment