Google Charts-like Provincial Data Map For Canada

Map of Canada chart with province value colour coding.

This is PHP class I developed for work when I needed a Canada-specific map chart in some reporting tools I was creating. Obviously Google’s Map Charts API would’ve been my first choice, but it didn’t support Canada as it’s zoom level for reporting province-based data sets.

This is where I sat down, thought about a quick and dirty way to create this chart and went to work. I was able to create a chart as show on the right, with full control of output dimensions and colours.

Before I jump right into the full code, I want give a brief explanation of some of the techniques I used to accomplish this task.

Map of Canada chart with each province uniquely coloured

The idea I had was to have a pre-coloured map of Canada such that each province has it’s own very distinct colour (as shown on left). From this starting point, I could replace each unique province colour with a degree of color based on a primary foreground color (e.g. red, #FF0000, as in the example above). To do this properly, I set up an array based on province short-forms (for data entry) and their unique colour on the base map:

$provs = array(
  "AB" => "00DF6A",
  "BC" => "8AC707",
  "MB" => "3D5DFE",
  "NB" => "FF6BAA",
  "NL" => "C0FF00",
  "NT" => "FF8029",
  "NS" => "FFE26B",
  "NU" => "FFE328",
  "ON" => "D43CFF",
  "PE" => "6BFF7C",
  "QC" => "FF3DC0",
  "SK" => "01D7DF",
  "YT" => "FE293D"
);

and I was able to use an excellent function that I found which can take a HTML/hex color code and make it lighter by a percentage factor:

function hexLighter($hex,$factor = 30) {
  $new_hex = '';

  $base['R'] = hexdec($hex{0}.$hex{1});
  $base['G'] = hexdec($hex{2}.$hex{3});
  $base['B'] = hexdec($hex{4}.$hex{5});

  foreach ($base as $k => $v)
      {
      $amount = 255 - $v;
      $amount = $amount / 100;
      $amount = round($amount * $factor);
      $new_decimal = $v + $amount;

      $new_hex_component = dechex($new_decimal);
      if(strlen($new_hex_component) < 2)
          { $new_hex_component = "0".$new_hex_component; }
      $new_hex .= $new_hex_component;
      }

  return $new_hex;
}

From here, replacing one colour with another is quite a simple task:

function colorReplace($image, $oldcolor, $newcolor) {
  // find old color
  $oldcolor = $this->html2rgb($oldcolor);
  $old = imagecolorexact($image, $oldcolor['r'], $oldcolor['g'], $oldcolor['b']);
  // replace with new color
  $newcolor = $this->html2rgb($newcolor);
  imagecolorset($image, $old, $newcolor['r'], $newcolor['g'], $newcolor['b']);
}

…the rest is simply basic PHP image manipulation.

View/download the complete Canada Chart PHP class.
Click here to download the full-size coloured map of Canada required by the class.

Now since I was already using Google’s Charts API, I wanted to make my own URL API to be relatively similar in fashion. So you could use this class like so, click to see result:

canada.chart.php?chld=ON,QC,AB,NL,BC,NB,MB,PE,NS,SK&chd=1000,450,132,56,6,775,320,950,100,645&chf=ff0000&w=450&h=450

This should make using this class in a project in which you’re already using Google Charts API fairly consistent.

I did add basic support for data labeling, but this wasn’t something I specifically needed so I didn’t pretty it up too much, but you can see an example here:

canada.chart.php?chld=ON,QC,AB,NL,BC,NB,MB,PE,NS,SK&chd=1000,450,132,56,6,775,320,950,100,645&chf=ff0000&w=450&h=450&clb=1

This requires a GDF conversion of the Arial font for use with PHP’s GD library. Feel free to never use this functionality, take it out completely, or make it better.

If you successfully use this code, take it apart, or make it better — please let me know! I love to be constantly improving reusable classes like this, and it’s great to share good code with everyone.

Addendum

I’ve been so kind as to release this code under the Apache License v2.0, which means you’re more than welcome to use, distribute, and modify this code as long as you follow the terms of the license (which includes keeping the license with the modified source code).

If this code has been useful to you, and if you can find it in your heart, please donate a dollar or two. If you can buy me a coffee I’d be eternally√ā¬†grateful. Below is a donate button for my PayPal account.

 










5 thoughts on “Google Charts-like Provincial Data Map For Canada

  1. Very nice, I’m looking to use this for a geocaching statistics program I’m developing. I’m planning on using it for province regional districts and counties, and perhaps other subdivisions in other countries. Looks fairly easy to adapt your code for this use, hopefully you don’t mind!

    • Andrew

      I definitely don’t mind at all, feel free to use it however you like — just pass along any improvements you make so others can use it too!

  2. I’ve released my modifications here. http://code.google.com/p/geocachepython/downloads/list
    I’ve included a map of the regional districts of BC, and you can now specify a map as a parameter. I’m planning to add more in time, though probably just Ontario for the near future.

    • Andrew

      This is fantastic, great job. It’s nice to know this code is easy enough to understand to port for use with essentially any map. I’d like to do something with Ontario, but find a way to nicely integrate postal codes and what region of Ontario they correspond to. My starting point would probably be something along these lines I’m guessing: http://en.wikipedia.org/wiki/List_of_L_postal_codes_of_Canada

  3. Wolvendeer

    Sorry for the off topic comment, however I’ve been playing with the idea of getting in contact with you about your old Dreamtome project to see if you had any interest still in keeping it up and making new developments or, if not, if you would be willing to either release the code or take on someone to develop it and push it, perhaps bringing it the life it deserves.

    Again, sorry for the off topic comment, but I couldn’t find any email address for you, and I didn’t really feel like pulling records for your domain names to try to get it. In any case, I hope to hear back from you on it. My email is linked in my alias.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>