janela 0.16.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83aee3a06740005fd9bf9e81ddc12c6de350ea4b8f6fce34899a94869e0f2615
4
- data.tar.gz: cd6d59364454c17e80302de50377a5ca2ca3f2db2ceb2bd58be8ca6a29d6b878
3
+ metadata.gz: 720d124c207d9183b7450a7be6597adc0593b3addb26cc548cd2e445b828f250
4
+ data.tar.gz: db09ec1528a8b2b75c2369ae1e8d537b515e314416f01cd0e2463cdafab9d64b
5
5
  SHA512:
6
- metadata.gz: 670dcac643875f4723159a3f8ecc4429d9feb115dcf58c7336fc823f8290eff4bb3c25316893dc382958753d43e689c4572416d9371b7fa36e0e23447640052c
7
- data.tar.gz: 6c423db2685c60bb12a6f3878ea956fe926dfde507a9a373d71be3f42092322a22a6958ecf6cc54aee68e6535fd8690e9d4320a0a55da2aa6eed4e40074b0734
6
+ metadata.gz: 9497ce5bb01d59a4e43006bca8c3243ce162c0b5ea760011c58921791acf43df2932785c89d5bc99a7eb62c113b4a53e5fce3a7c983395ac410571fd439e26db
7
+ data.tar.gz: 9f7bcad7c5cbbed3523960fc0f0db1c045fabd8b02e41e1f2bed357a9dad000a6dfaeae9eee02c716acd7e5b65018dff14bfba257e19e5450ee3d302e1b20ac6
data/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.16.1] - 2026-11-02
9
+
10
+ ### Added
11
+
12
+ - **A Charts guide, `docs/charts.md`.** The pane options were documented only in the README, so the demo's Documentation page had nowhere to say how to choose a renderer or how to build a chart with a running total and more series on two axes. The guide covers the renderers, the options that shape one chart, `cumulative:` and `series:` with the combined chart as a worked example, and the colours. It ships in the gem and is listed under Documentation on the demo (ADR 062).
13
+
8
14
  ## [0.16.0] - 2026-10-29
9
15
 
10
16
  ### Added
@@ -320,6 +326,7 @@ First alpha, installed from GitHub for testing in a single host application.
320
326
  - Only models that declare a `janela` block are addressable over HTTP.
321
327
  - ADRs 001 to 004 in `docs/decisions/`, shipped inside the gem.
322
328
 
329
+ [0.16.1]: https://github.com/retail-tasker/janela/releases/tag/v0.16.1
323
330
  [0.16.0]: https://github.com/retail-tasker/janela/releases/tag/v0.16.0
324
331
  [0.15.0]: https://github.com/retail-tasker/janela/releases/tag/v0.15.0
325
332
  [0.14.0]: https://github.com/retail-tasker/janela/releases/tag/v0.14.0
data/README.md CHANGED
@@ -581,7 +581,7 @@ Deliberately out of scope: natural-language query, a separate data warehouse, a
581
581
 
582
582
  ## Status
583
583
 
584
- **v0.16.0 alpha.** The measures/dimensions DSL, time dimensions, cross-filtering with multi-selection, bar, line, doughnut and pie charts, pane URLs, shareable dashboard URLs, snapshots, database-backed frames found by owner and key, panes that hold words or a host partial as well as a query, a host-fixed filter no click can remove and a frame's own permanent one beside it, STI subclasses, the engine's own pages for reading and editing them, bar charts that read in their measure's format and can show each bar's value, category panes that can be ordered either way by their measure or by their label, tools an agent can use to read and arrange a dashboard, and the optional vitral theme work and are covered by unit and real-browser tests, with the classes a theme may target documented in [Theming Janela](docs/theming.md). Not yet built: a visual editor, and narrowing a time pane's own granularity by clicking one of its buckets (a click on a bucket does filter the others). [Vista](docs/roadmap.md), the roadmap, says what 1.0 means and which of these are in it; open work is in [GitHub Issues](https://github.com/retail-tasker/janela/issues).
584
+ **v0.16.1 alpha.** The measures/dimensions DSL, time dimensions, cross-filtering with multi-selection, bar, line, doughnut and pie charts, pane URLs, shareable dashboard URLs, snapshots, database-backed frames found by owner and key, panes that hold words or a host partial as well as a query, a host-fixed filter no click can remove and a frame's own permanent one beside it, STI subclasses, the engine's own pages for reading and editing them, bar charts that read in their measure's format and can show each bar's value, category panes that can be ordered either way by their measure or by their label, tools an agent can use to read and arrange a dashboard, and the optional vitral theme work and are covered by unit and real-browser tests, with the classes a theme may target documented in [Theming Janela](docs/theming.md). Not yet built: a visual editor, and narrowing a time pane's own granularity by clicking one of its buckets (a click on a bucket does filter the others). [Vista](docs/roadmap.md), the roadmap, says what 1.0 means and which of these are in it; open work is in [GitHub Issues](https://github.com/retail-tasker/janela/issues).
585
585
 
