sunburstR going d3v4

The kind, generous, and very skilled CJ Yetman pinged me the other day asking if he could help with any of "my" htmlwidgets.  After seeing CJ's work on networkD3, I could not refuse this incredible offer, and I asked if he would be willing to help convert sunburstR to d3v4.  sunburstR has been by far the most popular htmlwidget from my htmlwidget/week project.

d3v4 for htmlwidgets

The transition to d3v4 will be very painful for the htmlwidgets community, and the pain is amplified by the loosely knit band of htmlwidget developers who find it nearly impossible to get help, feedback, or use cases for their open source efforts.  This sankeyD3 issue provides more of the gory details of the transition.

Join In The Fun

I have expressed many times my frustration with solo open source.  Please, please join in the fun on this project, and I promise I will be overly nice and helpful.  I will track the d3v4 conversion of sunburstR with a Github project.  If you have any interest in learning more about htmlwidgets, modern JavaScript tooling and testing, and/or d3v4, follow along.  Just to reiterate, if you are reading, I would love to have you participate in this project.

 

 

Another Little Shiny Module Trick

Probably everyone knows this but me, but I wanted to use the namespace in my Shiny server module function and I finally figured out how to accomplish this in a non-hacky way.  So in continuation of my unplanned Shiny module tips (see Super Simple Shiny Modules), here is the code.

library(shiny)

moduleUI <- function(id) {
  ns <- NS(id)
  div(sprintf("hi from %s", ns(NULL)))
}
module <- function(input, output, session) {
  print(session$ns(NULL))
}

ui <- div(
  h3("module"),
  moduleUI("module")
)
server <- function(...) {
  callModule(module, "module")
}
shinyApp(ui,server)

Super Simple Shiny Module Code

Shiny modules are especially nice as your app grows bigger and more complicated.  While there are some good resources on Shiny modules,

RStudio Shiny Modules

Steph Locke's Shiny Modules Design Patterns Series

I remember needing something simpler.  I wrote this code a while back as I learned.   Since I just recently had to refer back to it, I thought I would add in a quick post in hopes it might help someone.

library(shiny)

# this will be our super simple module UI and server
# simple UI will be blank to keep it simple
simple_moduleUI <- tagList()
# simple server will return a new runif random number
#   every 1000 milliseconds
simple_module <- function(input, output, session) {
  rctv <- reactive({
    invalidateLater(1000)
    runif(1)
  })
}

# now let's write our app which will use our
#   simple module to fill our textOutput with the random number
# UI will be just a textOutput
ui <- textOutput("randomnum")

server <- function(input, output, session) {
  # server will call our simple_module with "simple" namespace
  rndnum <- callModule(simple_module, "simple")
  # fill textOutput with the random number
  #   returned as a reactive from our callModule
  output$randomnum <- renderText({
    rndnum()
  })
}

# run our app
# use shiny.trace = TRUE if you want to see how namespacing works
# options(shiny.trace = TRUE)
shinyApp(ui, server)

Break from Unpaid Open Source

Today I start my day differently. I start my day writing this very difficult post instead of open source code. For 2017, I plan to take a break from all unpaid open source contributions. Saying all this is especially difficult knowing that there are others out there, namely CRAN team and Mike Bostock who do far more than I. In my PlotCon talk I showed this slide.

Of the four types of open source developers, I am Type 4, and I average 15-20 hours/week of personal time to commit to open source.

  1. Full-time developers whose job is to work on employer sponsored open-source projects.
  2. Developers who use open source software in their job and who contribute the byproducts of their work back to the core project or as extensions. Many do this as a way to give back to the open source projects on which they or their employers rely.
  3. Academic researchers who post open source code as a byproduct of their research or as a method of reproducibility.
  4. Passionate volunteers who sacrifice personal time to contribute out of a sense for charity, for fun, or some other reason that leads them to believe they should not be paid for their efforts.

Motivations

As I evaluate this decision, I realize that I am driven by the following motivations.

  1. I absolutely love working on open source, and I understand that I never ever expected to get anything back from those contributions. However, this cost/benefit analysis doesn’t reconcile and is in absolutely no way sustainable. I still plan to share much of what I do and, if lucky enough to get paid to work on a project, I will do everything possible to make sure that I can open source it.

  2. My real career and compensation have stalled for nearly 10 years, and I need to spend time and mental energy figuring that out.

  3. I know my audience is small, but I want to raise awareness among all those who rely on open source yet give nothing in return. If you depend on open source, please, please find a way to support or contribute to those projects on which you rely. This can be as simple as sharing examples and use cases or could be as difficult as pricing your consulting work such that you can pay the open source developers who are providing the tools on which you earn your livelihood. Just imagine for a second what would happen if a large number of open source contributors stopped suddenly and went on strike.

  4. Those 15-20 hours/week add up. I want to see how I fill these 15-20 hours each week. I am 40 years old, and time is an extremely scarce resource. I want to make sure I am maximizing however much I have left. What will I learn? What will I do? Who will I meet?

Conclusion

I am a little scared, and I now face a void.

I alternate between feeling like the boy and the tree in "The Giving Tree". Thanks to all those who contribute to open source.

d3 hierarchy as R nested tibble

After Jenny Bryan’s fantastic PlotCon presentation Data Rectangling, I started thinking what would a d3.js hierarchy look like as a nested tibble.

d3r Shows Us

I had forgotten that in d3r::d3_nest I provided an argument to get the tibble instead of the JSON, so getting an example on your machine should be fairly simple (let me know if it isn’t). We will use the helpful random.hierarchical.data function in the treemap package to generate the data.

# install.packages("d3r")
# install.packages("treemap")
library(treemap)
library(d3r)

d3_nest(
  random.hierarchical.data(),
  json = FALSE
)[,c("id","children")]
## # A tibble: 1 × 2
##      id         children
##   <chr>           <list>
## 1  root <tibble [4 × 2]>

Still No Easier to Query

Unfortunately, even though we can get the data in this form, I don’t think R tooling makes it any easier to query or manipulate. Please let me know if you have ideas or a workflow for working with this type data in R. data.tree seems to be our best option.