shinyHeatmap
The goal of {shinyHeatmap}
is to provide a free and local alternative to more advanced user tracking platform such as Hotjar.
{shinyHeatmap}
generates beautiful and persistent visual heatmaps, representing the app usage across many user sessions.
If you ever wondered:
- Is the left action button used?
- Did people notice the new tab?
- Is the top left checkbox still useful?
You should give it a try! If you're concerned about data privacy, {shinyHeatmap}
only records x and y clicks coordinates on the window.
Examples
{shiny}
{bs4Dash}
{shinydashboard}
{shiny.fluent}
Installation
You can install the development version of {shinyHeatmap}
from GitHub with:
# install.packages("devtools")
devtools::install_github("RinteRface/shinyHeatmap")
Getting started
How to use it
The app must have a www
folder since heatmap data are stored in www/heatmap-data.json
by default.
-
In
ui.R
, wrap the UI insidewith_heatmap()
. This initializes the canvas to record the click coordinates. -
In
server.R
, callrecord_heatmap()
. Overall, this recovers the coordinates of each click on the JS side and store them inwww/heatmap-<USER_AGENT>-<DATE>.json
. This may be used later to preview the heatmap by aggregating all compatible user sessions. For instance, mobile platforms are not aggregated with destkop since coordinates would be incorrect. With vanilla{shiny}
templates likefluidPage
, you don't need to change anything. However, with more complex templates, you can pass the target CSS selector of the heatmap container withrecord_heatmap(target = ".wrapper")
. If the app takes time to load, a timeout parameters is available. This could be the case when you rely on packages such as {waiter}. -
To download the heatmap locally, you must add
download_heatmap()
to your app, which will read data stored in the JSON files, generate the heatmap and save it as a png file. By default,download_heatmap()
will show a tiny UI below your app. It allows to see a timeline of the app usage as shown below. To disable the UI, you can calldownload_heatmap(show_ui = FALSE)
, which will show all the aggregated data as well as take a screenshot of the heatmap area. Don't forget to removerecord_heatmap()
if you don't want to generate extra logs! In general, you don't want to usedownload_heatmap()
on a deployed app since end users might not be supposed to access and view usage data.
Below shows an example to record the heatmap:
library(shiny)
library(shinyHeatmap)
# Define UI for application that draws a histogram
ui <- with_heatmap(
fluidPage(
# Application title
titlePanel("Old Faithful Geyser Data"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput(
"bins",
"Number of bins:",
min = 1,
max = 50,
value = 30
)
),
# Show a plot of the generated distribution
mainPanel(plotOutput("distPlot"))
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output, session) {
record_heatmap()
output$distPlot <- renderPlot({
# generate bins based on input$bins from ui.R
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins + 1)
# draw the histogram with the specified number of bins
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
}
# Run the application
shinyApp(ui = ui, server = server)
Options
{shinyHeatmap}
allows to tweak the heatmap style with few lines of code. This may be achieved with the options parameter that expects a list of properties available in the heatmap.js documentation. For instance, below we change the points radius and color:
download_heatmap(
options = list(
radius = 10,
maxOpacity = .5,
minOpacity = 0,
blur = .75,
gradient = list(
".5" = "blue",
".8" = "red",
".95" = "white"
)
)
)
This is ideal if your app contains custom design like in the following example.
Acknowledgement
{shinyHeatmap}
is proudly powered by the excellent and free heatmap.js library. Thanks @pa7 for making this possible.