Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why my D3 line graphs shows black areas for each entity?

I made a webscraper that gets data about currency transfer rates of different banks and shows that in a D3 line graph over time (each bank has a line, and the rates are per day). A cronjob server-side makes sure the scraping occurs daily.

In the front-end, it uses D3.json to get data from this url:

http://rateswebscraper.herokuapp.com/rates

I made the line graph but instead of a line for every bank, it shows a black area, see screenshot below:

enter image description here

Here is my code:

/*global d3*/

var margin = {

  top: 20,
  right: 50,
  bottom: 20,
  left: 50

};

var w = 1000 - margin.left - margin.right,
  h = 500 - margin.top - margin.bottom;

var ratesData = "http://rateswebscraper.herokuapp.com/rates";

//load buy or sell data    
var loadData = function(dataSet, title) {

  //set chart title
  document.getElementById("title").innerHTML = title;

  //reset SVG container element
  d3.select("#chart").select("svg").remove();

  var svg = d3.select("#chart")
    .append("svg")
    .attr("width", w + margin.left + margin.right)
    .attr("height", h + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    .attr("id", "area");

  //Create the scales    
  var x = d3.scaleTime().range([0, w]),
    y = d3.scaleLinear().range([h, 0]),
    z = d3.scaleOrdinal(d3.schemeCategory10);

  //Line generator for path   
  var line = d3.line()
    .x(function(d) {
      return x(d.date);
    })
    .y(function(d) {
      return y(d.rate);
    });

  d3.json(ratesData, function(data) {

    //convert date strings bank to date objects for d3.scaleTime    
    var rates = data.map(function(item) {

      item.date = new Date(item.date);

      return item;

    });

    var banks = rates[0].data.map(function(item) {
      //loop through the .data array and get the bank names for the series

      var bank = {};

      bank.id = item.name;

      bank.values = [];

      return bank;

    });


    var createRates = function(type) {

      rates.forEach(function(item) {

        item.data.forEach(function(rate) {

          for (var i = 0; i < banks.length; i++) {

            if (banks[i].id === rate.name) {

              var rateObject = {};

              rateObject.date = new Date(item.date);

              if (type === "buy") {

                rateObject.rate = Number(rate.buy);

              } else {

                rateObject.rate = Number(rate.sell);

              }

              banks[i].values.push(rateObject);

            }

          }

        });

      });

    }; 

    //Create a rates array per bank of buy values
    if (dataSet === "buy") {

      createRates("buy");

    } else {

      createRates("sell");

    }

    //Get the Min/Max values for date and rates and setup color scale based on bank ID
    x.domain(d3.extent(rates, function(d) {
      return d.date;
    }));
    y.domain([
      d3.min(banks, function(c) {
        return d3.min(c.values, function(d) {
          if (d.rate !== 0) {
            return d.rate;
          } else {
            return
          }
        });
      }),
      d3.max(banks, function(c) {
        return d3.max(c.values, function(d) {
          return d.rate;
        });
      })
    ]);
    //color scale needs an array of bank id's
    z.domain(banks.map(function(c) {
      return c.id;
    }));

    //append x Axis
    svg.append("g")
      .attr("class", "axis axis--x")
      .attr("transform", "translate(0," + h + ")")
      .call(d3.axisBottom(x));

    //append y Axis
    svg.append("g")
      .attr("class", "axis axis--y")
      .call(d3.axisLeft(y))
      .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", "0.71em")
      .attr("fill", "#000")
      .text("Rates in HKD");

    //for every bank element we append a g group element 
    var bank = svg.selectAll(".bank")
      .data(banks)
      .enter().append("g")
      .attr("class", "bank");

    //for every bank element we append a path element and use the line generator            
    bank.append("path")
      .attr("class", "line")
      .attr("d", function(d) {
        return line(d.values);
      })
      .style("stroke", function(d) {
        return z(d.id);
      });

    //append a text next to the line for every bank    
    bank.append("text")
      .datum(function(d) {
        return {
          id: d.id,
          value: d.values[d.values.length - 1]
        };
      })
      .attr("transform", function(d) {
        return "translate(" + x(d.value.date) + "," + y(d.value.rate) + ")";
      })
      .attr("x", 3)
      .attr("dy", "0.35em")
      .style("font", "10px work sans")
      .text(function(d) {
        return d.id;
      });

  }); =

}; 

//Call loadData function on page load with buy rates
loadData("buy", "Buy Rates");


//Add click events to buttons to load buy or sell data
document.getElementById("buyData").addEventListener("click", function() {

  loadData("buy", "Buy Rates");

});

document.getElementById("sellData").addEventListener("click", function() {

  loadData("sell", "Sell Rates");

})

Anyone can help me what I am doing wrong in my code?

like image 916
chemook78 Avatar asked Mar 13 '17 03:03

chemook78


People also ask

Is Line a closed path?

However, each independent line acts as a closed path.

How do you add a title to a D3 graph?

Use append("text") to append a title to the graph: svg. append("text") . attr("x", w/2) .


1 Answers

Add a style to the path:

.style("fill","none");
like image 183
Akhil Mohan Avatar answered Sep 28 '22 22:09

Akhil Mohan