Thursday, June 7, 2012

Rendering static progress bars using HTML5 canvas

This project is up on GitHub.

Recently our stakeholders were in need of an analytics page for some common tabular data generated from an in-house application we’ve built.  Without going into too much detail, they essentially needed to track progress.

In all honestly they would have been happy seeing a table of integers with some format like “progress / total”.  I thought that we could do better than that though, since it would just look like a wall of text.  The solution I wanted to build would allow them to easily glance at the data and know immediately what kind of progress was being made.

I’ve had some experience using fusion charts before but I needed something a little simpler for static progress bars.  Initially I was thinking to use SVG, but I would be rendering hundreds of progress bars on one page (even if I’m paging the data, which I am using a custom paging class I built – that’s for a future post though).

So, I decided on using canvas.  Everyone using our app has the latest browsers, and I knew it would be a good learning experience.

 

File->New Project… Lets model our data

We use ASP.net MVC for the analytics site but I won’t go into too much detail here.  I’m using the Visual Studio 2012 preview.

For my demo data, I’ll create a simple model that allows me to display a set of progress values for one total value.
1-ProgressModel_thumb6

 

Index action

My index action is really simple.  Using the model above, I create a viewmodel and populate it with a whole bunch of random data.  For the demonstration, each set of progress data has 5 progress values for a given total.

First I randomize the total, and I then I use that value to randomize 5 progress values.

2-Index_thumb3

 

Create the index view

Next up I create my view which is strongly typed to a list of my ProgressionData model.  Most of the work will be done using the tooling template, which will allow me to easily display the data in a table.  Nothing too impressive to see yet.

5-TemplatedView_thumb1

I make some modifications to the templated view so that I have ‘appropriate’ headers, and utilize my viewmodels list of progress values so I can render progress bars. 

For each progress value, I have a cell that will contain the canvas.  Notice I use custom ‘data’ attributes so I have the values to work with in javascript.  The final markup is below:

6-FinalTable_thumb4

 

Rendering borders

For each progress bar in my markup I want to render using the same method, so I select all the canvas elements by class using Jquery and iterate through them using an anonymous function.

First I need to get those custom data values.  I calculate the percentage complete here too, which you’ll see I use in rendering.

7-GetScriptValues_thumb1

I’m finally ready to begin rendering, and I’m going to start with the borders for each progress bar.  It’s a nice starting point since it puts something on the screen and all I’m dealing with is width and height.

To render to a canvas you need to first get the rendering context, “2d” in this case.

Drawing with canvas is similar to openGL and DirectX in that it’s a state machine.  You setup some state, and then put all your rendering calls together in “batches” (or at least that is what you should be doing to maintain optimal rendering).

Here I don’t really need to set anything up.  Black is the default stroke and fill colors, so I just draw the border using the strokeRect function.

8-DrawingBorders_thumb2

The first two parameters are the starting x and y points for the rectangle; the last two are the width and height.

Canvas’ coordinate system is setup such that 0,0 is the upper left point of the rendering area with positive x values moving right, and positive y values moving down.

I set the context to null at the end to encourage FireFox to collect garbage as quickly as possible.  It’s a performance trick I’ve read about somewhere… It did seem to help when looking under the hood at memory consumption.

Here’s what we have so far:

9-BordersRendered_thumb1

 

Visualizing the data

I’m well on my way to displaying a nice representation of the progress data that I have.  Next I’ll fill in those bars.

In order to draw the progress I multiply the width of the progress bar by the percentageComplete which gives me a value equal to or less than the width.

I also need to add a pixel of padding when I fill, otherwise I’ll draw over the border (which isn’t necessarily horrible depending on your needs).

I’ll set the fillStyle to green before I add an additional fill draw call.  I start just 1 pixel in for both x and y, and subtract 2 from the progress width and height (1 for the border pixel on the left and right, and 1 for the top and bottom – 2 total for the width and height).

11-DrawingProgress_thumb2

Here’s what it looks like (keeping in mind that the values are randomized every refresh).

12-FilledGreen_thumb1

 

