@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,207 @@
1
+ import { DouSpinner, DouTooltip, useNamespace } from "dou-ui";
2
+ import { Fragment, Transition, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, normalizeClass, normalizeStyle, onBeforeUnmount, openBlock, renderList, toDisplayString, unref, useId, withCtx } from "vue";
3
+ // src/overlay.vue?vue&type=script&setup=true&lang.ts
4
+ var _hoisted_1 = [
5
+ "aria-pressed",
6
+ "aria-describedby",
7
+ "onClick",
8
+ "onKeydown",
9
+ "onPointerdown",
10
+ "onPointerenter",
11
+ "onFocus"
12
+ ];
13
+ var _hoisted_2 = ["id"];
14
+ var HOLD = 500;
15
+ var LEGEND_PAD = 4;
16
+ var overlay_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
17
+ name: "DouChartOverlay",
18
+ __name: "overlay",
19
+ props: { state: {} },
20
+ setup(__props) {
21
+ const ns = useNamespace("chart");
22
+ const { shown, labels, titles, legend, legendBox, hole, toggle, isolate, hint, focus, markers, data, dataShown, dataFocus, empty, loading } = __props.state;
23
+ const Center = () => __props.state.center();
24
+ const hintId = useId();
25
+ /** How long a finger stays on an entry to show only it, in ms. */
26
+ let holdTimer;
27
+ /** A hold just showed one entry alone: the click that ends it isn't a toggle. */
28
+ let held = false;
29
+ function holdLegend(index) {
30
+ letGo();
31
+ held = false;
32
+ holdTimer = setTimeout(() => {
33
+ holdTimer = void 0;
34
+ held = true;
35
+ isolate(index);
36
+ }, HOLD);
37
+ }
38
+ function letGo() {
39
+ if (holdTimer) clearTimeout(holdTimer);
40
+ holdTimer = void 0;
41
+ }
42
+ function onLegendClick(event, index) {
43
+ if (held) {
44
+ held = false;
45
+ return;
46
+ }
47
+ if (event.altKey) isolate(index);
48
+ else toggle(index);
49
+ }
50
+ function onLegendKey(event, index) {
51
+ if (!event.altKey || event.key !== "Enter" && event.key !== " ") return;
52
+ event.preventDefault();
53
+ isolate(index);
54
+ }
55
+ /** No callout menu over an entry while it is held down. */
56
+ function noMenu(event) {
57
+ if (holdTimer || held) event.preventDefault();
58
+ }
59
+ onBeforeUnmount(letGo);
60
+ /** Room around the legend's entries in its box, so a focus ring isn't cut off where it scrolls. */
61
+ const Empty = () => __props.state.emptyContent();
62
+ const focusVisible = (e) => e.target.matches(":focus-visible");
63
+ return (_ctx, _cache) => {
64
+ return openBlock(), createElementBlock(Fragment, null, [
65
+ unref(shown) ? (openBlock(), createElementBlock("div", {
66
+ key: 0,
67
+ class: normalizeClass(unref(ns).e("labels")),
68
+ "aria-hidden": "true"
69
+ }, [
70
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(labels), (tick) => {
71
+ return openBlock(), createElementBlock("span", {
72
+ key: tick.key,
73
+ class: normalizeClass([
74
+ unref(ns).e("tick"),
75
+ unref(ns).is(tick.axis),
76
+ unref(ns).is("clipped", !!tick.clipped)
77
+ ]),
78
+ style: normalizeStyle({
79
+ transform: `translate(${tick.left}px, ${tick.top}px)`,
80
+ width: tick.clipped ? `${tick.width}px` : void 0
81
+ })
82
+ }, [createElementVNode("span", { class: normalizeClass(unref(ns).e("text")) }, toDisplayString(tick.text), 3)], 6);
83
+ }), 128)),
84
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(titles), (title) => {
85
+ return openBlock(), createElementBlock("span", {
86
+ key: title.key,
87
+ class: normalizeClass([unref(ns).e("title"), unref(ns).is("end", title.align === "end")]),
88
+ style: normalizeStyle({ transform: `translate(${title.left}px, ${title.top}px)` })
89
+ }, [createElementVNode("span", { class: normalizeClass(unref(ns).e("text")) }, toDisplayString(title.text), 3)], 6);
90
+ }), 128)),
91
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(markers), (marker) => {
92
+ return openBlock(), createElementBlock("span", {
93
+ key: marker.key,
94
+ class: normalizeClass([
95
+ unref(ns).e("marker"),
96
+ unref(ns).is(marker.tone),
97
+ unref(ns).is(marker.align),
98
+ unref(ns).is("backdrop", marker.backdrop)
99
+ ]),
100
+ style: normalizeStyle({ transform: `translate(${marker.left}px, ${marker.top}px)` })
101
+ }, [createElementVNode("span", { class: normalizeClass(unref(ns).e("text")) }, toDisplayString(marker.text), 3)], 6);
102
+ }), 128)),
103
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(data), (label) => {
104
+ return openBlock(), createElementBlock("span", {
105
+ key: `data:${label.key}`,
106
+ class: normalizeClass([
107
+ unref(ns).e("value"),
108
+ unref(ns).is(label.align),
109
+ unref(ns).is("inside", !!label.on),
110
+ unref(ns).is("hidden", !unref(dataShown)),
111
+ unref(ns).is("faded", unref(dataFocus) !== null && unref(dataFocus) !== label.series),
112
+ unref(ns).is("clipped", label.width !== void 0)
113
+ ]),
114
+ style: normalizeStyle({
115
+ transform: `translate(${label.left}px, ${label.top}px)`,
116
+ color: label.ink,
117
+ width: label.width === void 0 ? void 0 : `${label.width}px`
118
+ })
119
+ }, [createElementVNode("span", { class: normalizeClass(unref(ns).e("text")) }, toDisplayString(label.text), 3)], 6);
120
+ }), 128))
121
+ ], 2)) : createCommentVNode("", true),
122
+ unref(shown) && unref(legend).length && unref(legendBox) ? (openBlock(), createElementBlock("div", {
123
+ key: 1,
124
+ class: normalizeClass([unref(ns).e("legends"), unref(ns).is("scroll", unref(legendBox).scroll)]),
125
+ style: normalizeStyle({
126
+ left: `${unref(legendBox).x - LEGEND_PAD}px`,
127
+ top: `${unref(legendBox).y - LEGEND_PAD}px`,
128
+ width: `${unref(legendBox).width + 8}px`,
129
+ height: `${unref(legendBox).height + 8}px`
130
+ })
131
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(legend), (item) => {
132
+ return openBlock(), createBlock(unref(DouTooltip), {
133
+ key: `legend:${item.index}`,
134
+ content: item.text,
135
+ disabled: !item.clipped
136
+ }, {
137
+ default: withCtx(() => [createElementVNode("button", {
138
+ type: "button",
139
+ class: normalizeClass([
140
+ unref(ns).e("legend"),
141
+ unref(ns).is(item.kind),
142
+ unref(ns).is("dashed", item.dashed),
143
+ unref(ns).is("off", item.off),
144
+ unref(ns).is("locked", item.locked),
145
+ unref(ns).is("clipped", !!item.clipped)
146
+ ]),
147
+ style: normalizeStyle({
148
+ transform: `translate(${item.left - unref(legendBox).x + LEGEND_PAD}px, ${item.top - unref(legendBox).y + LEGEND_PAD}px)`,
149
+ width: item.clipped ? `${item.width}px` : void 0
150
+ }),
151
+ "aria-pressed": !item.off,
152
+ "aria-describedby": unref(hintId),
153
+ "aria-keyshortcuts": "Alt+Enter",
154
+ onClick: (e) => onLegendClick(e, item.index),
155
+ onKeydown: (e) => onLegendKey(e, item.index),
156
+ onPointerdown: (e) => e.pointerType === "touch" && holdLegend(item.index),
157
+ onPointerup: letGo,
158
+ onPointercancel: letGo,
159
+ onContextmenu: noMenu,
160
+ onPointerenter: (e) => e.pointerType !== "touch" && !item.off && unref(focus)(item.index),
161
+ onPointerleave: _cache[0] || (_cache[0] = ($event) => (letGo(), unref(focus)(null))),
162
+ onFocus: (e) => focusVisible(e) && !item.off && unref(focus)(item.index),
163
+ onBlur: _cache[1] || (_cache[1] = ($event) => unref(focus)(null))
164
+ }, [createElementVNode("span", {
165
+ class: normalizeClass(unref(ns).e("swatch")),
166
+ style: normalizeStyle(item.scale ? {
167
+ width: `${item.swatch}px`,
168
+ background: `linear-gradient(to right, ${item.scale.join(", ")})`
169
+ } : item.pattern ? {
170
+ color: item.color,
171
+ backgroundImage: item.pattern.image,
172
+ backgroundSize: item.pattern.size
173
+ } : { color: item.color })
174
+ }, null, 6), createElementVNode("span", { class: normalizeClass(unref(ns).e("text")) }, toDisplayString(item.text), 3)], 46, _hoisted_1)]),
175
+ _: 2
176
+ }, 1032, ["content", "disabled"]);
177
+ }), 128)), createElementVNode("span", {
178
+ id: unref(hintId),
179
+ hidden: ""
180
+ }, toDisplayString(unref(hint)), 9, _hoisted_2)], 6)) : createCommentVNode("", true),
181
+ unref(hole) ? (openBlock(), createElementBlock("div", {
182
+ key: 2,
183
+ class: normalizeClass([unref(ns).e("center"), unref(ns).is("above", !!unref(hole).above)]),
184
+ style: normalizeStyle({
185
+ left: `${unref(hole).left}px`,
186
+ top: `${unref(hole).top}px`,
187
+ width: `${unref(hole).width}px`
188
+ })
189
+ }, [createVNode(Center)], 6)) : createCommentVNode("", true),
190
+ unref(empty) ? (openBlock(), createElementBlock("div", {
191
+ key: 3,
192
+ class: normalizeClass(unref(ns).e("empty"))
193
+ }, [createVNode(Empty)], 2)) : createCommentVNode("", true),
194
+ createVNode(Transition, { name: "dou-fade" }, {
195
+ default: withCtx(() => [unref(loading) ? (openBlock(), createElementBlock("div", {
196
+ key: 0,
197
+ class: normalizeClass(unref(ns).e("loading"))
198
+ }, [createVNode(unref(DouSpinner))], 2)) : createCommentVNode("", true)]),
199
+ _: 1
200
+ })
201
+ ], 64);
202
+ };
203
+ }
204
+ });
205
+ export { overlay_vue_vue_type_script_setup_true_lang_default as default };
206
+
207
+ //# sourceMappingURL=overlay.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_Fragment","_unref","_normalizeClass","_renderList","_normalizeStyle","_createElementVNode","_toDisplayString","_createCommentVNode","_createBlock","_withCtx","_createVNode","_Transition"],"sources":["../src/overlay.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouSpinner, DouTooltip, useNamespace, type Tone } from 'dou-ui'\nimport { onBeforeUnmount, useId, type ComputedRef, type VNodeChild } from 'vue'\nimport type { TickLabel } from './core/layout'\nimport type { PlacedDataLabel } from './core/labels'\nimport type { LegendBox } from './core/layout'\nimport type { MarkerLabel } from './core/marker'\n\n/**\n * The text over the canvas: tick labels, titles, the legend and what goes\n * in a donut's hole. Kept apart from the chart, so laying it out again\n * doesn't render the chart's slot again: a part written with a new\n * function each render (`:format=\"(v) => …\"`) would otherwise be laid out\n * again and again.\n */\nexport interface OverlayState {\n shown: ComputedRef<boolean>\n labels: ComputedRef<Array<TickLabel & { key: string; axis: string }>>\n titles: ComputedRef<\n Array<{ key: string; text: string; left: number; top: number; align: 'start' | 'end' }>\n >\n legend: ComputedRef<\n Array<{\n index: number\n text: string\n left: number\n top: number\n color: string\n kind: string\n dashed: boolean\n /** Turned off. */\n off: boolean\n /** The last one shown: it can't be turned off. */\n locked: boolean\n /** The room it takes, swatch and name, in px. */\n width: number\n /** Its name is cut short to the room down the side. */\n clipped?: boolean\n /** A heatmap's scale: its colors, least to most, in a swatch `swatch` px wide. */\n scale?: string[]\n swatch?: number\n /** The pattern over its color, as a CSS background image and its size. */\n pattern?: { image: string; size?: string }\n }>\n >\n /** Where the legend shows; its entries scroll in it when they don't all fit. */\n legendBox: ComputedRef<LegendBox | undefined>\n /** Turns the series (or slice) at `index` on or off. */\n toggle: (index: number) => void\n /** Shows only the series (or slice) at `index`, or all again. */\n isolate: (index: number) => void\n /** How to show one entry alone, read out with each entry. */\n hint: ComputedRef<string>\n /** Brings the series at `index` forward while the pointer or focus is on its entry; `null` to stop. */\n focus: (index: number | null) => void\n /** Where the donut's hole is, if there is one to fill. */\n hole: ComputedRef<{ left: number; top: number; width: number; above?: boolean } | null>\n center: () => VNodeChild\n /** The markers' labels. */\n markers: ComputedRef<Array<MarkerLabel & { key: string; tone: Tone; backdrop: boolean }>>\n /** Data labels: values by the points and on the bars; `ink` is their color, when not the default. */\n data: ComputedRef<Array<PlacedDataLabel & { ink?: string; width?: number }>>\n /** Whether the data labels show (not while the series come in). */\n dataShown: ComputedRef<boolean>\n /** The series brought forward: the other series' labels are faded too. */\n dataFocus: ComputedRef<number | null>\n /** No series has a value: the empty message shows. */\n empty: ComputedRef<boolean>\n emptyContent: () => VNodeChild\n loading: ComputedRef<boolean>\n}\n\ndefineOptions({ name: 'DouChartOverlay' })\n\nconst { state } = defineProps<{ state: OverlayState }>()\nconst ns = useNamespace('chart')\nconst {\n shown,\n labels,\n titles,\n legend,\n legendBox,\n hole,\n toggle,\n isolate,\n hint,\n focus,\n markers,\n data,\n dataShown,\n dataFocus,\n empty,\n loading,\n} = state\nconst Center = () => state.center()\nconst hintId = useId()\n\n/* the legend: a click turns an entry on or off; with Alt, or held down on a touch screen, it shows only that one */\n\n/** How long a finger stays on an entry to show only it, in ms. */\nconst HOLD = 500\nlet holdTimer: ReturnType<typeof setTimeout> | undefined\n/** A hold just showed one entry alone: the click that ends it isn't a toggle. */\nlet held = false\n\nfunction holdLegend(index: number) {\n letGo()\n held = false\n holdTimer = setTimeout(() => {\n holdTimer = undefined\n held = true\n isolate(index)\n }, HOLD)\n}\n\nfunction letGo() {\n if (holdTimer) clearTimeout(holdTimer)\n holdTimer = undefined\n}\n\nfunction onLegendClick(event: MouseEvent, index: number) {\n if (held) {\n held = false\n return\n }\n if (event.altKey) isolate(index)\n else toggle(index)\n}\n\nfunction onLegendKey(event: KeyboardEvent, index: number) {\n if (!event.altKey || (event.key !== 'Enter' && event.key !== ' ')) return\n event.preventDefault()\n isolate(index)\n}\n/** No callout menu over an entry while it is held down. */\nfunction noMenu(event: Event) {\n if (holdTimer || held) event.preventDefault()\n}\nonBeforeUnmount(letGo)\n/** Room around the legend's entries in its box, so a focus ring isn't cut off where it scrolls. */\nconst LEGEND_PAD = 4\nconst Empty = () => state.emptyContent()\n// a click focuses the entry too: only keyboard focus brings its series forward\nconst focusVisible = (e: FocusEvent) => (e.target as Element).matches(':focus-visible')\n</script>\n\n<template>\n <div v-if=\"shown\" :class=\"ns.e('labels')\" aria-hidden=\"true\">\n <span\n v-for=\"tick in labels\"\n :key=\"tick.key\"\n :class=\"[ns.e('tick'), ns.is(tick.axis), ns.is('clipped', !!tick.clipped)]\"\n :style=\"{\n transform: `translate(${tick.left}px, ${tick.top}px)`,\n width: tick.clipped ? `${tick.width}px` : undefined,\n }\"\n ><span :class=\"ns.e('text')\">{{ tick.text }}</span></span\n >\n <span\n v-for=\"title in titles\"\n :key=\"title.key\"\n :class=\"[ns.e('title'), ns.is('end', title.align === 'end')]\"\n :style=\"{ transform: `translate(${title.left}px, ${title.top}px)` }\"\n ><span :class=\"ns.e('text')\">{{ title.text }}</span></span\n >\n <span\n v-for=\"marker in markers\"\n :key=\"marker.key\"\n :class=\"[\n ns.e('marker'),\n ns.is(marker.tone),\n ns.is(marker.align),\n ns.is('backdrop', marker.backdrop),\n ]\"\n :style=\"{ transform: `translate(${marker.left}px, ${marker.top}px)` }\"\n ><span :class=\"ns.e('text')\">{{ marker.text }}</span></span\n >\n <span\n v-for=\"label in data\"\n :key=\"`data:${label.key}`\"\n :class=\"[\n ns.e('value'),\n ns.is(label.align),\n ns.is('inside', !!label.on),\n ns.is('hidden', !dataShown),\n ns.is('faded', dataFocus !== null && dataFocus !== label.series),\n ns.is('clipped', label.width !== undefined),\n ]\"\n :style=\"{\n transform: `translate(${label.left}px, ${label.top}px)`,\n color: label.ink,\n width: label.width === undefined ? undefined : `${label.width}px`,\n }\"\n ><span :class=\"ns.e('text')\">{{ label.text }}</span></span\n >\n </div>\n <div\n v-if=\"shown && legend.length && legendBox\"\n :class=\"[ns.e('legends'), ns.is('scroll', legendBox.scroll)]\"\n :style=\"{\n left: `${legendBox.x - LEGEND_PAD}px`,\n top: `${legendBox.y - LEGEND_PAD}px`,\n width: `${legendBox.width + LEGEND_PAD * 2}px`,\n height: `${legendBox.height + LEGEND_PAD * 2}px`,\n }\"\n >\n <!-- a name cut short shows in full on hover and focus; on a phone the legend goes where names aren't cut -->\n <DouTooltip\n v-for=\"item in legend\"\n :key=\"`legend:${item.index}`\"\n :content=\"item.text\"\n :disabled=\"!item.clipped\"\n >\n <button\n type=\"button\"\n :class=\"[\n ns.e('legend'),\n ns.is(item.kind),\n ns.is('dashed', item.dashed),\n ns.is('off', item.off),\n ns.is('locked', item.locked),\n ns.is('clipped', !!item.clipped),\n ]\"\n :style=\"{\n transform: `translate(${item.left - legendBox.x + LEGEND_PAD}px, ${item.top - legendBox.y + LEGEND_PAD}px)`,\n width: item.clipped ? `${item.width}px` : undefined,\n }\"\n :aria-pressed=\"!item.off\"\n :aria-describedby=\"hintId\"\n aria-keyshortcuts=\"Alt+Enter\"\n @click=\"(e) => onLegendClick(e, item.index)\"\n @keydown=\"(e) => onLegendKey(e, item.index)\"\n @pointerdown=\"(e) => e.pointerType === 'touch' && holdLegend(item.index)\"\n @pointerup=\"letGo\"\n @pointercancel=\"letGo\"\n @contextmenu=\"noMenu\"\n @pointerenter=\"(e) => e.pointerType !== 'touch' && !item.off && focus(item.index)\"\n @pointerleave=\"(letGo(), focus(null))\"\n @focus=\"(e) => focusVisible(e) && !item.off && focus(item.index)\"\n @blur=\"focus(null)\"\n >\n <span\n :class=\"ns.e('swatch')\"\n :style=\"\n item.scale\n ? {\n width: `${item.swatch}px`,\n background: `linear-gradient(to right, ${item.scale.join(', ')})`,\n }\n : item.pattern\n ? {\n color: item.color,\n backgroundImage: item.pattern.image,\n backgroundSize: item.pattern.size,\n }\n : { color: item.color }\n \"\n /><span :class=\"ns.e('text')\">{{ item.text }}</span>\n </button>\n </DouTooltip>\n <span :id=\"hintId\" hidden>{{ hint }}</span>\n </div>\n <div\n v-if=\"hole\"\n :class=\"[ns.e('center'), ns.is('above', !!hole.above)]\"\n :style=\"{ left: `${hole.left}px`, top: `${hole.top}px`, width: `${hole.width}px` }\"\n >\n <Center />\n </div>\n <div v-if=\"empty\" :class=\"ns.e('empty')\"><Empty /></div>\n <Transition name=\"dou-fade\">\n <div v-if=\"loading\" :class=\"ns.e('loading')\"><DouSpinner /></div>\n </Transition>\n</template>\n"],"mappings":";;;;;;;;;;;;;AAoGA,IAAM,OAAO;AAwCb,IAAM,aAAa;;;;;;EAjEnB,MAAM,KAAK,aAAa,OAAO;EAC/B,MAAM,EACJ,OACA,QACA,QACA,QACA,WACA,MACA,QACA,SACA,MACA,OACA,SACA,MACA,WACA,WACA,OACA,YACE,QAAA;EACJ,MAAM,eAAe,QAAA,MAAM,OAAO;EAClC,MAAM,SAAS,MAAM;;EAMrB,IAAI;;EAEJ,IAAI,OAAO;EAEX,SAAS,WAAW,OAAe;GACjC,MAAM;GACN,OAAO;GACP,YAAY,iBAAiB;IAC3B,YAAY,KAAA;IACZ,OAAO;IACP,QAAQ,KAAK;GACf,GAAG,IAAI;EACT;EAEA,SAAS,QAAQ;GACf,IAAI,WAAW,aAAa,SAAS;GACrC,YAAY,KAAA;EACd;EAEA,SAAS,cAAc,OAAmB,OAAe;GACvD,IAAI,MAAM;IACR,OAAO;IACP;GACF;GACA,IAAI,MAAM,QAAQ,QAAQ,KAAK;QAC1B,OAAO,KAAK;EACnB;EAEA,SAAS,YAAY,OAAsB,OAAe;GACxD,IAAI,CAAC,MAAM,UAAW,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAM;GACnE,MAAM,eAAe;GACrB,QAAQ,KAAK;EACf;;EAEA,SAAS,OAAO,OAAc;GAC5B,IAAI,aAAa,MAAM,MAAM,eAAe;EAC9C;EACA,gBAAgB,KAAK;;EAGrB,MAAM,cAAc,QAAA,MAAM,aAAa;EAEvC,MAAM,gBAAgB,MAAmB,EAAE,OAAmB,QAAQ,gBAAgB;;;IAIzEG,MAAA,KAAA,KAAXH,UAAA,GAAAC,mBAgDM,OAAA;;KAhDa,OAAKG,eAAED,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA,CAAA;KAAY,eAAY;;MACpDH,UAAA,IAAA,GAAAC,mBASCC,UAAA,MAAAG,WARgBF,MAAA,MAAA,IAAR,SAAI;MADb,OAAAH,UAAA,GAAAC,mBASC,QAAA;OAPE,KAAK,KAAK;OACV,OAAKG,eAAA;QAAGD,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA;QAAUA,MAAA,EAAA,CAAE,CAAC,GAAG,KAAK,IAAI;QAAGA,MAAA,EAAA,CAAE,CAAC,GAAE,WAAA,CAAA,CAAc,KAAK,OAAO;OAAA,CAAA;OACvE,OAAKG,eAAA;QAAoC,WAAA,aAAA,KAAK,KAAI,MAAO,KAAK,IAAG;QAAsB,OAAA,KAAK,UAAO,GAAM,KAAK,MAAK,MAAO,KAAA;;M,IAI1HC,mBAAkD,QAAA,EAA3C,OAAKH,eAAED,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA,EAAa,GAAAK,gBAAA,KAAK,IAAI,GAAA,CAAA,C;;MAE3CR,UAAA,IAAA,GAAAC,mBAMCC,UAAA,MAAAG,WALiBF,MAAA,MAAA,IAAT,UAAK;MADd,OAAAH,UAAA,GAAAC,mBAMC,QAAA;OAJE,KAAK,MAAM;OACX,OAAKG,eAAA,CAAGD,MAAA,EAAA,CAAE,CAAC,EAAC,OAAA,GAAWA,MAAA,EAAA,CAAE,CAAC,GAAE,OAAQ,MAAM,UAAK,KAAA,CAAA,CAAA;OAC/C,OAAKG,eAAA,EAAA,WAAA,aAA4B,MAAM,KAAI,MAAO,MAAM,IAAG,KAAA,CAAA;M,IAC3DC,mBAAmD,QAAA,EAA5C,OAAKH,eAAED,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA,EAAa,GAAAK,gBAAA,MAAM,IAAI,GAAA,CAAA,C;;MAE5CR,UAAA,IAAA,GAAAC,mBAWCC,UAAA,MAAAG,WAVkBF,MAAA,OAAA,IAAV,WAAM;MADf,OAAAH,UAAA,GAAAC,mBAWC,QAAA;OATE,KAAK,OAAO;OACZ,OAAKG,eAAA;QAAYD,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA;QAAoBA,MAAA,EAAA,CAAE,CAAC,GAAG,OAAO,IAAI;QAAWA,MAAA,EAAA,CAAE,CAAC,GAAG,OAAO,KAAK;QAAWA,MAAA,EAAA,CAAE,CAAC,GAAE,YAAa,OAAO,QAAQ;;OAMnI,OAAKG,eAAA,EAAA,WAAA,aAA4B,OAAO,KAAI,MAAO,OAAO,IAAG,KAAA,CAAA;M,IAC7DC,mBAAoD,QAAA,EAA7C,OAAKH,eAAED,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA,EAAa,GAAAK,gBAAA,OAAO,IAAI,GAAA,CAAA,C;;MAE7CR,UAAA,IAAA,GAAAC,mBAiBCC,UAAA,MAAAG,WAhBiBF,MAAA,IAAA,IAAT,UAAK;MADd,OAAAH,UAAA,GAAAC,mBAiBC,QAAA;OAfE,KAAG,QAAU,MAAM;OACnB,OAAKG,eAAA;QAAYD,MAAA,EAAA,CAAE,CAAC,EAAC,OAAA;QAAmBA,MAAA,EAAA,CAAE,CAAC,GAAG,MAAM,KAAK;QAAWA,MAAA,EAAA,CAAE,CAAC,GAAE,UAAA,CAAA,CAAa,MAAM,EAAE;QAAWA,MAAA,EAAA,CAAE,CAAC,GAAE,UAAA,CAAYA,MAAA,SAAA,CAAS;QAAWA,MAAA,EAAA,CAAE,CAAC,GAAE,SAAUA,MAAA,SAAA,MAAS,QAAaA,MAAA,SAAA,MAAc,MAAM,MAAM;QAAWA,MAAA,EAAA,CAAE,CAAC,GAAE,WAAY,MAAM,UAAU,KAAA,CAAS;;OAQlQ,OAAKG,eAAA;QAAoC,WAAA,aAAA,MAAM,KAAI,MAAO,MAAM,IAAG;QAAsB,OAAA,MAAM;QAAoB,OAAA,MAAM,UAAU,KAAA,IAAY,KAAA,IAAS,GAAM,MAAM,MAAK;;M,IAKzKC,mBAAmD,QAAA,EAA5C,OAAKH,eAAED,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA,EAAa,GAAAK,gBAAA,MAAM,IAAI,GAAA,CAAA,C;;;IAItCL,MAAA,KAAA,KAASA,MAAA,MAAA,CAAM,CAAC,UAAUA,MAAA,SAAA,KADlCH,UAAA,GAAAC,mBAiEM,OAAA;;KA/DH,OAAKG,eAAA,CAAGD,MAAA,EAAA,CAAE,CAAC,EAAC,SAAA,GAAaA,MAAA,EAAA,CAAE,CAAC,GAAE,UAAWA,MAAA,SAAA,CAAS,CAAC,MAAM,CAAA,CAAA;KACzD,OAAKG,eAAA;MAAmB,MAAA,GAAAH,MAAA,SAAA,CAAS,CAAC,IAAI,WAAU;MAAoB,KAAA,GAAAA,MAAA,SAAA,CAAS,CAAC,IAAI,WAAU;MAAsB,OAAA,GAAAA,MAAA,SAAA,CAAS,CAAC,QAAQ,EAAU;MAA2B,QAAA,GAAAA,MAAA,SAAA,CAAS,CAAC,SAAS,EAAU;;I,KAQvMH,UAAA,IAAA,GAAAC,mBAoDaC,UAAA,MAAAG,WAnDIF,MAAA,MAAA,IAAR,SAAI;KADb,OAAAH,UAAA,GAAAU,YAoDaP,MAAA,UAAA,GAAA;MAlDV,KAAG,UAAY,KAAK;MACpB,SAAS,KAAK;MACd,UAAQ,CAAG,KAAK;;MAEjB,SAAAQ,cA6CS,CA7CTJ,mBA6CS,UAAA;OA5CP,MAAK;OACJ,OAAKH,eAAA;QAAcD,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA;QAAsBA,MAAA,EAAA,CAAE,CAAC,GAAG,KAAK,IAAI;QAAaA,MAAA,EAAA,CAAE,CAAC,GAAE,UAAW,KAAK,MAAM;QAAaA,MAAA,EAAA,CAAE,CAAC,GAAE,OAAQ,KAAK,GAAG;QAAaA,MAAA,EAAA,CAAE,CAAC,GAAE,UAAW,KAAK,MAAM;QAAaA,MAAA,EAAA,CAAE,CAAC,GAAE,WAAA,CAAA,CAAc,KAAK,OAAO;;OAQ1N,OAAKG,eAAA;QAAsC,WAAA,aAAA,KAAK,OAAOH,MAAA,SAAA,CAAS,CAAC,IAAI,WAAU,MAAO,KAAK,MAAMA,MAAA,SAAA,CAAS,CAAC,IAAI,WAAU;QAAwB,OAAA,KAAK,UAAO,GAAM,KAAK,MAAK,MAAO,KAAA;;OAIpL,gBAAY,CAAG,KAAK;OACpB,oBAAkBA,MAAA,MAAA;OACnB,qBAAkB;OACjB,UAAQ,MAAM,cAAc,GAAG,KAAK,KAAK;OACzC,YAAU,MAAM,YAAY,GAAG,KAAK,KAAK;OACzC,gBAAc,MAAM,EAAE,gBAAW,WAAgB,WAAW,KAAK,KAAK;OACtE,aAAW;OACX,iBAAe;OACf,eAAa;OACb,iBAAe,MAAM,EAAE,gBAAW,WAAA,CAAiB,KAAK,OAAOA,MAAA,KAAA,CAAK,CAAC,KAAK,KAAK;OAC/E,gBAAY,OAAA,OAAA,OAAA,MAAA,YAAG,MAAK,GAAIA,MAAA,KAAA,CAAK,CAAA,IAAA;OAC7B,UAAQ,MAAM,aAAa,CAAC,KAAA,CAAM,KAAK,OAAOA,MAAA,KAAA,CAAK,CAAC,KAAK,KAAK;OAC9D,QAAI,OAAA,OAAA,OAAA,MAAA,WAAEA,MAAA,KAAA,CAAK,CAAA,IAAA;M,IAEZI,mBAgBE,QAAA;OAfC,OAAKH,eAAED,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA,CAAA;OACX,OAAKG,eAAe,KAAK,Q;QAAoD,OAAA,GAAA,KAAK,OAAM;QAAiE,YAAA,6BAAA,KAAK,MAAM,KAAI,IAAA,EAAA;O,IAA6C,KAAK,U;QAAuD,OAAA,KAAK;QAA4C,iBAAA,KAAK,QAAQ;QAA2C,gBAAA,KAAK,QAAQ;O,IAAqD,EAAA,OAAA,KAAK,MAAK,C;M,aAcvcC,mBAAkD,QAAA,EAA3C,OAAKH,eAAED,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA,EAAa,GAAAK,gBAAA,KAAK,IAAI,GAAA,CAAA,C;;;I,WAG9CD,mBAA2C,QAAA;KAApC,IAAIJ,MAAA,MAAA;KAAQ,QAAA;IAAU,GAAAK,gBAAAL,MAAA,IAAA,CAAI,GAAA,GAAA,UAAA,C;IAG3BA,MAAA,IAAA,KADRH,UAAA,GAAAC,mBAMM,OAAA;;KAJH,OAAKG,eAAA,CAAGD,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA,GAAYA,MAAA,EAAA,CAAE,CAAC,GAAE,SAAA,CAAA,CAAYA,MAAA,IAAA,CAAI,CAAC,KAAK,CAAA,CAAA;KACnD,OAAKG,eAAA;MAAA,MAAA,GAAaH,MAAA,IAAA,CAAI,CAAC,KAAI;MAAA,KAAA,GAAcA,MAAA,IAAA,CAAI,CAAC,IAAG;MAAA,OAAA,GAAgBA,MAAA,IAAA,CAAI,CAAC,MAAK;KAAA,CAAA;I,IAE5ES,YAAU,MAAA,C;IAEDT,MAAA,KAAA,KAAXH,UAAA,GAAAC,mBAAwD,OAAA;;KAArC,OAAKG,eAAED,MAAA,EAAA,CAAE,CAAC,EAAC,OAAA,CAAA;I,IAAWS,YAAS,KAAA,C;IAClDA,YAEaC,YAAA,EAFD,MAAK,WAAU,GAAA;KACzB,SAAAF,cAAiE,CAAtDR,MAAA,OAAA,KAAXH,UAAA,GAAAC,mBAAiE,OAAA;;MAA5C,OAAKG,eAAED,MAAA,EAAA,CAAE,CAAC,EAAC,SAAA,CAAA;K,IAAaS,YAAcT,MAAA,UAAA,CAAA,C"}
@@ -0,0 +1,6 @@
1
+ import pointer_vue_vue_type_script_setup_true_lang_default from "./pointer.vue_vue_type_script_setup_true_lang.js";
2
+ // src/pointer.vue
3
+ var pointer_default = pointer_vue_vue_type_script_setup_true_lang_default;
4
+ export { pointer_default as default };
5
+
6
+ //# sourceMappingURL=pointer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pointer.js","names":["_sfc_main"],"sources":["../src/pointer.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useNamespace } from 'dou-ui'\nimport { useTemplateRef, watchPostEffect, type ComputedRef, type Ref } from 'vue'\nimport type { Rect } from './core/painter'\nimport type { ChartTooltipItem, ChartTooltipSlots } from './types'\n\n/** What is shown for the point (or x) under the pointer. */\nexport interface Tip {\n title?: string\n items: ChartTooltipItem[]\n /** One of the items' series is under the pointer: the others are muted. */\n focused?: boolean\n /** Where the tooltip points from, in px from the chart's top left. */\n anchor: [number, number]\n /** A hairline across the plot at the x. */\n line?: Rect\n /** A shaded band over the x's room, for bars. */\n band?: Rect\n /** A ring around a heatmap's cell. */\n cell?: Rect\n /** Rings and dots on the points. */\n marks: Array<{\n left: number\n top: number\n color: string\n radius: number\n ring: boolean\n /** Its series is faded: another one is under the pointer. */\n faded?: boolean\n }>\n /** Above the anchor rather than below, out from under a finger. */\n above?: boolean\n /** A place to keep clear of (the x under a finger): the tooltip goes beside it. */\n clear?: Rect\n /** A line under the values (slices left out of a pie). */\n note?: string\n /** The x as given, for `select`. */\n x?: unknown\n}\n\nexport interface PointerState {\n tip: ComputedRef<Tip | null>\n /** The chart's size, to keep the tooltip inside it. */\n size: ComputedRef<{ width: number; height: number } | null>\n content: Ref<ChartTooltipSlots['default'] | undefined>\n /** Read out as the keys move. */\n live: ComputedRef<string>\n}\n\ndefineOptions({ name: 'DouChartPointer' })\n\nconst { state } = defineProps<{ state: PointerState }>()\nconst ns = useNamespace('chart')\nconst { tip, live } = state\nconst box = useTemplateRef<HTMLElement>('box')\n\n/** Room between the tooltip and what it points at, and the chart's edges. */\nconst GAP = 12\nconst EDGE = 4\n\n// placed after it renders, when its size is known: beside the anchor, on whichever side has room\nwatchPostEffect(() => {\n const el = box.value\n const t = tip.value\n const size = state.size.value\n if (!el || !t || !size) return\n const width = el.offsetWidth\n const height = el.offsetHeight\n const c = t.clear\n if (c) {\n const fits = (at: number, span: number, room: number) => at >= EDGE && at + span <= room - EDGE\n if (c.width < c.height) {\n // a column: to its right, or its left, at the top of the plot\n const right = c.x + c.width + GAP\n const left = c.x - GAP - width\n if (fits(right, width, size.width) || fits(left, width, size.width)) {\n const x = fits(right, width, size.width) ? right : left\n el.style.transform = `translate(${Math.round(x)}px, ${Math.round(Math.max(EDGE, c.y))}px)`\n return\n }\n } else {\n // a row: below it, or above it, at the start of the plot\n const below = c.y + c.height + GAP\n const above = c.y - GAP - height\n if (fits(below, height, size.height) || fits(above, height, size.height)) {\n const y = fits(below, height, size.height) ? below : above\n const x = Math.min(Math.max(EDGE, c.x), size.width - EDGE - width)\n el.style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px)`\n return\n }\n }\n }\n const [x, y] = t.anchor\n let left = x + GAP\n if (left + width > size.width - EDGE) left = x - GAP - width\n left = Math.max(EDGE, Math.min(left, size.width - EDGE - width))\n let top = t.above ? y - GAP - height : y + GAP\n if (t.above ? top < EDGE : top + height > size.height - EDGE)\n top = t.above ? y + GAP : y - GAP - height\n top = Math.max(EDGE, Math.min(top, size.height - EDGE - height))\n el.style.transform = `translate(${Math.round(left)}px, ${Math.round(top)}px)`\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</script>\n\n<template>\n <div :class=\"ns.e('live')\" aria-live=\"polite\">{{ live }}</div>\n <div v-if=\"tip\" :class=\"ns.e('pointer')\" aria-hidden=\"true\">\n <div v-if=\"tip.band\" :class=\"ns.e('band')\" :style=\"px(tip.band)\" />\n <div v-if=\"tip.cell\" :class=\"ns.e('cell')\" :style=\"px(tip.cell)\" />\n <div v-if=\"tip.line\" :class=\"ns.e('crosshair')\" :style=\"px(tip.line)\" />\n <span\n v-for=\"(mark, i) in tip.marks\"\n :key=\"i\"\n :class=\"[ns.e('mark'), ns.is('ring', mark.ring), ns.is('faded', !!mark.faded)]\"\n :style=\"{\n transform: `translate(${mark.left - mark.radius}px, ${mark.top - mark.radius}px)`,\n width: `${mark.radius * 2}px`,\n height: `${mark.radius * 2}px`,\n color: mark.color,\n }\"\n />\n <div ref=\"box\" :class=\"ns.e('tooltip')\">\n <component\n :is=\"() => state.content.value!({ title: tip!.title, items: tip!.items, note: tip!.note })\"\n v-if=\"state.content.value\"\n />\n <template v-else>\n <div v-if=\"tip.title\" :class=\"ns.e('tooltip-title')\">\n <span :class=\"ns.e('text')\">{{ tip.title }}</span>\n </div>\n <div\n v-for=\"(item, i) in tip.items\"\n :key=\"i\"\n :class=\"[ns.e('tooltip-item'), ns.is('muted', tip.focused && !item.active)]\"\n >\n <span v-if=\"item.color\" :class=\"ns.e('tooltip-swatch')\" :style=\"{ color: item.color }\" />\n <span :class=\"[ns.e('tooltip-name'), ns.e('text')]\">{{ item.name }}</span>\n <span :class=\"[ns.e('tooltip-value'), ns.e('text')]\">{{ item.text }}</span>\n </div>\n <div v-if=\"tip.note\" :class=\"ns.e('tooltip-note')\">{{ tip.note }}</div>\n </template>\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -0,0 +1,136 @@
1
+ import { useNamespace } from "dou-ui";
2
+ import { Fragment, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, normalizeStyle, openBlock, renderList, resolveDynamicComponent, toDisplayString, unref, useTemplateRef, watchPostEffect } from "vue";
3
+ // src/pointer.vue?vue&type=script&setup=true&lang.ts
4
+ var GAP = 12;
5
+ var EDGE = 4;
6
+ var pointer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
7
+ name: "DouChartPointer",
8
+ __name: "pointer",
9
+ props: { state: {} },
10
+ setup(__props) {
11
+ const ns = useNamespace("chart");
12
+ const { tip, live } = __props.state;
13
+ const box = useTemplateRef("box");
14
+ /** Room between the tooltip and what it points at, and the chart's edges. */
15
+ watchPostEffect(() => {
16
+ const el = box.value;
17
+ const t = tip.value;
18
+ const size = __props.state.size.value;
19
+ if (!el || !t || !size) return;
20
+ const width = el.offsetWidth;
21
+ const height = el.offsetHeight;
22
+ const c = t.clear;
23
+ if (c) {
24
+ const fits = (at, span, room) => at >= EDGE && at + span <= room - EDGE;
25
+ if (c.width < c.height) {
26
+ const right = c.x + c.width + GAP;
27
+ const left = c.x - GAP - width;
28
+ if (fits(right, width, size.width) || fits(left, width, size.width)) {
29
+ const x = fits(right, width, size.width) ? right : left;
30
+ el.style.transform = `translate(${Math.round(x)}px, ${Math.round(Math.max(EDGE, c.y))}px)`;
31
+ return;
32
+ }
33
+ } else {
34
+ const below = c.y + c.height + GAP;
35
+ const above = c.y - GAP - height;
36
+ if (fits(below, height, size.height) || fits(above, height, size.height)) {
37
+ const y = fits(below, height, size.height) ? below : above;
38
+ const x = Math.min(Math.max(EDGE, c.x), size.width - EDGE - width);
39
+ el.style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px)`;
40
+ return;
41
+ }
42
+ }
43
+ }
44
+ const [x, y] = t.anchor;
45
+ let left = x + GAP;
46
+ if (left + width > size.width - EDGE) left = x - GAP - width;
47
+ left = Math.max(EDGE, Math.min(left, size.width - EDGE - width));
48
+ let top = t.above ? y - GAP - height : y + GAP;
49
+ if (t.above ? top < EDGE : top + height > size.height - EDGE) top = t.above ? y + GAP : y - GAP - height;
50
+ top = Math.max(EDGE, Math.min(top, size.height - EDGE - height));
51
+ el.style.transform = `translate(${Math.round(left)}px, ${Math.round(top)}px)`;
52
+ });
53
+ const px = (r) => ({
54
+ transform: `translate(${r.x}px, ${r.y}px)`,
55
+ width: `${r.width}px`,
56
+ height: `${r.height}px`
57
+ });
58
+ return (_ctx, _cache) => {
59
+ return openBlock(), createElementBlock(Fragment, null, [createElementVNode("div", {
60
+ class: normalizeClass(unref(ns).e("live")),
61
+ "aria-live": "polite"
62
+ }, toDisplayString(unref(live)), 3), unref(tip) ? (openBlock(), createElementBlock("div", {
63
+ key: 0,
64
+ class: normalizeClass(unref(ns).e("pointer")),
65
+ "aria-hidden": "true"
66
+ }, [
67
+ unref(tip).band ? (openBlock(), createElementBlock("div", {
68
+ key: 0,
69
+ class: normalizeClass(unref(ns).e("band")),
70
+ style: normalizeStyle(px(unref(tip).band))
71
+ }, null, 6)) : createCommentVNode("", true),
72
+ unref(tip).cell ? (openBlock(), createElementBlock("div", {
73
+ key: 1,
74
+ class: normalizeClass(unref(ns).e("cell")),
75
+ style: normalizeStyle(px(unref(tip).cell))
76
+ }, null, 6)) : createCommentVNode("", true),
77
+ unref(tip).line ? (openBlock(), createElementBlock("div", {
78
+ key: 2,
79
+ class: normalizeClass(unref(ns).e("crosshair")),
80
+ style: normalizeStyle(px(unref(tip).line))
81
+ }, null, 6)) : createCommentVNode("", true),
82
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(tip).marks, (mark, i) => {
83
+ return openBlock(), createElementBlock("span", {
84
+ key: i,
85
+ class: normalizeClass([
86
+ unref(ns).e("mark"),
87
+ unref(ns).is("ring", mark.ring),
88
+ unref(ns).is("faded", !!mark.faded)
89
+ ]),
90
+ style: normalizeStyle({
91
+ transform: `translate(${mark.left - mark.radius}px, ${mark.top - mark.radius}px)`,
92
+ width: `${mark.radius * 2}px`,
93
+ height: `${mark.radius * 2}px`,
94
+ color: mark.color
95
+ })
96
+ }, null, 6);
97
+ }), 128)),
98
+ createElementVNode("div", {
99
+ ref_key: "box",
100
+ ref: box,
101
+ class: normalizeClass(unref(ns).e("tooltip"))
102
+ }, [__props.state.content.value ? (openBlock(), createBlock(resolveDynamicComponent(() => __props.state.content.value({
103
+ title: unref(tip).title,
104
+ items: unref(tip).items,
105
+ note: unref(tip).note
106
+ })), { key: 0 })) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
107
+ unref(tip).title ? (openBlock(), createElementBlock("div", {
108
+ key: 0,
109
+ class: normalizeClass(unref(ns).e("tooltip-title"))
110
+ }, [createElementVNode("span", { class: normalizeClass(unref(ns).e("text")) }, toDisplayString(unref(tip).title), 3)], 2)) : createCommentVNode("", true),
111
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(tip).items, (item, i) => {
112
+ return openBlock(), createElementBlock("div", {
113
+ key: i,
114
+ class: normalizeClass([unref(ns).e("tooltip-item"), unref(ns).is("muted", unref(tip).focused && !item.active)])
115
+ }, [
116
+ item.color ? (openBlock(), createElementBlock("span", {
117
+ key: 0,
118
+ class: normalizeClass(unref(ns).e("tooltip-swatch")),
119
+ style: normalizeStyle({ color: item.color })
120
+ }, null, 6)) : createCommentVNode("", true),
121
+ createElementVNode("span", { class: normalizeClass([unref(ns).e("tooltip-name"), unref(ns).e("text")]) }, toDisplayString(item.name), 3),
122
+ createElementVNode("span", { class: normalizeClass([unref(ns).e("tooltip-value"), unref(ns).e("text")]) }, toDisplayString(item.text), 3)
123
+ ], 2);
124
+ }), 128)),
125
+ unref(tip).note ? (openBlock(), createElementBlock("div", {
126
+ key: 1,
127
+ class: normalizeClass(unref(ns).e("tooltip-note"))
128
+ }, toDisplayString(unref(tip).note), 3)) : createCommentVNode("", true)
129
+ ], 64))], 2)
130
+ ], 2)) : createCommentVNode("", true)], 64);
131
+ };
132
+ }
133
+ });
134
+ export { pointer_vue_vue_type_script_setup_true_lang_default as default };
135
+
136
+ //# sourceMappingURL=pointer.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pointer.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_Fragment","_createElementVNode","_normalizeClass","_unref","_toDisplayString","_normalizeStyle","_createCommentVNode","_renderList","_createBlock","_resolveDynamicComponent"],"sources":["../src/pointer.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useNamespace } from 'dou-ui'\nimport { useTemplateRef, watchPostEffect, type ComputedRef, type Ref } from 'vue'\nimport type { Rect } from './core/painter'\nimport type { ChartTooltipItem, ChartTooltipSlots } from './types'\n\n/** What is shown for the point (or x) under the pointer. */\nexport interface Tip {\n title?: string\n items: ChartTooltipItem[]\n /** One of the items' series is under the pointer: the others are muted. */\n focused?: boolean\n /** Where the tooltip points from, in px from the chart's top left. */\n anchor: [number, number]\n /** A hairline across the plot at the x. */\n line?: Rect\n /** A shaded band over the x's room, for bars. */\n band?: Rect\n /** A ring around a heatmap's cell. */\n cell?: Rect\n /** Rings and dots on the points. */\n marks: Array<{\n left: number\n top: number\n color: string\n radius: number\n ring: boolean\n /** Its series is faded: another one is under the pointer. */\n faded?: boolean\n }>\n /** Above the anchor rather than below, out from under a finger. */\n above?: boolean\n /** A place to keep clear of (the x under a finger): the tooltip goes beside it. */\n clear?: Rect\n /** A line under the values (slices left out of a pie). */\n note?: string\n /** The x as given, for `select`. */\n x?: unknown\n}\n\nexport interface PointerState {\n tip: ComputedRef<Tip | null>\n /** The chart's size, to keep the tooltip inside it. */\n size: ComputedRef<{ width: number; height: number } | null>\n content: Ref<ChartTooltipSlots['default'] | undefined>\n /** Read out as the keys move. */\n live: ComputedRef<string>\n}\n\ndefineOptions({ name: 'DouChartPointer' })\n\nconst { state } = defineProps<{ state: PointerState }>()\nconst ns = useNamespace('chart')\nconst { tip, live } = state\nconst box = useTemplateRef<HTMLElement>('box')\n\n/** Room between the tooltip and what it points at, and the chart's edges. */\nconst GAP = 12\nconst EDGE = 4\n\n// placed after it renders, when its size is known: beside the anchor, on whichever side has room\nwatchPostEffect(() => {\n const el = box.value\n const t = tip.value\n const size = state.size.value\n if (!el || !t || !size) return\n const width = el.offsetWidth\n const height = el.offsetHeight\n const c = t.clear\n if (c) {\n const fits = (at: number, span: number, room: number) => at >= EDGE && at + span <= room - EDGE\n if (c.width < c.height) {\n // a column: to its right, or its left, at the top of the plot\n const right = c.x + c.width + GAP\n const left = c.x - GAP - width\n if (fits(right, width, size.width) || fits(left, width, size.width)) {\n const x = fits(right, width, size.width) ? right : left\n el.style.transform = `translate(${Math.round(x)}px, ${Math.round(Math.max(EDGE, c.y))}px)`\n return\n }\n } else {\n // a row: below it, or above it, at the start of the plot\n const below = c.y + c.height + GAP\n const above = c.y - GAP - height\n if (fits(below, height, size.height) || fits(above, height, size.height)) {\n const y = fits(below, height, size.height) ? below : above\n const x = Math.min(Math.max(EDGE, c.x), size.width - EDGE - width)\n el.style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px)`\n return\n }\n }\n }\n const [x, y] = t.anchor\n let left = x + GAP\n if (left + width > size.width - EDGE) left = x - GAP - width\n left = Math.max(EDGE, Math.min(left, size.width - EDGE - width))\n let top = t.above ? y - GAP - height : y + GAP\n if (t.above ? top < EDGE : top + height > size.height - EDGE)\n top = t.above ? y + GAP : y - GAP - height\n top = Math.max(EDGE, Math.min(top, size.height - EDGE - height))\n el.style.transform = `translate(${Math.round(left)}px, ${Math.round(top)}px)`\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</script>\n\n<template>\n <div :class=\"ns.e('live')\" aria-live=\"polite\">{{ live }}</div>\n <div v-if=\"tip\" :class=\"ns.e('pointer')\" aria-hidden=\"true\">\n <div v-if=\"tip.band\" :class=\"ns.e('band')\" :style=\"px(tip.band)\" />\n <div v-if=\"tip.cell\" :class=\"ns.e('cell')\" :style=\"px(tip.cell)\" />\n <div v-if=\"tip.line\" :class=\"ns.e('crosshair')\" :style=\"px(tip.line)\" />\n <span\n v-for=\"(mark, i) in tip.marks\"\n :key=\"i\"\n :class=\"[ns.e('mark'), ns.is('ring', mark.ring), ns.is('faded', !!mark.faded)]\"\n :style=\"{\n transform: `translate(${mark.left - mark.radius}px, ${mark.top - mark.radius}px)`,\n width: `${mark.radius * 2}px`,\n height: `${mark.radius * 2}px`,\n color: mark.color,\n }\"\n />\n <div ref=\"box\" :class=\"ns.e('tooltip')\">\n <component\n :is=\"() => state.content.value!({ title: tip!.title, items: tip!.items, note: tip!.note })\"\n v-if=\"state.content.value\"\n />\n <template v-else>\n <div v-if=\"tip.title\" :class=\"ns.e('tooltip-title')\">\n <span :class=\"ns.e('text')\">{{ tip.title }}</span>\n </div>\n <div\n v-for=\"(item, i) in tip.items\"\n :key=\"i\"\n :class=\"[ns.e('tooltip-item'), ns.is('muted', tip.focused && !item.active)]\"\n >\n <span v-if=\"item.color\" :class=\"ns.e('tooltip-swatch')\" :style=\"{ color: item.color }\" />\n <span :class=\"[ns.e('tooltip-name'), ns.e('text')]\">{{ item.name }}</span>\n <span :class=\"[ns.e('tooltip-value'), ns.e('text')]\">{{ item.text }}</span>\n </div>\n <div v-if=\"tip.note\" :class=\"ns.e('tooltip-note')\">{{ tip.note }}</div>\n </template>\n </div>\n </div>\n</template>\n"],"mappings":";;;AAyDA,IAAM,MAAM;AACZ,IAAM,OAAO;;;;;;EANb,MAAM,KAAK,aAAa,OAAO;EAC/B,MAAM,EAAE,KAAK,SAAS,QAAA;EACtB,MAAM,MAAM,eAA4B,KAAK;;EAO7C,sBAAsB;GACpB,MAAM,KAAK,IAAI;GACf,MAAM,IAAI,IAAI;GACd,MAAM,OAAO,QAAA,MAAM,KAAK;GACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM;GACxB,MAAM,QAAQ,GAAG;GACjB,MAAM,SAAS,GAAG;GAClB,MAAM,IAAI,EAAE;GACZ,IAAI,GAAG;IACL,MAAM,QAAQ,IAAY,MAAc,SAAiB,MAAM,QAAQ,KAAK,QAAQ,OAAO;IAC3F,IAAI,EAAE,QAAQ,EAAE,QAAQ;KAEtB,MAAM,QAAQ,EAAE,IAAI,EAAE,QAAQ;KAC9B,MAAM,OAAO,EAAE,IAAI,MAAM;KACzB,IAAI,KAAK,OAAO,OAAO,KAAK,KAAK,KAAK,KAAK,MAAM,OAAO,KAAK,KAAK,GAAG;MACnE,MAAM,IAAI,KAAK,OAAO,OAAO,KAAK,KAAK,IAAI,QAAQ;MACnD,GAAG,MAAM,YAAY,aAAa,KAAK,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC,EAAE;MACtF;KACF;IACF,OAAO;KAEL,MAAM,QAAQ,EAAE,IAAI,EAAE,SAAS;KAC/B,MAAM,QAAQ,EAAE,IAAI,MAAM;KAC1B,IAAI,KAAK,OAAO,QAAQ,KAAK,MAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,MAAM,GAAG;MACxE,MAAM,IAAI,KAAK,OAAO,QAAQ,KAAK,MAAM,IAAI,QAAQ;MACrD,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC,GAAG,KAAK,QAAQ,OAAO,KAAK;MACjE,GAAG,MAAM,YAAY,aAAa,KAAK,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,EAAE;MACpE;KACF;IACF;GACF;GACA,MAAM,CAAC,GAAG,KAAK,EAAE;GACjB,IAAI,OAAO,IAAI;GACf,IAAI,OAAO,QAAQ,KAAK,QAAQ,MAAM,OAAO,IAAI,MAAM;GACvD,OAAO,KAAK,IAAI,MAAM,KAAK,IAAI,MAAM,KAAK,QAAQ,OAAO,KAAK,CAAC;GAC/D,IAAI,MAAM,EAAE,QAAQ,IAAI,MAAM,SAAS,IAAI;GAC3C,IAAI,EAAE,QAAQ,MAAM,OAAO,MAAM,SAAS,KAAK,SAAS,MACtD,MAAM,EAAE,QAAQ,IAAI,MAAM,IAAI,MAAM;GACtC,MAAM,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,KAAK,SAAS,OAAO,MAAM,CAAC;GAC/D,GAAG,MAAM,YAAY,aAAa,KAAK,MAAM,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,EAAE;EAC3E,CAAC;EAED,MAAM,MAAM,OAAa;GACvB,WAAW,aAAa,EAAE,EAAE,MAAM,EAAE,EAAE;GACtC,OAAO,GAAG,EAAE,MAAM;GAClB,QAAQ,GAAG,EAAE,OAAO;EACtB;;G,wDAIEG,mBAA8D,OAAA;IAAxD,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA;IAAU,aAAU;GAAY,GAAAC,gBAAAD,MAAA,IAAA,CAAI,GAAA,CAAA,GAC1CA,MAAA,GAAA,KAAXL,UAAA,GAAAC,mBAoCM,OAAA;;IApCW,OAAKG,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,SAAA,CAAA;IAAa,eAAY;;IACxCA,MAAA,GAAA,CAAG,CAAC,QAAfL,UAAA,GAAAC,mBAAmE,OAAA;;KAA7C,OAAKG,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA;KAAW,OAAKE,eAAE,GAAGF,MAAA,GAAA,CAAG,CAAC,IAAI,CAAA;;IACnDA,MAAA,GAAA,CAAG,CAAC,QAAfL,UAAA,GAAAC,mBAAmE,OAAA;;KAA7C,OAAKG,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA;KAAW,OAAKE,eAAE,GAAGF,MAAA,GAAA,CAAG,CAAC,IAAI,CAAA;;IACnDA,MAAA,GAAA,CAAG,CAAC,QAAfL,UAAA,GAAAC,mBAAwE,OAAA;;KAAlD,OAAKG,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,WAAA,CAAA;KAAgB,OAAKE,eAAE,GAAGF,MAAA,GAAA,CAAG,CAAC,IAAI,CAAA;;KACnEL,UAAA,IAAA,GAAAC,mBAUEC,UAAA,MAAAO,WAToBJ,MAAA,GAAA,CAAG,CAAC,QAAhB,MAAM,MAAC;KADjB,OAAAL,UAAA,GAAAC,mBAUE,QAAA;MARC,KAAK;MACL,OAAKG,eAAA;OAAGC,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA;OAAUA,MAAA,EAAA,CAAE,CAAC,GAAE,QAAS,KAAK,IAAI;OAAGA,MAAA,EAAA,CAAE,CAAC,GAAE,SAAA,CAAA,CAAY,KAAK,KAAK;MAAA,CAAA;MAC3E,OAAKE,eAAA;OAAoC,WAAA,aAAA,KAAK,OAAO,KAAK,OAAM,MAAO,KAAK,MAAM,KAAK,OAAM;OAAyB,OAAA,GAAA,KAAK,SAAM,EAAA;OAA6B,QAAA,GAAA,KAAK,SAAM,EAAA;OAAyB,OAAA,KAAK;;;;IAO1MJ,mBAoBM,OAAA;KApBG,SAAA;KAAJ,KAAI;KAAO,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,SAAA,CAAA;I,IAGjB,QAAA,MAAM,QAAQ,SAFtBL,UAAA,GAAAU,YAGEC,8BAFW,QAAA,MAAM,QAAQ,MAAK;KAAA,OAAWN,MAAA,GAAA,CAAG,CAAE;KAAK,OAASA,MAAA,GAAA,CAAG,CAAE;KAAK,MAAQA,MAAA,GAAA,CAAG,CAAE;IAAI,CAAA,CAAA,GAAA,EAAA,KAAA,EAAA,CAAA,MAGzFL,UAAA,GAAAC,mBAcWC,UAAA,EAAA,KAAA,EAAA,GAAA;KAbEG,MAAA,GAAA,CAAG,CAAC,SAAfL,UAAA,GAAAC,mBAEM,OAAA;;MAFiB,OAAKG,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,eAAA,CAAA;K,IAChCF,mBAAkD,QAAA,EAA3C,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA,EAAa,GAAAC,gBAAAD,MAAA,GAAA,CAAG,CAAC,KAAK,GAAA,CAAA,C;MAE1CL,UAAA,IAAA,GAAAC,mBAQMC,UAAA,MAAAO,WAPgBJ,MAAA,GAAA,CAAG,CAAC,QAAhB,MAAM,MAAC;MADjB,OAAAL,UAAA,GAAAC,mBAQM,OAAA;OANH,KAAK;OACL,OAAKG,eAAA,CAAGC,MAAA,EAAA,CAAE,CAAC,EAAC,cAAA,GAAkBA,MAAA,EAAA,CAAE,CAAC,GAAE,SAAUA,MAAA,GAAA,CAAG,CAAC,WAAO,CAAK,KAAK,MAAM,CAAA,CAAA;;OAE7D,KAAK,SAAjBL,UAAA,GAAAC,mBAAyF,QAAA;;QAAhE,OAAKG,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,gBAAA,CAAA;QAAqB,OAAKE,eAAA,EAAA,OAAW,KAAK,MAAK,CAAA;;OACnFJ,mBAA0E,QAAA,EAAnE,OAAKC,eAAA,CAAGC,MAAA,EAAA,CAAE,CAAC,EAAC,cAAA,GAAkBA,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA,CAAA,EAAc,GAAAC,gBAAA,KAAK,IAAI,GAAA,CAAA;OAChEH,mBAA2E,QAAA,EAApE,OAAKC,eAAA,CAAGC,MAAA,EAAA,CAAE,CAAC,EAAC,eAAA,GAAmBA,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA,CAAA,EAAc,GAAAC,gBAAA,KAAK,IAAI,GAAA,CAAA;;;KAExDD,MAAA,GAAA,CAAG,CAAC,QAAfL,UAAA,GAAAC,mBAAuE,OAAA;;MAAjD,OAAKG,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,cAAA,CAAA;KAAqB,GAAAC,gBAAAD,MAAA,GAAA,CAAG,CAAC,IAAI,GAAA,CAAA,K"}
package/dist/static.js ADDED
@@ -0,0 +1,6 @@
1
+ import static_vue_vue_type_script_setup_true_lang_default from "./static.vue_vue_type_script_setup_true_lang.js";
2
+ // src/static.vue
3
+ var static_default = static_vue_vue_type_script_setup_true_lang_default;
4
+ export { static_default as default };
5
+
6
+ //# sourceMappingURL=static.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static.js","names":["_sfc_main"],"sources":["../src/static.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useNamespace } from 'dou-ui'\nimport { computed, getCurrentInstance, type ComputedRef } from 'vue'\n\n/**\n * The chart drawn on the server, as an SVG filling the chart's box. Its own\n * component, after the chart's parts: on the server those are known only\n * once the chart's slot has rendered. In the browser it keeps the\n * server's drawing until the canvas has drawn.\n */\nexport interface StaticState {\n shown: ComputedRef<boolean>\n size: ComputedRef<{ width: number; height: number }>\n /** The drawing; empty in the browser, which takes the server's. */\n markup: ComputedRef<string>\n /** What the chart shows, read out. */\n label: ComputedRef<string>\n}\n\ndefineOptions({ name: 'DouChartStatic' })\n\nconst { state } = defineProps<{ state: StaticState }>()\nconst ns = useNamespace('chart')\nconst { shown, size, label } = state\n// taking over the server's page: its drawing, as the browser doesn't draw one\nconst taken = getCurrentInstance()?.vnode.el\nconst kept =\n typeof Element !== 'undefined' && taken instanceof Element && taken.matches(`.${ns.e('static')}`)\n ? taken.innerHTML\n : ''\nconst markup = computed(() => state.markup.value || kept)\n</script>\n\n<template>\n <svg\n v-if=\"shown\"\n :class=\"ns.e('static')\"\n xmlns=\"http://www.w3.org/2000/svg\"\n :viewBox=\"`0 0 ${size.width} ${size.height}`\"\n role=\"img\"\n :aria-label=\"label\"\n v-html=\"markup\"\n />\n</template>\n"],"mappings":""}
@@ -0,0 +1,34 @@
1
+ import { useNamespace } from "dou-ui";
2
+ import { computed, createCommentVNode, createElementBlock, defineComponent, getCurrentInstance, normalizeClass, openBlock, unref } from "vue";
3
+ // src/static.vue?vue&type=script&setup=true&lang.ts
4
+ var _hoisted_1 = [
5
+ "viewBox",
6
+ "aria-label",
7
+ "innerHTML"
8
+ ];
9
+ var static_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
10
+ name: "DouChartStatic",
11
+ __name: "static",
12
+ props: { state: {} },
13
+ setup(__props) {
14
+ const ns = useNamespace("chart");
15
+ const { shown, size, label } = __props.state;
16
+ const taken = getCurrentInstance()?.vnode.el;
17
+ const kept = typeof Element !== "undefined" && taken instanceof Element && taken.matches(`.${ns.e("static")}`) ? taken.innerHTML : "";
18
+ const markup = computed(() => __props.state.markup.value || kept);
19
+ return (_ctx, _cache) => {
20
+ return unref(shown) ? (openBlock(), createElementBlock("svg", {
21
+ key: 0,
22
+ class: normalizeClass(unref(ns).e("static")),
23
+ xmlns: "http://www.w3.org/2000/svg",
24
+ viewBox: `0 0 ${unref(size).width} ${unref(size).height}`,
25
+ role: "img",
26
+ "aria-label": unref(label),
27
+ innerHTML: markup.value
28
+ }, null, 10, _hoisted_1)) : createCommentVNode("", true);
29
+ };
30
+ }
31
+ });
32
+ export { static_vue_vue_type_script_setup_true_lang_default as default };
33
+
34
+ //# sourceMappingURL=static.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static.vue_vue_type_script_setup_true_lang.js","names":["_unref","_openBlock","_createElementBlock","_normalizeClass","_createCommentVNode"],"sources":["../src/static.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useNamespace } from 'dou-ui'\nimport { computed, getCurrentInstance, type ComputedRef } from 'vue'\n\n/**\n * The chart drawn on the server, as an SVG filling the chart's box. Its own\n * component, after the chart's parts: on the server those are known only\n * once the chart's slot has rendered. In the browser it keeps the\n * server's drawing until the canvas has drawn.\n */\nexport interface StaticState {\n shown: ComputedRef<boolean>\n size: ComputedRef<{ width: number; height: number }>\n /** The drawing; empty in the browser, which takes the server's. */\n markup: ComputedRef<string>\n /** What the chart shows, read out. */\n label: ComputedRef<string>\n}\n\ndefineOptions({ name: 'DouChartStatic' })\n\nconst { state } = defineProps<{ state: StaticState }>()\nconst ns = useNamespace('chart')\nconst { shown, size, label } = state\n// taking over the server's page: its drawing, as the browser doesn't draw one\nconst taken = getCurrentInstance()?.vnode.el\nconst kept =\n typeof Element !== 'undefined' && taken instanceof Element && taken.matches(`.${ns.e('static')}`)\n ? taken.innerHTML\n : ''\nconst markup = computed(() => state.markup.value || kept)\n</script>\n\n<template>\n <svg\n v-if=\"shown\"\n :class=\"ns.e('static')\"\n xmlns=\"http://www.w3.org/2000/svg\"\n :viewBox=\"`0 0 ${size.width} ${size.height}`\"\n role=\"img\"\n :aria-label=\"label\"\n v-html=\"markup\"\n />\n</template>\n"],"mappings":";;;;;;;;;;;;;EAsBA,MAAM,KAAK,aAAa,OAAO;EAC/B,MAAM,EAAE,OAAO,MAAM,UAAU,QAAA;EAE/B,MAAM,QAAQ,mBAAmB,CAAC,EAAE,MAAM;EAC1C,MAAM,OACJ,OAAO,YAAY,eAAe,iBAAiB,WAAW,MAAM,QAAQ,IAAI,GAAG,EAAE,QAAQ,GAAG,IAC5F,MAAM,YACN;EACN,MAAM,SAAS,eAAe,QAAA,MAAM,OAAO,SAAS,IAAI;;GAK9C,OAAAA,MAAA,KAAA,KADRC,UAAA,GAAAC,mBAQE,OAAA;;IANC,OAAKC,eAAEH,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA,CAAA;IACZ,OAAM;IACL,SAAO,OAASA,MAAA,IAAA,CAAI,CAAC,MAAK,GAAIA,MAAA,IAAA,CAAI,CAAC;IACpC,MAAK;IACJ,cAAYA,MAAA,KAAA;IACb,WAAQ,OAAA"}
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ @layer dou.components{.dou-chart{--dou-chart-surface:var(--dou-color-bg-surface);--dou-chart-grid:var(--dou-color-border-subtle);--dou-chart-baseline:var(--dou-color-border-strong);--dou-chart-label:var(--dou-color-text-tertiary);--dou-chart-title:var(--dou-color-text-secondary);--dou-chart-range-ink:var(--dou-color-text-tertiary);--dou-chart-marker:color-mix(in oklab,var(--dou-color-text)45%,transparent);--dou-chart-track:color-mix(in oklab,var(--dou-color-text)10%,transparent);position:relative;box-sizing:border-box;overflow:hidden;color:var(--dou-color-text);font-family:var(--dou-font-family);font-variant-numeric:tabular-nums;width:100%;min-width:0;font-size:12px;line-height:16px}.dou-chart__canvas{position:absolute;display:block;top:0;left:0}.dou-chart__static{position:absolute;display:block;width:100%;height:100%;font-size:12px;inset:0}.dou-chart__canvas,.dou-chart__static,.dou-chart__labels,.dou-chart__legends{transition:opacity var(--dou-motion-duration-fast)var(--dou-motion-easing)}.dou-chart.is-loading>:is(.dou-chart__canvas,.dou-chart__static,.dou-chart__labels,.dou-chart__legends){opacity:.4}.dou-chart__loading{position:absolute;display:flex;color:var(--dou-color-text-secondary);justify-content:center;align-items: center;inset:0}.dou-chart__labels{position:absolute;pointer-events:none;inset:0}.dou-chart__tick,.dou-chart__title{position:absolute;display:flex;white-space:nowrap;align-items: center;height:16px}.dou-chart__text{text-box:trim-both cap alphabetic}.dou-chart__tick{color:var(--dou-chart-label);will-change:transform;top:0;left:0}.dou-chart__tick.is-value{color:var(--dou-color-text-secondary);font-variant-numeric:tabular-nums}.dou-chart__tick.is-rate{font-variant-numeric:tabular-nums}.dou-chart__tick.is-clipped{pointer-events:auto}.dou-chart__tick.is-clipped>.dou-chart__text{overflow:hidden;text-overflow:ellipsis;text-box:normal;min-width:0;line-height:16px}.dou-chart__value{position:absolute;display:flex;color:var(--dou-color-text-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;transition:opacity var(--dou-motion-duration-fast)var(--dou-motion-easing);align-items: center;height:16px;top:0;left:0}.dou-chart__value.is-middle{translate:-50%}.dou-chart__value.is-end{translate:-100%}.dou-chart__value.is-inside{font-weight:var(--dou-font-weight-medium)}.dou-chart__value.is-faded{opacity:.24}.dou-chart__value.is-clipped{pointer-events:auto}.dou-chart__value.is-clipped>.dou-chart__text{overflow:hidden;text-overflow:ellipsis;text-box:normal;min-width:0;line-height:16px}.dou-chart__value.is-hidden{opacity:0;transition:none}.dou-chart__marker{position:absolute;display:flex;color:var(--dou-color-text-secondary);white-space:nowrap;align-items: center;height:16px;top:0;left:0}.dou-chart__marker.is-middle{translate:-50%}.dou-chart__marker.is-end{translate:-100%}.dou-chart__marker.is-backdrop{background-color:color-mix(in oklab,currentColor 10%,var(--dou-chart-surface));border-radius:4px;padding-inline-start:4px;padding-inline-end:4px}.dou-chart__marker.is-backdrop.is-start{margin-left:-4px}.dou-chart__marker.is-backdrop.is-end{margin-left:4px}.dou-chart__marker.is-primary{color:var(--dou-color-primary-text)}.dou-chart__marker.is-success{color:var(--dou-color-success-text)}.dou-chart__marker.is-warning{color:var(--dou-color-warning-text)}.dou-chart__marker.is-danger{color:var(--dou-color-danger-text)}.dou-chart__measure{visibility:hidden;contain:layout style}.dou-chart__title,.dou-chart__legend{top:0;left:0}.dou-chart.is-interactive:focus-visible{outline:2px solid var(--dou-color-focus);outline-offset:2px;border-radius:var(--dou-radius-control)}.dou-chart__legends{position:absolute;pointer-events:none}.dou-chart__legends.is-scroll{overflow-y:auto;overscroll-behavior:contain;pointer-events:auto;scrollbar-width:thin}.dou-chart__title{color:var(--dou-chart-title);font-weight:var(--dou-font-weight-medium)}.dou-chart__title.is-end{translate:-100%}.dou-chart__legend{position:absolute;display:flex;color:var(--dou-color-text-secondary);font:inherit;white-space:nowrap;cursor:pointer;pointer-events:auto;transition:color var(--dou-motion-duration-fast)var(--dou-motion-easing);-webkit-touch-callout:none;user-select:none;background:0 0;border:0;border-radius:2px;align-items: center;gap:6px;height:16px;padding:0}.dou-chart__legend:before{position:absolute;content:"";inset:-6px -4px}@media (pointer:coarse){.dou-chart__legend:before{inset:-12px -4px}}.dou-chart__legend:hover{color:var(--dou-color-text)}.dou-chart__legend:focus-visible{outline:2px solid var(--dou-color-focus);outline-offset:2px}.dou-chart__legend.is-clipped>.dou-chart__text{overflow:hidden;text-overflow:ellipsis;text-box:normal;min-width:0;line-height:16px}.dou-chart__legend.is-locked{cursor:default}.dou-chart__legend.is-locked:hover{color:var(--dou-color-text-secondary)}.dou-chart__legend.is-off{color:var(--dou-color-text-disabled)}.dou-chart__legend.is-off>.dou-chart__swatch{opacity:.32}.dou-chart__swatch{background-color:currentColor;border-radius:1px;flex-shrink:0;width:12px;height:2px}.is-area>.dou-chart__swatch{border-radius:2px;height:8px}.is-radar>.dou-chart__swatch{border-radius:2px;height:8px}.is-bar>.dou-chart__swatch{border-radius:2px;width:8px;height:8px;margin-inline-start:2px;margin-inline-end:2px}.is-pie>.dou-chart__swatch{border-radius:2px;width:8px;height:8px;margin-inline-start:2px;margin-inline-end:2px}.is-box>.dou-chart__swatch{box-sizing:border-box;background-color:color-mix(in srgb,currentColor 16%,transparent);border:1px solid;border-radius:1px;width:8px;height:10px;margin-inline-start:2px;margin-inline-end:2px}.is-scatter>.dou-chart__swatch{border-radius:50%;width:8px;height:8px;margin-inline-start:2px;margin-inline-end:2px}.is-heatmap>.dou-chart__swatch{box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--dou-color-text)8%,transparent);border-radius:2px;height:8px}.is-dashed>.dou-chart__swatch{background:repeating-linear-gradient(90deg,currentColor 0 4px,#0000 4px 7px)}.dou-chart__center{position:absolute;display:flex;text-align:center;flex-direction:column;justify-content:center;align-items: center;translate:-50% -50%}.dou-chart__center.is-above{translate:-50% calc(-100% - 4px)}.dou-chart__gauge-value{color:var(--dou-color-text);font-size:var(--dou-chart-gauge-value-size,28px);font-weight:var(--dou-font-weight-bold);font-variant-numeric:tabular-nums;line-height:1.3}.dou-chart__gauge-name{color:var(--dou-color-text-tertiary);font-size:var(--dou-font-size-sm);line-height:20px}.dou-chart__empty{position:absolute;display:flex;color:var(--dou-color-text-tertiary);font-size:var(--dou-font-size-sm);justify-content:center;align-items: center;inset:0}.dou-chart.is-table>:not(:-webkit-any(.dou-chart__table,.dou-chart__parts)){visibility:hidden}.dou-chart.is-table>:not(:-moz-any(.dou-chart__table,.dou-chart__parts)){visibility:hidden}.dou-chart.is-table>:not(:is(.dou-chart__table,.dou-chart__parts)){visibility:hidden}.dou-chart__table{position:absolute;overflow:auto;border:1px solid var(--dou-color-border);border-radius:var(--dou-radius-container);background-color:var(--dou-chart-surface);color:var(--dou-color-text);font-size:var(--dou-font-size-sm);overscroll-behavior:contain;line-height:1.5;inset:0}.dou-chart__table:focus-visible{outline:2px solid var(--dou-color-focus);outline-offset:2px}.dou-chart__table table{border-collapse:separate;border-spacing:0;font-variant-numeric:tabular-nums;width:100%}.dou-chart__table caption{position:absolute;overflow:hidden;clip-path:inset(50%);white-space:nowrap;width:1px;height:1px}.dou-chart__table th{box-sizing:border-box;border-bottom:1px solid var(--dou-color-border-subtle);text-align:end;white-space:nowrap;height:36px;padding:6px 10px}.dou-chart__table td{box-sizing:border-box;border-bottom:1px solid var(--dou-color-border-subtle);text-align:end;white-space:nowrap;height:36px;padding:6px 10px}.dou-chart__table th[scope=row]{text-align:start}.dou-chart__table thead th:first-child{text-align:start}.dou-chart__table th[scope=row]{font-weight:var(--dou-font-weight-regular)}.dou-chart__table thead th{position:sticky;z-index:1;border-bottom-color:var(--dou-color-border);background-color:color-mix(in oklab,var(--dou-color-text)2.5%,var(--dou-chart-surface));color:var(--dou-color-text-secondary);font-weight:var(--dou-font-weight-medium);height:32px;top:0}.dou-chart__table tbody tr:last-child>*{border-bottom:0}.dou-chart__table-more{border-top:1px solid var(--dou-color-border-subtle);color:var(--dou-color-text-tertiary);margin:0;padding:8px 10px}.dou-chart__pointer{position:absolute;pointer-events:none;inset:0}.dou-chart__crosshair,.dou-chart__band,.dou-chart__cell,.dou-chart__mark,.dou-chart__tooltip{position:absolute;top:0;left:0}.dou-chart__crosshair{background-color:var(--dou-chart-baseline)}.dou-chart__band{background-color:color-mix(in oklab,var(--dou-color-text)5%,transparent)}.dou-chart__cell{box-sizing:border-box;border:2px solid var(--dou-color-text);box-shadow:inset 0 0 0 1px var(--dou-chart-surface);border-radius:4px}.dou-chart__mark{box-sizing:border-box;border:2px solid var(--dou-chart-surface);box-shadow:0 0 0 1px color-mix(in oklab,currentColor 24%,transparent);background-color:currentColor;border-radius:50%}.dou-chart__mark.is-faded{opacity:.32}.dou-chart__mark.is-ring{box-shadow:0 0 0 1px var(--dou-chart-surface);background:0 0;border-color:currentColor}.dou-chart__tooltip{--dou-chart-tooltip-bg:color-mix(in oklab,var(--dou-color-text)calc(4%*var(--dou-scheme-dark)),var(--dou-color-bg-surface));box-sizing:border-box;border:1px solid var(--dou-color-border);border-radius:var(--dou-radius-container);background-color:var(--dou-chart-tooltip-bg);box-shadow:var(--dou-shadow-md);color:var(--dou-color-text-secondary);will-change:transform;min-width:120px;max-width:min(280px,100% - 8px);padding:8px 10px}.dou-chart__tooltip-title{display:flex;color:var(--dou-color-text);font-weight:var(--dou-font-weight-medium);align-items: center;min-height:16px;margin-bottom:6px}.dou-chart__tooltip-item{display:flex;align-items: center;gap:6px;min-height:16px}.dou-chart__tooltip-item+.dou-chart__tooltip-item{margin-top:4px}.dou-chart__tooltip-item.is-muted{color:var(--dou-color-text-tertiary)}.dou-chart__tooltip-item.is-muted>.dou-chart__tooltip-value{color:var(--dou-color-text-secondary)}.dou-chart__tooltip-swatch{box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--dou-color-text)8%,transparent);background-color:currentColor;border-radius:2px;flex-shrink:0;width:8px;height:8px}.dou-chart__tooltip-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-box:normal;flex:1;min-width:0;line-height:16px}.dou-chart__tooltip-value{color:var(--dou-color-text);font-weight:var(--dou-font-weight-medium);white-space:nowrap;margin-left:12px}.dou-chart__tooltip-note{color:var(--dou-color-text-tertiary);margin-top:6px;line-height:16px}.dou-chart__live{position:absolute;overflow:hidden;clip-path:inset(50%);white-space:nowrap;width:1px;height:1px}.dou-chart.is-zoomed{cursor:grab}.dou-chart.is-brushing{cursor:crosshair}.dou-chart__brush{position:absolute;box-sizing:border-box;border:1px solid color-mix(in oklab,var(--dou-color-text)28%,transparent);background-color:color-mix(in oklab,var(--dou-color-text)6%,transparent);pointer-events:none;top:0;left:0}.dou-chart__range{position:absolute;box-sizing:border-box;border-radius:var(--dou-radius-control);box-shadow:inset 0 0 0 1px var(--dou-color-border-subtle);cursor:pointer;touch-action:none;user-select:none;top:0;left:0}.dou-chart__range-canvas{position:absolute;display:block;opacity:.56;top:0;left:0}.dou-chart__range-shade,.dou-chart__range-window,.dou-chart__range-handle{position:absolute;top:0;left:0}.dou-chart__range-shade{background-color:color-mix(in oklab,var(--dou-chart-surface)72%,transparent)}.dou-chart__range-window{box-sizing:border-box;--dou-chart-range-edge:color-mix(in oklab,var(--dou-color-text)32%,transparent);border-block:1px solid var(--dou-chart-range-edge);background-color:color-mix(in oklab,var(--dou-color-text)6%,transparent);cursor:grab}.is-vertical>.dou-chart__range-window{border-block-start:none;border-block-end:none;border-inline:1px solid var(--dou-chart-range-edge)}.dou-chart__range-handle{box-sizing:border-box;border:1px solid var(--dou-color-border-strong);background-color:var(--dou-color-bg-surface);box-shadow:var(--dou-shadow-sm);outline:none;cursor:ew-resize;border-radius:4px;width:8px;height:20px;margin:6px 0 0 -4px}.dou-chart__range-handle:before{position:absolute;content:"";inset:-6px -8px}.dou-chart__range-handle:hover{border-color:var(--dou-color-text-tertiary)}.dou-chart__range-handle:focus-visible{outline:2px solid var(--dou-color-focus);outline-offset:2px}.is-vertical>.dou-chart__range-handle{cursor:ns-resize;width:20px;height:8px;margin:-4px 0 0 6px}.is-vertical>.dou-chart__range-handle:before{inset:-8px -6px}@media (pointer:coarse){.dou-chart__range-handle:before{inset:-10px -16px}.is-vertical>.dou-chart__range-handle:before{inset:-16px -10px}}}
@@ -0,0 +1 @@
1
+ export {}
package/dist/style.js ADDED
@@ -0,0 +1,3 @@
1
+ import 'dou-ui/components/spinner/style'
2
+ import 'dou-ui/components/tooltip/style'
3
+ import './style.css'
package/dist/table.js ADDED
@@ -0,0 +1,6 @@
1
+ import table_vue_vue_type_script_setup_true_lang_default from "./table.vue_vue_type_script_setup_true_lang.js";
2
+ // src/table.vue
3
+ var table_default = table_vue_vue_type_script_setup_true_lang_default;
4
+ export { table_default as default };
5
+
6
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.js","names":["_sfc_main"],"sources":["../src/table.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useNamespace } from 'dou-ui'\nimport type { ComputedRef } from 'vue'\n\n/** The chart's data as a table, shown in its place. */\nexport interface TableState {\n shown: ComputedRef<boolean>\n caption: ComputedRef<string>\n head: ComputedRef<string[]>\n /** Each row's cells; the first is the row's head. */\n rows: ComputedRef<string[][]>\n /** A line under a table cut short. */\n more: ComputedRef<string>\n /** Escape in the table: back to the chart. */\n close: () => void\n}\n\ndefineOptions({ name: 'DouChartTable' })\n\nconst { state } = defineProps<{ state: TableState }>()\nconst ns = useNamespace('chart')\nconst { shown, caption, head, rows, more } = state\n\nfunction onKeydown(event: KeyboardEvent) {\n // the chart's own keys are for its tooltip\n event.stopPropagation()\n if (event.key === 'Escape') state.close()\n}\n</script>\n\n<template>\n <!-- scrolls on its own, so it can take focus and be scrolled with the keys -->\n <!-- oxlint-disable-next-line vuejs-accessibility/no-noninteractive-tabindex -->\n <div\n v-if=\"shown\"\n :class=\"ns.e('table')\"\n tabindex=\"0\"\n @keydown=\"onKeydown\"\n @pointerdown.stop\n @pointermove.stop\n @wheel.stop\n @dblclick.stop\n >\n <table>\n <caption>\n {{\n caption\n }}\n </caption>\n <thead>\n <tr>\n <th v-for=\"(cell, i) in head\" :key=\"i\" scope=\"col\">{{ cell }}</th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(row, r) in rows\" :key=\"r\">\n <template v-for=\"(cell, i) in row\" :key=\"i\">\n <th v-if=\"i === 0\" scope=\"row\">{{ cell }}</th>\n <td v-else>{{ cell }}</td>\n </template>\n </tr>\n </tbody>\n </table>\n <p v-if=\"more\" :class=\"ns.e('table-more')\">{{ more }}</p>\n </div>\n</template>\n"],"mappings":""}
@@ -0,0 +1,52 @@
1
+ import { useNamespace } from "dou-ui";
2
+ import { Fragment, createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, openBlock, renderList, toDisplayString, unref, withModifiers } from "vue";
3
+ // src/table.vue?vue&type=script&setup=true&lang.ts
4
+ var _hoisted_1 = {
5
+ key: 0,
6
+ scope: "row"
7
+ };
8
+ var _hoisted_2 = { key: 1 };
9
+ var table_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
10
+ name: "DouChartTable",
11
+ __name: "table",
12
+ props: { state: {} },
13
+ setup(__props) {
14
+ const ns = useNamespace("chart");
15
+ const { shown, caption, head, rows, more } = __props.state;
16
+ function onKeydown(event) {
17
+ event.stopPropagation();
18
+ if (event.key === "Escape") __props.state.close();
19
+ }
20
+ return (_ctx, _cache) => {
21
+ return unref(shown) ? (openBlock(), createElementBlock("div", {
22
+ key: 0,
23
+ class: normalizeClass(unref(ns).e("table")),
24
+ tabindex: "0",
25
+ onKeydown,
26
+ onPointerdown: _cache[0] || (_cache[0] = withModifiers(() => {}, ["stop"])),
27
+ onPointermove: _cache[1] || (_cache[1] = withModifiers(() => {}, ["stop"])),
28
+ onWheel: _cache[2] || (_cache[2] = withModifiers(() => {}, ["stop"])),
29
+ onDblclick: _cache[3] || (_cache[3] = withModifiers(() => {}, ["stop"]))
30
+ }, [createElementVNode("table", null, [
31
+ createElementVNode("caption", null, toDisplayString(unref(caption)), 1),
32
+ createElementVNode("thead", null, [createElementVNode("tr", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(head), (cell, i) => {
33
+ return openBlock(), createElementBlock("th", {
34
+ key: i,
35
+ scope: "col"
36
+ }, toDisplayString(cell), 1);
37
+ }), 128))])]),
38
+ createElementVNode("tbody", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(rows), (row, r) => {
39
+ return openBlock(), createElementBlock("tr", { key: r }, [(openBlock(true), createElementBlock(Fragment, null, renderList(row, (cell, i) => {
40
+ return openBlock(), createElementBlock(Fragment, { key: i }, [i === 0 ? (openBlock(), createElementBlock("th", _hoisted_1, toDisplayString(cell), 1)) : (openBlock(), createElementBlock("td", _hoisted_2, toDisplayString(cell), 1))], 64);
41
+ }), 128))]);
42
+ }), 128))])
43
+ ]), unref(more) ? (openBlock(), createElementBlock("p", {
44
+ key: 0,
45
+ class: normalizeClass(unref(ns).e("table-more"))
46
+ }, toDisplayString(unref(more)), 3)) : createCommentVNode("", true)], 34)) : createCommentVNode("", true);
47
+ };
48
+ }
49
+ });
50
+ export { table_vue_vue_type_script_setup_true_lang_default as default };
51
+
52
+ //# sourceMappingURL=table.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.vue_vue_type_script_setup_true_lang.js","names":["_unref","_openBlock","_createElementBlock","_normalizeClass","_withModifiers","_createElementVNode","_toDisplayString","_Fragment","_renderList","_createCommentVNode"],"sources":["../src/table.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useNamespace } from 'dou-ui'\nimport type { ComputedRef } from 'vue'\n\n/** The chart's data as a table, shown in its place. */\nexport interface TableState {\n shown: ComputedRef<boolean>\n caption: ComputedRef<string>\n head: ComputedRef<string[]>\n /** Each row's cells; the first is the row's head. */\n rows: ComputedRef<string[][]>\n /** A line under a table cut short. */\n more: ComputedRef<string>\n /** Escape in the table: back to the chart. */\n close: () => void\n}\n\ndefineOptions({ name: 'DouChartTable' })\n\nconst { state } = defineProps<{ state: TableState }>()\nconst ns = useNamespace('chart')\nconst { shown, caption, head, rows, more } = state\n\nfunction onKeydown(event: KeyboardEvent) {\n // the chart's own keys are for its tooltip\n event.stopPropagation()\n if (event.key === 'Escape') state.close()\n}\n</script>\n\n<template>\n <!-- scrolls on its own, so it can take focus and be scrolled with the keys -->\n <!-- oxlint-disable-next-line vuejs-accessibility/no-noninteractive-tabindex -->\n <div\n v-if=\"shown\"\n :class=\"ns.e('table')\"\n tabindex=\"0\"\n @keydown=\"onKeydown\"\n @pointerdown.stop\n @pointermove.stop\n @wheel.stop\n @dblclick.stop\n >\n <table>\n <caption>\n {{\n caption\n }}\n </caption>\n <thead>\n <tr>\n <th v-for=\"(cell, i) in head\" :key=\"i\" scope=\"col\">{{ cell }}</th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(row, r) in rows\" :key=\"r\">\n <template v-for=\"(cell, i) in row\" :key=\"i\">\n <th v-if=\"i === 0\" scope=\"row\">{{ cell }}</th>\n <td v-else>{{ cell }}</td>\n </template>\n </tr>\n </tbody>\n </table>\n <p v-if=\"more\" :class=\"ns.e('table-more')\">{{ more }}</p>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;EAoBA,MAAM,KAAK,aAAa,OAAO;EAC/B,MAAM,EAAE,OAAO,SAAS,MAAM,MAAM,SAAS,QAAA;EAE7C,SAAS,UAAU,OAAsB;GAEvC,MAAM,gBAAgB;GACtB,IAAI,MAAM,QAAQ,UAAU,QAAA,MAAM,MAAM;EAC1C;;GAOU,OAAAA,MAAA,KAAA,KADRC,UAAA,GAAAC,mBA+BM,OAAA;;IA7BH,OAAKC,eAAEH,MAAA,EAAA,CAAE,CAAC,EAAC,OAAA,CAAA;IACZ,UAAS;IACC;IACT,eAAW,OAAA,OAAA,OAAA,KAAAI,oBAAZ,CAAA,GAAiB,CAAA,MAAA,CAAA;IAChB,eAAW,OAAA,OAAA,OAAA,KAAAA,oBAAZ,CAAA,GAAiB,CAAA,MAAA,CAAA;IAChB,SAAK,OAAA,OAAA,OAAA,KAAAA,oBAAN,CAAA,GAAW,CAAA,MAAA,CAAA;IACV,YAAQ,OAAA,OAAA,OAAA,KAAAA,oBAAT,CAAA,GAAc,CAAA,MAAA,CAAA;G,IAEdC,mBAmBQ,SAAA,MAAA;IAlBNA,mBAIU,WAAA,MAAAC,gBAFNN,MAAA,OAAA,CAAO,GAAA,CAAA;IAGXK,mBAIQ,SAAA,MAAA,CAHNA,mBAEK,MAAA,MAAA,EADHJ,UAAA,IAAA,GAAAC,mBAAkEK,UAAA,MAAAC,WAA1CR,MAAA,IAAA,IAAZ,MAAM,MAAC;KAAnB,OAAAC,UAAA,GAAAC,mBAAkE,MAAA;MAAnC,KAAK;MAAG,OAAM;KAAS,GAAAI,gBAAA,IAAI,GAAA,CAAA;;IAG9DD,mBAOQ,SAAA,MAAA,EANNJ,UAAA,IAAA,GAAAC,mBAKKK,UAAA,MAAAC,WALkBR,MAAA,IAAA,IAAX,KAAK,MAAC;KAAlB,OAAAC,UAAA,GAAAC,mBAKK,MAAA,EALyB,KAAK,EAAC,GAAA,EAClCD,UAAA,IAAA,GAAAC,mBAGWK,UAAA,MAAAC,WAHmB,MAAZ,MAAM,MAAC;MAAgB,OAAAP,UAAA,GAAAC,mBAAAK,UAAA,EAAA,KAAA,EAAC,GAAA,CAC9B,MAAC,KAAXN,UAAA,GAAAC,mBAA8C,MAA9C,YAA8CI,gBAAZ,IAAI,GAAA,CAAA,MACtCL,UAAA,GAAAC,mBAA0B,MAAA,YAAAI,gBAAZ,IAAI,GAAA,CAAA,E;;;G,IAKjBN,MAAA,IAAA,KAATC,UAAA,GAAAC,mBAAyD,KAAA;;IAAzC,OAAKC,eAAEH,MAAA,EAAA,CAAE,CAAC,EAAC,YAAA,CAAA;GAAmB,GAAAM,gBAAAN,MAAA,IAAA,CAAI,GAAA,CAAA,K"}