Let’s Angularize this map..

In order to get the map to react to the data, the sections of the map need to be integrated into Angular somehow. We can do this with a directive for each region:

We could reference the directive in the SVG like so:

<path region ng-click=”regionClick()” d=”m 380.03242,320.96457 4.90324,-86.32496 -113.38856,-12.64396 -12.21382,87.93916 120.69914,11.02976 z” id=”CO” class=”state” />

This sucks though for 2 reasons: Firstly it adds non standard mark-up to our SVG file and secondly and even more importantly it’s bloody tedious!

Instead, let’s inject the directive into the DOM with Angular. $compile to the rescue!

Edit our directives thus:

When you click on a region you should be alerted to its id. We’re getting somewhere now! Let’s look at what’s going on here in a bit more detail. First the “svgMap” directive:

var regions = element[0].querySelectorAll(‘.state’);

Create an array containing all elements of class “state” using querySelectorAll.

angular.forEach(regions, function (region, key) {

//...

})

Loop through the regions array.

var regionElement = angular.element(region);

Wrap the region DOM element as an Angular jqLite element.

regionElement.attr(“region”, “”);

Add the “region” attribute to the DOM element so it can be tied to the directive of the same name.

$compile(regionElement)(scope);

Compile the element so Angular can do it’s magic.

On to the region directive:

element.attr(“ng-click”, “regionClick()”);

Add the ng-click attribute to the region element in order to run the regionClick function, you guessed it, when we click the region.

element.removeAttr(“region”);

In order for the ng-click attribute to take effect we’ll need to compile the element again. However, if we do this, Angular will read the region attribrite, reattach the directive again, and consequently the universe will explode.

Luckily interstellar catastrophe can be avoided if we remove the region attribute from the element. Phew!

$compile(element)(scope);

More Angular magic, you know the drill by now.

Our map regions are now augmented with the mighty power of Angular. Onward!

Mapping in the data

If we want our map regions to tie up the dummyData object, we’ll need to give each of the regions access to the data via its scope:

When you click on a region it will hopefully alert to you the corresponding value for that region. Hardly a huge leap forward I know but don’t worry we’ll get to the pretty stuff in a minute.

A note: I am not going to go into great detail about the sometimes confusing world of Angular directive scopes. However, if you’re having trouble I shall point you in the direction of this great blog post on the subject: http://www.undefinednull.com/2014/02/11/mastering-the-scope-of-a-directive-in-angularjs/

Here’s the new bits:

regionElement.attr(“dummy-data”, “dummyData”);

Set the dummyData attribute on the region element so we can tie it into the region directive scope.

scope: {

dummyData: “=”

},

Create a two-way binding with the dummyData object.

scope.regionClick = function () {

alert(scope.dummyData[scope.elementId].value);

};

Use the id of the SVG element to access the corresponding data value.