poetry-charts 0.0.2

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 (124) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +6 -0
  3. data/CHANGELOG.md +3 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +94 -0
  6. data/THIRD_PARTY_NOTICES.md +39 -0
  7. data/app/assets/stylesheets/poetry-charts.css +117 -0
  8. data/app/components/poetry/charts/adapter_chart/component.html.erb +6 -0
  9. data/app/components/poetry/charts/adapter_chart/component.rb +99 -0
  10. data/app/components/poetry/charts/adapter_chart/preview.rb +37 -0
  11. data/app/components/poetry/charts/adapter_chart/style.rb +16 -0
  12. data/app/components/poetry/charts/area_chart/component.html.erb +75 -0
  13. data/app/components/poetry/charts/area_chart/component.rb +251 -0
  14. data/app/components/poetry/charts/area_chart/preview.rb +95 -0
  15. data/app/components/poetry/charts/area_chart/style.rb +29 -0
  16. data/app/components/poetry/charts/bar_chart/component.html.erb +95 -0
  17. data/app/components/poetry/charts/bar_chart/component.rb +318 -0
  18. data/app/components/poetry/charts/bar_chart/preview.rb +115 -0
  19. data/app/components/poetry/charts/bar_chart/style.rb +28 -0
  20. data/app/components/poetry/charts/bar_math.rb +95 -0
  21. data/app/components/poetry/charts/cartesian_family.rb +105 -0
  22. data/app/components/poetry/charts/chart_family.rb +58 -0
  23. data/app/components/poetry/charts/composed_chart/component.html.erb +95 -0
  24. data/app/components/poetry/charts/composed_chart/component.rb +309 -0
  25. data/app/components/poetry/charts/composed_chart/preview.rb +62 -0
  26. data/app/components/poetry/charts/composed_chart/style.rb +24 -0
  27. data/app/components/poetry/charts/container/component.html.erb +4 -0
  28. data/app/components/poetry/charts/container/component.rb +80 -0
  29. data/app/components/poetry/charts/container/preview.rb +45 -0
  30. data/app/components/poetry/charts/container/style.rb +22 -0
  31. data/app/components/poetry/charts/error_bars.rb +35 -0
  32. data/app/components/poetry/charts/legend_content/component.html.erb +10 -0
  33. data/app/components/poetry/charts/legend_content/component.rb +122 -0
  34. data/app/components/poetry/charts/legend_content/preview.rb +23 -0
  35. data/app/components/poetry/charts/legend_content/style.rb +26 -0
  36. data/app/components/poetry/charts/line_chart/component.html.erb +85 -0
  37. data/app/components/poetry/charts/line_chart/component.rb +252 -0
  38. data/app/components/poetry/charts/line_chart/preview.rb +115 -0
  39. data/app/components/poetry/charts/line_chart/style.rb +28 -0
  40. data/app/components/poetry/charts/live.rb +296 -0
  41. data/app/components/poetry/charts/motion.rb +98 -0
  42. data/app/components/poetry/charts/pie_chart/component.html.erb +36 -0
  43. data/app/components/poetry/charts/pie_chart/component.rb +256 -0
  44. data/app/components/poetry/charts/pie_chart/preview.rb +100 -0
  45. data/app/components/poetry/charts/pie_chart/style.rb +19 -0
  46. data/app/components/poetry/charts/polar_family.rb +95 -0
  47. data/app/components/poetry/charts/radar_chart/component.html.erb +73 -0
  48. data/app/components/poetry/charts/radar_chart/component.rb +329 -0
  49. data/app/components/poetry/charts/radar_chart/preview.rb +97 -0
  50. data/app/components/poetry/charts/radar_chart/style.rb +21 -0
  51. data/app/components/poetry/charts/radial_bar_chart/component.html.erb +65 -0
  52. data/app/components/poetry/charts/radial_bar_chart/component.rb +424 -0
  53. data/app/components/poetry/charts/radial_bar_chart/preview.rb +99 -0
  54. data/app/components/poetry/charts/radial_bar_chart/style.rb +27 -0
  55. data/app/components/poetry/charts/reference_marks.rb +156 -0
  56. data/app/components/poetry/charts/scatter_chart/component.html.erb +55 -0
  57. data/app/components/poetry/charts/scatter_chart/component.rb +396 -0
  58. data/app/components/poetry/charts/scatter_chart/preview.rb +93 -0
  59. data/app/components/poetry/charts/scatter_chart/style.rb +22 -0
  60. data/app/components/poetry/charts/tooltip_content/component.html.erb +19 -0
  61. data/app/components/poetry/charts/tooltip_content/component.rb +168 -0
  62. data/app/components/poetry/charts/tooltip_content/preview.rb +39 -0
  63. data/app/components/poetry/charts/tooltip_content/style.rb +31 -0
  64. data/app/components/poetry/charts/tooltip_layer/component.html.erb +6 -0
  65. data/app/components/poetry/charts/tooltip_layer/component.rb +61 -0
  66. data/app/components/poetry/charts/tooltip_layer/style.rb +13 -0
  67. data/app/components/poetry/charts/tooltip_wiring.rb +167 -0
  68. data/app/helpers/poetry/charts/components_helper.rb +125 -0
  69. data/app/javascript/poetry/charts/adapter_controller.js +75 -0
  70. data/app/javascript/poetry/charts/adapter_registry.js +52 -0
  71. data/app/javascript/poetry/charts/adapters/chartjs.js +86 -0
  72. data/app/javascript/poetry/charts/d3.js +14 -0
  73. data/app/javascript/poetry/charts/index.js +67 -0
  74. data/app/javascript/poetry/charts/live/renderer.js +456 -0
  75. data/app/javascript/poetry/charts/live_controller.js +195 -0
  76. data/app/javascript/poetry/charts/motion/flip.js +169 -0
  77. data/app/javascript/poetry/charts/motion/sector.js +62 -0
  78. data/app/javascript/poetry/charts/motion/tween.js +105 -0
  79. data/app/javascript/poetry/charts/motion_controller.js +230 -0
  80. data/app/javascript/poetry/charts/tooltip_controller.js +331 -0
  81. data/app/javascript/poetry/charts/window_controller.js +195 -0
  82. data/config/component_descriptions.yml +14 -0
  83. data/config/component_registry.yml +3055 -0
  84. data/config/controllers_manifest.json +100 -0
  85. data/config/importmap.rb +10 -0
  86. data/lib/poetry/charts/cartesian.rb +277 -0
  87. data/lib/poetry/charts/config.rb +149 -0
  88. data/lib/poetry/charts/engine.rb +76 -0
  89. data/lib/poetry/charts/geometry/area.rb +68 -0
  90. data/lib/poetry/charts/geometry/curve.rb +327 -0
  91. data/lib/poetry/charts/geometry/line.rb +64 -0
  92. data/lib/poetry/charts/geometry/nice_ticks.rb +220 -0
  93. data/lib/poetry/charts/geometry/path.rb +96 -0
  94. data/lib/poetry/charts/geometry/scale/band.rb +81 -0
  95. data/lib/poetry/charts/geometry/scale/linear.rb +127 -0
  96. data/lib/poetry/charts/geometry/stack.rb +129 -0
  97. data/lib/poetry/charts/geometry/ticks.rb +103 -0
  98. data/lib/poetry/charts/geometry.rb +66 -0
  99. data/lib/poetry/charts/polar.rb +179 -0
  100. data/lib/poetry/charts/spec.rb +108 -0
  101. data/lib/poetry/charts/theme_style.rb +53 -0
  102. data/lib/poetry/charts/version.rb +8 -0
  103. data/lib/poetry/charts.rb +114 -0
  104. data/lib/poetry-charts.rb +4 -0
  105. data/themes/default.css +146 -0
  106. data/themes/luma.css +139 -0
  107. data/themes/lyra.css +140 -0
  108. data/themes/maia.css +139 -0
  109. data/themes/mira.css +139 -0
  110. data/themes/nova.css +139 -0
  111. data/themes/rhea.css +139 -0
  112. data/themes/sera.css +140 -0
  113. data/themes/vega.css +144 -0
  114. data/vendor/d3-kernel/LICENSE-d3.txt +17 -0
  115. data/vendor/d3-kernel/LICENSE-decimal.js-light.txt +25 -0
  116. data/vendor/d3-kernel/LICENSE-recharts.txt +26 -0
  117. data/vendor/d3-kernel/README.md +30 -0
  118. data/vendor/d3-kernel/build.mjs +66 -0
  119. data/vendor/d3-kernel/entry.js +27 -0
  120. data/vendor/d3-kernel/recharts/state/cartesianAxisSlice.ts +6 -0
  121. data/vendor/d3-kernel/recharts/util/scale/getNiceTickValues.ts +310 -0
  122. data/vendor/d3-kernel/recharts/util/scale/util/arithmetic.ts +54 -0
  123. data/vendor/d3-kernel/recharts/util/types.ts +5 -0
  124. metadata +186 -0
