christophergandrud / christophergandrud/networkD3

allow for custom CSS and/or JavaScript

Open
#197 4 comments 0 reactions 0 assignees View on GitHub
enhancement feature request
Dominant language
R
Stars
659
Forks
259
PR merge metrics
No merged PRs in 30d

Description

Many of the questions or requests I see about `networkD3` here and on stackoverflow etc. involve some desire to stylize the output beyond the existing parameters available. The more inventive suggestions/answers tend to suggest injecting JavaScript through the `linkDistance` or `clickAction` argument, which often works, but is definitely not how it was intended to work, not ideal, and probably liable to muck something up eventually. The alternative, adding more and more parameters to the functions for every imaginable type of stylization, is not ideal either.

I propose facilitating a way for the user to pass custom CSS and/or JavaScript when calling the `networkD3` functions. This would allow near limitless stylization without inflating the argument list with a bunch of new parameters.

There is a way to do this, suggested by @timelyportfolio on [stackoverflow](http://stackoverflow.com/a/36255290/4389763), with the `htmltools` package. That would require moving `htmltools` from `Suggests` to `Imports`, and it may impact how it shows up in RMarkdown, Shiny, etc.. Otherwise, I'd be happy to hear any suggestions on how to inject custom CSS into a htmlwidget using the `htmlwidgets` package... I think it might be possible by writing a temp CSS file and adding it as a dependency, but it would probably be much more preferable to be able to simply pass it as a character vector.

For example, the `forceNetwork` function could accept an argument `css` and the end of the function could be modified to something like...
```r
widget <- htmlwidgets::createWidget(
name = "forceNetwork",
x = list(links = LinksDF, nodes = NodesDF, options = options),
width = width,
height = height,
htmlwidgets::sizingPolicy(padding = 10, browser.fill = TRUE),
package = "networkD3"
)

htmltools::browsable(
htmltools::tagList(
htmltools::tags$head(
htmltools::tags$style(css)
),
widget
)
)
```
then a user would be able to do something like this...
```r
extracss <- "
body{background-color: #DAE3F9 !important}
.nodetext{fill: #000000}
.legend text{fill: #FF0000}
"

forceNetwork(Links = MisLinks, Nodes = MisNodes, Source = "source",
Target = "target", Value = "value", NodeID = "name",
Group = "group", css = extracss)
```
If this is implemented, it would make sense to also...
1. make sure that all the elements created by the JavaScript are logically classed and or id'ed
2. document that somewhere in the help files so that users can easily figure out how to target certain elements with CSS

JavaScript injection would be a bit more complicated, but could allow, theoretically, the user to add more interaction than just the `clickAction`, among other things.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.