cristian-vargas
cristian-vargas

Reputation: 769

Programatically export highcharts to SVG using highcharter R package load event

I am attempting to leverage the load events available inside the hc_chart() function of the highcharter package in order to export a highcharts object to SVG once the chart has loaded, but so far my code fails to download anything. Normally, if I were interested in a PNG or JPEG image, I would just use webshot2::webshot(), but there's no native support for SVG. I could also manually point-and-click on the Export menu to download the chart as an SVG, but I am generating too many charts to manually download. Below I've included my attempt thus far:

library(highcharter)

hchart(
# Default data set included with highcharter
  citytemp_long, 
  type = "line",
  hcaes(x = month, y = temp, group = city)
) |>
  hc_exporting(enabled = TRUE, filename = "example-chart") |>
  hc_chart(
    events = list(
      load = JS(
        "function() {
          setTimeout(function() {
            this.exportChart({ type: 'image/svg+xml' });
          }, 100);
        }"
      )
    )
  )

Since highcharter needs to pass JavaScript wrapped inside the JS() function to the Highcharts API, I've looked at a few JSFiddle examples but every example I could find used a button + eventListener combo to essentially create an expedited export menu. Appreciate any help in advance!

Upvotes: 2

Views: 65

Answers (2)

Tim G
Tim G

Reputation: 4147

You can save the highchart as HTML and then use selenider to open it and click on the Download as SVG button.

out

#install.packages("pacman")
library(pacman)
p_load(highcharter, selenider, htmlwidgets)

chart <- hchart(citytemp_long,  type = "line",hcaes(x = month, y = temp, group = city)) |>
  hc_exporting(enabled = TRUE, filename = "example-chart")

download_HighChart <- function(chart){
  temp_html_file <- tempfile(fileext = ".html")
  saveWidget(chart, temp_html_file, selfcontained = TRUE)
  
  session <- selenider_session("selenium", browser = "chrome")
  open_url(paste0("file://", temp_html_file))
  session |> find_element("path.highcharts-button-symbol") |> elem_click()
  res <- session |> find_elements("li[class='highcharts-menu-item']")|>
    elem_find(has_text("SVG"))|>  elem_click()
  Sys.sleep(0.8)
  file.remove(temp_html_file)
}

download_HighChart(chart)

Upvotes: 1

jedrzejruta
jedrzejruta

Reputation: 596

You can also use the inbuilt exportChartLocal() function, which opens up a download pop-up window, where you can select where to put in the SVG file. Note that since Highcharter runs Highcharts in a browser environment, security policies require user interaction to prevent unauthorized downloads.

highcharter::highchart() %>%
hc_add_dependency("modules/exporting.js") %>%
hc_add_dependency("modules/offline-exporting.js") %>%
hc_chart(events = list(
  load = JS("function() {
    var chart = this;
    setTimeout(function() {
      chart.exportChartLocal({ type: 'image/svg' });
    }, 1000); // Delay to ensure chart is fully rendered
  ")
))

Upvotes: 2

Related Questions