Types/Turtle/BarGraph.ps1
<# .SYNOPSIS Draws a bar graph using turtle graphics. .DESCRIPTION This script uses turtle graphics to draw a bar graph based on the provided data. .EXAMPLE turtle barGraph 100 100 5 10 15 20 15 10 5 .EXAMPLE turtle barGraph 200 200 ( @(1..50;-1..-50) | Get-Random -Count (Get-Random -Minimum 5 -Maximum 20) ) save ./RandomBarGraph.svg .EXAMPLE turtle rotate 90 barGraph 200 200 ( @(1..50;-1..-50) | Get-Random -Count (Get-Random -Minimum 5 -Maximum 20) ) save ./RandomVerticalBarGraph.svg .EXAMPLE turtle rotate 45 barGraph 200 200 ( @(1..50;-1..-50) | Get-Random -Count (Get-Random -Minimum 5 -Maximum 20) ) save ./RandomDiagonalBarGraph.svg .EXAMPLE $sourceData = @(1..50;-1..-50) $itemCount = (Get-Random -Minimum 5 -Maximum 20) $points = $sourceData | Get-Random -Count $itemCount turtle bargraph 200 200 $points morph @( turtle bargraph 200 200 $points turtle bargraph 200 200 ( $sourceData | Get-Random -Count $itemCount ) turtle bargraph 200 200 $points ) save ./RandomBarGraphMorph.svg #> param( # The width of the bar graph [double]$Width, # The height of the bar graph. # Please note that in the case of negative values, the effective height is twice this number. [double]$Height, # The points in the bar graph. # Each point will be turned into a relative number and turned into an equal-width bar. [Parameter(ValueFromRemainingArguments)] [double[]]$Points ) # If there were no points, we are drawing nothing, so return ourself. if (-not $points) { return $this} # Divide the width by the number of points to get a very snug bar graph $barWidth = $width / $points.Length # Find the maximum and minimum values in the points $min, $max = 0, 0 foreach ($point in $points) { if ($point -gt $max) { $max = $point} if ($point -lt $min) { $min = $point} } # This gives us the range. $range = $max - $min # If the range is zero, we're drawing a flatline. if ($range -eq 0) { # so just draw that line and return. return $this.Forward($width) } # Now that we've normalized the range, we can draw the bars. for ($pointIndex =0 ; $pointIndex -lt $points.Length; $pointIndex++) { # Each point is essentially telling us the height $point = $points[$pointIndex] # which we can turn into a relative value $relativeHeight = ( # by subtracting the minimum and dividing by the range (($point - $min) / $range) ) * $height # If the point was negative, we need to flip the height if ($point -lt 0) { $relativeHeight *= -1} # Now we can draw the bar $this = $this. # Turn outward and draw the side Rotate(-90).Forward($relativeHeight). # Turn and draw the top Rotate(90).Forward($barWidth). # Turn and draw the other side Rotate(90).Forward($relativeHeight). # Turn back to the original direction Rotate(-90) } return $this |