December 12th, 2015

Weekend Scripter: PowerShell ASCII Bar Charts

Doctor Scripto
Scripter

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.

Here’s Wei…

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

Here is a screenshot of what the ASCII bar chart looks like when the script is run in a PowerShell session:
Image of chart

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

            d. Rendering

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:

Image of values

Names can also be given to each bar or column by assigning a string value to five variables:

Image of 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: 

Image of variable

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.

Image of command

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:

Image of chart

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:

Image of calculation

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.)

Image of command

Rendering

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:

Image of command

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

Image of chart

Image of command

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:

Image of command

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.

~Wei

Thanks, Wei!

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

0 comments

Discussion are closed.