@dou-ui/chart 0.0.0-stage → 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -2
  3. package/dist/chart.js +6 -0
  4. package/dist/chart.js.map +1 -0
  5. package/dist/chart.vue_vue_type_script_setup_true_lang.js +4245 -0
  6. package/dist/chart.vue_vue_type_script_setup_true_lang.js.map +1 -0
  7. package/dist/components/area.js +6 -0
  8. package/dist/components/area.js.map +1 -0
  9. package/dist/components/area.vue_vue_type_script_setup_true_lang.js +55 -0
  10. package/dist/components/area.vue_vue_type_script_setup_true_lang.js.map +1 -0
  11. package/dist/components/axis.js +6 -0
  12. package/dist/components/axis.js.map +1 -0
  13. package/dist/components/axis.vue_vue_type_script_setup_true_lang.js +46 -0
  14. package/dist/components/axis.vue_vue_type_script_setup_true_lang.js.map +1 -0
  15. package/dist/components/bar.js +6 -0
  16. package/dist/components/bar.js.map +1 -0
  17. package/dist/components/bar.vue_vue_type_script_setup_true_lang.js +46 -0
  18. package/dist/components/bar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  19. package/dist/components/boxplot.js +6 -0
  20. package/dist/components/boxplot.js.map +1 -0
  21. package/dist/components/boxplot.vue_vue_type_script_setup_true_lang.js +42 -0
  22. package/dist/components/boxplot.vue_vue_type_script_setup_true_lang.js.map +1 -0
  23. package/dist/components/brush.js +6 -0
  24. package/dist/components/brush.js.map +1 -0
  25. package/dist/components/brush.vue_vue_type_script_setup_true_lang.js +42 -0
  26. package/dist/components/brush.vue_vue_type_script_setup_true_lang.js.map +1 -0
  27. package/dist/components/funnel.js +6 -0
  28. package/dist/components/funnel.js.map +1 -0
  29. package/dist/components/funnel.vue_vue_type_script_setup_true_lang.js +41 -0
  30. package/dist/components/funnel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  31. package/dist/components/gauge.js +6 -0
  32. package/dist/components/gauge.js.map +1 -0
  33. package/dist/components/gauge.vue_vue_type_script_setup_true_lang.js +91 -0
  34. package/dist/components/gauge.vue_vue_type_script_setup_true_lang.js.map +1 -0
  35. package/dist/components/heatmap.js +6 -0
  36. package/dist/components/heatmap.js.map +1 -0
  37. package/dist/components/heatmap.vue_vue_type_script_setup_true_lang.js +45 -0
  38. package/dist/components/heatmap.vue_vue_type_script_setup_true_lang.js.map +1 -0
  39. package/dist/components/histogram.js +6 -0
  40. package/dist/components/histogram.js.map +1 -0
  41. package/dist/components/histogram.vue_vue_type_script_setup_true_lang.js +61 -0
  42. package/dist/components/histogram.vue_vue_type_script_setup_true_lang.js.map +1 -0
  43. package/dist/components/line.js +6 -0
  44. package/dist/components/line.js.map +1 -0
  45. package/dist/components/line.vue_vue_type_script_setup_true_lang.js +52 -0
  46. package/dist/components/line.vue_vue_type_script_setup_true_lang.js.map +1 -0
  47. package/dist/components/marker.js +6 -0
  48. package/dist/components/marker.js.map +1 -0
  49. package/dist/components/marker.vue_vue_type_script_setup_true_lang.js +31 -0
  50. package/dist/components/marker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  51. package/dist/components/pie.js +6 -0
  52. package/dist/components/pie.js.map +1 -0
  53. package/dist/components/pie.vue_vue_type_script_setup_true_lang.js +42 -0
  54. package/dist/components/pie.vue_vue_type_script_setup_true_lang.js.map +1 -0
  55. package/dist/components/radar.js +6 -0
  56. package/dist/components/radar.js.map +1 -0
  57. package/dist/components/radar.vue_vue_type_script_setup_true_lang.js +45 -0
  58. package/dist/components/radar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  59. package/dist/components/range.js +6 -0
  60. package/dist/components/range.js.map +1 -0
  61. package/dist/components/range.vue_vue_type_script_setup_true_lang.js +27 -0
  62. package/dist/components/range.vue_vue_type_script_setup_true_lang.js.map +1 -0
  63. package/dist/components/scatter.js +6 -0
  64. package/dist/components/scatter.js.map +1 -0
  65. package/dist/components/scatter.vue_vue_type_script_setup_true_lang.js +45 -0
  66. package/dist/components/scatter.vue_vue_type_script_setup_true_lang.js.map +1 -0
  67. package/dist/components/sunburst.js +6 -0
  68. package/dist/components/sunburst.js.map +1 -0
  69. package/dist/components/sunburst.vue_vue_type_script_setup_true_lang.js +36 -0
  70. package/dist/components/sunburst.vue_vue_type_script_setup_true_lang.js.map +1 -0
  71. package/dist/components/tooltip.js +6 -0
  72. package/dist/components/tooltip.js.map +1 -0
  73. package/dist/components/tooltip.vue_vue_type_script_setup_true_lang.js +31 -0
  74. package/dist/components/tooltip.vue_vue_type_script_setup_true_lang.js.map +1 -0
  75. package/dist/components/treemap.js +6 -0
  76. package/dist/components/treemap.js.map +1 -0
  77. package/dist/components/treemap.vue_vue_type_script_setup_true_lang.js +33 -0
  78. package/dist/components/treemap.vue_vue_type_script_setup_true_lang.js.map +1 -0
  79. package/dist/components/waterfall.js +6 -0
  80. package/dist/components/waterfall.js.map +1 -0
  81. package/dist/components/waterfall.vue_vue_type_script_setup_true_lang.js +49 -0
  82. package/dist/components/waterfall.vue_vue_type_script_setup_true_lang.js.map +1 -0
  83. package/dist/components/zoom.js +6 -0
  84. package/dist/components/zoom.js.map +1 -0
  85. package/dist/components/zoom.vue_vue_type_script_setup_true_lang.js +37 -0
  86. package/dist/components/zoom.vue_vue_type_script_setup_true_lang.js.map +1 -0
  87. package/dist/context.js +30 -0
  88. package/dist/context.js.map +1 -0
  89. package/dist/core/bar.js +223 -0
  90. package/dist/core/bar.js.map +1 -0
  91. package/dist/core/box.js +150 -0
  92. package/dist/core/box.js.map +1 -0
  93. package/dist/core/colors.js +58 -0
  94. package/dist/core/colors.js.map +1 -0
  95. package/dist/core/data.js +257 -0
  96. package/dist/core/data.js.map +1 -0
  97. package/dist/core/decimate.js +211 -0
  98. package/dist/core/decimate.js.map +1 -0
  99. package/dist/core/format.js +151 -0
  100. package/dist/core/format.js.map +1 -0
  101. package/dist/core/funnel.js +68 -0
  102. package/dist/core/funnel.js.map +1 -0
  103. package/dist/core/grid.js +87 -0
  104. package/dist/core/grid.js.map +1 -0
  105. package/dist/core/heatmap.js +187 -0
  106. package/dist/core/heatmap.js.map +1 -0
  107. package/dist/core/histogram.js +81 -0
  108. package/dist/core/histogram.js.map +1 -0
  109. package/dist/core/hit.js +115 -0
  110. package/dist/core/hit.js.map +1 -0
  111. package/dist/core/labels.js +141 -0
  112. package/dist/core/labels.js.map +1 -0
  113. package/dist/core/layout.js +1002 -0
  114. package/dist/core/layout.js.map +1 -0
  115. package/dist/core/line.js +230 -0
  116. package/dist/core/line.js.map +1 -0
  117. package/dist/core/marker.js +205 -0
  118. package/dist/core/marker.js.map +1 -0
  119. package/dist/core/model.js +391 -0
  120. package/dist/core/model.js.map +1 -0
  121. package/dist/core/painter.js +79 -0
  122. package/dist/core/painter.js.map +1 -0
  123. package/dist/core/pattern.js +102 -0
  124. package/dist/core/pattern.js.map +1 -0
  125. package/dist/core/pie.js +119 -0
  126. package/dist/core/pie.js.map +1 -0
  127. package/dist/core/radar.js +83 -0
  128. package/dist/core/radar.js.map +1 -0
  129. package/dist/core/scale.js +149 -0
  130. package/dist/core/scale.js.map +1 -0
  131. package/dist/core/scatter.js +263 -0
  132. package/dist/core/scatter.js.map +1 -0
  133. package/dist/core/svg.js +209 -0
  134. package/dist/core/svg.js.map +1 -0
  135. package/dist/core/sync.js +21 -0
  136. package/dist/core/sync.js.map +1 -0
  137. package/dist/core/time.js +217 -0
  138. package/dist/core/time.js.map +1 -0
  139. package/dist/core/tree.js +348 -0
  140. package/dist/core/tree.js.map +1 -0
  141. package/dist/core/warn.js +11 -0
  142. package/dist/core/warn.js.map +1 -0
  143. package/dist/core/waterfall.js +134 -0
  144. package/dist/core/waterfall.js.map +1 -0
  145. package/dist/core/window.js +94 -0
  146. package/dist/core/window.js.map +1 -0
  147. package/dist/define.js +62 -0
  148. package/dist/define.js.map +1 -0
  149. package/dist/index.js +49 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/locale.js +170 -0
  152. package/dist/locale.js.map +1 -0
  153. package/dist/overlay.js +6 -0
  154. package/dist/overlay.js.map +1 -0
  155. package/dist/overlay.vue_vue_type_script_setup_true_lang.js +207 -0
  156. package/dist/overlay.vue_vue_type_script_setup_true_lang.js.map +1 -0
  157. package/dist/pointer.js +6 -0
  158. package/dist/pointer.js.map +1 -0
  159. package/dist/pointer.vue_vue_type_script_setup_true_lang.js +136 -0
  160. package/dist/pointer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  161. package/dist/static.js +6 -0
  162. package/dist/static.js.map +1 -0
  163. package/dist/static.vue_vue_type_script_setup_true_lang.js +34 -0
  164. package/dist/static.vue_vue_type_script_setup_true_lang.js.map +1 -0
  165. package/dist/style.css +1 -0
  166. package/dist/style.d.ts +1 -0
  167. package/dist/style.js +3 -0
  168. package/dist/table.js +6 -0
  169. package/dist/table.js.map +1 -0
  170. package/dist/table.vue_vue_type_script_setup_true_lang.js +52 -0
  171. package/dist/table.vue_vue_type_script_setup_true_lang.js.map +1 -0
  172. package/dist/types/chart.vue.d.ts +24 -0
  173. package/dist/types/components/area.vue.d.ts +16 -0
  174. package/dist/types/components/axis.vue.d.ts +8 -0
  175. package/dist/types/components/bar.vue.d.ts +14 -0
  176. package/dist/types/components/boxplot.vue.d.ts +14 -0
  177. package/dist/types/components/brush.vue.d.ts +22 -0
  178. package/dist/types/components/funnel.vue.d.ts +14 -0
  179. package/dist/types/components/gauge.vue.d.ts +17 -0
  180. package/dist/types/components/heatmap.vue.d.ts +14 -0
  181. package/dist/types/components/histogram.vue.d.ts +14 -0
  182. package/dist/types/components/line.vue.d.ts +16 -0
  183. package/dist/types/components/marker.vue.d.ts +6 -0
  184. package/dist/types/components/pie.vue.d.ts +23 -0
  185. package/dist/types/components/radar.vue.d.ts +16 -0
  186. package/dist/types/components/range.vue.d.ts +12 -0
  187. package/dist/types/components/scatter.vue.d.ts +14 -0
  188. package/dist/types/components/sunburst.vue.d.ts +17 -0
  189. package/dist/types/components/tooltip.vue.d.ts +13 -0
  190. package/dist/types/components/treemap.vue.d.ts +8 -0
  191. package/dist/types/components/waterfall.vue.d.ts +16 -0
  192. package/dist/types/components/zoom.vue.d.ts +18 -0
  193. package/dist/types/context.d.ts +87 -0
  194. package/dist/types/core/bar.d.ts +38 -0
  195. package/dist/types/core/box.d.ts +25 -0
  196. package/dist/types/core/colors.d.ts +16 -0
  197. package/dist/types/core/data.d.ts +72 -0
  198. package/dist/types/core/decimate.d.ts +39 -0
  199. package/dist/types/core/format.d.ts +33 -0
  200. package/dist/types/core/funnel.d.ts +15 -0
  201. package/dist/types/core/grid.d.ts +18 -0
  202. package/dist/types/core/heatmap.d.ts +17 -0
  203. package/dist/types/core/histogram.d.ts +23 -0
  204. package/dist/types/core/hit.d.ts +31 -0
  205. package/dist/types/core/labels.d.ts +45 -0
  206. package/dist/types/core/layout.d.ts +259 -0
  207. package/dist/types/core/line.d.ts +36 -0
  208. package/dist/types/core/marker.d.ts +67 -0
  209. package/dist/types/core/model.d.ts +86 -0
  210. package/dist/types/core/painter.d.ts +34 -0
  211. package/dist/types/core/pattern.d.ts +14 -0
  212. package/dist/types/core/pie.d.ts +66 -0
  213. package/dist/types/core/radar.d.ts +12 -0
  214. package/dist/types/core/scale.d.ts +60 -0
  215. package/dist/types/core/scatter.d.ts +16 -0
  216. package/dist/types/core/series.d.ts +228 -0
  217. package/dist/types/core/svg.d.ts +63 -0
  218. package/dist/types/core/sync.d.ts +8 -0
  219. package/dist/types/core/time.d.ts +20 -0
  220. package/dist/types/core/tree.d.ts +84 -0
  221. package/dist/types/core/warn.d.ts +4 -0
  222. package/dist/types/core/waterfall.d.ts +24 -0
  223. package/dist/types/core/window.d.ts +36 -0
  224. package/dist/types/define.d.ts +115 -0
  225. package/dist/types/index.d.ts +363 -0
  226. package/dist/types/locale.d.ts +100 -0
  227. package/dist/types/overlay.vue.d.ts +95 -0
  228. package/dist/types/pointer.vue.d.ts +53 -0
  229. package/dist/types/static.vue.d.ts +24 -0
  230. package/dist/types/table.vue.d.ts +19 -0
  231. package/dist/types/types.d.ts +555 -0
  232. package/dist/types/zoom-layer.vue.d.ts +41 -0
  233. package/dist/zoom-layer.js +6 -0
  234. package/dist/zoom-layer.js.map +1 -0
  235. package/dist/zoom-layer.vue_vue_type_script_setup_true_lang.js +210 -0
  236. package/dist/zoom-layer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  237. package/package.json +53 -4
