functions/graph-demo.ps1
|
using namespace Terminal.Gui function Invoke-TuiGraphDemo { [cmdletbinding()] [Alias('tuiGraph')] [OutputType("None")] param() #region initialize #You MUST invoke Init() [Application]::Init() #I recommend setting a QuitKey [Application]::QuitKey = 'Esc' #endregion #region create the main window and status bar $window = [Window]@{ Title = 'TUI Bar Chart Demo' } #Create a status bar at the bottom of the TUI $StatusBar = [StatusBar]::New( @( [StatusItem]::New('Unknown', $(Get-Date -Format g), {}), [StatusItem]::New('Unknown', 'ESC or Alt+Q to quit', {}), [StatusItem]::New('Unknown', 'Ready', {}) ) ) [Application]::Top.Add($StatusBar) #endregion #region add controls <# [Graphs.BarSeries] The series that holds all bars [Graphs.BarSeries+Bar] A nested type - one bar per data entry $bar.ColorScheme.Normal Sets the fill color for each bar $barSeries.BarSpacing = 3 Blank columns between each bar $graphView.CellSize Maps data units -> screen cells; controls bar height scaling $graphView.AxisY.Increment = 10 Y-axis tick every 10 units [Graphs.LegendAnnotation] Floating legend box showing keys + values # Wider bars -- increase the first PointF argument $graphView.CellSize = [PointF]::new(2, ...) # Move the legend -- args are (X, Y, Width, Height) in graph cell units [Rect]::new(1, 1, 12, $chartData.Count + 2) #> #I'm using percentages in the demo $chartData = [ordered]@{ ps1 = 22 psd1 = 11 psm1 = 11 txt = 17 json = 5 yml = 3 ps1xml = 2 xml = 4 png = 12 md = 16 } # Graph at the top of the window $graphView = [GraphView]@{ X = 1 Y = 1 Width = 100 Height = $chartData.count + 2 CanFocus = $false # prevents keyboard scrolling MarginLeft = 0 MarginBottom = 1 } # For a horizontal bar chart: # AxisX = the value axis (numbers) -- shown along the bottom # AxisY = the category axis (labels) -- shown on the left #I'm adjusting where the X axis starts so things align nicer #AxisX is a graphView property $graphView.AxisX.Minimum = 1.4 $graphView.AxisX.Text = '% Usage (0-100)' $graphView.AxisX.Increment = 5 # tick every 5% on a 0-100 scale #Although I'm hiding the Axis lines for this demo. You can enable them #if you want to see them. $graphView.AxisX.Visible = $false #AxisY is a graphView property $graphView.AxisY.Minimum = 0 $graphView.AxisY.Text = 'Extension' $graphView.AxisY.Visible = $False $graphView.AxisY.Increment = 1 $graphView.CellSize = [Terminal.Gui.PointF]::new(.5, 1) # Pin the view so X=0 is always the left edge $graphView.ScrollOffset = [Terminal.Gui.PointF]::new(0, 0) # Build a horizontal BarSeries $barSeries = [Graphs.BarSeries]::new() $barSeries.Orientation = [Graphs.Orientation]::Horizontal $barSeries.OffSet = 0 # blank rows between bars $fills = @( [Terminal.Gui.Attribute]::new('Cyan', 'Black'), [Terminal.Gui.Attribute]::new('BrightGreen', 'Black'), [Terminal.Gui.Attribute]::new('BrightYellow', 'Black'), [Terminal.Gui.Attribute]::new('BrightCyan', 'Black'), [Terminal.Gui.Attribute]::new('Brown', 'Black') [Terminal.Gui.Attribute]::new('Green', 'Black') [Terminal.Gui.Attribute]::new('Magenta', 'Black') [Terminal.Gui.Attribute]::new('Red', 'Black') [Terminal.Gui.Attribute]::new('BrightMagenta', 'Black') [Terminal.Gui.Attribute]::new('Gray', 'Black') ) #what is the longest extension name? Will use this later for padding. $maxKeyLen = ($chartData.Keys | Measure-Object -Maximum -Property Length).Maximum $i = 0 foreach ($key in $chartData.Keys) { #get a color from the array of fills $cell = [Graphs.GraphCellToRender]::new([System.Char]0x2588, $fills[$i % $fills.Count]) #scale the values #pad the text in the bar $bar = [Graphs.BarSeries+Bar]::new($key.PadRight($maxKeyLen + 1), $cell, ($chartData[$key] * 2)) $barSeries.Bars.Add($bar) $i++ } #add the bars to the graph view $graphView.Series.Add($barSeries) $window.Add($graphView) # Legend directly below the graph $lblLegend = [Label]@{ X = 1 Y = $graphView.Frame.Bottom + 1 Text = 'Legend:' } $window.Add($lblLegend) $i = 0 foreach ($key in $chartData.Keys) { $lbl = [Label]@{ X = 3 Y = $lblLegend.Frame.Bottom + $i Text = ([System.Char]0x2588).ToString() + " $key ($($chartData[$key])%)" } # Apply the matching bar color to the legend swatch $cs = [ColorScheme]::new() $cs.Normal = $fills[$i % $fills.Count] $lbl.ColorScheme = $cs $window.Add($lbl) $i++ } $btnQuit = [Button]@{ X = [pos]::Center() Y = $lblLegend.Frame.Bottom + $chartData.Count + 1 Text = '_Quit' } $btnQuit.Add_Clicked({[Application]::RequestStop()}) $window.Add($btnQuit) #endregion #region display #Add the Window and its nested controls to the TUI application [Application]::Top.Add($window) #Invoke the TUI [Application]::Run() #When the TUI ends it will shutdown [Application]::ShutDown() #endregion } |