Going further

In all honesty I could have stopped here.  After all, this is a much better solution than just showing the values in plain text.  I can clearly see how much progress we’ve made for each set of data.

But, that’s just not my style.  I’m in it for the long haul; I don’t ever like to settle.

The first adjustment I want to make is the color.  It’s a bit flat, and it’s a whole lot of green.

To render a linear gradient you call createLinearGradient from the context, and pass in the start and end x and y coordinates.  I wanted a gradient that would travel down the height of the progress bar, so I only passed in the height value.

You make a call to addColorStop for every color you want to draw in the gradient.  The function takes a float value from 0.0 to 1.0, indicating the start position of that color.  The second parameter is the color of that color stop.

With this in mind, I decided to put a little life into the “staticness” of my progress bars. 

I start off with red and pink colors.  If our progress is equal to or above 75%, I color them green indicating that we’re close to being done!  If were 50% or above, yellow and orange.

13-SetupGradient_thumb1

Here’s what we have now, and I think you’ll agree this looks a ton better:

14-RenderedGradients_thumb3

Different colors can be used if you so desire.  You could for example, color the bar a flat faded green if it’s 100% to further help separate “completion” from “in progress”.

 

Overlaying text

One last finishing touch I wanted to make was to also display the values themselves on the progress bar.

To do this, I make add some state changes for text and then call fillText.  It takes three parameters:  The text, the x location and the y location.

Canvas has built-in support for rendering shadows so I took advantage of this.  Normally I would just render the shadow text first a few pixels off, so it’s a welcomed feature.

My shadow color is set to white and offset by a few pixels.  I also added a 2 pixel blur.

15-SetupFont_thumb1

To render the text, I needed to do some more math.  When text gets rendered, it appears at the x and y values you specify.  So if you were to render text at 0,0 you wouldn’t even see it because it would be just outside the canvas.

I decided to render the textual value of the progress as well as the percentage complete.  The text is rendered on the left and right side of the progress bar, centered in middle.

Rendering on the left was easy.  I used my previous padding variable and added it to 0.  To render in the middle of the bar, I divide the height by two and add a few pixels to compensate for the height of the text itself (you’ll have to play with this value to get it right).

Rendering on the right side is a bit more tricky.  You need to know how many pixels the text itself takes up to ensure that it doesn’t get rendered outside the canvas.

To solve this, you could guess and add padding, or just use the function measureText!  It takes one parameter, the text you want to measure.

To get the measurement I want, I needed to convert a float value with a very long trail of precision to a percentage.  So, I just multiply the float by 100 to move the decimal, and then call the toFixed function with 0 precision (I only wanted a whole number).  Then I added the percent symbol.

16-CalculateTextPositionAndDraw_thum

All that hard work has paid off.  Here’s how the final rendering looks:

17-FinalRendering_thumb2

 

Let me know what you think in the comments.  It was a really fun task that only took a few days of work, mostly to learn to use the canvas library and work with the data I had already been returning from our database (which took much longer).

The entire project is up on GitHub.  Feel free to download it and check it out.

Sunday, January 8, 2012

Typing In Dvorak

I came across an article over the Christmas break (I can’t find it for the life of me) which had rather large list of new things to try next year, the idea being to choose just one.  If I remember correctly, the purpose of the article explained how challenging your brain in new ways can help when learning new skills (something I’m trying to do all the time).  I chose to challenge my brain by learning to type in Dvorak.

I’ve actually done something like this before with a great deal of success.  In 5th grade, for whatever reason, I decided that it was time to learn how to write left handed.  I think I was just bored in school and needed something interesting to do.

I forced myself.  I did all my assignments and homework with my left hand.  For the first several weeks my writing looked awful, sometimes like scribbles.  My teacher wrote very concerned letters to my parents and even called home a few times.  My parents were not happy at all.  Looking back, I’m sure they thought I was just acting out.

That certainly didn’t stop me, and I’m glad it didn’t.  The effort was worth it.  To this day I’m fully ambidextrous.

 

