1

I have a problem with my slider. It doesn't show divisions up to number 13 and the button check doesn't work when I press it. What should I do to fix it? Please, help.

Here is the code I wrote:

library(shiny)
library(readr)

# GiuseppeData <- read_csv("Classes_with_Giuseppe.csv")
GiuseppeData <- structure(list(number_of_classes = c("1_class", "2_class", "3_class",
                                                     "4_class", "5_class", "6_class", "7_class", "8_class", "9_class", "10_class",
                                                     "11_class", "12_class", "13_class", "14_class", "15_class", "16_class",
                                                     "17_class", "18_class"), 
                               length_of_classes = c(2.24, 2.37, 2.14, 2.18, 2.28,
                                                     2.3, 2.32, 2.24, 2.36, 2.38, 2.21, 2.25, 2.17, 2.17, 2, 2.1, 2.05, 2.2)),
                               row.names = c(NA, -18L),
                               class = "data.frame")

ui <- fluidPage(
  titlePanel("Hello Giuseppe!"),
  sidebarLayout(
    sidebarPanel(
      sliderInput(inputId = "rows",
                  label = "Amount of Classes",
                  min = 1,
                  max = nrow(GiuseppeData),
                  value = 7, step = 1,
                  animate = animationOptions(interval = 600, loop = TRUE)),
      actionButton(
        inputId = "check",
        label = "Check"
      )
    ),
    mainPanel(
      plotOutput(outputId = "distPie")
    )
  )
)

server <- function(input, output) {
  output$distPie <- renderPlot({
    x <- GiuseppeData[1:input$rows,]$length_of_classes
    pie(x, col = "76776", border = "pink",
        xlab = "Pie of Length of Each Class (in hours)",
        main = "Pie of Classes")
  })
}

shinyApp(ui = ui, server = server)
ismirsehregal
  • 30,045
  • 5
  • 31
  • 78
