diff --git a/README.md b/README.md
index 05692ff..a76923f 100644
--- a/README.md
+++ b/README.md
@@ -121,10 +121,10 @@ Returns an array of all data in the quadtree.
Returns the total number of data in the quadtree.
-# quadtree.find(x, y[, radius])
+# quadtree.find(x, y[, radius][, filter])
[<>](https://github.com/d3/d3-quadtree/blob/master/src/find.js "Source")
-Returns the datum closest to the position ⟨*x*,*y*⟩ with the given search *radius*. If *radius* is not specified, it defaults to infinity. If there is no datum within the search area, returns undefined.
+Returns the datum closest to the position ⟨*x*,*y*⟩ with the given search *radius* that satisfies the *filter*. If *radius* is not specified, it defaults to infinity. If *filter* is not specified, all data are considered. If there is no acceptable datum within the search area, returns undefined.
# quadtree.visit(callback)
[<>](https://github.com/d3/d3-quadtree/blob/master/src/visit.js "Source")
diff --git a/src/find.js b/src/find.js
index e9db6c4..94c412e 100644
--- a/src/find.js
+++ b/src/find.js
@@ -1,6 +1,6 @@
import Quad from "./quad.js";
-export default function(x, y, radius) {
+export default function(x, y, radius, filter) {
var data,
x0 = this._x0,
y0 = this._y0,
@@ -58,10 +58,16 @@ export default function(x, y, radius) {
dy = y - +this._y.call(null, node.data),
d2 = dx * dx + dy * dy;
if (d2 < radius) {
- var d = Math.sqrt(radius = d2);
- x0 = x - d, y0 = y - d;
- x3 = x + d, y3 = y + d;
- data = node.data;
+ var f, d;
+ do {
+ if (!filter || filter(node.data)) f = node;
+ } while (!f && (node = node.next));
+ if (f) {
+ d = Math.sqrt(radius = d2);
+ x0 = x - d, y0 = y - d;
+ x3 = x + d, y3 = y + d;
+ data = f.data;
+ }
}
}
}
diff --git a/test/find-test.js b/test/find-test.js
index 82fc217..977a79f 100644
--- a/test/find-test.js
+++ b/test/find-test.js
@@ -32,3 +32,12 @@ tape("quadtree.find(x, y, null) treats the given radius as Infinity", function(t
test.deepEqual(q.find(20, 20, undefined), [0, 0]);
test.end();
});
+
+tape("quadtree.find(x, y, radius, filter) considers only filtered points", function(test) {
+ var q = d3_quadtree.quadtree([[0, 0, "red"], [100, 0, "blue"], [100, 0, "blue"], [0, 100, "red"], [100, 100, "red"], [100, 100, "blue"]]);
+ test.deepEqual(q.find(20, 0, null, d => d[2] == "red"), [0, 0, "red"]);
+ test.deepEqual(q.find(20, 0, null, d => d[2] == "blue"), [100, 0, "blue"]);
+ test.deepEqual(q.find(20, 0, 50, d => d[2] == "blue"), undefined);
+ test.deepEqual(q.find(20, 0, null, d => d[2] == "green"), undefined);
+ test.end();
+});