@bezda/rhp-mcp 0.0.0-stage → 0.1.0

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.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +221 -2
  3. package/bin/rhp-mcp.js +125 -0
  4. package/package.json +62 -4
  5. package/skill/SKILL.md +363 -0
  6. package/skill/recipes/area.html +150 -0
  7. package/skill/recipes/bar.html +139 -0
  8. package/skill/recipes/box-plot.html +158 -0
  9. package/skill/recipes/bubble.html +182 -0
  10. package/skill/recipes/bullet.html +132 -0
  11. package/skill/recipes/candlestick.html +173 -0
  12. package/skill/recipes/column.html +125 -0
  13. package/skill/recipes/diverging-bars.html +144 -0
  14. package/skill/recipes/donut.html +225 -0
  15. package/skill/recipes/dumbbell.html +131 -0
  16. package/skill/recipes/gantt.html +186 -0
  17. package/skill/recipes/grouped-bars.html +136 -0
  18. package/skill/recipes/heatmap.html +177 -0
  19. package/skill/recipes/histogram.html +193 -0
  20. package/skill/recipes/line.html +164 -0
  21. package/skill/recipes/live.html +249 -0
  22. package/skill/recipes/lollipop.html +146 -0
  23. package/skill/recipes/multi-line.html +223 -0
  24. package/skill/recipes/pyramid.html +156 -0
  25. package/skill/recipes/race.html +272 -0
  26. package/skill/recipes/radial-bars.html +151 -0
  27. package/skill/recipes/scatter.html +193 -0
  28. package/skill/recipes/slope.html +193 -0
  29. package/skill/recipes/sparklines.html +169 -0
  30. package/skill/recipes/stacked-100.html +152 -0
  31. package/skill/recipes/stacked-bars.html +144 -0
  32. package/skill/recipes/strip.html +215 -0
  33. package/skill/recipes/violin.html +163 -0
  34. package/skill/recipes/waffle.html +159 -0
  35. package/skill/recipes/waterfall.html +121 -0
  36. package/skill/references/api.md +1556 -0
  37. package/skill/references/design.md +763 -0
  38. package/skill/references/environments.md +1570 -0
  39. package/skill/references/forms.md +160 -0
  40. package/skill/references/interaction.md +792 -0
  41. package/skill/references/pitfalls.md +157 -0
  42. package/src/check/README.md +163 -0
  43. package/src/check/browser.js +92 -0
  44. package/src/check/build.js +439 -0
  45. package/src/check/colors.js +324 -0
  46. package/src/check/findings.js +247 -0
  47. package/src/check/index.js +419 -0
  48. package/src/check/inpage.js +1268 -0
  49. package/src/check/interact.js +266 -0
  50. package/src/check/png.js +98 -0
  51. package/src/check/report.js +103 -0
  52. package/src/check/source.js +387 -0
  53. package/src/check/sourcemap.js +75 -0
  54. package/src/guard/note.js +30 -0
  55. package/src/guard/render.js +17 -0
  56. package/src/guard/rhp.js +608 -0
  57. package/src/guard/rules.js +125 -0
  58. package/src/server.js +265 -0
  59. package/src/skill.js +140 -0
