rstudio / r2d3 Goto Github PK
View Code? Open in Web Editor NEWR Interface to D3 Visualizations
Home Page: https://rstudio.github.io/r2d3
License: Other
R Interface to D3 Visualizations
Home Page: https://rstudio.github.io/r2d3
License: Other
If I understand correctly r2d3 D3 support up to 5.0.0
but suggests that the latest minor version is supported (see screenshot below). How would one go about supporting up to the actual latest minor release (5.9.1
at the time of this writing, see d3/releases)?
This would make r2d3 better as it could take advantage of the latest improvements. As an example, the very useful+convenient d3-selection.join is >= 5.8.0
.
I would be happy to help but I'm not sure how to implement this as I am not yet very familiar with the package. From my experiments It seems that simply adding/changing the minified source in www/inst/d3
doesn't cause an error but does cause the default d3 script to plot an empty svg.
I am working on some visualization using the r2d3 package and integrating the d3output on a Shiny Dashboard.
While I completed what I thought would be the difficult chunks of work, I am stuck at a rather trivial stage.
After generating the d3output, I am not able to restrict it inside a box within a dashboardPage - it is covering the complete width of the page (including sidebarPanel) and eclipsing the dashboard, while the box where it is declared to appear is displaying as an empty box.
Please let me know what I might be missing out on here. I have spent a lot of time on this but have not been able to crack this one.
Please find a snip of the dashboard to better understand the issue.
Here is how I'm writing the code:
library(shiny)
library(r2d3)
library(data.tree)
ui <- dashboardPage(
##========================== Dashboard Header ==========================##
dashboardHeader(title = 'R2D3 Dashboard',titleWidth = 280
# tags$li(class = "dropdown",
# tags$a(tags$img(height = "20px", alt="Logo", src="logo.png", background = "white")))
),
##========================== Side Panel (Filters & Selections) ==========================##
dashboardSidebar( width=280,
sidebarMenu(
menuItem(text=strong('Tree'),
newtab=FALSE,
icon=NULL,
tabName="tab_11",
startExpanded=TRUE
)
)
),
dashboardBody(
fluidPage(theme="style.css",
verticalLayout(
box(width=12,d3Output("d5"),value = TRUE)),
verticalLayout(
box(width=12,verbatimTextOutput("selected"),value = TRUE))
)
)
)
# ui <- dashboardPage(
# titlePanel("R2D3 sample"),
# sidebarLayout(
# sidebarPanel(),
# mainPanel(
# verbatimTextOutput("selected"),
# d3Output("d5")
# )
# )
# )
server <- function(input, output) {
output$d5 <- renderD3({
r2d3(
NULL,
script = "examples/tree.js", d3_version = 3,
dependencies = "style.css"
)
})
output$selected <- renderText({
input$bar_clicked
})
}
shinyApp(ui = ui, server = server)
Due to the confidential nature of the data, I can't share the supporting files. Pardon me for the partial content.
--
Thanks & Regards,
Apoorv Mehrotra
Hi
I would like to use the cola(R): https://github.com/timelyportfolio/colaR package to layout my force network like: http://ialab.it.monash.edu/webcola/examples/smallworldwithgroups.html
and then present the network using shiny. My app.R looks like this:
libs <- c("r2d3","jsonlite")
loaded <- sapply(libs, function(x){ library(x, character.only=TRUE) })
ui <- shinyUI(fluidPage(
useShinyjs(),
titlePanel(
"Network Browser"
),
mainPanel(
d3Output("d3")
)
))
server <- shinyServer(function(input, output,session) {
output$d3 <- renderD3({
r2d3(data = jsonlite::read_json("miserables.json"), d3_version = 4, script = "forcegraph.js")
})
})
shinyApp(ui = ui, server = server)
I have installed colaR and tried to add this part to the forcegraph.js:
var d3cola = cola.d3adaptor()
.linkDistance(120)
.avoidOverlaps(true)
.size([width, height]);
But it complains that
Error: cola is not defined in forcegraph.js#11:14
ReferenceError: cola is not defined
Any advice would be great, Thanks!
Hello,
Excellent work for this R2D3 library! I tried using the R code provided in the documentation in the Shiny section. However, I could not find the code for baranims.js
anywhere.
May I ask where can I find it?
Cheers,
Perth
Could data be passed back from the visualisation to an object in [R]?
For example. on this simple shiny app I'd ideally like to be able to populate a list in [R] based on nodes that are clicked. Currently, I have to do it via a checkbox list and clicking the nodes just calls a basic 'alert("You clicked " + d.name);'
.
Thanks for this awesome package.
Since there's no mention about how to make a crosstalk compatible package with r2d3::r2d3()
in the website, I'm wondering if it's possible to enable crosstalk inside r2d3()
instead of taking htmlwidgets
route. If possible, it would be great to have a section on how to make crosstalk compatible.
Thank you so much.
Use Case:
Typically, to write a re-usable charts, I have to assign id
's (or class
) to chart and it's elements to give users finer DOM manipulation control:
.attr("id", 'tag-point-' + chartElement.id + '-' + layer.label.replace(/\s+/g, '') )
This creates a whole set of points that can now be manipulated by downstream calls without manipulating the plot next door that has the same circle
objects with the same layer label - common when using re-usable charts.
I think a major motivation for using d3.js is the DOM manipulation (not just customized plots), so it's important that users have this ability. It only gets more complicated when users start using clip paths, gradients, and other defs
for their plots.
Feature Request:
I have used the el
to assign the chart id via htmlwidgets
that passes the output ID from Shiny, I'm not seeing a similar avenue here - though I may have just missed it. I would request that a chart id argument be added so that it may be used for assignment to DOM elements. A user should be able to use d3.select('#mychart')
to select their chart in the DOM.
JavaScript console output from r2d3
is rendered directly into the RStudio viewer visualization instead of the javascript console. See documentation.
This also seems to be the behavior when
r2d3::r2d3(..., viewer = 'browser')
I.e., the console.log()
does not output to the console even in the browser. But sometimes I'd like to inspect objects written to the browser console because they are not text.
Is there a clean way to change this behavior, for console.log()
information in an r2d3
D3.js to be sent to the browser console?
r2d3 Version : 0.2.2
R Version : 3.5.1
Use an R Markdown file to recreate the sample bubbles D3 example from the gallery at https://github.com/rstudio/r2d3/tree/master/vignettes/gallery/bubbles
flare.csv
file, same as in the example.d3
chunk in an R Markdown file in RStudio using the code from bubbles.js
:```{r setup, include=FALSE}
library(r2d3)
knitr::opts_chunk$set(echo=FALSE, comment=NA)
```
```{d3 (data = read.csv("flare.csv"), d3_version = 4}
[Insert code from bubbles.js here]
```
The following error occurs:
Error: Cannot read property 'split' of undefined
There is an issue in which the split
command may not handle missing fields in the CSV file. However, the JavaScript file handles these correctly:
bubbles.js
file in the same directory as the flares.csv
file.The D3 file is rendered correctly without an error. Since D3 handles the data correctly, r2d3 in a an R Markdown's d3
chunk should work as well.
I am sure you are aware of this, but there is not currently a license
Line 13 in d80b2e4
For reference the d3 license is https://github.com/d3/d3/blob/master/LICENSE, which says you need written consent to include d3 in the name of derivatives, so something to keep in mind before this is public.
I am using r2d3 with the RStudio IDE (Version 1.2.1335). Is there any way to see the contents of data files and arrays created by an r2d3 script?
Would like to have something equivalent to the R studio View capabilities, or something equivalent to the data inspection tools available with observablehq.
TIA
e.g. see this code: http://bl.ocks.org/Rokotyan/0556f8facbaf344507cdc45dc3622177
Im getting an error running the example from https://rstudio.github.io/r2d3/:
r2d3(data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), script = "barchart.js")
Error: barchart is not defined
ReferenceError: barchart is not defined
The above code was found straight from the docs. I did however have a r2d3 0.2 installed on a second computer. Running the following still works and displays the demo graph.
r2d3(data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), script = system.file("examples/barchart.js", package = "r2d3"))
I've developed this interactive D3 visualization, and would like now to bring it into the r2d3 fold before developing it further. My aim ultimately would be to include it as an htmlwidget
in an R package, and to deploy it within a Shiny app.
Generally preferring declarative programming and modular program structure whenever I can get away with it, I specified some of my app layout in the index.html
file (as shown below). Must I refactor the creation of these DIVs, etc. back into procedural Javascript code before proceeding? Or is there a (supported) way to ask r2d3 to use this index.html
file instead of its default?
This is my first D3 app, so I would also welcome guidance to the effect that what I've done below is bad form, not generally recommended, etc.
<!DOCTYPE html>
<html>
<head profile="http://www.w3.org/2005/10/profile">
<link rel="icon"
type="image/png"
href="faviconDTAT.png" />
<meta charset="utf-8">
<title>3+3/PC dose-titration design</title>
<style>
</style>
</head>
<div class="svg-container" id="ox-plot">
</div>
<div class="svg-container" id="ds-plot">
</div>
<div class="footer">
<dl><dt>Reference</dt>
<dd>Norris DC. Precautionary Coherence Unravels Dose Escalation Designs.
<i>bioRxiv</i>. December 2017:240846.
<a href="https://www.biorxiv.org/content/early/2017/12/29/240846">
doi:10.1101/240846
</a>
</dd>
</dl>
</div>
<body>
<script src="assets/bundle.js"></script>
</body>
</html>
Since currently only the svg
container reference is passed to the user if you want to switch over your visualization to canvas rendering instead you need to jump through a few hoops to append a canvas to the parent of the svg.
Would adding an option along the lines of r2d3(data = ..., canvas = TRUE)
which then instead of giving the user an svg object, gives them a canvas be within the goal of this project? Or is the idea that r2d3
is for more quick sketching of ideas which then can be implemented more formally with something like htmlwidgets
when they get more complicated?
I'm trying to hide the d3 code chunk in an RMarkdown document that I'm making. I've tried:
{d3 echo = FALSE}
and
d3 include = FALSE}
But neither work, as they would with R code chunks. The first shows the code as normal and the second hides it, but doesn't make the plot. Any tips?
I can't successfully load other .js libraries to my r2d3 plots.
Example:
library(r2d3)
sliderD3 <-
htmltools::htmlDependency(name = "d3-simple-slider", version = "1.5.4",
src = c(href = "https://unpkg.com/[email protected]/dist/"),
script = "d3-simple-slider.js")
r2d3(
data = c (0.3, 0.6, 0.8, 0.95, 0.40, 0.20),
script = "barchart.js",
dependencies = list(sliderD3)
)
barchart.js :
var barHeight = Math.floor(height / data.length);
svg.selectAll('rect')
.data(data)
.enter().append('rect')
.attr('width', function(d) { return d * width; })
.attr('height', barHeight)
.attr('y', function(d, i) { return i * barHeight; })
.attr('fill', 'steelblue');
d3.sliderBottom(); // this makes an error
I can find them in the sources but can't use the functions. Any ideas?
Examples : mouseover, mouseout, onclick, mousemove
After working around the data
issue reported in #4 , I still get the following error:
This is really more of an observation and not an issue. Frequently I combine canvas and svg in the same plot to get the performance of canvas and the interactivity of svg. How I do it is like this:
const container = d3.select(canvas.node().parentElement);
container.style('position', 'relative');
const svg = container.selectAppend('svg')
.st({
position: 'absolute',
bottom: div_padding_bottom,
left: div_padding_left,
width: width,
height: height
});
I noticed that when I updated to the new r2d3 version the shadow dom breaks this workflow. I see that there is an option to disable the shadow dom from 4081f1b but can't find documentation on how to use it. Is it around somewhere?
Thanks!
Hello,
Thanks for this awesome package.
I usually use R for spatial data analysis but I am not familiar with D3 scripts.
I wonder if it would be possible to include D3js: Hexbin in leaflet with r2d3?
If possible, it would be great to have a section depicting that case.
Best!
Damien
Hello,
This package looks awesome and it promises to solve a lot of my pains with including customs d3 scripts in Rmarkdown, so thanks for the work on this!
I have a question on whether you plan to include higher level R bindings for d3 visuals in the package. If I understand it correctly now the package allows one to include a js d3 script seamlessly in R markdown/shiny, however one still needs to code the visual in d3 itself, which is not that easy for beginners. I thought it would be awesome to provide higher level R bindings to the d3 API so that plots can be done entirely in R, e.g. in the context of htmlwidgets.
Any plans on moving in this direction? If not, I might take up this challenge myself, if you think it would add value.
Best!
Riccardo.
I have some D3 code running from R (which creates and then provides the data to D3 using the data parameter) via R2D3 and its mostly working, but I need to use the browser console to understand what is happening with certain variables within the D3 element.
I can see the instructions below which show how to preview the D3 code from within Rstudio and a browser but the data passed is very simple, i.e.
// !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20)
https://rstudio.github.io/r2d3/articles/development_and_debugging.html
How do I run a more full R script to collate the data and import libraries (that are then referred to in dependencies) and then use R2D3 in such a way that I can use the browser debugger in a way similar to how the very simple example does.
I am attempting to replicate a simple scatter plot, based on this code:
http://bl.ocks.org/WilliamQLiu/803b712a4d6efbf7bdb4
I have updated the code to V5 (i.e., replaced d3.scale.linear with d3.scaleLinear, etc.)
I have converted my data from an R data frame to a JSON, eg:
[[0.100, 2.905],[-3.249, 0.550],[1.050, 3.222],[-0.059, -0.537],[-1.089, -0.990],[-2.614, -0.049],[1.168, 1.275],[2.130, 0.176],[0.681, -0.762],[0.275, -0.601], ...];
The code runs, but the circles are off of
I think my circles are in the upper left-hand corner of the plot.
My question is how do I scale this plot (and scale svgs generally) so I can see
the plotted items?
I have attached the r2d3 code I used.
TIA
AB
Right now if you append data at the 0 or width/height
points they will get cut off....
// !preview r2d3 data=NULL
//
// r2d3: https://rstudio.github.io/r2d3
//
svg.append('circle')
.attr('r', 50)
.attr('cx', 0)
.attr('cy', height)
.attr('fill', 'orangered');
Would making the svg
be a reference to a g
that has been inset...
const pagePadding = 10; //user supplied with options?
const svg = d3.select('svg')
.append('g')
.attr('transform', 'translate(' + pagePadding + ',' + pagePadding + ')');
...and then the provided height
and width
are the height and width of the inset g
...
const height = containerHeight - pagePadding*2;
const width = containerWidth - pagePadding*2;
Be something that would be considered? I could understand if it's a little too 'hands-on' with what the user is being given. Maybe an option to enable it? Personally I always do something like this whenever I make a d3 visualization.
Would turn code like this
const x = d3.scaleLinear()
.domain(d3.extent(data, d => d))
.range([margin.left, width-margin.right]);
to the (i think easier to reason about)
const x = d3.scaleLinear()
.domain(d3.extent(data, d => d))
.range([0, width]);
BTW, I love the little console popup for viewing logs.
I don't seem to be getting this right:
code:
R file:
`f =' {
"name": "aaaa",
"children": [
{
"name": "bbbb",
"children": [
{
"name": "cccc",
"children": [
{
"name": "dddd",
}
]
}
]
}
]
} '
r2d3(data=f, script = "learn_plot.js")`
learn_plot.js
`var treeData = data;
// set the dimensions and margins of the diagram
var margin = {top: 40, right: 90, bottom: 50, left: 90},
width = 660 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// declares a tree layout and assigns the size
var treemap = d3.tree()
.size([width, height]);
// assigns the data to a hierarchy using parent-child relationships
var nodes = d3.hierarchy(treeData);
// maps the node data to the tree layout
nodes = treemap(nodes);
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom),
g = svg.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// adds the links between the nodes
var link = g.selectAll(".link")
.data( nodes.descendants().slice(1))
.enter().append("path")
.attr("class", "link")
.attr("d", function(d) {
return "M" + d.x + "," + d.y
+ "C" + d.x + "," + (d.y + d.parent.y) / 2
+ " " + d.parent.x + "," + (d.y + d.parent.y) / 2
+ " " + d.parent.x + "," + d.parent.y;
});
// adds each node as a group
var node = g.selectAll(".node")
.data(nodes.descendants())
.enter().append("g")
.attr("class", function(d) {
return "node" +
(d.children ? " node--internal" : " node--leaf"); })
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; });
// adds the circle to the node
node.append("circle")
.attr("r", 10);
// adds the text to the node
node.append("text")
.attr("dy", ".35em")
.attr("y", function(d) { return d.children ? -20 : 20; })
.style("text-anchor", "middle")
.text(function(d) { return d.data.name; });`
any help?
I simply don't see any plot, and I don't know what is going on... Just a flashing plot screen in rstudio.
I installed v1.2 preview server.
Hi,
I am new to programming.
I was trying to run the example given on https://rstudio.github.io/r2d3/articles/gallery/bubbles/
i have placed the files given in https://github.com/rstudio/r2d3/tree/master/vignettes/gallery/bubbles in a folder and set the working directory
now when running the code: r2d3(data = read.csv("flare.csv"), d3_version = 4, script = "bubbles.js")
there is no output and no error displayed.
pls help.
Reason:
Output does not update when the slider is moved.
Session info:
> sessioninfo::session_info()
โ Session info โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
setting value
version R version 3.4.4 (2018-03-15)
os Ubuntu 16.04.5 LTS
system x86_64, linux-gnu
ui RStudio
language (EN)
collate en_US.UTF-8
tz Etc/UTC
date 2018-11-26
โ Packages โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
package * version date source
clisymbols 1.2.0 2017-05-21 CRAN (R 3.4.4)
digest 0.6.18 2018-10-10 cran (@0.6.18)
htmltools 0.3.6 2017-04-28 CRAN (R 3.4.4)
htmlwidgets 1.2 2018-04-19 CRAN (R 3.4.4)
httpuv 1.4.5 2018-07-19 CRAN (R 3.4.4)
jsonlite 1.5 2017-06-01 CRAN (R 3.2.3)
knitr 1.20 2018-02-20 CRAN (R 3.4.4)
later 0.7.5 2018-09-18 CRAN (R 3.4.4)
magrittr 1.5 2014-11-22 CRAN (R 3.2.3)
mime 0.5 2016-07-07 CRAN (R 3.2.3)
packrat 0.4.8-1 2016-09-07 CRAN (R 3.4.3)
promises 1.0.1 2018-04-13 CRAN (R 3.4.4)
r2d3 * 0.2.2 2018-05-30 CRAN (R 3.4.4)
R6 2.3.0 2018-10-04 cran (@2.3.0)
Rcpp 0.12.18 2018-07-23 CRAN (R 3.4.4)
rlang 0.3.0.1 2018-10-25 cran (@0.3.0.1)
rsconnect 0.8.8 2018-03-09 CRAN (R 3.4.4)
rstudioapi 0.7 2017-09-07 CRAN (R 3.4.4)
sessioninfo 1.0.0 2017-06-21 CRAN (R 3.4.4)
shiny * 1.2.0 2018-11-02 CRAN (R 3.4.4)
withr 2.1.2 2018-03-15 cran (@2.1.2)
xtable 1.8-2 2016-02-05 CRAN (R 3.4.4)
yaml 2.1.14 2016-11-12 CRAN (R 3.2.3)
Program (example from https://rstudio.github.io/r2d3/articles/shiny.html):
library(shiny)
library(r2d3)
ui <- fluidPage(
inputPanel(
sliderInput("bar_max", label = "Max:",
min = 10, max = 110, value = 10, step = 20)
),
d3Output("d3")
)
server <- function(input, output) {
output$d3 <- renderD3({
print(sprintf("slider value: %s", input$bar_max))
r2d3(
floor(runif(5, 5, input$bar_max)),
script = system.file("examples/baranims.js", package = "r2d3")
)
})
}
shinyApp(ui = ui, server = server)
Tested with:
Internal viewer
Google Chrome Version 70.0.3538.102 (Official Build) (64-bit)
Safari Version 12.0.1 (14606.2.104.1.1)
Debug:
Listening on http://127.0.0.1:3021
[1] "slider value: 10"
[1] "slider value: 70"
I would like to make a conda package for the r2d3 package.
According to this issue on GitHub, the repo of interest, r2d3 in this case, must have at least one release tag.
Here is the output of conda skeleton cran https://github.com/rstudio/r2d3
:
conda skeleton cran https://github.com/rstudio/r2d3
Tip: install CacheControl and lockfile (conda packages) to cache the CRAN metadata
Fetching metadata from https://cran.r-project.org/
Parsing input package https://github.com/rstudio/r2d3:
.. name: r2d3 location: https://github.com/rstudio/r2d3 new_location: /Users/amasonsingh/r-r2d3
Making/refreshing recipe for r2d3
Cloning into '/anaconda3/conda-bld/skeleton_1526498646711/work'...
done.
checkout: 'HEAD'
Your branch is up to date with 'origin/_conda_cache_origin_head'.
==> git log -n1 <==
fatal: No names found, cannot describe anything.
commit 0f4f58ab92869bb525cef4a31e0d5a78bd028e88
Author: jjallaire <[email protected]>
Date: Wed May 16 07:48:51 2018 -0400
remove sourceMappingURL for webcomponents-bundle.js
==> git describe --tags --dirty <==
commit 0f4f58ab92869bb525cef4a31e0d5a78bd028e88
Author: jjallaire <[email protected]>
Date: Wed May 16 07:48:51 2018 -0400
remove sourceMappingURL for webcomponents-bundle.js
==> git status <==
On branch _conda_cache_origin_head
Your branch is up to date with 'origin/_conda_cache_origin_head'.
nothing to commit, working tree clean
Leaving build/test directories:
Work: /anaconda3/conda-bld/skeleton_1526498646711/work
Test: /anaconda3/conda-bld/skeleton_1526498646711/test_tmp
Leaving build/test environments:
Test: source activate /anaconda3/conda-bld/skeleton_1526498646711/_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_p
Build: source activate /anaconda3/conda-bld/skeleton_1526498646711/_build_env
Error: no tags found
r2d3 Version : 0.2.2
R Version : 3.5.1
Use an R Markdown file to execute the sample bubbles D3 example from the gallery at https://github.com/rstudio/r2d3/tree/master/vignettes/gallery/bubbles
flare.csv
file, same as in the example.d3
chunk in an R Markdown file in RStudio that executes bubbles.js
:```{r setup, include=FALSE}
library(r2d3)
knitr::opts_chunk$set(echo=FALSE, comment=NA)
```
```{d3 data = read.csv("flare.csv"), d3_version = 4, script = "bubbles.js"}
```
The following error occurs:
d3
chunk, such as an r
chunk with plot(cars)
, will make this clear.The D3 portion should be displayed correctly. Compare this to the independent D3 JavaScript file:
bubbles.js
file in the same directory as the flares.csv
file.The D3 file is rendered correctly, including the bubbles image.
Note: If calling a file is not supported, then this should error out instead of displaying blank region or nothing.
Compare highlighting here:
To highlighting here:
If you haven't previously worked with Ace highlighting modes you should definitely consult @jmcphers before attempting to remedy this!
r2d3 looks really interesting. I'm curious if Rstudio is perhaps planning a REPL for javascript, similar to the REPL for python in reticulate?
theme.background
and theme.foreground
no longer supported in rstudioapi
and therefore, plots do not set the right color while run inside RStudio.
Actual:
Expected:
This would need support for background/foreground to be supported again in RStudio: rstudio/rstudio#4055
for the new beginner who is not familiar with d3.js, are there more r2d3 script examples like the basic chart as line, bar, area. etc. Since I still have difficulty to translate d3.js to r2d3 script which can be used in R
Hello,
First of all, thank you for creating R2D3!
I have an issue with the CSS styling in a r2d3 call affecting the entire HTML output of my R Markdown file. For example, I wrapped a r3d3 function and included it in my own package. When I created the vignette for my pkgdown site, the HTML output for that vignette uses the fonts in the CSS style embedded in the r2d3 call. (See https://usstudiescentre.github.io/ussc/articles/rollcall.html for an explanation of what I mean. The rest of the website uses the standard pkgdown CSS style.) I don't want this to happen. I'd like to contain the CSS style in the r2d3 call to that particular code chunk. Is this possible?
Thanks.
Hi all,
first of, thanks! r2d3 is amazing and inspired me to my first attempts at d3.js: a line graph with draggable points. Now I am trying to incorporate this in a shiny where users can modify various settings. However: it seems that every input made through the shiny inputs results in a new instance of the d3.js plot.... initially I "hackslved' this by giving the plot on opaque background but soon came to realize that all the 'former' instances of the d3.js remain active (and start throwing warnings when the number of pp (input$npp) is changed, because the new data does not fit the old instance's datastructure, which of course eventually leads to clogged up memory.
So: is there a way to reset/reinitialize/shutdownandrestart the d3.js (and its datastructure) within a shiny session?
Many thanks in advance!
Shiny code:
library(shiny)
library(r2d3)
library(data.table)
# Define UI for application that shows the D3 plot and returns the updated correlation:
ui <- fluidPage(
titlePanel(""),
sidebarLayout(
sidebarPanel(style = "background-color: #ffffff; border-color: gray92 ; border-width: 2px", width = 3,
numericInput("npp",
"number of 'participants'",
value = 8),
numericInput("meanBI",
"mean bias'",
value = 20),
numericInput("sdBI",
"sd bias'",
value = 0),
numericInput("meanRT",
"mean response times'",
value = 20),
numericInput("sdRT",
"sd response times'",
value = 10)
),
mainPanel(
fluidRow(
h3("corr:"),
verbatimTextOutput("corrComputed")),
fluidRow(
d3Output("d3"),
h4("drag the dots..."))
)))
# Define server
server <- function(input, output, session) {
observeEvent(input$npp, {
## I guess that here I need some statement that results in resetting the d3.js
## simply removing all datastructures (dfw, df, and dataD3Adjusted) doesn't do the trick.
})
observeEvent(c(input$npp, input$meanBI, input$sdBI, input$meanRT, input$sdRT), {
npp <<- input$npp
meanBI <- input$meanBI
sdBI <- input$sdBI
meanRT <- input$meanRT
sdRT <- input$sdRT
df <- data.table(ID = seq(1,npp),
BI = rnorm(npp, meanBI, sdBI) )
df$IT = rnorm(npp, meanRT, sdRT) + .5*df$BI
df$CT = df$IT - df$BI
dfw <- melt(df, id.vars = c("ID", "BI"), variable.name = "trialtype", value.name = "RT")
dfw$tt <- as.numeric(dfw$trialtype)
output$corrComputed <- renderText({
cor(dfw$RT [dfw$trialtype == "IT"], dfw$RT [dfw$trialtype == "CT"])
})
output$d3 <- renderD3({
r2d3(data=dfw, d3_version = 4, script = "dragmultilinechart.js")
})
observeEvent(input$dataD3Adjusted, {
dataD3Adjusted <<- input$dataD3Adjusted
dfw$RT <- as.numeric(dataD3Adjusted [names(dataD3Adjusted) == "RT"])
output$corrComputed <- renderText({
cor(dfw$RT [dfw$trialtype == "IT"], dfw$RT [dfw$trialtype == "CT"])
})
})
})
}
# Run the application
shinyApp(ui = ui, server = server)
and the js:
// !preview r2d3 data= data.frame(ID = c(1,1,2,2,3,3,4,4,5,5), tt = c(1, 2, 1, 2, 1, 2, 1, 2, 1, 2), RT = c(14.4, 19.3, 22.0, 27.0, 20.7, 25.74, 16.9, 21.9, 18.6, 23.6))
// svg.append("rect")
// .attr("width", "100%")
// .attr("height", "100%")
// .attr("fill", "white");
var dById = d3.nest()
.key(function(d) {
return d.ID;
})
.entries(data);
var margin = {
top: 40,
right: 40,
bottom: 40,
left: 40
},
width = 450 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var color = d3.scaleOrdinal()
.range(["#a6cee3", "#1f78b4", "#b2df8a", "#33a02c", "#fb9a99"]);
var x = d3.scaleLinear()
.range([0.25 * width, 0.75 * width])
.domain([1, 2]);
// I think that a continuous scale is required for the drag to work, but
// add a second ordinal x axis scale to show instead of the linear one:
var xOrd = d3.scaleOrdinal()
.range([0.25 * width, 0.75 * width])
.domain(["IT", "CT"]);
var yrange = d3.max(data, function(d) {return d.RT;}) - d3.min(data, function(d) {return d.RT;});
var y = d3.scaleLinear()
.rangeRound([height, 0])
.domain([d3.min(data, function(d) {return d.RT;}) - 0.3*yrange, d3.max(data, function(d) {return d.RT;}) + 0.3 *yrange ]);
var xAxis = d3.axisBottom(xOrd), // use the Ordinal x scale
yAxis = d3.axisLeft(y);
// Define the line by data variables
var connectLine = d3.line()
.x(function(d) {
return x(d.tt);
})
.y(function(d) {
return y(d.RT);
});
svg.append('rect')
.attr('class', 'zoom')
.attr('cursor', 'move')
.attr('fill', 'none')
.attr('pointer-events', 'all')
.attr('width', width)
.attr('height', height)
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var focus = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
focus.selectAll('lines')
.data(dById)
.enter().append("path")
.attr("class", "line")
.attr("d", function(d) {
return connectLine(d.values);
})
.attr("stroke", function(d) {
return color(d.key);
})
.attr('stroke-width', 4);
focus.selectAll('circles')
.data(dById)
.enter().append("g")
.attr("class", "dots")
.selectAll("circle")
.data(function(d) {
return d.values;
})
.enter().append("circle")
.attr("cx", function(d) {
return x(d.tt);
})
.attr("cy", function(d) {
return y(d.RT);
})
.attr("r", 6)
.style('cursor', 'pointer')
.attr("fill", function(d) {
return color(d.ID);
})
.attr("stroke", function(d) {
return color(d.ID);
});
focus.append('g')
.attr('class', 'axis axis--x')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
focus.append('g')
.attr('class', 'axis axis--y')
.call(yAxis);
/// drag stuff:
let drag = d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended);
focus.selectAll('circle')
.call(drag);
// focus.selectAll('line')
// .call(drag);
function dragstarted(d) {
d3.select(this).raise().classed('active', true);
}
function dragged(d) {
dragNewY = y.invert(d3.event.y);
d.RT = dragNewY;
d3.select(this)
.attr('cx', d => x(d.tt))
.attr('cy', d => y(d.RT));
focus.selectAll('path').attr("d", function(d) {
return connectLine(d.values);
});
}
function dragended(d) {
Shiny.setInputValue(
"dataD3Adjusted",
//dById,
data,
{priority: "event"}
);
d3.select(this).classed('active', false);
//.attr("d", function(d) {return d; });
}
Many functions that require a file input also accept some sort of a text
argument. For real production use this won't be recommended, but for making quick little scripts, for reproducibility (sharing a single code chunk online for example), for doing testing, for many little tasks it's useful to be able to do this.
I'm envisioning something like this:
my_r3_code <- "
// !preview r2d3 data=c(0.3, 0.6, 3, 0.95, 0.40, 0.20), width=600
var barHeight = Math.ceil(height / data.length);
svg.selectAll('rect')
.data(data)
.enter().append('rect')
.attr('width', function(d) { return d * width; })
.attr('height', barHeight)
.attr('y', function(d, i) { return i * barHeight; })
.attr('fill', 'steelblue');
"
r2d3(data = c(0.3, 0.6, 0.8, 0.95, 0.40), text = my_r3_code)
Now this can be ran and/or shared as one piece of code rather than mandating the creation of a separate file and saving it to disk and then coordinating finding its path.
I believe that this could be considered a bug but perhaps I'm just not understanding the way the callbacks should be used. Basically what happens is if you add both the resize method r2d3.onResize()
and also a render method r2d3.onRender()
and you have resized the viz then the next time you send new data that triggers onRender()
it returns the old width
, and height
variables to its callback function.
Here's a gif of what I'm describing
Here's a shiny app that demos what I'm talking about in as little code as I could.
app.R
library(shiny)
ui <- fluidPage(
h3('To recreate bug'),
tags$ul(
tags$li('Note the size of viz provided by onRender()'),
tags$li('Resize the app and note the new size reported by onResize()'),
tags$li('Next press refresh button below. The size is not the new resized size, but the original onRender() size.')
),
actionButton('refresh', 'Refresh Viz'),
mainPanel( r2d3::d3Output("d3") )
)
server <- function(input, output) {
output$d3 <- r2d3::renderD3({
input$refresh
r2d3::r2d3(container = 'div', script = "testing_bug.js")
})
}
shinyApp(ui = ui, server = server)
And here's the r2d3 script:
testing_bug.js
const displayed_text = div.append('h2');
r2d3.onRender(function(data, svg, width, height, options){
displayed_text.text(`onRender: Width: ${width}, Height: ${height}`);
});
r2d3.onResize(function(width, height){
displayed_text.text(`onResize: Width: ${width}, Height: ${height}`);
});
Feel free to let me know if you need more info or if you have an idea of where I would dig to attempt to fix this myself.
Thanks!
Hi, I've run into an issue that r2d3 seems to be acting quite differently on Windows versus Macs. I am trying to render a specific set of r2d3 visualizations in a Shiny app, one of them being a Sankey diagram (in my example code, attached, this is particularly simple, with 1 link and 2 nodes).
On Windows, this visualization appears perfectly in Shiny in an external window (Firefox/Chrome):
However, when running the same Shiny app on a Mac, nothing appears. Looking at the developer console, the error "TypeError: data.charCodeAt is not a function" appears, which seems to be from the r2d3-render.js script.
Is there any reason why this would be the case, and how would I fix it? The R code can be found below, and supporting JavaScript files can be found here.
r2d3 version: 0.2.3
Windows 10, Firefox v68.0, Chrome v75.0.3770.142
macOS Sierra v10.12.6, Firefox v67.0.2
#https://stackoverflow.com/questions/3452086/getting-path-of-an-r-script/35842176#35842176
# set working directory - only works in RStudio (with rstudioapi)
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
library(r2d3)
library(shiny)
data_to_json <- function(data) {
jsonlite::toJSON(data, dataframe = "rows", auto_unbox = FALSE, rownames = TRUE, digits = NA)
}
all_sig <- data.frame("name" = c("biol_process", "cell_proc"),
"go_name" = c("go1","go2"),
"sig" = c(1,.0303),
"is_sig"=c(F,T),
stringsAsFactors = F)
dat_sankey <- list(
"nodes" = data.frame("name"=c("biol_process", "cell_proc"), stringsAsFactors = F),
"links" = data.frame("source"=0,"target"=1,"value"=1)
)
rownames(dat_sankey$links) <- "biol_process"
sig_color <- "#B354B7"
no_sig_color <- "#afb1b5"
font_size <- 16
textcol_bg <- "#000000"
togg_border <- T
ui <- fluidPage(
d3Output("d3")
)
server <- function(input, output) {
output$d3 <- renderD3({
r2d3(data = data_to_json(dat_sankey), script = "js_scripts\\all_tabs.js",
d3_version = 5,
dependencies = c("js_scripts\\sankey\\d3-sankey.js",
"js_scripts\\sankey\\d3-sankey.min.js"),
options = list("all_sig"=all_sig,
"sig_color"=unname(sig_color),
"no_sig_color"=no_sig_color,
"font_size" = font_size,
"which_camp" = "ont_map",
textcol_bg = textcol_bg,
togg_border = togg_border
))
})
}
shinyApp(ui, server)
I have been trying out the r2d3 examples. But it seems any examples that have the r2d3.onRender is the .js file does not show any colour above the base layer.
For example, in the calendar example, all I get is the calendar but no colour. Please provide some pointers. Thanks!
I have used this code
library(r2d3) r2d3(data = jsonlite::read_json("flare.json"), d3_version = 4, script = "circlepacking.js")
But the image generated is static and I cannot zoom into circles individually
Is there any possibility of using imported fonts with r2d3? I tried many ways and it is always Arial that renders at the end.
Can we add jsonlite::toJSON(x)
there? or am i missing the point of this function.
I'm wondering if there are any plans to continue supporting this package and implementing D3 6.0? (It is beyond my abilities to do this myself, otherwise I would give it a shot and submit a pull request.)
Does r2d3 support the production of visualizations which require more than one dataset? e.g. force graphs, which require nodes and links. The package appears to only accept one entry into the data argument, which must always be referred to as "data" in the .js script, e.g.
svg.selectAll("circle.nodes")
.data(data)
.enter()
.append("svg:circle")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", "10px")
.attr("fill", "black")
I have tried various means of creating a nested dataset, which I can then call in the .js script, and even filtering the data within the .js script; this works if I write an html file, but not in R using the r2d3 command.
If r2d3 does support the production of visualizations which require more than one dataset, please can you provide an example in the gallery, such as the forcegraph, that actually converts r dataframes, rather than reading in pre-existing .json files?
When I add multiple dependences, I get the error below. Can I check I am adding them in the correct way (in a list and with full URLs)? See here for more info.
r2d3(data = station_readings_simple, script = "bbmapchartr2d3.js",
dependencies = list("https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js",
"https://d19vzq90twjlae.cloudfront.net/leaflet-0.7/leaflet.js",
"https://d3js.org/d3.v4.js",
"https://cdn.jsdelivr.net/gh/holtzy/D3-graph-gallery@master/LIB/d3-scale-radial.js",
"https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.7.1/d3-tip.min.js",
"https://d19vzq90twjlae.cloudfront.net/leaflet-0.7/leaflet.js"))
Uncaught TypeError: data.charCodeAt is not a function
at simpleHash (127.0.0.1/:1109)
at R2D3.self.addScript (127.0.0.1/:1120)
at R2D3.self.widgetRender (127.0.0.1/:1271)
at Object.renderValue (127.0.0.1/:1844)
at Object.renderValue (127.0.0.1/:961)
at 127.0.0.1/:728
at Array.forEach (<anonymous>)
at forEach (127.0.0.1/:130)
at 127.0.0.1/:651
at Array.forEach (<anonymous>)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.