class: hide-count cover_bkg .title_content[ .slide-1-title[ <h1 style="font-family:Courier New;color:white;padding-top:100px;font-size:45px;margin-bottom:0;"> JS + R == Amazing Applications</h1> <h3 style="color:#86CAC6;margin-top:0;">Understanding HTMLWidgets</h3> <span>Maya Gans</span> ] ] .footer-text[ <a href="bit.ly/atoruswidgets">bit.ly/atoruswidgets</a> ] --- class: middle hide-count dark_bkg .title[ # HTMLWidgets ] .content[ .gridcontainer[ .littlebox[ <p style="margin-top:30px;">WHAT ARE THEY?</p> ] .littlebox[ <p style="margin-top:16px;">WHY SHOULD I CARE?</p> ] .littlebox[ <p style="margin-top:16px;">HOW DO I MAKE ONE?</p> ] ] ] <img src="img/plotly.png" style="position:absolute; width: 60%; right: 212px; bottom: -7px;"> </img> <img src="img/leaflet.png" style="position:absolute; width: 50%; top: 22px; left: -150px;"> </img> --- class: hide-count cover_bkg .title_content[ <h1 style="color:white;padding-top:50px;font-size:80px;margin-bottom:0;width:30%;">Shiny: An Interlude</h1> ] --- class: middle hide-count dark_bkg .title[ # A Shiny Application ] .content[ <label for="paramcd">Choose a Parameter Code:</label> <select name="paramcd" id="paramcd" style="padding: 5px 10px; font-family: 'Maven Pro';"> <option value="img/sodium.PNG">Sodium</option> <option value="img/calcium.PNG">Calcium</option> </select> <br> <br> <div id="selected_img"> <img id="my_changing_image" src="img/sodium.PNG"></img> </div> <script> $( document ).ready(function() { $('#paramcd').change(function(){ $('#my_changing_image').attr('src', $('#paramcd').val()); }); }); </script> ] --- class: middle hide-count dark_bkg .title[ # Shiny Code ] .content[ ```r ui <- fluidPage( * selectInput("measurement", NULL, choices = c("Sodium", "Calcium")), plotOutput("plot") ) server <- function(input, output, session) { data <- reactive({ mydata %>% filter(measurement == input$measurement) }) output$plot <- renderPlot({ ggplot(data(), aes(x = xAxis, y = yAxis, group = IDs, color = IDs) ) }) } shinyApp(ui, server) ``` ] <img src="img/zoom.png" style="position: absolute; bottom: -300px; left: 385px; -webkit-transform: scaleX(-1); transform: scaleX(-1);"></img> --- class: middle hide-count dark_bkg .title[ # Shiny: Magic Under the Hood ] .content[ .cardbox[ <div class="flip-card"> <div class="flip-card-inner"> <div class="flip-card-front"> <h2>HTML</h2> </div> <div class="flip-card-back"> <h3>Hypertext Markup Language</h3> </div> </div> </div> <div class="flip-card"> <div class="flip-card-inner"> <div class="flip-card-front"> <h2>CSS</h2> </div> <div class="flip-card-back"> <h3>Cascading <br> Style Sheets</h3> </div> </div> </div> <div class="flip-card"> <div class="flip-card-inner"> <div class="flip-card-front"> <h2>JavaScript</h2> </div> <div class="flip-card-back"> <h3>The <br> Language <br> of the <br> Internet!</h3> </div> </div> </div> ] ] <img src="img/witch.png" style="position:absolute; bottom: 0px; width: 50%; left: -20px; transform: rotate(10deg);"></img> --- class: middle hide-count dark_bkg .title[ # Shiny: HTML ] .content[ ```html <div class="form-group shiny-input-container"> <label class="control-label" id="measurement-label" for="measurement"> * Y-Axis </label> <div> * <select id="measurement"> * <option value="Sodium" selected>Sodium</option> * <option value="Calcium">Calcium</option> * </select> <script type="application/json" data-for="measurement" data-nonempty=""> {"plugins":["selectize-plugin-a11y"]} </script> </div> </div> ``` ] --- class: middle hide-count dark_bkg .title[ # Shiny: CSS ] .content[ .pull-left[ ```css .selectize-input { border: 1px solid #cccccc; padding: 6px 12px; display: inline-block; width: 100%; overflow: hidden; position: relative; z-index: 1; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; -webkit-box-shadow: none; box-shadow: none; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } ``` <style type="text/css"> .selectize-input { border: 1px solid #cccccc; padding: 6px 12px; display: inline-block; width: 100%; overflow: hidden; position: relative; z-index: 1; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; -webkit-box-shadow: none; box-shadow: none; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } </style> ]] <img src="img/lipstick.png" style="position:absolute; bottom: 0px; left: 155px; width: 55%; top: 130px;"></img> <img src="img/line.PNG" style="position:absolute; bottom: 78px; left: 755px; width: 20%;"></img> --- class: middle hide-count dark_bkg .title[ # Shiny: JavaScript ] .content[ ```js ... success: function(res) { $.each(res, function(index, elem) { let optgroupId = elem[settings.optgroupField || "optgroup"]; let optgroup = {}; optgroup[settings.optgroupLabelField || "label"] = optgroupId; optgroup[settings.optgroupValueField || "value"] = optgroupId; selectize.addOptionGroup(optgroupId, optgroup); }); callback(res); if (!loaded) { * if (data.hasOwnProperty('value')) { * selectize.setValue(data.value); } else if (settings.maxItems === 1) { selectize.setValue(res[0].value); } } loaded = true; } ... ``` ] --- class: hide-count cover_bkg .title_content[ <h1 style="color:white;padding-top:50px;font-size:80px;margin-bottom:0;width:30%;">What's an HTMLWidget</h1> ] --- class: middle hide-count dark_bkg .title[ # Overview ] .content[ JavaScript runs in the browser Why reinvent the wheel? Enhance Shiny and Rmarkdown ] <img src="img/handoff.png" style=" position: absolute; bottom: 0px; left: -30px; width: 85%;"></img> <div id="hojs" class="handoff-text">JavaScript</div> <div id="hor" class="handoff-text">R</div> <div id="hoyaml" class="handoff-text">YAML</div> --- class: hide-count cover_bkg .title_content[ <h1 style="color:white;padding-top:50px;font-size:80px;margin-bottom:0;width:40%;">Why should I care?</h1> ] --- class: middle hide-count dark_bkg .title[ # Example: Hover Line Plot ] .content[ <div style="margin-left:10%;">
</div> ] <img src="img/mouse.png" style=" position: absolute; bottom: -10px; left: -70px; width: 30%;"></img> <div style="position:absolute; left: 500px; color: #1da5a9; bottom: 150px; font-family: Arial; font-size: 18px; font-size: 20px;">Study Visit Week</div> --- class: middle hide-count dark_bkg .title[ # Further Motivation: Gantt Chart ] .content[
] --- class: hide-count cover_bkg .title_content[ <h1 style="color:white;padding-top:50px;font-size:80px;margin-bottom:0;width:30%;">How do I make one?</h1> ] --- class: middle hide-count dark_bkg .title[ # Example ] .content[ ```r usethis::create_package("atoruswidgets") ``` .borderbox[ ```r htmlwidgets::scaffoldWidget("line_select") ``` ] ] <img style="position:absolute; width: 9%; top: 285px; left: 200px;" src="img/leftcurl.png"></img> <img style="position:absolute; width: 9%; top: 285px; left: 430px;" src="img/midcurl.png"></img> <img style="position:absolute; width: 9%; top: 285px; right: 450px;" src="img/rightcurl.png"></img> <div id="scaffr" class="scaffold-text">line_select.R</div> <div id="scaffjs" class="scaffold-text">line_select.js</div> <div id="scaffyml" class="scaffold-text">line_select.yaml</div> --- class: middle hide-count dark_bkg .title[ # `line_select.R` ] .content[ ```r #' <Add Title> #' <Add Description> #' @import htmlwidgets #' @export line_select <- function(message, width = NULL, height = NULL, elementId = NULL) { # forward options using x * x = list( * message = message * ) # create widget htmlwidgets::createWidget( name = 'line_select', * x, width = width, height = height, package = 'atoruswidgets', elementId = elementId ) } ``` ] <img style="position:absolute; width: 10%; top: 210px; left: 350px;" src="img/arrow1.png"></img> <img src="img/arrow2.png" style="position:absolute; width: 8%; left: 400px; bottom: 70px;"></img> <img style="position:absolute; width: 15%; right: 235px; bottom: 300px;" src="img/arrow3.png"></img> <div id="rarg" class="r-text">User supplied string</div> <div id="rlist" class="r-text">Wrap into a list</div> <div id="routput" class="r-text">Put string in inside HTML element</div> --- class: middle hide-count dark_bkg .title[ # `line_select.yaml` ] .content[ ```yaml # (uncomment to add a dependency) # dependencies: # - name: # version: # src: # script: # stylesheet: ``` ] <img src="img/handshake.png" style="position:absolute; position: absolute; width: 50%; left: 395px; "></img> <img src="img/line.PNG" style="position:absolute; width: 50%; bottom: 135px; left: -200px; "></img> --- class: middle hide-count dark_bkg .title[ # `line_select.js` ] .content[ ```js HTMLWidgets.widget({ name: 'line_select', type: 'output', factory: function(el, width, height) { // TODO: define shared variables for this instance return { renderValue: function(x) { // TODO: code to render the widget, e.g. * el.innerText = x.message; }, resize: function(width, height) { // TODO: code to re-render the widget with a new size } }; } }); ``` ] <img src="img/cloud.png" style="width: 30%; left: 570px; top: 290px; height: 25%; position: absolute;"></img> <div id="jsmessage" class="message-text">kind of like x$message</div> --- class: middle hide-count dark_bkg .title[ # Putting it all together ] .content[ ```r line_plot("This is a line plot.") ``` <div style="background-color:white;color:black;font-family:'Times New Roman';height:200px;"> This is a line plot. <div> ] <img style="position:absolute; width: 80%; top: 32px; left: 235px;" src="img/inspector.png"></img> --- class: middle hide-count dark_bkg .title[ # Under the hood ] .content[ ```html <div id="htmlwidget_container"> <div id="htmlwidget-c21cca0e76e520b46fc7" style="width:960px;height:500px;" class="line_select html-widget"> * This is a line plot. </div> </div> <script type="application/json" data-for="htmlwidget-c21cca0e76e520b46fc7"> {"x":{"message":"This is a line plot."},"evals":[],"jsHooks":[]} </script> ``` ] --- class: middle hide-count dark_bkg .title[ # Let Each Language Shine ] .content[ > R is a language and environment for statistical computing and graphics. .test[ > D3.js is a JavaScript library for manipulating documents based on data. ] ] <img src="img/bridge.png" style="position:absolute; position: absolute; top: -150px; left: -212px;"></img> --- class: middle hide-count fin_bkg .title[ # Thank you! Questions? ] <div style="position:absolute;right:350px;bottom:30px;"> <a href="https://twitter.com/mayacelium"><svg class="icon end" fill="#cbf7ed" xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 24 24"><path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/></svg><a> <a href="https://www.linkedin.com/in/mayagans/"><svg class="icon end" xmlns="http://www.w3.org/2000/svg" width="50" height="50" fill="#cbf7ed" viewBox="0 0 24 24"><path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/></a> <a class="mailto" href="mailto:maya.gans@atorusresearch.com"><svg class="icon end" fill="#cbf7ed" xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 24 24"><path d="M12 12.713l-11.985-9.713h23.971l-11.986 9.713zm-5.425-1.822l-6.575-5.329v12.501l6.575-7.172zm10.85 0l6.575 7.172v-12.501l-6.575 5.329zm-1.557 1.261l-3.868 3.135-3.868-3.135-8.11 8.848h23.956l-8.11-8.848z"/></svg></a> </div>