Recreating a custom dashboard in Omni

Using calculations, markdown visualizations, and a bit of HTML/CSS to get it just right

Recreating a custom dashboard in Omni hero image

We spend a lot of time thinking about the best ways to visualize data, and one of the ways I enjoy doing this is by learning how others approach the problem. Recently, my colleague Trevor shared a mortgage rate demo dashboard from Observable that one of our customers liked for its visualizations, interactions, and design details. I was inspired to recreate it in Omni and here is how I approached it. 

In this post, I’ll walk through: 

But first, let’s admire the original. #

1-original-dashboard

It’s a straightforward, clean design: a short intro at the top, 2 summary cards, and 2 time series charts. However, there are a lot of details to appreciate:

The creator smartly used color consistently throughout the dashboard — the 30-year metrics are blue and the 15-year metrics are yellow. By underlining the names of these metrics in the intro with their corresponding color, legends aren’t needed on any of the subsequent charts.

Visually, the time series charts have been stripped of unnecessary details to help the user focus on what matters most. 

The summary cards provide easy-to-read information in a small space and add a lot of context to the time series. They also include a lovely little strip plot. 

The dashboard is also interactive — the top time series chart is a zoomed view of the selection in the bottom, all-time chart. When you click and drag on the bottom chart, the other time series chart updates. This data set includes over 50 years of mortgage rates, so this provides awesome historical context for understanding the last year.

2-original-dashboard-annoted

Recreating this custom dashboard in Omni #

We want to help our customers quickly create beautiful visualizations and dashboards, and also have the ability to customize exactly what they want. To do this, Omni provides a lot of great charts and dashboard elements out of the box as well as some powerful calculation, markdown, and custom visualization features. I started to think about how I could play with what we have in Omni to recreate this dashboard. Getting all this actual mortgage rate data would have been a pain, so my version below uses generic eCommerce data I had readily available.

Building time series charts #

I started with what’s easy out of the box.

At first glance, I was pretty sure I could build the time series charts quickly. The data is straightforward, and our built-in styling controls could get close to the stripped-down aesthetic. I really liked some of the small details the builder added to these charts and was able to mimic those:

  • Using the step interpolation to make it easy to compare weekly changes

  • Removing unnecessary details: x-axis label, most vertical lines, the y-axis line, & the legend

  • Formatting the axis labels correctly and in an easy-to-read format

  • Customizing the colors of the series

There’s a small detail on the top-right chart that I liked a lot: a dot on the last value of each line.

2.5-zoom-on-dots

It's a nice subtle way to indicate “this is where we are now” if you’re working with data that’s updating regularly. This is less straightforward to add in Omni. To do this, I created a separate calculation in the result table that only included the value for the most recent data. I set the mark type to “points” and colored it the same as the line to create a similar effect. It was definitely a bit hacky, and since we don’t yet support styling options for the points, I couldn’t quite get it to visually pop as well as I’d like. So, I’m taking note that this is an area where we have some room to improve our out-of-the-box configuration options 😅 (peek at our weekly demos to see our progress).

3-last-row-calculation

Before I move on, there are two details I liked but didn't implement. The obvious one is the cross-filtering interactivity. While possible with some advanced Vega visualization configurations, I wanted to preserve the 2-tile aesthetic, which wasn’t possible with the advanced Vega approach. Additionally, I wasn’t able to configure the x-axis tick labels to not repeat the year for each month's tick mark. That is a nice touch for reducing “chart junk.” We definitely want to support this level of interactivity and even more detailed out-of-the-box customizations in the future. 

Creating markdown summary cards #

Next, I moved on to the summary cards. I really liked these because they provide a lot of context about the highlighted metric with the change percents, comparisons, and averages. The trend arrows catch your eye and provide understanding with just a quick glance. Additionally, the strip plot presents the exact same data from the 52-week time series chart to the right, but in a different way that helps the user understand the distribution as well as the trend over time.

4-summary-card-up-close

We don’t have an out-of-the-box chart like this. But we do have really powerful ways to combine Excel calculations and our markdown visualizations to create all sorts of bespoke visualizations, if you know a little HTML and CSS. 

I’ll show you how I approached building these custom cards.

1) Get all the necessary data in one query 

Omni markdown visualizations can reference any data in your results table, including calculations. If you look closely at the data in these cards, there’s very little data we need from the database: the last year of the metric broken down by week. The rest of these values are just calculations: averages, change rates, min value, and max value.

5-query-data-vs-calculated-values
6-query-vs-calcs-datatable

2) Build the basic HTML/CSS

Next, I headed over to the markdown visualization editor to start putting down some basic HTML and CSS. Using mustache, I popped values from the query into my HTML and CSS. I typically use the little inserter widget to get individual values because the markdown references can be a bit long and tricky to type out. 

