JohnCoene / echarts4r

🐳 ECharts 5 for R
http://echarts4r.john-coene.com/
Other
585 stars 82 forks source link

Adding images to echarts from package in Shiny #598

Closed BKimptonHCC closed 7 months ago

BKimptonHCC commented 7 months ago

Hi,

I've developed a package our team use internally to create SPC charts. We use a mix of packages including echarts4r (which we love!).

In the package, there is an inst folder which contains an icon/ folder, which includes all the icons we aim to add to our echarts4r plots with e_image_g( ). We have used this before in R shiny with a www/ folder within the project, and that functionality works.

My issue is that the e_image_g( ) within HertsSPC::spc_add_icons( ) does not successfully add the images to the echart4r plot in R shiny. Now, I suspect this issue is related to R shiny and how it identifies images from within packages. I've seen reproducible examples (e.g. https://stackoverflow.com/questions/38791613/including-an-image-in-a-shiny-app-package), but these relate to adding images directly into the Shiny UI. I have not found anything related to this unique case with echarts4r.

See below code as example:

devtools::install_github("herts-phei/HertsSPC")
library(shiny)
library(dplyr)
library(HertsSPC)

shiny::addResourcePath(
  prefix = "icons",
  directoryPath = system.file(
    "icons",
    package = "HertsSPC"
  )
)

ui <- fluidPage(
  echarts4r::echarts4rOutput("chart"),
  br(),
)

server <- function(input, output)

{
  output$chart <- echarts4r::renderEcharts4r({
    tooth_data <- force(ToothGrowth) %>%
      filter(supp == "VC") %>% slice(-15:-27) %>%
      mutate(Date = seq.Date(as.Date("2021-01-01"), as.Date("2021-01-17"), by = "days"),
             supp = "Indicator 1",
             polarity = "up",
             greater_than_hundred = FALSE,
             less_than_zero = FALSE,
             unit = "count")

    spc_data <- HertsSPC::spc_output(data = tooth_data, 
                                     time_field = "Date",
                                     indicator = "supp",
                                     value = "len",
                                     output = "data")

    graph <-  HertsSPC::spc_chart(.data = filter(spc_data, indicator == "Indicator 1"),
                                   .plot_title = i,
                                   .base_date_range = NULL, 
                                   .package = "echarts")  %>%
      echarts4r::e_axis_labels(x = "Day")  %>% 
      echarts4r::e_image_g(
        elements = list(
          list(type = "image",
               right = 200,
               top = 200,
               z = -999,
               style = list(
                 image = "https://www.r-project.org/logo/Rlogo.png",
                 width = 50,
                 height = 50,
                 opacity = 1
               )))
      ) %>% 
      HertsSPC::spc_add_icons()

  })

}

shinyApp(ui = ui, server = server)

The product of HertsSPC::spc_chart( ) is an echarts4r object.

You can see in the code, and when you run the app, the R logo appears as expected. However, the piped spc_add_icons ( ) at the end doesn't add the icons stored in the package as intended (one blue icon should appear in the top right). This is only the case with echarts4r, as it works as expected with plotly and ggplot2. I use system.file in the package to locate the icons folder.

The code within spc_add_icons shares the exact code as the e_image_g line in the example, besides the icon being located from the icons folder within the package.

Essentially the question here is whether anyone has had a similar problem in adding images stored in a specific package to an echarts plot in R shiny (not images stored in a local www/)?

Thanks in advance!

JohnCoene commented 7 months ago

The image needs to be accessible by echarts.js, hence it works with shiny if you serve the image.

Otherwise the documentation indicates it should be a datauri.

I think something like.

image <- system.file("path/to/file.png", package = "mypkg")

encoded <- base64enc::base64encode(image)
uri <- paste0("data:image/png;base64,", encoded)

Then use uri where you'd normally use the url in echarts4r

BKimptonHCC commented 7 months ago

Hi John,

Thanks for the prompt response! I've just attempted to amend the package so now looks like so:

    image <- system.file(paste0("icons/", icon_variation), package = "HertsSPC")
    encoded <- base64enc::base64encode(image)
    uri <- paste0("data:image/png;base64,", encoded)

    spc <- .spc %>%
      echarts4r::e_image_g(
        elements = list(
          list(type = "image",
               right = echarts_variation[1],
               top = echarts_variation[2],
               z = echarts_variation[3],
               style = list(
                 image = uri,
                 width = echarts_variation[4],
                 height = echarts_variation[5],
                 opacity = 1
               )))
      )

Unfortunately, still having the same issue. Have I implemented this wrong?

JohnCoene commented 7 months ago

I can't tell what is going wrong because I do not have access to the package, are those icons indeed png?

This works.

img <- "https://www.r-project.org/logo/Rlogo.png"
encoded <- base64enc::base64encode(img)
uri <- paste0("data:image/png;base64,", encoded)

cars |>
  e_charts(speed) |>
  e_scatter(dist) |>
  e_image_g(
    right = 20,
    top = 20,
    z = -999,
    style = list(
      image = uri,
      width = 150,
      height = 150,
      opacity = .6
    )
  )
BKimptonHCC commented 7 months ago

Evening John,

Thanks for your help! The code did work the first, I just needed to make a slight amendment elsewhere. Hopefully this will help someone in the future as well.

Your responsiveness is much appreciated!

JohnCoene commented 7 months ago

You're welcome, thanks for using echarts4r!