PoshCode Logo PowerShell Code Repository

LibraryChart (modification of post by Chad Miller view diff)
diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/1330"></script>download | new post

Defines functions for wokring with Microsoft Chart Control for .NET 3.5 Framework.Pipe output to Out-Chart function and specify chart type. Chart will display in form or save to image file. Real-time charts are supported by passing in a script block. Updated to fix line chart. Line Chart XAxis needs tweaking.

  1. # ---------------------------------------------------------------------------
  2. ### <Script>
  3. ### <Author>
  4. ### Chad Miller
  5. ### </Author>
  6. ### <Description>
  7. ### Defines functions for wokring with  Microsoft Chart Control for .NET 3.5 Framework
  8. ### Pipe output of Powershell command to Out-Chart function and specify chart type
  9. ### Chart will display in form or save to image file
  10. ### Real-time charts are supported by passing in a script block
  11. ### My thanks to Richard MacDonald for his wonderful post on Charting with PowerShell
  12. ### http://blogs.technet.com/richard_macdonald/archive/2009/04/28/3231887.aspx
  13. ### Note: Requires NET Framework 3.5 and Microsoft Chart Controls for Microsoft .NET Framework 3.5
  14. ### *** Updated 9/20/09 with  Ben's fixes http://xcud.com/post/192277838/mschart-in-psh ***
  15. ### </Description>
  16. ### <Usage>
  17. ### . ./LibraryChart.ps1
  18. ###  -------------------------- EXAMPLE 1 --------------------------
  19. ### Get-Process | Sort-Object -Property WS | Select-Object Name,WS -Last 5  | out-chart -xField 'name' -yField 'WS'
  20. ###
  21. ### This command will produce a default column chart
  22. ###
  23. ###  -------------------------- EXAMPLE 2 --------------------------
  24. ### Get-Process | Sort-Object -Property WS | Select-Object Name,WS -Last 5 | out-chart -xField 'name' -yField 'WS' -filename 'c:\users\u00\documents\process.png'
  25. ### This command will output the chart to a file
  26. ###
  27. ###  -------------------------- EXAMPLE 3 --------------------------
  28. ### Get-Process | Sort-Object -Property WS | Select-Object Name,WS -Last 5  | out-chart -xField 'name' -yField 'WS' -chartType 'Pie'
  29. ###
  30. ### This command will produce a pie chart
  31. ###
  32. ###  -------------------------- EXAMPLE 4 --------------------------
  33. ### out-chart -xField 'name' -yField 'WS' -scriptBlock {Get-Process | Sort-Object -Property WS | Select-Object Name,WS -Last 1} -chartType 'line'
  34. ###
  35. ### This command will produce a real-time line chart
  36. ###
  37. ### </Usage>
  38. ### </Script>
  39. # --------------------------------------------------------------------------
  40. [void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
  41. [void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
  42.  
  43. #######################
  44. function New-Chart
  45. {
  46.     param ([int]$width,[int]$height,[int]$left,[int]$top,[string]$chartTitle)
  47.     # create chart object
  48.     $global:Chart = New-object System.Windows.Forms.DataVisualization.Charting.Chart
  49.     $global:Chart.Width = $width
  50.     $global:Chart.Height = $height
  51.     $global:Chart.Left = $left
  52.     $global:Chart.Top = $top
  53.    # create a chartarea to draw on and add to chart
  54.     $chartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
  55.     $global:chart.ChartAreas.Add($chartArea)
  56.  
  57.     [void]$global:Chart.Titles.Add([string]$chartTitle)
  58.  
  59.     # change chart area colour
  60.     $global:Chart.BackColor = [System.Drawing.Color]::Transparent
  61.  
  62. } #New-Chart
  63.  
  64. #######################
  65. function New-BarColumnChart
  66. {
  67.     param ([hashtable]$ht, $chartType='Column', $chartTitle,$xTitle,$yTitle, [int]$width,[int]$height,[int]$left,[int]$top,[bool]$asc)
  68.  
  69.     New-Chart -width $width -height $height -left $left -top $top -chartTile $chartTitle
  70.  
  71.     $chart.ChartAreas[0].AxisX.Title = $xTitle
  72.     $chart.ChartAreas[0].AxisY.Title = $yTitle
  73.  
  74.     [void]$global:Chart.Series.Add("Data")
  75.     $global:Chart.Series["Data"].Points.DataBindXY($ht.Keys, $ht.Values)
  76.  
  77.     $global:Chart.Series["Data"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::$chartType
  78.  
  79.     if ($asc)
  80.     { $global:Chart.Series["Data"].Sort([System.Windows.Forms.DataVisualization.Charting.PointSortOrder]::Ascending, "Y") }
  81.     else
  82.     { $global:Chart.Series["Data"].Sort([System.Windows.Forms.DataVisualization.Charting.PointSortOrder]::Descending, "Y") }
  83.    
  84.     $global:Chart.Series["Data"]["DrawingStyle"] = "Cylinder"
  85.     $global:chart.Series["Data"].IsValueShownAsLabel = $true
  86.     $global:chart.Series["Data"]["LabelStyle"] = "Top"
  87.  
  88.  
  89. } #New-BarColumnChart
  90.  
  91. #######################
  92. function New-LineChart
  93. {
  94.  
  95.     param ([hashtable]$ht,$chartTitle, [int]$width,[int]$height,[int]$left,[int]$top)
  96.  
  97.     New-Chart -width $width -height $height -left $left -top $top -chartTile $chartTitle
  98.  
  99.     [void]$global:Chart.Series.Add("Data")
  100. #    $global:Chart.Series["Data"].Points.AddXY($(get-date), $($ht.Values))            
  101.     $global:Chart.Series["Data"].Points.DataBindXY($ht.Keys,$ht.Values)
  102.  
  103.     #$global:Chart.Series["Data"].XValueType = [System.Windows.Forms.DataVisualization.Charting.ChartValueType]::Time
  104.     #$global:Chart.chartAreas[0].AxisX.LabelStyle.Format = "hh:mm:ss"
  105.     #$global:Chart.chartAreas[0].AxisX.LabelStyle.Interval = 1
  106.     #$global:Chart.chartAreas[0].AxisX.LabelStyle.IntervalType = [System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType]::Seconds
  107.     $global:Chart.Series["Data"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line
  108.     #$global:chart.Series["Data"].IsValueShownAsLabel = $false
  109.  
  110. } #New-LineChart
  111.  
  112. #######################
  113. function New-PieChart
  114. {
  115.  
  116.     param ([hashtable]$ht,$chartTitle, [int]$width,[int]$height,[int]$left,[int]$top)
  117.  
  118.     New-Chart -width $width -height $height -left $left -top $top -chartTile $chartTitle
  119.  
  120.     [void]$global:Chart.Series.Add("Data")
  121.     $global:Chart.Series["Data"].Points.DataBindXY($ht.Keys, $ht.Values)
  122.  
  123.     $global:Chart.Series["Data"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Pie
  124.  
  125.     $global:Chart.Series["Data"]["PieLabelStyle"] = "Outside"
  126.     $global:Chart.Series["Data"]["PieLineColor"] = "Black"
  127.     #$global:chart.Series["Data"].IsValueShownAsLabel = $true
  128.     #$global:chart.series["Data"].Label =  "#PERCENT{P1}"
  129.     #$legend = New-object System.Windows.Forms.DataVisualization.Charting.Legend
  130.     #$global:Chart.Legends.Add($legend)
  131.     #$Legend.Name = "Default"
  132.  
  133. } #New-PieChart  
  134.  
  135. #######################
  136. function Remove-Points
  137. {
  138.     param($name='Data',[int]$maxPoints=200)
  139.    
  140.     while ( $global:chart.Series["$name"].Points.Count > $maxPoints )
  141.     { $global:chart.Series["$name"].Points.RemoveAT(0) }
  142.  
  143. } #Add-Series
  144.  
  145. #######################
  146. function Out-Form
  147. {
  148.     param($interval,$scriptBlock,$xField,$yField)
  149.  
  150.     # display the chart on a form
  151.     $global:Chart.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Right -bor
  152.                     [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Left
  153.     $Form = New-Object Windows.Forms.Form
  154.     $Form.Text = 'PowerCharts'
  155.     $Form.Width = 600
  156.     $Form.Height = 600
  157.     $Form.controls.add($global:Chart)
  158.     if ($scriptBlock -is [ScriptBlock])
  159.     {
  160.         if (!($xField -or $yField))
  161.         { throw 'xField and yField required with scriptBlock parameter.' }
  162.         $timer = New-Object System.Windows.Forms.Timer
  163.         $timer.Interval = $interval
  164.         $timer.add_Tick({
  165.  
  166.         $ht = &$scriptBlock | ConvertTo-HashTable $xField $yField
  167.         if ($global:Chart.Series["Data"].ChartTypeName -eq 'Line')
  168.         {
  169.             Remove-Points
  170.             $ht | foreach { $global:Chart.Series["Data"].Points.AddXY($($_.Keys), $($_.Values)) }              
  171.         }
  172.         else
  173.         { $global:Chart.Series["Data"].Points.DataBindXY($ht.Keys, $ht.Values) }
  174.         $global:chart.ResetAutoValues()
  175.         $global:chart.Invalidate()
  176.  
  177.         })
  178.         $timer.Enabled = $true
  179.         $timer.Start()
  180.        
  181.     }
  182.     $Form.Add_Shown({$Form.Activate()})
  183.     $Form.ShowDialog()
  184.  
  185. } #Out-Form
  186.  
  187. #######################
  188. function Out-ImageFile
  189. {
  190.     param($fileName,$fileformat)
  191.  
  192.     $global:Chart.SaveImage($fileName,$fileformat)
  193. }
  194. #######################
  195. ### ConvertTo-Hashtable function based on code by Jeffery Snover
  196. ### http://blogs.msdn.com/powershell/archive/2008/11/23/poshboard-and-convertto-hashtable.aspx
  197. #######################
  198. function ConvertTo-Hashtable
  199. {
  200.     param([string]$key, $value)
  201.  
  202.     Begin
  203.     {
  204.         $hash = @{}
  205.     }
  206.     Process
  207.     {
  208.         $thisKey = $_.$Key
  209.         $hash.$thisKey = $_.$Value
  210.     }
  211.     End
  212.     {
  213.         Write-Output $hash
  214.     }
  215.  
  216. } #ConvertTo-Hashtable
  217.  
  218. #######################
  219. function Out-Chart
  220. {
  221.     param(  $xField=$(throw 'Out-Chart:xField is required'),
  222.             $yField=$(throw 'Out-Chart:yField is required'),
  223.             $chartType='Column',$chartTitle,
  224.             [int]$width=500,
  225.             [int]$height=400,
  226.             [int]$left=40,
  227.             [int]$top=30,
  228.             $filename,
  229.             $fileformat='png',
  230.             [int]$interval=1000,
  231.             $scriptBlock,
  232.             [switch]$asc
  233.         )
  234.  
  235.     Begin
  236.     {
  237.         $ht = @{}
  238.     }
  239.     Process
  240.     {
  241.        if ($_)
  242.        {
  243.         $thisKey = $_.$xField
  244.         $ht.$thisKey = $_.$yField
  245.        }
  246.     }
  247.     End
  248.     {
  249.         if ($scriptBlock)
  250.         { $ht = &$scriptBlock | ConvertTo-HashTable $xField $yField }
  251.         switch ($chartType)
  252.         {
  253.             'Bar' {New-BarColumnChart -ht $ht -chartType $chartType -chartTitle $chartTitle -width $width -height $height -left $left -top $top -asc $($asc.IsPresent)}
  254.             'Column' {New-BarColumnChart -ht $ht -chartType $chartType -chartTitle $chartTitle -width $width -height $height -left $left -top $top -asc $($asc.IsPresent)}
  255.             'Pie' {New-PieChart -chartType -ht $ht  -chartTitle $chartTitle -width $width -height $height -left $left -top $top }
  256.             'Line' {New-LineChart -chartType -ht $ht -chartTitle $chartTitle -width $width -height $height -left $left -top $top }
  257.  
  258.         }
  259.  
  260.         if ($filename)
  261.         { Out-ImageFile $filename $fileformat }
  262.         elseif ($scriptBlock )
  263.         { Out-Form $interval $scriptBlock $xField $yField }
  264.         else
  265.         { Out-Form }
  266.     }
  267.  
  268. } #Out-Chart

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me