Weekend Scripter: PowerShell ASCII Bar Charts
Summary: Microsoft PFE, Wei Hao Lim, presents a script that creates ASCII bar charts.
Microsoft Scripting Guy, Ed Wilson, is here. Today we have a new guest blogger. Please welcome Wei Hao Lim.
Wei is a Microsoft PFE from Australia who works primarily with enterprise customers helping to configure, deploy, maintain, and customize System Center implementations. In his spare time, he enjoys video editing, swimming, playing with board games, and video games. He writes a very popular blog named Wei Out There with System Center.
This article features a sample PowerShell script that generates a bar chart made up of ASCII characters. This sample script can now be downloaded from the Script Center Repository: Sample Script to Generate ASCII Bar Charts.
There are four main parts of this sample script:
a. Assigning values to main variables
b. Normalizing, sizing, and scaling the height of the bars and columns
c. Figuring out the amount of whitespace to allocate to each column
Assigning values to main variables
In this instance, the script creates a five bar or column ASCII bar chart based on the values assigned to five variables:
Names can also be given to each bar or column by assigning a string value to five variables:
Normalizing, sizing, and scaling the height of the bars and columns
With values assigned to the main variables, the script calculates the number of pipe characters ( | ) required end-to-end to represent the height of each ASCII bar. This is determined by first normalizing the values obtained earlier, and then multiplying with their average value to determine the number of pipe characters required (or the “height” of each bar).
Using the average value as a coefficient to determine the height of each bar is a design decision because the value can be calculated automatically without the need to manually assign a meaningful value to another variable. However, any other values could be used as the coefficient. This coefficient is used to determine the maximum height of the bar chart columns and the relative height for each bar within its column.
There is another variable that can be used to decrease or increase the overall height of the bars on the bar chart to fit into the space or screen size available:
The calculated height of each bar must be a whole number (Round()) because they will be used to determine the number of pipe characters required to render each of the bars within the ASCII bar chart.
Figuring out the amount of whitespace to allocate to each column
For me, the most challenging part when writing this script was figuring out the “space-time continuum” (where space = whitespace characters) as printing of the characters happens from left to right and top to bottom.
If the whitespaces in each column are not taken into account, the rows could overlap and become distorted when rendering the bar chart, as you can see in the following example:
By leveraging this behavior of how characters are printed from left to right, and by tackling the whitespaces and bar space one column at a time, I was able to address the problem.
To determine how many rows of whitespaces are required for a specific column, the difference between the maximum and its current bar height is calculated:
Based on the difference, if the condition is still valid, the script will append a padded string of whitespace characters (“ “) to the output string ($renderString) at every new row until the bar space rendering part takes over.
Note The length of the padded string of whitespace characters is equal to the length of the string value assigned to the bar name variable + extra padding of four whitespace characters.)
The rendering part is simply appending strings and newline characters to produce an output string that consist of multiple rows, based on the total height of the bar chart determined earlier:
At the end of every loop cycle, a newline character is appended to the output string.
The width of a bar in a column is determined by the name or string value that you assigned to the main variables.
At the beginning of each loop cycle, the script determines if a whitespace padded string should be appended to the output string for each column. Otherwise, the bar space rendering part starts with the following strings appended in the first three rows, then pipe characters for the remainder of the column:
Row 1: A string of the assigned values in parentheses
Row 2: The cover of the bar (using a string consisting of pipe characters)
Row 3: The name of the bar assigned
To add a new bar and column to the ASCII bar chart, you can reuse this section and replace the variables with new ones for the new bar or column.
Finally, after the loop completes, a string is appended to the output string to give the chart an X-axis:
This script can add value to many reporting and alerting scenarios by providing a quick and simple way to generate a bar chart that can help visualize and compare data collected or generated by monitoring systems like System Center Operations Manager.
Disclaimer All the information in this post is provided on an as-is basis with no warranties and for informational purposes only. Use at your own risk. The opinions and views expressed in this post are those of the author and do not necessarily state or reflect those of my employer.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy