2

I use the function exampleData() to generate a flat, 1-dimensional array that is used to generate SVG elements with d3.js (vesion 3.5.5). That works perfectly.

But when I use the below mentioned function load() [like dataset = load();], this leads to the error TypeError: groupData is undefined d3.v3.js:1688:31 .

Can anyone help? The file data.csv has a column header called x and 20 additional rows with one integer in each row . The arrays seems to be okay when querying at he console of the webbrowser.

Best , Frank

function exampleData() {
  return  [ 11, 12, 15, 20, 18, 17, 16, 18, 23, 25,5, 10, 13, 19, 21, 25, 22, 18, 15, 13];
}


function load() {
	d3.csv("data.csv", function(data) {
	 	 dataset2 = data.map(function(d) { 
	 	 	return [ +d["x"] ];
	 	 	});
	 	 //console.log(dataset2);
	 	 dataset2= d3.merge(dataset2);
	 	 //console.log(data);
	 	 return dataset2;
	 });

}

1
  • There is no groupData in your example and you have not indicated which line throws the error. Without that it is impossible to answer your question. Commented Jun 21, 2015 at 0:33

1 Answer 1

0

Since the code you provided doesn't throw any errors like the one you describe, i guess the error occures when you try to work with the loaded dataset, because with dataset = load(), dataset will be undefined.

The problem with your code is, that load() does not have a return statement.

Actually load() can't even return anything because d3.csv() loads data asynchronous. d3.csv() does not return anything. It starts a request for the given csv and when this request finishes, it calls the callback function.

When you call load() in your code, the next line after the call will probably be executed before the data is loaded. If you try it this way:

function load() {
  d3.csv("data.csv", function(data) {
    dataset2 = data.map(function(d) { 
      return [ +d["x"] ];
    });
    dataset2= d3.merge(dataset2);
    console.log(dataset2);
  });
}

load();
console.log("afterLoad");

The afterLoad will be logged first. Later on, when the data is loaded, the dataset will be logged.

Therefore you have to handle your data inside the callback. Probably you should have another function that draws your chart. You have to call this function from the callback function like this:

function load() {
  d3.csv("data.csv", function(data) {
    dataset2 = data.map(function(d) { 
      return [ +d["x"] ];
    });
    //console.log(dataset2);
    dataset2= d3.merge(dataset2);
    //console.log(data);
    //call the function that needs the data
    drawMyChart(dataset2);
  });
}

Since you named your dataset dataset2 i guess there is more than one dataset. I gave an explanation on loading multiple csv files in this answer. Maybe this will help you understanding the concept of asynchronous programming.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer. I heard about the asynchronous behaviour of d3.csv(). Your example is a good use case to understand this "special" behaviour.
What I wanted to achieve is to load different CSV files whenever there is a mouse click on a button with the ID = "click1", "click2", etc. And I wanted to solve it this way: d3.select("#click1") .on("click", function() { //New values for dataset dataset = load(); // ..... }); But your answer with the function load() with the chart drawing within the function is exactly what I need. If I use the function with an input value like load(filename) {d3.csv(filename, ....}, then I should have the solution I need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.