block by timelyportfolio d3c478944fa7ccecf262

example for Stack Overflow post about nested d3.js json hierarchy in R

Full Screen

This gist is a live example for Stack Overflow question.

Converting JSON format to CSV to upload data table in R to produce D3 bubble chart

To reproduce, here is the code.

library(jsonlite)
library(dplyr)


flare_json <- rjson::fromJSON(  ## rjson just works better on these for me
    file = "http://bl.ocks.org/mbostock/raw/4063269/flare.json"
)

# let's have a look at the structure of flare.json
# listviewer htmlwidget might help us see what is happening
#   devtools::install_github("timelyportfolio/listviewer")
#   library(listviewer)
jsonedit(
  paste0(
    readLines("http://bl.ocks.org/mbostock/raw/4063269/flare.json")
    ,collapse=""
  )
)

# the interesting thing about Mike Bostock's Bubble Chart example
#   though is that the example removes the nested hierarchy
#    with a JavaScript function called classes
#// Returns a flattened hierarchy containing all leaf nodes under the root.
#function classes(root) {
#  var classes = [];
#  
#  function recurse(name, node) {
#    if (node.children) node.children.forEach(function(child) { recurse(node.name, child); });
#    else classes.push({packageName: name, className: node.name, value: node.size});
#  }
#  
#  recurse(null, root);
#  return {children: classes};
#}

# let's try to recreate this in R
classes <- function(root){
  classes <- data.frame()

  haschild <- function(node){
    (!is.null(node) && "children" %in% names(node))
  }

  recurse <- function(name,node){
    if(haschild(node)){
      lapply(
        1:length(node$children)
        ,function(n){
          recurse(node$name,node$children[[n]])
        }
      )
    } else {
      classes <<- bind_rows(
        classes,
        data.frame(
          "packageName"= name
          ,"className" = node[["name"]]
          ,"size" = node[["size"]]
          ,stringsAsFactors = F
        )
      )
    }
  }

  recurse(root$name,root)
  return(classes)
}

# now with a R flavor our class replica should work
flare_df <- classes(flare_json)


# so the example uses a data.frame with columns
#   packageName, className, size
# and feeds that to bubble.nodes where bubble = d3.layout.pack
# fortunately Joe Cheng has already made a htmlwidget called bubbles
#   https://github.com/jcheng5/bubbles
# that will produce a d3.layout.pack bubble chart

library(scales)

bubbles(
  flare_df$size
  ,flare_df$className
  ,color = col_factor(
    RColorBrewer::brewer.pal(9,"Set1")
    ,factor(flare_df$packageName)
  )(flare_df$packageName)
  ,height = 600
  ,width = 960
)

# it's not perfect with things such as text sizing
#    but it's a start