ja·ne·la

gem, Ruby. A window.

Cross-filtering dashboards, native to Rails.

Declare measures and dimensions on your ActiveRecord models. Click any value and the whole dashboard re-scopes around it. No warehouse, no separate frontend, no admin panel bolted on the side.

Open the live dashboard Read the source

gem "janela", "~> 0.16"

Free and open source, running 0.16.1 right here.

This one is live. Click a bar.

A few panes over a year of demo orders. Clicking a value filters the others and puts the filter in the URL, so a filtered dashboard is a link you can send. Hold Ctrl, or Cmd on a Mac, to select more than one value. Escape clears. Nothing here is a video.

Revenue $660,823.69

Revenue by Status
Revenue by Region
$277,451.70
$213,135.26
$170,236.73
Orders by Status
paid: 410 pending: 103 refunded: 63 cancelled: 24
410
103
63
24
Revenue by Placed on per week

That dashboard is a few rows in a database table. Nobody deployed to make it, and you can edit it right now.

The full dashboard has nine panes, including a time series and a top five. Janela's own pages serve an index and an editor that need no JavaScript at all.

Why it exists

Every business intelligence option for Rails today is one of two things.

Neither lets you click one chart and re-scope every other chart on the page. That is the part people actually buy a commercial tool for, and it is the part Janela does.

What you get

Measures and dimensions

Declared on the model, in a block a competent Rails developer reads in one sitting. Not a new query language.

Cross-filtering

Turbo Frames and one Stimulus controller. You write no JavaScript, and there are no sockets or streams to run.

Every pane is a URL

/dashboards/orders/revenue/status?as=bar is a whole pane. Openable, linkable, cacheable.

A dashboard can be data

Compose in ERB, or let an analyst who cannot deploy build one from records with nothing but HTML.

Snapshots

Freeze the numbers at an instant so an audience sees exactly what was signed off while the live one keeps moving.

Your authorisation

Every query runs through your own policy_scope. Janela adds no tenancy of its own and asks before it reads.

The whole of it

Declare once on the model, then put panes wherever you want them.

class Order < ApplicationRecord
  belongs_to :customer

  janela do
    measure :revenue, sum: :amount, prefix: "$"
    measure :orders, count: true

    dimension :status
    dimension :region, through: :customer
    dimension :placed_on, granularity: :month
  end
end
<%= janela_frame do %>
  <%= janela_pane Order, :revenue %>
  <%= janela_pane Order, :revenue, by: :status, as: :bar %>
  <%= janela_pane Order, :revenue, by: :region %>
<% end %>

Add the gem, mount the engine, register two Stimulus controllers. That is the install.

Built to be forked

MIT licensed, and small on purpose. Janela ships the load-bearing part of a business intelligence tool and stops. Everyone's remaining five per cent is different, so the project stays legible enough that taking it apart is a normal way to use it rather than a last resort. Every decision is recorded as an ADR, so you can read why a piece exists before you change it.

Source on GitHub The decisions

Questions

Do I need a data warehouse?

No. Janela queries your database through ActiveRecord and owns no data store of its own. If you later put your reporting data somewhere columnar, a measure is still a measure.

Does it respect my authorisation?

Yes, and without configuration. If your controller defines policy_scope, every pane is calculated through it, including the ones an analyst composed. There is a guide for multi tenant applications.

Do I need a JavaScript build step?

No. On importmap the engine pins what it needs. On esbuild or bun there is an npm package with the same two controllers. Charts use Chart.js and nothing else.

Can someone who cannot deploy build a dashboard?

Yes. A dashboard is a record, so the engine's own pages let them add panes, reorder them and set the grid, working with plain HTML. They can only pick measures and dimensions your models already declare.

Is it ready?

It is an alpha at 0.16.1, used in real applications and covered by unit and real browser tests. Breaking change is communicated in an upgrade guide and a janela:doctor task that reads your application and tells you what to change.

What does Janela mean?

Window, in Portuguese. A window has frames and panes, which is where the rest of the vocabulary comes from. None of it is a word your own application is likely to want, which is the point.