Benefits

  • Increased typing speed
  • Less finger movement
  • Less mistakes
  • Help prevent RSI (repetitive strain injury)

 

Starting out

To begin this journey, I took a popular typing test using QWERTY.  The results are below:
Typing Speed

Speed is obviously not the primary reason for my wanting to learn as I’m well above average.  As a software engineer, my job requires constant typing (although there are auto-complete tools I use to cut down on typing).  My primary reason is to help prevent RSI, though making less mistakes overall would be nice.

I’ve already begun!  I’ve successfully memorized the location of all the keys using an on-screen keyboard and practiced using the tutor here, which is great since I don’t have a physical Dvorak keyboard (nor do I want one – we only have laptops).

Here’s an assessment of my current speed in Dvorak:
image

Having typed this entire post using Dvorak, I can say with certainty that this will be challenging, yet possible.  I have a ways to go, but the key to success is to keep practicing.  Somewhat similar to being ambidextrous, I fully plan on being ambikeyboardstrous.

If you are thinking about trying it out, here are some tips (assuming you are using Windows):

 

More info

Here’s some more information about the Dvorak layout:

Monday, December 19, 2011

What video games taught me

When I was 4 years old my dad brought home a ColecoVision video game console and introduced our family to a whole new world of entertainment.  Games like Time Pilot, Mouse Trap and Pitfall helped create a warm and fuzzy bond between my dad and I (my Mom really loved Time Pilot too).

A few years later he purchased a family computer with a 286 Intel processor and 4 megs of RAM, loaded with MS-DOS and Windows 3.1.  It was this computer that I would upgrade over the years and enjoy a ton of computer games.  Some of my favorites back then were Ultimate Domain, Commander Keen, XCOM, Wolfenstein 3D, Doom, Diablo, Command and Conquer and Warcraft II.

Throughout those same years I would receive Nintendo, Super Nintendo and Nintendo 64 as Christmas gifts from my parents.  Anyone who has owned Nintendo knows how many awesome games were available with epic stories, silly characters and really fun gameplay.  Games like Secret of Mana, Chrono Trigger, Zelda (I, II and III), Metroid (I and II), and of course Mario Brothers (I, II, III, IV and V).  My best friend Brian owned Sega Genesis and Sega CD which gave me access to even more good stuff.  Seriously though, there are just too many great games.  I haven’t even scratched the surface, and haven’t listed anything relatively new.

Video games are now a hobby of mine and I own 18 game consoles/hand-helds and around 200 games (including computer games).  Needless to say, I’ve played tons of different video games in my life.  Probably somewhere over 500 titles in 20 years.  I’m not even sure I could list them all.  Unless you’re a gamer like me, you might find this horribly unproductive.

Oh but you would be so wrong!  I’ve actually learned so much from playing video games, including real-world skills and knowledge that have helped me even today.  It has been shown that video games offer a great deal of benefits as well, such as good hand-eye coordination, improved motor skills, resistance to distraction, and increased peripheral vision among and other things.

As with any type of learning, it is what you make of it.  There are no guarantees here that kids will learn anything useful while playing video games (especially today as games become more violent and less challenging).



Patience

It’s no surprise that video games test one’s patience.  It doesn’t really matter if it’s a console game, computer game or even a game on your not-so-smart phone.

Games today spoil you a bit too.  Especially in the mobile world, most games have an active save state allowing you to return right where you left off when you last put it down.  Games like Angry Birds set a new standard for level saving, such that when you beat a level you have confidence that it’s beaten.  This just wasn’t always true when I was a kid. 

I remember spending several hours playing Contra, Super Smash TV or  Battletoads, only to lose all my lives so far in and have to START ALL OVER!  Sometimes it would simply be time for homework, or we’d have to leave the house for a while.  I could pause the game I suppose and turn off the TV (something my cousins did often).

This taught me patience and I was having fun in the process.  I had to spend time earning the right to play later levels in the game to achieve that goal of victory!  Sure some games today have this level of challenge, but it’s rare.



Problem solving

While all games have the potential to force you to think of problems in new ways and come up with strategies to solve them, puzzle games do this very well. 

My dad and I love Tetris, and we both have it on our iPhones now (although fun is emphasized more with the upgraded touch abilities).

Zelda is another great example.  While Zelda games place emphasis on their story and adventure, deep down they are puzzle games, but in a very different way.  Most of the enemies in Zelda require some particular item or special way to beat them.  Many rooms require a specific block to be pushed or pulled on.  Sometimes the puzzles themselves aren’t exactly obvious. 

 

In the real-world, it’s doubtful that you’ll ever be thinking to yourself “I’ll just move those boxes I have in the backyard around, and the door to my next new job will be open!  Thanks Zelda!”, but you might find yourself looking at the world with a new perspective.

The main thing about problem solving in games is that it just forces you to think about things differently.



Money management, interest and taxes

Aside from school lunch and saving for toys, why would a child even need to know how to manage money at an early age?  They probably wouldn’t, unless they’re playing video games.

My absolute favorite genre of games is simulation.  Games like SimCity, Utopia and Theme Hospital all involved building an empire.

They taught me about spending and saving, credit through loans and interest when paying them back.  I had a limited amount of starting money, and needed to earn more through a successful empire.

 

Today I’m not exactly fit to fill the shoes of a mayor or run a company as CEO (I’m not sure I’d want to), but I did learn all about money at an early age.



Multitasking

I think the most intellectually demanding genres of games is real-time strategy(RTS).  They really require constant focus because you are always doing something.  At times you feel like an octopus with 100 tasks to get done, but you’re having a ridiculous amount of fun while doing them.

My work requires that I use a computer all day, and I truly believe that playing these games increases my overall productivity.  I can use software more quickly because I utilize hotkeys.  I find myself interacting with buttons and menus more accurately.

For me it started with Command and Conquer, but Blizzard’s RTS games Warcraft and Starcraft are my favorites.



Typing skills

Most modern games are social in some way, either via chat or message boards.  Some games are fast paced enough that if you even want to chat while you play, you should probably have some decent typing skills.  This actually might encourage some kids to learn shorthand, but not me.  Online games was a great way for me to practice “correct” home row typing.

To this day, my typing speed is still well above average I’m sure (somewhere around 80 wpm and closer too 100 on good days).



Spatial awareness, organization and efficiency

The other day I was reorganizing our bathroom closet and realized that I was treating it like an inventory in a game.  I placed items in similar categories together and placed the most common use items within easy reach.  I also put smaller items in front so you could still easily see items in the back.  While this sounds like common sense, this is something that comes up in games quite a bit, albeit in different ways.

In Diablo specifically, your inventory is comprised of several slots.  Depending on the size of the item, you often have to rearrange these items to fit.

 

Games like World of Warcraft and Minecraft have an action bar and you find yourself placing common use items within easy reach of your left hand (the action bars are accessed via the 1-0 keys typically on your keyboard).



Interface design

There isn't anything more frustrating than trying to play a game that has horrid UI (this is also true of websites and apps).  But what is bad UI?

The answer is subjective, but most people will probably agree with at least one of these:

  • Clumped together controls
  • Small or blurry text
  • Complicated HUDs (heads-up displays)
  • Complicated menus (how many actions does it take to use an ability, or save your game, etc.)
  • Improperly categorized controls (what is this button doing here??)

Spending time playing games really helps in the design process.  I find myself thinking of what has worked well in the past, based on my experiences at the time.


 

World history and culture

There are actually quite a few games that let you play as (or play with) a particular ruler or leader of people in history.  Civilization and Empire Earth are my two favorites, though there are others like Caesar and CivCity: Rome.

What makes Civilization so great is it’s in-game “Civilopedia” that had a great deal of historical information.  Every time you gained access to a new military unit or built a building, met a new civilization or made a new scientific discovery, the Civilopedia would popup.

I still love playing Civilization not only because it’s fun, but it’s super interesting.  The replay value is high for me because I have the chance to beat the game using another one of the many nationalities or by initiating a different form of government the second time around.  It also makes for a fun time recreating history (what would it be like if George Washington was a communist?).



Science and Terminology

While most games are made to be fun, often they have ties back to real-life.  Just as with world history and culture, game designers and writers use terms from our real-world in their stories, object and character names and game concepts and mechanics.

More often than not these particular games are on the educational side, but not always.  The game developer Maxis released surprisingly fun simulation games that were really educational. 

SimEarth was full of information you’d learn when taking an earth science course.  SimEarth exposes you to a wide variety of animals and their growth, our Earth’s geosphere, weather systems and other good stuff (many topics of which I hadn’t even learned in school yet).

 

When I took animal diversity in college, several students in our class were confused about a bee’s caste system and how it was different from other species.  I remember thinking to myself: “You should have played SimAnt man…”.  SimAnt introduced castes by allowing you to change the percentage of ant workers, breeders and warriors that were hatched from your queen’s eggs.


 

Scientific research trees are a popular mechanic in games.  It enables the developer to slowly introduce new abilities to the player, while at the same time giving them a sense of accomplishment and reward.  Even though games like Civilization and Ultimate Domain weren’t strictly educational, they had really extensive scientific research trees.  I was probably in 5th grade when I played these games, which taught me about metallurgy, combustion and a bit of chemistry.



How to let go of possessions

Letting go… of possessions… huh?

Think about this one.  How many possessions do you own?  Do you pay for storage for your stuff?  How hard is it for you to de-clutter?  It’s written somewhere, in Luke I think… “Beware!  Guard against every kind of greed.  Life is not measured by how much you own.”  Okay okay, I’m not talking about greed, but just STUFF.  Stuff everywhere

During the Christmas season I was off work for a nice 12 days and did a lot of cleaning and de-cluttering around the house.  It can be really hard to let go of items that you think you might need, but believe it or not, games have helped make this process easier for me.

Take World of Warcraft for example.  This is a game of epic adventuring.  You explore, quest, fight and loot and loot and then loot some more.  You need some place to put these things yes? 

Similar to previously mentioned Diablo, in WoW you have a main backpack and the option of purchasing 4 additional bags (with varying number of ‘slots’ depending on the quality).  Unlike Diablo, Each slot corresponds to a storage place for any item in the game.  You even have a bank with slots!

Over time, you use up your empty slots.  It just happens, and it happens easily.  Sometimes you have to make some tough decisions on what to get rid of.  Some items take hours to find, some are useless but are nostalgic.  In any case, you eventually have to give up something (or come to terms with never looting anything again).

This is similar to life, and working with inventory in games really does help you come to terms with the fact that stuff accumulates, and you have to eventually purge.



Keep learning, keep playing games

These are really only a few examples.  Having played so many games over the years and with so many favorites, it’s a real challenge to come up with a short list.

I still play RTS games to help improve my multi-tasking and problem solving, platformers and first-person shooters to keep my reaction and hand-eye coordination sharp, and Minecraft to… well help me relax after a long day of work.

While there seems to be a movement of games that hold your hand the entire time, I still find myself learning from games.

Do you agree?  Did I miss anything?   If anything, leave a comment with a list of your favorite all time games.

Saturday, December 17, 2011

My ambitious book list for 2012

I love to learn, and learning usually involves a lot of reading.  When I was younger I hated reading books.  They were boring and I felt like I was going cross-eyed staring at the black and white.  Then again, these were books that I felt forced to read (in school, as gifts, etc.).  I often didn’t care about the subject or didn’t find it interesting (actually most of the time I daydreamed about how I could turn the topic into a fun game).

Active developer communities such as channel 9, stack exchange and game dev really changed things for me.  Plus with digital books now, my material is even more accessible.  I find myself consuming more and more information from my iPhone, so having the kindle reader app is huge for me.  Reading and learning is fun again!

I’m already making progress, as you’ll soon find out.

Reading list


C++ Programming with Text-Based Games by Michael Dawson


TextBased Games

I’m actually almost finished with this book (a little over half-way).  It’s super introductory; most of the assignments and challenges I could already do in C#.

But it’s a fun book so far and helps when learning C++.

What I hope to learn:

  • Tricks in memory management
  • Class design
  • Not so much learn, but give inspiration for new projects

Sams Teach Yourself C++ in 21 Days by Jesse Liberty and Bradley L. Jones


21 Days

I actually have a PDF version of this book.  I’m almost done and it’s been extremely useful in catching up on C++.

I’ve found some discrepancies and bad practices in the section on pointers as well as memory management with overloaded operators (stray pointer bugs), but I think that’s to be expected in a crash course book.

What I hope to learn:

  • Templates in C++
  • More on memory management (or what not to do…)
  • Some practice with multiple inheritance and polymorphism

Programming: Principles and Practice Using C++ by Bjarne Stroustrup


programming_front

The C++ book written by the creator himself.

I only list this book because I’m almost finished.  This book really teaches you programming, and uses C++ to do it.  So for me, it hasn’t been all that informative (other than understanding the inner thought processes of Bjarne as he writes a calculator from scratch).

Not super useful for me at this point, but I’m almost done.

What I hope to learn:

  • I have already learned the basics of user interface graphics
  • I’ve learned a particular implementation of building a calculator from scratch
  • I still hope to learn how Bjarne intended multiple inheritance to be used

C++ Primer Plus by Stephen Prata


PrimerPlus

This book is huge and much more comprehensive than the other two C++ books. 

I’ll probably end up skimming the text or trying the exercises first and only going back if I don’t understand something.

What I hope to learn:

  • A more in-depth coverage of C++ language features
  • Good patterns and practices (wishful thinking here I think)
  • Tips and tricks

The Art of Computer Programming Volume 1 of 4 by Donald E. Knuth


ArtofProg

I’ve been told this is an excellent series on algorithms.  I cracked open the first volume already and it looks to be filled with math equations, solutions and example code. 

My curiosity is peeked, however I’m going to need to stay motivated for this one.
Winking smile

What I hope to learn:

  • Introduction to algorithms
  • Solutions to common data problems
  • Sharpen my math skills

Advanced 2D Game Development by Jonathan S. Harbour


2dGame

I’m really excited to read this.  I’ve already read through chapter 2, and it seems to teach a really great implementation of a 2d game engine that is easily portable to other platforms.

Not only that, but his method also allows migration to different IDEs.  Pretty neat.

One of the bummers for me is that it focuses on using 3d model based sprites instead of painted spritesheets (which I understand makes creating sprite animation easier), so I’m sure I’ll get over it.

What I hope to learn:

  • How to build a 2d game engine (one possible implementation)
  • Graphics using DirectX
  • Other game related topics such as input collision and sound

Real-Time Rendering by Tomas Akenine-Moller, Eric Haines and Naty Hoffman


RealTime

As I understand it, this is the book for current day 3d rendering.  It gives an overview of the rendering pipeline, helps get your math up to speed and thoroughly covers advanced concepts.

I think the 4th edition is going to be available soon if not already, but I own the 3rd so I’ll start there.

What I hope to learn:

  • The graphics pipeline
  • Brush up on Trigonometry and Linear Algebra
  • Everything 3d graphics

Steve Jobs by Walter Isaacson


jobscover

Over the past few years I have been largely impressed with Apple.  Their ability to innovate and design has completely influenced the decisions I make as I work.  I even bought a MacBook to accompany my iPhone and I love it.

While I understand that Steve probably did not have his hand in every innovation and decision, I think this will be a great read.

What I hope to learn:

  • Ways to better communicate
  • An inside look at Apple's development process
  • New strategies when making important decisions

Full Steam Ahead

So there you have it!  My reading commitment for 2012.  It might not seem like a lot for a year of studying, but I intend to do many of the exercises (if not all of them).  Game programming books always get me on a project tangent too.  I might lose a ton of sleep this year (and hopefully make a cool iPhone game).

I plan on writing reviews for these books as well, so be on the look out for those.

Do you have any reading plans for 2012?  Leave a list in the comments!