Search code examples
rhighchartsr-highcharter

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!


Solution

  • 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
      ")
    ))