Reputation: 514
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
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