Using D3 with Shiny - Collapsible Tree? - d3.js

I have a fair understanding of Shiny and R but I'm just getting started with Javascript and have never coded in HTML or CSS. I would like to learn to build a collapsible tree using D3.js ( Something like this) Is there any tutorial that I can refer to get started with integrating D3.js into Shiny?
I have come across the CollapsibeTree package but I would like to learn how to build one myself. Any help would be highly appreciated!

here is the minimap example using the diamonds dataset. You can find more examples here https://github.com/AdeelK93/collapsibleTree
library(shiny)
#install.packages("collapsibleTree")
library(collapsibleTree)
data(diamonds,package = "ggplot2")
subdiamonds <- diamonds[1:300,]
ui <- fluidPage(
mainPanel(
collapsibleTreeOutput("tree")
)
)
server <- function(input, output, session) {
output$tree <- renderCollapsibleTree({
collapsibleTree(
subdiamonds,
hierarchy = c("cut", "color","price"),
width = 800
)
})
}
shinyApp(ui = ui, server = server)

Related

Unipdf pdf creation- table rows with content spanning multiple pages has display issues

I'm using Unidoc's unipdf library to generate a pdf with multiple tables in it.
When the content in a table cell is huge and needs to span over multiple pages, the pdf generated has the cells in the row scrambled, each cell goes over to a new page and no data is being displayed in the cell which has the huge data.
And in the same scenario some times I see this process hangs and also starts eating up a lot of memory.
Here are the screenshots of the same:
Page1/cell1 - the cell spans the entire page but has only one line
Page2/cell2 - with actual huge data, but no data being displayed
Page3/cell3 - the cell spans the entire page but has only one line
The code snippet for doing the above:
func AddTableCell(c *ctx.Context, t *creator.Table, parag *creator.Paragraph, colSpan int, width float64, sides ...creator.CellBorderSide) {
cell := t.MultiColCell(colSpan)
for _, s := range sides {
cell.SetBorder(s, creator.CellBorderStyleSingle, width)
}
cell.SetHorizontalAlignment(creator.CellHorizontalAlignmentLeft)
cell.SetVerticalAlignment(creator.CellVerticalAlignmentMiddle)
err := cell.SetContent(parag)
c.NoError(err, "error setting cell content: %v", err)
}
func NewParagraph(c *creator.Creator, text string, font *pdfmodel.PdfFont, fontSize, lineHeight float64) *creator.Paragraph {
parag := c.NewParagraph(text)
parag.SetFont(font)
parag.SetFontSize(fontSize)
parag.SetColor(reportTextColor)
parag.SetLineHeight(lineHeight)
parag.SetEnableWrap(true)
return parag
}
These are my two functions which help me draw the table
And here is how I use them:
for col := 0; col < len(rowVals); col++ {
if col == 0 {
AddTableCell(g.c, tb.Table, NewParagraph(g.Creator, rowVals[col], font, 10, 1.5),
colSpans[col], tb.cellBorderWidth, creator.CellBorderSideAll)
} else {
AddTableCell(g.c, tb.Table, NewParagraph(g.Creator, rowVals[col], font, 10, 1.5),
colSpans[col], tb.cellBorderWidth, creator.CellBorderSideTop, creator.CellBorderSideRight, creator.CellBorderSideBottom)
}
if g.c.HasErr() {
return
}
}
Using the same logic I'm able generate pdf for smaller piece of data but it breaks when the data is huge as shown in the screenshots above.
Does unidoc support handling data spanning multiple pages when embeded within tables? Or does it have some option/flag to enable it? What is it that I'm missing here?
Another approach which you can use is
create GO HTML template and render it.
Use wkhtmltopdf to convert html to pdf.
I also faced similar issues where I was unable to generate a complex pdf and using wkhtmltopdf I was able to generate it.
ps: you can use pdfg.AddPage to add new page.
The newest release UniPDF v3.16.0 (just released) adds support for row-wrapping, and can be enabled via EnableRowWrap on the table:
t.EnableRowWrap(true)
We have verified that it works with your example posted above.
If you continue seeing large use of resources in the newest versions, please share with us. We have made some pretty big performance enhancements recently and will continue to improve it. Getting good bug reports is a great step towards that.
Disclosure: I am the original developer of UniPDF.

D3.js Visualizations from Local Files

