Foliotek Developer Blog

Computing Color-Based Representation of Performance

Initial Work

I have been working on trying to visually represent numerical data of how a particular user/student has performed, and I thought I would share some of my thoughts. There are many different scales in our system with which a student may be scored. For instance, a metric may have 5 levels of scoring:

  • Does not meet expectations: 1 point
  • Approaches expectations: 2 points
  • Meets expectations: 3 points
  • Exceeds expectations: 4 points
  • Exemplary: 5 points

The maximum amount of points is 5 and the minimum is 1. One way to represent this is to show a miniature rubric of the levels with the student’s level selected. This just a simple table with a td for each level. Mousing over the td shows the level’s name. This table is specified at a 100 px width.

Adding Color

However, just having a colored indicator for what was selected seemed a little bland, so I began trying to envision how an appropriate color could be added. Red and Green are commonly used to associate bad to good, so I decided to try to compute appropriate greens and reds to represent the student’s score. The all green (#0F0) and all red (#F00) seem a little too much, so I thought I would set the range between what I will refer to as “strong green” and “strong red” (#0A0 and #A00).

*For anyone not familiar with this representation, it is the RGB/Red Green Blue value in hexadecimal with an integer range of 0 to 255 for each. “A” = 160 an “F” = 255. *

The Math

So, how do you represent the different levels by color? Essentially, the amount of green will start at zero and increase to “A” (160) and the amount of red will start at “A” (160) and decrease to zero. The blue will remain at zero no matter what.

In the case above, I initially came up with this computation:

Green = ( (Points Earned) / (Max Points Possible) ) * 160
= ( 4 / 5 ) * 160
= 80% green
= 128 (80 in hex)

Red = 160 – Green
= 32 (20 in hex)

Computed Color = #280 (20% of max red, 80% of max green, no blue)

The Mathematical Error

However, this does not work completely right, specifically due to the fact that the scale does not begin at zero. Thus, while the highest score will compute to the maximum green, the lowest score will not compute to no green, but to 20% of the maximum amount of green.

To fix this, I realized I needed to essentially make the minimum score equal to zero. This can be easily done by subtracting the minimum points possible from BOTH the Points Earned and the Max Points Possible.

Green = ( (Points Earned) – (Min Points Possible) ) / ( (Max Points Possible) – (Min Points Possible) ) * 160
= ( (4 – 1) / (5 – 1) ) * 160
= ( 3 / 4 ) * 160
= 75% green
= 120 (78 in hex)

Red = 160 – Green
= 40 (28 in hex)

Computed Color = #280 (20% of max red, 80% of max green, no blue)

Thus, there are five possibilities: 0% Green, 25% Green, 50% Green, 75% Green and 100% Green. The inclusive zero is the key here.

The Colorful Grid

This allows for a more colorful grid. I have provided one grid with a single score selected and then one with each of them, just to show the different colors:

Expanding to Aggregate Scores

We also needed a way to represent aggregate data that would not have specific set of defined levels. For instance, if a user had 20 scores from varying metrics, how could this be represented?

What I did was again computed the total number of points and the total earned points. Then I again adjusted for the minimum number of points possible in cases where the metrics do not start at zero.

I enlarged the width of the table for this to stretch across the entire screen. I’ll make it 500 px for this example. This table also has just three cells, with the first and third being essentially spacers and the second cell representing the score. I realized I only needed to compute the width of the first cell. The second cell will be a fixed width of 30 px, and then the third cell will take up the remaining space, if any.

The math for computing the color will still be the same. The key thing is to compute the size of the first column. If the table width is 500 px and the width of the score cell is 30 px, then there is only a total range of 0 to 470 pixels where that cell can be placed on the range. When it is placed at 470 pixels, that is the maximum it can be, as it will fill the remainder of the space on the table.

The Math for Placement

So, let’s assume that the total number of points a student received was 215 out of a total possible of 250. The minimum points earned will be 15. Adjusting the scale, this would indicate 200 out of 235 points earned. We can easily see, then, that our math should give us a width of the first cell of 400 pixels, since 235 is half of 470. (Yeah, I made it easy. I know. But this way we can validate the math.)

Placement = ( (Total Points Earned) – (Min Points Possible) ) / ( (Max Points Possible) – (Min Points Possible) ) * 470
= ( 215 – 15 ) / ( 250 – 15 ) * 470
= 200 / 235 * 470
= 400

Green = ( (Points Earned) – (Min Points Possible) ) / ( (Max Points Possible) – (Min Points Possible) ) * 160
= ( (215 – 15) / (250 – 15) ) * 160
= ( 200 / 235 ) * 160
= 85% green
= 136 (88 in hex)

Red = 160 – Green
= 24 (18 in hex)

Thus, the table looks like this:


So, I thought that was pretty interesting, but it gives a fairly clear visual representation of a student’s performance.