Я пытаюсь создать интерактивную визуализацию данных в R. Пользователю предоставляются данные на агрегированном уровне, а затем он может выбрать дезагрегирование по двум доступным переменным (по одной за раз). В приведенном ниже примере данные о населении агрегированы по континентам. Затем я детализирую страны.
library(highcharter)
library(dplyr)
library(purrr)
data <- data.frame(
continent = rep(c("Asia", "Europe", "Africa"), each = 6),
country = rep(c("AA", "AB", "AC", "BA", "BB", "BC", "CA", "CB", "CC"), each = 2),
gender = rep(c('Men', 'Women'), each = 9),
pop = c(2, 2, 2, 3, 4, 2, 1, 2, 3, 2, 1, 1, 0, 1, 4, 2, 5, 2)
)
column <- data %>%
group_by(continent) %>% summarise(pop = sum(pop))
drilldown_country <- data %>%
group_nest(continent) %>%
mutate(
id = continent,
type = "column",
data = map(data, mutate, name = country, y = pop),
data = map(data, list_parse)
)
hchart(
column,
"column",
hcaes(x = continent, y = pop, name = continent, drilldown = continent),
name = "Population",
colorByPoint = TRUE
) |>
hc_drilldown(
allowPointDrilldown = TRUE,
series = list_parse(drilldown_country)
)
Я надеюсь, что можно дать пользователю выбор: детализировать эти данные по стране или по полу. Я предполагаю, что это может быть что-то вроде кнопки, где пользователь может выбрать «Страна» или «Пол», а затем щелкнуть панель континента, и тогда население этого континента будет показано по стране/полу. Я очень открыт для решений, пока есть одна диаграмма, на которой пользователь может выбрать, как выполнять детализацию. Я видел, что возможна иерархическая детализация, и то, что я ищу, можно назвать параллельной детализацией. Я думаю, что предпосылкой для этого является что-то вроде приведенного ниже кода, но я не уверен, как его использовать.
drilldown_gender <- data %>%
group_nest(continent) %>%
mutate(
id = continent,
type = "column",
data = map(data, mutate, name = gender, y = pop),
data = map(data, list_parse)
)
Я задал аналогичный вопрос здесь, где я пытался использовать plotly
, но думаю, что мои шансы выше с highcharter
и что на этот раз я лучше представил свои данные.
Возможно, вы передаете данные drilldown
для обеих связанных переменных, которые также содержат столбец info
, который позже используется для фильтрации данных в зависимости от выбора кнопки:
hc_drilldown(allowPointDrilldown = TRUE,
series = list_parse(rbind(drilldown_country, drilldown_gender)))
> rbind(drilldown_country, drilldown_gender)
# A tibble: 6 × 5
continent data id type info
<chr> <list> <chr> <chr> <chr>
1 Africa <list [6]> Africa column country
2 Asia <list [6]> Asia column country
3 Europe <list [6]> Europe column country
4 Africa <list [6]> Africa column gender
5 Asia <list [6]> Asia column gender
6 Europe <list [6]> Europe column gender
Затем мы прикрепляем к диаграмме событие load
, которое сначала определяет переменную, содержащую эти данные:
hc_chart(events = list(
load = JS(
"function() {
var chart = this;
var drillDownData = chart.options.drilldown.series;
...
"
Затем (подробности ниже) определяется кнопка, имеющая событие onclick
для переключения переменной drilldown
и фильтрации данных drilldown
.
library(highcharter)
library(dplyr)
library(purrr)
data <- data.frame(
continent = rep(c("Asia", "Europe", "Africa"), each = 6),
country = rep(c(
"AA", "AB", "AC", "BA", "BB", "BC", "CA", "CB", "CC"
), each = 2),
gender = rep(c('Men', 'Women'), each = 9),
pop = c(2, 2, 2, 3, 4, 2, 1, 2, 3, 2, 1, 1, 0, 1, 4, 2, 5, 2)
)
column <- data %>%
group_by(continent) %>% summarise(pop = sum(pop))
drilldown_country <- data %>%
group_nest(continent) %>%
mutate(
id = continent,
type = "column",
data = map(data, mutate, name = country, y = pop),
data = map(data, list_parse),
info = "country"
)
drilldown_gender <- data %>%
group_nest(continent) %>%
mutate(
id = continent,
type = "column",
data = map(data, mutate, name = gender, y = pop),
data = map(data, list_parse),
info = "gender"
)
hchart(
column,
"column",
hcaes(
x = continent,
y = pop,
name = continent,
drilldown = continent
),
name = "Population",
colorByPoint = TRUE
) |>
hc_drilldown(allowPointDrilldown = TRUE,
series = list_parse(rbind(drilldown_country, drilldown_gender))) |>
hc_chart(events = list(
load = JS(
"function() {
var chart = this;
var drillDownData = chart.options.drilldown.series;
chart.options.drilldown.series = drillDownData.filter(v => v.info === 'country');
chart.drilldownTextInfo = chart.renderer.text(' ', 300, 25)
.css({
'color': 'red'
})
.add();
chart.renderer.button('Change drilldown variable', 75, 25)
.attr({
zIndex: 3
})
.on('click', function() {
var info = chart.options.drilldown.series[0].info
info = ((info == 'country') ? 'gender' : 'country');
chart.options.drilldown.series = drillDownData.filter(v => v.info === info);
chart.drilldownTextInfo.attr({
text: 'Current drilldown variable: ' + info
})
})
.add();
}"
)
))
@EmilA Это должно быть возможно, но, пожалуйста, задайте по этому поводу отдельный дополнительный вопрос (содержащий подходящий минимальный пример, аналогичный вашим реальным данным), поскольку на ваш первоначальный вопрос дан ответ. Вы также можете сослаться на этот вопрос в новом.
Большое спасибо @Jan и извините за опоздание с дополнительными вопросами: в моих реальных данных иногда бывает до 5 переменных, по которым данные можно детализировать. Можно ли изменить кнопку, чтобы вместо изменения переменной детализации она отображала раскрывающийся список переменных, а затем нажатие на одну из них изменяло переменную детализации? Например. нажатие на «Изменить переменную детализации» отображает список «Пол», «Страна», «Возраст», «Цвет волос», а затем нажатие, например, на «Возраст» позволяет выполнять детализацию по возрасту, нажимая на панели?