Pete
Pete

Reputation: 514

Values from file don't expand as x axis in D3.js using x.domain?

I have the following .tsv file format:

date    Edward Snowden    Urban Gardening    Barack Obama

2014-W15    14  3   34

2014-W16    3   5   54

2014-W17    5   15  34

I want the date displayed on the x axis with the minimum and maximum value extracted from the file and the other values as three lines on the y axis.

var parseDate = d3.time.format("%Y-W%U").parse;
d3.tsv("test.tsv", function(data) {
          data.forEach(function(d) {
            d.date = parseDate(d.date);
          });

          //set min max values of axis
          x.domain(d3.extent(data, function(d) { return d.date; }));
});

I just extracted that piece of code, not sure if it can be used as minimal example. However, the problem is that there is no x axis expanding according to the values from the file. With other files where date was formatted as %Y%m%d it was working.

Upvotes: 0

Views: 286

Answers (1)

ocket-san
ocket-san

Reputation: 884

The problem with your formatting is like saikiran says: The only correct value is the year. Your min and max value are the same, because every date passed within the same year is parsed to:

Wed Jan 01 2014 00:00:00 GMT+0100 (Romance Standard Time)

I know this because i have executed following code:

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    <title>barcode chart</title>   
    <style>
        body {height:100vh !important;}
    </style>
</head>
<body>
    <div id="chart">
    </div>



    <script src='http://d3js.org/d3.v3.min.js'></script>
    <script>

    var parseDate = d3.time.format("%Y-W%U").parse;
    var date1 = parseDate("2014-W16");
    var date2 = parseDate("2015-W25");
    var date3 = parseDate("2014-W36");

    console.log(date1);
    console.log(date2);
    console.log(date3);

    </script>
</body>
</html>

The results in the browser were as following:

Wed Jan 01 2014 00:00:00 GMT+0100 (Romance Standard Time)
Thu Jan 01 2015 00:00:00 GMT+0100 (Romance Standard Time)
Wed Jan 01 2014 00:00:00 GMT+0100 (Romance Standard Time)

And the only reason that there is a Thu jan 01 2015 is because there is value with year 2015 as input.

So I guess you will need to find a way to get the real date or you can also try to use ordinal scales. Also, beware that you don't mix the terms axis and scales. Output values with a domain and a range are calculated with scales. The axis which shows values (as ticks) uses a scale for its ticks. I say this, because in your code I see the following:

//set min max values of axis
x.domain(d3.extent(data, function(d) { return d.date; }));

But x cannot be an axis function, because d3.svg.axis() does not have a domain function. Just saying though ;-).

More information on ordinal scales can be found here

EDIT

Here is how I would implement the ordinal scale:

d3.tsv("test.tsv", function(data) {

          var xDomainValues = []; //you need an array for your domain

          data.forEach(function(d) {
             xDomainValues.push(d.date); //d.date is a string value here, but that is ok
          });

          //this ordinal scale will calculate a value between 0 and graphWidth 
          //for each value in the xDomainValues array
          var xScale = d3.scale.ordinal()
                               .domain(xDomainValues)
                               .rangeRoundPoints([0, graphWidth]); 

          var xAxis = d3.svg.axis()
                            .scale(xScale)
                            .orient("bottom"); //I oriented the tick texts on the bottom.
});

The xAxis should now expand nicely as you intended. I would seriously consider using ordinal scales in your case, but do mind: I am not a D3 expert, I am just familiar with the basics.

Upvotes: 1

Related Questions