Functions/Public/Write-Chart.ps1
|
<#
================================================================================ ORION DESIGN - POWERSHELL UI FRAMEWORK | Write-Chart Function ================================================================================ Author: Sune Alexandersen Narud Date: August 22, 2025 Module: OrionDesign v1.6.0 Category: Data Presentation Dependencies: OrionDesign Theme System FUNCTION PURPOSE: Creates visual charts including bar, column, line, and pie charts. Advanced data presentation component providing graphical data visualization with customizable dimensions, colors, and value display options. HLD INTEGRATION: ┌─ DATA PRESENTATION ─┐ ┌─ CHART TYPES ─┐ ┌─ OUTPUT ─┐ │ Write-Chart │◄──►│ Bar/Column │───►│ Visual │ │ • Multiple Types │ │ Line/Pie │ │ Charts │ │ • Custom Dimensions │ │ Custom Size │ │ Color │ │ • Value Display │ │ Auto Scale │ │ Coded │ └─────────────────────┘ └───────────────┘ └──────────┘ ================================================================================ #> <# .SYNOPSIS Creates simple ASCII charts for data visualization. .DESCRIPTION The Write-Chart function displays data in various chart formats using ASCII characters for basic visualization in the console. .PARAMETER Data Array of values or hashtable with labels and values. .PARAMETER ChartType The type of chart to display. Valid values: - 'Bar' - Horizontal bar chart - 'Column' - Vertical column chart - 'Line' - Simple line chart - 'Pie' - Basic pie chart representation .PARAMETER Title Optional title for the chart. .PARAMETER Width Width of the chart area. .PARAMETER Height Height of the chart area (for Column and Line charts). .PARAMETER ShowValues Display actual values on the chart. .PARAMETER ShowPercentage Display percentage values (for Pie charts). .EXAMPLE Write-Chart -Data @{CPU=75; Memory=60; Disk=90} -ChartType Bar -Title "System Usage" Displays a horizontal bar chart of system usage. .EXAMPLE Write-Chart -Data @(10, 20, 30, 25, 15) -ChartType Line -Title "Trend Analysis" Displays a line chart of trend data. #> function Write-Chart { [CmdletBinding(DefaultParameterSetName = 'Default')] param( [Parameter(Mandatory, ParameterSetName = 'Default', Position = 0)]$Data, [ValidateSet('Bar', 'Column', 'Line', 'Pie')] [string]$ChartType = 'Bar', [string]$Title = "", [int]$Width = 50, [int]$Height = 10, [switch]$ShowValues, [switch]$ShowPercentage, [Parameter(Mandatory, ParameterSetName = 'Demo')] [switch]$Demo ) if ($Demo) { $renderCodeBlock = { param([string[]]$Lines) $innerWidth = ($Lines | Measure-Object -Property Length -Maximum).Maximum + 4 $bar = '─' * $innerWidth Write-Host ' # Code' -ForegroundColor DarkGray Write-Host " ┌$bar┐" -ForegroundColor DarkGray foreach ($line in $Lines) { $padded = (" $line").PadRight($innerWidth) Write-Host " │" -ForegroundColor DarkGray -NoNewline Write-Host $padded -ForegroundColor Green -NoNewline Write-Host '│' -ForegroundColor DarkGray } Write-Host " └$bar┘" -ForegroundColor DarkGray Write-Host '' } Write-Host '' Write-Host ' Write-Chart Demo' -ForegroundColor Cyan Write-Host ' ================' -ForegroundColor DarkGray Write-Host '' Write-Host ' [Bar Chart]' -ForegroundColor Yellow Write-Host '' & $renderCodeBlock @("Write-Chart -Data @{CPU=75; Memory=60; Disk=90} -ChartType Bar -Title 'System Usage' -ShowValues") Write-Chart -Data @{CPU=75; Memory=60; Disk=90} -ChartType Bar -Title 'System Usage' -ShowValues Write-Host ' [Pie Chart]' -ForegroundColor Yellow Write-Host '' & $renderCodeBlock @("Write-Chart -Data @{Critical=5; High=12; Medium=23; Low=41} -ChartType Pie -Title 'Issues by Severity' -ShowPercentage") Write-Chart -Data @{Critical=5; High=12; Medium=23; Low=41} -ChartType Pie -Title 'Issues by Severity' -ShowPercentage return } # Default theme if (-not $script:Theme) { $script:Theme = @{ Accent = 'Cyan' Success = 'Green' Warning = 'Yellow' Error = 'Red' Text = 'White' Muted = 'DarkGray' Divider = '─' UseAnsi = $true } if ($psISE) { $script:Theme.UseAnsi = $false } } Write-Host if ($Title) { Write-Host "📊 $Title" -ForegroundColor $script:Theme.Accent Write-Host ("-" * ($Title.Length + 3)) -ForegroundColor $script:Theme.Muted Write-Host } # Convert data to consistent format $chartData = @() if ($Data -is [hashtable]) { foreach ($key in $Data.Keys) { $chartData += @{ Label = $key; Value = $Data[$key] } } } elseif ($Data -is [array]) { for ($i = 0; $i -lt $Data.Count; $i++) { $chartData += @{ Label = "Item $($i+1)"; Value = $Data[$i] } } } # Find max value for scaling $maxValue = ($chartData | ForEach-Object { $_.Value } | Measure-Object -Maximum).Maximum if ($maxValue -eq 0) { $maxValue = 1 } switch ($ChartType) { 'Bar' { foreach ($item in $chartData) { $barLength = [Math]::Round(($item.Value / $maxValue) * $Width) $label = $item.Label.PadRight(15) Write-Host $label -ForegroundColor $script:Theme.Text -NoNewline Write-Host " │" -ForegroundColor $script:Theme.Muted -NoNewline # Color coding based on value $color = $script:Theme.Accent if ($item.Value -ge $maxValue * 0.8) { $color = $script:Theme.Error } elseif ($item.Value -ge $maxValue * 0.6) { $color = $script:Theme.Warning } elseif ($item.Value -ge $maxValue * 0.3) { $color = $script:Theme.Success } for ($i = 0; $i -lt $barLength; $i++) { Write-Host "█" -ForegroundColor $color -NoNewline } if ($ShowValues) { Write-Host " $($item.Value)" -ForegroundColor $script:Theme.Text } else { Write-Host } } } 'Column' { # Scale values to fit height $scaledData = @() foreach ($item in $chartData) { $scaledValue = [Math]::Round(($item.Value / $maxValue) * $Height) $scaledData += @{ Label = $item.Label; Value = $item.Value; Scaled = $scaledValue } } # Draw chart from top to bottom for ($row = $Height; $row -gt 0; $row--) { foreach ($item in $scaledData) { if ($item.Scaled -ge $row) { Write-Host "██" -ForegroundColor $script:Theme.Accent -NoNewline } else { Write-Host " " -NoNewline } Write-Host " " -NoNewline } Write-Host } # Draw x-axis foreach ($item in $scaledData) { Write-Host "--" -ForegroundColor $script:Theme.Muted -NoNewline Write-Host " " -NoNewline } Write-Host # Draw labels foreach ($item in $scaledData) { $shortLabel = if ($item.Label.Length -gt 2) { $item.Label.Substring(0,2) } else { $item.Label } Write-Host $shortLabel -ForegroundColor $script:Theme.Text -NoNewline Write-Host " " -NoNewline } Write-Host if ($ShowValues) { Write-Host foreach ($item in $scaledData) { Write-Host "$($item.Label): $($item.Value)" -ForegroundColor $script:Theme.Text } } } 'Line' { # Scale values to fit height $scaledData = @() foreach ($item in $chartData) { $scaledValue = [Math]::Round(($item.Value / $maxValue) * ($Height - 1)) $scaledData += $scaledValue } # Create chart grid for ($row = $Height - 1; $row -ge 0; $row--) { Write-Host ($maxValue * ($row / ($Height - 1))).ToString("0").PadLeft(5) -ForegroundColor $script:Theme.Muted -NoNewline Write-Host " │" -ForegroundColor $script:Theme.Muted -NoNewline for ($col = 0; $col -lt $scaledData.Count; $col++) { if ($scaledData[$col] -eq $row) { Write-Host "●" -ForegroundColor $script:Theme.Accent -NoNewline } elseif ($col -gt 0 -and (($scaledData[$col-1] -gt $row -and $scaledData[$col] -lt $row) -or ($scaledData[$col-1] -lt $row -and $scaledData[$col] -gt $row))) { Write-Host "│" -ForegroundColor $script:Theme.Accent -NoNewline } else { Write-Host " " -NoNewline } # Connect points with lines if ($col -lt $scaledData.Count - 1) { if ($scaledData[$col] -eq $row -and $scaledData[$col+1] -eq $row) { Write-Host "─" -ForegroundColor $script:Theme.Accent -NoNewline } else { Write-Host " " -NoNewline } } } Write-Host } # X-axis Write-Host " " -NoNewline Write-Host "└" -ForegroundColor $script:Theme.Muted -NoNewline Write-Host ("─" * ($scaledData.Count * 2 - 1)) -ForegroundColor $script:Theme.Muted } 'Pie' { $total = ($chartData | ForEach-Object { $_.Value } | Measure-Object -Sum).Sum if ($total -eq 0) { $total = 1 } Write-Host " Pie Chart Representation" -ForegroundColor $script:Theme.Muted Write-Host $colors = @($script:Theme.Accent, $script:Theme.Success, $script:Theme.Warning, $script:Theme.Error, $script:Theme.Text) $colorIndex = 0 foreach ($item in $chartData) { $percentage = [Math]::Round(($item.Value / $total) * 100, 1) $barLength = [Math]::Round($percentage / 2) # Scale to reasonable size $color = $colors[$colorIndex % $colors.Count] $colorIndex++ Write-Host " " -NoNewline Write-Host "●" -ForegroundColor $color -NoNewline Write-Host " $($item.Label)".PadRight(15) -ForegroundColor $script:Theme.Text -NoNewline for ($i = 0; $i -lt $barLength; $i++) { Write-Host "█" -ForegroundColor $color -NoNewline } if ($ShowPercentage) { Write-Host " $percentage%" -ForegroundColor $script:Theme.Text } else { Write-Host " $($item.Value)" -ForegroundColor $script:Theme.Text } } } } Write-Host } |