PoshCode Logo PowerShell Code Repository

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