@bezda/rhp-mcp 0.1.0 → 0.1.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.
- package/README.md +4 -3
- package/bin/rhp-mcp.js +5 -1
- package/package.json +3 -3
- package/skill/SKILL.md +112 -25
- package/skill/recipes/area.html +6 -0
- package/skill/recipes/bar.html +6 -0
- package/skill/recipes/box-plot.html +6 -0
- package/skill/recipes/bubble.html +6 -0
- package/skill/recipes/bullet.html +6 -0
- package/skill/recipes/candlestick.html +6 -0
- package/skill/recipes/column.html +18 -5
- package/skill/recipes/dial.html +349 -0
- package/skill/recipes/diverging-bars.html +6 -0
- package/skill/recipes/donut.html +6 -0
- package/skill/recipes/dumbbell.html +6 -0
- package/skill/recipes/gantt.html +14 -4
- package/skill/recipes/grouped-bars.html +6 -0
- package/skill/recipes/heatmap.html +6 -0
- package/skill/recipes/histogram.html +6 -0
- package/skill/recipes/line.html +7 -1
- package/skill/recipes/live.html +6 -0
- package/skill/recipes/log-line.html +493 -0
- package/skill/recipes/lollipop.html +6 -0
- package/skill/recipes/multi-line.html +10 -5
- package/skill/recipes/pyramid.html +6 -0
- package/skill/recipes/race.html +6 -0
- package/skill/recipes/radial-bars.html +6 -0
- package/skill/recipes/scatter.html +6 -0
- package/skill/recipes/silhouettes.html +352 -0
- package/skill/recipes/slope.html +6 -0
- package/skill/recipes/sparklines.html +7 -1
- package/skill/recipes/stacked-100.html +6 -0
- package/skill/recipes/stacked-bars.html +6 -0
- package/skill/recipes/strip.html +6 -0
- package/skill/recipes/unit-stack.html +276 -0
- package/skill/recipes/violin.html +6 -0
- package/skill/recipes/waffle.html +6 -0
- package/skill/recipes/waterfall.html +6 -0
- package/skill/references/api.md +150 -22
- package/skill/references/design.md +303 -326
- package/skill/references/environments.md +11 -4
- package/skill/references/forms.md +41 -4
- package/skill/references/interaction.md +3 -1
- package/skill/references/looks.md +267 -0
- package/skill/references/pitfalls.md +52 -7
- package/src/check/README.md +15 -2
- package/src/check/findings.js +1 -1
- package/src/check/index.js +103 -14
- package/src/check/inpage.js +80 -16
- package/src/check/report.js +4 -1
- package/src/guard/rhp.js +4 -0
- package/src/guard/rules.js +1 -1
- package/src/server.js +9 -8
package/skill/references/api.md
CHANGED
|
@@ -4,7 +4,7 @@ rhp 2 (`@bezda/rhp@2`, built on SolidJS 1.9).
|
|
|
4
4
|
Every statement here was checked against rhp's source and by running it in a browser, and every code block is a complete example that runs.
|
|
5
5
|
The `js` examples are the module script of [the page skeleton](#a-page-with-a-chart): they draw into `<div id="chart">`.
|
|
6
6
|
|
|
7
|
-
Contents: [1 The model](#1-the-model) · [2 Imports and the html template](#2-imports-and-the-html-template) · [3 Chart](#3-chart) · [4 Plot](#4-plot) · [5 slat()](#5-slat) · [6 Blocks](#6-blocks) · [7 Scales and axes](#7-scales-and-axes) · [8 Theme](#8-theme) · [9 Helpers](#9-helpers) · [10 Poster](#10-poster) · [11 CSS](#11-css) · [12 Motion](#12-motion) · [13 Accessibility and interaction](#13-accessibility-and-interaction) · [14 Limits](#14-limits) · [15 Gotchas](#15-gotchas)
|
|
7
|
+
Contents: [1 The model](#1-the-model) · [2 Imports and the html template](#2-imports-and-the-html-template) · [3 Chart](#3-chart) · [4 Plot](#4-plot) · [5 slat()](#5-slat) · [6 Blocks](#6-blocks) · [ManyDots](#manydots-experimental-point-collection) · [7 Scales and axes](#7-scales-and-axes) · [8 Theme](#8-theme) · [9 Helpers](#9-helpers) · [10 Poster](#10-poster) · [11 CSS](#11-css) · [12 Motion](#12-motion) · [13 Accessibility and interaction](#13-accessibility-and-interaction) · [14 Limits](#14-limits) · [15 Gotchas](#15-gotchas)
|
|
8
8
|
|
|
9
9
|
## 1. The model
|
|
10
10
|
|
|
@@ -16,6 +16,8 @@ Contents: [1 The model](#1-the-model) · [2 Imports and the html template](#2-im
|
|
|
16
16
|
It reads the row as `d.fruit` and `d.sold`, plus `d.index` (the row's number) and `d.position` (its place on screen).
|
|
17
17
|
rhp places that element in its band and moves it when the order changes.
|
|
18
18
|
- **Blocks** inside the slat (Bar, Dot, Tick, Label, Cell, Place, Area, Line) sit at their numbers on the Chart's scale.
|
|
19
|
+
- **ManyDots** is an experimental bulk point collection, placed directly inside a Chart with `cross`.
|
|
20
|
+
It draws one plain HTML element per valid row without a Plot, slat, or Solid computation per point.
|
|
19
21
|
- **Orientation** is the direction bars run.
|
|
20
22
|
`"horizontal"` (the default): bars run left to right and slats stack top to bottom.
|
|
21
23
|
`"vertical"`: bars run bottom to top and slats stand side by side.
|
|
@@ -40,6 +42,7 @@ Both `@bezda/rhp` and `@bezda/rhp/standalone` export rhp's whole API:
|
|
|
40
42
|
|
|
41
43
|
- components: `Chart`, `Plot`, `Scale`, `Axis`, `Theme`, `Poster`
|
|
42
44
|
- blocks: `Bar`, `Dot`, `Tick`, `Label`, `Cell`, `Place`, `Area`, `Line`
|
|
45
|
+
- experimental point collection: [`ManyDots`](#manydots-experimental-point-collection), in builds of this repository that export it
|
|
43
46
|
- functions: `slat`, `restyle`, `linkedCss`, `shape`, `at`, `useOrientation`, `series`, `cycle`, `sortBy`, `extent`, `every`, `nice`, `stackUp`, `shares`, `running`, `summary`, `bins`, `density`, `animated`, `curve`, `drawing`
|
|
44
47
|
- the object `THEME` (the default theme)
|
|
45
48
|
|
|
@@ -72,7 +75,9 @@ The rules, in full:
|
|
|
72
75
|
The helpers `sortBy()`, `series()`, `cycle()` and `every()` already return such functions.
|
|
73
76
|
3. On a plain element (`<div>`, `<button>`), handlers attach normally, with or without a parameter.
|
|
74
77
|
4. Booleans are written out: `overlap=${true}`, `keyboard=${true}`, `static=${true}`, `animate=${true}`, `mirror=${true}`, `fill=${true}`, `smooth=${true}`.
|
|
75
|
-
5. A slat returns one element
|
|
78
|
+
5. A slat returns one element; whitespace around it is fine, and two elements side by side throw.
|
|
79
|
+
Use a wrapper for an ordinary Plot or several blocks.
|
|
80
|
+
In an `overlap` Plot or a Scale, a single block can be the root itself, with no extra wrapper.
|
|
76
81
|
6. Never destructure `d`: `({ sold }) => …` reads each value once.
|
|
77
82
|
Read `d.sold` inside a function.
|
|
78
83
|
7. Use `class`, never `className`: on a block, `className` replaces rhp's class and the block is no longer drawn; on a plain element it does nothing.
|
|
@@ -159,12 +164,14 @@ export default function FruitChart() {
|
|
|
159
164
|
| `height` | px | 240 when vertical or with `cross` | the **plot's** height (room and axis come on top). Horizontal: slats without `thickness` share it; slats with one keep theirs and `height` does nothing. |
|
|
160
165
|
| `aspect` | number above 0 | none | the **whole** chart's width over its height (`16 / 9`), room and axis included, at any width. `height` is then ignored (with a warning). Horizontal slats without `thickness` share the height; slats with one keep it (with a warning). |
|
|
161
166
|
| `ticks` | `number[]`, a count, `([min, max]) => number[]`, or `false` | about 5 round values | the axis: grid lines and numbers. A list keeps only values inside the scale. `false` draws no axis and leaves no room for it. |
|
|
167
|
+
| `grid` | boolean | `true` | `false` hides the value-axis grid lines while keeping the numbers and axis room. |
|
|
162
168
|
| `format` | `(value) => text or element` | the number as is | the text of each axis number |
|
|
163
169
|
| `animate` | `true` or `{ duration, ease, slide }` | off | the JS version of motion (section 12); the Plots inside take it |
|
|
164
170
|
| `theme` | theme object (section 8) | `THEME` | colors and font, over those of a `<Theme>` around it |
|
|
165
171
|
| `static` | boolean | `false` | for data that never changes: slats are drawn once and keep no signals; a data change draws them all again, without motion |
|
|
166
172
|
| `cross` | `[min, max]` | none | a second axis across the band (scatter plots, line charts; section 7) |
|
|
167
173
|
| `crossTicks`, `crossFormat` | like `ticks`, `format` | about 5, the number | the second axis |
|
|
174
|
+
| `crossGrid` | boolean | `true` | `false` hides only the second axis' grid lines, keeping its numbers. |
|
|
168
175
|
| `label` | string | none | names the chart for screen readers: the chart gets `role="figure"` and `aria-label` |
|
|
169
176
|
| `aria-labelledby`, `aria-describedby`, any `aria-*` | string | none | set on the chart's element; `aria-labelledby` also makes it a figure |
|
|
170
177
|
| `id`, `class`, `role` | string | none | set on the chart's element |
|
|
@@ -174,7 +181,7 @@ export default function FruitChart() {
|
|
|
174
181
|
A Chart passes nothing else to its element: `data-*`, `title`, `tabindex` and event handlers are dropped.
|
|
175
182
|
Put them on an element around the chart, or on the [Poster](#10-poster).
|
|
176
183
|
|
|
177
|
-
Children: one or more Plots (later ones drawn on top), a `Scale`, and Solid control flow (`Show`) around them.
|
|
184
|
+
Children: one or more Plots (later ones drawn on top), a `Scale`, a `ManyDots` collection with a cross scale, and Solid control flow (`Show`) around them.
|
|
178
185
|
A Plot outside a Chart draws nothing usable: no CSS, no scale, no message.
|
|
179
186
|
|
|
180
187
|
**Size and room.** The chart's element (`.rhp-chart`) is a block as wide as its container.
|
|
@@ -265,7 +272,9 @@ Without `overlap` its slats divide the band (grouped bars); with `overlap` they
|
|
|
265
272
|
`orientation="across"` turns it, so its slats run along the value axis (one Cell per hour).
|
|
266
273
|
`thick` uses a part of the band.
|
|
267
274
|
A Plot inside a slat asks for no room, is not a list for screen readers, and does not take the Chart's `animate`.
|
|
268
|
-
A slat of an `overlap` Plot may return a block itself (the stacked bars in section 9 do)
|
|
275
|
+
A slat of an `overlap` Plot or a Scale may return a block itself (the stacked bars in section 9 do), including that block's own children.
|
|
276
|
+
Use that direct root for a single mark to avoid an extra wrapper; several blocks still need a common root.
|
|
277
|
+
In a Plot without `overlap`, keep the wrapper: a block as the slat's root loses part of its placing and may warn.
|
|
269
278
|
|
|
270
279
|
```js
|
|
271
280
|
import { Chart, Plot, Bar, Label, Tick, slat, sortBy, html, render, createSignal } from "@bezda/rhp/standalone";
|
|
@@ -286,7 +295,7 @@ const City = slat({ thickness: 34, room: { start: 64, end: 48 } }, (d) => html`
|
|
|
286
295
|
<${Label} at=${() => d.temp}>${() => d.temp} ${() => d.unit}<//>
|
|
287
296
|
</div>`);
|
|
288
297
|
// One line across the whole plot: an overlay Plot with one slat, asking for no room
|
|
289
|
-
const Mean = slat({ room: {} }, (d) => html
|
|
298
|
+
const Mean = slat({ room: {} }, (d) => html`<${Tick} at=${() => d.mean} thick=${1} color="muted" />`);
|
|
290
299
|
|
|
291
300
|
// Chart component: rows with a key, a shared value, a per-row function, a sort that changes
|
|
292
301
|
const CityChart = () => {
|
|
@@ -368,9 +377,13 @@ Read it inside functions (`${() => d.sold}`) and never destructure it.
|
|
|
368
377
|
|
|
369
378
|
**What it returns.**
|
|
370
379
|
One element, the slat's root, usually a `<div>` holding blocks and any other elements.
|
|
380
|
+
For a single block in an `overlap` Plot or a Scale, return that block directly instead.
|
|
371
381
|
rhp sets on the root: `data-rhp-slat` (the type's CSS scope), `data-rhp-o` (`h` or `v`), `role="listitem"` in a top-level Plot without `overlap` (unless the root has a role), an `id` when the slats are sorted (unless it has one), `hidden` when its position is `null`, `tabindex` with `keyboard`, and the style `--rhp-position`.
|
|
372
|
-
rhp places and sizes
|
|
373
|
-
|
|
382
|
+
rhp places and sizes an ordinary Plot's root, absolutely, in its band: the slat's CSS can style it (background, border, radius, hover) but cannot move or resize it.
|
|
383
|
+
An `overlap` Plot or a Scale leaves a direct block's own geometry in control.
|
|
384
|
+
Elements of your own inside a wrapper are positioned by your CSS against the full slat's band.
|
|
385
|
+
Children inside a direct block use that block's box instead; keep a wrapper for independently positioned sibling marks or labels.
|
|
386
|
+
Keep a wrapper when a single mark needs a full-band hover or pointer target.
|
|
374
387
|
|
|
375
388
|
```js
|
|
376
389
|
import { Chart, Plot, Bar, Label, slat, series, html, render, createSignal } from "@bezda/rhp/standalone";
|
|
@@ -414,7 +427,7 @@ render(MoonChart, document.getElementById("chart"));
|
|
|
414
427
|
|
|
415
428
|
## 6. Blocks
|
|
416
429
|
|
|
417
|
-
Every block also takes `class`, `style` (an object or a string), `ref`, children, event handlers and any HTML attribute (`title`, `data-*`, `aria-*`).
|
|
430
|
+
Every block also takes `class`, `style` (an object or a string; published rhp 2.0.2 needs objects for changing styles, gotcha 4), `ref`, children, event handlers and any HTML attribute (`title`, `data-*`, `aria-*`).
|
|
418
431
|
`color` takes a theme key or any CSS color (section 8).
|
|
419
432
|
Bar, Dot, Tick, Label and Cell take `shape` (an outline from `shape()`, section 9).
|
|
420
433
|
Values are on the Chart's scale.
|
|
@@ -444,7 +457,7 @@ Where things sit:
|
|
|
444
457
|
An Area is filled with its color at 35% and stroked 1.5px; a Line is stroked 2px, and with `fill` filled at 22%.
|
|
445
458
|
- A Place's children are placed by your CSS from its point: `position: absolute; translate: -50% -50%` centers one.
|
|
446
459
|
- `color` sets `--rhp-color` on that block only, so a Label next to a Bar does not see the Bar's color.
|
|
447
|
-
Set `--rhp-color` on the slat's root to share one.
|
|
460
|
+
Set `--rhp-color` on the slat's root to share one, in a style object (`style=${() => ({ "--rhp-color": … })}`).
|
|
448
461
|
|
|
449
462
|
A Bar from one value to another, Dots at its ends, and a Tick:
|
|
450
463
|
|
|
@@ -645,6 +658,109 @@ const ChangeChart = () => html`
|
|
|
645
658
|
render(ChangeChart, document.getElementById("chart"));
|
|
646
659
|
```
|
|
647
660
|
|
|
661
|
+
### ManyDots (experimental point collection)
|
|
662
|
+
|
|
663
|
+
`ManyDots` draws a bulk collection of points directly inside a `Chart` with `scale` and `cross`.
|
|
664
|
+
It is part of the upcoming npm 2.0.3 release.
|
|
665
|
+
It is a collection rather than a block in a slat, so do not wrap it in a `Plot` or supply a slat function.
|
|
666
|
+
Use a repository build that exports `ManyDots`; the version-2 CDN URL in the page skeleton does not guarantee this experimental API is available.
|
|
667
|
+
Both package entry points export it in that build, and Solid users can import `ManyDotsProps<T>` and `ManyDotsValue<T, V>` for its types.
|
|
668
|
+
|
|
669
|
+
Choose it explicitly for bulk HTML points, or keep `Dot` for individual blocks, rich point content, and Plot behavior at any point count.
|
|
670
|
+
Neither component switches into the other automatically, including at 500 points.
|
|
671
|
+
|
|
672
|
+
| Prop | Type | Default | What it does |
|
|
673
|
+
|---|---|---|---|
|
|
674
|
+
| `rows` | readonly array of rows | required | one point per row with finite coordinates |
|
|
675
|
+
| `at`, `cross` | number or `(row, index) => number` | required | coordinates on the Chart's value and cross scales |
|
|
676
|
+
| `key` | `(row, index) => identity` | source row index | stable identity for keyed updates; rendered keys must be unique |
|
|
677
|
+
| `size` | number, CSS length, or accessor | `"4px"` | diameter; a number means pixels, unlike Dot's band fraction |
|
|
678
|
+
| `color` | CSS color, theme key, or accessor | `"series-1"` | shared or individual point colors |
|
|
679
|
+
| `shape` | `shape()` outline or accessor | circular points | shared or individual point outlines |
|
|
680
|
+
| `pointClass` | string or accessor | none | space-separated application classes on each point |
|
|
681
|
+
| `pointStyle` | CSS properties object or accessor | none | individual appearance overrides |
|
|
682
|
+
| `class`, `classList`, `style`, `ref`, HTML attributes and events | normal div props | none | apply to the collection host; `style` accepts an object or string |
|
|
683
|
+
|
|
684
|
+
The appearance accessors above receive `(row, index)`.
|
|
685
|
+
Both domains must have finite, distinct endpoints, and nonfinite point coordinates are skipped.
|
|
686
|
+
Finite coordinates outside a domain keep their outside positions, so choose scales that cover the data.
|
|
687
|
+
Every rendered point retains its original row index in `data-rhp-index`, even when preceding rows are skipped.
|
|
688
|
+
|
|
689
|
+
**Appearance and DOM.**
|
|
690
|
+
The light-DOM host is `.rhp-manydots`, its point container is `.rhp-manydots-points`, and each point is a `.rhp-manydot` div.
|
|
691
|
+
There is no shadow root, so document queries, Testing Library queries, native events, and page-level event delegation see the points.
|
|
692
|
+
Use `pointClass` with ordinary application CSS for background color, radius, opacity, outlines, filters, transforms, and hover styles.
|
|
693
|
+
Shared defaults use one scoped stylesheet per collection, with a fallback for browsers without `@scope` support.
|
|
694
|
+
Per-point color and shape accessors write inline styles, which take precedence over ordinary class rules.
|
|
695
|
+
Size, color, and shape accessors also override the same properties supplied through `pointStyle`.
|
|
696
|
+
The collection owns coordinates and centering and guards position, dimensions, margins, padding, borders, and min/max dimensions.
|
|
697
|
+
Explicit width and height in `pointStyle` can override a shared size; appearance remains customizable without the slat's general text and font reset.
|
|
698
|
+
|
|
699
|
+
**Interaction and accessibility.**
|
|
700
|
+
CSS hover and native click, touch, and pointer events work on the plain HTML points.
|
|
701
|
+
Attach handlers to the host and recover the row with `data-rhp-index`; there is no per-point handler prop or built-in drag behavior.
|
|
702
|
+
Implement dragging with pointer events and pointer capture when needed, and use `getBoundingClientRect()` for overlays against the visible point box.
|
|
703
|
+
`ManyDots` does not implement Plot's automatic keyboard navigation, selection, or readout behavior and accepts no point children, `innerHTML`, or `textContent`.
|
|
704
|
+
Provide a Chart `label` and a textual summary, data table, or keyboard-accessible controls when readers need individual values.
|
|
705
|
+
The following complete module example includes a table whose buttons offer the same selection as clicking a point.
|
|
706
|
+
Validate the experimental collection's point count, geometry, appearance, native interactions, and accessible controls in the browser rather than treating a standard-chart checker report as complete bulk-point coverage.
|
|
707
|
+
|
|
708
|
+
```js
|
|
709
|
+
import { Chart, ManyDots, html, render, createSignal } from "@bezda/rhp/standalone";
|
|
710
|
+
|
|
711
|
+
const samples = [
|
|
712
|
+
{ id: "a", name: "Sample A", x: 20, y: 35, diameter: 8, color: "#a73157" },
|
|
713
|
+
{ id: "b", name: "Sample B", x: 60, y: 80, diameter: 10, color: "#18749a" },
|
|
714
|
+
{ id: "c", name: "Sample C", x: 85, y: 50, diameter: 6, color: "#6b4da1" },
|
|
715
|
+
];
|
|
716
|
+
|
|
717
|
+
function Measurements() {
|
|
718
|
+
const [selected, setSelected] = createSignal(null);
|
|
719
|
+
const chosen = () => samples.find(row => row.id === selected());
|
|
720
|
+
const pick = event => {
|
|
721
|
+
const point = event.target.closest?.(".rhp-manydot");
|
|
722
|
+
if (point && event.currentTarget.contains(point)) {
|
|
723
|
+
setSelected(samples[Number(point.dataset.rhpIndex)].id);
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
return html`
|
|
727
|
+
<section>
|
|
728
|
+
<style>
|
|
729
|
+
.measurement-point { cursor: pointer; }
|
|
730
|
+
.measurement-point:hover { outline: 2px solid currentColor; outline-offset: 2px; }
|
|
731
|
+
</style>
|
|
732
|
+
<p>Click or tap a point, or choose a sample in the table.</p>
|
|
733
|
+
<${Chart} scale=${[0, 100]} cross=${[0, 100]} height=${280} label="Illustrative sample measurements">
|
|
734
|
+
<${ManyDots} rows=${samples} at=${row => row.x} cross=${row => row.y} key=${row => row.id}
|
|
735
|
+
size=${row => row.diameter} color=${row => row.color} pointClass="measurement-point"
|
|
736
|
+
pointStyle=${row => ({ opacity: selected() == null || selected() === row.id ? 1 : 0.35 })}
|
|
737
|
+
onClick=${pick} />
|
|
738
|
+
<//>
|
|
739
|
+
<p aria-live="polite">${() => chosen() ? `${chosen().name}: x ${chosen().x}, y ${chosen().y}` : "No sample selected"}</p>
|
|
740
|
+
<table>
|
|
741
|
+
<caption>Illustrative sample values</caption>
|
|
742
|
+
<thead><tr><th scope="col">Sample</th><th scope="col">X</th><th scope="col">Y</th></tr></thead>
|
|
743
|
+
<tbody>${samples.map(row => html`
|
|
744
|
+
<tr><th scope="row"><button type="button" onClick=${event => setSelected(row.id)}>${row.name}</button></th>
|
|
745
|
+
<td>${row.x}</td><td>${row.y}</td></tr>`)}
|
|
746
|
+
</tbody>
|
|
747
|
+
</table>
|
|
748
|
+
</section>`;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
render(Measurements, document.getElementById("chart"));
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
**Updates and server rendering.**
|
|
755
|
+
Stable keys preserve leaf elements through replacement arrays, reordering, and removals.
|
|
756
|
+
One collection computation visits every row when a dependency changes, while unchanged points receive no managed style writes.
|
|
757
|
+
Dragging one point through reactive data therefore still requires a bulk row pass; update and drag performance have not been measured.
|
|
758
|
+
Data updates move points immediately, and JavaScript-driven Chart scale animation updates their resolved coordinates.
|
|
759
|
+
Server rendering emits the complete HTML collection, and hydration reuses its host, container, and points.
|
|
760
|
+
Initial leaves are adopted by row order because server keys are not serialized; keep server and client row order aligned when point DOM identity matters.
|
|
761
|
+
Managed classes, coordinates, and appearance declarations can be rewritten by the collection, while native listeners and metadata outside its managed fields survive ordinary updates.
|
|
762
|
+
See the [prototype guide](../../../examples/manydots/README.md) for centering and custom-size animation details and the [capabilities explanation](../../../examples/manydots/TRADEOFFS.md) for the measured initial-render tradeoffs.
|
|
763
|
+
|
|
648
764
|
## 7. Scales and axes
|
|
649
765
|
|
|
650
766
|
**The axis.** The Chart draws grid lines and numbers from `ticks` and `format`:
|
|
@@ -745,9 +861,9 @@ const HighChart = () => html`
|
|
|
745
861
|
<${Chart} scale=${[0.5, 12.5]} ticks=${month} format=${(m) => "JFMAMJJASOND"[m - 1]}
|
|
746
862
|
cross=${[10, 30]} crossTicks=${[10, 20, 30]} crossFormat=${(t) => t + "°"} height=${200}>
|
|
747
863
|
<${Plot} overlap=${true} points=${[month.map((m, i) => [m, high[i]])]}>${(d) => html`
|
|
748
|
-
|
|
864
|
+
<${Line} points=${() => d.points} fill=${true} base=${10} />`}<//>
|
|
749
865
|
<${Plot} overlap=${true} month=${month} high=${high}>${(d) => html`
|
|
750
|
-
|
|
866
|
+
<${Dot} at=${() => d.month} cross=${() => d.high} size="8px" />`}<//>
|
|
751
867
|
<//>`;
|
|
752
868
|
|
|
753
869
|
render(HighChart, document.getElementById("chart"));
|
|
@@ -850,6 +966,10 @@ When their input changes, call them inside `createMemo` so they run once per cha
|
|
|
850
966
|
| `restyle(slatType, css)` | gives a slat type made with `css` new CSS; its slats restyle in place | for style editors |
|
|
851
967
|
| `linkedCss()` | tells rhp the page links `@bezda/rhp/rhp.css` itself | call before the first chart; without the link rhp warns and adds its CSS anyway |
|
|
852
968
|
|
|
969
|
+
A shape must start with `M`.
|
|
970
|
+
Further `M` commands start separate subpaths, allowing disconnected pieces or holes with the opposite winding direction.
|
|
971
|
+
These work with native CSS `shape()` and the polygon fallback; curves in the fallback retain the existing approximation.
|
|
972
|
+
|
|
853
973
|
Stacked bars: `stackUp` per slat, and an overlap Plot whose slats are Bars:
|
|
854
974
|
|
|
855
975
|
```js
|
|
@@ -1038,7 +1158,8 @@ Where each kind of style goes:
|
|
|
1038
1158
|
|
|
1039
1159
|
| What | Where |
|
|
1040
1160
|
|---|---|
|
|
1041
|
-
|
|
|
1161
|
+
| slat blocks: bars, labels, hover, fonts per label | the slat type's `css` |
|
|
1162
|
+
| ManyDots point appearance | `pointClass` with ordinary application CSS, or `pointStyle`, `color`, `size`, and `shape` |
|
|
1042
1163
|
| colors and the font of the whole chart | the Chart's `theme` (or `Theme`) |
|
|
1043
1164
|
| the chart's box: width, margin, background, border, radius | page CSS on the chart's element, or the Chart's `class` and `style` |
|
|
1044
1165
|
| the poster around it, and elements of your own outside the chart | page CSS |
|
|
@@ -1051,11 +1172,11 @@ A selector may start with `.rhp-chart` to depend on the chart (`.rhp-chart[data-
|
|
|
1051
1172
|
`@keyframes` names are made private to the type: use them in the same CSS.
|
|
1052
1173
|
`::before` and `::after` work on the slat's root and on any element.
|
|
1053
1174
|
|
|
1054
|
-
**Layers.** rhp makes
|
|
1175
|
+
**Layers for slat blocks.** rhp makes its regular block and slat declarations `!important`, inside cascade layers declared first: `rhp.place`, then `rhp.slat`, then `rhp.core`.
|
|
1055
1176
|
For `!important` the first layer wins, and any layered `!important` beats every page rule (`!important` or not).
|
|
1056
1177
|
So a slat's CSS beats rhp's core (colors, corners, fonts, even a block's position), placement beats a slat's CSS (a slat's root, its motion), and the page reaches none of them.
|
|
1057
1178
|
|
|
1058
|
-
**What page CSS can and cannot change** (measured):
|
|
1179
|
+
**What page CSS can and cannot change on regular slat blocks** (measured):
|
|
1059
1180
|
|
|
1060
1181
|
| Page CSS on rhp's elements | Result |
|
|
1061
1182
|
|---|---|
|
|
@@ -1076,6 +1197,7 @@ Even where page CSS reaches rhp's custom properties, set them in the slat's `css
|
|
|
1076
1197
|
| `.rhp-body` | the grid inside it |
|
|
1077
1198
|
| `.rhp-axis`, `.rhp-gridline`, `.rhp-gridline > span` | the axis, a grid line, its number (`.rhp-axis[data-rhp-cross]`: the second axis) |
|
|
1078
1199
|
| `.rhp-plot` | a Plot; `data-rhp-overlap`, `data-rhp-reorder`; `.rhp-plot.rhp-scale` is a Scale |
|
|
1200
|
+
| `.rhp-manydots`, `.rhp-manydots-points`, `.rhp-manydot[data-rhp-index]` | ManyDots host, point container, and point with its original row index |
|
|
1079
1201
|
| `[data-rhp-slat]` | a slat's root (the value is the type's scope) |
|
|
1080
1202
|
| `.rhp-bar` (`[data-rhp-back]` when it runs backward), `.rhp-dot`, `.rhp-tick`, `.rhp-cell`, `.rhp-place` | blocks |
|
|
1081
1203
|
| `.rhp-label[data-rhp-at]`, `.rhp-label[data-rhp-edge="start"]`, `.rhp-label[data-rhp-edge="end"]`, `[data-rhp-side="before"]` | Labels at a value, in the start room, in the end room |
|
|
@@ -1476,9 +1598,12 @@ Every one of these was found by running rhp 2.0.1.
|
|
|
1476
1598
|
3. **`${d.sold}` never updates.**
|
|
1477
1599
|
A value read without a function is read once.
|
|
1478
1600
|
Wrap it, `${() => d.sold}`, and never destructure `d`.
|
|
1479
|
-
4. **
|
|
1601
|
+
4. **Use style objects on Chart, Plot and a slat's root.**
|
|
1480
1602
|
`style="pointer-events: none"` on a Plot or Chart is dropped without a message; write `style=${{ "pointer-events": "none" }}`.
|
|
1481
|
-
|
|
1603
|
+
On a slat's root, a string that changes or a style that becomes `undefined` replaces the whole style attribute and erases the stack position, so keep it an object.
|
|
1604
|
+
Published rhp 2.0.2 has the same problem on Blocks: a Bar can disappear and SVG geometry can be lost, so use `style=${() => ({ "--n": d.n })}` there too.
|
|
1605
|
+
Current source fixes the Block replacement bug for the upcoming 2.0.3 release; Blocks then retain their geometry when strings change or style is removed.
|
|
1606
|
+
Plain children that hold no rhp geometry can use changing strings.
|
|
1482
1607
|
5. **`className` breaks a block.**
|
|
1483
1608
|
It replaces rhp's class, so the block is no longer drawn.
|
|
1484
1609
|
Use `class`.
|
|
@@ -1517,18 +1642,19 @@ Every one of these was found by running rhp 2.0.1.
|
|
|
1517
1642
|
With a theme of 4 series colors use `series(4)`, or rows 5 and 6 take `series-1`.
|
|
1518
1643
|
19. **A Label does not see its Bar's color.**
|
|
1519
1644
|
`color` sets `--rhp-color` on that block only, so `.value { color: var(--rhp-color) }` on a sibling Label stays ink.
|
|
1520
|
-
Set `--rhp-color` on the slat's root (and leave `color` off the Bar), or color the Label itself.
|
|
1645
|
+
Set `--rhp-color` on the slat's root in a style object (and leave `color` off the Bar), or color the Label itself.
|
|
1521
1646
|
20. **The page's font, colors and `--rhp-*` variables stop at the chart.**
|
|
1522
1647
|
Give the font with `theme.font` and the colors with the theme; theme values may read the page's own variables (`ink: "var(--ink)"`), which do reach the chart.
|
|
1523
1648
|
`color="var(--brand)"` on a block works but warns.
|
|
1524
1649
|
21. **Page CSS cannot restyle bars, labels, slats or the axis**, even with `!important`.
|
|
1525
1650
|
It can set `opacity`, `cursor`, `filter`, `transform`, `z-index` and `pointer-events`; it also reaches rhp's `--rhp-*` variables, but those belong in the slat's `css` or the theme, never in page CSS.
|
|
1526
1651
|
Style the inside of a chart in the slat's `css`.
|
|
1527
|
-
22. **A `transition` on a block replaces rhp's own**, and the block jumps to new values
|
|
1652
|
+
22. **A `transition` on a block replaces rhp's own**, and the block jumps to new values.
|
|
1653
|
+
A transition on an ordinary Plot's slat root is ignored (rhp keeps the root's slide).
|
|
1528
1654
|
Transition an element inside a block.
|
|
1529
1655
|
Focus styles for slats go in the slat's `css`: rhp's core CSS resets `outline` on slat roots, so a page `:focus-visible` rule never reaches them.
|
|
1530
|
-
23. **Slat CSS cannot move or resize
|
|
1531
|
-
It can move blocks (a pie's wedge takes over its Bar's box).
|
|
1656
|
+
23. **Slat CSS cannot move or resize an ordinary Plot's slat root** (`top`, `left`, `width`, `height` are rhp's).
|
|
1657
|
+
It can move blocks, including a direct block root in an `overlap` Plot or a Scale (a pie's wedge takes over its Bar's box).
|
|
1532
1658
|
24. **A chart collapses in a shrink-to-fit box.**
|
|
1533
1659
|
As a plain flex item, in an `inline-block`, a float or a `width: fit-content` box, it is only as wide as its room (148px by default) with a plot 0px wide.
|
|
1534
1660
|
Give it `flex: 1; min-width: 0`, or a width.
|
|
@@ -1541,14 +1667,16 @@ Every one of these was found by running rhp 2.0.1.
|
|
|
1541
1667
|
For the slat the reader is on, a per-row data group works with every rhp 2: `on=${(d) => on() === d.index}`; `createSelector` saves work when a chart has hundreds of slats.
|
|
1542
1668
|
29. **A Plot outside a Chart draws nothing usable**, and a Scale outside one throws.
|
|
1543
1669
|
30. **A slat must return one element.**
|
|
1544
|
-
Two top-level elements or text throw "rhp: a slat must return one element"
|
|
1670
|
+
Two top-level elements or text throw "rhp: a slat must return one element".
|
|
1671
|
+
Return a single block directly only in an `overlap` Plot or a Scale.
|
|
1672
|
+
An ordinary Plot needs a wrapper to preserve the block's placing.
|
|
1545
1673
|
31. **The Poster brings no CSS**: a bare `<figure>` keeps 40px side margins and its caption spans run inline.
|
|
1546
1674
|
Style `.poster`, `figcaption`, `.kicker`, `.headline`, `.dek` and `.note`.
|
|
1547
1675
|
32. **An overlay Plot with a plain slat function asks for the default room** (104px and 44px).
|
|
1548
1676
|
Give its slat `room: {}` when the chart's room is smaller, and `style=${{ "pointer-events": "none" }}`.
|
|
1549
1677
|
33. **`static` charts ignore other signals.**
|
|
1550
1678
|
A per-row function that reads a signal (a hovered row) runs once on a static chart, so keep interactive charts off `static`.
|
|
1551
|
-
34. **Warnings rhp prints** (each once per page), all worth fixing: a block as
|
|
1679
|
+
34. **Warnings rhp prints** (each once per page), all worth fixing: a block as an ordinary Plot's slat root; an edge Label inside another element with room "auto"; `aspect` with `height`, with slats that have a `thickness`, or not above 0; a page variable as a color; `--rhp-radius` with several lengths; an unknown ease; `linkedCss()` without the stylesheet.
|
|
1552
1680
|
35. **A space that stands alone between two tags is dropped** in the html template.
|
|
1553
1681
|
`<b>${() => d.name}</b> <em>12</em>` renders "Name12".
|
|
1554
1682
|
Write the space as `${" "}`, or keep it next to other text (`<b>Name</b>: <em>12</em>`).
|