Reputation: 2101
I'm trying to write a function for the .tickValues method on my X axis so that the first year in my array of data is written as the full year (2000) and the rest of the years are written as: '01, '02, '03..ect
here are the scale, axis and data:
var xScale = d3.time.scale()
.range([0, width])
.domain(d3.extent(dataset, function(d) { return d.year }));
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var dataset = [
{ year: "2000", age1: 31, age2: 10, age3: 32, age4: 27 },
{ year: "2001", age1: 32, age2: 12, age3: 30, age4: 26 },
{ year: "2002", age1: 24, age2: 19, age3: 32, age4: 25 },
{ year: "2003", age1: 26, age2: 18, age3: 31, age4: 25 },
{ year: "2004", age1: 22, age2: 17, age3: 34, age4: 27 },
{ year: "2004", age1: 24, age2: 17, age3: 33, age4: 26 },
{ year: "2006", age1: 31, age2: 15, age3: 32, age4: 22 },
{ year: "2007", age1: 30, age2: 15, age3: 35, age4: 20 },
{ year: "2008", age1: 27, age2: 18, age3: 31, age4: 24 },
{ year: "2009", age1: 25, age2: 15, age3: 35, age4: 25 },
{ year: "2010", age1: 34, age2: 12, age3: 33, age4: 21 },
{ year: "2011", age1: 31, age2: 14, age3: 32, age4: 23 },
{ year: "2012", age1: 27, age2: 18, age3: 30, age4: 25 },
{ year: "2013", age1: 25, age2: 20, age3: 35, age4: 20 }
];
// convert years to dates
var parseDate = d3.time.format("%Y").parse;
dataset.forEach(function(d) {
d.year = parseDate(d.year);
});
I have a function to format the years as '01, '02 ect:
var formatYear = d3.time.format("'" +"%y");
But when I apply to it my function in the .tickValues() method it does not work:
xAxis.tickValues( function(d){ if(d==dataset[0].year){return d;}else{return formatYear(d);} } );
Upvotes: 0
Views: 209
Reputation: 9138
The .tickValues()
method is used for assigning which values receive ticks on the axis, not for assigning how they are formatted. For that, you should use the .tickFormat()
method.
To start, it looks like your are doing things precisely backwards in the code block you posted. You should define your data and convert your values into dates before you create the domain of your scale.
Since you are turning the year values in your data into Date
objects, when you create your scale, you can use the unary +
operator to coerce them into the number of ms...
var xScale = d3.time.scale()
.range([0, width])
.domain(d3.extent(dataset, function(d) { return +d.year; }));
...which you can then use within the function you pass to .tickFormat()
:
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickFormat(function(d) {
// if the year ends in 00 then display the full year
if (d3.time.format('%Y')(d).slice(-2) === '00') {
return d3.time.format('%Y')(d);
} else {
// otherwise shorten it to the final 2 digits
return d3.time.format('\'%y')(d);
}
})
.ticks(d3.time.year, 1);
The last line there shows the advantage of using the actual date objects rather than the year string for the scale, as you can have precise control of the time-interval of your ticks. In this case I have specified that there should be a tick for every year.
Here is a demo JSFiddle
Upvotes: 0