【问题标题】:R Highcharter: Select category from a single pointR Highcharter:从单点选择类别
【发布时间】:2019-06-15 12:23:35
【问题描述】:

在 R 中使用 highchart(使用 highcharter 包)我试图在选择任何单个点时选择单个类别的所有点。下面的代码允许在堆叠条形图中选择堆叠的单个切片。我希望通过单击任何堆叠条切片来选择/取消选择整个堆叠条。

library("shiny")
library("highcharter")

ui <- shinyUI(
  fluidPage(
    column(width = 8, highchartOutput("hcontainer", height = "500px")),
    column(width = 4, textOutput("text"))
  )
)

server <- function(input, output) {      

  a <- data.frame(b = LETTERS[1:10], b_alt = LETTERS[11:20], c = 11:20, d = 21:30, e = 31:40)

  output$hcontainer <- renderHighchart({      

    canvasClickFunction <- JS("function(event) {Shiny.onInputChange('canvasClicked', [this.name, event.point.series.chart.series[0].options.additionalInfo[event.point.index]]);}")
    legendClickFunction <- JS("function(event) {Shiny.onInputChange('legendClicked', this.name);}")

    highchart() %>% 
      hc_xAxis(categories = a$b) %>% 
      hc_add_series(name = "c", additionalInfo = a$b_alt, data = a$c, color = "red") %>%
      hc_add_series(name = "d", data = a$d) %>% 
      hc_add_series(name = "e", data = a$e) %>%
      hc_plotOptions(series = list(stacking = TRUE, allowPointSelect = TRUE, events = list(click = canvasClickFunction, legendItemClick = legendClickFunction))) %>% 
      hc_chart(type = "column")

  })      

  makeReactiveBinding("outputText")

  observeEvent(input$canvasClicked, {
    outputText <<- paste0("You clicked on series ", input$canvasClicked[1], " and the bar you clicked was from category ", input$canvasClicked[2], ".") 
  })

  observeEvent(input$legendClicked, {
    outputText <<- paste0("You clicked into the legend and selected series ", input$legendClicked, ".")
  })

  output$text <- renderText({
    outputText      
  })
}

shinyApp(ui, server) 

【问题讨论】:

    标签: r highcharts r-highcharter


    【解决方案1】:

    您可以在点单击时触发事件(我们称之为单击点clickedPoint)循环遍历所有系列,然后遍历所有点,检查该点是否与我们的 clickedPoint 具有相同的类别 如果是,请使用 point.select() 方法选择它。

    这里是主要代码:

    hc_plotOptions(series = list(stacking = TRUE, events = list(click = canvasClickFunction, legendItemClick = legendClickFunction), point = list(events = list(click = JS(
        "function() {
          var clickedPoint = this;
            clickedPoint.series.chart.series.forEach(function(series) {
              series.points.forEach(function(point) {
                if (point.category === clickedPoint.category) {
                  if (point.selected) {
                    point.select(false, true)
                  } else {
                    point.select(true, true)
                  }
                }
              })
            })
          }"
      ))))) %>% 
    

    这是整个代码:

    library("shiny")
    library("highcharter")
    
    ui <- shinyUI(
      fluidPage(
        column(width = 8, highchartOutput("hcontainer", height = "500px")),
        column(width = 4, textOutput("text"))
      )
    )
    
    server <- function(input, output) {      
    
      a <- data.frame(b = LETTERS[1:10], b_alt = LETTERS[11:20], c = 11:20, d = 21:30, e = 31:40)
    
      output$hcontainer <- renderHighchart({      
    
        canvasClickFunction <- JS("function(event) {Shiny.onInputChange('canvasClicked', [this.name, event.point.series.chart.series[0].options.additionalInfo[event.point.index]]);}")
        legendClickFunction <- JS("function(event) {Shiny.onInputChange('legendClicked', this.name);}")
    
    highchart() %>% 
      hc_xAxis(categories = a$b) %>% 
      hc_add_series(name = "c", additionalInfo = a$b_alt, data = a$c, color = "red") %>%
      hc_add_series(name = "d", data = a$d) %>% 
      hc_add_series(name = "e", data = a$e) %>%
      hc_plotOptions(series = list(stacking = TRUE, events = list(click = canvasClickFunction, legendItemClick = legendClickFunction), point = list(events = list(click = JS(
        "function() {
          var clickedPoint = this;
            clickedPoint.series.chart.series.forEach(function(series) {
              series.points.forEach(function(point) {
                if (point.category === clickedPoint.category) {
                  if (point.selected) {
                    point.select(false, true)
                  } else {
                    point.select(true, true)
                  }
                }
              })
            })
          }"
      ))))) %>% 
      hc_chart(type = "column")
    
      })      
    
      makeReactiveBinding("outputText")
    
      observeEvent(input$canvasClicked, {
        outputText <<- paste0("You clicked on series ", input$canvasClicked[1], " and the bar you clicked was from category ", input$canvasClicked[2], ".") 
      })
    
      observeEvent(input$legendClicked, {
        outputText <<- paste0("You clicked into the legend and selected series ", input$legendClicked, ".")
      })
    
      output$text <- renderText({
        outputText      
      })
    }
    
    shinyApp(ui, server)
    

    API:https://api.highcharts.com/class-reference/Highcharts.Point#select https://api.highcharts.com/highcharts/plotOptions.column.point.events.click

    带有纯 JS 实现的 jsFiddle:https://jsfiddle.net/BlackLabel/p135s4vm/

    【讨论】:

    • 这很棒。是否有可能与默认行为类似,通过shit/ctrl+click选择多个类别,然后在新选择中取消选择所有内容?
    • 是的,有可能。更新的 jsFiddle:jsfiddle.net/BlackLabel/pgn58tyq 请注意,“if”语句可能可以简化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 2020-04-26
    • 2018-08-18
    • 2018-02-19
    • 1970-01-01
    • 2016-01-01
    • 2020-03-29
    相关资源
    最近更新 更多