使用 Highcharter 的 R 交互式数据可视化:并行钻取

问题描述 投票:0回答:1

我正在尝试在 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)
  )

我希望可以让用户选择是按国家还是按性别深入了解这些数据。我想这可能有点像一个按钮,用户可以选择“国家”或“性别”,然后单击洲栏,然后按国家/性别显示该洲的人口。我对解决方案非常开放,只要有 1 个图表,用户可以在其中选择如何进行钻取。我已经看到分层钻取是可能的,我正在寻找的可能被称为并行钻取。我认为这样做的先决条件在于下面的代码,但我不知道如何使用它。

drilldown_gender <- data %>% 
  group_nest(continent) %>% 
  mutate(
    id = continent,
    type = "column",
    data = map(data, mutate, name = gender, y  = pop),
    data = map(data, list_parse)
  )

我在here问了一个类似的问题,我尝试使用

plotly
,但我认为使用
highcharter
我的机会更大,而且这次我更好地代表了我的数据。

r r-highcharter drilldown
1个回答
0
投票

一种可能性是您为绑定的两个变量传递

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;
          globalThis.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;
          globalThis.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();
      }"
    )
  ))
© www.soinside.com 2019 - 2024. All rights reserved.