Tuesday, August 25, 2009

PowerShell and ZedGraph – Example 3

Welcome to part three in our PowerShell/ZedGraph series. Make sure you take a look at Part 1 & Part 2 before you continue on. Before we jump into more advanced features, I thought I would demonstrate how to populate the chart with real data. Apparently some were not impressed by the Yuengling consumption example (a fictitious one at that!).

We will use the ever diligent Get-Process cmdlet for our "real" data. The end result will look something like this:


Pretty no?

The code:
#Load the zedgraph dll
$ZedGraphDll = "C:\zedgraph_dll_v5.1.5\ZedGraph.dll"
[System.Reflection.Assembly]::LoadFrom($ZedGraphDll) | out-null

# Create a WinForm to serve as a container
$global:form = new-object Windows.Forms.form
$form.Size = new-object System.Drawing.Size @(500,400)

# Create a ZedGraphControl
$zgc = new-object -typename ZedGraph.ZedGraphControl
$zgc.GraphPane.Title.Text = "Processes"
$zgc.GraphPane.XAxis.Title.Text = "Process"
$zgc.GraphPane.YAxis.Title.Text = "WS(MB)"

# Go fetch me some processes data
$WS = @{Name='WS';Expression={"{0:#}" -f ($_.WorkingSet/1KB)}}
$processes = Get-Process | where {$_.WorkingSet -gt 30MB} | Sort Name | select $WS, Name

$a = $b = @()
foreach($Process in $Processes)
{
$a+= $Process.WS
$b+= $Process.Name
}

$curve = $zgc.GraphPane.AddBar("Test",$null,$a,[System.Drawing.Color]::Red)
$zgc.GraphPane.XAxis.Type = 'Text'
$zgc.GraphPane.XAxis.Scale.FontSpec.Angle = 65
$zgc.GraphPane.XAxis.Scale.MajorStep = 1
$zgc.GraphPane.X2Axis.Scale.FontSpec.Size = 8
$zgc.GraphPane.XAxis.Scale.TextLabels = $b

# Hide the legend
$zgc.GraphPane.Legend.IsVisible = $False

# Make me pretty...
$zgc.GraphPane.Fill = New-Object ZedGraph.Fill([System.Drawing.Color]::WhiteSmoke,[System.Drawing.Color]::Lavender,0)
$zgc.GraphPane.Chart.Fill = New-Object ZedGraph.Fill([System.Drawing.Color]::FromArgb(255,255,245), [System.Drawing.Color]::FromArgb(255,255,190),90)

# Calculate the Axis Scale Ranges
$zgc.AxisChange()

# Add our graph to the form
$Form.Controls.Add($zgc)
$zgc.dock = [System.Windows.Forms.DockStyle]::Fill

# Show the form
$Form.Add_Shown({$form.Activate()})
[void]$form.showdialog()
The only difference in this example is we create and populate a couple arrays (forgive my naming conventions) and use them as our data points.

I hope I have answered some of the questions about "real" data utilization with ZedGraph.

Enjoy!

Monday, August 24, 2009

PowerShell and ZedGraph – Example 2

If you haven't already, take a look at Example 1 before you move forward!
Let's continuing with our charting example. At this point we have created a simple bar chart. Let's make a couple of modifications.
The first thing we will do is to remove the legend.
All we need to do is set the Legend.IsVisible property:
$zgc.GraphPane.Legend.IsVisible = $False
Next, let's apply some color. We will set the pane background and the Axis background with a gradient:
$zgc.GraphPane.Fill = New-Object ZedGraph.Fill([System.Drawing.Color]::WhiteSmoke,[System.Drawing.Color]::Lavender,0)

$zgc.GraphPane.Chart.Fill = New-Object ZedGraph.Fill([System.Drawing.Color]::FromArgb(255,255,245), [System.Drawing.Color]::FromArgb(255,255,190),90)

Lastly, lets add some text to the graph:
$text = New-Object ZedGraph.TextObj("Supply`nDepleted",5,30)
$zgc.GraphPane.GraphObjList.Add($text)
$arrow = New-Object ZedGraph.ArrowObj([System.Drawing.Color]::Black,10,5,26,5,15)
$zgc.GraphPane.GraphObjList.Add($arrow)

So our end result should look something like this:

The code...
#Load the zedgraph dll
$ZedGraphDll = "C:\zedgraph_dll_v5.1.5\ZedGraph.dll"
[System.Reflection.Assembly]::LoadFrom($ZedGraphDll) | out-null

# Create a WinForm to serve as a container
$global:form = new-object Windows.Forms.form
$form.Size = new-object System.Drawing.Size @(500,400)

# Create a ZedGraphControl
$zgc = new-object -typename ZedGraph.ZedGraphControl
$zgc.GraphPane.Title.Text = "Yuengling Consumption"
$zgc.GraphPane.XAxis.Title.Text = "Month"
$zgc.GraphPane.YAxis.Title.Text = "Bottles"

$xLabels = "April", "May", "June","July", "August"
$yLabels = 60, 60, 75, 70, 15

$zgc.GraphPane.AddBar("Ying",$null,$yLabels,[System.Drawing.Color]::Red)
$zgc.GraphPane.XAxis.Type = 'Text'
$zgc.GraphPane.XAxis.Scale.TextLabels = $xLabels

