6

I'm building a stacked barchart containing retweets using R, ggplot and plotly. If a part of a barchart is clicked on, I want a new browser tab to open and show the tweet from this specific date with the indicated amount of retweets. However, when I click on one of the bars in the example below, a different link is opened, indicating that the url´s are not properly connected with the bars. How do I solve this?

I have never worked or even seen JavaScript before, so chances are high the answer is in there. The plot is eventually meant to appear in a Shiny application.

library(rtweet)
library(ggplot2)
library(plotly)

# Get tweets
tweets <- get_timeline("BBC", n = 10)

# Create dataframe
data <- data.frame("retweet_count" = tweets$retweet_count,
                   "week" =  c(1,1,1,2,2,3,4,5,5,6),
                   "url"  =  tweets$status_url)

# Create ggplot
ggplot(data = data,
           aes(x = week,
           y = retweet_count,
           label = url)) + 
  geom_bar(stat = 'sum', 
           fill = "darkblue")

# Convert to plotly
p <- ggplotly(
  p,
  tooltip = c("y", 'label'))

# Add URL data to plot
p$x$data[[1]]$customdata <- data$url

# JS function to make a tab open when clicking on a specific bar
onRender(
  p,
  "
    function(el,x){
    el.on('plotly_click', function(d) {
    var websitelink = d.points[0].customdata;
    window.open(websitelink);
    });
    }
    ")
Julian
  • 6,586
  • 2
  • 9
  • 33
jjh
  • 61
  • 2

1 Answers1

0

I don't have a twitter account, so I changed your dataset to use some Wikipedia articles.

Your problem can be resolved by reordering your data.frame according to the URLs. If you run the below with articles from 1:9 everything works as expected. Once you switch to the dataset with links 9:1 you'll get the wrong links. Plotly seems to reorder internally - Same logic as here.

In your case: data <- data[order(data$url),] should fix the order.

The following is working fine:

# library(rtweet)
library(ggplot2)
library(plotly)
library(htmlwidgets)

# Get tweets
# tweets <- get_timeline("BBC", n = 10)

# Create dataframe
# data <- data.frame("retweet_count" = tweets$retweet_count,
#                    "week" =  c(1,1,1,2,2,3,4,5,5,6),
#                    "url"  =  tweets$status_url)

# Create dataframe
# Works!
data <- data.frame("retweet_count" = 1:9,
                   "week" =  1:9,
                   "url"  =  paste0(c("https://en.wikipedia.org/wiki/166"), 1:9))
# Doesn't work!
# data <- data.frame("retweet_count" = 9:1,
#                    "week" =  9:1,
#                    "url"  =  paste0(c("https://en.wikipedia.org/wiki/166"), 9:1))

# Create ggplot
p <- ggplot(data = data,
       aes(x = week,
           y = retweet_count,
           label = url)) + 
  geom_bar(stat = 'sum', 
           fill = "darkblue")

# Convert to plotly
p <- ggplotly(
  p,
  tooltip = c("y", 'label'))

# Add URL data to plot
p$x$data[[1]]$customdata <- data$url

# JS function to make a tab open when clicking on a specific bar
onRender(
  p,
  "
    function(el,x){
    el.on('plotly_click', function(d) {
    var websitelink = d.points[0].customdata;
    window.open(websitelink);
    });
    }
    ")
ismirsehregal
  • 30,045
  • 5
  • 31
  • 78
  • Thank you for you effort! Applying your example gives me indeed the correct solution. However, for me ot goes wrong when different tweets are send on the same day, stacking the bars on eachother. The order function then doesn't work anymore since the sorting per day is different. – jjh Oct 31 '20 at 08:15
  • 1
    Could you please provide me with the output of `dput(tweets)`? – ismirsehregal Oct 31 '20 at 09:41