Skip to content

Commit b9acab4

Browse files
committed
Official 4.9.0 CRAN release, add drill_down shiny example
1 parent 62adf00 commit b9acab4

File tree

2 files changed

+157
-1
lines changed

2 files changed

+157
-1
lines changed

DESCRIPTION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: plotly
22
Title: Create Interactive Web Graphics via 'plotly.js'
3-
Version: 4.8.0.9000
3+
Version: 4.9.0
44
Authors@R: c(person("Carson", "Sievert", role = c("aut", "cre"),
55
email = "[email protected]", comment = c(ORCID = "0000-0002-4958-2844")),
66
person("Chris", "Parmer", role = "aut",

inst/examples/shiny/drill_down/app.R

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
library(shiny)
2+
library(plotly)
3+
library(dplyr)
4+
5+
data(sales, package = "plotlyBook")
6+
categories <- unique(sales$category)
7+
sub_categories <- unique(sales$sub_category)
8+
ids <- unique(sales$id)
9+
10+
ui <- fluidPage(
11+
uiOutput("history"),
12+
plotlyOutput("bars", height = 200),
13+
plotlyOutput("lines", height = 300)
14+
)
15+
16+
server <- function(input, output, session) {
17+
# These reactive values keep track of the drilldown state
18+
# (NULL means inactive)
19+
drills <- reactiveValues(
20+
category = NULL,
21+
sub_category = NULL,
22+
id = NULL
23+
)
24+
# filter the data based on active drill-downs
25+
# also create a column, value, which keeps track of which
26+
# variable we're interested in
27+
sales_data <- reactive({
28+
if (!length(drills$category)) {
29+
return(mutate(sales, value = category))
30+
}
31+
sales <- filter(sales, category %in% drills$category)
32+
if (!length(drills$sub_category)) {
33+
return(mutate(sales, value = sub_category))
34+
}
35+
sales <- filter(sales, sub_category %in% drills$sub_category)
36+
mutate(sales, value = id)
37+
})
38+
39+
# bar chart of sales by 'current level of category'
40+
output$bars <- renderPlotly({
41+
d <- count(sales_data(), value, wt = sales)
42+
43+
p <- plot_ly(d, x = ~value, y = ~n, source = "bars") %>%
44+
layout(
45+
yaxis = list(title = "Total Sales"),
46+
xaxis = list(title = "")
47+
)
48+
49+
if (!length(drills$sub_category)) {
50+
add_bars(p, color = ~value)
51+
} else if (!length(drills$id)) {
52+
add_bars(p) %>%
53+
layout(
54+
hovermode = "x",
55+
xaxis = list(showticklabels = FALSE)
56+
)
57+
} else {
58+
# add a visual cue of which ID is selected
59+
add_bars(p) %>%
60+
filter(value %in% drills$id) %>%
61+
add_bars(color = I("black")) %>%
62+
layout(
63+
hovermode = "x", xaxis = list(showticklabels = FALSE),
64+
showlegend = FALSE, barmode = "overlay"
65+
)
66+
}
67+
})
68+
69+
# time-series chart of the sales
70+
output$lines <- renderPlotly({
71+
p <- if (!length(drills$sub_category)) {
72+
sales_data() %>%
73+
count(order_date, value, wt = sales) %>%
74+
plot_ly(x = ~order_date, y = ~n) %>%
75+
add_lines(color = ~value)
76+
} else if (!length(drills$id)) {
77+
sales_data() %>%
78+
count(order_date, wt = sales) %>%
79+
plot_ly(x = ~order_date, y = ~n) %>%
80+
add_lines()
81+
} else {
82+
sales_data() %>%
83+
filter(id %in% drills$id) %>%
84+
select(-value) %>%
85+
plot_ly() %>%
86+
add_table()
87+
}
88+
p %>%
89+
layout(
90+
yaxis = list(title = "Total Sales"),
91+
xaxis = list(title = "")
92+
)
93+
})
94+
95+
# control the state of the drilldown by clicking the bar graph
96+
observeEvent(event_data("plotly_click", source = "bars"), {
97+
x <- event_data("plotly_click", source = "bars")$x
98+
if (!length(x)) return()
99+
100+
if (!length(drills$category)) {
101+
drills$category <- x
102+
} else if (!length(drills$sub_category)) {
103+
drills$sub_category <- x
104+
} else {
105+
drills$id <- x
106+
}
107+
})
108+
109+
# populate a `selectInput()` for each active drilldown
110+
output$history <- renderUI({
111+
if (!length(drills$category)) return("Click the bar chart to drilldown")
112+
categoryInput <- selectInput(
113+
"category", "Category",
114+
choices = categories, selected = drills$category
115+
)
116+
if (!length(drills$sub_category)) return(categoryInput)
117+
sd <- filter(sales, category %in% drills$category)
118+
subCategoryInput <- selectInput(
119+
"sub_category", "Sub-category",
120+
choices = unique(sd$sub_category),
121+
selected = drills$sub_category
122+
)
123+
if (!length(drills$id)) {
124+
return(fluidRow(
125+
column(3, categoryInput),
126+
column(3, subCategoryInput)
127+
))
128+
}
129+
sd <- filter(sd, sub_category %in% drills$sub_category)
130+
idInput <- selectInput(
131+
"id", "Product ID",
132+
choices = unique(sd$id), selected = drills$id
133+
)
134+
fluidRow(
135+
column(3, categoryInput),
136+
column(3, subCategoryInput),
137+
column(3, idInput)
138+
)
139+
})
140+
141+
# control the state of the drilldown via the `selectInput()`s
142+
observeEvent(input$category, {
143+
drills$category <- input$category
144+
drills$sub_category <- NULL
145+
drills$id <- NULL
146+
})
147+
observeEvent(input$sub_category, {
148+
drills$sub_category <- input$sub_category
149+
drills$id <- NULL
150+
})
151+
observeEvent(input$id, {
152+
drills$id <- input$id
153+
})
154+
}
155+
156+
shinyApp(ui, server)

0 commit comments

Comments
 (0)