@@ -0,0 +1,3055 @@
1
+ # poetry component registry - generated by `bin/rake registry:generate` FROM SOURCE.
2
+ # DO NOT EDIT: CI verifies this file matches a fresh build (rake registry:verify).
3
+ ---
4
+ components:
5
+ poetry/charts/adapter_chart:
6
+ class_name: Poetry::Charts::AdapterChart::Component
7
+ identifier: poetry--charts--adapter_chart
8
+ bem_block: poetry-charts-adapter_chart
9
+ styles: []
10
+ options:
11
+ - name: axes
12
+ type:
13
+ description: 'The axis config ({ x:, y: } hashes), also spec-carried.'
14
+ - name: config
15
+ type:
16
+ required: true
17
+ description: 'The series config - key => { label:, color: } - naming and coloring
18
+ every series.'
19
+ - name: data
20
+ type:
21
+ required: true
22
+ description: The rows to plot, serialized into the spec.
23
+ - name: engine
24
+ type: string
25
+ required: true
26
+ description: The registered adapter's name; the controller hands it the mount
27
+ and the spec.
28
+ - name: id
29
+ type: string
30
+ description: Explicit DOM id token, stable across renders; otherwise the chart
31
+ gets a unique per-render id.
32
+ - name: label
33
+ type: string
34
+ description: Accessible name for the mount; defaults to one built from the type
35
+ and engine.
36
+ - name: series
37
+ type:
38
+ required: true
39
+ description: The series list ({ data_key:, ... } hashes) - the closed spec's
40
+ replacement for slots.
41
+ - name: type
42
+ type: symbol
43
+ variants:
44
+ - area
45
+ - bar
46
+ - line
47
+ - pie
48
+ - radar
49
+ - radial
50
+ required: true
51
+ description: The chart type carried in the spec (see Spec::TYPES).
52
+ slots: []
53
+ description: 'The bring-your-own-engine path: a themed mount and chart-spec JSON
54
+ for a client library (Chart.js, etc.) to draw, instead of poetry''s server-side
55
+ SVG.'
56
+ elements:
57
+ - frame
58
+ - mount
59
+ capsule: 9305db093df7
60
+ controllers:
61
+ - identifier: poetry--charts--adapter
62
+ targets:
63
+ - mount
64
+ - spec
65
+ values:
66
+ - engine
67
+ actions: []
68
+ events:
69
+ - poetry--charts--adapter:rendered
70
+ agent_rules:
71
+ - 'The adapter path takes series:/axes: ARGUMENTS (the closed spec), not slots.'
72
+ - 'The host must register the engine first: registerChartAdapter(name, adapter)
73
+ - poetry ships createChartJsAdapter(Chart) as the reference.'
74
+ - 'The Container contract still applies: config colors, --chart tokens, dark mode.'
75
+ - Prefer the default engine; adapters are for engine-specific needs (e.g. >10k
76
+ points on canvas).
77
+ parts:
78
+ - name: chart-adapter-mount
79
+ description: The engine's drawing surface (role=img carrying the accessible
80
+ label) - the registered adapter renders into it
81
+ - name: chart-spec
82
+ description: The frozen chart-spec v1, served as JSON in an application/json
83
+ script for the adapter to consume
84
+ stimulus:
85
+ - element: frame
86
+ controllers:
87
+ - identifier: poetry--charts--adapter
88
+ registers: true
89
+ values:
90
+ - name: engine
91
+ - element: mount
92
+ controllers:
93
+ - identifier: poetry--charts--adapter
94
+ targets:
95
+ - name: mount
96
+ - element: spec
97
+ controllers:
98
+ - identifier: poetry--charts--adapter
99
+ targets:
100
+ - name: spec
101
+ poetry/charts/area_chart:
102
+ class_name: Poetry::Charts::AreaChart::Component
103
+ identifier: poetry--charts--area_chart
104
+ bem_block: poetry-charts-area_chart
105
+ styles: []
106
+ options:
107
+ - name: animate
108
+ type: boolean
109
+ default: true
110
+ description: Entrance animation switch - reduced-motion users always get the
111
+ finished chart regardless.
112
+ - name: animation_begin
113
+ type: integer
114
+ default: 0
115
+ description: Pre-animation hold in milliseconds.
116
+ - name: animation_duration
117
+ type: integer
118
+ default: 1500
119
+ description: Entrance/morph duration in milliseconds.
120
+ - name: animation_easing
121
+ type: symbol
122
+ default: ease
123
+ description: Animation easing keyword (see EASINGS).
124
+ - name: config
125
+ type:
126
+ required: true
127
+ description: 'The series config - key => { label:, color: } - naming and coloring
128
+ every series.'
129
+ - name: data
130
+ type:
131
+ required: true
132
+ description: 'The rows to plot: an array of hashes, one per x category.'
133
+ - name: height
134
+ type: integer
135
+ default: 360
136
+ description: ViewBox height in pixels.
137
+ - name: id
138
+ type: string
139
+ description: Explicit DOM id token, stable across renders; otherwise the chart
140
+ gets a unique per-render id.
141
+ - name: label
142
+ type: string
143
+ description: Accessible name for the chart SVG; defaults to one built from the
144
+ configured series.
145
+ - name: live
146
+ type: boolean
147
+ default: false
148
+ description: Embeds the {spec, frame} payload so the client renderer can recompute
149
+ geometry when data changes without a server round-trip.
150
+ - name: margin
151
+ type:
152
+ description: 'Plot margin overrides ({ top:, right:, bottom:, left: }), merged
153
+ over the defaults.'
154
+ - name: offset
155
+ type: symbol
156
+ variants:
157
+ - none
158
+ - expand
159
+ default: none
160
+ description: Stack baseline mode - :expand normalizes each stack to percentages.
161
+ - name: sync
162
+ type: string
163
+ - name: width
164
+ type: integer
165
+ default: 640
166
+ description: ViewBox width in pixels; the rendered chart scales to its container.
167
+ - name: zoom
168
+ type: boolean
169
+ default: false
170
+ description: 'Drag-to-zoom on the plot; slices the data client-side, so it needs
171
+ live: true.'
172
+ slots:
173
+ - name: reference_lines
174
+ many: true
175
+ setter_args:
176
+ reference_line: 0
177
+ setter_kwargs:
178
+ reference_line:
179
+ - x
180
+ - "y"
181
+ - label
182
+ - stroke_dasharray
183
+ - name: reference_areas
184
+ many: true
185
+ setter_args:
186
+ reference_area: 0
187
+ setter_kwargs:
188
+ reference_area:
189
+ - x1
190
+ - x2
191
+ - y1
192
+ - y2
193
+ - label
194
+ - fill_opacity
195
+ - name: reference_dots
196
+ many: true
197
+ setter_args:
198
+ reference_dot: 0
199
+ setter_kwargs:
200
+ reference_dot:
201
+ - x
202
+ - "y"
203
+ - r
204
+ - label
205
+ - name: brush
206
+ many: false
207
+ description: 'The brush strip below the x axis - drag its window to slice the
208
+ visible range; needs live: true.'
209
+ setter_args:
210
+ brush: 0
211
+ setter_kwargs:
212
+ brush:
213
+ - height
214
+ - name: areas
215
+ many: true
216
+ description: 'An area series bound to data_key:. Areas sharing a stack: id pile
217
+ up; gradient: true fades the fill; curve: picks the interpolation.'
218
+ setter_args:
219
+ area: 0
220
+ setter_kwargs:
221
+ area:
222
+ - data_key
223
+ - stack
224
+ - curve
225
+ - fill_opacity
226
+ - gradient
227
+ - stroke_width
228
+ - name: x_axis
229
+ many: false
230
+ setter_args:
231
+ x_axis: 0
232
+ setter_kwargs:
233
+ x_axis:
234
+ - data_key
235
+ - tick_formatter
236
+ - tick_margin
237
+ - name: y_axis
238
+ many: false
239
+ description: 'The value axis: tick_count: sets how many ticks show; tick_formatter:
240
+ reshapes each label; tick_margin: pads it.'
241
+ setter_args:
242
+ y_axis: 0
243
+ setter_kwargs:
244
+ y_axis:
245
+ - tick_count
246
+ - tick_formatter
247
+ - tick_margin
248
+ - name: grid
249
+ many: false
250
+ setter_args:
251
+ grid: 0
252
+ setter_kwargs:
253
+ grid:
254
+ - vertical
255
+ - horizontal
256
+ - name: legend
257
+ many: false
258
+ setter_args:
259
+ legend: 0
260
+ - name: tooltip
261
+ many: false
262
+ setter_args:
263
+ tooltip: 0
264
+ description: An area chart for volume or cumulative totals over a continuous axis.
265
+ elements:
266
+ - frame
267
+ - svg
268
+ - grid_line
269
+ - tick
270
+ - cursor_line
271
+ - cursor_band
272
+ - reference_line
273
+ - reference_area
274
+ - reference_dot
275
+ - error_bar
276
+ - brush_track
277
+ - brush_window
278
+ - brush_handle
279
+ capsule: adf1ec3bc1d1
280
+ controllers:
281
+ - identifier: poetry--charts--live
282
+ targets:
283
+ - payload
284
+ values: []
285
+ actions:
286
+ - receive
287
+ - setWindow
288
+ - toggleSeries
289
+ - update
290
+ events:
291
+ - poetry--charts--live:settled
292
+ - poetry--charts--live:updated
293
+ - identifier: poetry--charts--motion
294
+ targets: []
295
+ values: []
296
+ actions: []
297
+ events:
298
+ - poetry--charts--motion:settled
299
+ - identifier: poetry--charts--tooltip
300
+ targets:
301
+ - data
302
+ - svg
303
+ - tooltip
304
+ values:
305
+ - sync
306
+ actions:
307
+ - blur
308
+ - count
309
+ - enter
310
+ - focus
311
+ - keydown
312
+ - leave
313
+ - move
314
+ - refresh
315
+ - show
316
+ events:
317
+ - poetry--charts--tooltip:hide
318
+ - poetry--charts--tooltip:show
319
+ - identifier: poetry--charts--window
320
+ targets: []
321
+ values:
322
+ - brush
323
+ - plot
324
+ - zoom
325
+ actions:
326
+ - reset
327
+ - startBrush
328
+ - startZoom
329
+ events: []
330
+ agent_rules:
331
+ - 'Compose from slots: with_grid / with_x_axis(data_key:) / with_area(data_key:)
332
+ / with_legend.'
333
+ - 'Stack areas by giving them the same stack: id; offset: :expand makes the stack
334
+ percent-based.'
335
+ - Colors come from the config - never set fill/stroke on an area directly.
336
+ - 'gradient: true on an area gets the source''s 5%/95% fade fill.'
337
+ - Charts render complete on the server; the tooltip layer attaches separately.
338
+ - 'Entrance animation is on by default (source parity); animate: false for a static
339
+ chart. Reduced-motion users always get the finished chart.'
340
+ parts:
341
+ - name: chart-brush
342
+ description: 'The brush strip group (with_brush): track + window + two handles
343
+ below the x axis'
344
+ - name: chart-brush-track
345
+ description: The full-width brush rail
346
+ - name: chart-brush-window
347
+ description: The selected-range rect the drag moves
348
+ - name: chart-brush-handle
349
+ description: One draggable window edge
350
+ states:
351
+ - attr: data-edge
352
+ condition: always - which edge
353
+ values:
354
+ - start
355
+ - end
356
+ - name: chart-zoom-selection
357
+ description: 'The zoom drag-selection overlay (zoom: true), hidden until a drag
358
+ starts'
359
+ - name: chart-live-payload
360
+ description: The embedded {spec, frame} JSON the live renderer recomputes geometry
361
+ from
362
+ - name: chart-svg
363
+ description: The chart canvas (<svg>) - server-computed geometry in a fixed
364
+ viewBox; role=img, or the focusable role=application accessibilityLayer when
365
+ the tooltip attaches
366
+ states:
367
+ - attr: data-animate
368
+ condition: present when animate (the default) - the motion stylesheet and
369
+ controller key the entrance off it
370
+ - attr: data-motion
371
+ condition: runtime - the motion rig stamps the animation lifecycle (entrance/morph,
372
+ then settled)
373
+ values:
374
+ - entrance
375
+ - morph
376
+ - settled
377
+ vars:
378
+ - name: "--poetry-motion-duration"
379
+ description: the entrance/morph duration (animation_duration, ms)
380
+ - name: "--poetry-motion-easing"
381
+ description: the animation easing keyword (animation_easing)
382
+ - name: "--poetry-motion-delay"
383
+ description: the pre-animation hold (animation_begin, ms)
384
+ - name: chart-motion-reveal
385
+ description: The entrance clipPath rect (the ported area reveal) - the motion
386
+ stylesheet scales it 0 -> 1; only when animate
387
+ - name: chart-grid
388
+ description: The gridline group (with_grid) - horizontal and/or vertical rules
389
+ across the plot
390
+ - name: chart-cursor
391
+ description: The hover cursor, hidden until the tooltip controller positions
392
+ and reveals it at the active index - a vertical rule or a translucent band
393
+ rect (bar charts)
394
+ - name: chart-areas
395
+ description: The area-mark group - a fill path plus top-curve stroke per series,
396
+ clipped by the reveal rect while animating
397
+ - name: chart-area
398
+ description: One series' fill path (var(--color-<key>) or its gradient)
399
+ states:
400
+ - attr: data-key
401
+ condition: the series key
402
+ - name: chart-area-stroke
403
+ description: One series' top-curve stroke path (the source strokes the curve,
404
+ never the area outline)
405
+ states:
406
+ - attr: data-key
407
+ condition: the series key
408
+ - name: chart-active-dots
409
+ description: The hover-marker group (with_tooltip) - pre-rendered hidden circles
410
+ for every series x index
411
+ - name: chart-active-dot
412
+ description: One hover marker - display=none until the tooltip controller reveals
413
+ the active index's dot
414
+ states:
415
+ - attr: data-key
416
+ condition: the series key
417
+ - attr: data-index
418
+ condition: the datum index
419
+ - attr: data-active
420
+ condition: runtime - rides the marker while its index is the active one
421
+ - name: chart-x-axis
422
+ description: The x-axis tick-label group (with_x_axis)
423
+ - name: chart-y-axis
424
+ description: The y-axis tick-label group (with_y_axis)
425
+ - name: chart-coordinates
426
+ description: The embedded per-index geometry payload (<script type=application/json>)
427
+ the tooltip controller reads - zero chart math in the browser
428
+ stimulus:
429
+ - element: frame
430
+ controllers:
431
+ - identifier: poetry--charts--tooltip
432
+ conditional: if tooltip?
433
+ registers: true
434
+ values:
435
+ - name: sync
436
+ conditional: if
437
+ - identifier: poetry--charts--motion
438
+ conditional: if animate?
439
+ registers: true
440
+ - identifier: poetry--charts--live
441
+ conditional: if live?
442
+ registers: true
443
+ actions:
444
+ - method: receive
445
+ 'on': poetry-chart:update
446
+ - identifier: poetry--charts--tooltip
447
+ conditional: if
448
+ actions:
449
+ - method: refresh
450
+ 'on': poetry--charts--live:updated
451
+ - identifier: poetry--charts--window
452
+ conditional: if window_features?
453
+ registers: true
454
+ values:
455
+ - name: zoom
456
+ - name: plot
457
+ - name: brush
458
+ conditional: if
459
+ - element: svg
460
+ controllers:
461
+ - identifier: poetry--charts--tooltip
462
+ conditional: if tooltip?
463
+ targets:
464
+ - name: svg
465
+ actions:
466
+ - method: move
467
+ 'on': pointermove
468
+ - method: leave
469
+ 'on': pointerleave
470
+ - method: focus
471
+ 'on': focus
472
+ - method: blur
473
+ 'on': blur
474
+ - method: keydown
475
+ 'on': keydown
476
+ - identifier: poetry--charts--window
477
+ conditional: if zoom?
478
+ actions:
479
+ - method: startZoom
480
+ 'on': pointerdown
481
+ - method: reset
482
+ 'on': dblclick
483
+ - element: coordinates
484
+ controllers:
485
+ - identifier: poetry--charts--tooltip
486
+ conditional: if tooltip?
487
+ targets:
488
+ - name: data
489
+ - element: tooltip_layer
490
+ controllers:
491
+ - identifier: poetry--charts--tooltip
492
+ conditional: if tooltip?
493
+ targets:
494
+ - name: tooltip
495
+ - element: live_payload
496
+ controllers:
497
+ - identifier: poetry--charts--live
498
+ targets:
499
+ - name: payload
500
+ - element: brush
501
+ controllers:
502
+ - identifier: poetry--charts--window
503
+ conditional: if
504
+ actions:
505
+ - method: startBrush
506
+ 'on': pointerdown
507
+ poetry/charts/bar_chart:
508
+ class_name: Poetry::Charts::BarChart::Component
509
+ identifier: poetry--charts--bar_chart
510
+ bem_block: poetry-charts-bar_chart
511
+ styles: []
512
+ options:
513
+ - name: animate
514
+ type: boolean
515
+ default: true
516
+ description: Entrance animation switch - reduced-motion users always get the
517
+ finished chart regardless.
518
+ - name: animation_begin
519
+ type: integer
520
+ default: 0
521
+ description: Pre-animation hold in milliseconds.
522
+ - name: animation_duration
523
+ type: integer
524
+ default: 400
525
+ description: Entrance/morph duration in milliseconds.
526
+ - name: animation_easing
527
+ type: symbol
528
+ default: ease
529
+ description: Animation easing keyword (see EASINGS).
530
+ - name: bar_category_gap
531
+ type: string
532
+ default: 10%
533
+ description: 'Band trim on each side: a percent string of the band width, or
534
+ a bare pixel number.'
535
+ - name: bar_gap
536
+ type: integer
537
+ default: 4
538
+ description: Pixels between side-by-side bars inside one category band.
539
+ - name: config
540
+ type:
541
+ required: true
542
+ description: 'The series config - key => { label:, color: } - naming and coloring
543
+ every series.'
544
+ - name: data
545
+ type:
546
+ required: true
547
+ description: 'The rows to plot: an array of hashes, one per category.'
548
+ - name: height
549
+ type: integer
550
+ default: 360
551
+ description: ViewBox height in pixels.
552
+ - name: id
553
+ type: string
554
+ description: Explicit DOM id token, stable across renders; otherwise the chart
555
+ gets a unique per-render id.
556
+ - name: label
557
+ type: string
558
+ description: Accessible name for the chart SVG; defaults to one built from the
559
+ configured series.
560
+ - name: live
561
+ type: boolean
562
+ default: false
563
+ description: Embeds the {spec, frame} payload so the client renderer can recompute
564
+ geometry when data changes without a server round-trip.
565
+ - name: margin
566
+ type:
567
+ description: 'Plot margin overrides ({ top:, right:, bottom:, left: }), merged
568
+ over the defaults.'
569
+ - name: offset
570
+ type: symbol
571
+ variants:
572
+ - none
573
+ - expand
574
+ default: none
575
+ description: Stack baseline mode - :expand normalizes each stack to percentages.
576
+ - name: orientation
577
+ type: symbol
578
+ variants:
579
+ - vertical
580
+ - horizontal
581
+ default: vertical
582
+ description: ":vertical = columns (the default); :horizontal = bars growing
583
+ rightward - the category axis moves to the Y side (with_y_axis data_key:)
584
+ and the numeric axis hides."
585
+ - name: sync
586
+ type: string
587
+ - name: width
588
+ type: integer
589
+ default: 640
590
+ description: ViewBox width in pixels; the rendered chart scales to its container.
591
+ - name: zoom
592
+ type: boolean
593
+ default: false
594
+ description: 'Drag-to-zoom on the plot; slices the data client-side, so it needs
595
+ live: true.'
596
+ slots:
597
+ - name: reference_lines
598
+ many: true
599
+ setter_args:
600
+ reference_line: 0
601
+ setter_kwargs:
602
+ reference_line:
603
+ - x
604
+ - "y"
605
+ - label
606
+ - stroke_dasharray
607
+ - name: reference_areas
608
+ many: true
609
+ setter_args:
610
+ reference_area: 0
611
+ setter_kwargs:
612
+ reference_area:
613
+ - x1
614
+ - x2
615
+ - y1
616
+ - y2
617
+ - label
618
+ - fill_opacity
619
+ - name: reference_dots
620
+ many: true
621
+ setter_args:
622
+ reference_dot: 0
623
+ setter_kwargs:
624
+ reference_dot:
625
+ - x
626
+ - "y"
627
+ - r
628
+ - label
629
+ - name: brush
630
+ many: false
631
+ description: 'The brush strip below the x axis - drag its window to slice the
632
+ visible range; needs live: true.'
633
+ setter_args:
634
+ brush: 0
635
+ setter_kwargs:
636
+ brush:
637
+ - height
638
+ - name: bars
639
+ many: true
640
+ description: 'A bar series bound to data_key:. Bars sharing a stack: id pile
641
+ up; radius: rounds corners; labels:/label_key: stamp values; color_key:/cell_fill:
642
+ color per cell; active_index: highlights one bar; error_key: adds whiskers.'
643
+ setter_args:
644
+ bar: 0
645
+ setter_kwargs:
646
+ bar:
647
+ - data_key
648
+ - stack
649
+ - radius
650
+ - labels
651
+ - label_key
652
+ - color_key
653
+ - cell_fill
654
+ - active_index
655
+ - stroke_width
656
+ - error_key
657
+ - error_width
658
+ - name: x_axis
659
+ many: false
660
+ setter_args:
661
+ x_axis: 0
662
+ setter_kwargs:
663
+ x_axis:
664
+ - data_key
665
+ - tick_formatter
666
+ - tick_margin
667
+ - name: y_axis
668
+ many: false
669
+ description: 'The y axis: data_key: makes it the category axis (horizontal orientation);
670
+ tick_count:/tick_formatter:/tick_margin: as on the x axis.'
671
+ setter_args:
672
+ y_axis: 0
673
+ setter_kwargs:
674
+ y_axis:
675
+ - data_key
676
+ - tick_count
677
+ - tick_formatter
678
+ - tick_margin
679
+ - name: grid
680
+ many: false
681
+ setter_args:
682
+ grid: 0
683
+ setter_kwargs:
684
+ grid:
685
+ - vertical
686
+ - horizontal
687
+ - name: legend
688
+ many: false
689
+ setter_args:
690
+ legend: 0
691
+ - name: tooltip
692
+ many: false
693
+ setter_args:
694
+ tooltip: 0
695
+ description: A bar chart for comparing values across categories.
696
+ elements:
697
+ - frame
698
+ - svg
699
+ - grid_line
700
+ - tick
701
+ - cursor_line
702
+ - cursor_band
703
+ - reference_line
704
+ - reference_area
705
+ - reference_dot
706
+ - error_bar
707
+ - brush_track
708
+ - brush_window
709
+ - brush_handle
710
+ - label
711
+ capsule: b8433411927b
712
+ controllers:
713
+ - identifier: poetry--charts--live
714
+ targets:
715
+ - payload
716
+ values: []
717
+ actions:
718
+ - receive
719
+ - setWindow
720
+ - toggleSeries
721
+ - update
722
+ events:
723
+ - poetry--charts--live:settled
724
+ - poetry--charts--live:updated
725
+ - identifier: poetry--charts--motion
726
+ targets: []
727
+ values: []
728
+ actions: []
729
+ events:
730
+ - poetry--charts--motion:settled
731
+ - identifier: poetry--charts--tooltip
732
+ targets:
733
+ - data
734
+ - svg
735
+ - tooltip
736
+ values:
737
+ - sync
738
+ actions:
739
+ - blur
740
+ - count
741
+ - enter
742
+ - focus
743
+ - keydown
744
+ - leave
745
+ - move
746
+ - refresh
747
+ - show
748
+ events:
749
+ - poetry--charts--tooltip:hide
750
+ - poetry--charts--tooltip:show
751
+ - identifier: poetry--charts--window
752
+ targets: []
753
+ values:
754
+ - brush
755
+ - plot
756
+ - zoom
757
+ actions:
758
+ - reset
759
+ - startBrush
760
+ - startZoom
761
+ events: []
762
+ agent_rules:
763
+ - 'Compose from slots: with_grid / with_x_axis(data_key:) / with_bar(data_key:)
764
+ / with_legend.'
765
+ - 'radius: 8 rounds all corners; stacked bars use arrays - [0,0,4,4] bottom bar,
766
+ [4,4,0,0] top bar.'
767
+ - 'Stack bars with the same stack: id; negatives automatically drop below the
768
+ zero line.'
769
+ - 'cell_fill: ->(row, value) { ... } colors bars per datum (validated CSS-safe);
770
+ color_key: reads a row key.'
771
+ - 'active_index: highlights one bar (fill-opacity 0.8 + dashed stroke - the active
772
+ block look).'
773
+ - 'Entrance animation is on by default (source parity); animate: false for a static
774
+ chart. Reduced-motion users always get the finished chart.'
775
+ parts:
776
+ - name: chart-brush
777
+ description: 'The brush strip group (with_brush): track + window + two handles
778
+ below the x axis'
779
+ - name: chart-brush-track
780
+ description: The full-width brush rail
781
+ - name: chart-brush-window
782
+ description: The selected-range rect the drag moves
783
+ - name: chart-brush-handle
784
+ description: One draggable window edge
785
+ states:
786
+ - attr: data-edge
787
+ condition: always - which edge
788
+ values:
789
+ - start
790
+ - end
791
+ - name: chart-zoom-selection
792
+ description: 'The zoom drag-selection overlay (zoom: true), hidden until a drag
793
+ starts'
794
+ - name: chart-live-payload
795
+ description: The embedded {spec, frame} JSON the live renderer recomputes geometry
796
+ from
797
+ - name: chart-svg
798
+ description: The chart canvas (<svg>) - server-computed geometry in a fixed
799
+ viewBox; role=img, or the focusable role=application accessibilityLayer when
800
+ the tooltip attaches
801
+ states:
802
+ - attr: data-animate
803
+ condition: present when animate (the default) - the motion stylesheet and
804
+ controller key the entrance off it
805
+ - attr: data-motion
806
+ condition: runtime - the motion rig stamps the animation lifecycle (entrance/morph,
807
+ then settled)
808
+ values:
809
+ - entrance
810
+ - morph
811
+ - settled
812
+ vars:
813
+ - name: "--poetry-motion-duration"
814
+ description: the entrance/morph duration (animation_duration, ms)
815
+ - name: "--poetry-motion-easing"
816
+ description: the animation easing keyword (animation_easing)
817
+ - name: "--poetry-motion-delay"
818
+ description: the pre-animation hold (animation_begin, ms)
819
+ - name: chart-grid
820
+ description: The gridline group (with_grid) - horizontal and/or vertical rules
821
+ across the plot
822
+ - name: chart-cursor
823
+ description: The hover cursor, hidden until the tooltip controller positions
824
+ and reveals it at the active index - a vertical rule or a translucent band
825
+ rect (bar charts)
826
+ - name: chart-bars
827
+ description: The bar-mark group wrapping every series
828
+ - name: chart-bar-series
829
+ description: One series' bar group
830
+ states:
831
+ - attr: data-key
832
+ condition: the series key
833
+ - name: chart-bar
834
+ description: One bar cell (a per-corner rounded-rect path)
835
+ states:
836
+ - attr: data-key
837
+ condition: the series key
838
+ - attr: data-index
839
+ condition: the datum index
840
+ - attr: data-active
841
+ condition: the highlighted cell - server-rendered from active_index:, and
842
+ the tooltip controller marks the hovered index at runtime
843
+ - attr: data-motion-origin
844
+ condition: when animate - the zero edge the entrance grows from
845
+ values:
846
+ - bottom
847
+ - top
848
+ - left
849
+ - right
850
+ - name: chart-labels
851
+ description: 'One series'' value-label group (labels: true)'
852
+ states:
853
+ - attr: data-key
854
+ condition: the series key
855
+ - name: chart-x-axis
856
+ description: The x-axis tick-label group (with_x_axis)
857
+ - name: chart-y-axis
858
+ description: The y-axis tick-label group (with_y_axis)
859
+ - name: chart-coordinates
860
+ description: The embedded per-index geometry payload (<script type=application/json>)
861
+ the tooltip controller reads - zero chart math in the browser
862
+ stimulus:
863
+ - element: frame
864
+ controllers:
865
+ - identifier: poetry--charts--tooltip
866
+ conditional: if tooltip?
867
+ registers: true
868
+ values:
869
+ - name: sync
870
+ conditional: if
871
+ - identifier: poetry--charts--motion
872
+ conditional: if animate?
873
+ registers: true
874
+ - identifier: poetry--charts--live
875
+ conditional: if live?
876
+ registers: true
877
+ actions:
878
+ - method: receive
879
+ 'on': poetry-chart:update
880
+ - identifier: poetry--charts--tooltip
881
+ conditional: if
882
+ actions:
883
+ - method: refresh
884
+ 'on': poetry--charts--live:updated
885
+ - identifier: poetry--charts--window
886
+ conditional: if window_features?
887
+ registers: true
888
+ values:
889
+ - name: zoom
890
+ - name: plot
891
+ - name: brush
892
+ conditional: if
893
+ - element: svg
894
+ controllers:
895
+ - identifier: poetry--charts--tooltip
896
+ conditional: if tooltip?
897
+ targets:
898
+ - name: svg
899
+ actions:
900
+ - method: move
901
+ 'on': pointermove
902
+ - method: leave
903
+ 'on': pointerleave
904
+ - method: focus
905
+ 'on': focus
906
+ - method: blur
907
+ 'on': blur
908
+ - method: keydown
909
+ 'on': keydown
910
+ - identifier: poetry--charts--window
911
+ conditional: if zoom?
912
+ actions:
913
+ - method: startZoom
914
+ 'on': pointerdown
915
+ - method: reset
916
+ 'on': dblclick
917
+ - element: coordinates
918
+ controllers:
919
+ - identifier: poetry--charts--tooltip
920
+ conditional: if tooltip?
921
+ targets:
922
+ - name: data
923
+ - element: tooltip_layer
924
+ controllers:
925
+ - identifier: poetry--charts--tooltip
926
+ conditional: if tooltip?
927
+ targets:
928
+ - name: tooltip
929
+ - element: live_payload
930
+ controllers:
931
+ - identifier: poetry--charts--live
932
+ targets:
933
+ - name: payload
934
+ - element: brush
935
+ controllers:
936
+ - identifier: poetry--charts--window
937
+ conditional: if
938
+ actions:
939
+ - method: startBrush
940
+ 'on': pointerdown
941
+ poetry/charts/composed_chart:
942
+ class_name: Poetry::Charts::ComposedChart::Component
943
+ identifier: poetry--charts--composed_chart
944
+ bem_block: poetry-charts-composed_chart
945
+ styles: []
946
+ options:
947
+ - name: animate
948
+ type: boolean
949
+ default: true
950
+ description: Entrance animation switch - reduced-motion users always get the
951
+ finished chart regardless.
952
+ - name: animation_begin
953
+ type: integer
954
+ default: 0
955
+ description: Pre-animation hold in milliseconds.
956
+ - name: animation_duration
957
+ type: integer
958
+ default: 1500
959
+ description: Entrance/morph duration in milliseconds.
960
+ - name: animation_easing
961
+ type: symbol
962
+ default: ease
963
+ description: Animation easing keyword (see EASINGS).
964
+ - name: bar_category_gap
965
+ type: string
966
+ default: 10%
967
+ description: 'Band trim on each side: a percent string of the band width, or
968
+ a bare pixel number.'
969
+ - name: bar_gap
970
+ type: integer
971
+ default: 4
972
+ description: Pixels between side-by-side bars inside one category band.
973
+ - name: config
974
+ type:
975
+ required: true
976
+ description: 'The series config - key => { label:, color: } - naming and coloring
977
+ every series.'
978
+ - name: data
979
+ type:
980
+ required: true
981
+ description: 'The rows to plot: an array of hashes, one per x category.'
982
+ - name: height
983
+ type: integer
984
+ default: 360
985
+ description: ViewBox height in pixels.
986
+ - name: id
987
+ type: string
988
+ description: Explicit DOM id token, stable across renders; otherwise the chart
989
+ gets a unique per-render id.
990
+ - name: label
991
+ type: string
992
+ description: Accessible name for the chart SVG; defaults to one built from the
993
+ configured series.
994
+ - name: margin
995
+ type:
996
+ description: 'Plot margin overrides ({ top:, right:, bottom:, left: }), merged
997
+ over the defaults.'
998
+ - name: sync
999
+ type: string
1000
+ - name: width
1001
+ type: integer
1002
+ default: 640
1003
+ description: ViewBox width in pixels; the rendered chart scales to its container.
1004
+ slots:
1005
+ - name: reference_lines
1006
+ many: true
1007
+ setter_args:
1008
+ reference_line: 0
1009
+ setter_kwargs:
1010
+ reference_line:
1011
+ - x
1012
+ - "y"
1013
+ - label
1014
+ - stroke_dasharray
1015
+ - name: reference_areas
1016
+ many: true
1017
+ setter_args:
1018
+ reference_area: 0
1019
+ setter_kwargs:
1020
+ reference_area:
1021
+ - x1
1022
+ - x2
1023
+ - y1
1024
+ - y2
1025
+ - label
1026
+ - fill_opacity
1027
+ - name: reference_dots
1028
+ many: true
1029
+ setter_args:
1030
+ reference_dot: 0
1031
+ setter_kwargs:
1032
+ reference_dot:
1033
+ - x
1034
+ - "y"
1035
+ - r
1036
+ - label
1037
+ - name: areas
1038
+ many: true
1039
+ description: 'An area mark bound to data_key:; areas sharing a stack: id pile
1040
+ up (area stacks never join bar stacks).'
1041
+ setter_args:
1042
+ area: 0
1043
+ setter_kwargs:
1044
+ area:
1045
+ - data_key
1046
+ - stack
1047
+ - curve
1048
+ - fill_opacity
1049
+ - gradient
1050
+ - stroke_width
1051
+ - name: bars
1052
+ many: true
1053
+ description: 'A bar mark bound to data_key:; radius: rounds corners; bars sharing
1054
+ a stack: id pile up within the bar marks.'
1055
+ setter_args:
1056
+ bar: 0
1057
+ setter_kwargs:
1058
+ bar:
1059
+ - data_key
1060
+ - stack
1061
+ - radius
1062
+ - name: lines
1063
+ many: true
1064
+ description: 'A line mark bound to data_key:; dots: marks each point.'
1065
+ setter_args:
1066
+ line: 0
1067
+ setter_kwargs:
1068
+ line:
1069
+ - data_key
1070
+ - curve
1071
+ - stroke_width
1072
+ - dots
1073
+ - dot_radius
1074
+ - name: x_axis
1075
+ many: false
1076
+ setter_args:
1077
+ x_axis: 0
1078
+ setter_kwargs:
1079
+ x_axis:
1080
+ - data_key
1081
+ - tick_formatter
1082
+ - tick_margin
1083
+ - name: y_axis
1084
+ many: false
1085
+ description: 'The value axis: tick_count: sets how many ticks show; tick_formatter:
1086
+ reshapes each label; tick_margin: pads it.'
1087
+ setter_args:
1088
+ y_axis: 0
1089
+ setter_kwargs:
1090
+ y_axis:
1091
+ - tick_count
1092
+ - tick_formatter
1093
+ - tick_margin
1094
+ - name: grid
1095
+ many: false
1096
+ setter_args:
1097
+ grid: 0
1098
+ setter_kwargs:
1099
+ grid:
1100
+ - vertical
1101
+ - horizontal
1102
+ - name: legend
1103
+ many: false
1104
+ setter_args:
1105
+ legend: 0
1106
+ - name: tooltip
1107
+ many: false
1108
+ setter_args:
1109
+ tooltip: 0
1110
+ description: A composed chart layering bars, lines, and areas on shared axes.
1111
+ elements:
1112
+ - frame
1113
+ - svg
1114
+ - grid_line
1115
+ - tick
1116
+ - cursor_line
1117
+ - cursor_band
1118
+ - reference_line
1119
+ - reference_area
1120
+ - reference_dot
1121
+ - error_bar
1122
+ capsule: 6947e8a26d43
1123
+ controllers:
1124
+ - identifier: poetry--charts--motion
1125
+ targets: []
1126
+ values: []
1127
+ actions: []
1128
+ events:
1129
+ - poetry--charts--motion:settled
1130
+ - identifier: poetry--charts--tooltip
1131
+ targets:
1132
+ - data
1133
+ - svg
1134
+ - tooltip
1135
+ values:
1136
+ - sync
1137
+ actions:
1138
+ - blur
1139
+ - count
1140
+ - enter
1141
+ - focus
1142
+ - keydown
1143
+ - leave
1144
+ - move
1145
+ - refresh
1146
+ - show
1147
+ events:
1148
+ - poetry--charts--tooltip:hide
1149
+ - poetry--charts--tooltip:show
1150
+ agent_rules:
1151
+ - 'Mix marks freely: with_area / with_bar / with_line - declaration order is paint
1152
+ order.'
1153
+ - All marks share the x band and ONE y domain; lines and areas ride the band centers.
1154
+ - 'stack: ids only combine within the same mark type (a bar stack never joins
1155
+ an area stack).'
1156
+ - Colors come from the config - never set fill/stroke on a mark directly.
1157
+ - Entrance animation is on by default; each mark keeps its own reveal mechanism.
1158
+ parts:
1159
+ - name: chart-svg
1160
+ description: The chart canvas (<svg>) - server-computed geometry in a fixed
1161
+ viewBox; role=img, or the focusable role=application accessibilityLayer when
1162
+ the tooltip attaches
1163
+ states:
1164
+ - attr: data-animate
1165
+ condition: present when animate (the default) - the motion stylesheet and
1166
+ controller key the entrance off it
1167
+ - attr: data-motion
1168
+ condition: runtime - the motion rig stamps the animation lifecycle (entrance/morph,
1169
+ then settled)
1170
+ values:
1171
+ - entrance
1172
+ - morph
1173
+ - settled
1174
+ vars:
1175
+ - name: "--poetry-motion-duration"
1176
+ description: the entrance/morph duration (animation_duration, ms)
1177
+ - name: "--poetry-motion-easing"
1178
+ description: the animation easing keyword (animation_easing)
1179
+ - name: "--poetry-motion-delay"
1180
+ description: the pre-animation hold (animation_begin, ms)
1181
+ - name: chart-motion-reveal
1182
+ description: The entrance clipPath rect (the ported area reveal) - the motion
1183
+ stylesheet scales it 0 -> 1; only when animate
1184
+ - name: chart-grid
1185
+ description: The gridline group (with_grid) - horizontal and/or vertical rules
1186
+ across the plot
1187
+ - name: chart-cursor
1188
+ description: The hover cursor, hidden until the tooltip controller positions
1189
+ and reveals it at the active index - a vertical rule or a translucent band
1190
+ rect (bar charts)
1191
+ - name: chart-areas
1192
+ description: The area-mark group - a fill path plus top-curve stroke per series,
1193
+ clipped by the reveal rect while animating
1194
+ - name: chart-area
1195
+ description: One series' fill path (var(--color-<key>) or its gradient)
1196
+ states:
1197
+ - attr: data-key
1198
+ condition: the series key
1199
+ - name: chart-area-stroke
1200
+ description: One series' top-curve stroke path (the source strokes the curve,
1201
+ never the area outline)
1202
+ states:
1203
+ - attr: data-key
1204
+ condition: the series key
1205
+ - name: chart-bar-series
1206
+ description: One series' bar group
1207
+ states:
1208
+ - attr: data-key
1209
+ condition: the series key
1210
+ - name: chart-bar
1211
+ description: One bar cell (a per-corner rounded-rect path)
1212
+ states:
1213
+ - attr: data-key
1214
+ condition: the series key
1215
+ - attr: data-index
1216
+ condition: the datum index
1217
+ - attr: data-active
1218
+ condition: runtime - the tooltip controller marks the hovered index
1219
+ - attr: data-motion-origin
1220
+ condition: when animate - the zero edge the entrance grows from
1221
+ values:
1222
+ - bottom
1223
+ - top
1224
+ - name: chart-lines
1225
+ description: The line-mark group - each series' curve plus its companion marks
1226
+ - name: chart-line
1227
+ description: One series' stroked curve - pathLength=1 when animating so the
1228
+ dash draw-in needs no measurement
1229
+ states:
1230
+ - attr: data-key
1231
+ condition: the series key
1232
+ - name: chart-dots
1233
+ description: 'One series'' point-dot group (dots: true)'
1234
+ states:
1235
+ - attr: data-key
1236
+ condition: the series key
1237
+ - name: chart-dot
1238
+ description: One point dot (<circle>)
1239
+ - name: chart-active-dots
1240
+ description: The hover-marker group (with_tooltip) - pre-rendered hidden circles
1241
+ for every series x index
1242
+ - name: chart-active-dot
1243
+ description: One hover marker - display=none until the tooltip controller reveals
1244
+ the active index's dot
1245
+ states:
1246
+ - attr: data-key
1247
+ condition: the series key
1248
+ - attr: data-index
1249
+ condition: the datum index
1250
+ - attr: data-active
1251
+ condition: runtime - rides the marker while its index is the active one
1252
+ - name: chart-x-axis
1253
+ description: The x-axis tick-label group (with_x_axis)
1254
+ - name: chart-coordinates
1255
+ description: The embedded per-index geometry payload (<script type=application/json>)
1256
+ the tooltip controller reads - zero chart math in the browser
1257
+ stimulus:
1258
+ - element: frame
1259
+ controllers:
1260
+ - identifier: poetry--charts--tooltip
1261
+ conditional: if tooltip?
1262
+ registers: true
1263
+ values:
1264
+ - name: sync
1265
+ conditional: if
1266
+ - identifier: poetry--charts--motion
1267
+ conditional: if animate?
1268
+ registers: true
1269
+ - element: svg
1270
+ controllers:
1271
+ - identifier: poetry--charts--tooltip
1272
+ conditional: if tooltip?
1273
+ targets:
1274
+ - name: svg
1275
+ actions:
1276
+ - method: move
1277
+ 'on': pointermove
1278
+ - method: leave
1279
+ 'on': pointerleave
1280
+ - method: focus
1281
+ 'on': focus
1282
+ - method: blur
1283
+ 'on': blur
1284
+ - method: keydown
1285
+ 'on': keydown
1286
+ - element: coordinates
1287
+ controllers:
1288
+ - identifier: poetry--charts--tooltip
1289
+ conditional: if tooltip?
1290
+ targets:
1291
+ - name: data
1292
+ - element: tooltip_layer
1293
+ controllers:
1294
+ - identifier: poetry--charts--tooltip
1295
+ conditional: if tooltip?
1296
+ targets:
1297
+ - name: tooltip
1298
+ poetry/charts/container:
1299
+ class_name: Poetry::Charts::Container::Component
1300
+ identifier: poetry--charts--container
1301
+ bem_block: poetry-charts-container
1302
+ styles: []
1303
+ options:
1304
+ - name: config
1305
+ type:
1306
+ required: true
1307
+ description: 'The series config - key => { label:, color: } - driving the per-series
1308
+ color emission.'
1309
+ - name: id
1310
+ type: string
1311
+ description: Explicit DOM id token, stable across renders; otherwise the frame
1312
+ gets a unique per-render id.
1313
+ slots: []
1314
+ elements: []
1315
+ capsule: 7b90eeaff974
1316
+ agent_rules:
1317
+ - Every chart lives inside poetry_chart_container(config:) - the config maps series
1318
+ keys to labels/colors.
1319
+ - Reference series colors as var(--color-<key>); never hard-code a color in chart
1320
+ markup.
1321
+ - 'Config colors point at theme tokens (var(--chart-1..5)) or use theme: { light:,
1322
+ dark: } maps.'
1323
+ - 'Give charts an explicit id: when the page renders more than one of the same
1324
+ chart.'
1325
+ parts:
1326
+ - name: chart
1327
+ description: The chart frame (<div>) - the aspect-video chrome, the tooltip
1328
+ layer's positioning anchor, and the id scope the per-series colors are emitted
1329
+ for
1330
+ states:
1331
+ - attr: data-chart
1332
+ condition: 'always - the chart instance id (explicit id: or unique per render);
1333
+ the scoped color emission keys off it'
1334
+ vars:
1335
+ - name: "--color-*"
1336
+ description: per-series color, one entry per series key - the frame's <style>
1337
+ block emits them for [data-chart=<id>] in both themes
1338
+ poetry/charts/legend_content:
1339
+ class_name: Poetry::Charts::LegendContent::Component
1340
+ identifier: poetry--charts--legend_content
1341
+ bem_block: poetry-charts-legend_content
1342
+ styles:
1343
+ - name: align
1344
+ type: symbol
1345
+ variants:
1346
+ - top
1347
+ - bottom
1348
+ default: bottom
1349
+ required: true
1350
+ description: 'Which chart edge the legend sits on: :top pads below it, :bottom
1351
+ (the default) pads above. A style axis, not an option - options silently drop
1352
+ the dictionary''s variant classes.'
1353
+ options:
1354
+ - name: config
1355
+ type:
1356
+ required: true
1357
+ description: 'The series config - key => { label:, color: } - the default item
1358
+ source.'
1359
+ - name: hide_icon
1360
+ type: boolean
1361
+ default: false
1362
+ description: Hides the color swatches, leaving labels only.
1363
+ - name: items
1364
+ type:
1365
+ description: 'Explicit entries ([{ key:, name:, color: }]) overriding the config-derived
1366
+ list.'
1367
+ - name: toggle
1368
+ type: boolean
1369
+ default: false
1370
+ description: 'Interactive legend: items render as buttons that toggle their
1371
+ series through the live controller (the host chart guards that live: is on).'
1372
+ slots: []
1373
+ elements:
1374
+ - item
1375
+ - swatch
1376
+ - toggle
1377
+ capsule: e0df3abb928a
1378
+ agent_rules:
1379
+ - 'The legend derives from the chart config by default - omit items: unless slices
1380
+ differ from series.'
1381
+ - 'align: :top pads below (pb-3), :bottom (default) pads above (pt-3) - matching
1382
+ the chart edge it sits on.'
1383
+ identity: false
1384
+ parts:
1385
+ - name: chart-legend-content
1386
+ description: The legend row (<div>) - centered swatch + label pairs
1387
+ - name: chart-legend-item
1388
+ description: One legend entry (<div>; a <button> in toggle mode)
1389
+ states:
1390
+ - attr: data-key
1391
+ condition: in toggle mode - the series key the button toggles
1392
+ - attr: data-hidden
1393
+ condition: in toggle mode - the item's series is toggled off (the live controller
1394
+ stamps it at runtime; the item dims)
1395
+ - name: chart-legend-swatch
1396
+ description: The color swatch (<div>) - inline background-color carries the
1397
+ entry's color; omitted with hide_icon or colorless entries
1398
+ poetry/charts/line_chart:
1399
+ class_name: Poetry::Charts::LineChart::Component
1400
+ identifier: poetry--charts--line_chart
1401
+ bem_block: poetry-charts-line_chart
1402
+ styles: []
1403
+ options:
1404
+ - name: animate
1405
+ type: boolean
1406
+ default: true
1407
+ description: Entrance animation switch - reduced-motion users always get the
1408
+ finished chart regardless.
1409
+ - name: animation_begin
1410
+ type: integer
1411
+ default: 0
1412
+ description: Pre-animation hold in milliseconds.
1413
+ - name: animation_duration
1414
+ type: integer
1415
+ default: 1500
1416
+ description: Entrance/morph duration in milliseconds.
1417
+ - name: animation_easing
1418
+ type: symbol
1419
+ default: ease
1420
+ description: Animation easing keyword (see EASINGS).
1421
+ - name: config
1422
+ type:
1423
+ required: true
1424
+ description: 'The series config - key => { label:, color: } - naming and coloring
1425
+ every series.'
1426
+ - name: data
1427
+ type:
1428
+ required: true
1429
+ description: 'The rows to plot: an array of hashes, one per x category.'
1430
+ - name: height
1431
+ type: integer
1432
+ default: 360
1433
+ description: ViewBox height in pixels.
1434
+ - name: id
1435
+ type: string
1436
+ description: Explicit DOM id token, stable across renders; otherwise the chart
1437
+ gets a unique per-render id.
1438
+ - name: label
1439
+ type: string
1440
+ description: Accessible name for the chart SVG; defaults to one built from the
1441
+ configured series.
1442
+ - name: live
1443
+ type: boolean
1444
+ default: false
1445
+ description: Embeds the {spec, frame} payload so the client renderer can recompute
1446
+ geometry when data changes without a server round-trip.
1447
+ - name: margin
1448
+ type:
1449
+ description: 'Plot margin overrides ({ top:, right:, bottom:, left: }), merged
1450
+ over the defaults.'
1451
+ - name: sync
1452
+ type: string
1453
+ - name: width
1454
+ type: integer
1455
+ default: 640
1456
+ description: ViewBox width in pixels; the rendered chart scales to its container.
1457
+ - name: zoom
1458
+ type: boolean
1459
+ default: false
1460
+ description: 'Drag-to-zoom on the plot; slices the data client-side, so it needs
1461
+ live: true.'
1462
+ slots:
1463
+ - name: reference_lines
1464
+ many: true
1465
+ setter_args:
1466
+ reference_line: 0
1467
+ setter_kwargs:
1468
+ reference_line:
1469
+ - x
1470
+ - "y"
1471
+ - label
1472
+ - stroke_dasharray
1473
+ - name: reference_areas
1474
+ many: true
1475
+ setter_args:
1476
+ reference_area: 0
1477
+ setter_kwargs:
1478
+ reference_area:
1479
+ - x1
1480
+ - x2
1481
+ - y1
1482
+ - y2
1483
+ - label
1484
+ - fill_opacity
1485
+ - name: reference_dots
1486
+ many: true
1487
+ setter_args:
1488
+ reference_dot: 0
1489
+ setter_kwargs:
1490
+ reference_dot:
1491
+ - x
1492
+ - "y"
1493
+ - r
1494
+ - label
1495
+ - name: brush
1496
+ many: false
1497
+ description: 'The brush strip below the x axis - drag its window to slice the
1498
+ visible range; needs live: true.'
1499
+ setter_args:
1500
+ brush: 0
1501
+ setter_kwargs:
1502
+ brush:
1503
+ - height
1504
+ - name: lines
1505
+ many: true
1506
+ description: 'A line series bound to data_key:. dots: marks each point; dot_color_key:
1507
+ reads per-point dot colors from the row; labels: stamps each value above its
1508
+ point; error_key: adds error whiskers.'
1509
+ setter_args:
1510
+ line: 0
1511
+ setter_kwargs:
1512
+ line:
1513
+ - data_key
1514
+ - curve
1515
+ - stroke_width
1516
+ - dots
1517
+ - dot_radius
1518
+ - dot_color_key
1519
+ - labels
1520
+ - error_key
1521
+ - error_width
1522
+ - name: x_axis
1523
+ many: false
1524
+ setter_args:
1525
+ x_axis: 0
1526
+ setter_kwargs:
1527
+ x_axis:
1528
+ - data_key
1529
+ - tick_formatter
1530
+ - tick_margin
1531
+ - name: y_axis
1532
+ many: false
1533
+ description: 'The value axis: tick_count: sets how many ticks show; tick_formatter:
1534
+ reshapes each label; tick_margin: pads it.'
1535
+ setter_args:
1536
+ y_axis: 0
1537
+ setter_kwargs:
1538
+ y_axis:
1539
+ - tick_count
1540
+ - tick_formatter
1541
+ - tick_margin
1542
+ - name: grid
1543
+ many: false
1544
+ setter_args:
1545
+ grid: 0
1546
+ setter_kwargs:
1547
+ grid:
1548
+ - vertical
1549
+ - horizontal
1550
+ - name: legend
1551
+ many: false
1552
+ setter_args:
1553
+ legend: 0
1554
+ - name: tooltip
1555
+ many: false
1556
+ setter_args:
1557
+ tooltip: 0
1558
+ description: A line chart for trends over a continuous axis.
1559
+ elements:
1560
+ - frame
1561
+ - svg
1562
+ - grid_line
1563
+ - tick
1564
+ - cursor_line
1565
+ - cursor_band
1566
+ - reference_line
1567
+ - reference_area
1568
+ - reference_dot
1569
+ - error_bar
1570
+ - brush_track
1571
+ - brush_window
1572
+ - brush_handle
1573
+ - label
1574
+ capsule: b8433411927b
1575
+ controllers:
1576
+ - identifier: poetry--charts--live
1577
+ targets:
1578
+ - payload
1579
+ values: []
1580
+ actions:
1581
+ - receive
1582
+ - setWindow
1583
+ - toggleSeries
1584
+ - update
1585
+ events:
1586
+ - poetry--charts--live:settled
1587
+ - poetry--charts--live:updated
1588
+ - identifier: poetry--charts--motion
1589
+ targets: []
1590
+ values: []
1591
+ actions: []
1592
+ events:
1593
+ - poetry--charts--motion:settled
1594
+ - identifier: poetry--charts--tooltip
1595
+ targets:
1596
+ - data
1597
+ - svg
1598
+ - tooltip
1599
+ values:
1600
+ - sync
1601
+ actions:
1602
+ - blur
1603
+ - count
1604
+ - enter
1605
+ - focus
1606
+ - keydown
1607
+ - leave
1608
+ - move
1609
+ - refresh
1610
+ - show
1611
+ events:
1612
+ - poetry--charts--tooltip:hide
1613
+ - poetry--charts--tooltip:show
1614
+ - identifier: poetry--charts--window
1615
+ targets: []
1616
+ values:
1617
+ - brush
1618
+ - plot
1619
+ - zoom
1620
+ actions:
1621
+ - reset
1622
+ - startBrush
1623
+ - startZoom
1624
+ events: []
1625
+ agent_rules:
1626
+ - 'Compose from slots: with_grid / with_x_axis(data_key:) / with_line(data_key:)
1627
+ / with_legend.'
1628
+ - 'Lines default to stroke-width 2 and NO dots (the ported block look); dots:
1629
+ true adds them.'
1630
+ - 'dot_color_key: reads a per-row data key for per-point dot colors (the dots-colors
1631
+ block).'
1632
+ - 'labels: true stamps each value above its point; give the chart margin top when
1633
+ using it.'
1634
+ - Colors come from the config - never set stroke on a line directly.
1635
+ - 'Entrance animation is on by default (source parity); animate: false for a static
1636
+ chart. Reduced-motion users always get the finished chart.'
1637
+ parts:
1638
+ - name: chart-brush
1639
+ description: 'The brush strip group (with_brush): track + window + two handles
1640
+ below the x axis'
1641
+ - name: chart-brush-track
1642
+ description: The full-width brush rail
1643
+ - name: chart-brush-window
1644
+ description: The selected-range rect the drag moves
1645
+ - name: chart-brush-handle
1646
+ description: One draggable window edge
1647
+ states:
1648
+ - attr: data-edge
1649
+ condition: always - which edge
1650
+ values:
1651
+ - start
1652
+ - end
1653
+ - name: chart-zoom-selection
1654
+ description: 'The zoom drag-selection overlay (zoom: true), hidden until a drag
1655
+ starts'
1656
+ - name: chart-live-payload
1657
+ description: The embedded {spec, frame} JSON the live renderer recomputes geometry
1658
+ from
1659
+ - name: chart-svg
1660
+ description: The chart canvas (<svg>) - server-computed geometry in a fixed
1661
+ viewBox; role=img, or the focusable role=application accessibilityLayer when
1662
+ the tooltip attaches
1663
+ states:
1664
+ - attr: data-animate
1665
+ condition: present when animate (the default) - the motion stylesheet and
1666
+ controller key the entrance off it
1667
+ - attr: data-motion
1668
+ condition: runtime - the motion rig stamps the animation lifecycle (entrance/morph,
1669
+ then settled)
1670
+ values:
1671
+ - entrance
1672
+ - morph
1673
+ - settled
1674
+ vars:
1675
+ - name: "--poetry-motion-duration"
1676
+ description: the entrance/morph duration (animation_duration, ms)
1677
+ - name: "--poetry-motion-easing"
1678
+ description: the animation easing keyword (animation_easing)
1679
+ - name: "--poetry-motion-delay"
1680
+ description: the pre-animation hold (animation_begin, ms)
1681
+ - name: chart-grid
1682
+ description: The gridline group (with_grid) - horizontal and/or vertical rules
1683
+ across the plot
1684
+ - name: chart-cursor
1685
+ description: The hover cursor, hidden until the tooltip controller positions
1686
+ and reveals it at the active index - a vertical rule or a translucent band
1687
+ rect (bar charts)
1688
+ - name: chart-lines
1689
+ description: The line-mark group - each series' curve plus its companion marks
1690
+ - name: chart-line
1691
+ description: One series' stroked curve - pathLength=1 when animating so the
1692
+ dash draw-in needs no measurement
1693
+ states:
1694
+ - attr: data-key
1695
+ condition: the series key
1696
+ - name: chart-dots
1697
+ description: 'One series'' point-dot group (dots: true)'
1698
+ states:
1699
+ - attr: data-key
1700
+ condition: the series key
1701
+ - name: chart-dot
1702
+ description: One point dot (<circle>)
1703
+ - name: chart-error-bars
1704
+ description: One series' error-whisker group (error_key:) - cap-stem-cap paths
1705
+ in the foreground color
1706
+ states:
1707
+ - attr: data-key
1708
+ condition: the series key
1709
+ - name: chart-labels
1710
+ description: 'One series'' value-label group (labels: true)'
1711
+ states:
1712
+ - attr: data-key
1713
+ condition: the series key
1714
+ - name: chart-reference
1715
+ description: The reference-mark group (with_reference_line/_area/_dot), painted
1716
+ above the series
1717
+ - name: chart-active-dots
1718
+ description: The hover-marker group (with_tooltip) - pre-rendered hidden circles
1719
+ for every series x index
1720
+ - name: chart-active-dot
1721
+ description: One hover marker - display=none until the tooltip controller reveals
1722
+ the active index's dot
1723
+ states:
1724
+ - attr: data-key
1725
+ condition: the series key
1726
+ - attr: data-index
1727
+ condition: the datum index
1728
+ - attr: data-active
1729
+ condition: runtime - rides the marker while its index is the active one
1730
+ - name: chart-x-axis
1731
+ description: The x-axis tick-label group (with_x_axis)
1732
+ - name: chart-coordinates
1733
+ description: The embedded per-index geometry payload (<script type=application/json>)
1734
+ the tooltip controller reads - zero chart math in the browser
1735
+ stimulus:
1736
+ - element: frame
1737
+ controllers:
1738
+ - identifier: poetry--charts--tooltip
1739
+ conditional: if tooltip?
1740
+ registers: true
1741
+ values:
1742
+ - name: sync
1743
+ conditional: if
1744
+ - identifier: poetry--charts--motion
1745
+ conditional: if animate?
1746
+ registers: true
1747
+ - identifier: poetry--charts--live
1748
+ conditional: if live?
1749
+ registers: true
1750
+ actions:
1751
+ - method: receive
1752
+ 'on': poetry-chart:update
1753
+ - identifier: poetry--charts--tooltip
1754
+ conditional: if
1755
+ actions:
1756
+ - method: refresh
1757
+ 'on': poetry--charts--live:updated
1758
+ - identifier: poetry--charts--window
1759
+ conditional: if window_features?
1760
+ registers: true
1761
+ values:
1762
+ - name: zoom
1763
+ - name: plot
1764
+ - name: brush
1765
+ conditional: if
1766
+ - element: svg
1767
+ controllers:
1768
+ - identifier: poetry--charts--tooltip
1769
+ conditional: if tooltip?
1770
+ targets:
1771
+ - name: svg
1772
+ actions:
1773
+ - method: move
1774
+ 'on': pointermove
1775
+ - method: leave
1776
+ 'on': pointerleave
1777
+ - method: focus
1778
+ 'on': focus
1779
+ - method: blur
1780
+ 'on': blur
1781
+ - method: keydown
1782
+ 'on': keydown
1783
+ - identifier: poetry--charts--window
1784
+ conditional: if zoom?
1785
+ actions:
1786
+ - method: startZoom
1787
+ 'on': pointerdown
1788
+ - method: reset
1789
+ 'on': dblclick
1790
+ - element: coordinates
1791
+ controllers:
1792
+ - identifier: poetry--charts--tooltip
1793
+ conditional: if tooltip?
1794
+ targets:
1795
+ - name: data
1796
+ - element: tooltip_layer
1797
+ controllers:
1798
+ - identifier: poetry--charts--tooltip
1799
+ conditional: if tooltip?
1800
+ targets:
1801
+ - name: tooltip
1802
+ - element: live_payload
1803
+ controllers:
1804
+ - identifier: poetry--charts--live
1805
+ targets:
1806
+ - name: payload
1807
+ - element: brush
1808
+ controllers:
1809
+ - identifier: poetry--charts--window
1810
+ conditional: if
1811
+ actions:
1812
+ - method: startBrush
1813
+ 'on': pointerdown
1814
+ poetry/charts/pie_chart:
1815
+ class_name: Poetry::Charts::PieChart::Component
1816
+ identifier: poetry--charts--pie_chart
1817
+ bem_block: poetry-charts-pie_chart
1818
+ styles: []
1819
+ options:
1820
+ - name: animate
1821
+ type: boolean
1822
+ default: true
1823
+ description: Entrance animation switch - reduced-motion users always get the
1824
+ finished chart regardless.
1825
+ - name: animation_begin
1826
+ type: integer
1827
+ default: 400
1828
+ description: Pre-animation hold in milliseconds.
1829
+ - name: animation_duration
1830
+ type: integer
1831
+ default: 1500
1832
+ description: Entrance/morph duration in milliseconds.
1833
+ - name: animation_easing
1834
+ type: symbol
1835
+ default: ease
1836
+ description: Animation easing keyword (see EASINGS).
1837
+ - name: config
1838
+ type:
1839
+ required: true
1840
+ description: 'The series config - name => { label:, color: } - naming and coloring
1841
+ the slices.'
1842
+ - name: data
1843
+ type:
1844
+ description: 'Default rows for pies that don''t bring their own data: - one
1845
+ hash per slice.'
1846
+ - name: height
1847
+ type: integer
1848
+ default: 250
1849
+ description: ViewBox height in pixels.
1850
+ - name: id
1851
+ type: string
1852
+ description: Explicit DOM id token, stable across renders; otherwise the chart
1853
+ gets a unique per-render id.
1854
+ - name: label
1855
+ type: string
1856
+ description: Accessible name for the chart SVG; defaults to one built from the
1857
+ configured series.
1858
+ - name: margin
1859
+ type:
1860
+ description: 'Margin overrides ({ top:, right:, bottom:, left: }), merged over
1861
+ the slim polar default.'
1862
+ - name: sync
1863
+ type: string
1864
+ - name: width
1865
+ type: integer
1866
+ default: 250
1867
+ description: ViewBox width in pixels; the rendered chart scales to its container.
1868
+ slots:
1869
+ - name: pies
1870
+ many: true
1871
+ description: 'One ring of slices reading data_key: values and name_key: slice
1872
+ names. inner_radius: makes the donut; padding_angle: spaces the slices; active_index:
1873
+ pops one out by active_grow: pixels.'
1874
+ setter_args:
1875
+ pie: 0
1876
+ setter_kwargs:
1877
+ pie:
1878
+ - data_key
1879
+ - data
1880
+ - name_key
1881
+ - inner_radius
1882
+ - outer_radius
1883
+ - padding_angle
1884
+ - stroke_width
1885
+ - color_key
1886
+ - labels
1887
+ - label_key
1888
+ - active_index
1889
+ - active_grow
1890
+ - name: center_label
1891
+ many: false
1892
+ description: 'The donut-hole text: a title line plus an optional subtitle.'
1893
+ setter_args:
1894
+ center_label: 0
1895
+ setter_kwargs:
1896
+ center_label:
1897
+ - title
1898
+ - subtitle
1899
+ - name: legend
1900
+ many: false
1901
+ description: 'The legend row: align:, items:, and hide_icon:.'
1902
+ setter_args:
1903
+ legend: 0
1904
+ - name: tooltip
1905
+ many: false
1906
+ description: The hover tooltip; the slice name carries the label, so hide_label
1907
+ defaults on.
1908
+ setter_args:
1909
+ tooltip: 0
1910
+ description: A pie chart for showing parts of a whole.
1911
+ slot_extras:
1912
+ - py
1913
+ elements:
1914
+ - frame
1915
+ - svg
1916
+ - inside_label
1917
+ - center_title
1918
+ - center_subtitle
1919
+ capsule: 0e163387c077
1920
+ controllers:
1921
+ - identifier: poetry--charts--motion
1922
+ targets: []
1923
+ values: []
1924
+ actions: []
1925
+ events:
1926
+ - poetry--charts--motion:settled
1927
+ - identifier: poetry--charts--tooltip
1928
+ targets:
1929
+ - data
1930
+ - svg
1931
+ - tooltip
1932
+ values:
1933
+ - sync
1934
+ actions:
1935
+ - blur
1936
+ - count
1937
+ - enter
1938
+ - focus
1939
+ - keydown
1940
+ - leave
1941
+ - move
1942
+ - refresh
1943
+ - show
1944
+ events:
1945
+ - poetry--charts--tooltip:hide
1946
+ - poetry--charts--tooltip:show
1947
+ agent_rules:
1948
+ - Rows carry their slice color in a fill key (var(--color-<name>)); the config
1949
+ maps names to labels.
1950
+ - 'inner_radius: 60 makes the donut; with_center_label(title:, subtitle:) fills
1951
+ the hole.'
1952
+ - 'Stacked pies: two with_pie slots with their own data: and non-overlapping radii.'
1953
+ - 'active_index: pops one slice out by 10px (the donut-active look).'
1954
+ - The tooltip walks slices by hover AND arrow keys (role=application when attached).
1955
+ - 'Entrance animation is on by default (source parity); animate: false for a static
1956
+ chart. Reduced-motion users always get the finished chart.'
1957
+ parts:
1958
+ - name: chart-svg
1959
+ description: The chart canvas (<svg>) - the aria-label surface, the tooltip's
1960
+ focus/keyboard surface (role=application when it attaches), and the motion
1961
+ rig's mount
1962
+ states:
1963
+ - attr: data-animate
1964
+ condition: when animate (the default) - the entrance tier's flag the motion
1965
+ stylesheet and controller key off
1966
+ - attr: data-motion
1967
+ condition: runtime, when animate - the motion engine's lifecycle stamp
1968
+ values:
1969
+ - entrance
1970
+ - morph
1971
+ - settled
1972
+ vars:
1973
+ - name: "--poetry-motion-delay"
1974
+ description: the motion rig's entrance delay (animation_begin)
1975
+ - name: "--poetry-motion-duration"
1976
+ description: the motion rig's entrance duration (animation_duration)
1977
+ - name: "--poetry-motion-easing"
1978
+ description: the motion rig's easing keyword (animation_easing)
1979
+ - name: chart-pie
1980
+ description: One pie's slice group (<g>) - a ring per with_pie slot
1981
+ states:
1982
+ - attr: data-key
1983
+ condition: always - the series key
1984
+ - name: chart-pie-sector
1985
+ description: One slice (<path>) - fill from its row's color, popped out when
1986
+ active
1987
+ states:
1988
+ - attr: data-key
1989
+ condition: always - the series key
1990
+ - attr: data-index
1991
+ condition: on the first pie's slices - the datum index the tooltip walks
1992
+ - attr: data-active
1993
+ condition: the active slice - server-rendered via active_index:, and reflected
1994
+ onto the hovered/arrow-keyed index by the tooltip controller at runtime
1995
+ - attr: data-motion-group
1996
+ condition: when animate - the motion rig's sweep group (one per ring)
1997
+ - attr: data-motion-sector
1998
+ condition: when animate - the motion rig's server-computed sector params for
1999
+ the fan-out sweep
2000
+ - name: chart-labels
2001
+ description: A series' value labels (<g> of <text>, aria-hidden), rendered when
2002
+ the series opts into labels
2003
+ states:
2004
+ - attr: data-key
2005
+ condition: always - the series key
2006
+ - name: chart-center-label
2007
+ description: The center text (<text>) - title tspan plus optional subtitle filling
2008
+ the chart's middle
2009
+ - name: chart-coordinates
2010
+ description: The embedded JSON payload (<script>) the tooltip controller reads
2011
+ - per-category anchors and pre-formatted values, zero chart math in the browser
2012
+ stimulus:
2013
+ - element: frame
2014
+ controllers:
2015
+ - identifier: poetry--charts--tooltip
2016
+ conditional: if tooltip?
2017
+ registers: true
2018
+ values:
2019
+ - name: sync
2020
+ conditional: if
2021
+ - identifier: poetry--charts--motion
2022
+ conditional: if animate?
2023
+ registers: true
2024
+ - element: svg
2025
+ controllers:
2026
+ - identifier: poetry--charts--tooltip
2027
+ conditional: if tooltip?
2028
+ targets:
2029
+ - name: svg
2030
+ actions:
2031
+ - method: move
2032
+ 'on': pointermove
2033
+ - method: leave
2034
+ 'on': pointerleave
2035
+ - method: focus
2036
+ 'on': focus
2037
+ - method: blur
2038
+ 'on': blur
2039
+ - method: keydown
2040
+ 'on': keydown
2041
+ - identifier: poetry--charts--tooltip
2042
+ conditional: if tooltip?
2043
+ actions:
2044
+ - method: enter
2045
+ 'on': pointerover
2046
+ - element: coordinates
2047
+ controllers:
2048
+ - identifier: poetry--charts--tooltip
2049
+ conditional: if tooltip?
2050
+ targets:
2051
+ - name: data
2052
+ - element: tooltip_layer
2053
+ controllers:
2054
+ - identifier: poetry--charts--tooltip
2055
+ conditional: if tooltip?
2056
+ targets:
2057
+ - name: tooltip
2058
+ poetry/charts/radar_chart:
2059
+ class_name: Poetry::Charts::RadarChart::Component
2060
+ identifier: poetry--charts--radar_chart
2061
+ bem_block: poetry-charts-radar_chart
2062
+ styles: []
2063
+ options:
2064
+ - name: animate
2065
+ type: boolean
2066
+ default: true
2067
+ description: Entrance animation switch - reduced-motion users always get the
2068
+ finished chart regardless.
2069
+ - name: animation_begin
2070
+ type: integer
2071
+ default: 0
2072
+ description: Pre-animation hold in milliseconds.
2073
+ - name: animation_duration
2074
+ type: integer
2075
+ default: 1500
2076
+ description: Entrance/morph duration in milliseconds.
2077
+ - name: animation_easing
2078
+ type: symbol
2079
+ default: ease
2080
+ description: Animation easing keyword (see EASINGS).
2081
+ - name: config
2082
+ type:
2083
+ required: true
2084
+ description: 'The series config - key => { label:, color: } - naming and coloring
2085
+ every series.'
2086
+ - name: data
2087
+ type:
2088
+ required: true
2089
+ description: 'The rows to plot: an array of hashes, one per category.'
2090
+ - name: height
2091
+ type: integer
2092
+ default: 250
2093
+ description: ViewBox height in pixels.
2094
+ - name: id
2095
+ type: string
2096
+ description: Explicit DOM id token, stable across renders; otherwise the chart
2097
+ gets a unique per-render id.
2098
+ - name: label
2099
+ type: string
2100
+ description: Accessible name for the chart SVG; defaults to one built from the
2101
+ configured series.
2102
+ - name: margin
2103
+ type:
2104
+ description: 'Margin overrides ({ top:, right:, bottom:, left: }), merged over
2105
+ the slim polar default.'
2106
+ - name: outer_radius
2107
+ type:
2108
+ default: 80%
2109
+ description: 'The rim radius: a percent string of the max radius, or pixels.'
2110
+ - name: sync
2111
+ type: string
2112
+ - name: width
2113
+ type: integer
2114
+ default: 250
2115
+ description: ViewBox width in pixels; the rendered chart scales to its container.
2116
+ slots:
2117
+ - name: radars
2118
+ many: true
2119
+ description: 'A radar series bound to data_key:. fill_opacity: 0 with stroke_width:
2120
+ 2 draws lines only; dots: marks every vertex.'
2121
+ setter_args:
2122
+ radar: 0
2123
+ setter_kwargs:
2124
+ radar:
2125
+ - data_key
2126
+ - fill_opacity
2127
+ - stroke_width
2128
+ - dots
2129
+ - dot_radius
2130
+ - name: angle_axis
2131
+ many: false
2132
+ description: 'The category labels around the rim: data_key: names the field;
2133
+ tick_formatter: reshapes each label.'
2134
+ setter_args:
2135
+ angle_axis: 0
2136
+ setter_kwargs:
2137
+ angle_axis:
2138
+ - data_key
2139
+ - tick_formatter
2140
+ - name: grid
2141
+ many: false
2142
+ description: 'The polar grid: type: :circle swaps polygons for circles; radial_lines:
2143
+ false drops the spokes; fill: tints every ring with a series color at opacity:.'
2144
+ setter_args:
2145
+ grid: 0
2146
+ setter_kwargs:
2147
+ grid:
2148
+ - type
2149
+ - radial_lines
2150
+ - fill
2151
+ - opacity
2152
+ - name: legend
2153
+ many: false
2154
+ description: 'The legend row: align:, items:, and hide_icon:.'
2155
+ setter_args:
2156
+ legend: 0
2157
+ - name: tooltip
2158
+ many: false
2159
+ description: The hover tooltip - multi-series rows under the category label.
2160
+ setter_args:
2161
+ tooltip: 0
2162
+ description: A radar chart for comparing several variables on radial axes.
2163
+ elements:
2164
+ - frame
2165
+ - svg
2166
+ - grid_line
2167
+ - grid_fill
2168
+ - tick
2169
+ capsule: e07db6d1050e
2170
+ controllers:
2171
+ - identifier: poetry--charts--motion
2172
+ targets: []
2173
+ values: []
2174
+ actions: []
2175
+ events:
2176
+ - poetry--charts--motion:settled
2177
+ - identifier: poetry--charts--tooltip
2178
+ targets:
2179
+ - data
2180
+ - svg
2181
+ - tooltip
2182
+ values:
2183
+ - sync
2184
+ actions:
2185
+ - blur
2186
+ - count
2187
+ - enter
2188
+ - focus
2189
+ - keydown
2190
+ - leave
2191
+ - move
2192
+ - refresh
2193
+ - show
2194
+ events:
2195
+ - poetry--charts--tooltip:hide
2196
+ - poetry--charts--tooltip:show
2197
+ agent_rules:
2198
+ - 'Compose from slots: with_angle_axis(data_key:) / with_grid / with_radar(data_key:)
2199
+ / with_legend.'
2200
+ - 'Radars fill at 0.6 opacity by default; lines-only = fill_opacity: 0, stroke_width:
2201
+ 2.'
2202
+ - 'with_grid type: :circle swaps polygons for circles; fill: :desktop tints every
2203
+ grid ring (opacity 0.2, compounding toward the center - the grid-fill look).'
2204
+ - 'dots: true marks every vertex (r 4, solid).'
2205
+ - Colors come from the config - never set fill/stroke on a radar directly.
2206
+ - 'Entrance animation is on by default (source parity); animate: false for a static
2207
+ chart. Reduced-motion users always get the finished chart.'
2208
+ parts:
2209
+ - name: chart-svg
2210
+ description: The chart canvas (<svg>) - the aria-label surface, the tooltip's
2211
+ focus/keyboard surface (role=application when it attaches), and the motion
2212
+ rig's mount
2213
+ states:
2214
+ - attr: data-animate
2215
+ condition: when animate (the default) - the entrance tier's flag the motion
2216
+ stylesheet and controller key off
2217
+ - attr: data-motion
2218
+ condition: runtime, when animate - the motion engine's lifecycle stamp
2219
+ values:
2220
+ - entrance
2221
+ - morph
2222
+ - settled
2223
+ vars:
2224
+ - name: "--poetry-motion-delay"
2225
+ description: the motion rig's entrance delay (animation_begin)
2226
+ - name: "--poetry-motion-duration"
2227
+ description: the motion rig's entrance duration (animation_duration)
2228
+ - name: "--poetry-motion-easing"
2229
+ description: the motion rig's easing keyword (animation_easing)
2230
+ - name: "--poetry-motion-center"
2231
+ description: the polar center the CSS entrance scales the series from
2232
+ - name: chart-polar-grid
2233
+ description: The polar grid (<g>, aria-hidden) - ring and spoke linework behind
2234
+ the series
2235
+ - name: chart-radars
2236
+ description: The series layer (<g>) - every radar polygon renders here; the
2237
+ CSS entrance scales this group from the polar center
2238
+ - name: chart-radar
2239
+ description: One series' closed polygon (<path>) - config color, 0.6 fill by
2240
+ default
2241
+ states:
2242
+ - attr: data-key
2243
+ condition: always - the series key
2244
+ - name: chart-dots
2245
+ description: 'A series'' vertex dots (<g>), rendered when dots: true'
2246
+ states:
2247
+ - attr: data-key
2248
+ condition: always - the series key
2249
+ - name: chart-dot
2250
+ description: One vertex dot (<circle>) - solid, at the series color
2251
+ - name: chart-angle-axis
2252
+ description: The category labels around the rim (<g> of <text>)
2253
+ - name: chart-hit-wedges
2254
+ description: The tooltip's hit layer (<g>), rendered when the tooltip attaches
2255
+ - name: chart-hit-wedge
2256
+ description: One per-category hit wedge (<path>, transparent but painted so
2257
+ it hit-tests) - the tooltip's hover target
2258
+ states:
2259
+ - attr: data-index
2260
+ condition: always - the datum index
2261
+ - attr: data-active
2262
+ condition: the hovered/arrow-keyed category - the tooltip controller reflects
2263
+ the active index here at runtime
2264
+ - name: chart-coordinates
2265
+ description: The embedded JSON payload (<script>) the tooltip controller reads
2266
+ - per-category anchors and pre-formatted values, zero chart math in the browser
2267
+ stimulus:
2268
+ - element: frame
2269
+ controllers:
2270
+ - identifier: poetry--charts--tooltip
2271
+ conditional: if tooltip?
2272
+ registers: true
2273
+ values:
2274
+ - name: sync
2275
+ conditional: if
2276
+ - identifier: poetry--charts--motion
2277
+ conditional: if animate?
2278
+ registers: true
2279
+ - element: svg
2280
+ controllers:
2281
+ - identifier: poetry--charts--tooltip
2282
+ conditional: if tooltip?
2283
+ targets:
2284
+ - name: svg
2285
+ actions:
2286
+ - method: move
2287
+ 'on': pointermove
2288
+ - method: leave
2289
+ 'on': pointerleave
2290
+ - method: focus
2291
+ 'on': focus
2292
+ - method: blur
2293
+ 'on': blur
2294
+ - method: keydown
2295
+ 'on': keydown
2296
+ - identifier: poetry--charts--tooltip
2297
+ conditional: if tooltip?
2298
+ actions:
2299
+ - method: enter
2300
+ 'on': pointerover
2301
+ - element: coordinates
2302
+ controllers:
2303
+ - identifier: poetry--charts--tooltip
2304
+ conditional: if tooltip?
2305
+ targets:
2306
+ - name: data
2307
+ - element: tooltip_layer
2308
+ controllers:
2309
+ - identifier: poetry--charts--tooltip
2310
+ conditional: if tooltip?
2311
+ targets:
2312
+ - name: tooltip
2313
+ poetry/charts/radial_bar_chart:
2314
+ class_name: Poetry::Charts::RadialBarChart::Component
2315
+ identifier: poetry--charts--radial_bar_chart
2316
+ bem_block: poetry-charts-radial_bar_chart
2317
+ styles: []
2318
+ options:
2319
+ - name: animate
2320
+ type: boolean
2321
+ default: true
2322
+ description: Entrance animation switch - reduced-motion users always get the
2323
+ finished chart regardless.
2324
+ - name: animation_begin
2325
+ type: integer
2326
+ default: 0
2327
+ description: Pre-animation hold in milliseconds.
2328
+ - name: animation_duration
2329
+ type: integer
2330
+ default: 1500
2331
+ description: Entrance/morph duration in milliseconds.
2332
+ - name: animation_easing
2333
+ type: symbol
2334
+ default: ease
2335
+ description: Animation easing keyword (see EASINGS).
2336
+ - name: config
2337
+ type:
2338
+ required: true
2339
+ description: 'The series config - name => { label:, color: } - naming and coloring
2340
+ the rings.'
2341
+ - name: data
2342
+ type:
2343
+ required: true
2344
+ description: 'The rows to plot: an array of hashes, one ring per row.'
2345
+ - name: end_angle
2346
+ type: integer
2347
+ default: 360
2348
+ description: Where the sweep ends - 180 makes a half gauge.
2349
+ - name: height
2350
+ type: integer
2351
+ default: 250
2352
+ description: ViewBox height in pixels.
2353
+ - name: id
2354
+ type: string
2355
+ description: Explicit DOM id token, stable across renders; otherwise the chart
2356
+ gets a unique per-render id.
2357
+ - name: inner_radius
2358
+ type:
2359
+ default: 20%
2360
+ description: 'The innermost ring edge: a percent string of the max radius, or
2361
+ pixels.'
2362
+ - name: label
2363
+ type: string
2364
+ description: Accessible name for the chart SVG; defaults to one built from the
2365
+ configured series.
2366
+ - name: margin
2367
+ type:
2368
+ description: 'Margin overrides ({ top:, right:, bottom:, left: }), merged over
2369
+ the slim polar default.'
2370
+ - name: max_value
2371
+ type:
2372
+ description: 'The angle-axis maximum: nil = the largest single value, so the
2373
+ largest ring closes the full sweep EXACTLY (nicing it would leave a notch);
2374
+ stacked gauges pass the stack total when the segments should fill the span.'
2375
+ - name: name_key
2376
+ type: string
2377
+ default: name
2378
+ description: The row key naming each ring.
2379
+ - name: outer_radius
2380
+ type:
2381
+ default: 80%
2382
+ description: 'The outermost ring edge: a percent string of the max radius, or
2383
+ pixels.'
2384
+ - name: start_angle
2385
+ type: integer
2386
+ default: 0
2387
+ description: Where the sweep starts, in degrees.
2388
+ - name: sync
2389
+ type: string
2390
+ - name: width
2391
+ type: integer
2392
+ default: 250
2393
+ description: ViewBox width in pixels; the rendered chart scales to its container.
2394
+ slots:
2395
+ - name: radial_bars
2396
+ many: true
2397
+ description: 'A radial series reading data_key: values. background: draws the
2398
+ muted track ring; bars sharing a stack: id share the ring and stack by angle;
2399
+ corner_radius: rounds the arc ends.'
2400
+ setter_args:
2401
+ radial_bar: 0
2402
+ setter_kwargs:
2403
+ radial_bar:
2404
+ - data_key
2405
+ - stack
2406
+ - background
2407
+ - corner_radius
2408
+ - color_key
2409
+ - labels
2410
+ - label_key
2411
+ - name: polar_grid
2412
+ many: false
2413
+ description: 'The disc track behind the rings: radii: places the circles (default:
2414
+ each ring''s centerline), fills: tints them, and radial_lines: draws the faint
2415
+ value spokes that show through ring gaps and the open wedge (on by default;
2416
+ gauges turn them off).'
2417
+ setter_args:
2418
+ polar_grid: 0
2419
+ setter_kwargs:
2420
+ polar_grid:
2421
+ - radii
2422
+ - fills
2423
+ - radial_lines
2424
+ - name: center_label
2425
+ many: false
2426
+ description: 'The center text: a title line plus an optional subtitle. The default
2427
+ is the full gauge''s big centered number; compact: shrinks it and sits it
2428
+ just above a half gauge''s flat baseline.'
2429
+ setter_args:
2430
+ center_label: 0
2431
+ setter_kwargs:
2432
+ center_label:
2433
+ - title
2434
+ - subtitle
2435
+ - compact
2436
+ - name: legend
2437
+ many: false
2438
+ description: 'The legend row: align:, items:, and hide_icon:.'
2439
+ setter_args:
2440
+ legend: 0
2441
+ - name: tooltip
2442
+ many: false
2443
+ description: The hover tooltip; the ring name carries the label, so hide_label
2444
+ defaults on.
2445
+ setter_args:
2446
+ tooltip: 0
2447
+ description: A radial bar chart with bars wrapped around a circular axis.
2448
+ elements:
2449
+ - frame
2450
+ - svg
2451
+ - background_ring
2452
+ - grid_circle
2453
+ - grid_fill_muted
2454
+ - grid_fill_background
2455
+ - inside_label
2456
+ - center_title
2457
+ - center_title_compact
2458
+ - center_subtitle
2459
+ capsule: 753933f16121
2460
+ controllers:
2461
+ - identifier: poetry--charts--motion
2462
+ targets: []
2463
+ values: []
2464
+ actions: []
2465
+ events:
2466
+ - poetry--charts--motion:settled
2467
+ - identifier: poetry--charts--tooltip
2468
+ targets:
2469
+ - data
2470
+ - svg
2471
+ - tooltip
2472
+ values:
2473
+ - sync
2474
+ actions:
2475
+ - blur
2476
+ - count
2477
+ - enter
2478
+ - focus
2479
+ - keydown
2480
+ - leave
2481
+ - move
2482
+ - refresh
2483
+ - show
2484
+ events:
2485
+ - poetry--charts--tooltip:hide
2486
+ - poetry--charts--tooltip:show
2487
+ agent_rules:
2488
+ - One ring per data row; rows carry their color in a fill key (var(--color-<name>)).
2489
+ - 'background: true draws the muted track ring behind each bar (the gauge look).'
2490
+ - 'Stack two radial bars with the same stack: id - they share the ring and stack
2491
+ by ANGLE.'
2492
+ - corner_radius rounds the arc ends (10 on a 10px ring = full pill caps).
2493
+ - with_polar_grid(radii:, fills:) draws the shape/text blocks' disc track; with_center_label
2494
+ fills the middle.
2495
+ - 'Entrance animation is on by default (source parity); animate: false for a static
2496
+ chart. Reduced-motion users always get the finished chart.'
2497
+ parts:
2498
+ - name: chart-svg
2499
+ description: The chart canvas (<svg>) - the aria-label surface, the tooltip's
2500
+ focus/keyboard surface (role=application when it attaches), and the motion
2501
+ rig's mount
2502
+ states:
2503
+ - attr: data-animate
2504
+ condition: when animate (the default) - the entrance tier's flag the motion
2505
+ stylesheet and controller key off
2506
+ - attr: data-motion
2507
+ condition: runtime, when animate - the motion engine's lifecycle stamp
2508
+ values:
2509
+ - entrance
2510
+ - morph
2511
+ - settled
2512
+ vars:
2513
+ - name: "--poetry-motion-delay"
2514
+ description: the motion rig's entrance delay (animation_begin)
2515
+ - name: "--poetry-motion-duration"
2516
+ description: the motion rig's entrance duration (animation_duration)
2517
+ - name: "--poetry-motion-easing"
2518
+ description: the motion rig's easing keyword (animation_easing)
2519
+ - name: chart-polar-grid
2520
+ description: The polar grid (<g>, aria-hidden) - ring and spoke linework behind
2521
+ the series
2522
+ - name: chart-radial-series
2523
+ description: One series' ring group (<g>)
2524
+ states:
2525
+ - attr: data-key
2526
+ condition: always - the series key
2527
+ - name: chart-radial-background
2528
+ description: 'The muted track ring (<path>) behind a bar, rendered when background:
2529
+ true'
2530
+ - name: chart-radial-bar
2531
+ description: One angular bar (<path>) - a ring per data row, sweep proportional
2532
+ to value
2533
+ states:
2534
+ - attr: data-key
2535
+ condition: always - the series key
2536
+ - attr: data-index
2537
+ condition: on the first series' bars - the datum index the tooltip walks
2538
+ - attr: data-active
2539
+ condition: the hovered/arrow-keyed bar - the tooltip controller reflects the
2540
+ active index here at runtime
2541
+ - attr: data-motion-group
2542
+ condition: when animate - the motion rig's sweep group (one per ring)
2543
+ - attr: data-motion-sector
2544
+ condition: when animate - the motion rig's server-computed sector params for
2545
+ the fan-out sweep
2546
+ - name: chart-labels
2547
+ description: A series' value labels (<g> of <text>, aria-hidden), rendered when
2548
+ the series opts into labels
2549
+ states:
2550
+ - attr: data-key
2551
+ condition: always - the series key
2552
+ - name: chart-center-label
2553
+ description: The center text (<text>) - title tspan plus optional subtitle filling
2554
+ the chart's middle
2555
+ - name: chart-coordinates
2556
+ description: The embedded JSON payload (<script>) the tooltip controller reads
2557
+ - per-category anchors and pre-formatted values, zero chart math in the browser
2558
+ stimulus:
2559
+ - element: frame
2560
+ controllers:
2561
+ - identifier: poetry--charts--tooltip
2562
+ conditional: if tooltip?
2563
+ registers: true
2564
+ values:
2565
+ - name: sync
2566
+ conditional: if
2567
+ - identifier: poetry--charts--motion
2568
+ conditional: if animate?
2569
+ registers: true
2570
+ - element: svg
2571
+ controllers:
2572
+ - identifier: poetry--charts--tooltip
2573
+ conditional: if tooltip?
2574
+ targets:
2575
+ - name: svg
2576
+ actions:
2577
+ - method: move
2578
+ 'on': pointermove
2579
+ - method: leave
2580
+ 'on': pointerleave
2581
+ - method: focus
2582
+ 'on': focus
2583
+ - method: blur
2584
+ 'on': blur
2585
+ - method: keydown
2586
+ 'on': keydown
2587
+ - identifier: poetry--charts--tooltip
2588
+ conditional: if tooltip?
2589
+ actions:
2590
+ - method: enter
2591
+ 'on': pointerover
2592
+ - element: coordinates
2593
+ controllers:
2594
+ - identifier: poetry--charts--tooltip
2595
+ conditional: if tooltip?
2596
+ targets:
2597
+ - name: data
2598
+ - element: tooltip_layer
2599
+ controllers:
2600
+ - identifier: poetry--charts--tooltip
2601
+ conditional: if tooltip?
2602
+ targets:
2603
+ - name: tooltip
2604
+ poetry/charts/scatter_chart:
2605
+ class_name: Poetry::Charts::ScatterChart::Component
2606
+ identifier: poetry--charts--scatter_chart
2607
+ bem_block: poetry-charts-scatter_chart
2608
+ styles: []
2609
+ options:
2610
+ - name: animate
2611
+ type: boolean
2612
+ default: true
2613
+ description: Entrance animation switch - reduced-motion users always get the
2614
+ finished chart regardless.
2615
+ - name: animation_begin
2616
+ type: integer
2617
+ default: 0
2618
+ description: Pre-animation hold in milliseconds.
2619
+ - name: animation_duration
2620
+ type: integer
2621
+ default: 400
2622
+ description: Entrance/morph duration in milliseconds.
2623
+ - name: animation_easing
2624
+ type: symbol
2625
+ default: linear
2626
+ description: Animation easing keyword (see EASINGS).
2627
+ - name: config
2628
+ type:
2629
+ required: true
2630
+ description: 'The series config - key => { label:, color: } - naming and coloring
2631
+ every series.'
2632
+ - name: data
2633
+ type:
2634
+ description: 'Default rows for series that don''t bring their own data: - one
2635
+ hash per point.'
2636
+ - name: height
2637
+ type: integer
2638
+ default: 360
2639
+ description: ViewBox height in pixels.
2640
+ - name: id
2641
+ type: string
2642
+ description: Explicit DOM id token, stable across renders; otherwise the chart
2643
+ gets a unique per-render id.
2644
+ - name: label
2645
+ type: string
2646
+ description: Accessible name for the chart SVG; defaults to one built from the
2647
+ configured series.
2648
+ - name: margin
2649
+ type:
2650
+ description: 'Plot margin overrides ({ top:, right:, bottom:, left: }), merged
2651
+ over the defaults.'
2652
+ - name: sync
2653
+ type: string
2654
+ - name: width
2655
+ type: integer
2656
+ default: 640
2657
+ description: ViewBox width in pixels; the rendered chart scales to its container.
2658
+ slots:
2659
+ - name: reference_lines
2660
+ many: true
2661
+ setter_args:
2662
+ reference_line: 0
2663
+ setter_kwargs:
2664
+ reference_line:
2665
+ - x
2666
+ - "y"
2667
+ - label
2668
+ - stroke_dasharray
2669
+ - name: reference_areas
2670
+ many: true
2671
+ setter_args:
2672
+ reference_area: 0
2673
+ setter_kwargs:
2674
+ reference_area:
2675
+ - x1
2676
+ - x2
2677
+ - y1
2678
+ - y2
2679
+ - label
2680
+ - fill_opacity
2681
+ - name: reference_dots
2682
+ many: true
2683
+ setter_args:
2684
+ reference_dot: 0
2685
+ setter_kwargs:
2686
+ reference_dot:
2687
+ - x
2688
+ - "y"
2689
+ - r
2690
+ - label
2691
+ - name: scatters
2692
+ many: true
2693
+ description: 'A point series colored by key:. data: gives it its own rows; error_key:
2694
+ adds error whiskers.'
2695
+ setter_args:
2696
+ scatter: 0
2697
+ setter_kwargs:
2698
+ scatter:
2699
+ - key
2700
+ - data
2701
+ - error_key
2702
+ - error_width
2703
+ - name: x_axis
2704
+ many: false
2705
+ description: 'The numeric x axis: data_key: names the row key to plot; name:
2706
+ labels its tooltip row.'
2707
+ setter_args:
2708
+ x_axis: 0
2709
+ setter_kwargs:
2710
+ x_axis:
2711
+ - data_key
2712
+ - tick_count
2713
+ - tick_margin
2714
+ - name
2715
+ - name: y_axis
2716
+ many: false
2717
+ description: 'The numeric y axis: data_key: names the row key to plot; name:
2718
+ labels its tooltip row.'
2719
+ setter_args:
2720
+ y_axis: 0
2721
+ setter_kwargs:
2722
+ y_axis:
2723
+ - data_key
2724
+ - tick_count
2725
+ - tick_margin
2726
+ - name
2727
+ - name: z_axis
2728
+ many: false
2729
+ description: 'A third dimension sizing the markers: range: is marker AREA in
2730
+ px2 mapped linearly from the data_key: values.'
2731
+ setter_args:
2732
+ z_axis: 0
2733
+ setter_kwargs:
2734
+ z_axis:
2735
+ - data_key
2736
+ - range
2737
+ - name: grid
2738
+ many: false
2739
+ description: 'The gridlines: both directions by default.'
2740
+ setter_args:
2741
+ grid: 0
2742
+ setter_kwargs:
2743
+ grid:
2744
+ - vertical
2745
+ - horizontal
2746
+ - name: legend
2747
+ many: false
2748
+ description: 'The legend row: align:, items:, and hide_icon:.'
2749
+ setter_args:
2750
+ legend: 0
2751
+ - name: tooltip
2752
+ many: false
2753
+ description: The hover tooltip - per-point x/y(/z) rows under the series name.
2754
+ setter_args:
2755
+ tooltip: 0
2756
+ description: A scatter chart for the relationship between two variables.
2757
+ elements:
2758
+ - frame
2759
+ - svg
2760
+ - grid_line
2761
+ - tick
2762
+ - reference_line
2763
+ - reference_area
2764
+ - reference_dot
2765
+ - error_bar
2766
+ capsule: 132a5aba612e
2767
+ controllers:
2768
+ - identifier: poetry--charts--motion
2769
+ targets: []
2770
+ values: []
2771
+ actions: []
2772
+ events:
2773
+ - poetry--charts--motion:settled
2774
+ - identifier: poetry--charts--tooltip
2775
+ targets:
2776
+ - data
2777
+ - svg
2778
+ - tooltip
2779
+ values:
2780
+ - sync
2781
+ actions:
2782
+ - blur
2783
+ - count
2784
+ - enter
2785
+ - focus
2786
+ - keydown
2787
+ - leave
2788
+ - move
2789
+ - refresh
2790
+ - show
2791
+ events:
2792
+ - poetry--charts--tooltip:hide
2793
+ - poetry--charts--tooltip:show
2794
+ agent_rules:
2795
+ - 'Both axes are numeric: with_x_axis(data_key:) / with_y_axis(data_key:) name
2796
+ the row keys to plot.'
2797
+ - 'with_scatter(key:) colors points var(--color-<key>); data: gives a series its
2798
+ own rows.'
2799
+ - 'with_z_axis(data_key:, range: [64, 144]) sizes points by a third dimension
2800
+ - the range is marker AREA in px2 (the source''s z-axis contract).'
2801
+ - The tooltip hits per point and shows the x/y(/z) values with the series color.
2802
+ - 'Entrance animation is on by default (400ms linear, source-exact); animate:
2803
+ false for a static chart.'
2804
+ parts:
2805
+ - name: chart-svg
2806
+ description: The chart canvas (<svg>) - server-computed geometry in a fixed
2807
+ viewBox; role=img, or the focusable role=application accessibilityLayer when
2808
+ the tooltip attaches
2809
+ states:
2810
+ - attr: data-animate
2811
+ condition: present when animate (the default) - the motion stylesheet and
2812
+ controller key the entrance off it
2813
+ - attr: data-motion
2814
+ condition: runtime - the motion rig stamps the animation lifecycle (entrance/morph,
2815
+ then settled)
2816
+ values:
2817
+ - entrance
2818
+ - morph
2819
+ - settled
2820
+ vars:
2821
+ - name: "--poetry-motion-duration"
2822
+ description: the entrance/morph duration (animation_duration, ms)
2823
+ - name: "--poetry-motion-easing"
2824
+ description: the animation easing keyword (animation_easing)
2825
+ - name: "--poetry-motion-delay"
2826
+ description: the pre-animation hold (animation_begin, ms)
2827
+ - name: chart-grid
2828
+ description: The gridline group (with_grid) - horizontal and/or vertical rules
2829
+ across the plot
2830
+ - name: chart-scatters
2831
+ description: The scatter-mark group - every series' points flattened with a
2832
+ global index
2833
+ - name: chart-scatter-point
2834
+ description: One data point (<circle>) - r carries the z-axis area sizing
2835
+ states:
2836
+ - attr: data-key
2837
+ condition: the series key
2838
+ - attr: data-index
2839
+ condition: the point's global index across every series
2840
+ - attr: data-active
2841
+ condition: runtime - the tooltip controller marks the hovered point
2842
+ - name: chart-error-bars
2843
+ description: One series' error-whisker group (error_key:) - cap-stem-cap paths
2844
+ in the foreground color
2845
+ states:
2846
+ - attr: data-key
2847
+ condition: the series key
2848
+ - name: chart-reference
2849
+ description: The reference-mark group (with_reference_line/_area/_dot), painted
2850
+ above the series
2851
+ - name: chart-x-axis
2852
+ description: The x-axis tick-label group (with_x_axis)
2853
+ - name: chart-y-axis
2854
+ description: The y-axis tick-label group (with_y_axis)
2855
+ - name: chart-coordinates
2856
+ description: The embedded per-index geometry payload (<script type=application/json>)
2857
+ the tooltip controller reads - zero chart math in the browser
2858
+ stimulus:
2859
+ - element: frame
2860
+ controllers:
2861
+ - identifier: poetry--charts--tooltip
2862
+ conditional: if tooltip?
2863
+ registers: true
2864
+ values:
2865
+ - name: sync
2866
+ conditional: if
2867
+ - identifier: poetry--charts--motion
2868
+ conditional: if animate?
2869
+ registers: true
2870
+ - element: svg
2871
+ controllers:
2872
+ - identifier: poetry--charts--tooltip
2873
+ conditional: if tooltip?
2874
+ targets:
2875
+ - name: svg
2876
+ actions:
2877
+ - method: move
2878
+ 'on': pointermove
2879
+ - method: leave
2880
+ 'on': pointerleave
2881
+ - method: focus
2882
+ 'on': focus
2883
+ - method: blur
2884
+ 'on': blur
2885
+ - method: keydown
2886
+ 'on': keydown
2887
+ - identifier: poetry--charts--tooltip
2888
+ conditional: if tooltip?
2889
+ actions:
2890
+ - method: enter
2891
+ 'on': pointerover
2892
+ - element: coordinates
2893
+ controllers:
2894
+ - identifier: poetry--charts--tooltip
2895
+ conditional: if tooltip?
2896
+ targets:
2897
+ - name: data
2898
+ - element: tooltip_layer
2899
+ controllers:
2900
+ - identifier: poetry--charts--tooltip
2901
+ conditional: if tooltip?
2902
+ targets:
2903
+ - name: tooltip
2904
+ poetry/charts/tooltip_content:
2905
+ class_name: Poetry::Charts::TooltipContent::Component
2906
+ identifier: poetry--charts--tooltip_content
2907
+ bem_block: poetry-charts-tooltip_content
2908
+ styles: []
2909
+ options:
2910
+ - name: config
2911
+ type:
2912
+ required: true
2913
+ description: 'The series config - key => { label:, color: } - resolving row
2914
+ names and colors.'
2915
+ - name: hide_indicator
2916
+ type: boolean
2917
+ default: false
2918
+ description: Hides the row swatches.
2919
+ - name: hide_label
2920
+ type: boolean
2921
+ default: false
2922
+ description: Hides the category label.
2923
+ - name: indicator
2924
+ type: symbol
2925
+ variants:
2926
+ - dot
2927
+ - line
2928
+ - dashed
2929
+ default: dot
2930
+ description: The row swatch shape.
2931
+ - name: items
2932
+ type:
2933
+ required: true
2934
+ description: 'The rows: [{ key:, name:, value:, color: }] hashes, one per series.'
2935
+ - name: label
2936
+ type: string
2937
+ description: The category label above the rows, resolved through the config.
2938
+ slots: []
2939
+ elements:
2940
+ - label
2941
+ - inner
2942
+ - row
2943
+ - row_dot
2944
+ - indicator
2945
+ - indicator_dot
2946
+ - indicator_line
2947
+ - indicator_dashed
2948
+ - indicator_dashed_nested
2949
+ - value_wrap
2950
+ - value_wrap_center
2951
+ - value_wrap_end
2952
+ - name
2953
+ - value
2954
+ capsule: 74b8c24f20d2
2955
+ agent_rules:
2956
+ - Tooltip rows resolve names/colors through the chart config - pass key:, not
2957
+ a display string.
2958
+ - 'indicator: :dot (default) | :line | :dashed matches the ported variants.'
2959
+ - Numeric values render delimited (1,234) in the mono tabular column automatically.
2960
+ identity: false
2961
+ parts:
2962
+ - name: chart-tooltip-content
2963
+ description: The tooltip box (<div>) - the styled chrome the chart's tooltip
2964
+ controller positions and text-swaps
2965
+ - name: chart-tooltip-label
2966
+ description: The category label (<div>) - above the rows, or nested inside the
2967
+ single row for line/dashed indicators
2968
+ - name: chart-tooltip-item
2969
+ description: One series row (<div>) - indicator + name + value
2970
+ states:
2971
+ - attr: data-key
2972
+ condition: always - the series key the controller matches values by
2973
+ - name: chart-tooltip-indicator
2974
+ description: The row's swatch (<div>) - dot/line/dashed per indicator:, hidden
2975
+ with hide_indicator
2976
+ vars:
2977
+ - name: "--color-bg"
2978
+ description: the swatch fill - carries the row's series color (inline; polar
2979
+ charts retint it to the hovered slice's color at runtime)
2980
+ - name: "--color-border"
2981
+ description: the swatch border - the same series color as the fill
2982
+ - name: chart-tooltip-name
2983
+ description: The series name (<span>) - resolved through the chart config
2984
+ - name: chart-tooltip-value
2985
+ description: The formatted value (<span>) - the mono tabular column, numbers
2986
+ delimited
2987
+ poetry/charts/tooltip_layer:
2988
+ class_name: Poetry::Charts::TooltipLayer::Component
2989
+ identifier: poetry--charts--tooltip_layer
2990
+ bem_block: poetry-charts-tooltip_layer
2991
+ styles: []
2992
+ options:
2993
+ - name: config
2994
+ type:
2995
+ required: true
2996
+ description: 'The series config - key => { label:, color: } - resolving row
2997
+ names and colors.'
2998
+ - name: hide_indicator
2999
+ type: boolean
3000
+ default: false
3001
+ description: Hides the row swatches.
3002
+ - name: hide_label
3003
+ type: boolean
3004
+ default: false
3005
+ description: Hides the category label.
3006
+ - name: indicator
3007
+ type: symbol
3008
+ default: dot
3009
+ description: The row swatch shape.
3010
+ - name: series_keys
3011
+ type:
3012
+ required: true
3013
+ description: The series keys to pre-render rows for.
3014
+ slots: []
3015
+ elements: []
3016
+ capsule: 3aa9cd90e2e1
3017
+ controllers:
3018
+ - identifier: poetry--charts--tooltip
3019
+ targets:
3020
+ - data
3021
+ - svg
3022
+ - tooltip
3023
+ values:
3024
+ - sync
3025
+ actions:
3026
+ - blur
3027
+ - count
3028
+ - enter
3029
+ - focus
3030
+ - keydown
3031
+ - leave
3032
+ - move
3033
+ - refresh
3034
+ - show
3035
+ events:
3036
+ - poetry--charts--tooltip:hide
3037
+ - poetry--charts--tooltip:show
3038
+ identity: false
3039
+ stimulus:
3040
+ - element: root
3041
+ controllers:
3042
+ - identifier: poetry--charts--tooltip
3043
+ targets:
3044
+ - name: tooltip
3045
+ helpers:
3046
+ poetry_chart:
3047
+ yields: the dispatched chart component
3048
+ helper_args:
3049
+ poetry_area_chart: 0
3050
+ poetry_bar_chart: 0
3051
+ poetry_chart: 1
3052
+ poetry_chart_container: 0
3053
+ poetry_chart_legend_content: 0
3054
+ poetry_chart_tooltip_content: 0
3055
+ poetry_line_chart: 0