1

I'm trying to embed hyperlinks within a plot of likert data, using a combination of the likert package and the gridSVG packages. I want to link the text of each question to a separate link, but I'm having problems. The following code embeds a single link to the text of every question, but I can't figure-out how to embed on each question separately, because the set of questions seem to be grouped in a single grob together. Thanks in advance for your input.

#creates an example plot from sample data from likert package.
require(likert) 
data(pisaitems)
items29 <- pisaitems[,substr(names(pisaitems), 1,5) ==  "ST25Q" ]
names(items29) <- c("Magazines", "Comic books", "Fiction",
               "Non-fiction books", "Newspapers")
l29 <- likert(items29)
summary(l29)
plot(l29)

require(grid)
require(gridSVG)

#identifies grob of question text (all questions are in a single grob)
titleGrobName <- grep("axis-l.3-3-3-3", grid.ls(print=FALSE)$name, value=TRUE)

#embeds link in grob
grid.hyperlink(titleGrobName, "http://www.r-project.org")

#creates svg
gridToSVG("testPlot.svg", "none", "none")
Jeremyjaytaylor
  • 163
  • 1
  • 1
  • 6

1 Answers1

2

This grouped GROB is not uncommon. Since I don't think we want to rewrite likert to ungroup these, we might be better off by manipulating the SVG after grid with XML. Here is one way of accomplishing this.

live example

We could also add the links on the HTML/JavaScript side if you expect this graphic to be part of a bigger web page.

#creates an example plot from sample data from likert package.
require(likert) 
data(pisaitems)
items29 <- pisaitems[,substr(names(pisaitems), 1,5) ==  "ST25Q" ]
names(items29) <- c("Magazines", "Comic books", "Fiction",
                    "Non-fiction books", "Newspapers")
l29 <- likert(items29)
summary(l29)
plot(l29)

# if possible to use htmltools from RStudio
#   install.packages("htmltools")
#  then we can add the links on the
#  XML side instead of in grid
library(XML)
library(htmltools)
library(gridSVG)

# export as XML SVG
likert_svg <- grid.export("", addClasses=TRUE)$svg

# find our axes
nodes <- getNodeSet(
  likert_svg,
  # thanks http://stackoverflow.com/questions/5818681/xpath-how-to-select-node-with-some-attribute-by-index
  "(//x:g[contains(@id,'axis')])[1]//x:tspan",
  "x"
)

lapply(
  nodes,
  function(node){
    # get the text value of the node
    lbl = xmlValue(node)
    # remove the text from our node
    xmlValue(node) <- ""

    # create a <a href=> hyperlink
    #  https://www.w3.org/wiki/SVG_Links
    a_node <- newXMLNode(
      "a",
      #######   change your link here ###########
      attrs = c("xlink:href"=paste0("http://google.com/search?q=",lbl)),
      lbl
    )
    # add our new linked text to the node
    addChildren(node, a_node)
  }
)


# look at it in the browser/RStudio Viewer
browsable(
  HTML(
    saveXML(
      #  export as SVG XML
      likert_svg,
      prefix = ""
    )
  )
)
timelyportfolio
  • 6,479
  • 30
  • 33
  • timelyportfolio's javascript example appears to work. Thanks! – Jeremyjaytaylor Apr 04 '16 at 17:13
  • The example does appear to work, but how do export the resulting svg file with the linked axis labels? In the example the resulting svg opens in a browser, which appears to be living in a temporary folder, but how can I do the manipulation and then export the resulting svg with the linked axis (like I did when I previously exported "testPlot.svg")? I tried adding a file name to the `grid.export("", addClasses=TRUE)$svg` part of the example code, which did create an svg file, but it did not have the live links. Thanks for your help! – Jeremyjaytaylor Apr 12 '16 at 01:19
  • If I understand correctly, the `saveXML` will give you what you want (see http://www.inside-r.org/packages/cran/xml/docs/saveXML). You can eliminate the `prefix=""` if you want a full XML, and if you want a file you can specify `file = "mysvg.svg"`. `saveXML(likert_svg, prefix = "" )` – timelyportfolio Apr 12 '16 at 20:49