I try to create shiny app with
rpivotTable and nvd3 rcharts
all works , but when i try to to show any chart from pivot
i get error
An error occurred rendering the PivotTable results.
But if i use only rpivotTable charts works in pivot and i think that there is problem when using rpivotTable and nvd3 rcharts in one shiny app.
Example
UI
library(shiny)
library(rCharts)
library(rpivotTable)
shinyUI(fluidPage(
showOutput('plot1',lib = "nvd3"),
rpivotTableOutput('pivot1', width = "100%", height = "500px"))
)
Server
library(shiny)
library(rCharts)
library(rpivotTable)
df=data.frame(A=c(1:10),B=c(-10:-1),C=c("x",rep(c("x","y","z"),3)))
shinyServer(function(input, output, session) {
output$pivot1 <- renderRpivotTable({
rpivotTable(data =df ,
width="100%", height="500px")
})
output$plot1=renderChart2({
myform <- as.formula(paste('A','~','B'))
n2 <- nPlot(myform, group ="C", data = df, type = 'multiBarChart')
n2$chart(margin = list(left = 100))
n2$chart(reduceXTicks = F)
n2$set(width = 800, height = 500)
print(n2)
})
})
Give me
If i use only rpivotTable charts in pivot works
When i look at inspect i see
TypeError: a.axisTimeFormat.multi is not a function
at e.i.initParams (c3.min.js:1)
at e.i.init (c3.min.js:1)
at new d (c3.min.js:1)
at Object.k.generate (c3.min.js:1)
at Object.renderer (c3_renderers.coffee:129)
at t.fn.pivot (pivot.coffee:546)
at pivot.coffee:835
Is there way to fix it?
Package versions :
rpivotTable_0.1.5.7
rCharts_0.4.2
shiny_0.12.2.9005
Thanks!
As pointed out in the comments, this is due to the double loading of the n3 libraries. To avoid this issue (this is more of a hack than a fix), you could plot the rcharts frame in an iframe to avoid js and css issues.
To do this, you can use uiOutput/renderUI for the shiny part, and show to output the rCharts.
Here's an example:
library(shiny)
library(rCharts)
library(rpivotTable)
df=data.frame(A=c(1:10),B=c(-10:-1),C=c("x",rep(c("x","y","z"),3)))
ui <-shinyUI(fluidPage(
uiOutput('plot1'),
rpivotTableOutput('pivot1')
))
server <- shinyServer(function(input, output, session) {
output$pivot1 <- renderRpivotTable({
rpivotTable(data =df)
})
output$plot1=renderUI({
myform <- as.formula(paste('A','~','B'))
n2 <- nPlot(myform, group ="C", data = df, type = 'multiBarChart')
n2$chart(margin = list(left = 100))
n2$chart(reduceXTicks = F)
HTML(paste(capture.output(n2$show('iframesrc', cdn = TRUE)), collapse = '\n'))
})
})
shinyApp(ui,server)
Related
Hello This chart bellow is a part of my dashboard but its making the dashboard have a bad performance.
It takes time do update.
Is there any alternative to the functions htmlOutput()+ renderUI() ?
How can I improve the performance? Is it the case to create and generate the charts outside the server?
library(shiny)
library(highcharter)
library(tidyverse)
df <-tibble(months = month.abb, value = ts(cumsum(rnorm(100)))[1:12] )
ui <- fluidPage(
h1("Highcharts"),
htmlOutput('chart_grid')
)
server <- function(input, output, session) {
output$chart_grid<- renderUI({
charts <- lapply(1:9, function(x) {
highchart() %>%
hc_add_series(type = 'spline',data = df, hcaes(x = months,y = value))%>%
hc_xAxis(categories = df$months)
})
hw_grid(charts, rowheight = 300,add_htmlgrid_css = TRUE)%>%
htmltools::browsable()
})
}
shinyApp(ui, server)
TL;DR highcharts JS boost module for many data points, static HTML for a plot if there is one or a few plot versions, own grid and highcharter::highchartOutput
Static HTML
Strategy is to create the needed plot before the shiny app is started, but we have to assume that the plot have one or a few versions as a huge collection of html's could be a wrong direction too.
Usually we are using htmlwidgets::saveWidget to save any shiny widgets so we could get its html representation. As the hw_grid is not returning a shiny widgets I save it as a regular html but we have to take care of the dependencies.
Here I use the hchart (not highchart) as it persists labels on the plots.
You do not have to leave the code for html creation in the app.R file. But in my example you need still leave the dependencies list.
Then you could add dependencies in the DOM head with htmltools::renderDependencies(htmltools::resolveDependencies(DEPS)).
Remember that when you deploy the shiny app you have to add static files with e.g. addResourcePath https://shiny.rstudio.com/reference/shiny/1.0.2/addResourcePath.html
library(shiny)
library(highcharter)
library(tidyverse)
library(magrittr)
df <- tibble::tibble(months = month.abb, value = ts(cumsum(rnorm(100)))[1:12])
charts <- lapply(1:9, function(x) {
hchart(df, type = "spline", hcaes(x = months, y = value)) %>%
hc_xAxis(categories = df$months) %>%
hc_boost(enabled = TRUE)
})
hc_test <- hw_grid(charts, rowheight = 300, add_htmlgrid_css = TRUE, browsable = TRUE)
# get HTML of the plot
# we could not use htmlwidgets::saveWidget as it is not a widget
writeLines(as.character(hc_test), "hc_test.html")
# get the dependencies of the plot
hc_deps <- htmltools::findDependencies(hc_test)
# unique dependencies in the HTML format, could be added in the head
# htmltools::renderDependencies(htmltools::resolveDependencies(hc_deps))
ui <- fluidPage(
h1("Highcharts"),
htmlOutput("chart_grid")
)
server <- function(input, output, session) {
output$chart_grid <- renderUI({
# Load HTML with proper dependencies
htmltools::attachDependencies(
shiny::HTML(readLines("hc_test.html")),
htmltools::resolveDependencies(hc_deps)
)
})
}
shinyApp(ui, server)
Boost module
The source highcharts JS library offers a boost module which could boost the performance. From the perspective of R it is as easy as adding hc_boost(enabled = TRUE) to your pipeline.
https://www.highcharts.com/docs/advanced-chart-features/boost-module
As I understand the hc_boost could improve performance only in specific scenarios and for the cost of losing some functionality. I did not test if it truly works as expected.
library(shiny)
library(highcharter)
library(tidyverse)
df <- tibble(months = month.abb, value = ts(cumsum(rnorm(100)))[1:12])
ui <- fluidPage(
h1("Highcharts"),
htmlOutput("chart_grid")
)
server <- function(input, output, session) {
output$chart_grid <- renderUI({
charts <- lapply(1:9, function(x) {
highchart() %>%
hc_add_series(type = "spline", data = df, hcaes(x = months, y = value)) %>%
hc_xAxis(categories = df$months) %>%
hc_boost(enabled = TRUE)
})
hw_grid(charts, rowheight = 300, add_htmlgrid_css = TRUE, browsable = TRUE)
})
}
shinyApp(ui, server)
Highcharts and own grid
library(shiny)
library(highcharter)
library(tidyverse)
df <- tibble(months = month.abb, value = ts(cumsum(rnorm(100)))[1:12])
ui <- fluidPage(
h1("Highcharts"),
shiny::tags$div(
style = "display:flex;flex-wrap: wrap;",
lapply(1:9, function(x) shiny::tags$div(
style = "flex: 1 1 30%;",
highcharter::highchartOutput(sprintf("hplot%s", x)))
)
)
)
server <- function(input, output, session) {
charts <- lapply(1:9, function(x) {
output[[sprintf("hplot%s", x)]] <- highcharter::renderHighchart(
highchart(width = 600) %>%
hc_add_series(type = "spline", data = df, hcaes(x = months, y = value)) %>%
hc_xAxis(categories = df$months)
)
})
}
shinyApp(ui, server)
BTW.
My personal opinion is that the highcharter package need much work regarding the code quality and documentation, e.g. hw_grid does not even have documented the return value.
I have simple Shiny app with DT table
library(shiny)
library(DT)
iris2 = head(iris, 30)
server <- function(input, output) {
output$tb <-DT::renderDataTable(server=FALSE,{
datatable(
iris2,
colnames = c(colnames(iris2)), extensions = 'RowReorder',
options = list(rowReorder = TRUE))
})
}
ui <- fluidPage(dataTableOutput('tb', width = '200px', height = '200px'))
shinyApp(ui, server)
However, when I try to adjust the table row only the first column changes the position. It is probably related to the configuration of the ReorderRow, as described here. Unfortunately, I don't know how to implement JavaScript into the Shiny app, especially datatable options.
One has to add the row names and sort the table on them, as mentioned in the github issue. The working solutions requires only adding order = list(list(0, 'asc')) in the DT options:
library(shiny)
library(DT)
iris2 = head(iris, 30)
server <- function(input, output) {
output$tb <-DT::renderDataTable(server=FALSE,{
datatable(
iris2,
colnames = c(colnames(iris2)), extensions = 'RowReorder',
options = list(order = list(list(0, 'asc')), rowReorder = TRUE))
})
}
ui <- fluidPage(dataTableOutput('tb', width = '200px', height = '200px'))
shinyApp(ui, server)
I'm looking to customized the output of a data table in one of my shiny applications. I'd like to only keep the "next page" button on the bottom of the data table, but cannot figure out how to do so. I know you can customize the output using options = list(dom = ...) but cannot figure out how to produce the output I would like. Is this something that will only be able to be accomplished using java script? Example below, where Previous 1, 2, etc. is what I would like to keep. Thank you!
library(DT)
library(shiny)
ui <- fluidPage(
dataTableOutput(outputId = "dat")
)
server <- function(input, output, session) {
tb = iris
tb = datatable(tb, list(pageLength = 10))
output$dat = renderDataTable({
tb
})
}
shinyApp(ui, server)
To learn about all datatable options see this (datatables documentation). The option you are interested in is pagingType. So just do
library(DT)
library(shiny)
ui <- fluidPage(
DT::dataTableOutput(outputId = "dat")
)
server <- function(input, output, session) {
tb = iris
tb = DT::datatable(tb, list(pageLength = 10,pagingType = 'simple'))
output$dat = DT::renderDataTable(
{tb}
)
}
shinyApp(ui, server)
I am unable to control the width of a datatable I have added to a shiny app using the function dataTableOutput(). I've tried to use the width parameter within the function but it changes nothing in the output and there is no error ~ it's not telling me that it's ignoring the width parameter.
library(shiny)
library(shinythemes)
ui <- fluidPage(theme = shinytheme("Spacelab"),
fluidRow(
column(6,dataTableOutput(outputId = "table")),
column(6,p(textOutput("para")))
)
)
server <- function(input, output){
df <- as.data.frame(matrix(0, ncol = 15, nrow = 20))
output$table <- renderDataTable({df})
output$para <- renderText({
text <- rep(x = "Hello World",1000)
})
}
shinyApp(ui = ui,server = server)
dataTableOutput does not have an argument width. You can use column within a fluidRow with argument width, supplying an integer between 1 and 12.
library(shinythemes)
ui <- fluidPage(theme = shinytheme("Spacelab"),
fluidRow(
column(
dataTableOutput(outputId = "table"), width = 6)
)
)
server <- function(input, output){
df <- as.data.frame(matrix(0, ncol = 20, nrow = 5))
output$table <- renderDataTable({df},
options = list(scrollX = TRUE))
}
shinyApp(ui = ui,server = server)
Options from the JavaScript library DataTable can be passed directly via renderDataTable argument options. For example, setting scrollX to be true allows tables to scroll.
If you use the "DT" R package, and the respective DT::dataTableOutput and DT::renderDataTable, you can use a "width" option with those calls, which apparently can be either a % (e.g. width = "100%") or pixels (width = 300) which should get you the control you want.
See:
https://rstudio.github.io/DT/shiny.html
Note from that page:
Important: Be sure to use the DT:: prefix when calling dataTableOutput
and renderDataTable so that the DT versions of these functions are
guaranteed to be called, instead of the deprecated Shiny versions. If
you make sure to library(DT) after library(shiny), normally the DT
versions should just override the shiny versions if you do not use the
DT:: prefix (when in doubt, use this prefix, until we completely
remove these functions from shiny)
I am working with a d3pie rChart. It works when I view it in the rStudio viewer. When I try to enter it into a shiny app, I get an error:
Error in addResourcePath(LIB$name, LIB$url) : object 'LIB' not found
It wants me to tell it what library I am working with in showOutput('chart1','LIB') (e.g., Nvd3, Highcharts), but I'm not sure which one to use.
Similarly, when I save the d3pie chart as an html file, it won't open in my browser. Is there a way around this?
Data:
x <- data.frame(table = as.factor(c("A","B","C","D","E","F")),
value = c(518,39,337,304,56,7))
Code for d3pie:
require(magrittr)
require(dplyr)
require(rCharts)
rPie <- rCharts$new()
rPie$setLib("http://timelyportfolio.github.io/rChartsExtra/d3pie")
rPie$addParams(
chartspec = list(
header = list(
title = list(
text = "Breakdown of 2014 Revenue Sources"
)
)
,data = list(
content = x
)
)
)
rPie
server.R:
require(rCharts)
require(reshape)
require(magrittr)
require(dplyr)
x <- data.frame(table = as.factor(c("A","B","C","D","E","F")),
value = c(518,39,337,304,56,7))
shinyServer(function(input, output) {
output$chart1 <- renderChart2({
rPie <- rCharts$new()
rPie$setLib("http://timelyportfolio.github.io/rChartsExtra/d3pie")
cat(add_lib_assets(rPie$lib,cdn=T))
rPie$addParams(
chartspec = list(
header = list(
title = list(
text = "This is the title"
)
)
, data = list(
content = x
)
)
)
rPie$set(dom = "chart1")
return(rPie)
})
})
ui.R:
require(rCharts)
shinyUI(fluidPage(
titlePanel("Shiny App"),
mainPanel(
showOutput('chart1')
)
)
)
To make it work in shiny, you need to add d3pie as the lib in your showOutput:
showOutput('chart1','d3pie')
You also to download the extra libraries and copy/paste the d3pie folder in the same folder as where your server.R and ui.R are.