2

I'm trying to split a datetime in two variables cx (should be the day in the year) and cy (should be the hour+minute/60) according to:

<!-- date format of d.date: 24-8-2016 9:47:38-->
            var parseDayinYearFormat = d3.time.format('%j').parse;
            var parseHourFormat = d3.time.format('%H').parse;
            var parseMinuteFormat = d3.time.format('%M').parse;

            <!-- add the objects-->
            var circles = svg.selectAll("circle")
                .data(data)
                .enter()
                .append("circle");
            var circleAttributes = circles
                .attr("cx", function (d) { return +parseDayinYearFormat(d.date);  })
                .attr("cy", function (d) { return +parseHourFormat(d.date)+(parseMinuteFormat(d.date)/60);  })
                .attr("r", function (d)  { return 20.0/(9-d.total); })
                .attr("class", function (d) {if (d.w>d.total-d.w) {return "cr"} else { return "cb" }});

But d3 isn't playing nice: cx and cy become a NaN and d3 is giving the error Uncaught TypeError: n.apply is not a function

Please help.

Rense
  • 91
  • 5

1 Answers1

2

You need to parse the entire string with a single format object. You can’t parse the string with a sequence of parsings.

Using the d3 version 3.x documentation I came up with the following, which works on your example.

var datestring = '24-8-2016 9:47:38';
var format = d3.time.format('%-d-%-m-%Y %-H:%-M:%-S');

console.log(format.parse(datestring))
// "2016-08-24T13:47:38.000Z" // (my time zone is UTC-4)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Note that because your example 24-8-2016 9:47:38 has many fields that show no zero-padding, I use a dash between the % and the specifier, i.e., %-d, to tell d3 that there may be no zero in the beginning.

Also note that in your example, there is no way 24 is a day-of-year, which is between 1 and 366: 24 is clearly just a day of the month, right?

However, it appears from your code snippet that you just want to extract the day and hour and minute from a string. For this simple purpose, d3.time.format might be overkill, since it gives you a Date object, which then you have to parse to extract the day/hour/minute. Consider using a regular expression for this task.

Ahmed Fasih
  • 6,458
  • 7
  • 54
  • 95
  • Thanks for your quick answer. But I do need hour and minutes seperately in order to do the math. As for the 24 indeed it is a day of a month, but I need it to be converted in the range 1..366. – Rense Aug 23 '16 at 18:09
  • Ya ok you can use `Date`’s methods like `GetHours` to extract the numbers you need (test to make sure you don’t get hit by local-timezone-vs-UTC bugs), or you can use `d3.time.format`. Looking at http://stackoverflow.com/q/8619879/500207, it looks like using d3 to convert the Date object to day-of-year (1–366) will be super-easy: `+d3.time.format("%j")(format.parse(datestring))` evaluates to `237`. – Ahmed Fasih Aug 23 '16 at 18:42