@@ -0,0 +1,160 @@
1
+ # Choosing the form: data, story, slat and recipe
2
+
3
+ Use this file in step 3 of the workflow, after the brief.
4
+ It goes from what the reader should see, to the form, to the slat that draws it, to the recipe to start from.
5
+ When the user named a form ("a donut", "a gantt"), use it, and start at the recipe catalog below.
6
+
7
+ ## Contents
8
+
9
+ - Start from the reader's question
10
+ - The compositions rhp charts are made of
11
+ - The recipe catalog
12
+ - Orientation, size and phones
13
+ - Combining recipes
14
+ - What rhp does not draw, and the closest answer
15
+
16
+ ## Start from the reader's question
17
+
18
+ Write the one question the chart answers before you pick a form.
19
+ The headline will be its answer.
20
+
21
+ | The reader wants to... | Data | Form | Recipe |
22
+ |---|---|---|---|
23
+ | see which is biggest, in order | one value per item | ranked horizontal bars | `bar` |
24
+ | compare a few periods or categories | one value per period | columns | `column` |
25
+ | see a ranking with a reference value | one value per item and a reference | lollipop with a baseline | `lollipop` |
26
+ | compare two to four values per item | a few values per item, same unit | grouped bars | `grouped-bars` |
27
+ | see totals and what they are made of | parts per item that add up | stacked bars | `stacked-bars` |
28
+ | compare how each whole splits | parts per item, as shares | 100% stacked bars | `stacked-100` |
29
+ | see two sides of zero (agree and disagree, gain and loss) | values above and below zero | diverging bars | `diverging-bars` |
30
+ | follow how one amount becomes another | a start, changes, an end | waterfall | `waterfall` |
31
+ | see a few parts of one whole | two to six parts | donut | `donut` |
32
+ | count out of 100 people or units | counts or shares of a population | waffle | `waffle` |
33
+ | see progress toward goals | a share of a target per goal | radial bars, or bullets | `radial-bars`, `bullet` |
34
+ | see actual against target | actual, target, quality bands | bullet | `bullet` |
35
+ | follow one measure over time | a value per date | line | `line` |
36
+ | compare a few measures over time | a value per date per series | multi-line | `multi-line` |
37
+ | see a quantity's volume over time | a value per hour or day | area | `area` |
38
+ | see change between two dates per item | two values per item | slope | `slope` |
39
+ | see the gap between two values per item | two values per item | dumbbell | `dumbbell` |
40
+ | see many small trends at a glance | a short series per item | sparklines in slats | `sparklines` |
41
+ | watch a ranking reshuffle over time | one value per item per step | a bar chart race | `race` |
42
+ | follow values that keep arriving | a feed of readings per item | a live board | `live` |
43
+ | see how one measure is spread | many samples | histogram | `histogram` |
44
+ | compare spreads of a few groups, summarized | samples per group | box plot | `box-plot` |
45
+ | compare full distributions of a few groups | samples per group | violin | `violin` |
46
+ | see every value of a few groups | samples per group, tens per group | strip plot | `strip` |
47
+ | see how two measures relate | two values per item | scatter | `scatter` |
48
+ | see two measures and a size | three values per item | bubble | `bubble` |
49
+ | see a value over two categories | a grid of values (day by hour) | heatmap | `heatmap` |
50
+ | see two groups across ordered bands | two values per band | pyramid | `pyramid` |
51
+ | see a schedule and its progress | tasks with start, end, progress | gantt | `gantt` |
52
+ | follow prices with their range | open, high, low, close per day | candlestick | `candlestick` |
53
+
54
+ If two forms fit, prefer the one whose marks the reader compares by length from a shared baseline (bars, columns, lollipops): length is read most precisely.
55
+ Use a donut only for two to six parts with one or two of them the story; otherwise use stacked or ranked bars.
56
+
57
+ ## The compositions rhp charts are made of
58
+
59
+ Every rhp chart is one or more Plots of slats inside a Chart.
60
+ These are the patterns the recipes use; recognizing them lets you build a chart no recipe has.
61
+
62
+ 1. **One value per slat**: an edge Label for the name, a Bar from 0 (or `from`) to the value, a value Label at its end.
63
+ Recipes: `bar`, `column`, `lollipop` (a thin Bar and a Dot), `histogram`, `waterfall` (Bars from the running total before to the one after).
64
+ 2. **Several values on one slat, same scale**: several blocks in the same slat, each at its own value.
65
+ Recipes: `dumbbell` (two Dots and the Bar between them), `bullet` (band Bars, the actual Bar, a target Tick), `box-plot` (Bars for whiskers and box, Ticks for the median), `candlestick` (a thin Bar for the wick, a wide one for the body), `gantt` (planned, done and late Bars), `pyramid` (a Bar to each side of zero).
66
+ 3. **Parts of each slat**: a Plot inside the slat, one inner slat per part.
67
+ An `overlap` inner Plot puts the parts in one band, which makes a stack (`stacked-bars`, `stacked-100`, with `stackUp()` and `shares()`); an inner Plot without `overlap` lays the parts side by side across the band (`grouped-bars`).
68
+ 4. **A grid**: a Plot of Cells inside each slat, one Cell per column of the grid.
69
+ Recipes: `heatmap` (days by hours), `waffle` (ten slats of ten people).
70
+ 5. **Points on two axes**: `cross={[min, max]}` on the Chart adds a second axis across the slats; an `overlap` Plot's slats then share the whole plot, and a Dot or Label takes `at` (along the scale) and `cross` (across it), a Line takes `[x, y]` points.
71
+ Recipes: `scatter`, `bubble` (Dot size from a value), `line`, `multi-line`, `area` (a filled Line), `slope` (a Line of two points per item).
72
+ 6. **Every value of a group in its band**: an `overlap` Plot of Dots inside each group's slat.
73
+ Recipe: `strip`.
74
+ 7. **A distribution's outline**: an Area from `density()` points, `mirror` for violins.
75
+ Recipe: `violin`.
76
+ 8. **Layers over the slats**: an overlay Plot drawn over the others with `style=${{ "pointer-events": "none" }}` and `room: {}` on its slat type: a crosshair, a today line, a baseline, outliers.
77
+ Recipes: `candlestick` and `multi-line` (crosshairs), `gantt` (today), `lollipop` (the baseline), `box-plot` (outliers).
78
+ 9. **A scale drawn your own way**: a `Scale` in the Chart, a Plot of ticks with `d.at`, `d.next`, `d.first`, `d.last`.
79
+ Recipes: `gantt` (weeks), `line` and `multi-line` (decades), `scatter` and `bubble` (log scales), `area` (hours), `slope` (the two dates).
80
+ 10. **Shapes drawn from Bars**: the slat's CSS gives a Bar a new box, and the Bar draws a wedge or an arc from its values.
81
+ Recipes: `donut` (an SVG wedge inside each Bar, from `stackUp()` of `shares()`), `radial-bars` (rings drawn in CSS from the Bar's `--rhp-hi`).
82
+ Start from these recipes; the CSS is the hard part.
83
+
84
+ Inside any slat, add ordinary elements where the story needs them: an icon or a flag in the name Label, a note beside the highlighted slat, a small image in a Place.
85
+
86
+ ## The recipe catalog
87
+
88
+ Each recipe is a complete page in `recipes/<name>.html` with a designed poster, fixed data and one interaction.
89
+ The interaction listed is the recipe's; interaction.md has the others.
90
+
91
+ | Recipe | Shows | Composition | Interaction |
92
+ |---|---|---|---|
93
+ | `bar` | ranked categories, long names, the top one highlighted | 1 | readout on hover, focus and tap |
94
+ | `column` | values over twelve months, a season marked | 1, vertical | a scrub with a running total |
95
+ | `grouped-bars` | two values per category | 3 (side by side) | sort switch |
96
+ | `stacked-bars` | totals made of parts | 3 (stack) | a key that moves one part to the start and ranks by it |
97
+ | `stacked-100` | shares of each whole | 3 (stack of shares) | a key that lights one part in every bar |
98
+ | `diverging-bars` | survey answers either side of zero | 2 (Bars to both sides) | a switch between questions |
99
+ | `waterfall` | a profit bridge | 1 (Bars between running totals) | a switch between periods |
100
+ | `lollipop` | ranked prices against a reference | 1 + 8 | a switch between values and differences |
101
+ | `bullet` | actual against target with bands | 2 | sort by value or by share of target |
102
+ | `donut` | a few parts of one whole | 10 | the slice read out in place |
103
+ | `radial-bars` | progress on five goals | 10 | a day switch |
104
+ | `waffle` | 100 people by group | 4 | a picker that lights related units |
105
+ | `heatmap` | a value by weekday and hour | 4 | readout of a cell; turns on phones |
106
+ | `line` | one series over time | 5 + 9 | a callout that follows pointer, tap and arrow keys |
107
+ | `multi-line` | several series over time | 5 + 8 + 9 | a crosshair with every series' value |
108
+ | `area` | one quantity over a day | 5 + 9 | a switch between two days, the other kept as a thin line |
109
+ | `scatter` | two measures per item | 5 + 9 | readout of the nearest point |
110
+ | `bubble` | two measures and a size | 5 + 9 | readout of the bubble under the pointer |
111
+ | `slope` | change between two dates | 5 + 9 | the line nearest the pointer picked out |
112
+ | `dumbbell` | two values per item and the gap | 2 | re-sort by level or by change |
113
+ | `histogram` | one measure's spread | 1, vertical, `bins()` | readout of a bin and the share ahead of it |
114
+ | `box-plot` | spreads of groups, summarized | 2 + 8, `summary()` | readout of a group |
115
+ | `violin` | full distributions of groups | 7, `density()` | a switch that morphs the shapes |
116
+ | `strip` | every value of a few groups | 6 | readout of a dot |
117
+ | `pyramid` | two sides of a population by age | 2 | an age picked lights everyone that age or older |
118
+ | `gantt` | tasks over weeks, progress, today | 2 + 8 + 9 | readout of a task and its dependencies |
119
+ | `candlestick` | daily open, high, low, close | 2 + 8 | a crosshair and price readout |
120
+ | `sparklines` | a table of trends, one per slat, each scaled to itself | 1 + a Line in each slat + 8 | a year scrubber (pointer, tap, drag; a keyboard slider) |
121
+ | `race` | a ranking that reshuffles step by step, played over time | 1, JS motion, the scale following the leader | play and pause, a year slider, a readout |
122
+ | `live` | values arriving from a feed, each slat with its last minute scrolling | 1 + a Line from one animated `now` | pause and resume, a readout |
123
+
124
+ Adapting a recipe:
125
+
126
+ - **More or fewer slats**: a horizontal chart grows with its slats (`thickness`); keep 18px or more per slat for a name, 28px or more for a name and a value. Over about 30 rows, show the top ones and say so in the dek, or switch to a form that summarizes (a histogram, a box plot).
127
+ - **Negative values**: give the scale a min below 0 (`nice(min, max)`), and put value Labels for negative bars on the other side (`side="before"`).
128
+ - **Long names**: room in px for the longest, or `max-width` with an ellipsis, or wrap; on phones consider the other orientation.
129
+ - **More series**: grouped bars stay readable to four series; stacks to five or six parts; lines to five or six series, with direct labels at the line ends. Beyond that, highlight one or two and mute the rest, or split into small multiples (a Plot inside each slat).
130
+ - **Other units**: change `format` and the value Labels with `Intl.NumberFormat`, and the units in the headline, dek or axis.
131
+
132
+ ## Orientation, size and phones
133
+
134
+ - **Horizontal** (the default): rankings, long names, many items. Names sit in the start room, values at the bar ends.
135
+ - **Vertical**: time periods and short category names, up to about 24 columns on a desktop and 12 on a phone. Give it a `height` (240px by default is usually too short for a poster: 300 to 420px).
136
+ - **Two axes** (`cross`): time series, scatter and bubble charts. Give the Chart a `height` that suits the data's spread (260 to 420px).
137
+ - **Phones (390px wide)**: everything must still fit. Shorten or wrap names, drop a secondary label, use fewer ticks, or switch orientation with a `matchMedia` signal (the `heatmap` recipe turns its grid on phones; `column` keeps months short).
138
+
139
+ ## Combining recipes
140
+
141
+ When the story needs a slat no recipe has, take each part from the recipe that has it.
142
+
143
+ - **A table of trends with a target or a rank**: `sparklines` plus a Tick for the target from `bullet`, or `order=${sortBy("latest", "desc")}` from `bar` (a Line in a slat without `cross` is scaled to its own slat; give `peak` to compare slats).
144
+ - **Ranked bars with a target**: `bar` plus the target Tick from `bullet`.
145
+ - **A ranking that changes over time** (a bar chart race): start from `race`, which moves by the JS version because its data changes without pause.
146
+ - **A tile grid map** (states or countries as cells laid out like a map): a Plot of rows, each slat a Plot of Cells (the `heatmap` composition), with empty cells where there is no state.
147
+
148
+ ## What rhp does not draw, and the closest answer
149
+
150
+ Say plainly in your brief when a request is outside rhp, then build the closest rhp answer and say why in the handoff.
151
+
152
+ | Asked for | Closest rhp answer |
153
+ |---|---|
154
+ | a geographic map (choropleth) | a tile grid map (each region a Cell placed in a grid that echoes the map), or ranked bars of the regions |
155
+ | a network or a flow diagram (sankey) | stacked bars of what goes where, or a matrix heatmap of from-to pairs |
156
+ | a treemap or a sunburst | a waffle for shares, or stacked bars for parts of parts |
157
+ | a radar (spider) chart | a dot plot or grouped bars across the same axes |
158
+ | a 3D chart | the 2D form of the same data |
159
+ | a word cloud | ranked bars of the words |
160
+ | a free-form drawing or an image | Place blocks to position your own elements, or an image next to the chart |