File: app.R

package info (click to toggle)
r-cran-plotly 4.10.4%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 30,636 kB
  • sloc: javascript: 195,272; sh: 24; makefile: 6
file content (156 lines) | stat: -rw-r--r-- 4,399 bytes parent folder | download | duplicates (3)
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
41
42
43
44
45
46
47
48
49
50
51
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
library(shiny)
library(plotly)
library(dplyr)

data(sales, package = "plotlyBook")
categories <- unique(sales$category)
sub_categories <- unique(sales$sub_category)
ids <- unique(sales$id)

ui <- fluidPage(
  uiOutput("history"),
  plotlyOutput("bars", height = 200),
  plotlyOutput("lines", height = 300)
)

server <- function(input, output, session) {
  # These reactive values keep track of the drilldown state
  # (NULL means inactive)
  drills <- reactiveValues(
    category = NULL,
    sub_category = NULL,
    id = NULL
  )
  # filter the data based on active drill-downs
  # also create a column, value, which keeps track of which
  # variable we're interested in 
  sales_data <- reactive({
    if (!length(drills$category)) {
      return(mutate(sales, value = category))
    }
    sales <- filter(sales, category %in% drills$category)
    if (!length(drills$sub_category)) {
      return(mutate(sales, value = sub_category))
    }
    sales <- filter(sales, sub_category %in% drills$sub_category)
    mutate(sales, value = id)
  })
  
  # bar chart of sales by 'current level of category'
  output$bars <- renderPlotly({
    d <- count(sales_data(), value, wt = sales)
    
    p <- plot_ly(d, x = ~value, y = ~n, source = "bars") %>%
      layout(
        yaxis = list(title = "Total Sales"), 
        xaxis = list(title = "")
      )
    
    if (!length(drills$sub_category)) {
      add_bars(p, color = ~value)
    } else if (!length(drills$id)) {
      add_bars(p) %>%
        layout(
          hovermode = "x",
          xaxis = list(showticklabels = FALSE)
        )
    } else {
      # add a visual cue of which ID is selected
      add_bars(p) %>%
        filter(value %in% drills$id) %>%
        add_bars(color = I("black")) %>%
        layout(
          hovermode = "x", xaxis = list(showticklabels = FALSE),
          showlegend = FALSE, barmode = "overlay"
        )
    }
  })
  
  # time-series chart of the sales
  output$lines <- renderPlotly({
    p <- if (!length(drills$sub_category)) {
      sales_data() %>%
        count(order_date, value, wt = sales) %>%
        plot_ly(x = ~order_date, y = ~n) %>%
        add_lines(color = ~value)
    } else if (!length(drills$id)) {
      sales_data() %>%
        count(order_date, wt = sales) %>%
        plot_ly(x = ~order_date, y = ~n) %>%
        add_lines()
    } else {
      sales_data() %>%
        filter(id %in% drills$id) %>%
        select(-value) %>%
        plot_ly() %>% 
        add_table()
    }
    p %>%
      layout(
        yaxis = list(title = "Total Sales"), 
        xaxis = list(title = "")
      )
  })
  
  # control the state of the drilldown by clicking the bar graph
  observeEvent(event_data("plotly_click", source = "bars"), {
    x <- event_data("plotly_click", source = "bars")$x
    if (!length(x)) return()
    
    if (!length(drills$category)) {
      drills$category <- x
    } else if (!length(drills$sub_category)) {
      drills$sub_category <- x
    } else {
      drills$id <- x
    }
  })
  
  # populate a `selectInput()` for each active drilldown 
  output$history <- renderUI({
    if (!length(drills$category)) return("Click the bar chart to drilldown")
    categoryInput <- selectInput(
      "category", "Category", 
      choices = categories, selected = drills$category
    )
    if (!length(drills$sub_category)) return(categoryInput)
    sd <- filter(sales, category %in% drills$category)
    subCategoryInput <- selectInput(
      "sub_category", "Sub-category", 
      choices = unique(sd$sub_category), 
      selected = drills$sub_category
    )
    if (!length(drills$id)) {
      return(fluidRow(
        column(3, categoryInput), 
        column(3, subCategoryInput)
      ))
    }
    sd <- filter(sd, sub_category %in% drills$sub_category)
    idInput <- selectInput(
      "id", "Product ID", 
      choices = unique(sd$id), selected = drills$id
    )
    fluidRow(
      column(3, categoryInput), 
      column(3, subCategoryInput),
      column(3, idInput)
    )
  })
  
  # control the state of the drilldown via the `selectInput()`s
  observeEvent(input$category, {
    drills$category <- input$category
    drills$sub_category <- NULL
    drills$id <- NULL
  })
  observeEvent(input$sub_category, {
    drills$sub_category <- input$sub_category
    drills$id <- NULL
  })
  observeEvent(input$id, {
    drills$id <- input$id
  })
}

shinyApp(ui, server)