与 x 和 y 值(而不是像素大小)相关的线宽 - htmlwidgets plotly R

Line width related to x and y values (rather than pixel size) - htmlwidgets plotly R

我的目标是使用 htmlwidgets 包中的 onRender() 函数制作绘图,用户可以在其中单击一个点并绘制一条灰线。我正在尝试将灰线的粗细设置为一个变量。

我有一个暂定的 MWE,如下所示。但是,我目前有一个问题。基本上,线条的宽度会根据图像 and/or 浏览器的大小调整而变化。这会产生一个问题,因为一些点会根据不断变化的线宽(由于图像或浏览器调整大小)而从灰线内部或外部发生变化。不过,圆点是在灰线内还是在灰线外,我需要保持一致的意思。

因此,我试图将线的粗细指定为相对于 x 和 y 轴值的值(而不是屏幕上可以更改大小的像素值)。我希望这会创建一个一致的灰线宽度,即使用户调整图像或浏览器的大小也不会相对于点发生变化。这在onRender()函数中可以完成吗?

library(plotly)
library(broom)
library(htmlwidgets)

dat <- mtcars
dat$mpg <- dat$mpg * 10
maxVal = max(abs(dat))
maxRange = c(-1*maxVal, maxVal)

# Specify line width
ciVal = 100

p <- ggplot(data = dat, aes(x=disp,y=mpg)) + geom_point(size=0.5) + coord_cartesian(xlim = c(maxRange[1], maxRange[2]), ylim = c(maxRange[1], maxRange[2]))

ggplotly(p) %>%
  onRender("
           function(el, x, data) {
            el.on('plotly_click', function(e) {

              var trace1 = {
                 x: [0, 600],
                 y: [0, 600],
                 mode: 'lines',
                 line: {
                   color: 'gray',
                   width: 2*data.ciVal
                 },
                 opacity: 0.5
              }

              Plotly.addTraces(el.id, trace1);
           })
          }
          ", data = list(dat=dat, ciVal=ciVal))

注意:这个问题是对我之前提出的问题 () 的额外调整。

您可以用两条线来标记边界并填充中间的 space (fill: 'tonexty'),而不是使用一条宽度不同的线。因此,该线将始终根据您的轴范围和缩放比例调整大小。

library(plotly)
library(htmlwidgets)

dat <- mtcars
dat$mpg <- dat$mpg * 10
maxVal = max(abs(dat))
maxRange = c(-1*maxVal, maxVal)

p <- ggplot(data = dat, aes(x=disp,y=mpg)) + geom_point(size=0.5) + coord_cartesian(xlim = c(maxRange[1], maxRange[2]), ylim = c(maxRange[1], maxRange[2]))

ggplotly(p) %>%
  onRender("
           function(el, x, data) {
           el.on('plotly_click', function(e) {

           var trace1 = {
             x: [0, 500],
             y: [450, 50],
             mode: 'lines',
             line: {
               color: 'gray',
               width: 2
             },
             opacity: 0.5
           }
           var trace2 = {
             x: [0, 500],
             y: [250, -150],
             mode: 'lines',
             fill: 'tonexty',
             line: {
               color: 'gray',
               width: 2
             },
             opacity: 0.5
           }
           Plotly.addTraces(el.id, trace1);
           Plotly.addTraces(el.id, trace2);

           })
           }
           ", data = list(dat=dat, ciVal=ciVal))