# Hide the legend
$zgc.GraphPane.Legend.IsVisible = $False

# Fill the pane background with a gradient
$zgc.GraphPane.Fill = New-Object ZedGraph.Fill([System.Drawing.Color]::WhiteSmoke,[System.Drawing.Color]::Lavender,0)

# Fill the Axis Background with a gradient
$zgc.GraphPane.Chart.Fill = New-Object ZedGraph.Fill([System.Drawing.Color]::FromArgb(255,255,245), [System.Drawing.Color]::FromArgb(255,255,190),90)

# Add text item to decorate the graph
$text = New-Object ZedGraph.TextObj("Supply`nDepleted",5,30)
$zgc.GraphPane.GraphObjList.Add($text)

# Add an arrow pointer for the above text line
$arrow = New-Object ZedGraph.ArrowObj([System.Drawing.Color]::Black,10,5,26,5,15)
$zgc.GraphPane.GraphObjList.Add($arrow)

# Calculate the Axis Scale Ranges
$zgc.AxisChange()

# Add our graph to the form
$Form.Controls.Add($zgc)
$zgc.dock = [System.Windows.Forms.DockStyle]::Fill

# Show the form
$Form.Add_Shown({$form.Activate()})
[void]$form.showdialog()
Till next time - Enjoy!

Sunday, August 23, 2009

PowerShell and ZedGraph – Example 1

Was searching for a PowerShell Mathematics library when I stumbled upon a cool .NET drawing library that can be easily consumed in PowerShell –ZedGraph. This is a fairly robust library that will enable you to graph multiple types of charts, including overlays. I plan on writing a series of posts that will demonstrate these capabilities.

Lets get started!

For the first chart, we are going to keep it simple. We will create a standard Bar chart with some fictitious data. The end result will look something like this.


Now to the code:

# Load the ZedGraph dll   
$ZedGraphDll = "C:\zedgraph_dll_v515\zedgraph_dll_v5.1.5\ZedGraph.dll"
[System.Reflection.Assembly]::LoadFrom($ZedGraphDll) | out-null

# Create a WinForm to serve as a container
$global:form = new-object Windows.Forms.form
$form.Size = new-object System.Drawing.Size @(500,400)

# Create a ZedGraphControl
$zgc = new-object -typename ZedGraph.ZedGraphControl
$zgc.GraphPane.Title.Text = "Yuengling Consumption"
$zgc.GraphPane.XAxis.Title.Text = "Month"
$zgc.GraphPane.YAxis.Title.Text = "Bottles"

$xLabels = "April", "May", "June","July", "August"
$yLabels = 60, 60, 75, 70, 15

$zgc.GraphPane.AddBar("Ying",$null,$yLabels,[System.Drawing.Color]::Red)
$zgc.GraphPane.XAxis.Type = 'Text'
$zgc.GraphPane.XAxis.Scale.TextLabels = $xLabels

# Calculate the Axis Scale Ranges
$zgc.AxisChange()

# Add our graph to the form
$Form.Controls.Add($zgc)
$zgc.dock = [System.Windows.Forms.DockStyle]::Fill

# Show the form
$Form.Add_Shown({$form.Activate()})
[void]$form.showdialog()

As you can see, it is fairly simple to get a standard graph output. The class documentation on the ZedGraph site was very helpfull. Make sure you spend some time looking over it as you start to explore this dll. I will continue to build on this example over the next few days.

Enjoy!

Wednesday, August 12, 2009

2009 Summer Scripting Games – Beginner Event 3

What a pleasant surprise! Came into work this morning and saw that @makovec sent me a note indicating that this mornings Scripting Guys Blog referenced one of my submissions posted during the 2009 Summer Scripting Games!

The posting sited the use of the “undocumented” parameter –delimiter.

Their post is here.

It isn’t very often that Stahler and elegant are used in the same sentence…

Wednesday, August 5, 2009

Removing Header/Footer lines from CSV files

I was recently tasked with scheduling a script to read in a TSM.out file and create a usable CSV file from it. The TSM *.out file has at least 9 header lines that are not relevant to the end file as well as some extra footer lines. I also noticed that the column headers are not descriptive either. So, to automate the file transformation, we look to PowerShell!
function Create-CSV {
param( [int]$HeaderLines,
[int]$FooterLines,
[string]$SourceFilePath,
[string]$DestinationFilePath,
[string]$NewColumnNames )

if(Test-Path -literalPath $SourceFilePath) {
$a = Get-Content -path $SourceFilePath
if ($NewColumnNames -ne $null) {
Add-Content -path $DestinationFilePath `
-value $NewColumnNames
}
# Grab only the lines we need
$a[$HeaderLines..($a.count - $FooterLines)] | `
foreach{Add-Content -path $DestinationFilePath -value $_}
}
else {
Write-Error "$SourceFilePath does not exist."
}
} # End of function

Create-CSV -HeaderLines 9 `
-FooterLines 4 `
-SourceFilePath 'c:\temp\test.out' `
-DestinationFilePath 'c:\temp\test.csv' `
-NewColumnNames "Nodename,hostname,tcpipaddress"

Enjoy!