The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
myIO provides standard htmlwidgets Shiny bindings, so
charts work like any other output in your Shiny app. This vignette
covers the basics, interactive I/O patterns, and common recipes.
Use myIOOutput() in the UI and renderMyIO()
in the server:
library(shiny)
library(myIO)
ui <- fluidPage(
titlePanel("myIO + Shiny"),
myIOOutput("chart", width = "100%", height = "400px")
)
server <- function(input, output) {
output$chart <- renderMyIO({
myIO() |>
addIoLayer(
type = "point",
color = "steelblue",
label = "scatter",
data = mtcars,
mapping = list(x_var = "wt", y_var = "mpg")
)
})
}
shinyApp(ui, server)Because renderMyIO() is reactive, the chart updates
automatically when inputs change. Use standard Shiny reactivity to
filter or transform data:
library(shiny)
library(myIO)
ui <- fluidPage(
titlePanel("Reactive myIO Chart"),
sidebarLayout(
sidebarPanel(
selectInput("cyl", "Cylinders:",
choices = c("All", sort(unique(mtcars$cyl))),
selected = "All"
),
selectInput("chart_type", "Chart Type:",
choices = c("point", "bar", "line"),
selected = "point"
)
),
mainPanel(
myIOOutput("chart", height = "500px")
)
)
)
server <- function(input, output) {
filtered_data <- reactive({
if (input$cyl == "All") mtcars else mtcars[mtcars$cyl == as.numeric(input$cyl), ]
})
output$chart <- renderMyIO({
myIO() |>
addIoLayer(
type = input$chart_type,
color = "#E69F00",
label = "data",
data = filtered_data(),
mapping = list(x_var = "wt", y_var = "mpg")
) |>
setAxisFormat(xLabel = "Weight (1000 lbs)", yLabel = "Miles per Gallon") |>
setMargin(top = 20, bottom = 70, left = 60, right = 10)
})
}
shinyApp(ui, server)setBrush() enables rectangle selection on a chart. The
selected data points are available as a Shiny reactive input:
library(shiny)
library(myIO)
ui <- fluidPage(
titlePanel("Brush Selection"),
fluidRow(
column(8, myIOOutput("chart", height = "400px")),
column(4,
h4("Selected Points"),
verbatimTextOutput("selected")
)
)
)
server <- function(input, output) {
output$chart <- renderMyIO({
myIO() |>
addIoLayer(
type = "point",
color = "#4E79A7",
label = "scatter",
data = mtcars,
mapping = list(x_var = "wt", y_var = "mpg")
) |>
setBrush() |>
setAxisFormat(xLabel = "Weight", yLabel = "MPG")
})
output$selected <- renderPrint({
brushed <- input$`myIO-chart-brushed`
if (is.null(brushed)) return("Drag to select points")
sel <- jsonlite::fromJSON(brushed)
if (length(sel$keys) == 0) return("No points selected")
paste(length(sel$keys), "points selected")
})
}
shinyApp(ui, server)The brush input key follows the pattern
myIO-{outputId}-brushed. The payload includes:
data — array of selected row objectskeys — _source_key values for each
selected pointextent — brush bounds in data coordinatesUse direction = "x" or direction = "y" for
single-axis brushing.
setAnnotation() enables click-to-label mode. Each
annotation is stored as structured data and available as a Shiny
reactive:
library(shiny)
library(myIO)
ui <- fluidPage(
titlePanel("Data Annotation"),
fluidRow(
column(8, myIOOutput("chart", height = "400px")),
column(4,
h4("Annotations"),
tableOutput("annotations")
)
)
)
server <- function(input, output) {
output$chart <- renderMyIO({
myIO() |>
addIoLayer(
type = "point",
color = "#4E79A7",
label = "scatter",
data = mtcars,
mapping = list(x_var = "wt", y_var = "mpg")
) |>
setAnnotation(
labels = c("outlier", "interesting", "normal"),
colors = c(outlier = "#E63946", interesting = "#F4A261", normal = "#2A9D8F")
) |>
setAxisFormat(xLabel = "Weight", yLabel = "MPG")
})
output$annotations <- renderTable({
ann <- input$`myIO-chart-annotated`
if (is.null(ann)) return(data.frame())
parsed <- jsonlite::fromJSON(ann)
if (length(parsed$annotations) == 0) return(data.frame())
parsed$annotations[, c("label", "x", "y", "category")]
})
}
shinyApp(ui, server)The annotation input key is myIO-{outputId}-annotated.
Each annotation includes _source_key, x,
y, label, category (color), and
timestamp.
setLinked() connects two or more myIO charts via
Crosstalk. Brushing points in one chart highlights them in the
other:
library(shiny)
library(myIO)
library(crosstalk)
ui <- fluidPage(
titlePanel("Linked Brushing"),
fluidRow(
column(6, myIOOutput("scatter1", height = "350px")),
column(6, myIOOutput("scatter2", height = "350px"))
)
)
server <- function(input, output) {
shared <- crosstalk::SharedData$new(mtcars, key = ~rownames(mtcars))
output$scatter1 <- renderMyIO({
myIO() |>
addIoLayer(
type = "point",
color = "#4E79A7",
label = "wt vs mpg",
data = shared$data(),
mapping = list(x_var = "wt", y_var = "mpg")
) |>
setBrush() |>
setLinked(shared, mode = "source") |>
setAxisFormat(xLabel = "Weight", yLabel = "MPG")
})
output$scatter2 <- renderMyIO({
myIO() |>
addIoLayer(
type = "point",
color = "#E15759",
label = "hp vs mpg",
data = shared$data(),
mapping = list(x_var = "hp", y_var = "mpg")
) |>
setLinked(shared, mode = "target") |>
setAxisFormat(xLabel = "Horsepower", yLabel = "MPG")
})
}
shinyApp(ui, server)Both charts share the same SharedData object. The
mode parameter controls direction: "source"
emits selections, "target" receives them, and
"both" (default) does both.
Set filter = TRUE to hide non-matching points instead of
dimming them.
setSlider() adds a slider below the chart that sends its
value as a Shiny input. This is useful for adjusting transform
parameters (confidence level, smoothing span, polynomial degree) without
building a separate sidebar:
library(shiny)
library(myIO)
ui <- fluidPage(
titlePanel("Interactive Regression"),
myIOOutput("chart", height = "450px")
)
server <- function(input, output) {
output$chart <- renderMyIO({
ci <- input$`myIO-chart-slider-ci_level` %||% 0.95
myIO(data = mtcars) |>
addIoLayer(
type = "regression",
label = "fit",
mapping = list(x_var = "wt", y_var = "mpg"),
options = list(method = "lm", showCI = TRUE, level = ci)
) |>
setSlider("ci_level", "Confidence Level", 0.80, 0.99, ci, 0.01) |>
setAxisFormat(xLabel = "Weight", yLabel = "MPG")
})
}
shinyApp(ui, server)The slider input key is myIO-{outputId}-slider-{param}.
Use debounce to control how often the slider fires (default
200ms).
Add multiple myIOOutput() calls to display several
charts side by side. Each chart gets its own output ID:
library(shiny)
library(myIO)
ui <- fluidPage(
titlePanel("Multiple Charts"),
fluidRow(
column(6, myIOOutput("scatter", height = "350px")),
column(6, myIOOutput("bars", height = "350px"))
)
)
server <- function(input, output) {
output$scatter <- renderMyIO({
myIO() |>
addIoLayer(
type = "point",
color = "#56B4E9",
label = "scatter",
data = mtcars,
mapping = list(x_var = "wt", y_var = "mpg")
) |>
setAxisFormat(xLabel = "Weight", yLabel = "MPG")
})
output$bars <- renderMyIO({
myIO() |>
addIoLayer(
type = "bar",
color = "#E69F00",
label = "bars",
data = mtcars,
mapping = list(x_var = "cyl", y_var = "mpg")
) |>
defineCategoricalAxis(xAxis = TRUE) |>
setAxisFormat(xLabel = "Cylinders", yLabel = "MPG")
})
}
shinyApp(ui, server)Theme tokens from setTheme() work the same way in
Shiny:
library(shiny)
library(myIO)
ui <- fluidPage(
style = "background-color: #1a1a2e; color: #e0e0e0;",
titlePanel("Dark Mode Dashboard"),
myIOOutput("chart", height = "400px")
)
server <- function(input, output) {
output$chart <- renderMyIO({
myIO() |>
addIoLayer(
type = "line",
color = c("#48dbfb", "#ff6b6b", "#feca57", "#ff9ff3", "#00d2ff"),
label = "Month",
data = within(airquality, Month <- paste0("M", Month)),
mapping = list(x_var = "Day", y_var = "Temp", group = "Month")
) |>
setTheme(
text_color = "#b0b0b0",
grid_color = "#2d2d2d",
bg = "#1a1a2e",
font = "Inter, system-ui, sans-serif"
) |>
setAxisFormat(xLabel = "Day", yLabel = "Temperature")
})
}
shinyApp(ui, server)myIOOutput() accepts width and
height as CSS units. Charts are responsive by default and
will adapt to their container:
All myIO Shiny inputs follow the naming pattern
myIO-{outputId}-{event}:
| Input key | Event | Payload |
|---|---|---|
myIO-{id}-rollover |
Hover on data element | JSON data point |
myIO-{id}-dragEnd |
Point drag completed | JSON { point, layerLabel } |
myIO-{id}-brushed |
Brush selection | JSON { data, extent, keys } |
myIO-{id}-annotated |
Annotation added/removed | JSON { annotations, action } |
myIO-{id}-slider-{param} |
Slider value changed | Numeric value |
myIO-{id}-error |
Render error | Error message string |
setTransitionSpeed(speed = 0) to disable animations if the
chart updates frequently from reactive inputs.dragPoints() enables
interactive point dragging. In a Shiny context, you can use this for
exploratory what-if analysis.setSlider("span", "Span", 0.1, 1.0, 0.5, debounce = 500).For a comprehensive walkthrough with the live demo app embedded, see
the package documentation at
vignette("shiny-integration", package = "myIO").
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.