586
586
  ## Development
587
587
 
data/docs/charts.md ADDED
@@ -0,0 +1,148 @@
1
+ ---
2
+ Topics: charts, renderers, panes, time, series, cumulative
3
+ ---
4
+
5
+ # Charts and Their Options
6
+
7
+ A pane is a measure, sometimes over a dimension, drawn one way. This page
8
+ is the reference for the drawing: which renderer suits which question, the
9
+ options that change how it reads, and how to put more than one measure on
10
+ a chart. Each option is written the same three ways, in `janela_pane`, as a
11
+ column on a stored pane, and in the pane's URL, so a hand written page, an
12
+ analyst's row and a link all say the same thing.
13
+
14
+ The short version: pick the renderer from the shape of the question, pass
15
+ the option you need, and let the others stay unset. Every option is off
16
+ until a pane asks for it, and a pane that sets none is drawn as it always
17
+ was.
18
+
19
+ ## Choosing a renderer
20
+
21
+ `as:` is `:table` unless the pane says otherwise.
22
+
23
+ | Renderer | The question it answers | Needs |
24
+ | --- | --- | --- |
25
+ | `:table` | what are the exact numbers | anything |
26
+ | `:bar` | how do the values of a category compare | a category dimension |
27
+ | `:line` | how does a measure move over time | a time dimension |
28
+ | `:doughnut`, `:pie` | how is a whole split between a handful of values | a category dimension, no negatives |
29
+ | none, with no `by:` | what is the single figure | a measure alone |
30
+
31
+ ```erb
32
+ <%= janela_pane Order, :revenue %>
33
+ <%= janela_pane Order, :revenue, by: :status, as: :bar %>
34
+ <%= janela_pane Order, :revenue, by: :placed_on, as: :line, granularity: :week %>
35
+ <%= janela_pane Order, :orders, by: :region, as: :doughnut, limit: 8 %>
36
+ ```
37
+
38
+ A table is also what any chart becomes where there is no chart runtime, so
39
+ the numbers are always readable. Bars and lines are drawn in the browser
40
+ with Chart.js. A doughnut or a pie is drawn on the server as SVG with a
41
+ legend of buttons beside it, so it is in the page before any JavaScript
42
+ runs and can be operated from the keyboard. A ring cannot show a negative
43
+ value, so a pane with one is drawn as a table and says so.
44
+
45
+ Clicking a bar, a slice or a table value narrows the other panes on the
46
+ frame. A click on a line's bucket narrows them to that range.
47
+
48
+ ## Shaping one chart
49
+
50
+ These options apply to a single measure over a single dimension.
51
+
52
+ | Option | Does | Applies to |
53
+ | --- | --- | --- |
54
+ | `limit:` | keeps the top rows or bars | table, bar, ring |
55
+ | `sort:` | `:asc`, `:label`, `:label_desc`; the default is largest first | a category pane |
56
+ | `granularity:` | `:hour` to `:year`; the bucket size | a time pane |
57
+ | `height:` | `1` to `5`, from about 96px to about 448px | bar, line |
58
+ | `prominence:` | `1` to `3`, the size of a single figure | a single value |
59
+ | `value_labels:` | writes the value on the chart | bar, line |
60
+ | `companions:` | up to three more columns | table |
61
+
62
+ A bar or line chart is drawn at twice its width, up to 20rem, unless it
63
+ is given a height. Heights and prominences are steps rather than lengths,
64
+ so a stored pane takes them from its form. `value_labels` on a bar is all
65
+ or none: if any label is wider than its bar's share of the chart, none is
66
+ drawn. The README has the detail of each; ADRs 046, 047, 050, 051, 054
67
+ and 055 have the reasons.
68
+
69
+ ## A running total
70
+
71
+ A time pane reads per period by default: orders placed each month.
72
+ `cumulative: true` reads the same buckets as a total to date.
73
+
74
+ ```erb
75
+ <%= janela_pane Order, :orders, by: :placed_on, as: :line, granularity: :month, cumulative: true %>
76
+ ```
77
+
78
+ The total is summed after the read, so the buckets, the filters and a
79
+ click on a bucket are exactly what they were. It is refused, with its
80
+ reason, on a category pane, on a single value, and on a measure that does
81
+ not add up: an average, a minimum, a maximum or a ratio. A running sum of
82
+ averages would be a number, but not the average to date. Per period and to
83
+ date are two different answers that can share a page, so a pane that sets
84
+ `cumulative` has its own frame id.
85
+
86
+ ## More than one series
87
+
88
+ A time pane can carry up to three more measures over the same buckets.
89
+ Each is a hash led by its measure.
90
+
91
+ ```erb
92
+ <%= janela_pane Order, :orders, by: :placed_on, as: :line, granularity: :month, cumulative: true,
93
+ series: [
94
+ { measure: :orders, by: :shipped_on, cumulative: true, title: "Orders shipped to date" },
95
+ { measure: :orders, as: :bar, axis: :right, title: "Orders per month" }
96
+ ] %>
97
+ ```
98
+
99
+ That is orders placed and orders shipped, both to date, as two lines on
100
+ the left axis, with orders per month as bars on a right one.
101
+
102
+ | Key | Means | Left out |
103
+ | --- | --- | --- |
104
+ | `measure` | a measure the model declares | required |
105
+ | `by` | a time dimension of the same model | the pane's own |
106
+ | `cumulative` | a running total | per period |
107
+ | `as` | `line` or `bar` | the pane's renderer if it is one of those, else `line` |
108
+ | `axis` | `left` or `right` | `left` |
109
+ | `title` | the legend's name for it | one Janela writes, such as `Orders shipped to date` |
110
+
111
+ **What the chart does.** Every series' buckets are joined into one axis,
112
+ from the first bucket any series has to the last. A series with no row in
113
+ a bucket reads zero there, so a total to date is flat across a month
114
+ nothing shipped. For a measure that has no value in an empty bucket (an
115
+ average, a minimum, a maximum or a ratio) the bucket is a gap instead. A
116
+ chart with series shows a legend and colours by series rather than by
117
+ category: `--janela-series-1` for the pane's own, the rest in order. Bars
118
+ are drawn behind lines. A right axis exists only when a series asks for
119
+ one, and then both axes are titled with the series on them. A right axis
120
+ that holds only bars is scaled so the tallest reaches about a third of the
121
+ plot, which keeps them from covering the lines.
122
+
123
+ **What it does not do.** Series belong to a time pane. A category pane,
124
+ a ring and a single value refuse them or ignore them, and a stored
125
+ snapshot holds none. A series cannot have its own granularity or filter,
126
+ or come from another model, and nothing stacks. With `value_labels`, each
127
+ line writes its latest value at its end and a bar writes nothing.
128
+
129
+ **Where to set it.** The same keys are rows on the pane form, `cumulative`
130
+ and `series` in `Janela::Tools`, and `?cumulative=1&series[][measure]=orders&series[][by]=shipped_on`
131
+ in the pane URL. Put `measure` first in a series in a URL, because that is
132
+ what starts a new one. A table draws each series as a column after the
133
+ measure's, which is also what a page with no chart runtime shows.
134
+
135
+ ## Colours
136
+
137
+ Bars, slices and series are drawn from eight colours by position, and every
138
+ position after the eighth in one neutral. They are `--janela-series-1` to
139
+ `--janela-series-8` and `--janela-series-other`, and [Theming
140
+ Janela](theming) says how to change them.
141
+
142
+ ## What this page is not
143
+
144
+ It is not the list of what can be asked of a model; that is the model's
145
+ own `janela` block, and `Janela::Definition` answers it. It is not the
146
+ layout around a pane either, which is [Composing a Page Around
147
+ Panes](composing). The decisions behind the options are the ADRs: 062 for
148
+ running totals and series, and the README for the rest.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Janela
4
- VERSION = "0.16.0"
4
+ VERSION = "0.16.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: janela
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.16.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jay Killeen
@@ -151,6 +151,7 @@ files:
151
151
  - db/migrate/20261029000001_add_series_to_janela_panes.rb