I have a mostly working code that can load one record, but I'm not sure how to expand it. The closest that I've been able to get is to pull 1 record column names from a csv based on the logic from this bl.ocks code snippet.
How can I modify the function below to pull an entire dataset rather than just one record?
By modifying code from the bl.ocks code, below is what I've been able to achieve. But I'm still having trouble looping the second function into pulling every row. In R, I could do something like rowtoHTML(0:length(data))
var rowToHtml = function( row ) {
var result = "";
for (key in row) {
result += key + ": " + row[key] + "<br/>"
}
return result;
}
var previewCsvUrl = function( csvUrl ) {
d3.csv( csvUrl, function( rows ) {
d3.select("div#preview").html(
"<b>First row:</b><br/>" + rowToHtml( rows[0] ));
})
}
d3.select("body")
.append("div")
.attr("id", "preview")
.style("margin", "5px")
previewCsvUrl("Test.csv")
This question has been asked before. I've tried to do my due diligence by reading through similar questions, but was not able to use the recommended solution based off of my technology constraints or due to inexperience with Javascript. The sample code I've used comes from a trimmed version of this bl.ocks code: http://bl.ocks.org/hlvoorhees/9d58e173825aed1e0218
Edit - I understand that hosting a file locally is the right move, but its not an option for me (hence this approach). Python has been recommended for local hosting, but I'm unable to install it on my machine at this time. I'm working with Edge and IE as my two browser options. I really appreciate the help!

plot.CA() renders in shiny app locally but not when app is deployed

