3

Dears,

In my app, users rate some stuff.

I want to output 5-star ratings based on their ratings just like the ones in IMDB.

There are fractions in my numbers, and I want the stars to accommodate them.

I don't know Java nor JavaScript at all.

Is there something like a package for this? or what to do?

Thanks in advance.

Am95
  • 59
  • 6
  • Am95, this is too broad a question. StackOverflow is a site about specific programming questions. Most good questions contain code, and I suspect these are "good" because: (1) the asker is showing effort; (2) it's a starting point from which suggestions (and perhaps unrelated bugs) can be made; (3) it's much easier to help with already-present code; and perhaps very importantly (4) this is not a free code service. Please read a little about solid questions here: Refs: https://stackoverflow.com/questions/5963269, https://stackoverflow.com/help/mcve, and https://stackoverflow.com/tags/r/info. – r2evans Oct 01 '19 at 23:09

2 Answers2

8

You'll need to create two files, a css and then your app...ie:

  • app.R
    -- www/
    ------ stars.css

Your stars.css file will have the rules for the HTML markup which will update based on our app after using includeCSS in the header::

.ratings {
  position: relative;
  vertical-align: middle;
  display: inline-block;
  color: #b1b1b1;
  overflow: hidden;
}

.full-stars{
  position: absolute;
  left: 0;
  top: 0;
  white-space: nowrap;
  overflow: hidden;
  color: #fde16d;
}

.empty-stars:before,
.full-stars:before {
  content: "\2605\2605\2605\2605\2605";
  font-size: 44pt; /* Make this bigger or smaller to control size of stars*/
}

.empty-stars:before {
  -webkit-text-stroke: 1px #848484;
}

.full-stars:before {
  -webkit-text-stroke: 1px orange;
}

/* Webkit-text-stroke is not supported on firefox or IE */
/* Firefox */
@-moz-document url-prefix() {
  .full-stars{
    color: #ECBE24;
  }
}
/* IE */
<!--[if IE]>
  .full-stars{
    color: #ECBE24;
  }
<![endif]-->

In our app we want the final markup to appear as follows:

<div class="ratings">
  <div class="empty-stars"></div>
  <div class="full-stars" style="width:70%"></div>
</div>

So to do this we use a combination of UI static elements and then uiOutput, which matches a renderUI on the server side:

library(shiny)


ui <- fluidPage(
    includeCSS("www/stars.css"),
    sliderInput(inputId = "n_stars", label = "Ratings", min = 0,  max = 5, value = 3, step = .15),
    tags$div(class = "ratings",
             tags$div(class = "empty-stars",
                      uiOutput("stars_ui")
             )
    )
)

# Define server logic required to draw a histogram
server <- function(input, output, session) {

    output$stars_ui <- renderUI({
        # to calculate our input %
        n_fill <- (input$n_stars / 5) * 100
        # element will look like this: <div class="full-stars" style="width:n%"></div>
        style_value <- sprintf("width:%s%%", n_fill)
        tags$div(class = "full-stars", style = style_value)
    })

}

# Run the application
shinyApp(ui = ui, server = server)

Our app then using the slider inpout to create the fill % of stars.

enter image description here

Carl Boneri
  • 2,632
  • 1
  • 13
  • 15
3

I wrote a package to solve similar problem so that others don't need to work with CSS and JS. https://github.com/shahronak47/shinyRatings

#Installation of the package from Github
#devtools::install_github('shahronak47/shinyRatings')

library(shiny)
library(shinyRatings)

ui <- fluidPage(
  shinyRatings('star'), 
  textOutput('text')
)

server <- function(input, output, session) {
  output$text <- renderText({paste("No. of stars : ", input$star)})
}

shinyApp(ui, server)

enter image description here

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213