score:3

Accepted answer

Data will only be matched by index unless you provide a key function as the second argument to selection.data([data[, key]]).

If a key function is not specified, then the first datum in data is assigned to the first selected element, the second datum to the second selected element, and so on. A key function may be specified to control which datum is assigned to which element, replacing the default join-by-index.

If you do provide a key function, however, it is worth noting, that this function will first be called for every element in the selection and will afterwards be evaluated for every new datum in your data array. Or, as the docs have it:

This key function 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]). The key function is then also evaluated for each new datum in data, being passed the current datum (d), the current index (i), and the group’s new data, with this as the group’s parent DOM element. The datum for a given key is assigned to the element with the matching key.

To match your new data to your existing texts by id you can make use of this by specifying a key function as follows:

d3.selectAll("text")
  .data(data, function(d) { return this.id || d.id; })

This will evaluate to the text elements' ids in the first run, i.e. this.id, and to the data ids in the second run, whereby matching elements to new data.

Have a look at the following snippet for a working demo:

var data = [{"id": "id1", "val":1}, {"id": "id2", "val":2}, {"id": "id3", "val":3}];

d3.selectAll("text")
  .data(data, function(d) { return this.id || d.id; })
  .text(d => d.val);
<script src="https://d3js.org/d3.v4.js"></script>
<svg>
  <text id="id1" y="10">text1</text>
  <text id="id2" y="25">text2</text>
  <text id="id3" y="40">text3</text>
  <text id="abc1" y="55">textABC1</text>
  <text id="abc2" y="70">textABC2</text>
  <text id="abc3" y="85">textABC3</text>
</svg>

score:-1

Try to make loop for data ...

var data = [{"id": "id1", "val":1}, {"id": "id2", "val":2},...];

$(data).each(function(i,d){
    d3.select("#"+d.id).text(d.val);
}); 

and without jQuery

for(var i=0, ii=data.length; i<ii; i++){
    d3.select("#"+data[i].id).text(data[i].val);
}

Related Query