Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3.js key function running twice on simple selector/array combo

Learning d3 and when I create a simple array of numbers, then attempt to bind the data to a simple set of elements, but use the key function, it runs through the loop twice. The first time through, it tells me that the values of the array are undefined. The second time through they are available.

Here is the html:

<div class="testBind"></div>
<div class="testBind"></div>
<div class="testBind"></div>

And here is the js:

var numbers = [1, 2, 3];

function whichNumber(n){
    console.log('n----:' + n);
    return n;
}

var testKeyFunction = d3.selectAll("div.testBind").data(numbers, whichNumber);

When I run this, I get:

n----:undefined
n----:undefined
n----:undefined
n----:1
n----:2
n----:3

Here is a fiddler: http://jsfiddle.net/5f8mo2sa/3/

The reason this is a problem (aside from wtf) is because when the data is an array of objects and I try to reference a key in the function, it throws an undefined error.

like image 606
ofthewolf Avatar asked Dec 20 '14 05:12

ofthewolf


1 Answers

From the d3 help:

A key function may be specified to control how data is joined to elements. This replaces the default by-index behavior; the key function is invoked once for each element in the new data array, and once again for each existing element in the selection. In both cases the key function is passed the datum d and the index i. When the key function is evaluated on new data elements, the this context is the data array; when the key function is evaluated on the existing selection, the this context is the associated DOM element.

What you are seeing in the first loop is going through the existing data (which there is none), then it goes through the new data array (which has the values that you expect). If you key function depends on an object, you need to do a check first to make sure the object exists.

like image 108
Bill Avatar answered Sep 30 '22 14:09

Bill