timelyportfolio / sunburstR

R htmlwidget for interactive sunburst plots
http://timelyportfolio.github.io/sunburstR/articles/sunburst-2-0-0.html
Other
210 stars 124 forks source link

sunburst d2b & d3tree treemap fail to render together in shiny #102

Open ari-nz opened 4 years ago

ari-nz commented 4 years ago

Hi Kent,

Thanks for the excellent packages. I hope this is the right place to put this. I've come across an oddity using both d3treeR and this sunburst package together in a shiny app. The treemap renders, but not the sunburst chart.

Running either individually works successfully, just not together, where one widget loads, but not the other. A simple example below.

library(shiny)
library(sunburstR)
library(d3treeR)
library(treemap)

data(GNI2014)

# Prep Data
tm <-  treemap(
  GNI2014,
  index=c("continent", "iso3"),
  vSize="population",
  vColor="GNI",
  type="value",
  draw = FALSE
)

d3t = d3tree2( tm,rootname = "World" )

sd2b = sunburstR::sund2b(
  d3r::d3_nest(tm$tm, value_cols = colnames(tm$tm)[-c(1:2)]),
  colors = htmlwidgets::JS(
    "function(name, d){return d.color || '#ccc';}"
  ),
  valueField = "vSize"
)

# Start of shiny app

ui <- fluidPage(

  sunburstR::sund2bOutput('sun'),
  d3treeR::d3tree2Output('tree'),

  NULL
)

server <- function(input, output, session) {

  output$tree = d3treeR::renderD3tree2({
    d3t
  })

  output$sun = sunburstR::renderSund2b({
    sunburstR::add_shiny(sd2b)
  })

}

shinyApp(ui, server)

The app fails to load the sunburst in the top of the app. Note the white space. image

When running both widgets together I'm getting these errors in the JS console.

image

Any thoughts on how to resolve? If you have any thoughts on where to start looking I can investigate further.

timelyportfolio commented 4 years ago

@ari-nz Unfortunately this is a longstanding and difficult to solve issue with conflicting versions of d3 operating in the same global space both trying to use the variable d3. I intentionally rewrote sunburst as a standalone to avoid this as long as includeD3=TRUE is not used #40. Really, the only solution is a rewrite of d3treeR to the the newer d3 version. I like d3treeR but the community has not demonstrated or expressed the same love/interest, so I have not had the motivation to upgrade https://github.com/d3treeR/d3treeR/issues/37. The other option is to do a custom build of d2b with d3 included, but hard for me to justify the time since d3v4 was released in 2016. sund2b relies upon a proper version of d3 in window.d3.

I'll include this in case anyone is interested in the d3v4 changes https://iros.github.io/d3-v4-whats-new/#1.

ari-nz commented 4 years ago

My knowledge of JS is pretty haphazard, but for future would setting the namespaces on the d3 variable possibly hep remedy this to some extent for future conflicts?

image

(Granted, it would still require a re-write to the newer version of D3)

timelyportfolio commented 4 years ago

@ari-nz your suggestion is correct, and this is the strategy that we use in sunburstR sunburst. sund2b is based off d2b, which was not written by me, requires d3 in global/window. I could write a wrapper, but at this point with d3 > v4 out for this long, I'd prefer to leave as is so I don't have to rebuild d2b every time. Also, rolling up d3 into the library can significantly increase the build size and results in a lot of potential duplication.

Regarding d3treeR, unfortunately d3v3 was not written in the same modular way, so that we cannot pursue this approach unless as you say we rewrite d3treeR which I am not inclined to do because of lack of interest and/or volunteers. d3-hierachy was one of the portions of d3 with the most changes (all very good ones), so the port is a little intricate.