diff --git a/README.md b/README.md index e115d86..5d95e3e 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,14 @@ See [*selection*.data](#selection_data) for more. This method is not intended for concatenating arbitrary selections, however: if both this selection and the specified *other* selection have (non-null) elements at the same index, this selection’s element is returned in the merge and the *other* selection’s element is ignored. +# selection.selectChild([selector]) [<>](https://github.com/d3/d3-selection/blob/master/src/selection/selectChild.js "Source") + +Returns a new selection with the (first) child of each element of the current selection matching the *selector* (if specified). + +# selection.selectChildren([selector]) [<>](https://github.com/d3/d3-selection/blob/master/src/selection/selectChildren.js "Source") + +Returns a new selection with the children of each element of the current selection matching the *selector* (if specified). + # d3.matcher(selector) [<>](https://github.com/d3/d3-selection/blob/master/src/matcher.js "Source") Given the specified *selector*, returns a function which returns true if `this` element [matches](https://developer.mozilla.org/en-US/docs/Web/API/Element/matches) the specified selector. This method is used internally by [*selection*.filter](#selection_filter). For example, this: diff --git a/src/matcher.js b/src/matcher.js index 4d6aadc..e6d4f50 100644 --- a/src/matcher.js +++ b/src/matcher.js @@ -1,5 +1,4 @@ export default function(selector) { - selector += ""; return function() { return this.matches(selector); }; diff --git a/src/selection/selectChild.js b/src/selection/selectChild.js index c7c28bb..6711d30 100644 --- a/src/selection/selectChild.js +++ b/src/selection/selectChild.js @@ -1,13 +1,17 @@ import matcher from "../matcher.js"; +import constant from "../constant.js"; var find = Array.prototype.find; function childFind(match) { + match = typeof match === "function" ? match + : match == null ? constant(true) + : matcher(match); return function() { - return find.call(this.children, match); + return find.call(this.children, function(e) { return match.call(e); }); }; } export default function(match) { - return this.select(childFind(typeof match === "function" ? match : matcher(match))); + return this.select(childFind(match)); } diff --git a/src/selection/selectChildren.js b/src/selection/selectChildren.js index 32cb607..5f263e3 100644 --- a/src/selection/selectChildren.js +++ b/src/selection/selectChildren.js @@ -7,8 +7,9 @@ function children() { } function childrenFilter(match) { + match = typeof match === "function" ? match : matcher(match); return function() { - return filter.call(this.children, match); + return filter.call(this.children, function(e) { return match.call(e); }); }; } diff --git a/test/selection/selectChildren-test.js b/test/selection/selectChildren-test.js new file mode 100644 index 0000000..ac5adf8 --- /dev/null +++ b/test/selection/selectChildren-test.js @@ -0,0 +1,65 @@ +var tape = require("tape"), + jsdom = require("../jsdom"), + d3 = require("../../"); + +tape("select.selectChild(…) selects the first (matching) child", function(test) { + var document = jsdom("