直接在 htmlWidgets 的 onRender() 函数中闪亮的反应值
Shiny reactive value directly in onRender() function of htmlWidgets
我有一个有两个图的 Shiny 应用程序。如果用户单击顶部图中的一个点,该点的 x 和 y 坐标将保存到反应式 Shiny 变量中(在下面的代码中,它称为 pointSel)。
在底部绘图中,我希望将此 pointSel 的 x 和 y 坐标绘制为绿点。我目前有这个工作(如下面的脚本所示)。但是,每次更新 pointSel 对象时,都会重新绘制第二个图。相反,我试图不绘制第二个绘图背景,并简单地在其上覆盖一个新的绿点。
我认为这需要两件事:
1) isolate()函数应用于onRender()函数中的"data = pointSel()"。
2) 如果 pointSel 已更新,一些语法会提醒仅添加绿点轨迹。我在注释“$('#pointSel').on('click',function()”.
中给出了暂定语法
下面是我的代码:
library(plotly)
library(GGally)
library(hexbin)
library(htmlwidgets)
library(tidyr)
library(shiny)
library(edgeR)
library(EDASeq)
library(dplyr)
library(data.table)
library(ggplot2)
ui <- shinyUI(fluidPage(
plotlyOutput("plot1"),
plotlyOutput("plot2")
))
server <- shinyServer(function(input, output) {
data <- data.frame(mpg=mtcars$mpg,qsec=mtcars$qsec)
output$plot1 <- renderPlotly({
p <- qplot(data$mpg,data$qsec)
pP <- ggplotly(p)
pP %>% onRender("
function(el, x, data) {
el.on('plotly_click', function(e) {
var pointSel = [e.points[0].x, e.points[0].y]
Shiny.onInputChange('pointSel', pointSel);
})}
", data = data)
})
pointSel <- reactive(input$pointSel)
output$plot2 <- renderPlotly({
p2 <- qplot(mpg,qsec,data=data, geom="point", alpha=I(0))
pP2 <- ggplotly(p2)
pP2 %>% onRender("
function(el, x, data) {
console.log('Whole bottom plot is being redrawn')
var myX = data[0]
var myY = data[1]
//$('#pointSel').on('click',function() {
var Traces = [];
var trace = {
x: [myX],
y: [myY],
mode: 'markers',
marker: {
color: 'green',
size: 10
}
};
Traces.push(trace);
Plotly.addTraces(el.id, Traces);
//})
}", data = pointSel())
})
})
shinyApp(ui, server)
注意:这与我之前 post 编辑的问题类似,并且有一个有用的答案 ()。我一直遇到这个问题的变体(无法在 onRender() 函数中将绘图的各个方面覆盖到背景图),而当前的 post 只是该问题的另一个变体。我正试图为这种情况找到类似的答案!感谢您的任何建议。
您可以在 onRender
函数中使用自定义消息处理程序,并在 server.R
中使用它来传递选定的点坐标。
第二个图的 onRender
函数可能如下所示:
function(el, x, data) {
Shiny.addCustomMessageHandler('draw_point',
function(point) {
var Traces = [];
var trace = {
x: [point[0]],
y: [point[1]],
mode: 'markers',
marker: {
color: 'green',
size: 10
}
};
Traces.push(trace);
console.log(Traces);
Plotly.addTraces(el.id, Traces);
});
}
在您的 server.R
中,您可以:
observe({
session$sendCustomMessage(type = "draw_point", input$pointSel)
})
Whenever a point is selected, the coordinates will be sent to the function defined in the onRender
and the point will be drawn.
我有一个有两个图的 Shiny 应用程序。如果用户单击顶部图中的一个点,该点的 x 和 y 坐标将保存到反应式 Shiny 变量中(在下面的代码中,它称为 pointSel)。
在底部绘图中,我希望将此 pointSel 的 x 和 y 坐标绘制为绿点。我目前有这个工作(如下面的脚本所示)。但是,每次更新 pointSel 对象时,都会重新绘制第二个图。相反,我试图不绘制第二个绘图背景,并简单地在其上覆盖一个新的绿点。
我认为这需要两件事:
1) isolate()函数应用于onRender()函数中的"data = pointSel()"。
2) 如果 pointSel 已更新,一些语法会提醒仅添加绿点轨迹。我在注释“$('#pointSel').on('click',function()”.
中给出了暂定语法下面是我的代码:
library(plotly)
library(GGally)
library(hexbin)
library(htmlwidgets)
library(tidyr)
library(shiny)
library(edgeR)
library(EDASeq)
library(dplyr)
library(data.table)
library(ggplot2)
ui <- shinyUI(fluidPage(
plotlyOutput("plot1"),
plotlyOutput("plot2")
))
server <- shinyServer(function(input, output) {
data <- data.frame(mpg=mtcars$mpg,qsec=mtcars$qsec)
output$plot1 <- renderPlotly({
p <- qplot(data$mpg,data$qsec)
pP <- ggplotly(p)
pP %>% onRender("
function(el, x, data) {
el.on('plotly_click', function(e) {
var pointSel = [e.points[0].x, e.points[0].y]
Shiny.onInputChange('pointSel', pointSel);
})}
", data = data)
})
pointSel <- reactive(input$pointSel)
output$plot2 <- renderPlotly({
p2 <- qplot(mpg,qsec,data=data, geom="point", alpha=I(0))
pP2 <- ggplotly(p2)
pP2 %>% onRender("
function(el, x, data) {
console.log('Whole bottom plot is being redrawn')
var myX = data[0]
var myY = data[1]
//$('#pointSel').on('click',function() {
var Traces = [];
var trace = {
x: [myX],
y: [myY],
mode: 'markers',
marker: {
color: 'green',
size: 10
}
};
Traces.push(trace);
Plotly.addTraces(el.id, Traces);
//})
}", data = pointSel())
})
})
shinyApp(ui, server)
注意:这与我之前 post 编辑的问题类似,并且有一个有用的答案 (
您可以在 onRender
函数中使用自定义消息处理程序,并在 server.R
中使用它来传递选定的点坐标。
第二个图的 onRender
函数可能如下所示:
function(el, x, data) {
Shiny.addCustomMessageHandler('draw_point',
function(point) {
var Traces = [];
var trace = {
x: [point[0]],
y: [point[1]],
mode: 'markers',
marker: {
color: 'green',
size: 10
}
};
Traces.push(trace);
console.log(Traces);
Plotly.addTraces(el.id, Traces);
});
}
在您的 server.R
中,您可以:
observe({
session$sendCustomMessage(type = "draw_point", input$pointSel)
})
Whenever a point is selected, the coordinates will be sent to the function defined in the onRender
and the point will be drawn.