3

I am working on making a linegraph in D3 that displays data in JSON format that is retrieved from an API.

I found an example line graph project on D3's website and it seems relatively straight forward. The main difference between the example and my project is that the example uses data from a local csv file instead of JSON from an API request.

// This needs to be changed to my API request
d3.tsv("data.tsv", function(d) {
  d.date = parseTime(d.date);
  d.close = +d.close;
  return d;
}, function(error, data) {
  if (error) throw error;

  x.domain(d3.extent(data, function(d) { return d.date; }));
  y.domain(d3.extent(data, function(d) { return d.close; }));

  g.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x))
    .select(".domain")
      .remove();

  g.append("g")
      .call(d3.axisLeft(y))
    .append("text")
      .attr("fill", "#000")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", "0.71em")
      .attr("text-anchor", "end")
      .text("Price ($)");

  g.append("path")
      .datum(data)
      .attr("fill", "none")
      .attr("stroke", "steelblue")
      .attr("stroke-linejoin", "round")
      .attr("stroke-linecap", "round")
      .attr("stroke-width", 1.5)
      .attr("d", line);
});

I changed the csv request part to this because I'm trying to load in my JSON from the API:

    d3.json(url).get(function(d) {
    for(var i = 0; i < d.Data.length; i++) {
      coinValue.push(d.Data[i].close);
      dates.push(convertUnixTime(d.Data[i].time));
    }
    return d;
  }, function(error, data) {
  if (error) throw error;

This isn't working. I'm confused about why there's a comma and then another function right after.

What is the proper way to make the exact same line graph but with a d3.json function/API request instead?

My JSON looks like this: https://min-api.cryptocompare.com/data/histoday?fsym=ETH&tsym=USD&limit=2&aggregate=3&e=CCCAGG

Nick Kinlen
  • 1,356
  • 4
  • 30
  • 58

1 Answers1

5

The difference between d3.csv and d3.json is the accessor (2nd argument).

d3.csv: d3.csv(url[[, row], callback]) in which row is nothing but each row of the data fetched i.e. if you add a function as follows:

d3.csv(url, function(d) { // each row of the data }, callback)

d3.json: d3.json(url[, callback]) DOES NOT provide this each row accessor. But you can do that within the callback as follows:

d3.json(url, function(err, data) { data.forEach(function(row) { // parse each row as required }); })

Using the above syntax along with the provided example code and JSON URL, here's a code snippet drawing a line chart:

// This needs to be changed to my API request
d3.json("https://min-api.cryptocompare.com/data/histoday?fsym=ETH&tsym=USD&limit=2&aggregate=3&e=CCCAGG", function(error, d) {

 var data = d.Data;
  data.forEach(function(d){ d.time = new Date(d.time * 1000) });
  
  //console.log(data);
  if (error) throw error;

  var svg = d3.select("svg"),
      margin = {top: 20, right: 20, bottom: 30, left: 50},
      width = +svg.attr("width") - margin.left - margin.right,
      height = +svg.attr("height") - margin.top - margin.bottom,
      g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  var parseTime = d3.timeParse("%d-%b-%y");

  var x = d3.scaleTime()
      .rangeRound([0, width]);

  var y = d3.scaleLinear()
      .rangeRound([height, 0]);

  var line = d3.line()
      .x(function(d) { return x(d.time); })
      .y(function(d) { return y(d.close); });
      
  x.domain(d3.extent(data, function(d) { return d.time; }));
  y.domain(d3.extent(data, function(d) { return d.close; }));

  g.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x))
    .select(".domain")
      .remove();

  g.append("g")
      .call(d3.axisLeft(y))
    .append("text")
      .attr("fill", "#000")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", "0.71em")
      .attr("text-anchor", "end")
      .text("Price ($)");

  g.append("path")
      .datum(data)
      .attr("fill", "none")
      .attr("stroke", "steelblue")
      .attr("stroke-linejoin", "round")
      .attr("stroke-linecap", "round")
      .attr("stroke-width", 1.5)
      .attr("d", line);
});
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="500"></svg>

Hope this helps.

Shashank
  • 5,570
  • 1
  • 11
  • 17