Question

I'm having a lot of trouble trying to do a data bind combining an array onto an existing svg map.

The array contains objects which have a name property that corresponds to the id property of the svg elements in the d3 selection.

I'm doing the data-join like this:

mySelection.data(
  [
    {"name": "county1"},
    {"name": "county2"},
    {"name": "county3"}
  ],                 
  function (datum, index) {
    if (this.getAttribute("id") === datum["name"]) {
      return datum;
  });

However when I run it I get the error Uncaught TypeError: Cannot read property 'name' of undefined.

I've tried stepping through the code with a debugger, and it looks to me like the problem is that when d3 calls my key function, the datum argument is empty. So I can only assume it doesn't like like the format of the data array.

I've tried reading the documentation on the data function here, unfortunately it isn't very clear about what format the function expects for its first argument besides that it should be an "array of data".

Can you help me work out why my data bind isn't working?

Here is a jsFiddle using my actual data: http://jsfiddle.net/Racheet/GG3d5/

Was it helpful?

Solution

The second argument of .data() is a function that is executed for each data element and each DOM element in myselection. It is passed the data and assumed to return whatever allows to match data and DOM elements. In your case, this would be .name.

Your example doesn't have any data bound to the elements, so this doesn't work. You can however leverage this fact and check whether there is data bound and if not, return the ID of the DOM element:

provinces.data(data, function(d) { return d ? d.name : this.getAttribute("id"); });

Note that after this operation, the DOM elements will have data bound to them and the key function should work as expected. Complete demo here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top