向 R plotly graphic 添加特定的悬停行为

Add specific hovering behaviour to R plotly graphic

我在悬停 R Plotly 图形时无法定义特定行为。这是我想做的:我希望完整的箭头能够响应,这里只是箭头的尖端。我还想,当用户悬停一个箭头时,该箭头保持其不透明度,但其他箭头增加了透明度。 plotly 有可能吗?我尝试了一些 htmlwidgets onRender 选项,但找不到将样式添加到所有其他箭头的方法,除了悬停的箭头。

这是一个 repex :

library(ade4)
library(plotly)
library(FactoMineR)
data("decathlon")
res.pca <- dudi.pca(decathlon[, -13], scannf = FALSE, nf = 5)

res.pca.coord <- res.pca$co

res.pca.coord$Comp1init <- rep(0, nrow(res.pca.coord))
res.pca.coord$Comp2init <- rep(0, nrow(res.pca.coord))

t <- list(
  family = "sans serif",
  size = 14,
  color = toRGB("grey50"))

plot_ly(res.pca.coord, x = ~Comp1, y = ~Comp2, text = rownames(res.pca.coord)) %>% 
  layout(shapes = list(
    list(type = 'circle',
         xref = 'x', x0 = -1, x1 = 1,
         yref = 'y', y0 =  -1, y1 = 1,
         line = list(color = 'blue')))) %>% 
  add_text(textfont = t, 
           textposition = ifelse(res.pca.coord$Comp2 > 0 & res.pca.coord$Comp1 > 0, 'top right', 
                                 ifelse(res.pca.coord$Comp2 > 0 & res.pca.coord$Comp1 < 0, 'top left',
                                        ifelse(res.pca.coord$Comp2 < 0 & res.pca.coord$Comp1 < 0, 'bottom left', 'bottom right')))) %>% 
  add_annotations( x = ~Comp1,
                   y = ~Comp2,
                   xref = "x", yref = "y",
                   axref = "x", ayref = "y",
                   text = "",
                   showarrow = T,
                   ax = ~Comp1init,
                   ay = ~Comp2init)

这不是一个简单的实现。如果有更简单的方法,我不确定它是什么样的。也就是说,第一位代码是 Javascript。如果您在不同的编程语言中使用按钮,它基本上与您用于 updatemenus 的编码相同。

这不会改变不透明度;它模拟不透明度变化。这会使您悬停的点的箭头变黑​​,并将其他箭头更改为浅灰色。当您 'unhover' 时,它会将箭头恢复为原来的颜色。

hoverer = "function(el, x) {
            el.on('plotly_hover', function(d){
              var pn = d.points[0].pointNumber;
              var nCol = Array(12).fill('lightgray');
              nCol[pn] = '#000';
              var xer = d.points[0].data.x;
              var yer = d.points[0].data.y;
              var ann = [];
              for(i = 0; i < xer.length; i++){ 
                ann[i] = {
                  'text': '', 
                  'x': xer[i], 
                  'y': yer[i], 
                  'axref': 'x', 'ayref': 'y', 
                  'arrowcolor': nCol[i], 
                  'showarrow': true, 
                  'ax': 0, 'ay': 0}};
              a2 = {annotations: ann};
              Plotly.relayout(el.id, a2);
            });
            el.on('plotly_unhover', function(d){
              var xer = d.points[0].data.x;
              var yer = d.points[0].data.y;
              var ann = [];
              for(i = 0; i < xer.length; i++){ 
                ann[i] = {
                  text: '', 
                  x: xer[i], 
                  y: yer[i], 
                  axref: 'x', ayref: 'y', 
                  arrowcolor: '#444', 
                  showarrow: true, 
                  ax: 0, ay: 0}};
              Plotly.relayout(el.id, {annotations: ann});
            });}"

现在您将此 Javascript 添加到您的绘图中。为此,您需要调用库 htmlwidgets 或将其附加到函数调用中,就像我在此处所做的那样。

plot_ly(res.pca.coord, x = ~Comp1, y = ~Comp2, text = rownames(res.pca.coord)) %>% 
  layout(shapes = list(
    list(type = 'circle',
         xref = 'x', x0 = -1, x1 = 1,
         yref = 'y', y0 =  -1, y1 = 1,
         line = list(color = 'blue')))) %>% 
  add_text(textfont = t, 
           textposition = ifelse(
             res.pca.coord$Comp2 > 0 & res.pca.coord$Comp1 > 0, 'top right', 
             ifelse(
               res.pca.coord$Comp2 > 0 & res.pca.coord$Comp1 < 0, 'top left',
               ifelse(
                 res.pca.coord$Comp2 < 0 & res.pca.coord$Comp1 < 0, 
                 'bottom left', 'bottom right')))) %>% 
  add_annotations( x = ~Comp1,
                   y = ~Comp2,
                   xref = "x", yref = "y",
                   axref = "x", ayref = "y",
                   text = "",
                   arrowcolor = '#444',
                   showarrow = T,
                   ax = ~Comp1init,
                   ay = ~Comp2init) %>% 
  htmlwidgets::onRender(hoverer)