Recently, we added the ability to see both the chart and results at the same time, which made it a lot easier to verify I was putting the right values into my markdown. Honestly, for the top part of the card, getting and styling the data was pretty straightforward.

7-insert-markdown-values-menu

3) Get clever with CSS

To add the cute trend icons and strip plot, I needed to get creative with HTML, CSS, and calculations in Omni. 

Going back to the results table, I added more calculations to the result set that I’ll only use to control the presentation:

  • A string for the 1-week change trend that I’ll use as a CSS class name

  • A string for the 1-year change trend that I’ll use as a CSS class name

  • Some columns to calculate the % value to properly place each week’s tick mark

Trend arrows

I inserted the trend arrows as SVGs directly into the table. This isn’t the most efficient way to do this — with 3 SVGs (up, down, stable) for each place we want to show the trend, but it works 🤷 and ensures they’ll get generated in any PDFs or PNGs of the resulting dashboard. I also assigned a class name to the table cell based on the result set to allow me to target hiding and showing each of those SVGs based on the data.

Next, here’s the CSS I used to show the correct trend direction while hiding the others:

Using calculations as class names allowed me to get creative with markdown. If you’re interested in learning more, we have additional examples where we’ve used this same hack to hide and show different text or images, drive color, etc. 

Strip plot

For the strip plot, I used mustache list syntax to insert a list item for every data point for the last 52 weeks. In the CSS, I absolutely positioned those list items by directly inserting into each list item’s style tag the “left” property I calculated in the results table. I also added one extra tick that duplicates the most recent tick so I could style it separately to stand out. 

Here’s the code I used just to generate the strip plot:

Final summary card

Finally, I put all of this together and got a lovely little summary card that looks pretty close to the original.

8-summary-card-side-by-side

4) Use a field selector control to make duplicating the card easy

There are two of these lovely summary cards on this dashboard, so it’s possible to create the second query with a bit of copy-paste work. It’s just a bit tedious since Omni doesn't have a way to templatize or reuse these custom markdown visualizations…yet. These templates are on our list, but for now, here’s a little trick I’ve found to make reusing work a bit easier:

Fortunately, the format and calculations for these cards are identical — the only difference is the underlying field. So, I added a field selector on the Average Sale Price column and added my other metric to it on the results table. Then, I just duplicated the tab and switched the metric to display. All the calculated fields were built from that column so they immediately updated as well! There was a little cleaning necessary for my example because the formatting between my two metrics (a number vs. currency) is different. Lastly, I did some minor adjustments to the CSS to give the new tile a different color value.

field-swapper

Adding the introduction markdown #

The introduction tile is also a markdown tile, which is built from a very simple query pulling the date for the start of the last completed week. The bulk of the custom markdown work here comes in adding the CSS styling.

9-intro-tile

Tweaking the dashboard theme #

The final touches involved a little tweaking to the introduction tile to hide the background and build a simple custom theme. In my theme, I only changed a few colors: dashboard background, tile background, and tile borders. While it’s possible to copy the exact colors from the example dashboard, there are some disadvantages to hardcoding a specific color. Out-of-the-box, Omni’s dashboards have been built to work in both light and dark mode; however, once you begin to hardcode a color to look good in one mode, it often doesn’t work in the other. This is definitely an area we need to build better tooling for folks.

There is a little workaround that can sometimes help, but it requires a little bit of insider knowledge 💡. Internally, we use some CSS variables that will automatically set the correct Omni colors for backgrounds and text in light or dark mode. For example, “var(--color-background)” will be white in light mode and very dark gray in dark mode. While these colors may not perfectly match your design, they can be referenced in any markdown CSS and in custom themes.

However, if you do end up building some highly customized dashboards that work only in light or dark mode, we recently shipped the ability to restrict your instance and user preferences. Here’s the demo from my teammates, Luke and Alisa, if you’d like to check it out. 

Final bits and thoughts #

After the better part of an afternoon, I got pretty close to the original dashboard with our customization capabilities and custom markdown. Although, I did experience a few hiccups and workarounds that I’m looking forward to ironing out. 

As much as we strive to make our out-of-the-box experience look and feel as good as possible, we also want to give customers the necessary control to make end products look and feel like their own. Learning from and trying to recreate examples like this are fun little experiments for me — they help me understand our customer experience even better and identify new ways to make more possible with Omni.  

Ta-da, not bad! 🥳

10-side-by-side

If you’d like to follow along with what our engineering team is up to, you can check out our weekly engineering demos for the latest! And if you have a custom visualization you’d like help building, reach out to our team in Slack – I’d be happy to pop in.