-1

i am missing something basic about d3 selection. using the basic d3 force layout example, i want to select a particular node, say Myriel and make it fixed. following previous hints like this and this, it seems myrielNode = d3.select(["name=Myriel"]) should do it but does not? i've also tried filter() based strategies, ... what am i doing wrong, please?

Community
  • 1
  • 1
rikb
  • 630
  • 5
  • 18

2 Answers2

1
var myrielDomNode = d3.select('[name="Myriel"]');
var myrielDatum = myrielDomNode.datum();
myrielDatum.fixed = true;

This of course assumes a DOM node exists that has an attribute name="Myriel" and is bound to data such that datum() is an object controlled by the force layout.

Update

Turns out that name was not an attribute of the DOM node, but rather an attribute of the data. In this case, finding the Myriel node becomes a find operation (via filter) on the data array:

myrielNode = nodes.filter(function(d) { return d.name == 'Myriel'; })[0]
Community
  • 1
  • 1
meetamit
  • 24,727
  • 9
  • 57
  • 68
  • as your solution began the same as @Stephen's i started with that (adding additional quotes). as i replied to him, that isn't helping. but i do match your assumptions: i can grab a mouse-click event, get a `` DOM element, and it does have a fixed property the force layout respects? – rikb Oct 23 '14 at 04:48
  • @rikb It's not just the quotes that you're missing, but more importantly, the parentheses are missing (at least from the example you provided). – meetamit Oct 23 '14 at 12:58
  • ah! bad typo in my original post, sorry @Stephen. I edited that to include the parens; I HAD been using them. and to be complete, let me also say that (when i use a checkpoint with a mouse-click interupt i find) the `g` DOM element also has the correct `name` attribute. such a simple `select()` not working, it's driving me nuts! – rikb Oct 23 '14 at 16:03
  • @rikb Could there be more than a single DOM element with `name=Myriel`? `d3.select()` only returns the first one it finds, so if there are multiples, you need to work around it. `d3.selectAll()` will return a list of matches, but `datum()` will only return the first match's datum. If you also have jQuery on the page, you can use the developer console to check what you get with `$('[name="Myriel"]')`, or if you don't have jQuery, you can check whether (again, from the console) `d3.selectAll('[name="Myriel"]').size()` yields anything other than 1. – meetamit Oct 23 '14 at 16:44
  • @Stephen, no the names in [mbostock's miserables example](http://bl.ocks.org/mbostock/4062045) are unique. and if `selectAll()` returned ANYTHING other than arrays of null i'd be happy; both `select()` and 'selectAll()` return arrays of nulls(: – rikb Oct 24 '14 at 17:55
  • and sorry again @meetamit, i just realized i've been referring to you as Stephen (: – rikb Oct 24 '14 at 18:08
  • @rikb No probs. But I'm now realizing that there might be a disconnect here: all of the above assumes that the nodes have `name` attributes in the DOM. I.e. the circles would look something like ``. The Les Mis example does not have any `name` attributes. So unless your code is adds them, your viz doesn't have them either, & none of the above is applicable. It's now sounding to me like you mean that the JavaScript objects (the `d`) that correspond to those nodes hold the `name` attribute. Correct? If so, you can't use `d3.select`. – meetamit Oct 24 '14 at 23:19
  • In this case you just need to find the Myriel node within the array that you pass to the force layout: `graph.nodes.filter(function(d) { return d.name == 'Myriel'; })[0].fixed = true`. – meetamit Oct 24 '14 at 23:22
  • 1
    that was the hint i was missing @meetamit, just the trailing `[0]` suffix! you win the Answered check, and my thanks. – rikb Oct 27 '14 at 00:07
  • for posterity, what i was looking for was `myrielNode = nodes.filter(function(d) { return d.name == 'Myriel'; })[0];` – rikb Oct 27 '14 at 00:10
0

You probably want

d3.select('[name="Myriell"]');
Stephen Thomas
  • 13,843
  • 2
  • 32
  • 53