@fundar/data-chart-telling 1.17.0 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/configuration/config.svelte.js +3 -2
  3. package/dist/index.d.ts +7 -2
  4. package/dist/index.js +2 -0
  5. package/dist/layout/geometry/GeometryLayout.svelte +188 -54
  6. package/dist/layout/hover/HoverDefaults.d.ts +52 -0
  7. package/dist/layout/hover/HoverDefaults.js +96 -0
  8. package/dist/layout/hover/HoverLayers.d.ts +35 -0
  9. package/dist/layout/hover/HoverLayers.js +122 -0
  10. package/dist/layout/hover/HoverSettings.d.ts +1 -3
  11. package/dist/layout/hover/HoverSettings.js +3 -2
  12. package/dist/layout/hover/HoverShapes.d.ts +44 -0
  13. package/dist/layout/hover/HoverShapes.js +103 -0
  14. package/dist/layout/hover/PlotHover.svelte.d.ts +18 -0
  15. package/dist/layout/hover/PlotHover.svelte.js +54 -1
  16. package/dist/layout/legend/LegendState.svelte.d.ts +2 -0
  17. package/dist/layout/legend/LegendState.svelte.js +5 -0
  18. package/dist/layout/plot/Core.svelte +2 -2
  19. package/dist/layout/plot/PublicPlotContext.d.ts +6 -0
  20. package/dist/layout/plot/PublicPlotContext.js +8 -0
  21. package/dist/layout/styles/ValueLabels.d.ts +12 -4
  22. package/dist/layout/styles/ValueLabels.js +22 -13
  23. package/dist/layout/tooltip/TooltipState.svelte.d.ts +8 -9
  24. package/dist/layout/tooltip/TooltipState.svelte.js +28 -29
  25. package/dist/markers/MarkerKinds.d.ts +5 -0
  26. package/dist/markers/MarkerKinds.js +1 -0
  27. package/dist/markers/band/BandMarker.svelte +74 -0
  28. package/dist/markers/band/BandMarker.svelte.d.ts +7 -0
  29. package/dist/markers/band/Bands.d.ts +16 -0
  30. package/dist/markers/band/Bands.js +48 -0
  31. package/dist/markers/bar/BarMarker.svelte +23 -66
  32. package/dist/markers/hover/HoverMarker.svelte +7 -265
  33. package/dist/markers/hover/HoverMarker.svelte.d.ts +4 -27
  34. package/dist/markers/utils/PointPixel.d.ts +37 -0
  35. package/dist/markers/utils/PointPixel.js +44 -0
  36. package/dist/phases/Pipeline.d.ts +7 -7
  37. package/dist/phases/Pipeline.js +12 -9
  38. package/dist/phases/context/ContextPhase.d.ts +22 -0
  39. package/dist/phases/context/ContextPhase.js +23 -0
  40. package/dist/phases/context/RowContext.d.ts +35 -0
  41. package/dist/phases/context/RowContext.js +95 -0
  42. package/dist/phases/data/DataPhase.d.ts +4 -4
  43. package/dist/phases/data/DataPhase.js +7 -7
  44. package/dist/phases/hover/HoverPhase.d.ts +6 -7
  45. package/dist/phases/hover/HoverPhase.js +28 -23
  46. package/dist/phases/mapping/MappingPhase.d.ts +4 -4
  47. package/dist/phases/mapping/MappingPhase.js +2 -2
  48. package/dist/phases/markers/MarkerStyles.d.ts +8 -0
  49. package/dist/phases/markers/MarkerStyles.js +15 -0
  50. package/dist/phases/markers/MarkersPhase.d.ts +4 -4
  51. package/dist/phases/markers/MarkersPhase.js +4 -4
  52. package/dist/phases/scales/ScalesPhase.d.ts +4 -4
  53. package/dist/phases/scales/ScalesPhase.js +4 -4
  54. package/dist/phases/sharedScales/SharedScalesPhase.d.ts +2 -2
  55. package/dist/phases/sharedScales/SharedScalesPhase.js +2 -2
  56. package/dist/phases/statistics/MarkerGrouping.d.ts +0 -9
  57. package/dist/phases/statistics/MarkerGrouping.js +0 -16
  58. package/dist/phases/styles/StylesPhase.d.ts +3 -3
  59. package/dist/phases/styles/StylesPhase.js +2 -2
  60. package/dist/phases/tooltip/TooltipPhase.d.ts +4 -4
  61. package/dist/phases/tooltip/TooltipPhase.js +10 -7
  62. package/dist/phases/transforms/TransformsPhase.d.ts +3 -3
  63. package/dist/phases/transforms/TransformsPhase.js +2 -2
  64. package/dist/plots/correlation/heatmap/defaults.d.ts +2 -2
  65. package/dist/plots/correlation/heatmap/defaults.js +21 -6
  66. package/dist/plots/correlation/heatmap/markers.d.ts +2 -2
  67. package/dist/plots/correlation/heatmap/markers.js +4 -3
  68. package/dist/plots/correlation/scatter/defaults.d.ts +2 -2
  69. package/dist/plots/correlation/scatter/defaults.js +9 -3
  70. package/dist/plots/correlation/scatter/markers.d.ts +2 -2
  71. package/dist/plots/correlation/scatter/markers.js +4 -3
  72. package/dist/plots/distribution/box/BoxSummaries.d.ts +17 -8
  73. package/dist/plots/distribution/box/BoxSummaries.js +90 -40
  74. package/dist/plots/distribution/box/defaults.d.ts +2 -2
  75. package/dist/plots/distribution/box/defaults.js +9 -6
  76. package/dist/plots/distribution/box/markers.d.ts +2 -2
  77. package/dist/plots/distribution/box/markers.js +3 -3
  78. package/dist/plots/distribution/density/defaults.d.ts +2 -2
  79. package/dist/plots/distribution/density/defaults.js +17 -1
  80. package/dist/plots/distribution/density/markers.d.ts +2 -2
  81. package/dist/plots/distribution/density/markers.js +4 -4
  82. package/dist/plots/distribution/histogram/defaults.d.ts +2 -2
  83. package/dist/plots/distribution/histogram/defaults.js +20 -25
  84. package/dist/plots/distribution/histogram/markers.d.ts +2 -2
  85. package/dist/plots/distribution/histogram/markers.js +5 -4
  86. package/dist/plots/distribution/pyramid/defaults.d.ts +2 -2
  87. package/dist/plots/distribution/pyramid/defaults.js +4 -1
  88. package/dist/plots/distribution/pyramid/markers.d.ts +2 -2
  89. package/dist/plots/distribution/pyramid/markers.js +4 -3
  90. package/dist/plots/distribution/violin/defaults.d.ts +2 -2
  91. package/dist/plots/distribution/violin/defaults.js +9 -7
  92. package/dist/plots/distribution/violin/markers.d.ts +2 -2
  93. package/dist/plots/distribution/violin/markers.js +3 -3
  94. package/dist/plots/evolution/area/defaults.d.ts +2 -2
  95. package/dist/plots/evolution/area/defaults.js +1 -1
  96. package/dist/plots/evolution/area/markers.d.ts +2 -2
  97. package/dist/plots/evolution/area/markers.js +4 -4
  98. package/dist/plots/evolution/line/defaults.d.ts +2 -2
  99. package/dist/plots/evolution/line/defaults.js +1 -1
  100. package/dist/plots/evolution/line/markers.d.ts +2 -2
  101. package/dist/plots/evolution/line/markers.js +3 -3
  102. package/dist/plots/evolution/slope/defaults.d.ts +2 -2
  103. package/dist/plots/evolution/slope/defaults.js +8 -4
  104. package/dist/plots/evolution/slope/markers.d.ts +2 -2
  105. package/dist/plots/evolution/slope/markers.js +3 -3
  106. package/dist/plots/evolution/sparkline/defaults.d.ts +2 -2
  107. package/dist/plots/evolution/sparkline/defaults.js +5 -2
  108. package/dist/plots/evolution/sparkline/markers.d.ts +2 -2
  109. package/dist/plots/evolution/sparkline/markers.js +3 -3
  110. package/dist/plots/map/geo/Core.svelte +3 -3
  111. package/dist/plots/map/geo/defaults.d.ts +2 -2
  112. package/dist/plots/map/geo/phases/data.d.ts +1 -1
  113. package/dist/plots/map/geo/phases/data.js +1 -1
  114. package/dist/plots/map/geo/phases/hover.d.ts +2 -2
  115. package/dist/plots/map/geo/phases/hover.js +3 -3
  116. package/dist/plots/map/geo/phases/markers.d.ts +2 -2
  117. package/dist/plots/map/geo/phases/markers.js +3 -3
  118. package/dist/plots/map/geo/phases/scales.d.ts +2 -2
  119. package/dist/plots/map/geo/phases/scales.js +2 -2
  120. package/dist/plots/part-of-a-whole/treemap/defaults.d.ts +2 -2
  121. package/dist/plots/part-of-a-whole/treemap/defaults.js +37 -21
  122. package/dist/plots/ranking/bar/defaults.d.ts +2 -2
  123. package/dist/plots/ranking/bar/defaults.js +13 -7
  124. package/dist/plots/ranking/bar/markers.d.ts +3 -3
  125. package/dist/plots/ranking/bar/markers.js +8 -7
  126. package/dist/plots/ranking/bullet/defaults.d.ts +2 -2
  127. package/dist/plots/ranking/bullet/defaults.js +4 -4
  128. package/dist/plots/ranking/bullet/markers.d.ts +3 -3
  129. package/dist/plots/ranking/bullet/markers.js +9 -9
  130. package/dist/plots/ranking/cleveland/ClevelandMarkers.d.ts +3 -3
  131. package/dist/plots/ranking/cleveland/ClevelandMarkers.js +11 -10
  132. package/dist/plots/ranking/cleveland/defaults.d.ts +2 -2
  133. package/dist/plots/ranking/cleveland/defaults.js +7 -4
  134. package/dist/plots/ranking/dumbbell/defaults.d.ts +2 -2
  135. package/dist/plots/ranking/forest/defaults.d.ts +2 -2
  136. package/dist/plots/ranking/lollipop/defaults.d.ts +2 -2
  137. package/dist/types/configuration/styling.d.ts +4 -0
  138. package/dist/types/layout/context.d.ts +21 -0
  139. package/dist/types/layout/context.js +1 -0
  140. package/dist/types/layout/hover.d.ts +3 -0
  141. package/dist/types/layout/styles/values.d.ts +8 -2
  142. package/dist/types/layout/tooltip.d.ts +5 -10
  143. package/dist/types/markers/axis/axisBasedMarkersConfig.d.ts +2 -1
  144. package/dist/types/markers/axis/band.d.ts +24 -0
  145. package/dist/types/markers/axis/band.js +1 -0
  146. package/dist/types/markers/axis/bar.d.ts +2 -2
  147. package/dist/types/markers/axis/hover.d.ts +60 -15
  148. package/dist/types/markers/channels/commonMarkerConfig.d.ts +6 -2
  149. package/dist/types/markers/common.d.ts +1 -0
  150. package/dist/types/markers/common.js +1 -0
  151. package/dist/types/phases/context/phase.d.ts +7 -0
  152. package/dist/types/phases/context/phase.js +1 -0
  153. package/dist/types/phases/data/phase.d.ts +2 -2
  154. package/dist/types/phases/hover/phase.d.ts +10 -7
  155. package/dist/types/phases/index.d.ts +2 -1
  156. package/dist/types/phases/kind.d.ts +11 -8
  157. package/dist/types/phases/mapping/phase.d.ts +2 -2
  158. package/dist/types/phases/markers/phase.d.ts +3 -3
  159. package/dist/types/phases/scales/phase.d.ts +4 -4
  160. package/dist/types/phases/stage.d.ts +3 -3
  161. package/dist/types/phases/state.d.ts +1 -1
  162. package/dist/types/phases/styles/phase.d.ts +3 -2
  163. package/dist/types/phases/transforms/phase.d.ts +2 -2
  164. package/dist/types/plots/constants.d.ts +3 -5
  165. package/dist/types/plots/correlation/heatmap/state.d.ts +2 -2
  166. package/dist/types/plots/correlation/scatter/state.d.ts +2 -2
  167. package/dist/types/plots/distribution/box/props.d.ts +23 -1
  168. package/dist/types/plots/distribution/box/state.d.ts +6 -17
  169. package/dist/types/plots/distribution/density/state.d.ts +2 -2
  170. package/dist/types/plots/distribution/histogram/props.d.ts +14 -1
  171. package/dist/types/plots/distribution/histogram/state.d.ts +2 -2
  172. package/dist/types/plots/distribution/pyramid/state.d.ts +2 -2
  173. package/dist/types/plots/distribution/violin/props.d.ts +2 -1
  174. package/dist/types/plots/distribution/violin/state.d.ts +2 -2
  175. package/dist/types/plots/evolution/area/state.d.ts +2 -2
  176. package/dist/types/plots/evolution/line/state.d.ts +2 -2
  177. package/dist/types/plots/evolution/slope/state.d.ts +2 -2
  178. package/dist/types/plots/evolution/sparkline/state.d.ts +2 -2
  179. package/dist/types/plots/map/geo/state.d.ts +1 -1
  180. package/dist/types/plots/part-of-a-whole/treemap/props.d.ts +14 -4
  181. package/dist/types/plots/part-of-a-whole/treemap/state.d.ts +2 -2
  182. package/dist/types/plots/props.d.ts +3 -0
  183. package/dist/types/plots/ranking/bar/state.d.ts +2 -2
  184. package/dist/types/plots/ranking/bullet/state.d.ts +2 -2
  185. package/dist/types/plots/ranking/cleveland/state.d.ts +2 -2
  186. package/dist/types/plots/ranking/dumbbell/state.d.ts +2 -2
  187. package/dist/types/plots/ranking/forest/state.d.ts +2 -2
  188. package/dist/types/plots/ranking/lollipop/state.d.ts +2 -2
  189. package/docs/markers.md +34 -2
  190. package/docs/plots/evolution/line.md +1 -1
  191. package/docs/plots/evolution/slope.md +1 -1
  192. package/docs/plots/part-of-a-whole/treemap.md +36 -2
  193. package/docs/plots/ranking/bar.md +1 -0
  194. package/docs/plots/ranking/cleveland.md +1 -1
  195. package/docs/state.md +33 -0
  196. package/docs/styles-and-segments.md +2 -2
  197. package/docs/theming.md +2 -1
  198. package/docs/tooltip-and-hover.md +81 -3
  199. package/examples/LineDates.svelte +1 -1
  200. package/examples/ResponsiveLine.svelte +3 -1
  201. package/examples/TreemapHover.svelte +25 -0
  202. package/examples/ValueLabels.svelte +1 -1
  203. package/llms-full.txt +8 -6
  204. package/llms.txt +2 -1
  205. package/package.json +1 -1
@@ -1,13 +1,13 @@
1
1
  import type { ValueLabels } from '../../../layout/styles/ValueLabels';
2
2
  import type { AxisBasedMarkersConfig, TextMarkerConfig } from '../../markers/common';
3
3
  /** What a plot kind adds to the shared "markers" stage. */
4
- export type MarkersStageOptions<TState, TCtx> = {
4
+ export type MarkersStageOptions<TState, TEnv> = {
5
5
  /** The plot's own marks - its bars, lines, dots... - drawn under every other marker. */
6
- marks: (state: TState, ctx: TCtx) => AxisBasedMarkersConfig[];
6
+ marks: (state: TState, env: TEnv) => AxisBasedMarkersConfig[];
7
7
  /**
8
8
  * Its value labels, once they show: `text` markers drawn over everything.
9
9
  * The stage adds what every label shares - see {@link ValueLabels.hooks}.
10
10
  * Without it, the plot draws none.
11
11
  */
12
- valueLabels?: (labels: ValueLabels, state: TState, ctx: TCtx) => TextMarkerConfig[];
12
+ valueLabels?: (labels: ValueLabels, state: TState, env: TEnv) => TextMarkerConfig[];
13
13
  };
@@ -13,7 +13,7 @@ export type AxisFit = Partial<AnyAxisScale> & {
13
13
  * numeric axis to cover derived markers and transformed ranges; these say
14
14
  * where a kind goes beyond that.
15
15
  */
16
- export type ScalesStageOptions<TState, TCtx> = {
16
+ export type ScalesStageOptions<TState, TEnv> = {
17
17
  /** Axes whose marks grow from zero, so a domain this stage sets still reaches it - by name or by role (`'value'`). */
18
18
  zero?: AxisRef[];
19
19
  /** Axes that reach as far below zero as above it, to the largest magnitude - by name or by role. */
@@ -21,10 +21,10 @@ export type ScalesStageOptions<TState, TCtx> = {
21
21
  /** Keeps a category axis in the order the data gives it. Without it, categories sort ascending, as svelteplot does. */
22
22
  bandOrder?: 'data';
23
23
  /** The kind's own options for an axis, by name or by role, under the author's `scales`: padding, label anchor, tick format. */
24
- defaults?: (state: TState, ctx: TCtx) => Partial<Record<AxisRef, AnyAxisScale>>;
24
+ defaults?: (state: TState, env: TEnv) => Partial<Record<AxisRef, AnyAxisScale>>;
25
25
  /** The options the kind fits to its own marks on an axis the author left unpinned - a niced value axis, a domain padded for its dots. */
26
- fit?: (state: TState, ctx: TCtx) => Partial<Record<AxisChannelName, AxisFit>>;
26
+ fit?: (state: TState, env: TEnv) => Partial<Record<AxisChannelName, AxisFit>>;
27
27
  /** The kind's own extra "scales" output, once every scale is in place. */
28
- extend?: (state: TState, ctx: TCtx) => TState;
28
+ extend?: (state: TState, env: TEnv) => TState;
29
29
  };
30
30
  export {};
@@ -4,9 +4,9 @@
4
4
  * of a plot shares, `tooltip`, how a hovered row reads once
5
5
  * everything it reads from is placed, and `hover`, what the pointer can match.
6
6
  */
7
- export type PlotPhase = 'facet' | 'data' | 'mapping' | 'transforms' | 'statistics' | 'sharedScales' | 'scales' | 'styles' | 'markers' | 'coordinates' | 'tooltip' | 'hover';
7
+ export type PlotPhase = 'facet' | 'data' | 'mapping' | 'transforms' | 'context' | 'statistics' | 'sharedScales' | 'scales' | 'styles' | 'markers' | 'coordinates' | 'tooltip' | 'hover';
8
8
  /** A resolution step for one {@link PlotPhase} - same state shape in and out. Each shared phase is a class (`DataPhase`, `HoverPhase`...) that implements it. */
9
- export type PhaseStage<TState, TCtx = unknown> = {
9
+ export type PhaseStage<TState, TEnv = unknown> = {
10
10
  phase: PlotPhase;
11
- run: (state: TState, ctx: TCtx) => TState;
11
+ run: (state: TState, env: TEnv) => TState;
12
12
  };
@@ -91,7 +91,7 @@ export type AxisPlotState<TData extends Record<string, unknown>, TStyle extends
91
91
  hoverRows?: unknown[];
92
92
  };
93
93
  /** The environment every axis-based plot's phases read from, alongside the growing state. */
94
- export type AxisPlotCtx = {
94
+ export type AxisPlotEnv = {
95
95
  cfg: PlotStylesConfig;
96
96
  /** The legend's toggles and the figure's hover, read for one plot: which series show and how each dims. */
97
97
  interaction?: PlotInteraction;
@@ -1,3 +1,4 @@
1
+ import type { PlotRowContext } from '../../layout/context';
1
2
  import type { EdgeBox } from '../../layout/box';
2
3
  import type { ValueLabels } from '../../../layout/styles/ValueLabels';
3
4
  import type { ValueAnchor } from '../../plots/constants';
@@ -7,8 +8,8 @@ export type ValueLabelsOptions<TState> = {
7
8
  show?: boolean;
8
9
  /** Where a label sits when `styles.values.anchor` is unset. Defaults to `'outside'`. */
9
10
  anchor?: ValueAnchor;
10
- /** A label's text when `styles.values.format` is unset. Defaults to the bare value. `number` writes a value as the plot's `styles.values` display fields (`decimals`, `prefix`, `suffix`, `signDisplay`) ask. */
11
- format?: (value: number, seriesName: string, number: (value: number) => string) => string;
11
+ /** A label's text when `styles.values.format` is unset. Defaults to the bare value. `number` writes a value as the plot's `styles.values` display fields (`decimals`, `prefix`, `suffix`, `signDisplay`) ask, and `context` is what the plot knows of the labelled row. */
12
+ format?: (value: number, number: (value: number) => string, context: PlotRowContext) => string;
12
13
  /**
13
14
  * Where the labels are expected to sit, from the whole data: boxes around
14
15
  * the points they label, on the plot edges those points can reach (see
@@ -51,9 +51,9 @@ export type TransformsStageState = {
51
51
  processedGroups?: VisualGroup<Series<ProcessedRow>, any>[];
52
52
  };
53
53
  /** What differs between plots in the shared "transforms" stage. */
54
- export type TransformsStageOptions<TState extends TransformsStageState, TCtx> = {
54
+ export type TransformsStageOptions<TState extends TransformsStageState, TEnv> = {
55
55
  /** The transforms to run. Defaults to the plot's own `transforms`. */
56
- transforms?: (state: TState, ctx: TCtx) => MarkerTransform[];
56
+ transforms?: (state: TState, env: TEnv) => MarkerTransform[];
57
57
  /**
58
58
  * Whether a series the legend omits keeps its part of the whole (a treemap's tile): the transforms run over
59
59
  * its rows too, so every other part keeps its share and its place, and its own rows are dropped after.
@@ -32,11 +32,9 @@ export type FontWeight = 'normal' | 'bold' | number;
32
32
  /** `font-style` keyword accepted by any text styling. */
33
33
  export type FontStyleKeyword = 'normal' | 'italic';
34
34
  /**
35
- * Horizontal text anchor. `'outside'` is only meaningful where the consuming
36
- * mark resolves it per-point from a signed x value (currently `HoverMarker`
37
- * only) - it anchors the label away from zero: `'start'` (extending right)
38
- * for a positive x, `'end'` (extending left) for negative. Elsewhere it's
39
- * treated the same as `'start'`.
35
+ * Horizontal text anchor. `'outside'` leaves the side to the mark that writes
36
+ * the label, where it picks one per point (a Cleveland plot's labels take
37
+ * their own); elsewhere it's treated the same as `'start'`.
40
38
  */
41
39
  export type TextAnchor = 'start' | 'middle' | 'end' | 'outside';
42
40
  /** Vertical text anchor. */
@@ -1,7 +1,7 @@
1
1
  import type { CellSegmentStyle } from '../../segments/common';
2
2
  import type { ResolvedChannel, ResolvedChannels } from '../../../layout/mapping';
3
3
  import type { LegendRange } from '../../../layout/legend';
4
- import type { AxisPlotState, AxisPlotCtx } from '../../../phases';
4
+ import type { AxisPlotState, AxisPlotEnv } from '../../../phases';
5
5
  /**
6
6
  * The active continuous-legend range filter, if any - narrows which cells
7
7
  * render at full opacity, and in `'rescale'` mode, the color domain itself.
@@ -23,6 +23,6 @@ export type HeatmapPlotState<TData extends Record<string, unknown>> = AxisPlotSt
23
23
  resolveOpacity?: (row: TData) => number;
24
24
  };
25
25
  /** The environment every HeatmapPlot phase reads from, alongside the growing state. */
26
- export type HeatmapPlotCtx = AxisPlotCtx & {
26
+ export type HeatmapPlotEnv = AxisPlotEnv & {
27
27
  range: HeatmapRangeFilter | null | undefined;
28
28
  };
@@ -1,6 +1,6 @@
1
1
  import type { ScatterSegmentStyle } from '../../segments/common';
2
- import type { AxisPlotState, AxisPlotCtx } from '../../../phases';
2
+ import type { AxisPlotState, AxisPlotEnv } from '../../../phases';
3
3
  /** ScatterPlot's pipeline state: the shared axis-based state, with no extras of its own. */
4
4
  export type ScatterPlotState<TData extends Record<string, unknown>> = AxisPlotState<TData, ScatterSegmentStyle>;
5
5
  /** The environment every ScatterPlot phase reads from, alongside the growing state. */
6
- export type ScatterPlotCtx = AxisPlotCtx;
6
+ export type ScatterPlotEnv = AxisPlotEnv;
@@ -1,10 +1,32 @@
1
+ import type { KindRowContext } from '../../../layout/context';
2
+ import type { AxisValue } from '../../../layout/mapping';
1
3
  import type { BasePlotProps, PlotCoreProps } from '../../props';
2
4
  import type { AxisBasedScalesConfig } from '../../../layout/scales';
3
5
  import type { AxisBasedMarkersConfig } from '../../../markers/common';
4
6
  import type { SeriesProps, DualAxisDataProps } from '../../data/common';
5
7
  import type { AxisBasedStylesConfig } from '../../../layout/styles';
6
8
  import type { AreaStyle } from '../../styling';
9
+ /**
10
+ * One box's summary: its category, its quartiles, the whisker ends (the farthest values within 1.5 IQR of the box),
11
+ * how many values it has and the ones past the whiskers.
12
+ */
13
+ export type BoxSummary = {
14
+ category: AxisValue;
15
+ min: number;
16
+ p25: number;
17
+ median: number;
18
+ p75: number;
19
+ max: number;
20
+ count: number;
21
+ outliers: number[];
22
+ };
23
+ /**
24
+ * What a `BoxPlot` or a `ViolinPlot` knows of a row, which its tooltip's and value labels' `format`, its hover and
25
+ * `usePlot().contextOf` read: the summary of the box (or violin) it is in. A value's own `value` stays its own; a
26
+ * hovered box's is its median.
27
+ */
28
+ export type BoxRowContext = KindRowContext<BoxSummary>;
7
29
  /** `BoxPlot`'s public props. */
8
- export type BoxPlotProps<TData extends Record<string, unknown>> = BasePlotProps<SeriesProps<TData> | DualAxisDataProps<TData>, TData, AxisBasedStylesConfig, AreaStyle, AxisBasedMarkersConfig, AxisBasedScalesConfig<TData>>;
30
+ export type BoxPlotProps<TData extends Record<string, unknown>> = BasePlotProps<SeriesProps<TData> | DualAxisDataProps<TData>, TData, AxisBasedStylesConfig, AreaStyle, AxisBasedMarkersConfig, AxisBasedScalesConfig<TData>, undefined, BoxRowContext>;
9
31
  /** What `BoxPlot`'s core draws from. */
10
32
  export type BoxPlotCoreProps<TData extends Record<string, unknown>> = PlotCoreProps<SeriesProps<TData> | DualAxisDataProps<TData>, TData, AxisBasedStylesConfig, AreaStyle, AxisBasedMarkersConfig, AxisBasedScalesConfig<TData>>;
@@ -1,23 +1,12 @@
1
1
  import type { AreaStyle } from '../../styling';
2
- import type { AxisPlotState, AxisPlotCtx, ProcessedRow } from '../../../phases';
3
- import type { AxisValue } from '../../../layout/mapping';
2
+ import type { AxisPlotState, AxisPlotEnv, ProcessedRow } from '../../../phases';
3
+ import type { BoxSummary } from './props';
4
4
  /** BoxPlot's pipeline state: the shared axis-based state, with no extras of its own. */
5
5
  export type BoxPlotState<TData extends Record<string, unknown>> = AxisPlotState<TData, AreaStyle>;
6
6
  /** The environment every BoxPlot phase reads from, alongside the growing state. */
7
- export type BoxPlotCtx = AxisPlotCtx;
7
+ export type BoxPlotEnv = AxisPlotEnv;
8
8
  /**
9
- * One box's summary - what a hovered box reads as: its category, its
10
- * quartiles, the whisker ends (the farthest values within 1.5 IQR of the
11
- * box) and the values past them. It also keeps the series tags and, when the
12
- * category channel is a field key, the category under that field.
9
+ * One box's summary as a row - what a hovered box reads as. It also keeps the series tags and, when the category
10
+ * channel is a field key, the category under that field.
13
11
  */
14
- export type BoxSummaryRow = ProcessedRow & {
15
- category: AxisValue;
16
- min: number;
17
- p25: number;
18
- median: number;
19
- p75: number;
20
- max: number;
21
- count: number;
22
- outliers: number[];
23
- };
12
+ export type BoxSummaryRow = ProcessedRow & BoxSummary;
@@ -1,6 +1,6 @@
1
1
  import type { AreaStyle } from '../../styling';
2
- import type { AxisPlotState, AxisPlotCtx } from '../../../phases';
2
+ import type { AxisPlotState, AxisPlotEnv } from '../../../phases';
3
3
  /** DensityPlot's pipeline state: the shared axis-based state, with no extras of its own. */
4
4
  export type DensityPlotState<TData extends Record<string, unknown>> = AxisPlotState<TData, AreaStyle>;
5
5
  /** The environment every DensityPlot phase reads from, alongside the growing state. */
6
- export type DensityPlotCtx = AxisPlotCtx;
6
+ export type DensityPlotEnv = AxisPlotEnv;
@@ -1,10 +1,23 @@
1
+ import type { KindRowContext } from '../../../layout/context';
1
2
  import type { BasePlotProps, PlotCoreProps } from '../../props';
2
3
  import type { AxisBasedScalesConfig } from '../../../layout/scales';
3
4
  import type { AxisBasedMarkersConfig } from '../../../markers/common';
4
5
  import type { SeriesProps, SingleAxisDataProps } from '../../data/common';
5
6
  import type { AxisBasedStylesConfig } from '../../../layout/styles';
6
7
  import type { AreaStyle } from '../../styling';
8
+ /**
9
+ * What a `HistogramPlot` knows of a bin, which its tooltip's and value labels' `format`, its hover and
10
+ * `usePlot().contextOf` read: its `count` (also its `value`) and the edges it spans.
11
+ */
12
+ export type HistogramRowContext = KindRowContext<{
13
+ /** How many values fall in the bin. */
14
+ count: number;
15
+ /** The bin's lower edge. */
16
+ from: number;
17
+ /** The bin's upper edge. */
18
+ to: number;
19
+ }>;
7
20
  /** `HistogramPlot`'s public props. */
8
- export type HistogramPlotProps<TData extends Record<string, unknown>> = BasePlotProps<SeriesProps<TData> | SingleAxisDataProps<TData>, TData, AxisBasedStylesConfig, AreaStyle, AxisBasedMarkersConfig, AxisBasedScalesConfig<TData>>;
21
+ export type HistogramPlotProps<TData extends Record<string, unknown>> = BasePlotProps<SeriesProps<TData> | SingleAxisDataProps<TData>, TData, AxisBasedStylesConfig, AreaStyle, AxisBasedMarkersConfig, AxisBasedScalesConfig<TData>, undefined, HistogramRowContext>;
9
22
  /** What `HistogramPlot`'s core draws from. */
10
23
  export type HistogramPlotCoreProps<TData extends Record<string, unknown>> = PlotCoreProps<SeriesProps<TData> | SingleAxisDataProps<TData>, TData, AxisBasedStylesConfig, AreaStyle, AxisBasedMarkersConfig, AxisBasedScalesConfig<TData>>;
@@ -1,6 +1,6 @@
1
1
  import type { AreaStyle } from '../../styling';
2
- import type { AxisPlotState, AxisPlotCtx } from '../../../phases';
2
+ import type { AxisPlotState, AxisPlotEnv } from '../../../phases';
3
3
  /** HistogramPlot's pipeline state: the shared axis-based state, with no extras of its own. */
4
4
  export type HistogramPlotState<TData extends Record<string, unknown>> = AxisPlotState<TData, AreaStyle>;
5
5
  /** The environment every HistogramPlot phase reads from, alongside the growing state. */
6
- export type HistogramPlotCtx = AxisPlotCtx;
6
+ export type HistogramPlotEnv = AxisPlotEnv;
@@ -1,6 +1,6 @@
1
1
  import type { Series } from '../../data/common';
2
2
  import type { BarSegmentStyle } from '../../segments/common';
3
- import type { AxisPlotState, AxisPlotCtx } from '../../../phases';
3
+ import type { AxisPlotState, AxisPlotEnv } from '../../../phases';
4
4
  export type PyramidSide = 'left' | 'right';
5
5
  /** A resolved series tagged with which side of the shared zero baseline it renders on. */
6
6
  export type PyramidSeries<TData extends Record<string, unknown>> = Series<TData> & {
@@ -13,4 +13,4 @@ export type PyramidSeries<TData extends Record<string, unknown>> = Series<TData>
13
13
  */
14
14
  export type PyramidPlotState<TData extends Record<string, unknown>> = AxisPlotState<TData, BarSegmentStyle, PyramidSeries<TData>>;
15
15
  /** The environment every PyramidPlot phase reads from, alongside the growing state. */
16
- export type PyramidPlotCtx = AxisPlotCtx;
16
+ export type PyramidPlotEnv = AxisPlotEnv;
@@ -1,3 +1,4 @@
1
+ import type { BoxRowContext } from '../box/props';
1
2
  import type { BasePlotProps, PlotCoreProps } from '../../props';
2
3
  import type { AxisBasedScalesConfig } from '../../../layout/scales';
3
4
  import type { AxisBasedMarkersConfig } from '../../../markers/common';
@@ -18,6 +19,6 @@ export type ViolinPlotStylesConfig = AxisBasedStylesConfig & {
18
19
  box?: boolean | number;
19
20
  };
20
21
  /** `ViolinPlot`'s public props. */
21
- export type ViolinPlotProps<TData extends Record<string, unknown>> = BasePlotProps<SeriesProps<TData> | DualAxisDataProps<TData>, TData, ViolinPlotStylesConfig, AreaStyle, AxisBasedMarkersConfig, AxisBasedScalesConfig<TData>>;
22
+ export type ViolinPlotProps<TData extends Record<string, unknown>> = BasePlotProps<SeriesProps<TData> | DualAxisDataProps<TData>, TData, ViolinPlotStylesConfig, AreaStyle, AxisBasedMarkersConfig, AxisBasedScalesConfig<TData>, undefined, BoxRowContext>;
22
23
  /** What `ViolinPlot`'s core draws from. */
23
24
  export type ViolinPlotCoreProps<TData extends Record<string, unknown>> = PlotCoreProps<SeriesProps<TData> | DualAxisDataProps<TData>, TData, ViolinPlotStylesConfig, AreaStyle, AxisBasedMarkersConfig, AxisBasedScalesConfig<TData>>;
@@ -1,6 +1,6 @@
1
1
  import type { AreaStyle } from '../../styling';
2
- import type { AxisPlotState, AxisPlotCtx } from '../../../phases';
2
+ import type { AxisPlotState, AxisPlotEnv } from '../../../phases';
3
3
  /** ViolinPlot's pipeline state: the shared axis-based state, with no extras of its own. */
4
4
  export type ViolinPlotState<TData extends Record<string, unknown>> = AxisPlotState<TData, AreaStyle>;
5
5
  /** The environment every ViolinPlot phase reads from, alongside the growing state. */
6
- export type ViolinPlotCtx = AxisPlotCtx;
6
+ export type ViolinPlotEnv = AxisPlotEnv;
@@ -1,6 +1,6 @@
1
1
  import type { AreaStyle } from '../../styling';
2
- import type { AxisPlotState, AxisPlotCtx } from '../../../phases';
2
+ import type { AxisPlotState, AxisPlotEnv } from '../../../phases';
3
3
  /** AreaPlot's pipeline state: the shared axis-based state, with no extras of its own. */
4
4
  export type AreaPlotState<TData extends Record<string, unknown>> = AxisPlotState<TData, AreaStyle>;
5
5
  /** The environment every AreaPlot phase reads from, alongside the growing state. */
6
- export type AreaPlotCtx = AxisPlotCtx;
6
+ export type AreaPlotEnv = AxisPlotEnv;
@@ -1,9 +1,9 @@
1
1
  import type { GapsConfig } from '../../gaps';
2
2
  import type { LineSegmentStyle } from '../../segments/common';
3
- import type { AxisPlotState, AxisPlotCtx } from '../../../phases';
3
+ import type { AxisPlotState, AxisPlotEnv } from '../../../phases';
4
4
  /** LinePlot's pipeline state: the shared axis-based state plus its gaps. */
5
5
  export type LinePlotState<TData extends Record<string, unknown>> = AxisPlotState<TData, LineSegmentStyle> & {
6
6
  gaps?: GapsConfig<LineSegmentStyle>;
7
7
  };
8
8
  /** The environment every LinePlot phase reads from, alongside the growing state. */
9
- export type LinePlotCtx = AxisPlotCtx;
9
+ export type LinePlotEnv = AxisPlotEnv;
@@ -1,5 +1,5 @@
1
- import type { LinePlotState, LinePlotCtx } from '../line/state';
1
+ import type { LinePlotState, LinePlotEnv } from '../line/state';
2
2
  /** SlopePlot's pipeline state: a LinePlot's. */
3
3
  export type SlopePlotState<TData extends Record<string, unknown>> = LinePlotState<TData>;
4
4
  /** The environment every SlopePlot phase reads from, alongside the growing state. */
5
- export type SlopePlotCtx = LinePlotCtx;
5
+ export type SlopePlotEnv = LinePlotEnv;
@@ -1,5 +1,5 @@
1
- import type { LinePlotState, LinePlotCtx } from '../line/state';
1
+ import type { LinePlotState, LinePlotEnv } from '../line/state';
2
2
  /** SparklinePlot's pipeline state: a LinePlot's. */
3
3
  export type SparklinePlotState<TData extends Record<string, unknown>> = LinePlotState<TData>;
4
4
  /** The environment every SparklinePlot phase reads from, alongside the growing state. */
5
- export type SparklinePlotCtx = LinePlotCtx;
5
+ export type SparklinePlotEnv = LinePlotEnv;
@@ -78,7 +78,7 @@ export type GeoPlotState<TProps extends Record<string, unknown>> = {
78
78
  hoverRows?: TaggedGeoFeature<TProps>[];
79
79
  };
80
80
  /** The environment every GeoPlot phase reads from, alongside the growing state. */
81
- export type GeoPlotCtx<TProps extends Record<string, unknown>> = {
81
+ export type GeoPlotEnv<TProps extends Record<string, unknown>> = {
82
82
  cfg: PlotStylesConfig;
83
83
  range: GeoRangeFilter | null | undefined;
84
84
  fill?: string;
@@ -3,13 +3,23 @@ import type { AxisBasedScalesConfig } from '../../../layout/scales';
3
3
  import type { AxisBasedMarkersConfig } from '../../../markers/common';
4
4
  import type { NonAxisDataProps } from '../../data/common';
5
5
  import type { AxisBasedStylesConfig } from '../../../layout/styles';
6
- import type { TooltipContext } from '../../../layout/tooltip';
6
+ import type { KindRowContext } from '../../../layout/context';
7
7
  import type { BarSegmentStyle } from '../../segments/common';
8
- /** What a `TreemapPlot` knows of a hovered tile beyond its row, the third argument of `tooltip.format`. */
9
- export type TreemapTooltipContext = TooltipContext & {
8
+ /**
9
+ * What a `TreemapPlot` knows of a tile, which its tooltip's and value labels' `format`, its hover and
10
+ * `usePlot().contextOf` read: its series (the outermost level), and what the plot works out for it. Its `value`
11
+ * is the tile's summed value, and it has no `x` or `y`.
12
+ */
13
+ export type TreemapRowContext = KindRowContext<{
14
+ /** The tile's name: the value at its innermost level. */
15
+ name: string;
16
+ /** The value at every level of the tile, outermost first. */
17
+ path: string[];
10
18
  /** The tile's part of the whole, from `0` to `100`, worked out from the values in whatever unit they are. */
11
19
  share: number;
12
- };
20
+ }>;
21
+ /** What a `TreemapPlot`'s `tooltip.format` gets in its third argument - see {@link TreemapRowContext}. */
22
+ export type TreemapTooltipContext = TreemapRowContext;
13
23
  /**
14
24
  * `TreemapPlot`'s public props: flat rows, a tile each, on no axes. `value` is a tile's area, and `grouping` what
15
25
  * the tiles nest by (`'sector.branch'`, outermost first), whose outermost level colors them.
@@ -1,6 +1,6 @@
1
1
  import type { BarSegmentStyle } from '../../segments/common';
2
- import type { AxisPlotState, AxisPlotCtx } from '../../../phases';
2
+ import type { AxisPlotState, AxisPlotEnv } from '../../../phases';
3
3
  /** TreemapPlot's pipeline state: the shared axis-based state, over a unit square its tiles are laid out in. */
4
4
  export type TreemapPlotState<TData extends Record<string, unknown>> = AxisPlotState<TData, BarSegmentStyle>;
5
5
  /** The environment every TreemapPlot phase reads from, alongside the growing state. */
6
- export type TreemapPlotCtx = AxisPlotCtx;
6
+ export type TreemapPlotEnv = AxisPlotEnv;
@@ -1,3 +1,4 @@
1
+ import type { HoverLook } from '../markers/common';
1
2
  import type { Pipeline } from '../../phases/Pipeline';
2
3
  import type { Snippet } from 'svelte';
3
4
  import type { TooltipContext, TooltipOptions, TooltipProp } from '../layout/tooltip';
@@ -62,6 +63,8 @@ export type HoverConfig<TRow extends Record<string, unknown>> = {
62
63
  pointMatching?: PointMatchingStrategy;
63
64
  /** Forces the crosshair rule(s) a `hover` marker draws off entirely, overriding whatever `strategy` implies. */
64
65
  crosshair?: boolean;
66
+ /** The plot kind's own hover under the strategy in force, which an author's `hover` marker is laid over as it is drawn. */
67
+ look?: (strategy: HoverStrategy) => HoverLook;
65
68
  };
66
69
  /** The `scales` prop of any plot kind. */
67
70
  export type ScalesConfig<TData = Record<string, unknown>> = AxisBasedScalesConfig<TData> | GeoScalesConfig;
@@ -1,6 +1,6 @@
1
- import type { AxisPlotState, AxisPlotCtx } from '../../../phases';
1
+ import type { AxisPlotState, AxisPlotEnv } from '../../../phases';
2
2
  import type { BarSegmentStyle } from '../../segments/common';
3
3
  /** BarPlot's pipeline state: the shared axis-based state. */
4
4
  export type BarPlotState<TData extends Record<string, unknown>> = AxisPlotState<TData, BarSegmentStyle>;
5
5
  /** The environment every BarPlot phase reads from, alongside the growing state. */
6
- export type BarPlotCtx = AxisPlotCtx;
6
+ export type BarPlotEnv = AxisPlotEnv;
@@ -1,5 +1,5 @@
1
- import type { BarPlotState, BarPlotCtx } from '../bar/state';
1
+ import type { BarPlotState, BarPlotEnv } from '../bar/state';
2
2
  /** BulletPlot's pipeline state: a bar plot's, which already carries the `target` and `ranges` it measures against. */
3
3
  export type BulletPlotState<TData extends Record<string, unknown>> = BarPlotState<TData>;
4
4
  /** The environment every BulletPlot phase reads from. */
5
- export type BulletPlotCtx = BarPlotCtx;
5
+ export type BulletPlotEnv = BarPlotEnv;
@@ -1,9 +1,9 @@
1
- import type { AxisPlotState, AxisPlotCtx, ProcessedRow } from '../../../phases';
1
+ import type { AxisPlotState, AxisPlotEnv, ProcessedRow } from '../../../phases';
2
2
  import type { LineSegmentStyle } from '../../segments/common';
3
3
  /** ClevelandPlot's pipeline state (shared by its wrappers): the shared axis-based state, with no extras of its own. */
4
4
  export type ClevelandPlotState<TData extends Record<string, unknown>> = AxisPlotState<TData, LineSegmentStyle>;
5
5
  /** The environment every ClevelandPlot phase reads from, alongside the growing state. */
6
- export type ClevelandPlotCtx = AxisPlotCtx;
6
+ export type ClevelandPlotEnv = AxisPlotEnv;
7
7
  /** The configuration blocks the Cleveland-style plots draw their defaults from: one per plot. */
8
8
  export type ClevelandConfigKey = 'lollipop' | 'dumbbell' | 'cleveland' | 'forest';
9
9
  /** One category's dots along the value axis: the row each one draws, and the range they span. */
@@ -1,5 +1,5 @@
1
- import type { ClevelandPlotState, ClevelandPlotCtx } from '../cleveland/state';
1
+ import type { ClevelandPlotState, ClevelandPlotEnv } from '../cleveland/state';
2
2
  /** DumbbellPlot's pipeline state: a ClevelandPlot's. */
3
3
  export type DumbbellPlotState<TData extends Record<string, unknown>> = ClevelandPlotState<TData>;
4
4
  /** The environment every DumbbellPlot phase reads from, alongside the growing state. */
5
- export type DumbbellPlotCtx = ClevelandPlotCtx;
5
+ export type DumbbellPlotEnv = ClevelandPlotEnv;
@@ -1,5 +1,5 @@
1
- import type { ClevelandPlotState, ClevelandPlotCtx } from '../cleveland/state';
1
+ import type { ClevelandPlotState, ClevelandPlotEnv } from '../cleveland/state';
2
2
  /** ForestPlot's pipeline state: a ClevelandPlot's. */
3
3
  export type ForestPlotState<TData extends Record<string, unknown>> = ClevelandPlotState<TData>;
4
4
  /** The environment every ForestPlot phase reads from, alongside the growing state. */
5
- export type ForestPlotCtx = ClevelandPlotCtx;
5
+ export type ForestPlotEnv = ClevelandPlotEnv;
@@ -1,5 +1,5 @@
1
- import type { ClevelandPlotState, ClevelandPlotCtx } from '../cleveland/state';
1
+ import type { ClevelandPlotState, ClevelandPlotEnv } from '../cleveland/state';
2
2
  /** LollipopPlot's pipeline state: a ClevelandPlot's. */
3
3
  export type LollipopPlotState<TData extends Record<string, unknown>> = ClevelandPlotState<TData>;
4
4
  /** The environment every LollipopPlot phase reads from, alongside the growing state. */
5
- export type LollipopPlotCtx = ClevelandPlotCtx;
5
+ export type LollipopPlotEnv = ClevelandPlotEnv;
package/docs/markers.md CHANGED
@@ -74,6 +74,7 @@ Many markers also take channel fields (`color`, `fill`, `opacity`, `r`, `symbol`
74
74
  | `text` | A label per row; `text` (string or function), `styles` (`FontStyle`), `declutter`, `edgeAware`, `fitMargins`, `fit` |
75
75
  | `line` | A line through the rows |
76
76
  | `rule` | A reference line: `axis: 'x' \| 'y'`, `value` (a list draws a line at each, or a function with `data`), `styles` (`StrokeStyle`, and `inset`, `insetTop`, ... to pull it in from its ends) |
77
+ | `band` | The band of a category across the whole other axis: `axis: 'x' \| 'y'`, `value` (a list, or a function with `data`), `slice`, `styles` (`AreaStyle`). Only on a band scale |
77
78
  | `tick` | A short tick per row along one axis |
78
79
  | `bar` | A bar; `rect`, `cell`: rectangles and heatmap cells |
79
80
  | `rect` | A rectangle from `x1`/`x2`/`y1`/`y2`; `interval` turns `x`/`y` into ranges; `styles` (`AreaStyle`, and `inset`, `insetLeft`, ...); `label`, a text in each (`cell`, `bar` and `waffle` take it too) |
@@ -101,7 +102,7 @@ On a plot with a [`facet`](facets.md#markers-and-segments-in-some-panels), every
101
102
 
102
103
  ## Several positions at once
103
104
 
104
- A `rule` takes a list as its `value`, and a `delta` a list as its `at`. One marker then draws one line, or one delta, at each position, all with the same style and the same ends - instead of one marker for each.
105
+ A `rule` and a `band` take a list as their `value`, and a `delta` a list as its `at`. One marker then draws one line, or one delta, at each position, all with the same style and the same ends - instead of one marker for each.
105
106
 
106
107
  ```ts
107
108
  markers={[
@@ -123,9 +124,40 @@ A delta's `stroke`, `text` and `dot` can be functions of the position, to style
123
124
 
124
125
  Every other marker draws from `data` rows, one mark per row, so it already takes many positions.
125
126
 
127
+ ## Bands
128
+
129
+ `{ type: 'band', axis: 'x', value: 'Salta' }` fills the band of a category on a band scale, across the whole of the other axis: a column behind a bar plot's bars, a row across a horizontal one. With `data`, `value` is a field key or a function of the row, and the rows that name the same category draw one band. `slice` fills part of the band, as the fractions of its width left out at its start and its end (`{ start: 0.5, end: 0 }` is its second half), or a function of the row for each one's; a band several rows share fills what all of their slices do. `styles` take `AreaStyle`, each field a value or a function of the row, over `band` in the [configuration](theming.md). A band takes the pointer only with a handler of its own (`onclick`...), so one behind a plot's shapes leaves them their hover. On an axis that is not a band scale it draws nothing.
130
+
131
+ ```ts
132
+ markers={[
133
+ // The two provinces of the story, behind their bars.
134
+ { type: 'band', axis: 'x', value: ['Salta', 'Jujuy'], styles: { fill: '#fde68a', fillOpacity: 0.5 } }
135
+ ]}
136
+ ```
137
+
126
138
  ## Hover highlight
127
139
 
128
- `{ type: 'hover' }` draws a crosshair, a dot and a label at the hovered point. It makes the plot hoverable on its own; add `tooltip` for a floating box too. Fields: `strategy`, `sync`, `ruleX`, `ruleY`, `areaX`, `areaY` (a band highlight on band scales), `showLabels`, `format`, the number fields `decimals`, `prefix`, `suffix` and `signDisplay` (they write the label's value; `format` gets a `number` function that does the same), and the styles `rule`, `area`, `dot`, `text`. See [Tooltip and hover](tooltip-and-hover.md).
140
+ `{ type: 'hover' }` draws the plot's own hover: a crosshair, a dot and a label at the hovered point on most plots, the hovered category's band on a bar plot. It makes the plot hoverable on its own; add `tooltip` for a floating box too. Fields: `strategy`, `sync`, `series`, `scope`; `back` and `front`, the markers it draws behind the plot's shapes and in front of them, over the hovered points (they replace the plot's); `active` and `others`, which restyle the hovered shapes and the rest; and `format` and the number fields `decimals`, `prefix`, `suffix` and `signDisplay`, which write each point's label. See [Tooltip and hover](tooltip-and-hover.md#in-plot-hover).
141
+
142
+ ```ts
143
+ // A crosshair only at the hovered point, and its value in bold, without a dot.
144
+ { type: 'hover', back: [{ type: 'rule', axis: 'x', points: 'active' }], front: [{ type: 'text', styles: { fontWeight: 'bold' } }] }
145
+ ```
146
+
147
+ Every marker takes `hover`, which links it to the plot's hover:
148
+
149
+ - `'trigger'` makes it a hit area: the pointer over one of its shapes hovers that shape's row.
150
+ - `'style'` has its shapes take the hover marker's `active` and `others`.
151
+ - `true` does both.
152
+
153
+ ```ts
154
+ markers={[
155
+ { type: 'hover', active: { stroke: 'black', strokeWidth: 2 }, others: { fillOpacity: 0.3 } },
156
+ { type: 'rect', data: eras, x1: 'from', x2: 'to', y1: 0, y2: 100, hover: true }
157
+ ]}
158
+ ```
159
+
160
+ A plot's own shapes are linked already where its kind does it: the tiles, cells, bars, bins and dots of `TreemapPlot`, `HeatmapPlot`, `BarPlot`, `BulletPlot`, `PyramidPlot`, `HistogramPlot`, `ScatterPlot` and the Cleveland family. The `Layout/Hover` stories show every feature of the hover on every plot kind.
129
161
 
130
162
  ## Styles that depend on the row
131
163
 
@@ -20,7 +20,7 @@ One line per series. Rows with a missing value (`null`, `undefined`, `NaN`) brea
20
20
  x="date"
21
21
  y="index"
22
22
  color="commodity"
23
- styles={{ values: { show: true, format: (v, name) => `${name}: ${v}` } }}
23
+ styles={{ values: { show: true, format: (v, _number, context) => `${context.series}: ${v}` } }}
24
24
  />
25
25
  ```
26
26
 
@@ -32,7 +32,7 @@ A line per series between two positions of a category axis, a dot on each end, t
32
32
 
33
33
  - `x` is always a category axis (a point scale, so the first and last positions reach the plot's edges), even for numbers or dates: each distinct value is a position, in the order the data gives them (`scales.x.domain` sets it).
34
34
  - `grouping` (or `color`) names the series; the legend toggles them like any other.
35
- - `styles.values` writes each series' first and last value (`select` picks others: `'first'`, `'last'`, `'min'`, `'max'`). Each label sits out in the margin on a lane, joined to its dot by a connector. The text is `format` of the value and series name.
35
+ - `styles.values` writes each series' first and last value (`select` picks others: `'first'`, `'last'`, `'min'`, `'max'`). Each label sits out in the margin on a lane, joined to its dot by a connector. The text is `format` of the value, `number` and the row's context, with its `series`.
36
36
  - The value axis is hidden, since the labels carry the values; `scales.y.axisDisplay: 'visible'` brings it back. It fits the values without reaching for zero; pin `scales.y.domain` to start it there.
37
37
  - The stroke width, dot radius and padding come from `slope` in the [configuration](../../theming.md); `padding` leaves room outside the first and last position. The positions sit at the plot's edges, and the margins grow to fit the labels.
38
38
  - `segments` restyle chosen series (`styles: { stroke: { strokeWidth: 4 } }`), as in a line plot.
@@ -40,7 +40,7 @@ Each tile is labelled with its name and its **share of the whole**, in percent,
40
40
  3. The value alone, when almost none of the name would show.
41
41
  4. Nothing, when not even the value fits.
42
42
 
43
- `styles.values.format(value, group, row, number)` writes the tile's whole text instead (`value` is the share, in percent; `number` writes it as the display fields ask), and `styles.values.show: false` leaves the tiles bare. The label's `fontStyle` sets `fontSize` (the biggest it takes), `fontWeight` and `fill`; `treemap` in the [configuration](../../theming.md) sets the lines between tiles, the label color and the room kept around it.
43
+ `styles.values.format(value, number, context)` writes the tile's whole text instead (`value` is the share, in percent; `number` writes it as the display fields ask; `context` holds the tile's `series`, `name`, `path` and `share`), and `styles.values.show: false` leaves the tiles bare. The label's `fontStyle` sets `fontSize` (the biggest it takes), `fontWeight` and `fill`; `treemap` in the [configuration](../../theming.md) sets the lines between tiles, the label color and the room kept around it.
44
44
 
45
45
  ## Style
46
46
 
@@ -66,4 +66,38 @@ Each tile is labelled with its name and its **share of the whole**, in percent,
66
66
 
67
67
  ## Hover and tooltip
68
68
 
69
- Hovering a tile matches it alone - an invisible `rect` over each tile drives the plot's hover - and `tooltip` shows its name and share. `tooltip.format(row, number, context)` writes it by hand: `row` is the tile's row, with the fields of every level and its summed `value`, and `context` what the library works out about it - its `series` (the outermost level) and its `share` of the whole, from 0 to 100. The share is worked out from the values, in whatever unit they are, so a dataset whose `value` is a percentage already reads the same.
69
+ Hovering a tile matches it alone - an invisible `rect` over each tile drives the plot's hover - and `tooltip` shows its name and share. `tooltip.format(row, number, context)` writes it by hand: `row` is the tile's row, with the fields of every level and its summed `value`, and `context` what the library works out about it - its `series` (the outermost level), its `name`, `path`, summed `value` and `share` of the whole, from 0 to 100 (see [Row context](../../state.md#row-context)). The share is worked out from the values, in whatever unit they are, so a dataset whose `value` is a percentage already reads the same.
70
+
71
+ A `hover` marker draws no crosshair, dot or label over a treemap, since a tile has no axes and writes its own label: it outlines the hovered tile, in the configuration's `hover.active`. The tiles are linked to the hover, so its `active` and `others` restyle them: the hovered tile lightened and outlined, the rest faded, each label still on its tile and written in the color that reads best on its new one. A tile the legend dims stays hoverable and keeps its dimmed fill; one it hides, omits or rescales away is never hovered. See [Tooltip and hover](../../tooltip-and-hover.md#restyling-the-hovered-shapes).
72
+
73
+ <!-- example: examples/TreemapHover.svelte -->
74
+
75
+ ```svelte
76
+ <script lang="ts">
77
+ import { TreemapPlot } from '@fundar/data-chart-telling';
78
+ import { ACTIVITY_BRANCHES } from './datasets';
79
+ </script>
80
+
81
+ <!--
82
+ The hover marker restyles the tiles themselves: the hovered one at full strength and outlined, every other
83
+ faded. Each label is still written on its tile, in the color that reads best on it.
84
+ -->
85
+ <TreemapPlot
86
+ width={760}
87
+ height={440}
88
+ data={ACTIVITY_BRANCHES}
89
+ value="value"
90
+ grouping="sector.branch"
91
+ styles={{ area: { fillOpacity: 0.85 } }}
92
+ tooltip
93
+ markers={[
94
+ {
95
+ type: 'hover',
96
+ active: { fillOpacity: 1, stroke: '#111827', strokeWidth: 2 },
97
+ others: { fillOpacity: 0.35 }
98
+ }
99
+ ]}
100
+ />
101
+ ```
102
+
103
+ <!-- /example -->