I'm graphing weekly data using the dygraphs package. dygraphs automatically selects a weekly default axis. However, I'm hoping there is a way to have the default axis (Sundays) line up with my data (Mondays).
# Required packages
library("magrittr")
library("dygraphs")
library("xts")
# Data
daily <- structure(c(4000, 5000, 3000, 7000, 2000, 5000, 7000,
2000, 3000, 6000, 5000, 9000, 2000, 2000, 2000,
7000, 9000, 2000, 1000, 13000), .Dim = c(10L, 2L), .Dimnames = list(
NULL, c("col1", "col2")), index = structure(c(1476032400,
1476637200, 1477242000, 1477846800, 1478451600, 1479056400, 1479661200,
1480266000, 1480870800, 1481475600), tzone = "Asia/Saigon", tclass = c("POSIXct",
"POSIXt")), class = c("xts", "zoo"), .indexCLASS = c("POSIXct",
"POSIXt"), tclass = c("POSIXct", "POSIXt"), .indexTZ = "Asia/Saigon", tzone = "Asia/Saigon")
# Graph
dygraph(daily, main = "Stackoverflow") %>%
dyRangeSelector() %>%
dyOptions(useDataTimezone = TRUE)

You can try using a custom ticker function that starts on the first day of your data and places a tick every seven days.
Here's an example inspired from the dygraph-tickers.js Dygraph.getDateAxis function:
dygraph(daily, main = "Stackoverflow") %>%
dyRangeSelector() %>%
dyAxis("x",ticker='function(start_time, end_time, pixels, opts, dygraph, vals) {
var formatter = opts("axisLabelFormatter");
var ticks = [];
var t;
//spacing is a week in milliseconds
var spacing = 1000 * 604800;
for (t = start_time; t <= end_time; t += spacing) {
ticks.push({ v:t,
label: formatter(new Date(t), Dygraph.WEEKLY, opts, dygraph)
});
}
return ticks;
}') %>%
dyOptions(useDataTimezone = TRUE)
A workaround for this would be reformatting dyAxis label values via JavaScript functions (of course, considering that the only thing you need is changing the default first day of the week).
Take a look:
# libs and daily object ...
# the x values are passed as milliseconds, turn them into a date and extract day and month
getMonthDay <- 'function(d) {
var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun","Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var date;
if (typeof d == "number") { // value
date = new Date(d);
} else { // label
date = new Date(d.toString().substring(0, 15));
}
date.setDate(date.getDate() + 1);
return date.getUTCDate() + " " + monthNames[date.getMonth()];
}'
# Graph
dygraph(daily, main = "Stackoverflow") %>%
dyRangeSelector() %>%
dyAxis(
"x",
valueFormatter = JS(getMonthDay),
axisLabelFormatter = JS(getMonthDay),
rangePad = 40 # the rangePad would adapt by itself
) %>%
dyOptions(useDataTimezone = TRUE)
Note that we have a condition to check the type of the d object. That's because the
valueFormatter - returns the valueOf the date object;axisLabelFormatter - returns the actual date itselfSo, in case d parameter is:
number (valueFormatter), we simply create a new Date object;object (axisLabelFormatter) - yes, it sends the param as an Object; so, we need to convert it to a proper Date.The substring() approach is needed because dygraphs sends the object like this:
Sun Oct 09 2016 00:00:00 GMT+0700
... and, because of the 00's time, once you try to convert to a date, JavaScript will return
Sat Oct 08 2016 14:00:00 GMT-0300 (Local Standard Time)
This way, we'll always consider only the day, month and year for that. Also, you'd have the rangePad being applied properly:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With