Search code examples
rshinyflexdashboard

How change flexdashbord::gauge's label in shiny application with reactive data?


I would like the gauge label to change when the value changes.

I created the f_3 function to try to adjust this, but not succeed.

My rmarkdown code:

---
title: "Label of gauge"
runtime: shiny
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: fill
    theme: yeti
---

side{.sidebar}
-------------------------------------------

```{r}
library(tibble)
library(shiny)
library(shinyWidgets)
library(flexdashboard)
```

**Analysis**

```{r}
autonumericInput(
    inputId = "a", 
    value = 10, 
    label = "Value 1", 
    align = "center", 
    currencySymbol = "$", 
    currencySymbolPlacement = "p",
    digitGroupSeparator = ".",
    decimalCharacter = ",", 
    decimalPlaces = 0, 
    minimumValue = 0, 
    maximumValue = 100
)

autonumericInput(
    inputId = "b", 
    value = 10, 
    label = "Value 2", 
    align = "center", 
    currencySymbol = "R$", 
    currencySymbolPlacement = "p", 
    digitGroupSeparator = ".",
    decimalCharacter = ",", 
    decimalPlaces = 0, 
    minimumValue = 0, 
    maximumValue = 100
    )
```

```{r}
f_1 <- function(a, b) {
  a + b
}

reac <- reactive({
  tibble(
    a = input$a, 
    b = input$b
  )
})

pred <- reactive({
  temp <- reac()
  f_1(
    a = input$a, 
    b = input$b
  )
})
```

abc{}
--------------------------------------

###
```{r}
f_3 <- function(x) {
  if (x <= 40) {
    "Danger"
  } else if (x <= 80) {
    "Warning"
  } else ("Success")
}

renderGauge({
  gauge(
    value = round(x = pred(), digits = 0), min = 0, max = 100, symbol = "%", 
    label = f_3(x = pred())
    )
})
```

enter image description here

The label's value always appears as Danger, even when the value changes. What can you do for it to change as the value changes?


Solution

  • It feels like a bug to me. You can open an issue in the {flexdashboard} github and tell them to fix it.

    Meanwhile, I have a workaround for you. This requires you to have some advanced understanding of Shiny, I guess that is beyond what you have learned so far, so I am not gonna explain the details. Read this article if you are interested. In simple words, we write our own Shiny methods to communicate with the web UI and update the UI.

    ---
    title: "Label of gauge"
    runtime: shiny
    output: 
      flexdashboard::flex_dashboard:
        orientation: rows
        vertical_layout: fill
        theme: yeti
    ---
    
    side{.sidebar}
    -------------------------------------------
    
    ```{r}
    library(tibble)
    library(shiny)
    library(shinyWidgets)
    library(flexdashboard)
    ```
    
    **Analysis**
    
    ```{r}
    autonumericInput(
        inputId = "a", 
        value = 10, 
        label = "Value 1", 
        align = "center", 
        currencySymbol = "$", 
        currencySymbolPlacement = "p",
        digitGroupSeparator = ".",
        decimalCharacter = ",", 
        decimalPlaces = 0, 
        minimumValue = 0, 
        maximumValue = 100
    )
    
    autonumericInput(
        inputId = "b", 
        value = 10, 
        label = "Value 2", 
        align = "center", 
        currencySymbol = "R$", 
        currencySymbolPlacement = "p", 
        digitGroupSeparator = ".",
        decimalCharacter = ",", 
        decimalPlaces = 0, 
        minimumValue = 0, 
        maximumValue = 100
        )
    ```
    
    ```{r}
    f_1 <- function(a, b) {
      a + b
    }
    
    reac <- reactive({
      tibble(
        a = input$a, 
        b = input$b
      )
    })
    
    pred <- reactive({
      temp <- reac()
      f_1(
        a = input$a, 
        b = input$b
      )
    })
    ```
    
    abc{}
    --------------------------------------
    
    ###
    <div id="gauge">
    
    ```{r}
    f_3 <- function(x) {
      if (x <= 40) {
        "Danger"
      } else if (x <= 80) {
        "Warning"
      } else "Success"
    }
    
    renderGauge({
        session$sendCustomMessage("gauge-text",list(text = f_3(x = pred())))
      gauge(
        value = round(x = pred(), digits = 0), min = 0, max = 100, symbol = "%",
        label = "Danger"
        )
    })
    ```
    
    <script>
    Shiny.addCustomMessageHandler('gauge-text', data=>{
        document.querySelector('#section-gauge svg text[font-size="10px"] tspan').innerHTML = data.text 
    })
    </script>
    </div>