Getting Started with Cal-HeatMap and the AngularJS Cal-HeatMap directive

Working on my AngularJS app that visualizes historical playback of received Amateur Radio signals (www.spotviz.info) I wanted to have a ‘heatmap’ type display that shows density of the received signals per day (or hour). Searching around, the most common library to display a heatmap seems to be Cal-HeatMap. And since this is an AngularJS based app, it makes sense to use a directive to display the heatmap in my view where needed – Angular Cal-HeatMap seemed to be what I needed.

Starting with anything new it’s far easier to build something small that works first, and then include it into something larger/more complicated. Here’s my standalone test app using Angular Cal-HeatMap with Cal-HeatMap. It has hardcoded data, just to show the heatmap rendering.

The first issue I ran into, was that my standalone app was rendering fine, but copying the same directive usage into my SpotViz app, I could not get the directive to recognize my config options, or render any data.

As with everything I’ve found so far with AngularJS, sometimes stuff that should be easy turns out to be hard, but in most cases only because I don’t understand what’s going on, or how I assume it to be working is completely wrong 🙂 At least I’m not the only one who finds this about AngularJS, to quote Nathan LeClair from one of his posts:

"As I’ve gotten a little into AngularJS I’ve been surprised
by how often my assumptions about how things will work 
have turned out to be wrong".

Lesson #1:

I don’t know if this is an issue specifically with how Angular Cal-HeatMap directive is implemented or not, but the way I was trying to use it, it appears it initializes before the point where I retrieve and setup the data for display. Once I retrieve the data, setting it in the $scope variable that the directive is using seems to have no effect; it doesn’t see the data and display as I’d expect.

My work around for this was to use ng-if to only initialize the directive when I toggle a flag after the data is ready. Previously I was using ng-show to toggle the display of the directive, but that apparently causes the directive to initialize even though it’s not visible. I don’t know if there’s something else I can do to re-initialize the directive, but this works for now.

Here’s what I ended up with:

[code]<cal-heatmap ng-if="search.showDataDensity"
config="search.heatmap.config"></cal-heatmap>[/code]

For context, here’s an example of what the heatmap looks like with some example received signal data from 2014:

heatmap_example

 

 

Lesson #2:

Cal-HeatMap uses 5 CSS styles by default for coloring according to how many data points are for each date, from .q1 through .q5. For data with a count > that whatever the top range is set to, apparently css class .q6 gets applied. Without any other change however, if you haven’t defined your own .q6, these dates will be displayed as if there’s no data on those dates. This wasn’t obvious to me, but is discussed in this post on SO. Add a custom CSS class for .q6 with a slightly darker color than .q5, problem solved.

Summary

I’ve some polishing and cleanup to do, but my heatmap display is almost ready to go!

Re-flashing a WRT54GL running HSMM Ham Mesh firmware

I recently flashed the firmware on a spare Linksys WRT54GL to take a look at ham radio mesh networking on 2.4GHz re-using WiFi routers like the WRT54. I wanted to flash the router back to regular WiFi router firmware, and turned out this was more difficult than it should have been. For future reference, here’s a few notes.

The HSMM-Mesh firmware (3.0) has an admin page to either upload a new firmware to flash, or download an existing firmware from a list of available firmware versions. Neither of these worked for me – uploading a firmware gave an error that it wasn’t recognized, and then the router was connected to my network for internet access, it didn’t give any firmware options other than later versions of the HSMM firmware.

Elsewhere there are instructions for using the tftp approach to ftp a new firmware to the router as it boots. This seemed like an easy option, but I could not get it to work despite trying multiple times.

Instructions for OpenWrt here give steps for ensuring the tftp feature is enabled… this apparently is key, as before following the steps I could not get it to work, but after setting this options it worked first time.

ssh to the router using:

ssh root@10.72.105.9 -p 2222

this is the ip that my HSMM had on starting up, and sshd on the HSMM firmware is enabled by default and listening on 2222.

From thr OpenWrt page above, enter these commands to setup tftp:

nvram set boot_wait=on
nvram set boot_time=10
nvram set wait_time=10 #important for some models
nvram commit && reboot

Before the reboot step, set your ip address on laptop connected to router as:

192.168.1.2
netmask 255.255.255.0
router/gateway 192.168.1.1
Reboot router, start following the tftp procedure to upload the firmware:

If you are seeing WRQ messages with tftp trace turned on, the router is responding, but not yet accepting the tftp upload. You need to wait until you see messages like this to indicate the transfer is occurring:

sent DATA <block=6562, 512 bytes>
received ACK <block=6562>

These will repeat several times a second until the upload is complete, then they will stop, tftp will disconnect, and you’ll see the router power light flashing, indicating it is rebooting. Wait a couple of minutes until the lights are back to their normal state, and then try hitting the admin page for the new flashed firmware at 192.168.1.1

