Eventually I expect that CSS will be able to do this (perhaps with the
:scope selector, but I don't remember what the latest proposal is). In
the meantime, you can pass a function to select, for example:
child.select(function() { return this.parentNode; })
You should be careful, however, when selecting parents. If you have
multiple children, you could potentially select the same parent
multiple times. Also, if the child has bound data, it will be applied
to the parent.
Mike
On a similar note, if I have a dom element bound to 'this' (of course
within a function.... lets say a mousover event on the text node I was
speaking of). Now I want to do something to a sibling element, would
I crawl up to the parent, than select the element from the parent?
d3.select(this.parentNode).select('.siblingsClass')
Thanks,
Bob
Mike
Thanks again.
I'm thinking about forking d3, and prototyping the parent function on
the selection object. I have a few questions (Mike, these are pretty
much directed at you, though I don't mind hearing others opinions):
1) Would this be useful? (more specifically, if I program this
correctly, would my pull request be merged?)
2) What would make the most sense:
A) Select every elements parent, then return an array of unique
parents
B) Just select everyone's parent, return an array of the same
length as the parents
I'm leaning towards A... B is just too simple:
d3Selection.map(function(d) { return d.parentNode; })
Also, A seems to make more sense since, say You have a list of table
rows. If I select the parent, I just want the table (or I suppose the
tbody, if it exists)... I wouldn't want the selection to become the
same table(or tbody) N times (N = # rows)
3) What about something similar to the jQuery "parents()" sub-
selection function. This returns an array of the element's direct
parent, as well as its direct parents parent, all the way up the
tree. Which you can also pass in a selection string to select from
within the results. Again, may have to think this out a little more
when it comes to duplicates as well as when dealing with a selection
of multiple elements.
Let me know what you think, and if it makes sense to, I'll fork d3 and
make the pull request when I'm done.
Bob
On Dec 2, 2:33 pm, Mike Bostock <mbost...@cs.stanford.edu> wrote:
Perhaps. I'm skeptical, though. I don't know where I would use it. I
do occasionally d3.select(this.parentNode), but I don't see a big
advantage if, say, I could d3.select(this).parent(). That saves me two
characters, but it introduces a new method for people to learn over
just using the DOM.
Perhaps you could enumerate the places where you would want to use it?
I haven't needed to select parents in practice (or else I probably
would have created a facility to do that already).
> 2) What would make the most sense:
This is the danger. New functionality should hew to existing
functionality as much as possible (principle of least surprise, and
all that), but it should also be useful. This:
selection.select(function() { return this.parentNode; })
is not especially useful, because the parents may not be unique, and
also because it could unexpectedly overwrite parent data with child
data.
This is somewhat off-topic, but it might be nice to use
matchesSelector [1] in D3. A potential new feature might be
filter(selector), reducing a selection to nodes that match the given
selector. For example, these should be equivalent:
d3.selectAll("p").filter(".foo")
d3.selectAll("p.foo")
Another feature I want is a way to select only direct children of the
context node. That could be supported with Sizzle or with scoped
selectors, but I can't think of a way to do it with the standard W3C
Selectors API. In Sizzle, for example:
d3.selectAll("p").selectAll("> b")
Mike
Bob
That can give false positives. For example, say I selectAll("foo") and
then want to select all the "bar" children. If I
selectAll("foo").selectAll("foo > bar"), I'll get the correct result
in this case:
<foo>
<bar>
<baz></baz>
</bar>
<bar>
<baz></baz>
</bar>
</foo>
But I won't get the correct result in this case:
<foo>
<bar>
<foo>
<bar></bar>
</foo>
</bar>
</foo>
Admittedly, you can usually come up with some selector that does what you need.
Mike
On the other hand, considering all your work, I can take your word for
it... just strange that the "*" only selector the first children.
If this is definitely the case (as fucktarded as it is), maybe we
could implement something like jquery's .children() selector (that
allows you to select just the children, and then filter them with the
selector).... ACTUALLY, this is exactly what you mentioned above with
filter.... I guess, at the very least that can be implemented. If
you don't get to it, I'll take care of it later today. Been wanting
to contribute anyway, so might as well get a fork going.