Repository: yagoferrer/map-tools (js)

Issue:
Add API map.filterFeature({NAME: 'Colorado'})

Pull request description:
Adds filterFeature() API closes #166

Patch:
diff --git a/examples/code.snippet/topojson.snippet.html b/examples/code.snippet/topojson.snippet.html
index 758ffe1..2679924 100644
--- a/examples/code.snippet/topojson.snippet.html
+++ b/examples/code.snippet/topojson.snippet.html
@@ -11,9 +11,8 @@
   },
   filters: ['NAME']
   }]);
-  var dimension = map.json.filter.NAME;
-	var colorado = dimension.filter('Colorado').top(1)[0];
-	var nevada = dimension.filter('Nevada').top(1)[0];
+  var colorado = map.filterFeature({NAME:'Colorado'}, {limit: 1});
+  var nevada = map.filterFeature({NAME:'Nevada'}, {limit: 1});
 	var options = {
 		style:{
 			fillOpacity: 0.4,
@@ -23,7 +22,7 @@
 	map.updateFeature([colorado, nevada], options);
 
   // Choropleth based on Census
-  map.updateFeature([]), {style: function() {
+  map.updateFeature(...), {style: function() {
     // Choropleth function based on the CENSUSAREA data
     var value = (this.data.CENSUSAREA/570640.95);
     var alpha = 5;
diff --git a/examples/topojson.html b/examples/topojson.html
index 24ce14a..b56bc5f 100644
--- a/examples/topojson.html
+++ b/examples/topojson.html
@@ -41,9 +41,9 @@
 		  position: 'right center',
 		  events: {
 			  '.single click': function (e) {
-				  var feature1 = map.json.filter.NAME.filter('Colorado').top(1)[0];
-				  var feature2 = map.json.filter.NAME.filter('Nevada').top(1)[0];
-				  map.updateFeature([feature1,feature2], {style: {fillOpacity: 0.4, fillColor:'black', strokeColor: 'black'}});
+				  var colorado = map.filterFeature({NAME:'Colorado'}, {limit: 1});
+				  var nevada = map.filterFeature({NAME:'Nevada'}, {limit: 1});
+				  map.updateFeature([colorado, nevada], {style: {fillOpacity: 0.4, fillColor:'black', strokeColor: 'black'}});
 				  e.preventDefault();
 			  },
 
diff --git a/lib/map-tools/addFilter.js b/lib/map-tools/addFilter.js
index a743a1c..6c7e7bc 100644
--- a/lib/map-tools/addFilter.js
+++ b/lib/map-tools/addFilter.js
@@ -17,14 +17,12 @@ module.exports = function(global, that) {
     }
 
     for (dimension in filters) {
-
       item = filters[dimension];
       if (typeof item === 'string') {
         global.GMP.maps[that.id][type].filter[item] = global.GMP.maps[that.id][type].crossfilter.dimension(defaultDimension(item));
       } else {
         global.GMP.maps[that.id][type].filter[Object.keys(item)[0]] = global.GMP.maps[that.id][type].crossfilter.dimension(item[Object.keys(item)[0]]);
       }
-
     }
   }
 
diff --git a/lib/map-tools/filterFeature.js b/lib/map-tools/filterFeature.js
new file mode 100644
index 0000000..5f81f9a
--- /dev/null
+++ b/lib/map-tools/filterFeature.js
@@ -0,0 +1,38 @@
+'use strict';
+module.exports = function(global, that) {
+
+
+  var orderLookup = {
+    ASC: 'top',
+    DESC: 'bottom'
+  };
+
+  function filterFeature(args, options) {
+
+    var order, limit;
+    var dimension = Object.keys(args)[0];
+    var query = args[dimension];
+
+    if (that.json.filter[dimension]) {
+
+      order = (options && options.order && orderLookup[options.order]) ?
+        orderLookup[options.order]
+        : orderLookup[Object.keys(orderLookup)[0]];
+
+      limit = (options && options.limit) ? options.limit : Infinity;
+
+      var result = that.json.filter[dimension].filter(query)[order](limit);
+
+      if (limit == 1) {
+        return result[0];
+      }
+
+      return result;
+    }
+
+    return false;
+
+  }
+
+  return filterFeature;
+}
diff --git a/lib/map-tools/index.js b/lib/map-tools/index.js
index da4573b..93fb544 100644
--- a/lib/map-tools/index.js
+++ b/lib/map-tools/index.js
@@ -16,6 +16,7 @@ module.exports = function (global) {
     this.updateFeature = require('map-tools/updateFeature')(global, that);
     this.addPanel = require('map-tools/addPanel')(global, that);
     this.updateMarker = require('map-tools/updateMarker')(global, that);
+    this.filterFeature = require('map-tools/filterFeature')(global, that);
     this.addGroup = require('map-tools/groups')(global, that).addGroup;
     this.updateGroup = require('map-tools/groups')(global, that).updateGroup;
     this.updateMap = require('map-tools/updateMap')(global, that);


Test patch:
diff --git a/test/bootstrap.js b/test/bootstrap.js
index 9c1dcc8..32e68bc 100644
--- a/test/bootstrap.js
+++ b/test/bootstrap.js
@@ -18,3 +18,5 @@ global.GMP = window.GMP;
 // To test independent modules.
 global.window = window;
 global.google = window.google;
+
+global.crossfilter = require('crossfilter');
diff --git a/test/unit/filterFeature.Spec.js b/test/unit/filterFeature.Spec.js
new file mode 100644
index 0000000..658ac71
--- /dev/null
+++ b/test/unit/filterFeature.Spec.js
@@ -0,0 +1,31 @@
+describe('Given the filterFeature Module', function () {
+
+  var that, filterFeature, data;
+
+  beforeEach(function () {
+    data = [{NAME: 'Gert'}, {NAME: 'Peter', age: 23}, {NAME: 'Peter', age: 35}, {NAME: 'Max'}];
+
+    var cf = crossfilter(data);
+
+    that = {
+      json: {
+        filter: {
+          NAME: cf.dimension(function(d) {return d.NAME;})
+        }
+      }
+    };
+
+    filterFeature = require('map-tools/filterFeature')({}, that);
+  });
+
+  it('should filter exact values', function () {
+    var result = filterFeature({NAME: 'Peter'});
+    expect(result).to.eql([data[2], data[1]]);
+  });
+
+  it('should limit the results when using limit', function () {
+    var result = filterFeature({NAME: 'Peter'}, {limit: 1});
+    expect(result).to.eql(data[2]);
+  });
+
+});