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

Prepend node? Append existing? Insert at given location? #4

Closed
mbostock opened this issue Sep 30, 2010 · 5 comments
Closed

Prepend node? Append existing? Insert at given location? #4

mbostock opened this issue Sep 30, 2010 · 5 comments

Comments

@mbostock
Copy link
Member

Rename add to append, and introduce a similar method prepend for adding to the front.

@mbostock
Copy link
Member Author

Also, it might be nice for these methods to allow references to existing nodes, via the W3C DOM API (e.g., document.getElementById("foo")). But then it seems like you'd want to support the argument being a function, and not just a string... in which case, perhaps the function could return the node to insert (or return a string for the name of the node to create?).

If we allowed a function, perhaps that would allow the function to use a selector internally, especially if apply returned the array of matched nodes.

@mbostock
Copy link
Member Author

I like the idea of a prepend method for adding to the front. For inserting at a given location, a simple way to implement that is an insertAfter method, which creates a new node that is inserted after the context node, rather than as a child of the context node. This makes it easy to chain siblings together, as well:

d3.select("div")
  .append("span").attr("class", "sibling-1")
  .insertAfter("span").attr("class", "sibling-2")
  .insertAfter("span").attr("class", "sibling-3");

The alternative would be require capturing a reference to the selected div:

var div = d3.select("div");
div.append("span").attr("class", "sibling-1");
div.append("span").attr("class", "sibling-2");
div.append("span").attr("class", "sibling-3");

Or a way to select the parent. But you get the idea.

@mbostock
Copy link
Member Author

I guess we could name it insert for brevity, though I like the idea of doing before and after. And I think after should be the default, since insert-before is a bit awkward.

@mbostock
Copy link
Member Author

mbostock commented Feb 7, 2011

Added insert(tagName, referenceSelector). For example, insert("div", ":first-child") prepends child nodes.

mbostock added a commit that referenced this issue Jun 30, 2013
Like selection.select, selection.append and selection.insert can now accept a
function which returns a node. This makes it slightly easier to append or insert
elements whose name is computed from data, or to append elements that already
exist (say from an element pool).

There has been much discussion regarding whether the function should return the
name of the element or the element itself. Returning a name is less work for the
caller, but only supports creating new elements; returning a name is also more
consistent with how D3 defines attribute values, but D3 does not allow attribute
names to be specified as functions. So, it seemed better to opt for consistency
with selection.select and selection.selectAll, which accept functions that
return elements, since this is more expressive. Of course, you can still use
select and selectAll to append elements, but using append to do that directly is
more intuitive.

Related #4 #311 #724 #732 #734 #961 #1031 #1271.
GerHobbelt pushed a commit to GerHobbelt/d3 that referenced this issue Jan 7, 2014
first pass at getting .on() to work with Raphael event binding.
@drarmstr
Copy link

Note a difference is that (at least with Chrome 37 and D3 3.4.6) JQuery's prepend() will insert before any text node content while D3's insert(...,':first-child') will only insert before normal nodes, not text nodes.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants