├── .Rbuildignore ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── R ├── body-input.R ├── color-generator.R ├── color-vector.R ├── utils-pipe.R └── utils.R ├── README.md ├── inst ├── app │ ├── app.R │ └── www │ │ ├── script.js │ │ └── styles.css ├── examples │ └── app.R ├── images │ └── README_img.png ├── js │ ├── shinyBody.js │ └── styles.css └── svgs │ └── human.svg ├── man ├── bodyInput.Rd ├── bodyPalette.Rd └── pipe.Rd └── shinyBody.Rproj /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^LICENSE\.md$ 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rhistory 2 | .RData 3 | .Rproj.user 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: shinyBody 2 | Type: Package 3 | Title: An SVG Human Body Shiny Input Widget 4 | Version: 0.1.0 5 | Authors@R: 6 | person(given = "Maya", 7 | family = "Gans", 8 | role = c("aut", "cre"), 9 | email = "jaffemaya@gmail.com" 10 | ) 11 | Description: Just a single svg human body widget to add to your shiny app. 12 | License: MIT + file LICENSE 13 | URL: https://github.com/MayaGans/shinyBody 14 | BugReports: https://github.com/MayaGans/shinyBody/issues 15 | Encoding: UTF-8 16 | LazyData: true 17 | RoxygenNote: 7.1.0 18 | Imports: 19 | magrittr, 20 | shiny, 21 | htmltools, 22 | tidyr, 23 | glue, 24 | fBasics, 25 | grDevices, 26 | stats, 27 | RColorBrewer, 28 | scales, 29 | vctrs 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2020 2 | COPYRIGHT HOLDER: Maya Gans 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2020 Maya Gans 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export("%>%") 4 | export(bodyInput) 5 | export(bodyPalette) 6 | import(shiny) 7 | importFrom(magrittr,"%>%") 8 | -------------------------------------------------------------------------------- /R/body-input.R: -------------------------------------------------------------------------------- 1 | #' @title An SVG Human Body Input 2 | #' 3 | #' This input operates like a \code{shiny::radioButtons()} where you can select one of the body parts! 4 | #' 5 | #' @import shiny 6 | #' 7 | #' @param inputId The input id 8 | #' @param data a vector of 13 numbers to be converted to a continuous color scale. 9 | #' The numbers correspond to the following body part vector: 10 | #' 11 | #' \enumerate{ 12 | #' \item head 13 | #' \item left-shoulder 14 | #' \item right-shoulder 15 | #' \item left-arm 16 | #' \item right-arm 17 | #' \item left-hand 18 | #' \item right-hand 19 | #' \item chest 20 | #' \item stomach 21 | #' \item left-leg 22 | #' \item right-lef 23 | #' \item left-foot 24 | #' \item right-foot 25 | #' } 26 | #' 27 | #' 28 | #' @param low.col continous color scale applied to data - this is the high vale color 29 | #' @param high.col continous color scale applied to data - this is the high value color 30 | #' @param color a single fill color for all body parts 31 | #' @param ... Passed to \code{htmltools::div()} 32 | #' 33 | #' @return The value returned by the input to the Shiny server is either `NULL` 34 | #' when no body part is select or a character string containing 35 | #' the selected body part 36 | #' 37 | #' @export 38 | #' 39 | #' @examples 40 | #' \dontrun{ 41 | #' bodyInput("human", data = rnorm(13, 100), low.col = "pink", high.col = "purple") 42 | #' } 43 | #' \dontrun{ 44 | #' bodyInput("human", color = "steelblue") 45 | #' } 46 | 47 | bodyInput <- function( 48 | inputId, 49 | data = NULL, 50 | low.col = "#eef4fb", 51 | high.col = "#164a85", 52 | color = "Black", 53 | ... 54 | ) { 55 | 56 | if (is.null(data)) { 57 | data = rep(color, 13) 58 | } else { 59 | data = bodyPalette(data, low.col, high.col) 60 | } 61 | 62 | body_options <- list( 63 | html = 64 | HTML(glue::glue( 65 | " 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | " 104 | ) 105 | ) 106 | ) 107 | 108 | htmltools::tagList( 109 | htmltools::htmlDependency( 110 | name = "shinyBody", 111 | version = utils::packageVersion("shinyBody"), 112 | package = "shinyBody", 113 | src = "js", 114 | script = "shinyBody.js", 115 | stylesheet = "styles.css" 116 | ), 117 | tags$div( 118 | # change this to use our css 119 | class = "human-body", 120 | id = inputId, 121 | `data-input-id` = inputId, 122 | ..., 123 | body_options 124 | ) 125 | ) 126 | 127 | } 128 | -------------------------------------------------------------------------------- /R/color-generator.R: -------------------------------------------------------------------------------- 1 | #' Color Generator for the Shiny body input 2 | #' 3 | #' @param n vector of values to create colors for 4 | #' @param low.col the color palette passed from body-input 5 | #' @param high.col the color palette passed from body-input 6 | #' @export 7 | bodyPalette <- function (n, low.col = "#eef4fb", high.col = "#164a85") { 8 | attr(color_vctr(n, text_color = color_scale(grDevices::colorRamp(c(low.col,high.col)))), ".text_color") 9 | } 10 | -------------------------------------------------------------------------------- /R/color-vector.R: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------- 2 | # All code adapted from: 3 | # https://github.com/thebioengineer/colortable/blob/master/R/scale_color_vctr.R 4 | # -------------------------------------------------------------- 5 | 6 | new_color_vctr <- function(vect, text_color = NA, background = NA, style = NA ){ 7 | 8 | stopifnot(is.atomic(vect)) 9 | stopifnot(length(text_color) == 1 | length(text_color) == length(vect)) 10 | stopifnot(length(background) == 1 | length(background) == length(vect)) 11 | stopifnot(length(style) == 1 | length(style) == length(vect)) 12 | 13 | if (is.function(text_color)) 14 | text_color <- text_color(vect) 15 | if (is.function(background)) 16 | background <- background(vect) 17 | 18 | if (length(text_color) == 1) 19 | text_color <- rep(text_color, length(vect)) 20 | if (length(background) == 1) 21 | background <- rep(background, length(vect)) 22 | if (length(style) == 1) 23 | style <- rep(style, length(vect)) 24 | 25 | return( 26 | structure( 27 | vect, 28 | ".text_color" = text_color, 29 | ".background" = background, 30 | ".style" = style, 31 | class = c("color_vctr",class(vect)) 32 | ) 33 | ) 34 | } 35 | 36 | color_vctr <- function(x,..., text_color = NA, background = NA, style = NA){ 37 | new_color_vctr( 38 | x, 39 | text_color = text_color, 40 | background = background, 41 | style = style 42 | ) 43 | } 44 | 45 | color_scale <- function(palette, na.color = "#808080") { 46 | function(x) { 47 | color_scaler <- switch( 48 | scale_col_type(x), 49 | continuous = scales::col_numeric( 50 | palette, 51 | domain = c(min(x, na.rm = TRUE), 52 | max(x, na.rm = TRUE)), 53 | na.color = na.color 54 | ), 55 | binned = scales::col_factor( 56 | palette, 57 | levels = levels(factor(x)), 58 | na.color = na.color) 59 | ) 60 | color_scaler(x) 61 | } 62 | } 63 | 64 | scale_col_type <- function(x) { 65 | ifelse( 66 | inherits(x,c("numeric","integer","Date", "POSIXt")), 67 | "continuous", 68 | "binned" 69 | ) 70 | } 71 | -------------------------------------------------------------------------------- /R/utils-pipe.R: -------------------------------------------------------------------------------- 1 | #' Pipe operator 2 | #' 3 | #' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 4 | #' 5 | #' @name %>% 6 | #' @rdname pipe 7 | #' @keywords internal 8 | #' @export 9 | #' @importFrom magrittr %>% 10 | #' @usage lhs \%>\% rhs 11 | NULL 12 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | `%||%` <- function(x, y) if (is.null(x)) y else x 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # shinyBody 3 | 4 | 5 | 6 | 7 | A custom Shiny input widget built with HTML and CSS that lets you select a body part and will return that body part's name.You can also color limbs based on data by specifying high and low color values: 8 | 9 | # Install using GitHub 10 | 11 | ```{r} 12 | remotes::install_github("MayaGans/shinyBody") 13 | ``` 14 | 15 | # Use Case 16 | 17 | ```{r} 18 | library(shiny) 19 | 20 | ui <- function() { 21 | 22 | fluidPage( 23 | bodyInput("human", data = c(rnorm(13, 100))), 24 | verbatimTextOutput("debug") 25 | ) 26 | } 27 | 28 | server <- function(input, output) { 29 | output$debug <- renderPrint(input$human) 30 | } 31 | 32 | shinyApp(ui = ui, server = server) 33 | ``` 34 | 35 | 36 | -------------------------------------------------------------------------------- /inst/app/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | human_data <- data.frame(body_part = c("head", 4 | "left-shoulder", 5 | "right-shoulder", 6 | "left-arm", 7 | "right-arm", 8 | "left-hand", 9 | "right-hand", 10 | "chest", 11 | "stomach", 12 | "left-leg", 13 | "right-leg", 14 | "left-foot", 15 | "right-foot"), 16 | values = c(40,20,40,60,90,100,25,50,15,20,70,70,30)) 17 | 18 | 19 | 20 | ui <- fluidPage( 21 | tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "styles.css")), 22 | 23 | sidebarPanel( 24 | # problem1: we are rending the svg in the server 25 | # we need to render this in the ui for the bodyInput 26 | # but I'm not sure how to set a timeout on it... 27 | div(class="human-body", id="human-body", uiOutput("svgout")), 28 | div(style="height:200px;"), 29 | verbatimTextOutput("debug") 30 | ), 31 | 32 | mainPanel( 33 | ), 34 | 35 | # this becomes the js in the bundle too 36 | tags$script(src = "script.js") 37 | 38 | ) 39 | 40 | 41 | server <- function(input, output, session) { 42 | 43 | output$debug <- renderPrint(input$human_body) 44 | 45 | # not sure how sending messages work 46 | # pass this as a list to js in the widget then what.... 47 | session$sendCustomMessage("body_data", human_data) 48 | 49 | # try to put this in the ui.... 50 | output$svgout <- renderUI({ 51 | HTML( 52 | " 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | " 92 | ) 93 | }) 94 | } 95 | 96 | shinyApp(ui = ui, server = server) 97 | -------------------------------------------------------------------------------- /inst/app/www/script.js: -------------------------------------------------------------------------------- 1 | // rather than select on a specifc id 2 | // we need to select on the user inputid 3 | $('#human-body').on('click', '.part', (ev) => { 4 | console.log({id: '#human_body', value: ev.target.id}) 5 | Shiny.setInputValue('human_body', ev.target.id) 6 | 7 | }) 8 | 9 | Shiny.addCustomMessageHandler('body_data', function(color) { 10 | parts = color.body_part 11 | vals = color.values 12 | 13 | var obj = {}; 14 | parts.forEach(function(item, index) { 15 | obj[item] = vals[index] 16 | }) 17 | 18 | const assignColor = (el, value) => { 19 | if (value < 25) { 20 | el.style.fill= "blue"; 21 | } else if (value < 50) { 22 | el.style.fill= "green"; 23 | } else { 24 | el.style.fill= "red"; 25 | } 26 | } 27 | 28 | /* THIS IS WHERE WE NEED THE CODE BELOW FROM THE SEND CUSTOM MESSAGE 29 | BUT WE NEED TO SET TIMEOUT FOR THE SVG TO LOAD 30 | */ 31 | setTimeout(function(){ 32 | for (key in obj){ 33 | const el = document.getElementById(key); 34 | if (obj[key] < 25) { 35 | el.style.fill= "#481567FF"; 36 | } else if (obj[key] < 50) { 37 | el.style.fill= "#453781FF"; 38 | } else if (obj[key] < 75) { 39 | el.style.fill= "#40478FF"; 40 | } else { 41 | el.style.fill= "#39568CFF"; 42 | } 43 | //etc. 44 | } 45 | }, 100); 46 | 47 | }) 48 | -------------------------------------------------------------------------------- /inst/app/www/styles.css: -------------------------------------------------------------------------------- 1 | .human-body { 2 | width: 207px; 3 | position: relative; 4 | padding-top: 240px; 5 | height: 260px; 6 | display: block; 7 | margin: 40px auto; 8 | } 9 | 10 | .human-body svg:hover { 11 | cursor: pointer; 12 | } 13 | 14 | .human-body svg:hover path { 15 | fill: #ff7d16; 16 | } 17 | 18 | .human-body svg { 19 | position: absolute; 20 | left: 50%; 21 | fill: #57c9d5; 22 | } 23 | 24 | .human-body svg#head { 25 | margin-left: -28.5px; 26 | top: -6px; 27 | } 28 | 29 | .human-body svg#left-shoulder { 30 | margin-left: -53.5px; 31 | top: 69px; 32 | } 33 | 34 | .human-body svg#right-shoulder { 35 | margin-left: 13.5px; 36 | top: 69px; 37 | } 38 | 39 | .human-body svg#left-arm { 40 | margin-left: -78px; 41 | top: 112px; 42 | } 43 | 44 | .human-body svg#right-arm { 45 | margin-left: 38px; 46 | top: 112px; 47 | z-index: 10001; 48 | } 49 | 50 | .human-body svg#chest { 51 | margin-left: -43.5px; 52 | top: 88px; 53 | } 54 | 55 | .human-body svg#stomach { 56 | margin-left: -37.5px; 57 | top: 130px; 58 | } 59 | 60 | .human-body svg#left-leg { 61 | margin-left: -46.5px; 62 | top: 205px; 63 | z-index: 9999; 64 | } 65 | 66 | .human-body svg#right-leg { 67 | margin-left: 1.5px; 68 | top: 205px; 69 | z-index: 9999; 70 | } 71 | 72 | .human-body svg#left-hand { 73 | margin-left: -102.5px; 74 | top: 224px; 75 | } 76 | 77 | .human-body svg#right-hand { 78 | margin-left: 66.5px; 79 | top: 224px; 80 | z-index: 10000; 81 | } 82 | 83 | .human-body svg#left-foot { 84 | margin-left: -35.5px; 85 | top: 455px; 86 | } 87 | 88 | .human-body svg#right-foot { 89 | margin-left: 5.5px; 90 | top: 455px; 91 | } 92 | 93 | #area { 94 | display: block; 95 | width: 100%; 96 | clear: both; 97 | padding: 10px; 98 | text-align: center; 99 | font-size: 25px; 100 | font-family: Courier New; 101 | color: #a5a5a5; 102 | } 103 | 104 | #area #data { 105 | color: black; 106 | } 107 | -------------------------------------------------------------------------------- /inst/examples/app.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Example of shinyBody Shiny Input 4 | library(shiny) 5 | library(shinyBody) 6 | 7 | ui <- function() { 8 | 9 | fluidPage( 10 | bodyInput("human", 11 | data = c(rnorm(13, 100)), 12 | low.col = "#800000", 13 | high.col = "#ffe8e8"), 14 | verbatimTextOutput("debug") 15 | ) 16 | } 17 | 18 | server <- function(input, output) { 19 | output$debug <- renderPrint(input$human) 20 | } 21 | 22 | shinyApp(ui = ui, server = server) 23 | -------------------------------------------------------------------------------- /inst/images/README_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MayaGans/shinyBody/365f087d24311af45ccb4f522d144a0e38b7b47b/inst/images/README_img.png -------------------------------------------------------------------------------- /inst/js/shinyBody.js: -------------------------------------------------------------------------------- 1 | var shinyBodyBinding = new Shiny.InputBinding(); 2 | $.extend(shinyBodyBinding, { 3 | 4 | // find the dom element with input$id 5 | // this becomes el downstream 6 | find: function find(scope) { 7 | return $(scope).find(".human-body") 8 | }, 9 | 10 | // get the data-anatomy of the element with class selected 11 | // use this as the input's value 12 | // SEE subscribe 13 | getValue: function getValue(el) { 14 | var value = $(el).find('.selected').data('anatomy') 15 | console.log(value) 16 | return value 17 | }, 18 | 19 | // on click, remove any previous selected classes 20 | // then add the selected class to the clicked limb 21 | // this is used in getValue 22 | subscribe: function(el, callback) { 23 | $(el).on("click.shinyBodyBinding", function(evt) { 24 | // remove all of the selected classes inside our element 25 | $(el).find(".selected").removeClass("selected"); 26 | // set the selected class to the closest clicked part 27 | //console.log($(evt.target).attr('id')) 28 | $(evt.target).addClass('selected'); 29 | callback(); 30 | }) 31 | }, 32 | unsubscribe: function(el) { 33 | $(el).off(".shinyBodyBinding"); 34 | } 35 | }); 36 | 37 | Shiny.inputBindings.register(shinyBodyBinding, 'shinyBody.bodyInput'); 38 | -------------------------------------------------------------------------------- /inst/js/styles.css: -------------------------------------------------------------------------------- 1 | .human-body { 2 | position: relative; 3 | height: 500px; 4 | width: 230px; 5 | } 6 | 7 | .human-body svg:hover { 8 | cursor: pointer; 9 | } 10 | 11 | .human-body svg:hover path { 12 | fill: #FDE725FF; 13 | } 14 | 15 | .human-body svg { 16 | position: absolute; 17 | left: 50%; 18 | } 19 | 20 | .human-body svg#head { 21 | margin-left: -28.5px; 22 | top: 3px; 23 | } 24 | 25 | .human-body svg#left-shoulder { 26 | margin-left: -53.5px; 27 | top: 73px; 28 | } 29 | 30 | .human-body svg#right-shoulder { 31 | margin-left: 13.5px; 32 | top: 73px; 33 | } 34 | 35 | .human-body svg#left-arm { 36 | margin-left: -78px; 37 | top: 115px; 38 | } 39 | 40 | .human-body svg#right-arm { 41 | margin-left: 38px; 42 | top: 115px; 43 | } 44 | 45 | .human-body svg#chest { 46 | margin-left: -43.5px; 47 | top: 93px; 48 | } 49 | 50 | .human-body svg#stomach { 51 | margin-left: -37.5px; 52 | top: 133px; 53 | } 54 | 55 | .human-body svg#left-leg { 56 | margin-left: -46.5px; 57 | top: 207px; 58 | z-index: 9999; 59 | } 60 | 61 | .human-body svg#right-leg { 62 | margin-left: 1.5px; 63 | top: 207px; 64 | z-index: 9999; 65 | } 66 | 67 | .human-body svg#left-hand { 68 | margin-left: -102.5px; 69 | top: 226px; 70 | } 71 | 72 | .human-body svg#right-hand { 73 | margin-left: 66.5px; 74 | top: 226px; 75 | } 76 | 77 | .human-body svg#left-foot { 78 | margin-left: -35.5px; 79 | top: 457px; 80 | } 81 | 82 | .human-body svg#right-foot { 83 | margin-left: 5.5px; 84 | top: 457px; 85 | } 86 | 87 | #area { 88 | display: block; 89 | width: 100%; 90 | clear: both; 91 | padding: 10px; 92 | text-align: center; 93 | font-size: 25px; 94 | font-family: Courier New; 95 | color: #a5a5a5; 96 | } 97 | 98 | #area #data { 99 | color: black; 100 | } 101 | 102 | .well{min-height:700px;} 103 | -------------------------------------------------------------------------------- /inst/svgs/human.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /man/bodyInput.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/body-input.R 3 | \name{bodyInput} 4 | \alias{bodyInput} 5 | \title{An SVG Human Body Input 6 | 7 | This input operates like a \code{shiny::radioButtons()} where you can select one of the body parts!} 8 | \usage{ 9 | bodyInput( 10 | inputId, 11 | data = NULL, 12 | low.col = "#eef4fb", 13 | high.col = "#164a85", 14 | color = "Black", 15 | ... 16 | ) 17 | } 18 | \arguments{ 19 | \item{inputId}{The input id} 20 | 21 | \item{data}{a vector of 13 numbers to be converted to a continuous color scale. 22 | The numbers correspond to the following body part vector: 23 | 24 | \enumerate{ 25 | \item head 26 | \item left-shoulder 27 | \item right-shoulder 28 | \item left-arm 29 | \item right-arm 30 | \item left-hand 31 | \item right-hand 32 | \item chest 33 | \item stomach 34 | \item left-leg 35 | \item right-lef 36 | \item left-foot 37 | \item right-foot 38 | }} 39 | 40 | \item{low.col}{continous color scale applied to data - this is the high vale color} 41 | 42 | \item{high.col}{continous color scale applied to data - this is the high value color} 43 | 44 | \item{color}{a single fill color for all body parts} 45 | 46 | \item{...}{Passed to \code{htmltools::div()}} 47 | } 48 | \value{ 49 | The value returned by the input to the Shiny server is either `NULL` 50 | when no body part is select or a character string containing 51 | the selected body part 52 | } 53 | \description{ 54 | An SVG Human Body Input 55 | 56 | This input operates like a \code{shiny::radioButtons()} where you can select one of the body parts! 57 | } 58 | \examples{ 59 | \dontrun{ 60 | bodyInput("human", data = rnorm(13, 100), low.col = "pink", high.col = "purple") 61 | } 62 | \dontrun{ 63 | bodyInput("human", color = "steelblue") 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /man/bodyPalette.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/color-generator.R 3 | \name{bodyPalette} 4 | \alias{bodyPalette} 5 | \title{Color Generator for the Shiny body input} 6 | \usage{ 7 | bodyPalette(n, low.col = "#eef4fb", high.col = "#164a85") 8 | } 9 | \arguments{ 10 | \item{n}{vector of values to create colors for} 11 | 12 | \item{low.col}{the color palette passed from body-input} 13 | 14 | \item{high.col}{the color palette passed from body-input} 15 | } 16 | \description{ 17 | Color Generator for the Shiny body input 18 | } 19 | -------------------------------------------------------------------------------- /man/pipe.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils-pipe.R 3 | \name{\%>\%} 4 | \alias{\%>\%} 5 | \title{Pipe operator} 6 | \usage{ 7 | lhs \%>\% rhs 8 | } 9 | \description{ 10 | See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /shinyBody.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | --------------------------------------------------------------------------------