Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

converting a d3.csv method to d3.csv.parse method

I just need to draw a d3 barchart of data retrieved from an sql query, so I don't have a tsv or csv file but a string of data in csv format. I know I can use d3.csv.parse method but somehow I couldn't figure out how to convert the example code for the csv bar chart using the data from a file to csv.parse method for data contained in a string variable.

here is the example code for csv file:

d3.csv("data.csv", type, function(error, data) {
  x.domain(data.map(function(d) {  return d.letter; }));
  y.domain([0, d3.max(data, function(d) { return d.frequency; })]);

here is the sample data for testing purposes and the code that doesn't work

var bardata="letter,frequency\nA,0.89\nB,0.71\nC,0.45";
d3.csv.parse(bardata,type, function(data) { 
    x.domain(data.map(function(d) { return d.letter; })); 
    y.domain([0, d3.max(data, function(d) { return d.frequency; })]);

Apparently, I cannot simply replace a file with a var containing the contents of the file. What would be the best way to do it?

Many thanks

like image 267
Baki Avatar asked Sep 30 '14 01:09

Baki


1 Answers

d3.csv.parse accepts only two parameters — a string which contains your CSV data, and an accessor function which you can use to construct the data array. Note the difference between d3.csv and d3.tsv, which both also accept the callback function as a parameter.

letters = d3.csv.parse(bardata, function(d) {
    return {
        letter:d.letter, 
        frequency:+d.frequency
    };
});

This would parse CSV data in bardata and put the values as an array in letters. In fact, the accessor function is optional. The following would also do the same thing:

letters = d3.csv.parse(bardata);

Once you have the array, you can build the bar chart as usual. See snippet below.

var bardata="letter,frequency\nA,0.89\nB,0.71\nC,0.45";

var margin = {top: 20, right: 30, bottom: 30, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1, .2);

var y = d3.scale.linear()
    .range([height, 0]);

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

letters = d3.csv.parse(bardata, function(d) { 
    return {
        letter:d.letter, 
        frequency:+d.frequency
    }; 
});

x.domain(letters.map(function(d) { return d.letter; }));
y.domain([0, d3.max(letters, function(d) { return d.frequency; })]);

svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.svg.axis().scale(x).orient("bottom"));

svg.append("g")
    .attr("class", "y axis")
    .call(d3.svg.axis().scale(y).orient("left"));

svg.selectAll(".bar")
    .data(letters)
  .enter().append("rect")
    .attr("class", "bar")
    .attr("x", function(d) { return x(d.letter); })
    .attr("width", x.rangeBand())
    .attr("y", function(d) { return y(d.frequency); })
    .attr("height", function(d) { return height - y(d.frequency); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.4/d3.min.js"></script>
like image 99
OrionMelt Avatar answered Sep 18 '22 03:09

OrionMelt