4

按照这个问题中给出的答案我可以通过每次点击获得一个多边形来在绘图上渲染:

带圆圈的地图

但是,我似乎无法找到一种简单的方法来允许polygon()持续存在。按照我现在的方式,每次都会重新绘制初始图和注释。

(a)将注释和绘图解耦以便可以创建多个注释的正确方法是什么?

我觉得我可以使用“Paint Circle”按钮添加一个新的polygon(),但我不知道如何在 R 中创建一个新的“对象”。

代码:

服务器.R

library(shiny)
library(maps)
library(mapdata)
library(rworldmap)
library(gridExtra)

circleFun <- function(center = c(0,0),radius = 1, npoints = 100){
    tt <- seq(0,2*pi,length.out = npoints)
    xx <- center[1] + radius * cos(tt)
    yy <- center[2] + radius * sin(tt)
    return(data.frame(x = xx, y = yy))
}

shinyServer(function(input, output) {
  # Reactive dependencies
  buttonClicked <- reactive(input$paintupdate)

  isolate({
  theworld <- function() {
    myplot <- map("world2", wrap=TRUE, plot=TRUE,
        resolution=2)
  }})

  user.circle <- function() {
    if (buttonClicked() > 0) {
      cur.circ <- circleFun(c(input$plotclick$x,input$plotclick$y),
                            radius=input$radius*100, npoints = 30)
      polygon(x=cur.circ$x,y=cur.circ$y,
              col = rainbow(1000,s=0.5,alpha=0.5)[input$circlecolor])
    }
  }

  output$myworld <- renderPlot({
    theworld()
    user.circle()
  })

  output$clickcoord <- renderPrint({
    # get user clicks, report coords
    if ("plotclick" %in% names(input)) {
      print(input$plotclick)
    }
    print(buttonClicked())
  })



})

用户界面

library(shiny)

# Define UI for application
shinyUI(pageWithSidebar(

  # Application title
  headerPanel("App"),

  sidebarPanel(
    sliderInput("radius", 
                "Location radius", 
                min = 0,
                max = 1, 
                value = 0.1,
                round=FALSE,
                step=0.001),
    sliderInput("circlecolor",
                "Circle color (hue)",
                min=0,
                max=1000,
                step=1,
                value=sample(1:1000,1)),
    actionButton("paintupdate", "Paint Circle"),
    textOutput("clickcoord")
  ),

  mainPanel(
    tabsetPanel(
      tabPanel("Map",
               plotOutput("myworld", height="650px",width="750px",
                          clickId="plotclick")
      )
    )
  )
))
4

1 回答 1

2

您可以稍微更改您的示例并添加一个reactiveValue以使其工作

library(shiny)
library(maps)
library(mapdata)
library(rworldmap)
library(gridExtra)

circleFun <- function(center = c(0,0),radius = 1, npoints = 100){
  tt <- seq(0,2*pi,length.out = npoints)
  xx <- center[1] + radius * cos(tt)
  yy <- center[2] + radius * sin(tt)
  return(data.frame(x = xx, y = yy))
}

library(shiny)

# Define UI for application
runApp(
  list(ui = pageWithSidebar(

    # Application title
    headerPanel("App"),

    sidebarPanel(
      sliderInput("radius", 
                  "Location radius", 
                  min = 0,
                  max = 1, 
                  value = 0.1,
                  round=FALSE,
                  step=0.001),
      sliderInput("circlecolor",
                  "Circle color (hue)",
                  min=0,
                  max=1000,
                  step=1,
                  value=sample(1:1000,1)),
      actionButton("paintupdate", "Paint Circle"),
      textOutput("clickcoord")
    ),

    mainPanel(
      tabsetPanel(
        tabPanel("Map",
                 plotOutput("myworld", height="650px",width="750px",
                            clickId="plotclick")
        )
      )
    )
  ),
  server = function(input, output, session) {
    # Reactive dependencies
    myReact <- reactiveValues()
    buttonClicked <- reactive(input$paintupdate)

    isolate({
      theworld <- function() {
        myplot <- map("world2", wrap=TRUE, plot=TRUE,
                      resolution=2)
      }})


    user.circle <- function(a,b,c,d) {
      cur.circ <- circleFun(c(a,b),
                            radius=c, npoints = 30)
      polygon(x=cur.circ$x,y=cur.circ$y,
              col = rainbow(1000,s=0.5,alpha=0.5)[d])     
    }


    observe({
      if (buttonClicked() > 0) {
        # take a dependence on button clicked
        myReact$poly <- c(isolate(myReact$poly), list(list(a=isolate(input$plotclick$x), b= isolate(input$plotclick$y)
                                             ,c=isolate(input$radius*100), d = isolate(input$circlecolor))))
      }
    }, priority = 100)

    output$myworld <- renderPlot({
      theworld()
        for(i in seq_along(myReact$poly)){
          do.call(user.circle, myReact$poly[[i]])
        }
    })

    output$clickcoord <- renderPrint({
      # get user clicks, report coords
      if ("plotclick" %in% names(input)) {
        print(input$plotclick)
      }
      print(buttonClicked())
    })



  }), display.mode= "showcase"
)

多聚的例子

于 2014-05-03T21:02:16.543 回答