user778
  • 35
  • 4
  • Please share the output of `dput(GiuseppeData)` (instead of the image of your csv file). – ismirsehregal Jun 16 '22 at 11:05
  • 1_class 2.24 2_class 2.37 3_class 2.14 4_class 2.18 5_class 2.28 6_class 2.30 7_class 2.32 8_class 2.24 9_class 2.36 10_class 2.38 11_class 2.21 12_class 2.25 13_class 2.17 14_class 2.17 15_class 2.00 16_class 2.10 17_class 2.05 18_class 2.20 – user778 Jun 16 '22 at 11:07
  • Including the `structure` call - please see the section *Copying original data* [here](https://stackoverflow.com/a/5963610/9841389). – ismirsehregal Jun 16 '22 at 11:08
  • sorry, I am not sure what structure call I should share exactly, could you, please, explain? I had this data in excel file which I later transformed into a csv file that is mentioned in the beginning of the code – user778 Jun 16 '22 at 11:11
  • In you R console read in the data: `GiuseppeData <- read_csv("Classes_with_Giuseppe.csv")` and then run `dput(GiuseppeData)`. Copy and paste the result here. – ismirsehregal Jun 16 '22 at 11:13
  • Thank you for your explanation! Here it is: structure(list(number_of_classes = c("1_class", "2_class", "3_class", "4_class", "5_class", "6_class", "7_class", "8_class", "9_class", "10_class", "11_class", "12_class", "13_class", "14_class", "15_class", "16_class", "17_class", "18_class"), length_of_classes = c(2.24, 2.37, 2.14, 2.18, 2.28, 2.3, 2.32, 2.24, 2.36, 2.38, 2.21, 2.25, 2.17, 2.17, 2, 2.1, 2.05, 2.2)), row.names = c(NA, -18L), spec = structure(list( cols = list(number_of_classes = structure(list(), class = – user778 Jun 16 '22 at 11:26
  • c("collector_character", "collector")), length_of_classes = structure(list(), class = c("collector_double", "collector"))), default = structure(list(), class = c("collector_guess", "collector")), delim = ","), class = "col_spec"), problems = , class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame")) – user778 Jun 16 '22 at 11:26
  • I just updated your question accordingly - the data should not be copied into the comments - it's part of the question to make it reproducible. So far the app is working fine - what is supposed to happen if the `check` button is pressed? – ismirsehregal Jun 16 '22 at 11:28
  • Thank you, I didn't know about that. When the check button is pressed it should change the number of classes shown on the pie by 1 and do so in the loop. When I press the check button nothing changes, only a small play button on the right side of the slider works. Also, the divisions on the slider are not shown for the first numbers. – user778 Jun 16 '22 at 11:42

1 Answers1

1

To show a custom button we can use animationOptions and pass an actionButton to its playButton argument.

Customizing the slider ticks is not possible out of the box - however, we can use htmltools::tagQuery. Here a related thread can be found.

library(shiny)
library(readr)
library(plotly)
library(htmltools)

# GiuseppeData <- read_csv("Classes_with_Giuseppe.csv")
GiuseppeData <- structure(list(number_of_classes = c("1_class", "2_class", "3_class",
                                                     "4_class", "5_class", "6_class", "7_class", "8_class", "9_class", "10_class",
                                                     "11_class", "12_class", "13_class", "14_class", "15_class", "16_class",
                                                     "17_class", "18_class"), 
                               length_of_classes = c(2.24, 2.37, 2.14, 2.18, 2.28,
                                                     2.3, 2.32, 2.24, 2.36, 2.38, 2.21, 2.25, 2.17, 2.17, 2, 2.1, 2.05, 2.2)),
                               row.names = c(NA, -18L),
                               class = "data.frame")


ui <- fluidPage(titlePanel("Hello Giuseppe!"),
                sidebarLayout(sidebarPanel(
                  {
                    customSlider <- sliderInput(
                    inputId = "rows",
                    label = "Amount of Classes",
                    min = 1,
                    max = nrow(GiuseppeData),
                    value = 7,
                    step = 1,
                    animate = animationOptions(
                      interval = 600,
                      loop = TRUE,
                      playButton = actionButton(
                        inputId = "play",
                        label = "Play",
                        style = "margin-top: 20px; margin-bottom: -15px; width: 160px;"
                      ),
                      pauseButton = actionButton(
                        inputId = "pause",
                        label = "Pause",
                        style = "margin-top: 20px; margin-bottom: -15px; width: 160px;"
                      )
                    ),
                    ticks = TRUE
                    )
                    tagQuery(customSlider)$find("input")$addAttrs("data-values" = paste0(seq_len(nrow(GiuseppeData)), collapse = ", "))$allTags()
                    }
                ),
                mainPanel(
                  plotlyOutput(outputId = "distPie", height = "60vh")
                )))

server <- function(input, output) {
  output$distPie <- renderPlotly({
    x <- GiuseppeData[1:input$rows, ]
    fig <- plot_ly(
        data = x,
        labels = ~ number_of_classes,
        values = ~ length_of_classes,
        type = 'pie',
        textposition = 'inside',
        textinfo = 'label+value+percent',
        direction ='clockwise', 
        sort = FALSE
      )
    fig <- fig %>% layout(
      title = "Pie of Classes",
      xaxis = list(
        title = "Pie of Length of Each Class (in hours)",
        showgrid = FALSE,
        zeroline = FALSE,
        showticklabels = FALSE
      ),
      yaxis = list(
        showgrid = FALSE,
        zeroline = FALSE,
        showticklabels = FALSE
      )
    )
  })
}

shinyApp(ui = ui, server = server)

result

PS: I've been using plotly pie charts instead of the base R plots. Feel free to revert this step.

ismirsehregal
  • 30,045
  • 5
  • 31
  • 78
  • 1
    That looks super cool!! Thank you for making my code better, that is very interesting and more advanced! – user778 Jun 16 '22 at 12:40