Extracting stats can be difficult

Finding stats often involves queries and tables and rigid reports. Companies often use reporting tools that “generate” them periodically.

This rigid structure makes it difficult to make decisions because it isn’t easy to access data as required.

Instead, build a robust dashboard

We found a good way of displaying stats early. Over time, we expanded it from the original 10 to more than a 100 rows

It’s a structure where the columns are different periods and the rows are different stats.

The user can choose:

  • The start and end date
  • The period length (one week, two weeks, one month)

The report then shows all the periods within the selected start and end dates as different columns.

Stats filters

Because the same statistic is always in the same row, it is very convenient to compare it over time.

The report is a table which means it can be copied into Excel for further analysis.

Stats table

Since this report operates on the entire data set, it runs from a different database instance. It also has a cache pre-warmer that loads some of the data and pre-emptively converts entries to JSON.

When the page is loaded, the page shows the current and previous two months because users need that view most frequently.

It also has a simple view where the user can pick a month and see the month before and after it.

The advanced view, besides the fields mentioned above, also has additional filters. For instance, breakdown by area, device, or supplier.

Group breakdown

A key feature is group breakdown. For instance, it can show rows that are the value of all the orders grouped by shipping method.

It also runs predominantly on the client, so loading is fast.

Being able to add rows on the fly is useful too

From a technical perspective, a key feature is adding a row by just defining the formula to be used and the name. It looks something like this: Stats.rows.push(['name', 'attribute'])

The attribute will be eval-ed on each of the collections of orders that correspond to the periods.

This setup also allows me to load the page and execute this in the console if I need a stat that’s not there.

I decided to use Backbone collection to group orders because they already had things like find by ID and parsing JSON. The structure was also easy to extend with utility functions such as collection.sum('order_value').