3MW (Use {bslib} without Shiny)

Guten Tag!

Many greetings from Ulm, Germany. Did you know that you can use the {bslib} package without {shiny}? For example, we could take our small interactive dashboard from last week and wrap it into a nicer layout from {bslib}.

Let’s do that in this week’s newsletter. But first, let me give you my usual announcements.

Combine any plots you want

Remember my last video where I recreated a complex chart from the PEW Research Center? This chart used {patchwork} heavily to assemble the maps and bars into one final plot.

That’s why I decided to take a deep-dive into {patchwork} this week. You can check out the amazing tools that {patchwork} offers in my newest vid.

Course progress

The kind people who are testing the first lessons of my course right now are currently still busy testing. But that doesn’t stop me from adding new content to the course. For example, I added a new lesson on creating complex heat maps like these:

Also, don’t forget that the pre-sale launches soon. It will come with probably around 80% of all lessons and comes at a reduced price. If you’re interest in joining the pre-sale, don’t forget to sign up to the extra mailing list on the course page.

Now, let’s jump into this week’s issue. As always, you can find all of the code on GitHub.

Small recap from last week

Let’s have a look at our dashboard from last week.

As you can see, the output of the table is still a bit ugly. Here, let me show you a zoomed in version so that you can see what’s going on.

Thankfully, we already have some tools to make this look nicer without knowing too much about {DT} tables.

All we have to do is do remember that we can create subsets of shared data sets as long as we use a common group name. Thus, let’s just create a data set in our data prep that contains all the nice labels.

And then we can create two shared data sets. In this case, one data set will contain all the columns and the second data set will contain only the nicely formatted labels.

Better column labels

Still, you will notice that the column labels are terrible. We cannot leave them like this. Hence, we will have to modify the columnDefs in the options of DT::datatable():

Wrap outputs into cards

Cool, our widgets look decent. Time to wrap them into a nice looking dashboard. This is exactly where {bslib} comes in.

For example, we could wrap all of our outputs into a card. In {bslib} this requires wrapping the object first into card_body() and then into card().

If you execute this code chunk, you will see that this will show you one card in RStudio’s Viewer window. Similarly, we can create two cards for both our chart and our table by repeating the process for our table and then wrapping everything into bslib::layout_columns(). (Notice that this aligns the sizes of the two widgets 🤩)

Wrap cards into a page

Neat. We have our outputs ready. Next, let us wrap all of this into a page with a navigation bar on top. Once again, this requires two things:

  1. Wrap bslib::layout_columns() into a bslib::nav_panel() and then

  2. wrap that stuff into a bslib::page_navbar().

That’s a lot of code, I know. Unfortunately, this cannot be helped. At least, we get a nice looking dashboard page where we could even switch panels if we wanted to.

Add a sidebar

All of this is nice and dandy. But we don’t have our filter slider yet. Time to put this into a side bar. That’s exactly what the sidebar argument of page_navbar() is for.

What this argument needs is a bslib::sidebar() into which we can throw in all the things that we want to have on our sidebar. Here’s how that code looks:

This will give us a collapsible sidebar (cool!) but unfortunately our slider doesn’t look well. Have a look.

Give me back my JavaScript

The last part is a bit unfortunate. Here’s the quick rundown of what happens:

  • Inputs usually look like what we currently see in the sidebar

  • Both {shiny} and {crosstalk} apply some custom JavaScript for you behind the scenes to turn this ugly input into a nice looking slider (cool again!)

  • For reasons that bamboozle me, {bslib} seems to overwrite the custom JavaScript from {crosstalk}

  • So no nice looking slider for us 😢

Thankfully, we don’t have to write new JavaScript. We just re-insert the JS code from {crosstalk} again. This works by using htmltools::tags$script() with a reference of where all the JS from {crosstalk} is stored:

“Where the heck did you get that path from?”, I hear you say. And the answer is surprisingly simple: I opened my browser, inspected the HTML code of our dashboard and there it was. Again, {crosstalk} usually calls this stuff itself. It’s just that {bslib} seems to mess with that.

Anyway, now putting this extra code into our sidebar solves all of our problems. And the slider is even themed according to our {bslib} theme. Hooray! 🥳

Hope you’ve enjoyed this week’s newsletter. If you want to reach out to me, just reply to this mail or find me on LinkedIn.

See you next week,
Albert 👋

If you like my content, you may also enjoy these:

Join the conversation

or to participate.