wordcloud2 icon indicating copy to clipboard operation
wordcloud2 copied to clipboard

Custom Hover Text

Open seanlacey opened this issue 5 years ago • 1 comments

Is it possible to customize the hover text?

I have a dataset with 3-4 very large words compared to all the others, to solve this I want to take the log of the frequencies (technically I'm taking the ceiling of the log base 2 and then adding 1). I'd either like to customize what frequency is shown in the hover text (or just not show it at all. Is that possible?

seanlacey avatar Apr 12 '19 01:04 seanlacey

I'd really liked that too. Especially since I often need to use a log scale for the words, but still want to see the real number. And please, don't say "you should use another display in this case", wordcloud still can be the best display sometimes, I use it in shiny for specific UX cases.

I've managed to do it by reworking the code a little, but it's not clean. To explain it simply: you modify the R function wordcloud2 to take a third column, that you name for exemple "label". That will make something like that (here I renamed it wordcloud3 because I didn't want to reinstall the package):

wordcloud3 <- function (data, size = 1, minSize = 0, gridSize = 0, fontFamily = "Segoe UI", 
                        fontWeight = "bold", color = "random-dark", backgroundColor = "white", 
                        minRotation = -pi/4, maxRotation = pi/4, shuffle = TRUE, 
                        rotateRatio = 0.4, shape = "circle", ellipticity = 0.65, 
                        widgetsize = NULL, figPath = NULL, hoverFunction = NULL) {
  if ("table" %in% class(data)) {
    dataOut = data.frame(name = names(data), freq = as.vector(data))
  }
  else {
    data = as.data.frame(data)
    dataOut = data[, 1:3]
    names(dataOut) = c("name", "freq", "label")
  }
  if (!is.null(figPath)) {
    if (!file.exists(figPath)) {
      stop("cannot find fig in the figPath")
    }
    spPath = strsplit(figPath, "\\.")[[1]]
    len = length(spPath)
    figClass = spPath[len]
    if (!figClass %in% c("jpeg", "jpg", "png", "bmp", "gif")) {
      stop("file should be a jpeg, jpg, png, bmp or gif file!")
    }
    base64 = base64enc::base64encode(figPath)
    base64 = paste0("data:image/", figClass, ";base64,", 
                    base64)
  }
  else {
    base64 = NULL
  }
  weightFactor = size * 180/max(dataOut$freq)
  settings <- list(word = dataOut$name, freq = dataOut$freq, label = dataOut$label, 
                   fontFamily = fontFamily, fontWeight = fontWeight, color = color, 
                   minSize = minSize, weightFactor = weightFactor, backgroundColor = backgroundColor, 
                   gridSize = gridSize, minRotation = minRotation, maxRotation = maxRotation, 
                   shuffle = shuffle, rotateRatio = rotateRatio, shape = shape, 
                   ellipticity = ellipticity, figBase64 = base64, hover = htmlwidgets::JS(hoverFunction))
  chart = htmlwidgets::createWidget("wordcloud2", settings, 
                                    width = widgetsize[1], height = widgetsize[2], sizingPolicy = htmlwidgets::sizingPolicy(viewer.padding = 0, 
                                                                                                                            browser.padding = 0, browser.fill = TRUE))
  htmlwidgets::onRender(chart, "function(el,x){\n                        console.log(123);\n                        if(!iii){\n                          window.location.reload();\n                          iii = False;\n\n                        }\n  }")
}


}

Then you modify 2 js files in your package (get to the installation path of your package, you can modify the files directly here without needing to reinstall) :

  • htmlwidgets/wordcloud2.js around line 20 you add the x.label[i] : for(var i=0; i<x.word.length; i++){ listData.push([x.word[i], x.freq[i], x.label[i]]); }
  • htmlwidgets/lib/wordcloud2-0.0.1/hover.js around line 32 replace the item[1] by item[2] document.getElementById("wcSpan").innerHTML =item[0]+":" + item[2];

That should work by using wordcloud3 as you use wordcloud2, but be sure to have you columns word, freq and label (and only these 3) and this order in your input dataframe. Also, the original wordcloud2 will not work after that. Always use wordcloud3. (Or if you are motivated, you can download the sources, do these modifications and reinstall it from the new sources)

robin-loche avatar Feb 05 '20 14:02 robin-loche