Dynamic loading data using d3.csv in D3 v5
First, there is no way to load/parse just the first n
rows of a CSV with d3.csv
, I'm afraid that's not possible. Unfortunately you'll have to load/parse all the file, which may be inconvenient if the file is huge, meaning that the user will have to wait for the whole file to be loaded/parsed before the chart is painted. Also, it's worth mentioning that since d3.csv
will load all the file the subsequent filter irrelevant: just use the rows of data you want, don't add even more unnecessary tasks to the browser, just use the rows you want for painting the chart.
Back to your main question:
Your data is an array. The problem here is just that you're using d3.csv
as if it was a XHR, which was the case of D3 v4... However, in D3 v5, d3.csv
is a promise.
So, it has to be:
d3.csv(url).then(callback);
Have a look at the demo below:
var csv = URL.createObjectURL(new Blob([ `foo,bar,baz12,43,2145,54,2187,13,1798,69,17`]));
d3.csv(csv).then(function(data) { console.log(data.filter(function(d, i) { return i < 2; }));})
<script src="https://d3js.org/d3.v5.min.js"></script>
How to load data from a CSV file in D3 v5
d3 v5 uses the fetch API and returns a promise requiring the below code.
d3.csv('yourcsv.csv')
.then(function(data) {
// data is now whole data set
// draw chart in here!
})
.catch(function(error){
// handle error
})
In case in the future people want v4. d3 v4 on the other hand uses the XMLHttpRequest method, and does not return a promise requiring this code
d3.csv('yourcsv.csv', function(data) {
//whole data set
// draw chart here
})
csv loading is async so make sure to run your chart code within the csv function.
getting and using data from CSV file d3 v5
This can be resolved by changing the last line to:
.attr("fill", d => d3.color(colorr(d.InspectionScore))));
The reason this works is that d3's attr
allows you to take the attribute value from a function. In this case you want to transform the data element to either red or blue. This is what the arrow function does in the above code. It is equivalent to :
.attr("fill", function(d) {
return d3.color(colorr(d.InspectionScore));
})
To get a deeper understanding of how D3 works, you can check the tutorials.
Parse and upload a csv file in D3.js V5
For v5, d3-fetch is your friend as d3-request has been deprecated.
For instance:
d3.csv("/path/to/file.csv", rowConverter).then(function(data){ do whatever })
How do I read a CSV file into an array using d3js v5
When you run your code you should see that you are indeed loading the data. When I use your example data in a dsv/csv file and run your function I get the following logged to console:
So it appears as both your load of the dsv file is successful, and your row function is successful, based on the console log in the then
method.
Let's take a closer look at the .then
method, this runs after the file has loaded and the row function been applied - or, once the promise has been fulfilled. So the key part here is the then
method doesn't execute the provided function until after the promise is fulfilled. While we are waiting for the the promise to be fulfilled, code continues to be executed, in your case the return statement executes - before the data is fully loaded and therefore before the then method executes. This means you aren't returning any data, and this is your problem.
The simplest and probably most common d3 patterns to fetch the data with your row function is to either place code that requires the loaded data in the .then method's fulfillment function:
function getCSVdata( ) { d3.dsv(";","https://raw.githubusercontent.com/Andrew-Reid/SO/master/dsv.csv", function(d) { return { State : d.Country, freq: { low : d.Car, med : d.Van, high : d.Truck } }; }).then(function(data) { console.log("file has " + data.length + " rows"); logger(data); }); }
getCSVdata();
function logger(data) { console.log(data);}
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://d3js.org/d3.v5.min.js"></script>
d3 importing csv file to array
In d3 v5 the API for fetching data has changed quite a bit, which became necessary as the underlying workings have switched from using XMLHttpRequest
to the Fetch API. In prior versions of D3 up to v4 your code would have behaved as you expected printing the single resulting array. The new API for d3.csv()
, however, look like this:
# d3.csv(input[, init][, row]) <>
Further down the docs provide an explanation for your observation:
If only one of init and row is specified, it is interpreted as the row conversion function if it is a function, and otherwise an init object.
In your code the second argument to d3.csv()
is a function and is, thus, interpreted as the row conversion function. Because the row conversion function is executed for every single row in your input file you see each object printed individually instead of the whole array at once.
Since d3.csv()
returns a Promise the correct usage would be like this:
d3.csv("data.csv")
.then(function(data) {
console.log(data);
});
Here data
refers to the entire array of objects.
Related Topics
How Does the New Operator Work in JavaScript
What's the Difference Between & and && in JavaScript
How to Implement Routereusestrategy Shoulddetach for Specific Routes in Angular 2
Browser-Native JSON Support (Window.JSON)
Get the Data of Uploaded File in JavaScript
Sharing a Variable Between Multiple HTML Pages
Angularjs Does Not Load Scripts Within Ng-View
Add/Remove HTML Inside Div Using JavaScript
Detect Input Value Change with Mutationobserver
Remove Whitespaces Inside a String in JavaScript
Msie and Addeventlistener Problem in JavaScript
Prevent a Webpage from Navigating Away Using JavaScript
How to Mock an Es6 Module Import Using Jest
How to Enable Cors Nodejs with Express
Get Unique Selector of Element in Jquery
Getelementsbyname() Not Working