1

I want the text labels on the stacked bar chart to be interactive so the bar chart doesn't flicker as you move the mouse over the text. To hide labels that don't fit on the small bars, I am using label=ifelse(Result > 0.06, percent(Result), ""). However, using ifelse() brings up the following error and prevents geom_text() from becoming interactive:

Warning message:
In set_attr(name = attrName, ids = as.integer(ids), values = attrValue) :
  Failed setting attribute 'data-id', mismatched lengths of ids and values (most often, it occurs because of clipping or because of NAs in data)

If this is a bug and there's no workaround, is there still a way for me to add custom css to the text labels, like "pointer-events: none", within the below code (and not by editing the html file after it's exported)?

The code:

library(ggplot2)
library(ggiraph)
require("tidyverse")
require("scales")

Area <- c("location1", "location2", "location3", "location4")
variable1 <-  c(14, 7, 17, 16)
variable2 <-  c(33, 31, 35, 31)
variable3 <-  c(33, 36, 30, 5)
variable4 <-  c(17, 5, 14, 10)

df1 <- data.frame(
  Area, 
  variable1, 
  variable2, 
  variable3,
  variable4
)

df1_subset <- df1 %>%
  mutate_at(vars(2:5), funs(./100)) %>% 
  pivot_longer(
    cols = c(2:5),
    names_to = "Question", values_to = "Result"
  )

df1_subset <- transform(
  df1_subset,groupID=as.numeric(forcats::fct_inorder(Question))
  )

set.seed(1)

stacked_chart <- ggplot(
  data=df1_subset, 
  aes(
    x=Result,
    y=Area,
    group=Question,
    fill=Question,
    data_id=groupID
  )
) +
  geom_col_interactive(
    position = position_fill(reverse = TRUE)
  ) +
  geom_text_interactive(
    aes(
      label=ifelse(Result > 0.06, percent(Result), "")
    ), 
    col="#FFFFFF",
    fontface="bold",
    position = position_fill(
      reverse = TRUE
    ), 
    hjust = 1.3
  ) +
  scale_y_discrete(
    limits=rev(Area)
  )+
  scale_x_continuous(
    labels=scales::percent,
    expand = c(0,0),
    limits = c(0, 1)
  )+
  scale_fill_manual(
    labels=c(
      "Variable 1", 
      "Variable 2", 
      "Variable 3",
      "Variable 4"
    ), 
    values=c(
      "#000000",
      "#333333",
      "#666666",
      "#999999"
    )
  )+
  theme_minimal()+
  theme(
    legend.position = "top",
    legend.justification = "left",
    legend.title = element_blank()
  )

stacked_chart_ggiraph <- girafe(
  ggobj = stacked_chart, width_svg = 9, height_svg = 6,
  options = list(
    opts_sizing(rescale = TRUE),
    opts_toolbar(saveaspng = FALSE),
    opts_hover_inv(css = girafe_css(
      css = "opacity:0.3;"
    )
    ),
    opts_hover(css = girafe_css(
      css = "cursor:pointer;"
    ))
  )
)

stacked_chart_ggiraph
stefan
  • 90,330
  • 6
  • 25
  • 51
Sidders
  • 124
  • 10

1 Answers1

1

After all it's just a warning not an error. But a possible workaround to avoid the warning would be plot all labels but to set the color for small values to "transparent" using an ifelse and scale_color_identity:

library(ggplot2)
library(ggiraph)
library(scales)

stacked_chart <- ggplot(
  data = df1_subset,
  aes(
    x = Result,
    y = Area,
    group = Question,
    fill = Question,
    data_id = groupID
  )
) +
  geom_col_interactive(
    position = position_fill(reverse = TRUE)
  ) +
  geom_text_interactive(
    aes(
      color = ifelse(Result > 0.06,  "#FFFFFF", "transparent"),
      label = percent(Result)
    ),
    fontface = "bold",
    position = position_fill(
      reverse = TRUE
    ),
    hjust = 1.3
  ) +
  scale_y_discrete(
    limits = rev(Area)
  ) +
  scale_x_continuous(
    labels = scales::percent,
    expand = c(0, 0),
    limits = c(0, 1)
  ) +
  scale_color_identity() +
  scale_fill_manual(
    labels = c(
      "Variable 1",
      "Variable 2",
      "Variable 3",
      "Variable 4"
    ),
    values = c(
      "#000000",
      "#333333",
      "#666666",
      "#999999"
    )
  ) +
  theme_minimal() +
  theme(
    legend.position = "top",
    legend.justification = "left",
    legend.title = element_blank()
  )

stacked_chart_ggiraph <- girafe(
  ggobj = stacked_chart, width_svg = 9, height_svg = 6,
  options = list(
    opts_sizing(rescale = TRUE),
    opts_toolbar(saveaspng = FALSE),
    opts_hover_inv(css = girafe_css(
      css = "opacity:0.3;"
    )),
    opts_hover(css = girafe_css(
      css = "cursor:pointer;"
    ))
  )
)

stacked_chart_ggiraph

stefan
  • 90,330
  • 6
  • 25
  • 51
  • This works brilliantly. I added your solution to my main graph and had issues with the text color being overwritten by the default pink, green, cyan, purple etc. Then I noticed that you used `scale_color_identity()` which I'm reading about now. Thanks again! – Sidders Sep 13 '22 at 20:37