Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

selection.wrap #297

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,26 @@ selection.select(function() {
});
```

<a name="selection_wrap" href="#selection_wrap">#</a> <i>selection</i>.<b>wrap</b>(<i>type</i>) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/wrap.js)

If the specified *type* is a string, creates a new element of this type (tag name) as a new parent for each selected element, and replaces that node in the document by its new parent.

If the specified *type* is a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). This function should return an element to be used as the new parent. (The function typically creates a new element, but it may instead return an existing element.) For example, to wrap a paragraph around each SPAN element:

```js
d3.selectAll("span").wrap("p");
```

This is equivalent to:

```js
d3.selectAll("span").wrap(() => document.createElement("p"));
```

In both cases, this method returns a new selection containing the new parent elements. Each new element inherits the data of the current element it wraps.

The specified *name* may have a namespace prefix, such as `svg:text` to specify a `text` attribute in the SVG namespace. See [namespaces](#namespaces) for the map of supported namespaces; additional namespaces can be registered by adding to the map. If no namespace is specified, the namespace will be inherited from the selected element; or, if the name is one of the known prefixes, the corresponding namespace will be used (for example, `svg` implies `svg:svg`). To wrap svg elements in HTML A elements, pass an explicit namespace.

<a name="selection_sort" href="#selection_sort">#</a> <i>selection</i>.<b>sort</b>(<i>compare</i>) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/sort.js)

Returns a new selection that contains a copy of each group in this selection sorted according to the *compare* function. After sorting, re-inserts elements to match the resulting order (per [*selection*.order](#selection_order)).
Expand Down
2 changes: 2 additions & 0 deletions src/selection/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import selection_datum from "./datum.js";
import selection_on from "./on.js";
import selection_dispatch from "./dispatch.js";
import selection_iterator from "./iterator.js";
import selection_wrap from "./wrap.js";

export var root = [null];

Expand Down Expand Up @@ -84,6 +85,7 @@ Selection.prototype = selection.prototype = {
datum: selection_datum,
on: selection_on,
dispatch: selection_dispatch,
wrap: selection_wrap,
[Symbol.iterator]: selection_iterator
};

Expand Down
11 changes: 11 additions & 0 deletions src/selection/wrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import creator from "../creator.js";

export default function(name) {
var create = typeof name === "function" ? name : creator(name);
return this.select(function() {
const wrap = create.apply(this, arguments);
if (this.parentNode) this.parentNode.insertBefore(wrap, this);
wrap.appendChild(this);
return wrap;
});
}
42 changes: 42 additions & 0 deletions test/selection/wrap-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import assert from "assert";
import {create, selectAll} from "../../src/index.js";
import {assertSelection} from "../asserts.js";
import it from "../jsdom.js";

it("selection.wrap(name) wraps each of the selected elements in a new element of the specified name", "<div id='one'></div><div id='two'></div>", () => {
const one = document.querySelector("#one");
const two = document.querySelector("#two");
const selection = selectAll([one, two]).data([1, 2]).wrap("pre");
const [three, four] = document.querySelectorAll("pre");
assertSelection(selection, {groups: [[three, four]], parents: [null]});
});

it("selection.wrap(name) wraps with the appropriate namespace", () => {
const htmllink = create("span").wrap("a");
assert.strictEqual(htmllink.node().namespaceURI, "http://www.w3.org/1999/xhtml");
const svglink = create("svg:text").wrap("a");
assert.strictEqual(svglink.node().namespaceURI, "http://www.w3.org/2000/svg");
});

it("selection.wrap(name) wraps unattached elements", () => {
const p = create("span").text("Hello").wrap("p");
assert.strictEqual(p.node().nodeName, "P");
});

it("selection.wrap(function) passes the creator function data, index and group", "<div id='one'></div><div id='two'></div>", () => {
const one = document.querySelector("#one");
const two = document.querySelector("#two");
const results = [];

selectAll([one, two])
.datum(function(d, i) { return "node-" + i; })
.wrap(function(d, i, nodes) {
results.push([this, d, i, nodes]);
return document.createElement("p");
});

assert.deepStrictEqual(results, [
[one, "node-0", 0, [one, two]],
[two, "node-1", 1, [one, two]]
]);
});