Reputation: 41
I have a problem concerning filling a dc.js table with data. The documentation allows for 2 ways for doing this.
However, my data is formatted so that element of the 3D-data-array is an object. In this object I store some information about the cell (datatype, faulty, empty etc) and the value (of course).
So instead of accessing a value by array[row][column]
, I access it by array[row][column].csvValue
.
This means that I cannot use the proposed way to create the function, which sets the column. (see the link from above)
chart.columns([function(d) { return d.date; }, ... ]);
So what I would like my array to look like is (if i have 3 columns):
chart.columns([function(d) { return d[0].cellValue; },
function(d) { return d[1].cellValue; },
function(d) { return d[2].cellValue; } ]);
To create this array dynamically I loop over each column and add a function to the array.
This approach cannot work, because I have a variable i
inside the inner function, which is undefined outside of this loop. But I cannot think of a way of building this array without having the variable for the row i
in my function.
for (var i = 0; i < cellInfo[0].length; i++) {
columnArray[i] = function(d) {return d[i].cellValue; /* d[i] produces the error */};
}
I have created 2 jsfiddles: one where you can see my error in the console, and one working example using just a 3D-array without an object inside each cell.
Upvotes: 2
Views: 130
Reputation: 41
As andiwand pointed out, a closure is needed to solve my problem. I have also edited the jsfiddle (by adding brackets around the function).
The critical line, where a closure is added is:
for (var i = 0; i < data.length; i++) {
columnArray[i] = (function(i){ return function(d) {return d[i].cellValue;}; })(i);
}
An interesting read on this topic is the closure documentation from developers.mozilla.org. It provides insight to scoping of variables and closures in JS and their implications.
Upvotes: 2