I have created a Shiny app that takes user input and creates a CA plot. It works just fine when I run the app locally, but for some reason when I deploy the dashboard, the image of the plot won't appear. I can see in the logs that the data uploading and reformatting into a proper data frame is working just fine, but the plot itself is failing to render.
Does anyone know why this might be? I posted my code below (you'll see some print() lines in my code that was used for debugging). Any help would be greatly appreciated!
#PERCEPTUAL MAPPING DASHBOARD
library(FactoMineR)
library(factoextra)
library(SensoMineR)
library(shinythemes)
library(ca)
ui <- fluidPage(theme = shinytheme("darkly"),
# Application title
titlePanel("Perceptual Map Dashboard"),
sidebarLayout(
# Sidebar with a slider and selection inputs
sidebarPanel(
#Excel doc row and column names
numericInput(inputId="startcol",label="Input start column of CSV file:",value="", min=1,max=10000),
numericInput(inputId="endcol",label="Input end column of CSV file:",value="", min=1,max=10000),
#Inputing brands and emotions
br(),
numericInput(inputId = "rownums",label = "How many emotions/characteristics are you evaluating?",value = "", min = 1,max = 10000),
br(),
h6("Note: Please enter brands and emotions/characteristics in the order that they appear in the excel document exported from Survey Gizmo."),
textInput ( 'brands', 'List the brands included in your perceptual map (separated by commas):', value=""),
textInput ( 'emotions', 'List the emotions/characteristics included in your perceptual map (separated by commas):', value=""),
#Removing brands and emotions
#Select graph type
textInput(inputId="plottitle",label="Title your graph:"),
#Upload Excel Grid
fileInput(inputId = 'data', 'Upload CSV File',
accept=c('.csv')),
actionButton("go","Create Map")
),
# Visual Output
mainPanel(
wellPanel(h4('Visual'),
h5("Once your visual appears, just right click it to save it as a .png file.")),
plotOutput(outputId = "plot", width = "100%", height=500)
# downloadButton("downloadPlot", "Download Visual")
)
)
)
server <- function(input,output){
K <- eventReactive(input$go,{
x <- read.csv(input$data$datapath, header = F)
x[!is.na(x)] <- 1
x[is.na(x)] <- 0
x<-x[,as.numeric(input$startcol):as.numeric(input$endcol)]
column.sums<-colSums(x)
print(column.sums)
pmd.matrix<-matrix(column.sums, byrow = T, nrow=as.numeric(input$rownums))
pmd.df2<-as.data.frame(pmd.matrix)
colnames(pmd.df2) = unlist(strsplit(as.character(input$brands),","))
print(pmd.df2)
row.names(pmd.df2)= unlist(strsplit(as.character(input$emotions),","))
print(pmd.df2)
pmd.df2[-nrow(pmd.df2),]
print(pmd.df2)
fit <- CA(pmd.df2, graph=F)
return(fit)
})
p <- eventReactive(input$go,{
input$plottitle
})
output$plot<- renderPlot({
plot.CA(K(), col.row = "blue", col.col="black", cex=1, new.plot=T,
title=p())
})
}
shinyApp(ui = ui, server = server)
What I suggest to you is to check whether this issue is specific to your plot or if plot.CA is not working with shiny in general. Try to "deploy" (apparently, you don't use a webserver?) the following app
library(FactoMineR)
library(shiny)
data(children)
res.ca <- CA(children, col.sup = 6:8, row.sup = 15:18)
shinyApp(
fluidPage(plotOutput("plot")),
function(input, output, sesison) {
output$plot <- renderPlot({
plot.CA(res.ca)
})
}
)
If this does work, there might be something wrong with your model or maybe there are name collusions between the ca package and the FactorMineR package.
If this does not work, try the following instead
## use same data/libraries as above
myfile <- tempfile(fileext = ".png")
shinyApp(
fluidPage(imageOutput("plot")),
function(input, output, sesison) {
output$plot <- renderImage({
png(file = myfile)
plot.CA(res.ca)
dev.off()
list(src = myfile)
}, deleteFile = FALSE)
}
)
And see
Whether the app works now
Whether myfile gets created and contains reasonable contents.

Accessing Dynamic Data from Drop down box in Shiny

I am creating a shiny dashboard wherein I need to dynamically update information based on an option in a drop down box.
My question is 1. can this be done, and if so: how?
I have created my drop down menu, which works fine, from there I want to same something along the lines of "if outlet xyz is picked, update charts with unique information"
Code thus far:
output$Box1 = renderUI(
selectInput("Outlets",
"Select an Outlet",
c("Start Typing Outlet
Name",as.character(unique(outlets$Outlets))),
"selectoutlet"))
once the outlet has been selected, I want the data in my R script to only update for that one outlet.
As You havent supplied reproducible example, here is the code with mtcars dataset:
library(shiny)
library(dplyr)
library(ggplot2)
ui= fluidPage(
sidebarLayout(
sidebarPanel(
selectInput(inputId= "cyl", label= "cyl",
choices= unique(mtcars$cyl),
selected= sort(unique(mtcars$cyl))[1],
multiple=F)
),
mainPanel(
plotOutput("plot")
)
)
)
server= function(input, output,session) {
df_filtered <-reactive({
data <- mtcars %>% {if (is.null(input$cyl)) . else filter(., cyl %in% input$cyl)} # here is the reactive dataset which You can further use it in table or in the plot
print(data)
data
})
output$plot <- renderPlot({
ggplot(data = df_filtered(), aes(x=cyl,y=mpg)) + geom_point(size=5) # as You can see i have used data = df_filtered()
})
}
shinyApp(ui, server)
Have a look at the comments in the code to get some better idea how it works.

How to visualize charts in Visual Studio and Azure ML through R script?

I have seen on various examples (even in Azure ML) that you are able to create appealing charts using R in Visual Studio (not R Studio!), but I have no clue how they did it. I am experienced with R, but if someone could point me in the right direction of how to visualize data sets in Visual Studio and Azure ML; I would really appreciate it.
Here is an example I would like to duplicate (in both Azure ML and Visual Studio): Visual studio chart
Image source: https://regmedia.co.uk/2016/03/09/r_vis_studio_plot.jpg?x=648&y=348&crop=1
You can install ggplot2 in your solution in the Visual Studio extension Open R (https://www.visualstudio.com/en-us/features/rtvs-vs.aspx) through this line of code and visualize it within the R Plot window in Visual Studio after creating your R-project:
install.packages('ggplot2', dep = TRUE)
library(ggplot2)
The reason I have «library(ggplot2)» is to check if the package got successfully installed, else you would get an error like this: Error in library(ggplot2) : there is no package called ‘ggplot2’
So if you don’t get that error; you should be good to go.
For your question about how to output charts; you simply have to populate the ggplot2 charts from a datasource, like in my example below (csv-file):
dataset1 <- read.csv("Adult Census Income Binary Classification dataset.csv", header = TRUE, sep = ",", quote = "", fill = TRUE, comment.char = "")
head(dataset1)
install.packages('ggplot2', dep = TRUE)
library(ggplot2)
names(dataset1) <- sub(pattern = ',', replacement = '.', x = names(dataset1))
foo = qplot(age, data = dataset1, geom = "histogram", fill = income, position = "dodge");
print(foo)
bar = qplot(age, data = dataset1, geom = "density", alpha = 1, fill = income);
print(bar)
Here you can see that I create two charts, one histogram and one density-chart.
In Azure ML, the same charts (this time I included a histogram for Relationships as well), would look like this:
// Map 1-based optional input ports to variables
dataset1 <- maml.mapInputPort(1) # class: data.frame
library(ggplot2)
library(data.table)
names(dataset1) <- sub(pattern=',', replacement='.', x=names(dataset1))
// This time we need to specify the X to be sex; which we didn’t need in Visual Studio
foo = qplot(x=sex, data=dataset1, geom="histogram", fill=income, position="dodge");
print(foo)
foo = qplot(x=relationship, data=dataset1, geom="histogram", fill=income, position="dodge");
print(foo)
foo = qplot(x=age, data=dataset1, geom="density", alpha=0.5, fill=income);
print(foo)
// Select data.frame to be sent to the output Dataset port maml.mapOutputPort("dataset1");
Remember to put all of this in a “Execute R Script module” in order to run it correctly. After that, you can right lick the module and visualize the result.
I believe you're referring to the R Tools for Visual Studio. These provide a means to develop and debug R code in the Visual Studio IDE, and can produce plots like the one you shared.
However, that plot looks like a pretty standard chart from the CRAN ggplot2 package, which means it could have been just as easily produced from R code running in the R console or RStudio.
This posting on the R-bloggers site should help get you started with ggplot2.
http://www.r-bloggers.com/basic-introduction-to-ggplot2/
Good luck, and enjoy!
jmp

Resources