如何在纯R/RMarkdown中实现highcharter图表数据系列切换?
在纯R/RMarkdown环境下用highcharter实现数据系列切换功能
现有如下R数据:
library(highcharter) year <- c(2017, 2018, 2019, 2020, 2021) black <- c(12, 15, 23, 16, 11) asian <- c(3, 12, 63, 46, 21) white <- c(5, 45, 44, 44, 4) hispanic <- c(23, 25, 44, 16, 112) male <- c(33, 33, 62, 66, 102) female <- c(57, 15, 46, 46, 172) df <- data.frame(year, black, asian, white, hispanic, male, female)
需求:
- 用highcharter创建柱状图,默认显示种族相关数据系列:
highchart() %>% hc_chart(type = "column") %>% hc_xAxis(opposite = TRUE, gridLineWidth = .3, categories = df$year) %>% hc_add_series(name="White",data = df$white) %>% hc_add_series(name="Black",data = df$black) %>% hc_add_series(name="Asian",data = df$asian) %>% hc_add_series(name="Hispanic",data = df$hispanic)
- 通过下拉框或按钮等用户输入,切换为显示性别相关数据系列:
highchart() %>% hc_chart(type = "column") %>% hc_xAxis(opposite = TRUE, gridLineWidth = .3, categories = df$year) %>% hc_add_series(name="female",data = df$female) %>% hc_add_series(name="male",data = df$male)
已知该功能可在Shiny或JavaScript版Highcharts中实现,询问能否在纯R/RMarkdown环境下实现此需求。
可以实现,不需要依赖Shiny,通过highcharter结合htmlwidgets的JavaScript交互能力就能完成。核心思路是先把所有数据系列加载到图表中,再通过自定义HTML控件触发JS事件,控制不同系列的显示和隐藏。
以下是具体实现代码:
library(highcharter) library(htmlwidgets) # 准备数据 year <- c(2017, 2018, 2019, 2020, 2021) black <- c(12, 15, 23, 16, 11) asian <- c(3, 12, 63, 46, 21) white <- c(5, 45, 44, 44, 4) hispanic <- c(23, 25, 44, 16, 112) male <- c(33, 33, 62, 66, 102) female <- c(57, 15, 46, 46, 172) df <- data.frame(year, black, asian, white, hispanic, male, female) # 创建图表,加载所有系列,默认只显示种族系列 hc <- highchart() %>% hc_chart(type = "column") %>% hc_xAxis(opposite = TRUE, gridLineWidth = .3, categories = df$year) %>% # 种族系列,默认显示 hc_add_series(name="White", data = df$white, visible = TRUE) %>% hc_add_series(name="Black", data = df$black, visible = TRUE) %>% hc_add_series(name="Asian", data = df$asian, visible = TRUE) %>% hc_add_series(name="Hispanic", data = df$hispanic, visible = TRUE) %>% # 性别系列,默认隐藏 hc_add_series(name="Female", data = df$female, visible = FALSE) %>% hc_add_series(name="Male", data = df$male, visible = FALSE) # 添加自定义HTML控件和JS交互 hc %>% onRender(" function(el, x) { // 创建下拉框 var select = document.createElement('select'); select.innerHTML = '<option value=\"race\">种族数据</option><option value=\"gender\">性别数据</option>'; el.parentNode.insertBefore(select, el); // 获取图表实例 var chart = this; // 下拉框切换事件 select.addEventListener('change', function() { var val = this.value; if (val === 'race') { // 显示种族系列,隐藏性别系列 chart.series[0].show(); chart.series[1].show(); chart.series[2].show(); chart.series[3].show(); chart.series[4].hide(); chart.series[5].hide(); } else { // 显示性别系列,隐藏种族系列 chart.series[0].hide(); chart.series[1].hide(); chart.series[2].hide(); chart.series[3].hide(); chart.series[4].show(); chart.series[5].show(); } }); } ")
代码说明:
- 将所有数据系列(种族+性别)添加到图表中,通过
visible参数控制默认显示/隐藏状态; - 使用
htmlwidgets::onRender注入自定义JavaScript代码,创建下拉框控件; - 为下拉框添加切换事件,通过Highcharts的API控制对应系列的显示和隐藏。
这种方式完全在纯R/RMarkdown环境下运行,不需要启动Shiny应用,生成的HTML文档可直接交互。
内容的提问来源于stack exchange,提问作者DiamondJoe12
相关产品推荐
相关产品推荐