152
152
  - db/migrate/20261029000003_add_ignore_unknown_filters_to_janela_panes.rb
153
153
  - docs/agents.md
154
+ - docs/charts.md
154
155
  - docs/composing.md
155
156
  - docs/decisions/001-built-to-be-forked.md
156
157
  - docs/decisions/002-measures-and-dimensions-over-ransack.md
@@ -242,23 +243,6 @@ metadata:
242
243
  changelog_uri: https://github.com/retail-tasker/janela/blob/main/CHANGELOG.md
243
244
  bug_tracker_uri: https://github.com/retail-tasker/janela/issues
244
245
  rubygems_mfa_required: 'true'
245
- post_install_message: |
246
- Janela 0.16.0: one migration, if you use stored frames.
247
-
248
- A time pane can now be a running total and carry more series on two
249
- axes (ADR 062), and a pane can ignore a filter its model cannot apply
250
- (ADR 063). That adds nullable cumulative, series and
251
- ignore_unknown_filters columns to janela_panes. Run
252
- bin/rails janela:install:migrations and then bin/rails db:migrate. If
253
- you never use stored frames there is nothing to do.
254
-
255
- Also: a line chart with value_labels now writes its latest value at
256
- its end.
257
-
258
- Steps: UPGRADING.md in this gem, or
259
- https://github.com/retail-tasker/janela/blob/main/UPGRADING.md
260
-
261
- Then run: bin/rails janela:doctor
262
246
  rdoc_options: []
263
247
  require_paths:
264
248
  - lib