问题
I'm trying to build a line chart using nvd3 for d3js but I've got some problems using a date domain on the x axis.
Here's my code:
data_lineChart = [
{
"key" : "key1",
"values" : [
{ "x" : "2014-04-20",
"y" : -6
},
{ "x" : "2014-04-13",
"y" : -5
},
{ "x" : "2014-04-06",
"y" : -1
},
]
},
{
"key" : "key2",
"values" : [
{ "x" : "2014-04-20",
"y" : 6
},
{ "x" : "2014-04-13",
"y" : 5
},
{ "x" : "2014-04-06",
"y" : 1
},
]
}
]
nv.addGraph(function() {
var chart = nv.models.lineChart();
chart.xAxis
.tickFormat(function(d) { return d3.time.format("%Y-%m-%d")(new Date(d)) });
chart.yAxis
.tickFormat(d3.format(',.2f'));
chart.tooltipContent(function(key, y, e, graph) {
var x = d3.time.format("%Y-%m-%d")(new Date(parseInt(graph.point.x)));
var y = String(graph.point.y);
var y = 'There is ' + String(graph.point.y) + ' calls';
tooltip_str = '<center><b>'+key+'</b></center>' + y + ' on ' + x;
return tooltip_str;
});
d3.select('#chart1 svg')
.datum(data_lineChart)
.transition()
.duration(500)
.call(chart);
return chart;
});
What I get is a x axis in which every date is 1970-01-01 and this because the d
in
chart.xAxis
.tickFormat(function(d) { return d3.time.format("%Y-%m-%d")(new Date(d)) });
ranges from 1 to -1 instead of the expected x value.
What's wrong with it?
EDIT: Starting from @AmeliaBR's solution I've managed to make this work using this code:
var chart = nv.models.lineChart().x( function(d){ return new Date(d.x);} );
chart.xScale = d3.time.scale();
chart.xAxis.tickFormat(function(d) { return d3.time.format("%d-%m-%Y")(new Date(d)) });
This because, in the tickFormat
function, d
was passed as an int
with the UNIX timestamp, and so I needed to parse the date again before formatting it.
回答1:
You're never telling NVD3 that your x-values are dates. By default, for a line chart NVD3 uses a linear (numerical) x-axis. When it tries to convert each of your x-value date strings to numbers, it gets NaN
(not a number). It therefore ends up without having any valid x values from which to create the x axis domain, and uses [-1,1] as the default.
You need to tell the chart function how to get a valid linear value from your data. You do this by setting an x-accessor function on your chart object:
var chart = nv.models.lineChart()
.x( function(d){ return Date(d.x);} );
You can also specifically tell the chart to use a Date scale for the x-axis. It's not required (once you convert your strings to Dates, they can be automatically converted into valid numbers), but it will result in better tick values (based on even multiples in date and time units, instead of even multiples of milliseconds).
chart.xScale = d3.time.scale();
chart.xAxis
.tickFormat(function(d) { return d3.time.format("%Y-%m-%d")(d) });
Note that tick value passed to the tick format from the date-time scale is a date value, so you only have to format it for printing, you don't need any conversion.
回答2:
Why dont you just pass epoch time to x, using dateObj.getTime()
more info : https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Date/getTime
Here is an example of my code which works :
chart.xAxis //Chart x-axis settings
.axisLabel('Date')
.tickFormat(function(d) { return d3.time.format('%d-%m-%y')(new Date(d)); })
.rotateLabels(-15); //This is optional but very useful sometimes
This is the kind of x I am passing to the values object :
var tmp = new Date(someDate);
tmp = tmp.getTime();
values : [{x:tmp, y:someData}, {x:tmp1, y:someData1}, etc]
来源:https://stackoverflow.com/questions/23891420/nvd3-formatting-date-returns-always-1970-01-01