dygraphs icon indicating copy to clipboard operation
dygraphs copied to clipboard

Contribution: CSS for better looking legends

Open cvmartin opened this issue 6 years ago • 5 comments

First of all, thanks for making available dygraphs for R; I find it way faster than D3.js for displaying time series (x10, according to my calculations) and think the library should get more love.

I use dygraphs in many of my personal projects, and with the time I came up with a CSS for the legend of the graphs that, as I see it, make them look dramatically better:

dygraph_custom_legend

The changes are:

  • The legend looks "neater", with a shadowing of the date and block display of the different series.
  • The box of the legend translates to the left when hoovered; a nice way to make all the data visible without placing the legend in its own div.
  • When using dyHighlight(), the highlighted series is signaled in the legend with a discrete gray left border.

Find below the CSS that I use. To me it works fine including it with dyCSS() or sourcing it into the shiny app. Also, I find it nicer to use combined with dyLegend(show = "onmouseover")

Please note that I am no expert myself in CSS, so probably the code can be improved (I had to use several infamous !important). Any suggestion is welcome, and naturally you are free to include this styling in the package if you find it convenient. Cheers.

.dygraph-legend {
  width: auto !important;
  min-width: 150px;
  color: white;
  background-color: #BABABA !important;
  padding-left:5px;
  border-color:#BABABA;
  border-style:solid;
  border-width:thin;
  transition:0s 4s;
  z-index: 80 !important;
  box-shadow: 2px 2px 5px rgba(0, 0, 0, .3);
  border-radius: 3px;
}

.dygraph-legend:hover{
  transform: translate(-110%);
  transition: 0s;
}

.dygraph-legend > span {
  color: black;
  padding-left:5px;
  padding-right:2px;
  margin-left:-5px;
  background-color: white !important;
  display: block;
}

.dygraph-legend > span:first-child {
  margin-top:2px;
}

.dygraph-legend > span > span{
  display: inline;
}

.highlight {
  border-left: 2px solid #BABABA;
  padding-left:3px !important;
}

cvmartin avatar Dec 22 '18 12:12 cvmartin

I would suggest wrapping this into some dy* function (leveraging dyCSS as you say) then including it a PR. I like the look!

klaukh avatar Dec 22 '18 22:12 klaukh

Like this, then. Here it is a minimum example, that I should have included above anyway.

library(dygraphs)
library(magrittr) # just for the pipe

dyCSScool <- function(dygraph){
  
  dygraph$x$css <- '
  .dygraph-legend {
  width: auto !important;
  min-width: 150px;
  color: white;
  background-color: #BABABA !important;
  padding-left:5px;
  border-color:#BABABA;
  border-style:solid;
  border-width:thin;
  transition:0s 4s;
  z-index: 80 !important;
  box-shadow: 2px 2px 5px rgba(0, 0, 0, .3);
  border-radius: 3px;
  }
  
  .dygraph-legend:hover{
  transform: translate(-110%);
  transition: 0s;
  }
  
  .dygraph-legend > span {
  color: black;
  padding-left:5px;
  padding-right:2px;
  margin-left:-5px;
  background-color: white !important;
  display: block;
  }
  
  .dygraph-legend > span:first-child {
  margin-top:2px;
  }
  
  .dygraph-legend > span > span{
  display: inline;
  }
  
  .highlight {
  border-left: 2px solid #BABABA;
  padding-left:3px !important;
  }
  '
  dygraph
}

lungDeaths <- cbind(mdeaths, fdeaths)

dygraph(lungDeaths) %>%
  dySeries("mdeaths", label = "Male") %>%
  dySeries("fdeaths", label = "Female") %>%
  dyRangeSelector() %>% 
  dyLegend(show = "onmouseover") %>% 
  dyOptions(stackedGraph = TRUE) %>%
  dyCSScool()

cvmartin avatar Jan 06 '19 23:01 cvmartin

Hi, really nice work and a good template for further work. I don't know if this is the right forum to ask, but do you have success changing the legend font-size? I am showing a dygraph in a Shiny App with labelsDiv in a htmloutput next to it. The highlighted legend font-size changes, but the non-highlighted doesn't seem to be affected. I am using this CSS:

.dygraph-legend  { 
  display: inline;
  font-size: 20px !important;
}
.highlight {
  display: inline;
  background-color: #B0B0B0;
  font-size: 15px;
}

aha-incom avatar Aug 31 '20 10:08 aha-incom

This works for me:

.dygraph-legend > span {
  font-size: 40px !important;
}

So the font size shall be applied to .dygraph-legend > span instead of .dygraph-legend

cvmartin avatar Aug 31 '20 10:08 cvmartin

Thanks for your quick reply, it helped me to boil down the problem. I realized it's the labelsDiv that causes a problem for me.

The code below works as intended. However, if you include the "LegendDiv" the behaviour of the legend changes.

(Not expecting an answer to this, just wanted to share the problem if others are having the same problem)

library(shiny)
library(dygraphs)
lungDeaths <- cbind(ldeaths, mdeaths, fdeaths)
ui <- fluidPage(
  fluidRow(column(12, dygraphOutput("my_dygraph")#, htmlOutput("LegendDiv")
                  ))
  
)
server <- function(input,output,session){
  output$my_dygraph <- renderDygraph(
    dygraph(lungDeaths, main = "Deaths from Lung Disease (UK)") %>%
      dyHighlight(highlightSeriesOpts = list(strokeWidth = 3)) %>%
      # dyLegend(show = "always", labelsDiv = "LegendDiv") %>%
      dyCSS(textConnection("
                  .dygraph-legend {
                    font-size: 50px !important;
                  }
                  .highlight {
                    display: inline;
                    background-color: #B0B0B0;
                    font-size: 30px;
                  }
                  .dygraph-axis-label {
                    font-size: 8px;
                  }
                  .dygraph-title {
                    font-size: 12px;
                  }
                ")
          )
    )
  
}
shinyApp(ui,server)

aha-incom avatar Aug 31 '20 11:08 aha-incom