├── .gitignore ├── Examples ├── Diamonds │ ├── global.R │ ├── plotlyGraphWidget.R │ ├── runApp.R │ ├── server.R │ ├── ui.R │ └── www │ │ └── plotlyGraphWidget.js ├── Movies │ ├── .Rapp.history │ ├── global.R │ ├── plotlyGraphWidget.R │ ├── runApp.R │ ├── server.R │ ├── ui.R │ └── www │ │ └── plotlyGraphWidget.js ├── UN_Advanced │ ├── .Rapp.history │ ├── .Rproj.user │ │ └── 291D9A59 │ │ │ └── pcs │ │ │ ├── files-pane.pper │ │ │ ├── source-pane.pper │ │ │ ├── windowlayoutstate.pper │ │ │ └── workbench-pane.pper │ ├── Data │ │ └── UN_IdealPoints.csv │ ├── global.R │ ├── plotlyGraphWidget.R │ ├── runApp.R │ ├── server.R │ ├── ui.R │ └── www │ │ └── plotlyGraphWidget.js └── UN_Simple │ ├── .Rapp.history │ ├── Data │ ├── UN_IdealPoints.csv │ └── UN_IdealPoints_old.csv │ ├── global.R │ ├── plotlyGraphWidget.R │ ├── runApp.R │ ├── server.R │ ├── ui.R │ └── www │ └── plotlyGraphWidget.js ├── README.md └── What_You_Need ├── global.R ├── plotlyGraphWidget.R ├── runApp.R ├── server_Template_GGPLOT.R ├── server_Template_PLOTLY.R ├── ui_Template.R └── www └── plotlyGraphWidget.js /.gitignore: -------------------------------------------------------------------------------- 1 | .Rhistory 2 | -------------------------------------------------------------------------------- /Examples/Diamonds/global.R: -------------------------------------------------------------------------------- 1 | # Golbal environment contains information needed in both the ui and server scripts 2 | 3 | library(plotly) 4 | library(shiny) 5 | 6 | py <- plotly(username="rAPI", key="yu680v5eii", base_url="https://plot.ly") 7 | 8 | source("plotlyGraphWidget.R") 9 | -------------------------------------------------------------------------------- /Examples/Diamonds/plotlyGraphWidget.R: -------------------------------------------------------------------------------- 1 | #This script is necessary in the app folder 2 | #but the user should not have to edit it 3 | 4 | #Output Graph Function 5 | graphOutput <- function(inputId, width="100%", height="550px") { 6 | tagList( 7 | singleton(tags$head( 8 | tags$script(src="plotlyGraphWidget.js") 9 | )), 10 | tags$iframe(id=inputId, src="https://plot.ly/~playground/7.embed", 11 | class="graphs", style="border:none;", seamless=TRUE, width=width, height=height) 12 | ) 13 | } 14 | 15 | renderGraph <- function(expr, env=parent.frame(), quoted=FALSE) { 16 | ## This gets called when inputs change -- 17 | ## Place data wrangling code in here 18 | ## and pass the result to the client 19 | ## to be graphed. 20 | 21 | 22 | installExprFunction(expr, "func", env, quoted) 23 | 24 | function(){ 25 | data = func(); 26 | ## data is the state of the widgets: see server.R 27 | ## this function returns a list of named lists that descripe 28 | ## valid postMessage commands to be sent to the embedded iframe. 29 | ## see binding.renderValue for the receiving JS side of this function 30 | ## and https://github.com/plotly/Embed-API for more about the postMessage 31 | ## graph messages 32 | return(data) 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Examples/Diamonds/runApp.R: -------------------------------------------------------------------------------- 1 | install.packages("shiny") 2 | install.packages("dplyr") 3 | install.packages("devtools") 4 | 5 | library(devtools) 6 | install_github("ropensci/plotly") 7 | 8 | shiny::runApp() -------------------------------------------------------------------------------- /Examples/Diamonds/server.R: -------------------------------------------------------------------------------- 1 | #Shiny 2 | shinyServer(function(input, output, session) { 3 | 4 | #add reactive data information. Dataset = built in diamonds data 5 | dataset <- reactive({ 6 | diamonds[sample(nrow(diamonds), input$sampleSize),] 7 | }) 8 | 9 | output$trendPlot <- renderGraph({ 10 | 11 | # build graph with ggplot syntax 12 | # pull x and y variable info 13 | p <- ggplot(dataset(), 14 | aes_string(x = input$x, 15 | y = input$y)) + 16 | geom_point() 17 | 18 | # if statements for possible color/facet row/facet column variables 19 | if (input$color != 'None') 20 | p <- p + aes_string(color=input$color) 21 | 22 | facets <- paste(input$facet_row, '~', input$facet_col) 23 | if (facets != '. ~ .') 24 | p <- p + facet_grid(facets) 25 | 26 | # use gg2list() to convert from ggplot->plotly 27 | gg <- gg2list(p) 28 | 29 | # make edits with plotly syntax 30 | gg$layout <- list(legend = list( 31 | x = 1, 32 | y = 1, 33 | bgcolor = "transparent")) 34 | 35 | # Send this message up to the browser client, which will get fed through to 36 | # Plotly's javascript graphing library embedded inside the graph 37 | return(list( 38 | list( 39 | id = "trendPlot", 40 | task = "newPlot", 41 | data = gg$data, 42 | layout= gg$layout 43 | ) 44 | )) 45 | 46 | }) 47 | 48 | }) -------------------------------------------------------------------------------- /Examples/Diamonds/ui.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | library(ggplot2) 3 | 4 | dataset <- diamonds 5 | 6 | shinyUI(pageWithSidebar( 7 | 8 | headerPanel("Diamonds Explorer"), 9 | 10 | sidebarPanel( 11 | 12 | sliderInput('sampleSize', 'Sample Size', min=1, max=nrow(dataset), 13 | value=min(1000, nrow(dataset)), step=500, round=0), 14 | 15 | selectInput('x', 'X', names(dataset)), 16 | selectInput('y', 'Y', names(dataset), names(dataset)[[2]]), 17 | selectInput('color', 'Color', c('None', names(dataset))), 18 | 19 | selectInput('facet_row', 'Facet Row', c(None='.', names(dataset))), 20 | selectInput('facet_col', 'Facet Column', c(None='.', names(dataset))) 21 | ), 22 | 23 | mainPanel( 24 | graphOutput('trendPlot') 25 | ) 26 | )) -------------------------------------------------------------------------------- /Examples/Diamonds/www/plotlyGraphWidget.js: -------------------------------------------------------------------------------- 1 | var binding = new Shiny.OutputBinding(); 2 | 3 | binding.find = function(scope) { 4 | // not sure what this function does, or 5 | // why its necessary... 6 | console.log('binding.scope'); 7 | return $(scope).find('.graphs'); 8 | }; 9 | 10 | binding.renderValue = function(el, messages) { 11 | // this gets called when the inputs change 12 | // messages is the list of named lists passed up 13 | // by renderGraph. these named lists are postMessage 14 | // commands that get passed into the embedded graph. 15 | // See https://github.com/plotly/Embed-API for details 16 | console.log('renderValue, messages: ', JSON.stringify(messages)); 17 | var $el = $(el); 18 | 19 | if (!window.graphs) { 20 | console.log('first time rendering'); 21 | initGraphs(messages); 22 | } 23 | messages.forEach(function(message){ 24 | console.log('posting ', message, ' to ', message.id); 25 | window.graphs[message.id].graphContentWindow.postMessage(message, 'https://plot.ly'); 26 | }); 27 | 28 | }; 29 | 30 | Shiny.outputBindings.register(binding, "plotlyshiny"); 31 | 32 | function initGraphs(initialMessages){ 33 | var $graphs = $('.graphs'); 34 | var graphs = {}; 35 | $graphs.each(function(i){ 36 | graphs[$graphs[i].id] = { 37 | graphContentWindow: $graphs[i].contentWindow, 38 | id: $graphs[i].id, 39 | pinger: setInterval(function(){ 40 | $graphs[i].contentWindow.postMessage({task: 'ping'}, 'https://plot.ly'); 41 | }, 500) 42 | }; 43 | }); 44 | 45 | 46 | // messages coming from the embedded graphs 47 | // either 'pong' or the 'hover', 'zoom', 'click' events 48 | window.addEventListener('message', function(e){ 49 | var message = e.data; 50 | for(var graph_id in graphs){ 51 | if(graphs[graph_id].graphContentWindow === e.source) { 52 | var graph = graphs[graph_id]; 53 | break; 54 | } 55 | } 56 | 57 | var pinger = graph.pinger; 58 | var graphContentWindow = graph.graphContentWindow; 59 | var id = graph.id; 60 | 61 | if('pong' in message && message.pong) { 62 | console.log('>> clearing!'); 63 | clearInterval(pinger); 64 | graphContentWindow.postMessage({ 65 | 'task': 'listen', 66 | 'events': ['zoom', 'click', 'hover']}, 67 | 'https://plot.ly'); 68 | initialMessages.forEach(function(initialMessage){ 69 | if(initialMessage.id == id){ 70 | graphContentWindow.postMessage(initialMessage, 'https://plot.ly'); 71 | } 72 | }); 73 | // TODO: send pong back to R 74 | } else if (message.type==='hover' || 75 | message.type==='zoom' || 76 | message.type==='click') { 77 | console.log('>> ', message.type); 78 | if(message.type !== 'zoom') { 79 | for(var i in message.points) { 80 | delete message.points[i].data; 81 | } 82 | } 83 | // TODO: Send back to R 84 | } 85 | }); 86 | window.graphs = graphs; 87 | } 88 | -------------------------------------------------------------------------------- /Examples/Movies/.Rapp.history: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chriddyp/plotly-shiny/c16d0339f267fbc5f7d1622b4b0789508a3e64ca/Examples/Movies/.Rapp.history -------------------------------------------------------------------------------- /Examples/Movies/global.R: -------------------------------------------------------------------------------- 1 | # Golbal environment contains information needed in both the ui and server scripts 2 | 3 | library(plotly) 4 | library(shiny) 5 | 6 | py <- plotly(username="rAPI", key="yu680v5eii", base_url="https://plot.ly") 7 | 8 | source("plotlyGraphWidget.R") 9 | -------------------------------------------------------------------------------- /Examples/Movies/plotlyGraphWidget.R: -------------------------------------------------------------------------------- 1 | #This script is necessary in the app folder 2 | #but the user should not have to edit it 3 | 4 | #Output Graph Function 5 | graphOutput <- function(inputId, width="100%", height="550px") { 6 | tagList( 7 | singleton(tags$head( 8 | tags$script(src="plotlyGraphWidget.js") 9 | )), 10 | tags$iframe(id=inputId, src="https://plot.ly/~playground/7.embed", 11 | class="graphs", style="border:none;", seamless=TRUE, width=width, height=height) 12 | ) 13 | } 14 | 15 | renderGraph <- function(expr, env=parent.frame(), quoted=FALSE) { 16 | ## This gets called when inputs change -- 17 | ## Place data wrangling code in here 18 | ## and pass the result to the client 19 | ## to be graphed. 20 | 21 | 22 | installExprFunction(expr, "func", env, quoted) 23 | 24 | function(){ 25 | data = func(); 26 | ## data is the state of the widgets: see server.R 27 | ## this function returns a list of named lists that descripe 28 | ## valid postMessage commands to be sent to the embedded iframe. 29 | ## see binding.renderValue for the receiving JS side of this function 30 | ## and https://github.com/plotly/Embed-API for more about the postMessage 31 | ## graph messages 32 | return(data) 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Examples/Movies/runApp.R: -------------------------------------------------------------------------------- 1 | install.packages("shiny") 2 | install.packages("dplyr") 3 | install.packages("devtools") 4 | 5 | library(devtools) 6 | install_github("ropensci/plotly") 7 | 8 | shiny::runApp() -------------------------------------------------------------------------------- /Examples/Movies/server.R: -------------------------------------------------------------------------------- 1 | # server.R 2 | x = movies$rating 3 | minx = min(x) 4 | maxx = max(x) 5 | 6 | shinyServer(function(input, output) { 7 | output$trendPlot <- renderGraph({ 8 | bins <- input$bins 9 | trace1 <- list(x = x, 10 | autobinx = FALSE, 11 | xbins = list(start = minx, 12 | end = maxx, 13 | size = ((maxx-minx)/bins) 14 | ), 15 | type = "histogram" 16 | ) 17 | 18 | data <- list(trace1) 19 | layout<- list(xaxis = 20 | list(title = "Ratings", 21 | range = c(minx, maxx), 22 | autorange = FALSE, 23 | autotick = FALSE, 24 | tick0 = minx, 25 | dtick = ((maxx-minx)/bins) 26 | ) 27 | ) 28 | 29 | return(list( 30 | list(id = "trendPlot", 31 | task = "newPlot", 32 | data = data, 33 | layout = layout 34 | ) 35 | )) 36 | }) 37 | }) 38 | 39 | -------------------------------------------------------------------------------- /Examples/Movies/ui.R: -------------------------------------------------------------------------------- 1 | # ui.R 2 | shinyUI(fluidPage( 3 | titlePanel("Movie Ratings!"), 4 | sidebarLayout( 5 | sidebarPanel( 6 | sliderInput("bins", 7 | "Number of bins:", 8 | min = 1, 9 | max = 50, 10 | value = 10 11 | ) 12 | ), 13 | mainPanel( 14 | graphOutput("trendPlot") 15 | ) 16 | ) 17 | )) -------------------------------------------------------------------------------- /Examples/Movies/www/plotlyGraphWidget.js: -------------------------------------------------------------------------------- 1 | var binding = new Shiny.OutputBinding(); 2 | 3 | binding.find = function(scope) { 4 | // not sure what this function does, or 5 | // why its necessary... 6 | console.log('binding.scope'); 7 | return $(scope).find('.graphs'); 8 | }; 9 | 10 | binding.renderValue = function(el, messages) { 11 | // this gets called when the inputs change 12 | // messages is the list of named lists passed up 13 | // by renderGraph. these named lists are postMessage 14 | // commands that get passed into the embedded graph. 15 | // See https://github.com/plotly/Embed-API for details 16 | console.log('renderValue, messages: ', JSON.stringify(messages)); 17 | var $el = $(el); 18 | 19 | if (!window.graphs) { 20 | console.log('first time rendering'); 21 | initGraphs(messages); 22 | } 23 | messages.forEach(function(message){ 24 | console.log('posting ', message, ' to ', message.id); 25 | window.graphs[message.id].graphContentWindow.postMessage(message, 'https://plot.ly'); 26 | }); 27 | 28 | }; 29 | 30 | Shiny.outputBindings.register(binding, "plotlyshiny"); 31 | 32 | function initGraphs(initialMessages){ 33 | var $graphs = $('.graphs'); 34 | var graphs = {}; 35 | $graphs.each(function(i){ 36 | graphs[$graphs[i].id] = { 37 | graphContentWindow: $graphs[i].contentWindow, 38 | id: $graphs[i].id, 39 | pinger: setInterval(function(){ 40 | $graphs[i].contentWindow.postMessage({task: 'ping'}, 'https://plot.ly'); 41 | }, 500) 42 | }; 43 | }); 44 | 45 | 46 | // messages coming from the embedded graphs 47 | // either 'pong' or the 'hover', 'zoom', 'click' events 48 | window.addEventListener('message', function(e){ 49 | var message = e.data; 50 | for(var graph_id in graphs){ 51 | if(graphs[graph_id].graphContentWindow === e.source) { 52 | var graph = graphs[graph_id]; 53 | break; 54 | } 55 | } 56 | 57 | var pinger = graph.pinger; 58 | var graphContentWindow = graph.graphContentWindow; 59 | var id = graph.id; 60 | 61 | if('pong' in message && message.pong) { 62 | console.log('>> clearing!'); 63 | clearInterval(pinger); 64 | graphContentWindow.postMessage({ 65 | 'task': 'listen', 66 | 'events': ['zoom', 'click', 'hover']}, 67 | 'https://plot.ly'); 68 | initialMessages.forEach(function(initialMessage){ 69 | if(initialMessage.id == id){ 70 | graphContentWindow.postMessage(initialMessage, 'https://plot.ly'); 71 | } 72 | }); 73 | // TODO: send pong back to R 74 | } else if (message.type==='hover' || 75 | message.type==='zoom' || 76 | message.type==='click') { 77 | console.log('>> ', message.type); 78 | if(message.type !== 'zoom') { 79 | for(var i in message.points) { 80 | delete message.points[i].data; 81 | } 82 | } 83 | // TODO: Send back to R 84 | } 85 | }); 86 | window.graphs = graphs; 87 | } 88 | -------------------------------------------------------------------------------- /Examples/UN_Advanced/.Rapp.history: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chriddyp/plotly-shiny/c16d0339f267fbc5f7d1622b4b0789508a3e64ca/Examples/UN_Advanced/.Rapp.history -------------------------------------------------------------------------------- /Examples/UN_Advanced/.Rproj.user/291D9A59/pcs/files-pane.pper: -------------------------------------------------------------------------------- 1 | { 2 | "path" : "~/Desktop/Shiny/UN_Advanced", 3 | "sortOrder" : [ 4 | { 5 | "ascending" : true, 6 | "columnIndex" : 2 7 | } 8 | ] 9 | } -------------------------------------------------------------------------------- /Examples/UN_Advanced/.Rproj.user/291D9A59/pcs/source-pane.pper: -------------------------------------------------------------------------------- 1 | { 2 | "activeTab" : -1 3 | } -------------------------------------------------------------------------------- /Examples/UN_Advanced/.Rproj.user/291D9A59/pcs/windowlayoutstate.pper: -------------------------------------------------------------------------------- 1 | { 2 | "left" : { 3 | "panelheight" : 1128, 4 | "splitterpos" : 465, 5 | "topwindowstate" : "HIDE", 6 | "windowheight" : 1164 7 | }, 8 | "right" : { 9 | "panelheight" : 1128, 10 | "splitterpos" : 698, 11 | "topwindowstate" : "NORMAL", 12 | "windowheight" : 1164 13 | } 14 | } -------------------------------------------------------------------------------- /Examples/UN_Advanced/.Rproj.user/291D9A59/pcs/workbench-pane.pper: -------------------------------------------------------------------------------- 1 | { 2 | "TabSet1" : 0, 3 | "TabSet2" : 0 4 | } -------------------------------------------------------------------------------- /Examples/UN_Advanced/global.R: -------------------------------------------------------------------------------- 1 | # Golbal environment for both ui and server 2 | # Include lines 3-6 in all global.R scripts 3 | library(plotly) 4 | library(shiny) 5 | library(dplyr) 6 | 7 | py <- plotly(username="rAPI", key="yu680v5eii", base_url="https://plot.ly") 8 | 9 | source("plotlyGraphWidget.R") 10 | 11 | # User specific info: 12 | 13 | # In this example, the data is read in the global.r script 14 | # because it is called in both the ui.R and server.R scripts 15 | Ideal_Point_Data <- read.csv("Data/UN_IdealPoints.csv", stringsAsFactors=F) 16 | Ideal_Point_Data<- Ideal_Point_Data[complete.cases(Ideal_Point_Data),] 17 | 18 | -------------------------------------------------------------------------------- /Examples/UN_Advanced/plotlyGraphWidget.R: -------------------------------------------------------------------------------- 1 | #This script is necessary in the app folder 2 | #but the user should not have to edit it 3 | 4 | #Output Graph Function 5 | graphOutput <- function(inputId, width="100%", height="550px") { 6 | tagList( 7 | singleton(tags$head( 8 | tags$script(src="plotlyGraphWidget.js") 9 | )), 10 | tags$iframe(id=inputId, src="https://plot.ly/~playground/7.embed", 11 | class="graphs", style="border:none;", seamless=TRUE, width=width, height=height) 12 | ) 13 | } 14 | 15 | renderGraph <- function(expr, env=parent.frame(), quoted=FALSE) { 16 | ## This gets called when inputs change -- 17 | ## Place data wrangling code in here 18 | ## and pass the result to the client 19 | ## to be graphed. 20 | 21 | 22 | installExprFunction(expr, "func", env, quoted) 23 | 24 | function(){ 25 | data = func(); 26 | ## data is the state of the widgets: see server.R 27 | ## this function returns a list of named lists that descripe 28 | ## valid postMessage commands to be sent to the embedded iframe. 29 | ## see binding.renderValue for the receiving JS side of this function 30 | ## and https://github.com/plotly/Embed-API for more about the postMessage 31 | ## graph messages 32 | return(data) 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Examples/UN_Advanced/runApp.R: -------------------------------------------------------------------------------- 1 | install.packages("shiny") 2 | install.packages("dplyr") 3 | install.packages("devtools") 4 | install.packages("BH") 5 | 6 | library("devtools") 7 | install_github("ropensci/plotly") 8 | 9 | library("dplyr") 10 | 11 | shiny::runApp() -------------------------------------------------------------------------------- /Examples/UN_Advanced/server.R: -------------------------------------------------------------------------------- 1 | #server script for United Nations Advanced Example 2 | library(ggthemes) 3 | 4 | shinyServer(function(input, output, session) { 5 | 6 | output$trendPlot <- renderGraph({ 7 | if (length(input$name)==0) print("Please select at least one country") 8 | 9 | else { 10 | df_trend <- Ideal_Point_Data %>% 11 | filter(Name %in% input$name) 12 | 13 | # Graph title 14 | if (length(input$name)>2) { 15 | j_names_comma <- paste(input$name[-length(input$name)], collapse = ', ') 16 | j_names <- paste(j_names_comma, ", and ", input$name[length(input$name)], 17 | sep="") 18 | } 19 | 20 | else{ 21 | j_names <- paste(input$name, collapse = ' and ') 22 | } 23 | 24 | graph_title <- paste("Ideal Points for ", j_names, sep="") 25 | 26 | ggideal_point <- ggplot(df_trend)+ 27 | geom_line(aes(x=Year, y=Ideal.point, by=Name, color=Name))+ 28 | labs(x = "Year")+ 29 | labs(y = "Ideology")+ 30 | labs(title = graph_title)+ 31 | scale_colour_hue("clarity",l=70, c=150)+ 32 | theme_few() 33 | 34 | ggideal_point <- ggideal_point+ 35 | theme(legend.direction = "horizontal", legend.position = "bottom") 36 | 37 | # Year range 38 | min_Year <- min(df_trend$Year) 39 | max_Year <- max(df_trend$Year) 40 | 41 | # Use gg2list() to convert from ggplot->plotly 42 | gg<- gg2list(ggideal_point) 43 | 44 | # Use Plotly syntax to further edit the plot: 45 | gg$layout$annotations <- NULL # Remove the existing annotations (the legend label) 46 | gg$layout$annotations <- list() 47 | 48 | # Add colored text annotations next to the end of each line 49 | # More about plotly annotations: https://plot.ly/r/reference/#annotation 50 | # Each key that we update is documented in that link above. 51 | for(i in 1:(length(gg$data))){ # data is a list of the lines in the graph 52 | gg$layout$annotations[[i]] <- list( 53 | text = gg$data[[i]]$name, # The text label of the annotation, e.g. "Canada" 54 | font = list(color = gg$data[[i]]$line$color), # Match the font color to the line color 55 | showarrow = FALSE, # Don't show the annotation arrow 56 | y = gg$data[[i]]$y[[length(gg$data[[i]]$y)]], # set the y position of the annotation to the last point of the line 57 | yref = "y1", # the "y" coordinates above are with respect to the yaxis 58 | x = 1, # set the x position of the graph to the right hand side of the graph 59 | xref = "paper", # the x coordinates are with respect to the "paper", where 1 means the right hand side of the graph and 0 means the left hand side 60 | xanchor = "left" # position the x coordinate with respect to the left of the text 61 | ); 62 | } 63 | 64 | gg$layout$showlegend <- FALSE # remove the legend 65 | gg$layout$margin$r <- 170 # increase the size of the right margin to accommodate more room for the annotation labels 66 | 67 | # Send this message up to the browser client, which will get fed through to 68 | # Plotly's javascript graphing library embedded inside the graph 69 | return(list( 70 | list( 71 | id="trendPlot", 72 | task="newPlot", 73 | data=gg$data, 74 | layout=gg$layout 75 | ) 76 | )) 77 | } 78 | }) 79 | 80 | output$termPlot <- renderPlot({ 81 | df_term <- Ideal_Point_Data %>% 82 | filter(Name %in% input$name) %>% 83 | group_by(Name) %>% 84 | summarise(terms = n()) 85 | 86 | trans_theme <- theme( 87 | panel.grid.minor = element_blank(), 88 | panel.grid.major = element_blank(), 89 | panel.background = element_rect(fill=NA), 90 | plot.background = element_rect(fill=NA) 91 | ) 92 | 93 | ggplot(df_term, aes(x=reorder(Name, terms), y=terms))+ 94 | geom_bar(stat = "identity", fill = "#2980b9")+ 95 | theme_bw()+ 96 | trans_theme+ 97 | labs(y="Terms (in years)", x="")+ 98 | coord_flip() 99 | }, bg="transparent") 100 | }) 101 | -------------------------------------------------------------------------------- /Examples/UN_Advanced/ui.R: -------------------------------------------------------------------------------- 1 | #user interface for United Nations Advanced Example 2 | shinyUI(fluidPage( 3 | 4 | # Application title 5 | titlePanel("Ideal Points"), 6 | 7 | # Sidebar with a slider input for number of bins 8 | 9 | sidebarPanel( 10 | h3("Ideal Points Estimation"), 11 | # Select Justices name here 12 | selectizeInput("name", 13 | label = "Country Name(s) of Interest", 14 | choices = unique(Ideal_Point_Data$Name), 15 | multiple = T, 16 | options = list(maxItems = 5, 17 | placeholder = 'Select a name'), 18 | selected = "United States of America" 19 | 20 | ), 21 | 22 | 23 | # Term plot 24 | plotOutput("termPlot", height = 200), 25 | 26 | helpText("Data: Bailey, Michael, Anton Strezhnev and Erik Voeten. Forthcoming. “Estimating Dynamic State Preferences from United Nations Voting Data.” Journal of Conflict Resolution. ") 27 | ), 28 | 29 | # Show a plot of the generated distribution 30 | mainPanel( 31 | graphOutput("trendPlot") 32 | ) 33 | ) 34 | ) 35 | -------------------------------------------------------------------------------- /Examples/UN_Advanced/www/plotlyGraphWidget.js: -------------------------------------------------------------------------------- 1 | var binding = new Shiny.OutputBinding(); 2 | 3 | binding.find = function(scope) { 4 | console.log('binding.scope'); 5 | return $(scope).find('.graphs'); 6 | }; 7 | 8 | binding.renderValue = function(el, messages) { 9 | // this gets called when the inputs change 10 | // messages is the list of named lists passed up 11 | // by renderGraph. these named lists are postMessage 12 | // commands that get passed into the embedded graph. 13 | // See https://github.com/plotly/Embed-API for details 14 | console.log('renderValue, messages: ', JSON.stringify(messages)); 15 | var $el = $(el); 16 | 17 | if (!window.graphs) { 18 | console.log('first time rendering'); 19 | initGraphs(messages); 20 | } 21 | messages.forEach(function(message){ 22 | console.log('posting ', message, ' to ', message.id); 23 | window.graphs[message.id].graphContentWindow.postMessage(message, 'https://plot.ly'); 24 | }); 25 | 26 | }; 27 | 28 | Shiny.outputBindings.register(binding, "plotlyshiny"); 29 | 30 | function initGraphs(initialMessages){ 31 | var $graphs = $('.graphs'); 32 | var graphs = {}; 33 | $graphs.each(function(i){ 34 | graphs[$graphs[i].id] = { 35 | graphContentWindow: $graphs[i].contentWindow, 36 | id: $graphs[i].id, 37 | pinger: setInterval(function(){ 38 | $graphs[i].contentWindow.postMessage({task: 'ping'}, 'https://plot.ly'); 39 | }, 500) 40 | }; 41 | }); 42 | 43 | // messages coming from the embedded graphs 44 | // either 'pong' or the 'hover', 'zoom', 'click' events 45 | window.addEventListener('message', function(e){ 46 | var message = e.data; 47 | for(var graph_id in graphs){ 48 | if(graphs[graph_id].graphContentWindow === e.source) { 49 | var graph = graphs[graph_id]; 50 | break; 51 | } 52 | } 53 | 54 | var pinger = graph.pinger; 55 | var graphContentWindow = graph.graphContentWindow; 56 | var id = graph.id; 57 | 58 | if('pong' in message && message.pong) { 59 | console.log('>> clearing!'); 60 | clearInterval(pinger); 61 | graphContentWindow.postMessage({ 62 | 'task': 'listen', 63 | 'events': ['zoom', 'click', 'hover']}, 64 | 'https://plot.ly'); 65 | initialMessages.forEach(function(initialMessage){ 66 | if(initialMessage.id == id){ 67 | graphContentWindow.postMessage(initialMessage, 'https://plot.ly'); 68 | } 69 | }); 70 | // TODO: send pong back to R 71 | } else if (message.type==='hover' || 72 | message.type==='zoom' || 73 | message.type==='click') { 74 | console.log('>> ', message.type); 75 | if(message.type !== 'zoom') { 76 | for(var i in message.points) { 77 | delete message.points[i].data; 78 | } 79 | } 80 | // TODO: Send back to R 81 | } 82 | }); 83 | window.graphs = graphs; 84 | } 85 | -------------------------------------------------------------------------------- /Examples/UN_Simple/.Rapp.history: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chriddyp/plotly-shiny/c16d0339f267fbc5f7d1622b4b0789508a3e64ca/Examples/UN_Simple/.Rapp.history -------------------------------------------------------------------------------- /Examples/UN_Simple/Data/UN_IdealPoints.csv: -------------------------------------------------------------------------------- 1 | Year,ID,Name,Ideal.point 1946,UKG,United Kingdom,2.158 1947,UKG,United Kingdom,2.119 1948,UKG,United Kingdom,2.074 1949,UKG,United Kingdom,2.039 1950,UKG,United Kingdom,1.574 1951,UKG,United Kingdom,1.832 1952,UKG,United Kingdom,2.106 1953,UKG,United Kingdom,2.193 1954,UKG,United Kingdom,2.391 1955,UKG,United Kingdom,2.209 1956,UKG,United Kingdom,2.247 1957,UKG,United Kingdom,2.225 1958,UKG,United Kingdom,2.389 1959,UKG,United Kingdom,2.067 1960,UKG,United Kingdom,1.899 1961,UKG,United Kingdom,1.844 1962,UKG,United Kingdom,2.002 1963,UKG,United Kingdom,2.072 1965,UKG,United Kingdom,2.006 1966,UKG,United Kingdom,2.108 1967,UKG,United Kingdom,2.192 1968,UKG,United Kingdom,2.108 1969,UKG,United Kingdom,2.024 1970,UKG,United Kingdom,1.85 1971,UKG,United Kingdom,1.599 1972,UKG,United Kingdom,1.965 1973,UKG,United Kingdom,2.118 1974,UKG,United Kingdom,1.777 1975,UKG,United Kingdom,1.859 1976,UKG,United Kingdom,2.071 1977,UKG,United Kingdom,1.957 1978,UKG,United Kingdom,2.018 1979,UKG,United Kingdom,2.028 1980,UKG,United Kingdom,1.976 1981,UKG,United Kingdom,1.925 1982,UKG,United Kingdom,1.955 1983,UKG,United Kingdom,1.971 1984,UKG,United Kingdom,2.047 1985,UKG,United Kingdom,2.04 1986,UKG,United Kingdom,2.103 1987,UKG,United Kingdom,2.03 1988,UKG,United Kingdom,2.052 1989,UKG,United Kingdom,2.105 1990,UKG,United Kingdom,2.108 1991,UKG,United Kingdom,1.992 1992,UKG,United Kingdom,1.863 1993,UKG,United Kingdom,1.904 1994,UKG,United Kingdom,1.986 1995,UKG,United Kingdom,2.228 1996,UKG,United Kingdom,2.034 1997,UKG,United Kingdom,1.977 1998,UKG,United Kingdom,1.759 1999,UKG,United Kingdom,1.687 2000,UKG,United Kingdom,1.689 2001,UKG,United Kingdom,1.626 2002,UKG,United Kingdom,1.674 2003,UKG,United Kingdom,1.67 2004,UKG,United Kingdom,1.635 2005,UKG,United Kingdom,1.671 2006,UKG,United Kingdom,1.533 2007,UKG,United Kingdom,1.625 2008,UKG,United Kingdom,1.588 2009,UKG,United Kingdom,1.479 2010,UKG,United Kingdom,1.611 2011,UKG,United Kingdom,1.497 2012,UKG,United Kingdom,1.53 1946,USA,United States of America,1.714 1947,USA,United States of America,1.813 1948,USA,United States of America,1.936 1949,USA,United States of America,1.877 1950,USA,United States of America,1.811 1951,USA,United States of America,1.828 1952,USA,United States of America,1.905 1953,USA,United States of America,1.693 1954,USA,United States of America,1.482 1955,USA,United States of America,1.719 1956,USA,United States of America,1.285 1957,USA,United States of America,1.247 1958,USA,United States of America,1.266 1959,USA,United States of America,1.547 1960,USA,United States of America,1.532 1961,USA,United States of America,1.698 1962,USA,United States of America,1.889 1963,USA,United States of America,1.852 1965,USA,United States of America,2.011 1966,USA,United States of America,2.069 1967,USA,United States of America,2.259 1968,USA,United States of America,2.213 1969,USA,United States of America,2.093 1970,USA,United States of America,2.132 1971,USA,United States of America,1.805 1972,USA,United States of America,2.04 1973,USA,United States of America,2.209 1974,USA,United States of America,2.031 1975,USA,United States of America,2.145 1976,USA,United States of America,2.393 1977,USA,United States of America,2.206 1978,USA,United States of America,2.228 1979,USA,United States of America,2.277 1980,USA,United States of America,2.318 1981,USA,United States of America,2.658 1982,USA,United States of America,2.568 1983,USA,United States of America,2.592 1984,USA,United States of America,2.737 1985,USA,United States of America,2.742 1986,USA,United States of America,2.851 1987,USA,United States of America,2.927 1988,USA,United States of America,2.902 1989,USA,United States of America,2.962 1990,USA,United States of America,2.893 1991,USA,United States of America,2.754 1992,USA,United States of America,2.766 1993,USA,United States of America,2.734 1994,USA,United States of America,2.688 1995,USA,United States of America,2.939 1996,USA,United States of America,3.014 1997,USA,United States of America,2.923 1998,USA,United States of America,2.854 1999,USA,United States of America,2.678 2000,USA,United States of America,2.611 2001,USA,United States of America,2.576 2002,USA,United States of America,2.628 2003,USA,United States of America,2.796 2004,USA,United States of America,2.771 2005,USA,United States of America,2.894 2006,USA,United States of America,2.879 2007,USA,United States of America,2.771 2008,USA,United States of America,2.752 2009,USA,United States of America,2.564 2010,USA,United States of America,2.519 2011,USA,United States of America,2.522 2012,USA,United States of America,2.681 1946,CAN,Canada,1.849 1947,CAN,Canada,1.987 1948,CAN,Canada,1.911 1949,CAN,Canada,1.672 1950,CAN,Canada,1.812 1951,CAN,Canada,1.916 1952,CAN,Canada,1.989 1953,CAN,Canada,1.745 1954,CAN,Canada,1.746 1955,CAN,Canada,1.714 1956,CAN,Canada,1.554 1957,CAN,Canada,1.608 1958,CAN,Canada,1.579 1959,CAN,Canada,1.096 1960,CAN,Canada,1.106 1961,CAN,Canada,1.467 1962,CAN,Canada,1.555 1963,CAN,Canada,1.61 1965,CAN,Canada,1.685 1966,CAN,Canada,1.774 1967,CAN,Canada,1.769 1968,CAN,Canada,1.577 1969,CAN,Canada,1.615 1970,CAN,Canada,1.577 1971,CAN,Canada,1.391 1972,CAN,Canada,1.549 1973,CAN,Canada,1.479 1974,CAN,Canada,1.471 1975,CAN,Canada,1.457 1976,CAN,Canada,1.501 1977,CAN,Canada,1.687 1978,CAN,Canada,1.768 1979,CAN,Canada,1.81 1980,CAN,Canada,1.824 1981,CAN,Canada,1.773 1982,CAN,Canada,1.656 1983,CAN,Canada,1.658 1984,CAN,Canada,1.703 1985,CAN,Canada,1.645 1986,CAN,Canada,1.555 1987,CAN,Canada,1.546 1988,CAN,Canada,1.403 1989,CAN,Canada,1.356 1990,CAN,Canada,1.286 1991,CAN,Canada,1.271 1992,CAN,Canada,1.234 1993,CAN,Canada,1.138 1994,CAN,Canada,1.145 1995,CAN,Canada,1.106 1996,CAN,Canada,1.196 1997,CAN,Canada,1.116 1998,CAN,Canada,1.178 1999,CAN,Canada,1.173 2000,CAN,Canada,1.112 2001,CAN,Canada,1.184 2002,CAN,Canada,1.129 2003,CAN,Canada,1.127 2004,CAN,Canada,1.236 2005,CAN,Canada,1.264 2006,CAN,Canada,1.412 2007,CAN,Canada,1.56 2008,CAN,Canada,1.611 2009,CAN,Canada,1.582 2010,CAN,Canada,1.529 2011,CAN,Canada,1.856 2012,CAN,Canada,2.059 -------------------------------------------------------------------------------- /Examples/UN_Simple/global.R: -------------------------------------------------------------------------------- 1 | # Golbal environment contains information needed in both the ui and server scripts 2 | # Lines 3-6 should be in all global.R scripts for shiny/plotly Apps 3 | library(plotly) 4 | library(shiny) 5 | library(dplyr) 6 | 7 | py <- plotly(username="rAPI", key="yu680v5eii", base_url="https://plot.ly") 8 | 9 | source("plotlyGraphWidget.R") 10 | 11 | # User Specific information: 12 | # Load data 13 | ## In this example, data is used in both the ui and server scripts 14 | Ideal_Point_Data <- read.csv("Data/UN_IdealPoints.csv", stringsAsFactors=F) 15 | 16 | -------------------------------------------------------------------------------- /Examples/UN_Simple/plotlyGraphWidget.R: -------------------------------------------------------------------------------- 1 | #This script is necessary in the app folder 2 | #but the user should not have to edit it 3 | 4 | #Output Graph Function 5 | graphOutput <- function(inputId, width="100%", height="550px") { 6 | tagList( 7 | singleton(tags$head( 8 | tags$script(src="plotlyGraphWidget.js") 9 | )), 10 | tags$iframe(id=inputId, src="https://plot.ly/~playground/7.embed", 11 | class="graphs", style="border:none;", seamless=TRUE, width=width, height=height) 12 | ) 13 | } 14 | 15 | renderGraph <- function(expr, env=parent.frame(), quoted=FALSE) { 16 | ## This gets called when inputs change -- 17 | ## Place data wrangling code in here 18 | ## and pass the result to the client 19 | ## to be graphed. 20 | 21 | installExprFunction(expr, "func", env, quoted) 22 | 23 | function(){ 24 | data = func(); 25 | ## data is the state of the widgets: see server.R 26 | ## this function returns a list of named lists that descripe 27 | ## valid postMessage commands to be sent to the embedded iframe. 28 | ## see binding.renderValue for the receiving JS side of this function 29 | ## and https://github.com/plotly/Embed-API for more about the postMessage 30 | ## graph messages 31 | return(data) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Examples/UN_Simple/runApp.R: -------------------------------------------------------------------------------- 1 | install.packages("shiny") 2 | install.packages("dplyr") 3 | install.packages("devtools") 4 | 5 | library("devtools") 6 | install_github("ropensci/plotly") 7 | 8 | shiny::runApp() -------------------------------------------------------------------------------- /Examples/UN_Simple/server.R: -------------------------------------------------------------------------------- 1 | #load libraries 2 | library(ggthemes) 3 | 4 | shinyServer(function(input, output, session) { 5 | 6 | output$trendPlot <- renderGraph({ 7 | if (length(input$name)==0) print("Please select at least one country") 8 | 9 | else { 10 | df_trend <- Ideal_Point_Data %>% 11 | filter(Name %in% input$name) 12 | 13 | ggideal_point <- ggplot(df_trend) + 14 | geom_line(aes(x=Year, y=Ideal.point, by=Name, color=Name)) + 15 | labs(x = "Year") + 16 | labs(y = "Ideology") + 17 | labs(title = "Ideal Points for Countries") + 18 | scale_colour_hue("clarity",l=70, c=150) + 19 | theme_few() 20 | 21 | # Year range 22 | min_Year <- min(df_trend$Year) 23 | max_Year <- max(df_trend$Year) 24 | 25 | # use gg2list() to convert from ggplot->plotly 26 | gg <- gg2list(ggideal_point) 27 | 28 | # Send this message up to the browser client, which will get fed through to 29 | # Plotly's javascript graphing library embedded inside the graph 30 | return(list( 31 | list( 32 | id="trendPlot", 33 | task="newPlot", 34 | data=gg$data, 35 | layout=gg$layout 36 | ) 37 | )) 38 | } 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /Examples/UN_Simple/ui.R: -------------------------------------------------------------------------------- 1 | shinyUI(fluidPage( 2 | 3 | # Application title 4 | titlePanel("Ideal Points"), 5 | 6 | # Sidebar with a slider input for number of bins 7 | 8 | sidebarPanel( 9 | h3("Ideal Points Estimation"), 10 | # Select Justices name here 11 | selectizeInput("name", 12 | label = "Country Name(s) of Interest", 13 | choices = unique(Ideal_Point_Data$Name), 14 | multiple = T, 15 | options = list(maxItems = 5, 16 | placeholder = 'Select a name'), 17 | selected = "United States of America" 18 | 19 | ), 20 | 21 | 22 | # Term plot 23 | plotOutput("termPlot", height = 200), 24 | 25 | helpText("Data: Bailey, Michael, Anton Strezhnev and Erik Voeten. Forthcoming. “Estimating Dynamic State Preferences from United Nations Voting Data.” Journal of Conflict Resolution. ") 26 | ), 27 | 28 | # Show a plot of the generated distribution 29 | mainPanel( 30 | graphOutput("trendPlot") 31 | ) 32 | ) 33 | ) 34 | -------------------------------------------------------------------------------- /Examples/UN_Simple/www/plotlyGraphWidget.js: -------------------------------------------------------------------------------- 1 | var binding = new Shiny.OutputBinding(); 2 | 3 | binding.find = function(scope) { 4 | console.log('binding.scope'); 5 | return $(scope).find('.graphs'); 6 | }; 7 | 8 | binding.renderValue = function(el, messages) { 9 | // this gets called when the inputs change 10 | // messages is the list of named lists passed up 11 | // by renderGraph. these named lists are postMessage 12 | // commands that get passed into the embedded graph. 13 | // See https://github.com/plotly/Embed-API for details 14 | console.log('renderValue, messages: ', JSON.stringify(messages)); 15 | var $el = $(el); 16 | 17 | if (!window.graphs) { 18 | console.log('first time rendering'); 19 | initGraphs(messages); 20 | } 21 | messages.forEach(function(message){ 22 | console.log('posting ', message, ' to ', message.id); 23 | window.graphs[message.id].graphContentWindow.postMessage(message, 'https://plot.ly'); 24 | }); 25 | 26 | }; 27 | 28 | Shiny.outputBindings.register(binding, "plotlyshiny"); 29 | 30 | function initGraphs(initialMessages){ 31 | var $graphs = $('.graphs'); 32 | var graphs = {}; 33 | $graphs.each(function(i){ 34 | graphs[$graphs[i].id] = { 35 | graphContentWindow: $graphs[i].contentWindow, 36 | id: $graphs[i].id, 37 | pinger: setInterval(function(){ 38 | $graphs[i].contentWindow.postMessage({task: 'ping'}, 'https://plot.ly'); 39 | }, 500) 40 | }; 41 | }); 42 | 43 | // messages coming from the embedded graphs 44 | // either 'pong' or the 'hover', 'zoom', 'click' events 45 | window.addEventListener('message', function(e){ 46 | var message = e.data; 47 | for(var graph_id in graphs){ 48 | if(graphs[graph_id].graphContentWindow === e.source) { 49 | var graph = graphs[graph_id]; 50 | break; 51 | } 52 | } 53 | 54 | var pinger = graph.pinger; 55 | var graphContentWindow = graph.graphContentWindow; 56 | var id = graph.id; 57 | 58 | if('pong' in message && message.pong) { 59 | console.log('>> clearing!'); 60 | clearInterval(pinger); 61 | graphContentWindow.postMessage({ 62 | 'task': 'listen', 63 | 'events': ['zoom', 'click', 'hover']}, 64 | 'https://plot.ly'); 65 | initialMessages.forEach(function(initialMessage){ 66 | if(initialMessage.id == id){ 67 | graphContentWindow.postMessage(initialMessage, 'https://plot.ly'); 68 | } 69 | }); 70 | // TODO: send pong back to R 71 | } else if (message.type==='hover' || 72 | message.type==='zoom' || 73 | message.type==='click') { 74 | console.log('>> ', message.type); 75 | if(message.type !== 'zoom') { 76 | for(var i in message.points) { 77 | delete message.points[i].data; 78 | } 79 | } 80 | // TODO: Send back to R 81 | } 82 | }); 83 | window.graphs = graphs; 84 | } 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Embed Plotly Graphs in Shiny Apps 2 | 3 | March 11, 2017 4 | 5 | This repository was created 2 years and a lot has changed with Plotly's R library since then! The examples in this repository are pretty outdated. Here are some more up-to-date resources to get you involved with Plotly and Shiny: 6 | 7 | - [Plotly and Shiny Gallery](https://plot.ly/r/shiny-gallery/) 8 | - [Plotly and Shiny Tutorial](https://plot.ly/r/shiny-tutorial/) 9 | - [Plotly's R Library](https://plot.ly/r/) 10 | - [Plotly and R User Guide Book](https://cpsievert.github.io/plotly_book/) 11 | - [@plotlygraphs](https://twitter.com/plotlygraphs) 12 | - [Shiny and Plotly Consulting](https://plot.ly/products/consulting-and-oem/) 13 | -------------------------------------------------------------------------------- /What_You_Need/global.R: -------------------------------------------------------------------------------- 1 | # global.R template for Plotly/Shiny apps 2 | 3 | library(plotly) 4 | library(shiny) 5 | 6 | py <- plotly(username="rAPI", key="yu680v5eii", base_url="https://plot.ly") 7 | 8 | source("plotlyGraphWidget.R") 9 | -------------------------------------------------------------------------------- /What_You_Need/plotlyGraphWidget.R: -------------------------------------------------------------------------------- 1 | #This script is necessary in the app folder 2 | #but the user should not have to edit it 3 | 4 | #Output Graph Function 5 | graphOutput <- function(inputId, width="100%", height="550px") { 6 | tagList( 7 | singleton(tags$head( 8 | tags$script(src="plotlyGraphWidget.js") 9 | )), 10 | tags$iframe(id=inputId, src="https://plot.ly/~playground/7.embed", 11 | class="graphs", style="border:none;", seamless=TRUE, width=width, height=height) 12 | ) 13 | } 14 | 15 | renderGraph <- function(expr, env=parent.frame(), quoted=FALSE) { 16 | ## This gets called when inputs change -- 17 | ## Place data wrangling code in here 18 | ## and pass the result to the client 19 | ## to be graphed. 20 | 21 | 22 | installExprFunction(expr, "func", env, quoted) 23 | 24 | function(){ 25 | data = func(); 26 | ## data is the state of the widgets: see server.R 27 | ## this function returns a list of named lists that descripe 28 | ## valid postMessage commands to be sent to the embedded iframe. 29 | ## see binding.renderValue for the receiving JS side of this function 30 | ## and https://github.com/plotly/Embed-API for more about the postMessage 31 | ## graph messages 32 | return(data) 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /What_You_Need/runApp.R: -------------------------------------------------------------------------------- 1 | # runApp.R template for Plotly/Shiny apps 2 | # open this script in R and select 3 | 4 | install.packages("shiny") 5 | install.packages("dplyr") 6 | install.packages("devtools") 7 | 8 | library("devtools") 9 | install_github("ropensci/plotly") 10 | 11 | shiny::runApp() -------------------------------------------------------------------------------- /What_You_Need/server_Template_GGPLOT.R: -------------------------------------------------------------------------------- 1 | ## Template for server.R script for Plotly/Shiny apps 2 | 3 | shinyServer(function(input, output, session) { 4 | 5 | ## ADD DATA 6 | YOUR_DATA<- call_your_data_file 7 | 8 | output$trendPlot <- renderGraph({ 9 | 10 | ## Create your ggplot 11 | YOUR_PLOT <- ggplot(YOUR_DATA, YOUR_GGPLOT_SPECIFICATIONS) 12 | 13 | ## You can edit your graph with ggplot syntax here! 14 | 15 | ## This function rewrites the ggplot figure in Plotly syntax 16 | ## and returns data information (gg$data) and layout information (gg$layout) 17 | gg<- gg2list(YOUR_PLOT) 18 | 19 | ## You can edit your graph with Plotly syntax here! 20 | 21 | # This sends message up to the browser client, which will get fed through to 22 | # Plotly's javascript graphing library embedded inside the graph 23 | return(list( 24 | list( 25 | id="trendPlot", 26 | task="newPlot", 27 | data=gg$data, 28 | layout=gg$layout 29 | ) 30 | )) 31 | 32 | }) 33 | 34 | }) -------------------------------------------------------------------------------- /What_You_Need/server_Template_PLOTLY.R: -------------------------------------------------------------------------------- 1 | ## Template for server.R script for Plotly/Shiny apps 2 | 3 | shinyServer(function(input, output, session) { 4 | 5 | ## ADD DATA 6 | YOUR_DATA<- call_your_data_file_here 7 | 8 | output$trendPlot <- renderGraph({ 9 | 10 | ## Create your Plotly graph 11 | trace <- list( YOUR_TRACE_SPECIFICATIONS) 12 | 13 | # define data 14 | data <- list(trace) 15 | # define layout information 16 | layout<- list(YOUR_LAYOUT_SPECIFICATIONS) 17 | 18 | # This sends message up to the browser client, which will get fed through to 19 | # Plotly's javascript graphing library embedded inside the graph 20 | return(list( 21 | list( 22 | id="trendPlot", 23 | task="newPlot", 24 | data=data, 25 | layout=layout 26 | ) 27 | )) 28 | 29 | }) 30 | 31 | }) -------------------------------------------------------------------------------- /What_You_Need/ui_Template.R: -------------------------------------------------------------------------------- 1 | # User interface (ui.R) template for Plotly/Shiny apps 2 | # Add 3 | 4 | shinyUI(pageWithSidebar( 5 | 6 | headerPanel("ADD_YOUR_HEADER"), 7 | 8 | sidebarPanel("ADD_YOUR_SIDEBAR"), 9 | 10 | ## Displays plotly graph in the main panel 11 | mainPanel( 12 | graphOutput('trendPlot') 13 | ) 14 | )) 15 | -------------------------------------------------------------------------------- /What_You_Need/www/plotlyGraphWidget.js: -------------------------------------------------------------------------------- 1 | var binding = new Shiny.OutputBinding(); 2 | 3 | binding.find = function(scope) { 4 | // not sure what this function does, or 5 | // why its necessary... 6 | console.log('binding.scope'); 7 | return $(scope).find('.graphs'); 8 | }; 9 | 10 | binding.renderValue = function(el, messages) { 11 | // this gets called when the inputs change 12 | // messages is the list of named lists passed up 13 | // by renderGraph. these named lists are postMessage 14 | // commands that get passed into the embedded graph. 15 | // See https://github.com/plotly/Embed-API for details 16 | console.log('renderValue, messages: ', JSON.stringify(messages)); 17 | var $el = $(el); 18 | 19 | if (!window.graphs) { 20 | console.log('first time rendering'); 21 | initGraphs(messages); 22 | } 23 | messages.forEach(function(message){ 24 | console.log('posting ', message, ' to ', message.id); 25 | window.graphs[message.id].graphContentWindow.postMessage(message, 'https://plot.ly'); 26 | }); 27 | 28 | }; 29 | 30 | Shiny.outputBindings.register(binding, "plotlyshiny"); 31 | 32 | function initGraphs(initialMessages){ 33 | var $graphs = $('.graphs'); 34 | var graphs = {}; 35 | $graphs.each(function(i){ 36 | graphs[$graphs[i].id] = { 37 | graphContentWindow: $graphs[i].contentWindow, 38 | id: $graphs[i].id, 39 | pinger: setInterval(function(){ 40 | $graphs[i].contentWindow.postMessage({task: 'ping'}, 'https://plot.ly'); 41 | }, 500) 42 | }; 43 | }); 44 | 45 | 46 | // messages coming from the embedded graphs 47 | // either 'pong' or the 'hover', 'zoom', 'click' events 48 | window.addEventListener('message', function(e){ 49 | var message = e.data; 50 | for(var graph_id in graphs){ 51 | if(graphs[graph_id].graphContentWindow === e.source) { 52 | var graph = graphs[graph_id]; 53 | break; 54 | } 55 | } 56 | 57 | var pinger = graph.pinger; 58 | var graphContentWindow = graph.graphContentWindow; 59 | var id = graph.id; 60 | 61 | if('pong' in message && message.pong) { 62 | console.log('>> clearing!'); 63 | clearInterval(pinger); 64 | graphContentWindow.postMessage({ 65 | 'task': 'listen', 66 | 'events': ['zoom', 'click', 'hover']}, 67 | 'https://plot.ly'); 68 | initialMessages.forEach(function(initialMessage){ 69 | if(initialMessage.id == id){ 70 | graphContentWindow.postMessage(initialMessage, 'https://plot.ly'); 71 | } 72 | }); 73 | // TODO: send pong back to R 74 | } else if (message.type==='hover' || 75 | message.type==='zoom' || 76 | message.type==='click') { 77 | console.log('>> ', message.type); 78 | if(message.type !== 'zoom') { 79 | for(var i in message.points) { 80 | delete message.points[i].data; 81 | } 82 | } 83 | // TODO: Send back to R 84 | } 85 | }); 86 | window.graphs = graphs; 87 | } 88 | --------------------------------------------------------------------------------