AngularJS and Google Maps – dynamic marker updates

I have a need to dynamically create and display markers on a Google Map. Statically declaring a single or an array of markers seems pretty easy, but updating an array of markers so they are displayed and removed over time seems more tricky using the available AngularJS libraries for Google Maps.

The two libraries I have looked at are:

Both offer AngularJS directives to insert a Google Maps into an existing page. Let’s take a quick look at each approach.

Angular Google Maps

With Angular Google Maps, use the provided directives to insert the map and an array of markers:

[code]
<ui-gmap-google-map center=’map.center’ zoom=’map.zoom’>
<ui-gmap-markers models="markers" coords="’self’" modelsbyref="false"/>
</ui-gmap-google-map>
[/code]

In my Controller I’ve added a map object to $scope with values for center and zoom:

[code]
$scope.map = {center: {latitude: 37.7699298, longitude: -122.4469157}, zoom: 12};
[/code]

… and to add the initial array of markers (random markers in SF):

[code]
var marker1 = {id: 1, latitude: 37.7699298, longitude: -122.40};
var marker2 = {id: 2, latitude: 37.7699298, longitude: -122.45};
var marker3 = {id: 3, latitude: 37.7699298, longitude: -122.46};
$scope.markers = [];
$scope.markers[0] = marker1;
$scope.markers[1] = marker2;
$scope.markers[2] = marker3;
[/code]

Since the markers array in $scope is reference by the ui-gmap-markers element, setting the markers array to [] deletes the markers from the map, and adding them back re-adds them back to the map. The property ‘coords’ is the name of the property on the object passed to models that contains the objects with the latitude/longitude properties for each marker. modelsByRef=”false” seems to add support for watching changes to the model.

ngMap

The ngMap approach is very similar. To add the map to a page with a repeating list of markers:

[code]
<map style="height:100%" center="37.7699298, -122.4469157" zoom="11">
<marker ng-repeat="pos in positions" position="{{pos.lat}}, {{pos.lng}}"></marker>
</map>
[/code]

To create the markers, create an array of markers with lat and lng properties, similarly to Angular Google Maps:

[code]
var marker1 = {lat: 37.769, lng: -122.44};
$scope.positions = [];
$scope.positions[0] = marker1;
//etc
[/code]

Summary

Since my app needs to dynamically add and remove markers for display to the Google Map, this was my primary requirement for selecting one of the libraries. I struggled to get this working initially with Angular Google Maps, but seemed to work straight out of the box with ngMap. Most of my struggles though may have been related to my misunderstanding of how $scope works in AngularJS (which I’m still learning), so maybe at some point I should go back and re-evaluate both of these again once I have a better understanding of AngularJS.

I put together a sample app that uses both of the libraries, which you can find on GitHub here: https://github.com/kevinhooke/AngularJSGoogleMapsExamples

Also, my final usage for ngMap you can see in action in my app, SpotViz, which is available here: http://www.spotviz.info/ . It allow Amateur Radio operators to playback an animated display of received station locations over time from log files from a digital mode application called WSJT-X.

 

Choosing an Issue Tracker for an Online Service

I’ve been working on an application that I’m getting close to publicly launching, and while the site is mostly functional with most of the development done (I’ve been working on it in my ‘spare time’ for almost a year), there’s some non-development tasks I need to complete before launching, including:

  • adding Google AdSense and Analytics
  • completing online documentation
  • setting up an online issue tracker

The options for an issue tracker has taken me by surprise as there are so many options, ranging from free to varying monthly fee options. I’m somewhat familiar with some of the older free development project focused options, like Bugzilla, Trac, Redmine, and commercial options like Atlassian’s Jira. Part of my app is open source on GitHub and so to use the GitHub issue tracker for that part is an easy choice. I’d also like to make sure whichever issue tracker I chose is easy to use from the point of view of my end users, the majority of which are unlikely to have existing GitHub accounts, or accounts on other online tracker sites, and I want to make sure it’s as easy as possible for them to log issues and enhancement requests.

(This article here has a good list of a number of issue trackers.)

Ranging from simplest to use, Trello is a stand-out from the crowd. Although it’s not a dedicated issue tracker, the approach of managing lists of items and moving items (cards) from one list (e.g. open items) to another (e.g.closed items) is trivial.

Categorized in interesting-but-with-high-technical-requirements is YouTrack from JetBrains, and free for upto 10 users … but requiring 1GB heap to run, this would cost me some monthly runtime costs for  medium gear on OpenShift, so I’m not sure  if this is worth the investment at this point.

Next up in the looks-interesting category is Asana – I’m not familiar with this service, it looks like it offers much more than I would need, but could be worth investigating.

I’ve some decisions to make here, and right now I’m thinking either using GitHub’s issue tracker or Trello. What would you recommend – leave me a comment!