@@ -0,0 +1,555 @@
1
+ import type { ChartAccessor, ChartData, ChartRow } from './core/data';
2
+ import type { ChartPattern } from './core/pattern';
3
+ import type { ChartAxisRole, ChartAxisType, ChartLegendPlacement, ChartTickValue } from './core/layout';
4
+ import type { Tone } from 'dou-ui';
5
+ import type { ChartCategorySort } from './core/model';
6
+ import type { ChartSeriesProps, ChartValueAxis } from './core/series';
7
+ import type { ChartMessagesOverride } from './locale';
8
+ export interface ChartProps {
9
+ /** The rows to draw. Replace the array to update it; for large data keep it in a `shallowRef`. */
10
+ data?: ChartData;
11
+ /**
12
+ * The x of each row: a key or a function. Numbers make a number axis,
13
+ * dates (`Date`, `'2026-10-31'`, `'2026-10-31 09:30'`) a time axis, and
14
+ * anything else categories. Without it, rows are placed by their index.
15
+ */
16
+ x?: ChartAccessor;
17
+ /** Height, a number in px or any CSS length. The width fills the container. */
18
+ height?: number | string;
19
+ /** The chart's accessible name, read out instead of the generated summary. */
20
+ ariaLabel?: string;
21
+ /** The legend: shown when there is more than one series, or slice of a pie; `true` or `false` shows or hides it. */
22
+ legend?: boolean;
23
+ /**
24
+ * Where the legend goes: `bottom` (the default), `top` or `right`.
25
+ * Entries that don't fit in three rows (or down the chart's height)
26
+ * scroll. On a chart narrower than 480px, `right` goes to the bottom,
27
+ * where it doesn't squeeze the plot.
28
+ */
29
+ legendPlacement?: ChartLegendPlacement;
30
+ /**
31
+ * Colors the series (and a pie's slices) take in turn, in place of the
32
+ * theme's eight: CSS colors or tones. A pie takes them from the first.
33
+ */
34
+ palette?: string[];
35
+ /**
36
+ * Gives each series with a fill (bars, areas) and each slice a pattern
37
+ * over its color, so they can be told apart in print or in grays.
38
+ */
39
+ patterns?: boolean;
40
+ /**
41
+ * Lay x down the left side and values along the bottom: bars that are
42
+ * easier to read across, with room for long category names. Axes and
43
+ * series keep their meaning (`x`, `y`, `y2`); only where they are drawn changes.
44
+ */
45
+ horizontal?: boolean;
46
+ /**
47
+ * Shows the data as a table in the chart's place (`v-model:table`): each
48
+ * x a row and each series a column, with values as the axes write them.
49
+ * For readers who'd rather go through the numbers, or copy them.
50
+ */
51
+ table?: boolean;
52
+ /** Texts to override. */
53
+ messages?: ChartMessagesOverride;
54
+ /** Shows that data is on its way: what is drawn fades and a spinner turns over it. */
55
+ loading?: boolean;
56
+ /**
57
+ * The width the chart is drawn at on the server, in px: the page shows it
58
+ * as an image until the browser draws it at its own width.
59
+ */
60
+ ssrWidth?: number;
61
+ }
62
+ export interface ChartSlots {
63
+ /** Series, axes and other parts of the chart. */
64
+ default?: () => unknown;
65
+ /** Shown instead of the chart when no series has a value. */
66
+ empty?: () => unknown;
67
+ }
68
+ export interface ChartExportOptions {
69
+ /** Fill the background with the chart's surface color. On by default; `false` leaves it clear. */
70
+ background?: boolean;
71
+ /** Room around the chart, in px. 16 by default. */
72
+ padding?: number;
73
+ }
74
+ export interface ChartImageOptions extends ChartExportOptions {
75
+ /** Pixels per CSS px. 2 by default, sharp on most screens. */
76
+ pixelRatio?: number;
77
+ }
78
+ /** What a `DouChart` ref gives. */
79
+ export interface ChartExpose {
80
+ /** The chart as it is shown, as an SVG document: series, markers, labels and legend. */
81
+ exportSVG: (options?: ChartExportOptions) => string;
82
+ /** The chart as a PNG image. */
83
+ exportPNG: (options?: ChartImageOptions) => Promise<Blob>;
84
+ }
85
+ export interface ChartMarkerProps {
86
+ /**
87
+ * A line across x at this value: a date, a category, a number. Give
88
+ * `[from, to]` for a band between two values.
89
+ */
90
+ x?: ChartTickValue | ChartInterval;
91
+ /**
92
+ * A line at this value, such as a target. Give `[from, to]` for a band.
93
+ * With a single `x` as well, a point. The value axis reaches it.
94
+ */
95
+ y?: number | [from: number, to: number];
96
+ /** The value axis `y` is on: `y2` for the second one. */
97
+ axis?: ChartValueAxis;
98
+ /** Text shown by the marker. */
99
+ label?: string;
100
+ /** The marker's color. Neutral by default. */
101
+ tone?: Tone;
102
+ /** Draws the line dashed, so it stands apart from the data. On by default; `false` for a solid line. */
103
+ dashed?: boolean;
104
+ }
105
+ export interface ChartAxisProps {
106
+ /**
107
+ * What the axis measures: `x`, the values (`y`), or a second kind of
108
+ * values (`y2`, for series with `axis="y2"`). x is drawn at the bottom,
109
+ * y on the left and y2 on the right; on a `horizontal` chart, x on the
110
+ * left, y at the bottom and y2 at the top.
111
+ */
112
+ for: ChartAxisRole;
113
+ /**
114
+ * How values are spaced. The x axis follows the data by default (numbers,
115
+ * dates or categories); value axes are `linear` unless set to `log`.
116
+ */
117
+ type?: ChartAxisType;
118
+ /** Where the axis starts; the data's smallest value (rounded out) by default. */
119
+ min?: number | string | Date;
120
+ /** Where the axis ends; the data's largest value (rounded out) by default. */
121
+ max?: number | string | Date;
122
+ /** Whether a value axis reaches 0. On by default when a series grows from 0 (areas, bars). */
123
+ zero?: boolean;
124
+ /** Round the ends out to tick values. On for value axes, off for the x axis. */
125
+ nice?: boolean;
126
+ /** About how many ticks to show, or exactly which values. */
127
+ ticks?: number | ChartTickValue[];
128
+ /**
129
+ * Stacks on this value axis show each part's share of the whole: every
130
+ * stack reaches 100%, and tick labels show percentages unless `format`
131
+ * is given. The tooltip shows both the value and its share.
132
+ */
133
+ percent?: boolean;
134
+ /** Formats tick labels: numbers, `Date`s on time axes, the category on category axes. */
135
+ format?: (value: any) => string;
136
+ /** Lines across the plot at each tick. On for `y` (or `y2` when it is alone), off for the others. */
137
+ grid?: boolean;
138
+ /** A short title: at the top for value axes (at the end for `y` on a horizontal chart), at the end of the x axis. */
139
+ title?: string;
140
+ /** Keep the axis (and its scale) but don't show it. */
141
+ hidden?: boolean;
142
+ /**
143
+ * The room for tick labels, in px, for an axis drawn down the side.
144
+ * Give charts stacked one above another the same value to line up their plots.
145
+ */
146
+ labelWidth?: number;
147
+ /**
148
+ * Runs the axis the other way: values down from the top (a ranking, 1st
149
+ * at the top), x from the right (from the bottom, on a horizontal chart).
150
+ */
151
+ reverse?: boolean;
152
+ /**
153
+ * For a category x axis: the order of the categories. `asc` and
154
+ * `desc` order them by their totals (the sum of the series shown);
155
+ * a function compares two category names. As in the data by default.
156
+ */
157
+ sort?: ChartCategorySort;
158
+ }
159
+ export interface ChartLineProps extends Omit<ChartSeriesProps, 'color'> {
160
+ /** Any CSS color. Defaults to the next color of the chart palette. */
161
+ color?: string;
162
+ /** Curve through the points without swinging past them. Dense data is drawn straight. */
163
+ smooth?: boolean;
164
+ /** Dots on the points: always, never, or `auto` when there is room for them. */
165
+ dots?: boolean | 'auto';
166
+ dashed?: boolean;
167
+ /** Line width in px. */
168
+ lineWidth?: number;
169
+ /** Join the line across gaps (`null` values) instead of breaking it. */
170
+ connectNulls?: boolean;
171
+ /**
172
+ * Steps from point to point instead of a slope: `after` (or `true`) keeps
173
+ * each value until the next x, `before` takes the next value at once,
174
+ * `middle` changes halfway. `smooth` doesn't apply.
175
+ */
176
+ step?: boolean | 'before' | 'after' | 'middle';
177
+ /**
178
+ * Shows each value as text: `true` writes it as the value axis does (a
179
+ * share, with a decimal, on a `percent` axis), a function writes its own
180
+ * (`null` or `undefined` leaves it out). Labels that would cover others
181
+ * are left out.
182
+ */
183
+ labels?: boolean | ChartLabelFormat;
184
+ /** Where labels go: above each point (`point`), or only beside the last one (`end`). */
185
+ labelPosition?: 'point' | 'end';
186
+ }
187
+ /** What a `labels` function gets: the value, and what it belongs to. */
188
+ export interface ChartDataLabel {
189
+ /** The value as given. */
190
+ value: number;
191
+ /** In a stack on a `percent` axis, and for a pie's slice: its part of the whole, 0 to 1. */
192
+ share?: number;
193
+ /** A band's bottom (`y0`). */
194
+ low?: number;
195
+ /** The series' name; for a pie, the slice's; for a tree, the node's. */
196
+ name: string;
197
+ row: ChartRow;
198
+ /** The row's index; for a treemap's or sunburst's node, its place among its siblings. */
199
+ index: number;
200
+ /** For a treemap's or sunburst's node: its level, 1 for the top. */
201
+ depth?: number;
202
+ }
203
+ /** The text of a data label; `null` or `undefined` for none. */
204
+ export type ChartLabelFormat = (label: ChartDataLabel) => string | null | undefined;
205
+ export interface ChartAreaProps extends ChartLineProps {
206
+ /** A pattern over the fill; `none` for none even when the chart's `patterns` is on. */
207
+ pattern?: ChartPattern | 'none';
208
+ /** Stack on the series before it with the same `stack` name (`true` is one shared stack). */
209
+ stack?: string | boolean;
210
+ /**
211
+ * The bottom of the area for each row, a key or a function: the area is
212
+ * then a band from it up to `y` (a forecast's range, a day's low and
213
+ * high) instead of growing from 0. Not with `stack`.
214
+ */
215
+ y0?: ChartAccessor;
216
+ }
217
+ /**
218
+ * The color of each bar or point, as a function of its row: any CSS color
219
+ * or a tone (`danger`, `neutral`…); `undefined` keeps the series' color.
220
+ */
221
+ export type ChartItemColor = (row: ChartRow, index: number) => string | undefined;
222
+ export interface ChartBarProps extends ChartSeriesProps {
223
+ /** A pattern over the bars; `none` for none even when the chart's `patterns` is on. */
224
+ pattern?: ChartPattern | 'none';
225
+ /**
226
+ * Any CSS color for all the bars, or a function that gives each bar its own
227
+ * (a CSS color or a tone; `undefined` keeps the series' color, as in the legend).
228
+ */
229
+ color?: string | ChartItemColor;
230
+ /** Stack on the bars before it with the same `stack` name (`true` is one shared stack). */
231
+ stack?: string | boolean;
232
+ /** Corner radius of the bar's end, in px. In a stack, only the outermost bar is rounded. */
233
+ radius?: number;
234
+ /** Shows each value as text, as for lines. */
235
+ labels?: boolean | ChartLabelFormat;
236
+ /**
237
+ * Where labels go: past the bar's end (`outside`) or in it (`inside`).
238
+ * Stacked bars default to `inside`, the others to `outside`. A label
239
+ * that doesn't fit inside its bar is left out.
240
+ */
241
+ labelPosition?: 'outside' | 'inside';
242
+ }
243
+ export interface ChartBoxplotProps extends ChartSeriesProps {
244
+ /** Each row's group of values, an array: a key of the row or a function of it. */
245
+ y: ChartAccessor;
246
+ /** Any CSS color for the boxes. */
247
+ color?: string;
248
+ /**
249
+ * How far the whiskers reach past the box, in box lengths; values past
250
+ * them are drawn as dots of their own. `Infinity` reaches all the values.
251
+ */
252
+ whisker?: number;
253
+ }
254
+ export interface ChartHistogramProps extends Omit<ChartSeriesProps, 'y' | 'x' | 'color'> {
255
+ /** The value of each row, counted into bins: a key of the row or a function of it. */
256
+ value: ChartAccessor;
257
+ /** About how many bins: their width is a round number near the span over it. Defaults by the number of values. */
258
+ bins?: number;
259
+ /** The width of each bin, exactly; takes the place of `bins`. */
260
+ step?: number;
261
+ /** Any CSS color for the bars. */
262
+ color?: string;
263
+ /** Corner radius of the bars' tops, in px. */
264
+ radius?: number;
265
+ /** A pattern over the bars; `none` for none even when the chart's `patterns` is on. */
266
+ pattern?: ChartPattern | 'none';
267
+ /** Shows each bin's count as text. */
268
+ labels?: boolean | ChartLabelFormat;
269
+ /** Where labels go: above each bar (`outside`) or in it (`inside`). */
270
+ labelPosition?: 'outside' | 'inside';
271
+ }
272
+ export interface ChartWaterfallProps extends ChartSeriesProps {
273
+ /** The change of each row; for a total row, it is not read. */
274
+ y: ChartAccessor;
275
+ /**
276
+ * Whether a row is a total: a key of the row or a function of it. A total
277
+ * row is a bar from 0 up to the running total of the rows before it.
278
+ */
279
+ total?: ChartAccessor;
280
+ /**
281
+ * Any CSS color for all the bars, or a function that gives each bar its
282
+ * own. By default, rises are in the success tone, falls in the danger
283
+ * tone and totals in the series' color.
284
+ */
285
+ color?: string | ChartItemColor;
286
+ /** Corner radius of the bars, in px. */
287
+ radius?: number;
288
+ /** Dashed lines from each bar to the next, at the total they share. */
289
+ connectors?: boolean;
290
+ /** Shows each change (with its sign) and each total as text. */
291
+ labels?: boolean | ChartLabelFormat;
292
+ /** Where labels go: past the bar's end (`outside`) or in it (`inside`). */
293
+ labelPosition?: 'outside' | 'inside';
294
+ }
295
+ export interface ChartScatterProps extends ChartSeriesProps {
296
+ /** Any CSS color for all the points, or a function that gives each point its own, as for bars. */
297
+ color?: string | ChartItemColor;
298
+ /** The size of each point, a key or a function: makes bubbles whose area grows with it. */
299
+ size?: ChartAccessor;
300
+ /** What `size` is, shown in the tooltip; defaults to `size` when that is a key. */
301
+ sizeName?: string;
302
+ /** The name of each point (a key or a function), the title of its tooltip; the series' name by default. */
303
+ label?: ChartAccessor;
304
+ /** Dot radius in px; with `size`, the radius of the largest bubble. */
305
+ radius?: number;
306
+ }
307
+ export interface ChartHeatmapProps extends Omit<ChartSeriesProps, 'color' | 'axis'> {
308
+ /** The category of each row down the side (a key or a function): one row of cells each, the first at the top. */
309
+ y: ChartAccessor;
310
+ /** The value of each cell, a key or a function: the larger, the stronger its color. */
311
+ value: ChartAccessor;
312
+ /**
313
+ * The color the scale runs to, from the chart's surface: any CSS color.
314
+ * Defaults to the palette's, as other series.
315
+ */
316
+ color?: string;
317
+ /** The value the scale starts at, as an axis' `min`; by default the smallest. Values below take its lightest color. */
318
+ min?: number;
319
+ /** The value the scale ends at; by default the largest. Values above take its strongest color. */
320
+ max?: number;
321
+ /** How values are written, in the tooltip, the labels and the scale; by default as numbers. */
322
+ format?: (value: number) => string;
323
+ /** Writes each cell's value in it, where it fits; a function writes its own text. */
324
+ labels?: boolean | ChartLabelFormat;
325
+ }
326
+ export interface ChartRadarProps extends Omit<ChartSeriesProps, 'color' | 'axis'> {
327
+ /** Any CSS color. Defaults to the next color of the chart palette. */
328
+ color?: string;
329
+ /** Dots on the corners; by default when there are 12 spokes or fewer. */
330
+ dots?: boolean;
331
+ /** The width of the outline, in px. */
332
+ lineWidth?: number;
333
+ }
334
+ export interface ChartFunnelProps extends Omit<ChartSeriesProps, 'color' | 'axis'> {
335
+ /** Any CSS color, for every stage. Defaults to the next color of the chart palette. */
336
+ color?: string;
337
+ /** Corner radius of the bars, in px. */
338
+ radius?: number;
339
+ }
340
+ export interface ChartPieProps {
341
+ /** The value of each slice: a key of the row or a function of it. Values of 0 or less are left out. */
342
+ value: ChartAccessor;
343
+ /** The name of each slice, shown in the legend; defaults to the chart's `x`. */
344
+ label?: ChartAccessor;
345
+ /** Rows of this pie alone; defaults to the chart's `data`. */
346
+ data?: ChartData;
347
+ /** What the pie shows, read out before its slices. */
348
+ name?: string;
349
+ /**
350
+ * The color of each slice, a key or a function: any CSS color, or a tone
351
+ * (`danger`, `neutral`…). Without it, slices take the palette's colors in
352
+ * turn, leaving out the neutral first one, which `neutral` gives to "other".
353
+ */
354
+ color?: ChartAccessor<string | undefined>;
355
+ /** The size of the hole, as a part of the radius: `0` is a pie, `0.6` a donut. */
356
+ innerRadius?: number;
357
+ /**
358
+ * Shows text by each slice: `true` writes its name and share outside,
359
+ * or its share inside; a function writes its own (`null` or
360
+ * `undefined` leaves it out).
361
+ */
362
+ labels?: boolean | ChartLabelFormat;
363
+ /**
364
+ * Where labels go: outside the pie, joined to their slice by a line,
365
+ * or inside each slice (left out where a slice is too small).
366
+ */
367
+ labelPosition?: 'outside' | 'inside';
368
+ /**
369
+ * Where the slices start and end, in degrees clockwise from 12 o'clock:
370
+ * `-90` to `90` makes a half pie (a half donut, with `inner-radius`).
371
+ * The whole turn by default.
372
+ */
373
+ startAngle?: number;
374
+ endAngle?: number;
375
+ /**
376
+ * A rose: each slice takes the same angle and reaches out by its value,
377
+ * its area in proportion to it.
378
+ */
379
+ rose?: boolean;
380
+ }
381
+ /** What a treemap and a sunburst take: a tree of nested rows. */
382
+ export interface ChartTreeProps {
383
+ /** The top level of the tree: rows, each with its children; defaults to the chart's `data`. */
384
+ data?: ChartRow[];
385
+ /** Each node's name. */
386
+ label?: ChartAccessor;
387
+ /** Each leaf's value; a node with children is the sum of theirs. */
388
+ value?: ChartAccessor;
389
+ /** Each node's children, an array of rows. */
390
+ children?: ChartAccessor;
391
+ /** What the whole is, read out first. */
392
+ name?: string;
393
+ /**
394
+ * Each node's color: a key of its row, or a function of the row and its
395
+ * level (1 for the top), giving a CSS color or a tone; nothing takes the
396
+ * parent's color, and the top level the palette's.
397
+ */
398
+ color?: string | ((row: ChartRow, depth: number) => string | undefined);
399
+ /**
400
+ * Writes each node's name in it, where it fits (`true`), or what a
401
+ * function gives; its `share` is the node's part of the whole.
402
+ */
403
+ labels?: boolean | ChartLabelFormat;
404
+ }
405
+ export type ChartTreemapProps = ChartTreeProps;
406
+ export interface ChartSunburstProps extends ChartTreeProps {
407
+ /** The hole in the middle as a share of the radius. */
408
+ innerRadius?: number;
409
+ }
410
+ export interface ChartSunburstSlots {
411
+ /** What goes in the hole in the middle. */
412
+ default?: () => any;
413
+ }
414
+ export interface ChartGaugeProps {
415
+ /** The value shown. */
416
+ value: number;
417
+ /** The start of the track. */
418
+ min?: number;
419
+ /** The end of the track. */
420
+ max?: number;
421
+ /** What the value is: under it in the middle, and read out. */
422
+ name?: string;
423
+ /**
424
+ * The color of the value's arc: a CSS color or a tone, or a function of
425
+ * the value giving one (`success` when it is high enough, say).
426
+ */
427
+ color?: string | ((value: number) => string);
428
+ /** The value as text, in the middle and read out. */
429
+ format?: (value: number) => string;
430
+ /** The hole in the middle as a share of the radius: how thin the arc is. */
431
+ innerRadius?: number;
432
+ /** Where the track starts, in degrees clockwise from 12 o'clock. */
433
+ startAngle?: number;
434
+ /** Where it ends, in degrees. */
435
+ endAngle?: number;
436
+ }
437
+ export interface ChartGaugeSlots {
438
+ /** What goes in the middle, in place of the value and its name. */
439
+ default?: (props: {
440
+ value: number;
441
+ text: string;
442
+ }) => any;
443
+ }
444
+ export interface ChartTooltipProps {
445
+ /**
446
+ * What it shows: every series at the x under the pointer (`axis`), or
447
+ * the one point or slice under it (`item`). `item` for scatters and pies,
448
+ * `axis` for the others.
449
+ */
450
+ trigger?: 'axis' | 'item';
451
+ /** A line across the plot at the x under the pointer (a shaded band for bars). On by default. */
452
+ crosshair?: boolean;
453
+ /** No tooltip: the chart doesn't follow the pointer and can't be focused. */
454
+ disabled?: boolean;
455
+ /**
456
+ * Charts whose tooltips have the same `group` follow one pointer: the x
457
+ * under it in one chart shows, with its tooltip, in the others. Charts
458
+ * of a group match x by its value (a category's name, a time, a number).
459
+ */
460
+ group?: string;
461
+ }
462
+ /** One line of a tooltip. */
463
+ export interface ChartTooltipItem {
464
+ /** The series' or slice's name, or what the value is (`x`) for one point. */
465
+ name: string;
466
+ /** The value as the axis shows it. */
467
+ text: string;
468
+ /** The value itself; `undefined` for an x that isn't a number. */
469
+ value?: number;
470
+ /** The series' or slice's color; `undefined` for a line that isn't one. */
471
+ color?: string;
472
+ /** The row the value comes from. */
473
+ row?: ChartRow;
474
+ /** Its series is the one under the pointer, brought forward. */
475
+ active?: boolean;
476
+ }
477
+ export interface ChartTooltipSlots {
478
+ /** The tooltip's content. */
479
+ default?: (props: {
480
+ /** The x (axis tooltips), or the series (one point). */
481
+ title?: string;
482
+ items: ChartTooltipItem[];
483
+ /** A note under the values: how many slices of a pie are turned off. */
484
+ note?: string;
485
+ }) => unknown;
486
+ }
487
+ /**
488
+ * What `select` and `hover` give: a bar, point or slice (or an x with every
489
+ * series at it), as the tooltip shows it there.
490
+ */
491
+ export interface ChartPointEvent {
492
+ /** The x as given: the category, a `Date` on a time axis, or the number; a slice's label. */
493
+ x: unknown;
494
+ title?: string;
495
+ /** One per series at the x, or the one point or slice. */
496
+ items: ChartTooltipItem[];
497
+ }
498
+ export interface ChartEmits {
499
+ /** A bar, point or slice was clicked, or Enter pressed on it: what the tooltip shows there. */
500
+ select: [event: ChartPointEvent];
501
+ /**
502
+ * The tooltip moved to something else (by pointer, finger or the arrow keys),
503
+ * or what it shows there changed with the data; `null` when it closes.
504
+ */
505
+ hover: [event: ChartPointEvent | null];
506
+ /** The table view was closed with Escape. */
507
+ 'update:table': [value: boolean];
508
+ }
509
+ export interface ChartPieSlots {
510
+ /** Shown in the hole of a donut: a total, a title. */
511
+ default?: () => unknown;
512
+ }
513
+ /**
514
+ * A stretch of an axis, from one value to another: numbers, `Date`s on a
515
+ * time axis, categories on a category axis (both ends included).
516
+ */
517
+ export type ChartInterval = [from: ChartTickValue, to: ChartTickValue];
518
+ /** Which axes a part works along: x, the values, or both. */
519
+ export type ChartZoomAxis = 'x' | 'y' | 'xy';
520
+ export interface ChartZoomProps {
521
+ /** The axes to zoom and pan: x (the default), the values (`y`, with `y2` following), or both. */
522
+ axis?: ChartZoomAxis;
523
+ /**
524
+ * Zoom with the wheel alone. By default the wheel scrolls the page, and
525
+ * zooms with Ctrl (⌘ on a Mac) held; pinching on a trackpad zooms either way.
526
+ */
527
+ wheel?: boolean;
528
+ /** Turns zooming off and shows the whole chart. */
529
+ disabled?: boolean;
530
+ }
531
+ export interface ChartBrushProps {
532
+ /** Select a stretch of x (the default), of the values (`y`), or a box of both. */
533
+ axis?: ChartZoomAxis;
534
+ /** Fade what is outside the selection. On by default. */
535
+ dim?: boolean;
536
+ /** Turns selecting off. */
537
+ disabled?: boolean;
538
+ }
539
+ /**
540
+ * What `select` of `DouChartBrush` gives: the stretch selected and the rows
541
+ * in it. When the selection is let go, neither `x` nor `y` and no rows.
542
+ */
543
+ export interface ChartBrushEvent {
544
+ /** The stretch of x, unless only values were selected. */
545
+ x?: ChartInterval;
546
+ /** The stretch of values (on `y`, or on `y2` when it is alone), when they were selected. */
547
+ y?: ChartInterval;
548
+ /** The rows with a point in the selection, each once: by series, then along x. */
549
+ rows: ChartRow[];
550
+ /** The same, by series. */
551
+ series: Array<{
552
+ name: string;
553
+ rows: ChartRow[];
554
+ }>;
555
+ }
@@ -0,0 +1,41 @@
1
+ import { type ComputedRef } from 'vue';
2
+ import type { Rect } from './core/painter';
3
+ /**
4
+ * What goes over the plot for zooming and selecting: the selection being
5
+ * dragged or kept, and the range strip with its handles. Kept apart from
6
+ * the chart, so a drag doesn't render the chart's slot again.
7
+ */
8
+ export interface ZoomLayerState {
9
+ /** The selection, in px from the chart's top left. */
10
+ brush: ComputedRef<Rect | null>;
11
+ /** The strip, and the part of x shown (0 to 1 of the whole). */
12
+ strip: ComputedRef<{
13
+ rect: Rect;
14
+ horizontal: boolean;
15
+ from: number;
16
+ to: number;
17
+ } | null>;
18
+ /** The smallest part of x that can be shown, 0 to 1. */
19
+ least: ComputedRef<number>;
20
+ /** How far a key moves a handle, 0 to 1. */
21
+ step: ComputedRef<number>;
22
+ /** The x at each end, as the axis shows it. */
23
+ texts: ComputedRef<[string, string]>;
24
+ labels: ComputedRef<[string, string]>;
25
+ /** Shows `from` to `to` (0 to 1); `settle` at the end of a drag. */
26
+ show: (from: number, to: number, settle: boolean) => void;
27
+ /** Shows all of x. */
28
+ reset: () => void;
29
+ /** A drag on the strip starts: the tooltip goes. */
30
+ start: () => void;
31
+ /** What the strip's sketch is drawn from: a new value only when it has to be drawn again. */
32
+ sketch: ComputedRef<unknown>;
33
+ /** Draws the series, small, on the strip's canvas. */
34
+ paint: (canvas: HTMLCanvasElement) => void;
35
+ }
36
+ type __VLS_Props = {
37
+ state: ZoomLayerState;
38
+ };
39
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
40
+ declare const _default: typeof __VLS_export;
41
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import zoom_layer_vue_vue_type_script_setup_true_lang_default from "./zoom-layer.vue_vue_type_script_setup_true_lang.js";
2
+ // src/zoom-layer.vue
3
+ var zoom_layer_default = zoom_layer_vue_vue_type_script_setup_true_lang_default;
4
+ export { zoom_layer_default as default };
5
+
6
+ //# sourceMappingURL=zoom-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zoom-layer.js","names":["_sfc_main"],"sources":["../src/zoom-layer.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { holdPointer, useNamespace, type PointerHold } from 'dou-ui'\nimport { computed, useTemplateRef, watchPostEffect, type ComputedRef } from 'vue'\nimport type { Rect } from './core/painter'\n\n/**\n * What goes over the plot for zooming and selecting: the selection being\n * dragged or kept, and the range strip with its handles. Kept apart from\n * the chart, so a drag doesn't render the chart's slot again.\n */\nexport interface ZoomLayerState {\n /** The selection, in px from the chart's top left. */\n brush: ComputedRef<Rect | null>\n /** The strip, and the part of x shown (0 to 1 of the whole). */\n strip: ComputedRef<{ rect: Rect; horizontal: boolean; from: number; to: number } | null>\n /** The smallest part of x that can be shown, 0 to 1. */\n least: ComputedRef<number>\n /** How far a key moves a handle, 0 to 1. */\n step: ComputedRef<number>\n /** The x at each end, as the axis shows it. */\n texts: ComputedRef<[string, string]>\n labels: ComputedRef<[string, string]>\n /** Shows `from` to `to` (0 to 1); `settle` at the end of a drag. */\n show: (from: number, to: number, settle: boolean) => void\n /** Shows all of x. */\n reset: () => void\n /** A drag on the strip starts: the tooltip goes. */\n start: () => void\n /** What the strip's sketch is drawn from: a new value only when it has to be drawn again. */\n sketch: ComputedRef<unknown>\n /** Draws the series, small, on the strip's canvas. */\n paint: (canvas: HTMLCanvasElement) => void\n}\n\ndefineOptions({ name: 'DouChartZoomLayer' })\n\nconst { state } = defineProps<{ state: ZoomLayerState }>()\nconst ns = useNamespace('chart')\nconst { brush, strip } = state\nconst canvas = useTemplateRef<HTMLCanvasElement>('canvas')\n\nwatchPostEffect(() => {\n // not on `strip`: moving the shown part leaves the sketch as it is\n if (canvas.value && state.sketch.value) state.paint(canvas.value)\n})\n\nconst px = (r: Rect) => ({\n transform: `translate(${r.x}px, ${r.y}px)`,\n width: `${r.width}px`,\n height: `${r.height}px`,\n})\n\n/** The shown part and the dimmed parts on either side, in px. */\nconst parts = computed(() => {\n const s = strip.value\n if (!s) return null\n const { rect, horizontal } = s\n const length = horizontal ? rect.height : rect.width\n const start = horizontal ? rect.y : rect.x\n const a = start + s.from * length\n const b = start + s.to * length\n const stretch = (from: number, to: number): Rect =>\n horizontal\n ? { x: rect.x, y: from, width: rect.width, height: to - from }\n : { x: from, y: rect.y, width: to - from, height: rect.height }\n return {\n before: stretch(start, a),\n window: stretch(a, b),\n after: stretch(b, start + length),\n ends: [a, b] as const,\n }\n})\n\n/* dragging a handle, the shown part, or the strip around it */\n\ntype Grip = 'from' | 'to' | 'window'\nlet drag: {\n grip: Grip\n start: number\n from: number\n to: number\n hold: PointerHold\n id: number\n} | null = null\n\nfunction along(event: PointerEvent): number {\n const s = strip.value!\n const el = event.currentTarget as HTMLElement\n const box = el.closest(`.${ns.e('range')}`)!.getBoundingClientRect()\n return s.horizontal\n ? (event.clientY - box.top) / box.height\n : (event.clientX - box.left) / box.width\n}\n\nfunction onPointerDown(event: PointerEvent, grip: Grip | 'track') {\n if (event.button !== 0 || !strip.value) return\n event.stopPropagation()\n event.preventDefault()\n state.start()\n const s = strip.value\n let { from, to } = s\n const at = along(event)\n if (grip === 'track') {\n // a press beside the shown part moves it there, and drags it from there\n const span = to - from\n from = Math.min(Math.max(0, at - span / 2), 1 - span)\n to = from + span\n state.show(from, to, false)\n grip = 'window'\n }\n const el = event.currentTarget as HTMLElement\n const hold = holdPointer(event, el)\n hold.grab()\n try {\n el.setPointerCapture?.(event.pointerId)\n } catch {\n // the pointer is already gone\n }\n drag = { grip, start: at, from, to, hold, id: event.pointerId }\n}\n\nfunction onPointerMove(event: PointerEvent) {\n if (!drag || event.pointerId !== drag.id) return\n const d = along(event) - drag.start\n state.show(...moved(drag.grip, drag.from, drag.to, d), false)\n}\n\nfunction onPointerUp(event: PointerEvent) {\n if (!drag || event.pointerId !== drag.id) return\n const d = along(event) - drag.start\n const grip = drag.grip\n drag.hold.release()\n const { from, to } = drag\n drag = null\n state.show(...moved(grip, from, to, d), true)\n}\n\nfunction onPointerCancel() {\n drag?.hold.release()\n drag = null\n}\n\n/** `from` and `to` after `grip` moved by `d`, kept in the strip and apart by the least. */\nfunction moved(grip: Grip, from: number, to: number, d: number): [number, number] {\n const least = state.least.value\n if (grip === 'from') return [Math.min(Math.max(0, from + d), to - least), to]\n if (grip === 'to') return [from, Math.max(Math.min(1, to + d), from + least)]\n const shift = Math.min(Math.max(d, -from), 1 - to)\n return [from + shift, to + shift]\n}\n\n/* the keys on a handle */\n\nfunction onKeydown(event: KeyboardEvent, grip: 'from' | 'to') {\n const s = strip.value\n if (!s) return\n const step = state.step.value\n const keys: Record<string, number> = {\n ArrowLeft: -step,\n ArrowDown: s.horizontal ? step : -step,\n ArrowRight: step,\n ArrowUp: s.horizontal ? -step : step,\n PageDown: -step * 10,\n PageUp: step * 10,\n Home: -Infinity,\n End: Infinity,\n }\n // down a vertical strip is further along x\n if (s.horizontal) [keys.PageDown, keys.PageUp] = [step * 10, -step * 10]\n const d = keys[event.key]\n if (d === undefined) return\n event.preventDefault()\n const at = grip === 'from' ? s.from : s.to\n const next = Number.isFinite(d) ? at + d : d < 0 ? 0 : 1\n state.show(...moved(grip, s.from, s.to, next - at), true)\n}\n\nconst percent = (value: number) => Math.round(value * 1000) / 10\n</script>\n\n<template>\n <div v-if=\"brush\" :class=\"ns.e('brush')\" :style=\"px(brush)\" aria-hidden=\"true\" />\n <div\n v-if=\"strip && parts\"\n :class=\"[ns.e('range'), ns.is('vertical', strip.horizontal)]\"\n :style=\"px(strip.rect)\"\n @pointerdown=\"(e) => onPointerDown(e, 'track')\"\n @pointermove=\"onPointerMove\"\n @pointerup=\"onPointerUp\"\n @pointercancel=\"onPointerCancel\"\n @dblclick.stop=\"state.reset()\"\n @click.stop\n >\n <canvas ref=\"canvas\" :class=\"ns.e('range-canvas')\" aria-hidden=\"true\" />\n <div\n :class=\"ns.e('range-shade')\"\n :style=\"\n px({ ...parts.before, x: parts.before.x - strip.rect.x, y: parts.before.y - strip.rect.y })\n \"\n />\n <div\n :class=\"ns.e('range-shade')\"\n :style=\"\n px({ ...parts.after, x: parts.after.x - strip.rect.x, y: parts.after.y - strip.rect.y })\n \"\n />\n <div\n :class=\"ns.e('range-window')\"\n :style=\"\n px({ ...parts.window, x: parts.window.x - strip.rect.x, y: parts.window.y - strip.rect.y })\n \"\n @pointerdown=\"(e) => onPointerDown(e, 'window')\"\n />\n <div\n v-for=\"(grip, i) in ['from', 'to'] as const\"\n :key=\"grip\"\n :class=\"ns.e('range-handle')\"\n role=\"slider\"\n tabindex=\"0\"\n :aria-label=\"state.labels.value[i]\"\n :aria-orientation=\"strip.horizontal ? 'vertical' : 'horizontal'\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n :aria-valuenow=\"percent(grip === 'from' ? strip.from : strip.to)\"\n :aria-valuetext=\"state.texts.value[i]\"\n :style=\"\n strip.horizontal\n ? { transform: `translate(0, ${parts.ends[i]! - strip.rect.y}px)` }\n : { transform: `translate(${parts.ends[i]! - strip.rect.x}px, 0)` }\n \"\n @pointerdown=\"(e) => onPointerDown(e, grip)\"\n @keydown=\"(e) => onKeydown(e, grip)\"\n />\n </div>\n</template>\n"],"mappings":""}