dreamRs / apexcharter

:bar_chart: R Htmlwidget for ApexCharts.js

Home Page:https://dreamrs.github.io/apexcharter

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Adding Icons to the Labels in a Legend

radovan-miletic opened this issue · comments

Hi Victor,

The labels in "donut" chart (which I very much appreciate) can be easily turned into additional filter with awesome set_input_click().
Following issue 50, in last few days I was trying to figure out how to add icon (or opacity, color, etc.) to the clicked label item in "donut" chart.
I was unable to pass from adding icons to all labels (non-desired output):

````
my_data <- mtcars |> 
  dplyr::select(mpg, hp) |> 
  tibble::rownames_to_column("car") |> 
  dplyr::arrange(car)
my_chart <- apexcharter::apex(data = my_data, 
                              type = "donut", 
                              mapping = ggplot2::aes(x = car, y = hp), 
                              auto_update = FALSE) 
my_chart$dependencies <- htmltools::htmlDependencies(shiny::icon("check-square"))
my_chart |> apexcharter::ax_legend(position = "right", 
                                   formatter = htmlwidgets::JS("function(value) {
   return '<i class=\"fa fa-check-square\" aria-hidden=\"true\"></i>' + ' ' + value + '</span>';}"))
````

Output:
apex

I'm wondering if it's possible to achieve desired output, maybe with JS onClick event?
Any help would be greatly appreciated if possible. Thank you.

Hello Radovan,

Glad you like those functionnalities ! 😄
No built-in way to do it I think, you have to use some CSS and JavaScript, here's an example for shiny :

library(apexcharter)
library(shiny)

ui <- fluidPage(
  # some CSS to style the clicked legend item (the one with class 'active')
  tags$style(
    ".apexcharts-legend-series.active {opacity: 0.5 !important;}",
    HTML(".apexcharts-legend-series.active > .apexcharts-legend-text > .my-icon {display: inline-block !important;}"),
    ".my-icon {display: none;}"
  ),
  # when legend item is clicked add class 'active' to it and remove to it for others
  tags$script(
    "$(document).on('click', '.apexcharts-legend-series', function(event) {
      $(this).siblings().removeClass('active');
      $(this).addClass('active');
    });"
  ),
  apexchartOutput("chart")
)

server <- function(input, output, session) {
  output$chart <- renderApexchart({
    my_data <- mtcars |> 
      dplyr::select(mpg, hp) |> 
      tibble::rownames_to_column("car") |> 
      dplyr::arrange(car)
    my_chart <- apexcharter::apex(data = my_data, 
                                  type = "donut", 
                                  mapping = ggplot2::aes(x = car, y = hp), 
                                  auto_update = FALSE) 
    my_chart$dependencies <- htmltools::htmlDependencies(shiny::icon("check-square"))
    my_chart |> apexcharter::ax_legend(position = "right", 
                                       formatter = htmlwidgets::JS("function(value) {
   return '<i class=\"fa fa-check-square my-icon\" aria-hidden=\"true\"></i>' + ' ' + value + '</span>';}")) # custom class to icon
  })
}

shinyApp(ui, server)

Let me know if you question about this.

Victor

This is almost exactly what I am looking for.
I'm wondering if it's possible to mark multiple choices instead of one at a time.
Could we click on a legend, add class 'active' to it, and remove it clicking back on the same legend (deselect selected options)?
In a way, it needs to be consistent with set_input_click(inputId = "id_click_multiple", multiple = TRUE).

Thank you very much for your time and attention, Victor.

Sure, you can replace in javascript code :

$(this).siblings().removeClass('active');
$(this).addClass('active');

by :

 $(this).toggleClass('active');

like this it will add the class active to the legend item if not present and remove it if present.

Beautiful! Thank you for support.