最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - D3.js: time.scale.utc() does not seem to do anything for me? - Stack Overflow

programmeradmin1浏览0评论

I'm trying to use d3.time.scale.utc() to generate a time scale that is the same on any device, as mentioned in the docs.

However, both of the following scales seem to generate tick dates that are locally formatted - in my case the returned dates are using BST and GMT:

var start = new Date("Mon Oct 21 2013 00:00:00 GMT+0000 (BST)");
var end = new Date("Mon Dec 02 2013 00:00:00 GMT+0000 (GMT)")

var x = d3.time.scale.utc()
    .domain([start, end])
    .range([0, 800])
    .ticks(d3.time.mondays, 1);
console.log(x);

var y = d3.time.scale()
    .domain([start, end])
    .range([0, 800])
    .ticks(d3.time.mondays, 1);
console.log(y);

How can I ask D3 to generate me tick dates that are not set to a local timezone?

Fiddle here: /

I'm trying to use d3.time.scale.utc() to generate a time scale that is the same on any device, as mentioned in the docs.

However, both of the following scales seem to generate tick dates that are locally formatted - in my case the returned dates are using BST and GMT:

var start = new Date("Mon Oct 21 2013 00:00:00 GMT+0000 (BST)");
var end = new Date("Mon Dec 02 2013 00:00:00 GMT+0000 (GMT)")

var x = d3.time.scale.utc()
    .domain([start, end])
    .range([0, 800])
    .ticks(d3.time.mondays, 1);
console.log(x);

var y = d3.time.scale()
    .domain([start, end])
    .range([0, 800])
    .ticks(d3.time.mondays, 1);
console.log(y);

How can I ask D3 to generate me tick dates that are not set to a local timezone?

Fiddle here: http://jsfiddle/qE9ur/

Share Improve this question edited Feb 11, 2014 at 19:21 flossfan asked Feb 11, 2014 at 19:15 flossfanflossfan 10.9k16 gold badges45 silver badges54 bronze badges 6
  • In the fiddle, they are returning GMT time, which is the same as UTC. Check this. There is a note on GMT being the same as UTC. So maybe the "conversion" might not make sense to D3. – FernOfTheAndes Commented Feb 11, 2014 at 19:36
  • Thanks, but the first item returned by the tick function in the fiddle is returning BST, which is surely not the same as UTC... – flossfan Commented Feb 11, 2014 at 19:39
  • I am getting this from the console output: Mon Oct 21 2013 00:00:00 GMT-0400 (EDT). – FernOfTheAndes Commented Feb 11, 2014 at 19:45
  • I guess that's your local timezone. Are you getting that as the first item in both x and y? If so, then utc() isn't doing what I'd expect it to. – flossfan Commented Feb 11, 2014 at 19:46
  • You're right. They are the same. Looking at the docs for possible defaults. – FernOfTheAndes Commented Feb 11, 2014 at 19:54
 |  Show 1 more ment

1 Answer 1

Reset to default 14

The problem is simply that you are logging date objects to the console, and your browser is applying default formatting to those objects to convert them to your local time zone.

Using d3.time.scale.utc() doesn't change the date objects. Javascript date objects are always stored internally as numbers of milliseconds since 1970.

What is unique about the UTC scale is the tickFormat function, which uses a UTC time formatter by default. However, the tick format function doesn't affect logging to console, only when you're actually drawing the ticks as labels!

The following fiddle actually uses the tick formatting function of each scale to format the date objects logged to the console:
http://jsfiddle/qE9ur/1/

var start = new Date("Mon Oct 21 2013 00:00:00 GMT+0100 (BST)");
var end = new Date("Mon Dec 02 2013 00:00:00 GMT+0000 (GMT)")

var xScale = d3.time.scale.utc()
    .domain([start, end])
    .range([0, 800]);
var xTicks =  xScale.ticks(d3.time.mondays, 1);

console.log( xTicks.map( xScale.tickFormat() ) );

var yScale = d3.time.scale()
    .domain([start, end])
    .range([0, 800]);
var yTicks = yScale.ticks(d3.time.mondays, 1);

console.log(yTicks.map( yScale.tickFormat() ) );

However, you'll discover another problem (assuming you're not in a GMT timezone). The default formatting function for a time scale is a multi-format: if values aren't for midnight, it will return the time instead of the date. When you specify the ticks as mondays, it still calculates them as midnight monday in your current timezone, which for me is 6 or 7 hours off of UTC.

That's why there are UTC versions of all the time interval functions, as well. Changing the ticks specification to

var xTicks =  xScale.ticks(d3.time.mondays.utc, 1);

gets the tick values to fall at midnight UTC: http://jsfiddle/qE9ur/2/

All that said, you'll still probably want to specify a custom tick formatter. The day of the week + day of the month format doesn't really work when you're scanning through multiple months on Mondays only.

发布评论

评论列表(0)

  1. 暂无评论