How to align the x-axis of synchronized R dygraphs with single and double y-axis?

530 Views Asked by At

My goal is to write a Shiny app to visually compare multiple time series. All time series have the same range of x-values. Vertically stacked and synchronized dygraphs nicely show the y-value of individual time series for a common x-value.

This approach works if all dygraphs only have one y-axis (i.e. no "y2" axis):

library(shiny)
library(dygraphs)

ui <- fluidPage(
  mainPanel(
    dygraphOutput("one_axis"),
    dygraphOutput("two_axis")
  )
)

server <- function(input, output) {
  output$one_axis <- renderDygraph({
    dygraph(fdeaths, group = "foo")
  })
  output$two_axis <- renderDygraph({
    dygraph(mdeaths, group = "foo")
  })
}

shinyApp(ui, server)

the x-axis ticks are vertically aligned

In my use case some dygraphs have two y-axis: "y" and "y2". The x-axis of the plot with the double y-axis get squashed to make space for the "y2" axis and labels:

library(shiny)
library(dygraphs)

ui <- fluidPage(
  mainPanel(
    dygraphOutput("one_axis"),
    dygraphOutput("two_axis")
  )
)

server <- function(input, output) {
  output$one_axis <- renderDygraph({
    combined <- cbind(mdeaths, fdeaths)
    dygraph(combined, group = "foo") %>% 
      dySeries("mdeaths", axis = "y") %>% 
      dySeries("fdeaths", axis = "y2")
  })
  output$two_axis <- renderDygraph({
    dygraph(mdeaths, group = "foo")
  })
}

shinyApp(ui, server)

the x-axis ticks are no longer aligned

Question:

Is there a way to align the x-axis of all dygraphs, regardless of whether they have one or two y-axis?

Things I tried without success:

  • adding two y-axis for a single variable
  • playing with dyOptions(rightGap)

I found a similar question but I'm not familiar with javascript.

edit: typo

1

There are 1 best solutions below

2
On BEST ANSWER

I got this working using this code (this is Javascript but perhaps there is something analogous in R):

// Find our max graph width (finding min doesn't work because dygraph clips its canvases)
var maxWidth = 0;
for (graph of graphs) {
    maxWidth = Math.max(maxWidth, graph.plotter_.area.w);
}
// Use a negative rightGap to make all graphs match the max width
for (graph of graphs) {
    graph.updateOptions({rightGap: graph.plotter_.area.w - maxWidth});
}

I don't love it for a number of reasons:

  • It's using the private .plotter_ variable
  • It's using a negative rightGap to align things (I tried using a positive rightGap to shrink graphs to the min size, but I think Dygraph clips its canvases so it never erased the right side of the wider graphs when I shrunk them)
  • The legends don't appear in the right spot for graphs that I expand

I'm on Dygraph 2.0.0 so maybe this is easier in the latest version. Anyway I hope this helps - I had the exact same problem and it got me by for now!