@vielzeug/prism 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/README.md +83 -0
  2. package/dist/_dev.cjs +2 -0
  3. package/dist/_dev.cjs.map +1 -0
  4. package/dist/_dev.d.ts +2 -0
  5. package/dist/_dev.d.ts.map +1 -0
  6. package/dist/_dev.js +12 -0
  7. package/dist/_dev.js.map +1 -0
  8. package/dist/animation/easing.cjs +2 -0
  9. package/dist/animation/easing.cjs.map +1 -0
  10. package/dist/animation/easing.d.ts +4 -0
  11. package/dist/animation/easing.d.ts.map +1 -0
  12. package/dist/animation/easing.js +14 -0
  13. package/dist/animation/easing.js.map +1 -0
  14. package/dist/animation/index.d.ts +6 -0
  15. package/dist/animation/index.d.ts.map +1 -0
  16. package/dist/animation/transition.cjs +2 -0
  17. package/dist/animation/transition.cjs.map +1 -0
  18. package/dist/animation/transition.d.ts +15 -0
  19. package/dist/animation/transition.d.ts.map +1 -0
  20. package/dist/animation/transition.js +28 -0
  21. package/dist/animation/transition.js.map +1 -0
  22. package/dist/animation/tween.cjs +2 -0
  23. package/dist/animation/tween.cjs.map +1 -0
  24. package/dist/animation/tween.d.ts +3 -0
  25. package/dist/animation/tween.d.ts.map +1 -0
  26. package/dist/animation/tween.js +8 -0
  27. package/dist/animation/tween.js.map +1 -0
  28. package/dist/axes/axis.cjs +2 -0
  29. package/dist/axes/axis.cjs.map +1 -0
  30. package/dist/axes/axis.d.ts +15 -0
  31. package/dist/axes/axis.d.ts.map +1 -0
  32. package/dist/axes/axis.js +60 -0
  33. package/dist/axes/axis.js.map +1 -0
  34. package/dist/axes/grid.cjs +2 -0
  35. package/dist/axes/grid.cjs.map +1 -0
  36. package/dist/axes/grid.d.ts +4 -0
  37. package/dist/axes/grid.d.ts.map +1 -0
  38. package/dist/axes/grid.js +30 -0
  39. package/dist/axes/grid.js.map +1 -0
  40. package/dist/axes/index.d.ts +3 -0
  41. package/dist/axes/index.d.ts.map +1 -0
  42. package/dist/axes/scale-utils.cjs +2 -0
  43. package/dist/axes/scale-utils.cjs.map +1 -0
  44. package/dist/axes/scale-utils.d.ts +17 -0
  45. package/dist/axes/scale-utils.d.ts.map +1 -0
  46. package/dist/axes/scale-utils.js +11 -0
  47. package/dist/axes/scale-utils.js.map +1 -0
  48. package/dist/axes/types.d.ts +2 -0
  49. package/dist/axes/types.d.ts.map +1 -0
  50. package/dist/charts/area/area-chart.cjs +2 -0
  51. package/dist/charts/area/area-chart.cjs.map +1 -0
  52. package/dist/charts/area/area-chart.d.ts +3 -0
  53. package/dist/charts/area/area-chart.d.ts.map +1 -0
  54. package/dist/charts/area/area-chart.js +58 -0
  55. package/dist/charts/area/area-chart.js.map +1 -0
  56. package/dist/charts/area/area-renderer.cjs +2 -0
  57. package/dist/charts/area/area-renderer.cjs.map +1 -0
  58. package/dist/charts/area/area-renderer.d.ts +14 -0
  59. package/dist/charts/area/area-renderer.d.ts.map +1 -0
  60. package/dist/charts/area/area-renderer.js +73 -0
  61. package/dist/charts/area/area-renderer.js.map +1 -0
  62. package/dist/charts/area/area-types.d.ts +2 -0
  63. package/dist/charts/area/area-types.d.ts.map +1 -0
  64. package/dist/charts/area/index.d.ts +2 -0
  65. package/dist/charts/area/index.d.ts.map +1 -0
  66. package/dist/charts/bar/bar-chart.cjs +2 -0
  67. package/dist/charts/bar/bar-chart.cjs.map +1 -0
  68. package/dist/charts/bar/bar-chart.d.ts +3 -0
  69. package/dist/charts/bar/bar-chart.d.ts.map +1 -0
  70. package/dist/charts/bar/bar-chart.js +151 -0
  71. package/dist/charts/bar/bar-chart.js.map +1 -0
  72. package/dist/charts/bar/bar-hit-test.cjs +2 -0
  73. package/dist/charts/bar/bar-hit-test.cjs.map +1 -0
  74. package/dist/charts/bar/bar-hit-test.d.ts +12 -0
  75. package/dist/charts/bar/bar-hit-test.d.ts.map +1 -0
  76. package/dist/charts/bar/bar-hit-test.js +29 -0
  77. package/dist/charts/bar/bar-hit-test.js.map +1 -0
  78. package/dist/charts/bar/bar-renderer.cjs +2 -0
  79. package/dist/charts/bar/bar-renderer.cjs.map +1 -0
  80. package/dist/charts/bar/bar-renderer.d.ts +19 -0
  81. package/dist/charts/bar/bar-renderer.d.ts.map +1 -0
  82. package/dist/charts/bar/bar-renderer.js +107 -0
  83. package/dist/charts/bar/bar-renderer.js.map +1 -0
  84. package/dist/charts/bar/bar-scale-context.d.ts +11 -0
  85. package/dist/charts/bar/bar-scale-context.d.ts.map +1 -0
  86. package/dist/charts/bar/bar-types.d.ts +2 -0
  87. package/dist/charts/bar/bar-types.d.ts.map +1 -0
  88. package/dist/charts/bar/index.d.ts +2 -0
  89. package/dist/charts/bar/index.d.ts.map +1 -0
  90. package/dist/charts/index.d.ts +6 -0
  91. package/dist/charts/index.d.ts.map +1 -0
  92. package/dist/charts/line/index.d.ts +2 -0
  93. package/dist/charts/line/index.d.ts.map +1 -0
  94. package/dist/charts/line/line-chart.cjs +2 -0
  95. package/dist/charts/line/line-chart.cjs.map +1 -0
  96. package/dist/charts/line/line-chart.d.ts +3 -0
  97. package/dist/charts/line/line-chart.d.ts.map +1 -0
  98. package/dist/charts/line/line-chart.js +59 -0
  99. package/dist/charts/line/line-chart.js.map +1 -0
  100. package/dist/charts/line/line-renderer.cjs +2 -0
  101. package/dist/charts/line/line-renderer.cjs.map +1 -0
  102. package/dist/charts/line/line-renderer.d.ts +15 -0
  103. package/dist/charts/line/line-renderer.d.ts.map +1 -0
  104. package/dist/charts/line/line-renderer.js +100 -0
  105. package/dist/charts/line/line-renderer.js.map +1 -0
  106. package/dist/charts/line/line-types.d.ts +2 -0
  107. package/dist/charts/line/line-types.d.ts.map +1 -0
  108. package/dist/charts/pie/index.d.ts +2 -0
  109. package/dist/charts/pie/index.d.ts.map +1 -0
  110. package/dist/charts/pie/pie-chart.cjs +2 -0
  111. package/dist/charts/pie/pie-chart.cjs.map +1 -0
  112. package/dist/charts/pie/pie-chart.d.ts +3 -0
  113. package/dist/charts/pie/pie-chart.d.ts.map +1 -0
  114. package/dist/charts/pie/pie-chart.js +156 -0
  115. package/dist/charts/pie/pie-chart.js.map +1 -0
  116. package/dist/charts/pie/pie-renderer.cjs +2 -0
  117. package/dist/charts/pie/pie-renderer.cjs.map +1 -0
  118. package/dist/charts/pie/pie-renderer.d.ts +23 -0
  119. package/dist/charts/pie/pie-renderer.d.ts.map +1 -0
  120. package/dist/charts/pie/pie-renderer.js +77 -0
  121. package/dist/charts/pie/pie-renderer.js.map +1 -0
  122. package/dist/charts/sparkline/index.d.ts +2 -0
  123. package/dist/charts/sparkline/index.d.ts.map +1 -0
  124. package/dist/charts/sparkline/sparkline.cjs +2 -0
  125. package/dist/charts/sparkline/sparkline.cjs.map +1 -0
  126. package/dist/charts/sparkline/sparkline.d.ts +3 -0
  127. package/dist/charts/sparkline/sparkline.d.ts.map +1 -0
  128. package/dist/charts/sparkline/sparkline.js +187 -0
  129. package/dist/charts/sparkline/sparkline.js.map +1 -0
  130. package/dist/core/cartesian-scales.cjs +2 -0
  131. package/dist/core/cartesian-scales.cjs.map +1 -0
  132. package/dist/core/cartesian-scales.d.ts +4 -0
  133. package/dist/core/cartesian-scales.d.ts.map +1 -0
  134. package/dist/core/cartesian-scales.js +54 -0
  135. package/dist/core/cartesian-scales.js.map +1 -0
  136. package/dist/core/chart-base.cjs +2 -0
  137. package/dist/core/chart-base.cjs.map +1 -0
  138. package/dist/core/chart-base.d.ts +14 -0
  139. package/dist/core/chart-base.d.ts.map +1 -0
  140. package/dist/core/chart-base.js +60 -0
  141. package/dist/core/chart-base.js.map +1 -0
  142. package/dist/core/chart-scaffold.cjs +2 -0
  143. package/dist/core/chart-scaffold.cjs.map +1 -0
  144. package/dist/core/chart-scaffold.d.ts +54 -0
  145. package/dist/core/chart-scaffold.d.ts.map +1 -0
  146. package/dist/core/chart-scaffold.js +104 -0
  147. package/dist/core/chart-scaffold.js.map +1 -0
  148. package/dist/core/index.d.ts +7 -0
  149. package/dist/core/index.d.ts.map +1 -0
  150. package/dist/core/layout.cjs +2 -0
  151. package/dist/core/layout.cjs.map +1 -0
  152. package/dist/core/layout.d.ts +7 -0
  153. package/dist/core/layout.d.ts.map +1 -0
  154. package/dist/core/layout.js +23 -0
  155. package/dist/core/layout.js.map +1 -0
  156. package/dist/core/responsive.cjs +2 -0
  157. package/dist/core/responsive.cjs.map +1 -0
  158. package/dist/core/responsive.d.ts +2 -0
  159. package/dist/core/responsive.d.ts.map +1 -0
  160. package/dist/core/responsive.js +20 -0
  161. package/dist/core/responsive.js.map +1 -0
  162. package/dist/devtools/index.d.ts +52 -0
  163. package/dist/devtools/index.d.ts.map +1 -0
  164. package/dist/devtools.cjs +2 -0
  165. package/dist/devtools.cjs.map +1 -0
  166. package/dist/devtools.js +19 -0
  167. package/dist/devtools.js.map +1 -0
  168. package/dist/errors.cjs +2 -0
  169. package/dist/errors.cjs.map +1 -0
  170. package/dist/errors.d.ts +16 -0
  171. package/dist/errors.d.ts.map +1 -0
  172. package/dist/errors.js +13 -0
  173. package/dist/errors.js.map +1 -0
  174. package/dist/index.cjs +1 -0
  175. package/dist/index.d.ts +19 -0
  176. package/dist/index.d.ts.map +1 -0
  177. package/dist/index.js +12 -0
  178. package/dist/interaction/crosshair.cjs +2 -0
  179. package/dist/interaction/crosshair.cjs.map +1 -0
  180. package/dist/interaction/crosshair.d.ts +13 -0
  181. package/dist/interaction/crosshair.d.ts.map +1 -0
  182. package/dist/interaction/crosshair.js +46 -0
  183. package/dist/interaction/crosshair.js.map +1 -0
  184. package/dist/interaction/events.cjs +2 -0
  185. package/dist/interaction/events.cjs.map +1 -0
  186. package/dist/interaction/events.d.ts +3 -0
  187. package/dist/interaction/events.d.ts.map +1 -0
  188. package/dist/interaction/events.js +12 -0
  189. package/dist/interaction/events.js.map +1 -0
  190. package/dist/interaction/hit-test.cjs +2 -0
  191. package/dist/interaction/hit-test.cjs.map +1 -0
  192. package/dist/interaction/hit-test.d.ts +3 -0
  193. package/dist/interaction/hit-test.d.ts.map +1 -0
  194. package/dist/interaction/hit-test.js +14 -0
  195. package/dist/interaction/hit-test.js.map +1 -0
  196. package/dist/interaction/index.d.ts +9 -0
  197. package/dist/interaction/index.d.ts.map +1 -0
  198. package/dist/interaction/legend.cjs +2 -0
  199. package/dist/interaction/legend.cjs.map +1 -0
  200. package/dist/interaction/legend.d.ts +12 -0
  201. package/dist/interaction/legend.d.ts.map +1 -0
  202. package/dist/interaction/legend.js +31 -0
  203. package/dist/interaction/legend.js.map +1 -0
  204. package/dist/interaction/series-interaction.cjs +2 -0
  205. package/dist/interaction/series-interaction.cjs.map +1 -0
  206. package/dist/interaction/series-interaction.d.ts +18 -0
  207. package/dist/interaction/series-interaction.d.ts.map +1 -0
  208. package/dist/interaction/series-interaction.js +58 -0
  209. package/dist/interaction/series-interaction.js.map +1 -0
  210. package/dist/interaction/tooltip.cjs +2 -0
  211. package/dist/interaction/tooltip.cjs.map +1 -0
  212. package/dist/interaction/tooltip.d.ts +10 -0
  213. package/dist/interaction/tooltip.d.ts.map +1 -0
  214. package/dist/interaction/tooltip.js +53 -0
  215. package/dist/interaction/tooltip.js.map +1 -0
  216. package/dist/prism.cjs +2 -0
  217. package/dist/prism.cjs.map +1 -0
  218. package/dist/prism.iife.js +2 -0
  219. package/dist/prism.iife.js.map +1 -0
  220. package/dist/prism.js +2 -0
  221. package/dist/prism.js.map +1 -0
  222. package/dist/scales/band.cjs +2 -0
  223. package/dist/scales/band.cjs.map +1 -0
  224. package/dist/scales/band.d.ts +3 -0
  225. package/dist/scales/band.d.ts.map +1 -0
  226. package/dist/scales/band.js +40 -0
  227. package/dist/scales/band.js.map +1 -0
  228. package/dist/scales/index.d.ts +4 -0
  229. package/dist/scales/index.d.ts.map +1 -0
  230. package/dist/scales/linear.cjs +2 -0
  231. package/dist/scales/linear.cjs.map +1 -0
  232. package/dist/scales/linear.d.ts +4 -0
  233. package/dist/scales/linear.d.ts.map +1 -0
  234. package/dist/scales/linear.js +44 -0
  235. package/dist/scales/linear.js.map +1 -0
  236. package/dist/scales/time.cjs +2 -0
  237. package/dist/scales/time.cjs.map +1 -0
  238. package/dist/scales/time.d.ts +4 -0
  239. package/dist/scales/time.d.ts.map +1 -0
  240. package/dist/scales/time.js +62 -0
  241. package/dist/scales/time.js.map +1 -0
  242. package/dist/scales/types.d.ts +19 -0
  243. package/dist/scales/types.d.ts.map +1 -0
  244. package/dist/svg/element.cjs +2 -0
  245. package/dist/svg/element.cjs.map +1 -0
  246. package/dist/svg/element.d.ts +4 -0
  247. package/dist/svg/element.d.ts.map +1 -0
  248. package/dist/svg/element.js +23 -0
  249. package/dist/svg/element.js.map +1 -0
  250. package/dist/svg/index.d.ts +5 -0
  251. package/dist/svg/index.d.ts.map +1 -0
  252. package/dist/svg/path.cjs +2 -0
  253. package/dist/svg/path.cjs.map +1 -0
  254. package/dist/svg/path.d.ts +9 -0
  255. package/dist/svg/path.d.ts.map +1 -0
  256. package/dist/svg/path.js +49 -0
  257. package/dist/svg/path.js.map +1 -0
  258. package/dist/svg/text.cjs +2 -0
  259. package/dist/svg/text.cjs.map +1 -0
  260. package/dist/svg/text.d.ts +7 -0
  261. package/dist/svg/text.d.ts.map +1 -0
  262. package/dist/svg/text.js +10 -0
  263. package/dist/svg/text.js.map +1 -0
  264. package/dist/theme/index.cjs +2 -0
  265. package/dist/theme/index.cjs.map +1 -0
  266. package/dist/theme/index.d.ts +6 -0
  267. package/dist/theme/index.d.ts.map +1 -0
  268. package/dist/theme/index.js +20 -0
  269. package/dist/theme/index.js.map +1 -0
  270. package/dist/theme/prism.css +342 -0
  271. package/dist/types.d.ts +204 -0
  272. package/dist/types.d.ts.map +1 -0
  273. package/package.json +79 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sparkline.js","names":[],"sources":["../../../src/charts/sparkline/sparkline.ts"],"sourcesContent":["import { effect, isReactive, scope } from '@vielzeug/ripple';\n\nimport type { Point } from '../../svg/path';\nimport type { ChartHandle, SparklineConfig, StackSegment } from '../../types';\n\nimport { resolveEasing } from '../../animation/easing';\nimport { tweenNumber } from '../../animation/tween';\nimport { createChartBase } from '../../core/chart-base';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { areaPath, linePath, monotonePath, stepPath } from '../../svg/path';\n\nfunction buildTopPoints(data: number[], width: number, height: number): Point[] {\n if (data.length === 0) return [];\n\n const xStep = width / Math.max(1, data.length - 1);\n const min = Math.min(...data);\n const max = Math.max(...data);\n const yRange = max - min || 1;\n\n return data.map((v, i) => ({\n x: i * xStep,\n y: height - ((v - min) / yRange) * height,\n }));\n}\n\nfunction buildAreaPath(\n data: number[],\n width: number,\n height: number,\n curve: SparklineConfig['curve'] = 'linear',\n): string {\n if (data.length === 0) return '';\n\n const top = buildTopPoints(data, width, height);\n const bottom = top.map((p) => ({ x: p.x, y: height }));\n\n return areaPath(top, bottom, curve ?? 'linear');\n}\n\nfunction buildPath(data: number[], width: number, height: number, curve: SparklineConfig['curve']): string {\n if (data.length === 0) return '';\n\n const points = buildTopPoints(data, width, height);\n\n return curve === 'monotone' ? monotonePath(points) : curve === 'step' ? stepPath(points) : linePath(points);\n}\n\nfunction renderSparkBars(\n parent: SVGGElement,\n data: number[],\n width: number,\n height: number,\n color: string,\n transition?: SparklineConfig['transition'],\n disposalSignal?: AbortSignal,\n): void {\n const count = data.length;\n const barW = Math.max(1, width / count - 1);\n const gap = width / count;\n const min = Math.min(0, ...data);\n const max = Math.max(...data);\n const yRange = max - min || 1;\n const dur = transition?.duration ?? 0;\n const easing = resolveEasing(transition?.easing);\n\n while (parent.children.length > count) {\n const last = parent.lastElementChild;\n\n if (last) parent.removeChild(last);\n }\n\n for (let i = 0; i < count; i++) {\n const finalH = Math.max(1, ((data[i] - min) / yRange) * height);\n const finalY = height - finalH;\n\n let rect = parent.children[i] as SVGRectElement | undefined;\n\n if (!rect) {\n rect = createSvgElement('rect', { class: 'prism-spark-bar' });\n parent.appendChild(rect);\n }\n\n setAttributes(rect, { fill: color, width: barW, x: i * gap });\n\n if (dur > 0 && !rect.hasAttribute('data-init')) {\n rect.setAttribute('data-init', '1');\n setAttributes(rect, { height: 0, y: height });\n\n let start: number | null = null;\n const from = { h: 0, y: height };\n const to = { h: finalH, y: finalY };\n\n const frame = (ts: number) => {\n if (disposalSignal?.aborted) return;\n\n if (start === null) start = ts;\n\n const t = easing(Math.min(1, (ts - start) / dur));\n\n setAttributes(rect!, {\n height: tweenNumber(from.h, to.h, t),\n y: tweenNumber(from.y, to.y, t),\n });\n\n if (t < 1) requestAnimationFrame(frame);\n };\n\n requestAnimationFrame(frame);\n } else {\n rect.setAttribute('data-init', '1');\n setAttributes(rect, { height: finalH, y: finalY });\n }\n }\n}\n\nfunction isStackData(data: number[] | StackSegment[]): data is StackSegment[] {\n return data.length > 0 && data[0] !== null && typeof data[0] === 'object';\n}\n\nfunction buildRoundedStackRect(\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n roundLeft: boolean,\n roundRight: boolean,\n): string {\n const maxR = Math.min(r, w / 2, h / 2);\n const tl = roundLeft ? maxR : 0;\n const bl = roundLeft ? maxR : 0;\n const tr = roundRight ? maxR : 0;\n const br = roundRight ? maxR : 0;\n\n return [\n `M${x + tl},${y}`,\n `H${x + w - tr}`,\n tr ? `Q${x + w},${y} ${x + w},${y + tr}` : '',\n `V${y + h - br}`,\n br ? `Q${x + w},${y + h} ${x + w - br},${y + h}` : '',\n `H${x + bl}`,\n bl ? `Q${x},${y + h} ${x},${y + h - bl}` : '',\n `V${y + tl}`,\n tl ? `Q${x},${y} ${x + tl},${y}` : '',\n 'Z',\n ]\n .filter(Boolean)\n .join('');\n}\n\nfunction defaultStackColor(i: number): string {\n return `var(--prism-color-${(i % 8) + 1})`;\n}\n\nexport function createSparkline(container: HTMLElement, config: SparklineConfig): ChartHandle {\n const variant = config.variant ?? 'line';\n const color = config.color ?? 'var(--prism-color-1)';\n const curve = config.curve ?? 'linear';\n const strokeWidth = config.strokeWidth ?? 1.5;\n const fillOpacity = config.fillOpacity ?? 0.2;\n\n const base = createChartBase(container, {\n ...(config.ariaLabel ? { ariaLabel: config.ariaLabel } : { ariaHidden: true }),\n margin: { bottom: 0, left: 0, right: 0, top: 0 },\n });\n\n const { svg } = base;\n\n svg.classList.add('prism-sparkline');\n\n const innerGroup = createSvgElement('g', { class: 'prism-spark-inner' });\n\n svg.appendChild(innerGroup);\n\n let cleanupInteraction: (() => void) | undefined;\n\n function renderAll(): void {\n const { height: h, width: w } = base.dimensions.value;\n const data = isReactive(config.data) ? config.data.value : config.data;\n\n while (innerGroup.firstChild) innerGroup.removeChild(innerGroup.firstChild);\n\n if (data.length === 0) return;\n\n if (variant === 'stack' && isStackData(data)) {\n const stackGroup = createSvgElement('g', { class: 'prism-spark-stack' });\n\n innerGroup.appendChild(stackGroup);\n\n const cornerRadius = config.cornerRadius ?? 4;\n const segs = data as StackSegment[];\n const total = segs.reduce((s, d) => s + Math.max(0, d.value), 0);\n\n if (total > 0) {\n const half = (config.padPixels ?? 0) / 2;\n let xAcc = 0;\n\n segs.forEach((seg, i) => {\n const xStart = Math.round(xAcc);\n\n xAcc += (Math.max(0, seg.value) / total) * w;\n\n const xEnd = i === segs.length - 1 ? w : Math.round(xAcc);\n const isFirst = i === 0;\n const isLast = i === segs.length - 1;\n const drawX = xStart + (isFirst ? 0 : half);\n const drawW = Math.max(0, xEnd - xStart - (isFirst ? 0 : half) - (isLast ? 0 : half));\n const d = buildRoundedStackRect(drawX, 0, drawW, h, cornerRadius, isFirst, isLast);\n const path = createSvgElement('path', { class: 'prism-spark-stack-segment' });\n\n setAttributes(path, { d, fill: seg.color ?? defaultStackColor(i) });\n stackGroup.appendChild(path);\n });\n }\n } else if (variant === 'bar') {\n const barsGroup = createSvgElement('g', { class: 'prism-spark-bars' });\n\n innerGroup.appendChild(barsGroup);\n renderSparkBars(barsGroup, data as number[], w, h, color, config.transition, ac.signal);\n } else {\n if (variant === 'area') {\n const fill = createSvgElement('path', { class: 'prism-spark-fill' });\n const fillD = buildAreaPath(data as number[], w, h, curve);\n\n setAttributes(fill, { d: fillD, fill: color, 'fill-opacity': fillOpacity, stroke: 'none' });\n innerGroup.appendChild(fill);\n }\n\n const path = createSvgElement('path', { class: 'prism-spark-line' });\n const pathD = buildPath(data as number[], w, h, curve);\n\n setAttributes(path, { d: pathD, fill: 'none', stroke: color, 'stroke-width': strokeWidth });\n innerGroup.appendChild(path);\n }\n\n if (!isStackData(data)) attachInteraction(data as number[]);\n }\n\n function attachInteraction(data: number[]): void {\n cleanupInteraction?.();\n cleanupInteraction = undefined;\n\n if (!config.onHover && !config.onClick) return;\n\n if (data.length <= 1) return;\n\n const { width: w } = base.dimensions.value;\n\n svg.style.cursor = 'crosshair';\n\n const xStep = w / (data.length - 1);\n\n const handleMove = (e: MouseEvent) => {\n const rect = svg.getBoundingClientRect();\n const relX = e.clientX - rect.left;\n const idx = Math.max(0, Math.min(data.length - 1, Math.round(relX / xStep)));\n\n config.onHover?.(idx, data[idx]);\n };\n\n const handleLeave = () => config.onHover?.(null, null);\n\n const handleClick = (e: MouseEvent) => {\n if (!config.onClick) return;\n\n const rect = svg.getBoundingClientRect();\n const relX = e.clientX - rect.left;\n const idx = Math.max(0, Math.min(data.length - 1, Math.round(relX / xStep)));\n\n config.onClick(idx, data[idx]);\n };\n\n svg.addEventListener('mousemove', handleMove);\n svg.addEventListener('mouseleave', handleLeave);\n svg.addEventListener('click', handleClick);\n\n cleanupInteraction = () => {\n svg.removeEventListener('mousemove', handleMove);\n svg.removeEventListener('mouseleave', handleLeave);\n svg.removeEventListener('click', handleClick);\n };\n }\n\n const ac = new AbortController();\n\n const s = scope(() => {\n effect(\n () => {\n renderAll();\n },\n { scheduler: 'microtask' },\n );\n });\n\n let isDisposed = false;\n\n return {\n get disposalSignal(): AbortSignal {\n return ac.signal;\n },\n\n dispose() {\n if (isDisposed) return;\n\n isDisposed = true;\n ac.abort();\n cleanupInteraction?.();\n s.dispose();\n base.dispose();\n },\n\n get disposed(): boolean {\n return isDisposed;\n },\n\n el: svg,\n\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n}\n"],"mappings":";;;;;;;AAWA,SAAS,EAAe,GAAgB,GAAe,GAAyB;CAC9E,IAAI,EAAK,WAAW,GAAG,OAAO,CAAC;CAE/B,IAAM,IAAQ,IAAQ,KAAK,IAAI,GAAG,EAAK,SAAS,CAAC,GAC3C,IAAM,KAAK,IAAI,GAAG,CAAI,GAEtB,IADM,KAAK,IAAI,GAAG,CACT,IAAM,KAAO;CAE5B,OAAO,EAAK,KAAK,GAAG,OAAO;EACzB,GAAG,IAAI;EACP,GAAG,KAAW,IAAI,KAAO,IAAU;CACrC,EAAE;AACJ;AAEA,SAAS,EACP,GACA,GACA,GACA,IAAkC,UAC1B;CACR,IAAI,EAAK,WAAW,GAAG,OAAO;CAE9B,IAAM,IAAM,EAAe,GAAM,GAAO,CAAM;CAG9C,OAAO,EAAS,GAFD,EAAI,KAAK,OAAO;EAAE,GAAG,EAAE;EAAG,GAAG;CAAO,EAE9B,GAAQ,KAAS,QAAQ;AAChD;AAEA,SAAS,EAAU,GAAgB,GAAe,GAAgB,GAAyC;CACzG,IAAI,EAAK,WAAW,GAAG,OAAO;CAE9B,IAAM,IAAS,EAAe,GAAM,GAAO,CAAM;CAEjD,OAAO,MAAU,aAAa,EAAa,CAAM,IAAI,MAAU,SAAS,EAAS,CAAM,IAAI,EAAS,CAAM;AAC5G;AAEA,SAAS,EACP,GACA,GACA,GACA,GACA,GACA,GACA,GACM;CACN,IAAM,IAAQ,EAAK,QACb,IAAO,KAAK,IAAI,GAAG,IAAQ,IAAQ,CAAC,GACpC,IAAM,IAAQ,GACd,IAAM,KAAK,IAAI,GAAG,GAAG,CAAI,GAEzB,IADM,KAAK,IAAI,GAAG,CACT,IAAM,KAAO,GACtB,IAAM,GAAY,YAAY,GAC9B,IAAS,EAAc,GAAY,MAAM;CAE/C,OAAO,EAAO,SAAS,SAAS,IAAO;EACrC,IAAM,IAAO,EAAO;EAEpB,AAAI,KAAM,EAAO,YAAY,CAAI;CACnC;CAEA,KAAK,IAAI,IAAI,GAAG,IAAI,GAAO,KAAK;EAC9B,IAAM,IAAS,KAAK,IAAI,IAAK,EAAK,KAAK,KAAO,IAAU,CAAM,GACxD,IAAS,IAAS,GAEpB,IAAO,EAAO,SAAS;EAS3B,IAPK,MACH,IAAO,EAAiB,QAAQ,EAAE,OAAO,kBAAkB,CAAC,GAC5D,EAAO,YAAY,CAAI,IAGzB,EAAc,GAAM;GAAE,MAAM;GAAO,OAAO;GAAM,GAAG,IAAI;EAAI,CAAC,GAExD,IAAM,KAAK,CAAC,EAAK,aAAa,WAAW,GAAG;GAE9C,AADA,EAAK,aAAa,aAAa,GAAG,GAClC,EAAc,GAAM;IAAE,QAAQ;IAAG,GAAG;GAAO,CAAC;GAE5C,IAAI,IAAuB,MACrB,IAAO;IAAE,GAAG;IAAG,GAAG;GAAO,GACzB,IAAK;IAAE,GAAG;IAAQ,GAAG;GAAO,GAE5B,KAAS,MAAe;IAC5B,IAAI,GAAgB,SAAS;IAE7B,AAAI,MAAU,SAAM,IAAQ;IAE5B,IAAM,IAAI,EAAO,KAAK,IAAI,IAAI,IAAK,KAAS,CAAG,CAAC;IAOhD,AALA,EAAc,GAAO;KACnB,QAAQ,EAAY,EAAK,GAAG,EAAG,GAAG,CAAC;KACnC,GAAG,EAAY,EAAK,GAAG,EAAG,GAAG,CAAC;IAChC,CAAC,GAEG,IAAI,KAAG,sBAAsB,CAAK;GACxC;GAEA,sBAAsB,CAAK;EAC7B,OAEE,AADA,EAAK,aAAa,aAAa,GAAG,GAClC,EAAc,GAAM;GAAE,QAAQ;GAAQ,GAAG;EAAO,CAAC;CAErD;AACF;AAEA,SAAS,EAAY,GAAyD;CAC5E,OAAO,EAAK,SAAS,KAAK,EAAK,OAAO,QAAQ,OAAO,EAAK,MAAO;AACnE;AAEA,SAAS,EACP,GACA,GACA,GACA,GACA,GACA,GACA,GACQ;CACR,IAAM,IAAO,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,GAC/B,IAAK,IAAY,IAAO,GACxB,IAAK,IAAY,IAAO,GACxB,IAAK,IAAa,IAAO,GACzB,IAAK,IAAa,IAAO;CAE/B,OAAO;EACL,IAAI,IAAI,EAAG,GAAG;EACd,IAAI,IAAI,IAAI;EACZ,IAAK,IAAI,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,MAAO;EAC3C,IAAI,IAAI,IAAI;EACZ,IAAK,IAAI,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,IAAI,EAAG,GAAG,IAAI,MAAM;EACnD,IAAI,IAAI;EACR,IAAK,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,IAAI,MAAO;EAC3C,IAAI,IAAI;EACR,IAAK,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,EAAG,GAAG,MAAM;EACnC;CACF,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,EAAE;AACZ;AAEA,SAAS,EAAkB,GAAmB;CAC5C,OAAO,qBAAsB,IAAI,IAAK,EAAE;AAC1C;AAEA,SAAgB,EAAgB,GAAwB,GAAsC;CAC5F,IAAM,IAAU,EAAO,WAAW,QAC5B,IAAQ,EAAO,SAAS,wBACxB,IAAQ,EAAO,SAAS,UACxB,IAAc,EAAO,eAAe,KACpC,IAAc,EAAO,eAAe,IAEpC,IAAO,EAAgB,GAAW;EACtC,GAAI,EAAO,YAAY,EAAE,WAAW,EAAO,UAAU,IAAI,EAAE,YAAY,GAAK;EAC5E,QAAQ;GAAE,QAAQ;GAAG,MAAM;GAAG,OAAO;GAAG,KAAK;EAAE;CACjD,CAAC,GAEK,EAAE,WAAQ;CAEhB,EAAI,UAAU,IAAI,iBAAiB;CAEnC,IAAM,IAAa,EAAiB,KAAK,EAAE,OAAO,oBAAoB,CAAC;CAEvE,EAAI,YAAY,CAAU;CAE1B,IAAI;CAEJ,SAAS,IAAkB;EACzB,IAAM,EAAE,QAAQ,GAAG,OAAO,MAAM,EAAK,WAAW,OAC1C,IAAO,EAAW,EAAO,IAAI,IAAI,EAAO,KAAK,QAAQ,EAAO;EAElE,OAAO,EAAW,aAAY,EAAW,YAAY,EAAW,UAAU;EAEtE,MAAK,WAAW,GAEpB;OAAI,MAAY,WAAW,EAAY,CAAI,GAAG;IAC5C,IAAM,IAAa,EAAiB,KAAK,EAAE,OAAO,oBAAoB,CAAC;IAEvE,EAAW,YAAY,CAAU;IAEjC,IAAM,IAAe,EAAO,gBAAgB,GACtC,IAAO,GACP,IAAQ,EAAK,QAAQ,GAAG,MAAM,IAAI,KAAK,IAAI,GAAG,EAAE,KAAK,GAAG,CAAC;IAE/D,IAAI,IAAQ,GAAG;KACb,IAAM,KAAQ,EAAO,aAAa,KAAK,GACnC,IAAO;KAEX,EAAK,SAAS,GAAK,MAAM;MACvB,IAAM,IAAS,KAAK,MAAM,CAAI;MAE9B,KAAS,KAAK,IAAI,GAAG,EAAI,KAAK,IAAI,IAAS;MAE3C,IAAM,IAAO,MAAM,EAAK,SAAS,IAAI,IAAI,KAAK,MAAM,CAAI,GAClD,IAAU,MAAM,GAChB,IAAS,MAAM,EAAK,SAAS,GAG7B,IAAI,EAFI,KAAU,IAAU,IAAI,IAEC,GADzB,KAAK,IAAI,GAAG,IAAO,KAAU,IAAU,IAAI,MAAS,IAAS,IAAI,EACrC,GAAO,GAAG,GAAc,GAAS,CAAM,GAC3E,IAAO,EAAiB,QAAQ,EAAE,OAAO,4BAA4B,CAAC;MAG5E,AADA,EAAc,GAAM;OAAE;OAAG,MAAM,EAAI,SAAS,EAAkB,CAAC;MAAE,CAAC,GAClE,EAAW,YAAY,CAAI;KAC7B,CAAC;IACH;GACF,OAAO,IAAI,MAAY,OAAO;IAC5B,IAAM,IAAY,EAAiB,KAAK,EAAE,OAAO,mBAAmB,CAAC;IAGrE,AADA,EAAW,YAAY,CAAS,GAChC,EAAgB,GAAW,GAAkB,GAAG,GAAG,GAAO,EAAO,YAAY,EAAG,MAAM;GACxF,OAAO;IACL,IAAI,MAAY,QAAQ;KACtB,IAAM,IAAO,EAAiB,QAAQ,EAAE,OAAO,mBAAmB,CAAC;KAInE,AADA,EAAc,GAAM;MAAE,GAFR,EAAc,GAAkB,GAAG,GAAG,CAE3B;MAAO,MAAM;MAAO,gBAAgB;MAAa,QAAQ;KAAO,CAAC,GAC1F,EAAW,YAAY,CAAI;IAC7B;IAEA,IAAM,IAAO,EAAiB,QAAQ,EAAE,OAAO,mBAAmB,CAAC;IAInE,AADA,EAAc,GAAM;KAAE,GAFR,EAAU,GAAkB,GAAG,GAAG,CAEvB;KAAO,MAAM;KAAQ,QAAQ;KAAO,gBAAgB;IAAY,CAAC,GAC1F,EAAW,YAAY,CAAI;GAC7B;GAEA,AAAK,EAAY,CAAI,KAAG,EAAkB,CAAgB;EAF1D;CAGF;CAEA,SAAS,EAAkB,GAAsB;EAM/C,IALA,IAAqB,GACrB,IAAqB,KAAA,GAEjB,CAAC,EAAO,WAAW,CAAC,EAAO,WAE3B,EAAK,UAAU,GAAG;EAEtB,IAAM,EAAE,OAAO,MAAM,EAAK,WAAW;EAErC,EAAI,MAAM,SAAS;EAEnB,IAAM,IAAQ,KAAK,EAAK,SAAS,IAE3B,KAAc,MAAkB;GACpC,IAAM,IAAO,EAAI,sBAAsB,GACjC,IAAO,EAAE,UAAU,EAAK,MACxB,IAAM,KAAK,IAAI,GAAG,KAAK,IAAI,EAAK,SAAS,GAAG,KAAK,MAAM,IAAO,CAAK,CAAC,CAAC;GAE3E,EAAO,UAAU,GAAK,EAAK,EAAI;EACjC,GAEM,UAAoB,EAAO,UAAU,MAAM,IAAI,GAE/C,KAAe,MAAkB;GACrC,IAAI,CAAC,EAAO,SAAS;GAErB,IAAM,IAAO,EAAI,sBAAsB,GACjC,IAAO,EAAE,UAAU,EAAK,MACxB,IAAM,KAAK,IAAI,GAAG,KAAK,IAAI,EAAK,SAAS,GAAG,KAAK,MAAM,IAAO,CAAK,CAAC,CAAC;GAE3E,EAAO,QAAQ,GAAK,EAAK,EAAI;EAC/B;EAMA,AAJA,EAAI,iBAAiB,aAAa,CAAU,GAC5C,EAAI,iBAAiB,cAAc,CAAW,GAC9C,EAAI,iBAAiB,SAAS,CAAW,GAEzC,UAA2B;GAGzB,AAFA,EAAI,oBAAoB,aAAa,CAAU,GAC/C,EAAI,oBAAoB,cAAc,CAAW,GACjD,EAAI,oBAAoB,SAAS,CAAW;EAC9C;CACF;CAEA,IAAM,IAAK,IAAI,gBAAgB,GAEzB,IAAI,QAAY;EACpB,QACQ;GACJ,EAAU;EACZ,GACA,EAAE,WAAW,YAAY,CAC3B;CACF,CAAC,GAEG,IAAa;CAEjB,OAAO;EACL,IAAI,iBAA8B;GAChC,OAAO,EAAG;EACZ;EAEA,UAAU;GACJ,MAEJ,IAAa,IACb,EAAG,MAAM,GACT,IAAqB,GACrB,EAAE,QAAQ,GACV,EAAK,QAAQ;EACf;EAEA,IAAI,WAAoB;GACtB,OAAO;EACT;EAEA,IAAI;EAEJ,CAAC,OAAO,WAAW;GACjB,KAAK,QAAQ;EACf;CACF;AACF"}
@@ -0,0 +1,2 @@
1
+ const e=require("../_dev.cjs"),t=require("../scales/linear.cjs"),n=require("../scales/time.cjs");function r(r,i){if(r.length===0)return t.linearScale({domain:[0,1],range:[0,i]});if(r.some(e=>e==null))return e.warn(`buildXScale: one or more x values are null or undefined — data must use the Datum shape { key, value }. Did you pass { x, y } instead?`),t.linearScale({domain:[0,1],range:[0,i]});if(r.some(e=>typeof e==`number`&&!Number.isFinite(e)))return e.warn(`buildXScale: one or more x values are NaN or Infinity — check upstream data for invalid arithmetic.`),t.linearScale({domain:[0,1],range:[0,i]});if(r[0]instanceof Date){let e=r,t=Math.min(...e.map(Number)),a=Math.max(...e.map(Number));return n.timeScale({domain:[new Date(t),new Date(t===a?a+1:a)],range:[0,i]})}let a=r,o=Math.min(...a),s=Math.max(...a);return t.linearScale({domain:[o,o===s?s+1:s],nice:!1,range:[0,i]})}function i(n,r,i=!0){if(n.length===0)return t.linearScale({domain:[0,1],range:[r,0]});if(n.some(e=>e==null))return e.warn(`buildYScale: one or more y values are null or undefined — data must use the Datum shape { key, value }. Did you pass { x, y } instead?`),t.linearScale({domain:[0,1],range:[r,0]});if(n.some(e=>!Number.isFinite(e)))return e.warn(`buildYScale: one or more y values are NaN or Infinity — check upstream data for invalid arithmetic.`),t.linearScale({domain:[0,1],range:[r,0]});let a=Math.min(...n),o=i?Math.min(0,a):a,s=Math.max(...n);return t.linearScale({domain:[o,o===s?s+1:s],range:[r,0]})}exports.buildXScale=r,exports.buildYScale=i;
2
+ //# sourceMappingURL=cartesian-scales.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cartesian-scales.cjs","names":[],"sources":["../../src/core/cartesian-scales.ts"],"sourcesContent":["import type { Scale } from '../types';\n\nimport { warn } from '../_dev';\nimport { linearScale } from '../scales/linear';\nimport { timeScale } from '../scales/time';\n\nexport function buildXScale(allX: (Date | number)[], width: number): Scale<Date> | Scale<number> {\n if (allX.length === 0) return linearScale({ domain: [0, 1], range: [0, width] });\n\n if (allX.some((v) => v == null)) {\n warn(\n 'buildXScale: one or more x values are null or undefined — data must use the Datum shape { key, value }. Did you pass { x, y } instead?',\n );\n\n return linearScale({ domain: [0, 1], range: [0, width] });\n }\n\n if (allX.some((v) => typeof v === 'number' && !Number.isFinite(v))) {\n warn('buildXScale: one or more x values are NaN or Infinity — check upstream data for invalid arithmetic.');\n\n return linearScale({ domain: [0, 1], range: [0, width] });\n }\n\n if (allX[0] instanceof Date) {\n const dates = allX as Date[];\n const minMs = Math.min(...dates.map(Number));\n const maxMs = Math.max(...dates.map(Number));\n const min = new Date(minMs);\n const max = new Date(minMs === maxMs ? maxMs + 1 : maxMs);\n\n return timeScale({ domain: [min, max], range: [0, width] });\n }\n\n const nums = allX as number[];\n const minN = Math.min(...nums);\n const maxN = Math.max(...nums);\n\n return linearScale({ domain: [minN, minN === maxN ? maxN + 1 : maxN], nice: false, range: [0, width] });\n}\n\nexport function buildYScale(allY: number[], height: number, includeZero = true): Scale<number> {\n if (allY.length === 0) return linearScale({ domain: [0, 1], range: [height, 0] });\n\n if (allY.some((v) => v == null)) {\n warn(\n 'buildYScale: one or more y values are null or undefined — data must use the Datum shape { key, value }. Did you pass { x, y } instead?',\n );\n\n return linearScale({ domain: [0, 1], range: [height, 0] });\n }\n\n if (allY.some((v) => !Number.isFinite(v))) {\n warn('buildYScale: one or more y values are NaN or Infinity — check upstream data for invalid arithmetic.');\n\n return linearScale({ domain: [0, 1], range: [height, 0] });\n }\n\n const rawMin = Math.min(...allY);\n const minY = includeZero ? Math.min(0, rawMin) : rawMin;\n const maxY = Math.max(...allY);\n\n return linearScale({ domain: [minY, minY === maxY ? maxY + 1 : maxY], range: [height, 0] });\n}\n"],"mappings":"iGAMA,SAAgB,EAAY,EAAyB,EAA4C,CAC/F,GAAI,EAAK,SAAW,EAAG,OAAO,EAAA,YAAY,CAAE,OAAQ,CAAC,EAAG,CAAC,EAAG,MAAO,CAAC,EAAG,CAAK,CAAE,CAAC,EAE/E,GAAI,EAAK,KAAM,GAAM,GAAK,IAAI,EAK5B,OAJA,EAAA,KACE,wIACF,EAEO,EAAA,YAAY,CAAE,OAAQ,CAAC,EAAG,CAAC,EAAG,MAAO,CAAC,EAAG,CAAK,CAAE,CAAC,EAG1D,GAAI,EAAK,KAAM,GAAM,OAAO,GAAM,UAAY,CAAC,OAAO,SAAS,CAAC,CAAC,EAG/D,OAFA,EAAA,KAAK,qGAAqG,EAEnG,EAAA,YAAY,CAAE,OAAQ,CAAC,EAAG,CAAC,EAAG,MAAO,CAAC,EAAG,CAAK,CAAE,CAAC,EAG1D,GAAI,EAAK,aAAc,KAAM,CAC3B,IAAM,EAAQ,EACR,EAAQ,KAAK,IAAI,GAAG,EAAM,IAAI,MAAM,CAAC,EACrC,EAAQ,KAAK,IAAI,GAAG,EAAM,IAAI,MAAM,CAAC,EAI3C,OAAO,EAAA,UAAU,CAAE,OAAQ,CAAC,IAHZ,KAAK,CAGO,EAAK,IAFjB,KAAK,IAAU,EAAQ,EAAQ,EAAI,CAElB,CAAG,EAAG,MAAO,CAAC,EAAG,CAAK,CAAE,CAAC,CAC5D,CAEA,IAAM,EAAO,EACP,EAAO,KAAK,IAAI,GAAG,CAAI,EACvB,EAAO,KAAK,IAAI,GAAG,CAAI,EAE7B,OAAO,EAAA,YAAY,CAAE,OAAQ,CAAC,EAAM,IAAS,EAAO,EAAO,EAAI,CAAI,EAAG,KAAM,GAAO,MAAO,CAAC,EAAG,CAAK,CAAE,CAAC,CACxG,CAEA,SAAgB,EAAY,EAAgB,EAAgB,EAAc,GAAqB,CAC7F,GAAI,EAAK,SAAW,EAAG,OAAO,EAAA,YAAY,CAAE,OAAQ,CAAC,EAAG,CAAC,EAAG,MAAO,CAAC,EAAQ,CAAC,CAAE,CAAC,EAEhF,GAAI,EAAK,KAAM,GAAM,GAAK,IAAI,EAK5B,OAJA,EAAA,KACE,wIACF,EAEO,EAAA,YAAY,CAAE,OAAQ,CAAC,EAAG,CAAC,EAAG,MAAO,CAAC,EAAQ,CAAC,CAAE,CAAC,EAG3D,GAAI,EAAK,KAAM,GAAM,CAAC,OAAO,SAAS,CAAC,CAAC,EAGtC,OAFA,EAAA,KAAK,qGAAqG,EAEnG,EAAA,YAAY,CAAE,OAAQ,CAAC,EAAG,CAAC,EAAG,MAAO,CAAC,EAAQ,CAAC,CAAE,CAAC,EAG3D,IAAM,EAAS,KAAK,IAAI,GAAG,CAAI,EACzB,EAAO,EAAc,KAAK,IAAI,EAAG,CAAM,EAAI,EAC3C,EAAO,KAAK,IAAI,GAAG,CAAI,EAE7B,OAAO,EAAA,YAAY,CAAE,OAAQ,CAAC,EAAM,IAAS,EAAO,EAAO,EAAI,CAAI,EAAG,MAAO,CAAC,EAAQ,CAAC,CAAE,CAAC,CAC5F"}
@@ -0,0 +1,4 @@
1
+ import type { Scale } from '../types';
2
+ export declare function buildXScale(allX: (Date | number)[], width: number): Scale<Date> | Scale<number>;
3
+ export declare function buildYScale(allY: number[], height: number, includeZero?: boolean): Scale<number>;
4
+ //# sourceMappingURL=cartesian-scales.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cartesian-scales.d.ts","sourceRoot":"","sources":["../../src/core/cartesian-scales.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAMtC,wBAAgB,WAAW,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAgC/F;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,UAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAsB7F"}
@@ -0,0 +1,54 @@
1
+ import { warn as e } from "../_dev.js";
2
+ import { linearScale as t } from "../scales/linear.js";
3
+ import { timeScale as n } from "../scales/time.js";
4
+ //#region src/core/cartesian-scales.ts
5
+ function r(r, i) {
6
+ if (r.length === 0) return t({
7
+ domain: [0, 1],
8
+ range: [0, i]
9
+ });
10
+ if (r.some((e) => e == null)) return e("buildXScale: one or more x values are null or undefined — data must use the Datum shape { key, value }. Did you pass { x, y } instead?"), t({
11
+ domain: [0, 1],
12
+ range: [0, i]
13
+ });
14
+ if (r.some((e) => typeof e == "number" && !Number.isFinite(e))) return e("buildXScale: one or more x values are NaN or Infinity — check upstream data for invalid arithmetic."), t({
15
+ domain: [0, 1],
16
+ range: [0, i]
17
+ });
18
+ if (r[0] instanceof Date) {
19
+ let e = r, t = Math.min(...e.map(Number)), a = Math.max(...e.map(Number));
20
+ return n({
21
+ domain: [new Date(t), new Date(t === a ? a + 1 : a)],
22
+ range: [0, i]
23
+ });
24
+ }
25
+ let a = r, o = Math.min(...a), s = Math.max(...a);
26
+ return t({
27
+ domain: [o, o === s ? s + 1 : s],
28
+ nice: !1,
29
+ range: [0, i]
30
+ });
31
+ }
32
+ function i(n, r, i = !0) {
33
+ if (n.length === 0) return t({
34
+ domain: [0, 1],
35
+ range: [r, 0]
36
+ });
37
+ if (n.some((e) => e == null)) return e("buildYScale: one or more y values are null or undefined — data must use the Datum shape { key, value }. Did you pass { x, y } instead?"), t({
38
+ domain: [0, 1],
39
+ range: [r, 0]
40
+ });
41
+ if (n.some((e) => !Number.isFinite(e))) return e("buildYScale: one or more y values are NaN or Infinity — check upstream data for invalid arithmetic."), t({
42
+ domain: [0, 1],
43
+ range: [r, 0]
44
+ });
45
+ let a = Math.min(...n), o = i ? Math.min(0, a) : a, s = Math.max(...n);
46
+ return t({
47
+ domain: [o, o === s ? s + 1 : s],
48
+ range: [r, 0]
49
+ });
50
+ }
51
+ //#endregion
52
+ export { r as buildXScale, i as buildYScale };
53
+
54
+ //# sourceMappingURL=cartesian-scales.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cartesian-scales.js","names":[],"sources":["../../src/core/cartesian-scales.ts"],"sourcesContent":["import type { Scale } from '../types';\n\nimport { warn } from '../_dev';\nimport { linearScale } from '../scales/linear';\nimport { timeScale } from '../scales/time';\n\nexport function buildXScale(allX: (Date | number)[], width: number): Scale<Date> | Scale<number> {\n if (allX.length === 0) return linearScale({ domain: [0, 1], range: [0, width] });\n\n if (allX.some((v) => v == null)) {\n warn(\n 'buildXScale: one or more x values are null or undefined — data must use the Datum shape { key, value }. Did you pass { x, y } instead?',\n );\n\n return linearScale({ domain: [0, 1], range: [0, width] });\n }\n\n if (allX.some((v) => typeof v === 'number' && !Number.isFinite(v))) {\n warn('buildXScale: one or more x values are NaN or Infinity — check upstream data for invalid arithmetic.');\n\n return linearScale({ domain: [0, 1], range: [0, width] });\n }\n\n if (allX[0] instanceof Date) {\n const dates = allX as Date[];\n const minMs = Math.min(...dates.map(Number));\n const maxMs = Math.max(...dates.map(Number));\n const min = new Date(minMs);\n const max = new Date(minMs === maxMs ? maxMs + 1 : maxMs);\n\n return timeScale({ domain: [min, max], range: [0, width] });\n }\n\n const nums = allX as number[];\n const minN = Math.min(...nums);\n const maxN = Math.max(...nums);\n\n return linearScale({ domain: [minN, minN === maxN ? maxN + 1 : maxN], nice: false, range: [0, width] });\n}\n\nexport function buildYScale(allY: number[], height: number, includeZero = true): Scale<number> {\n if (allY.length === 0) return linearScale({ domain: [0, 1], range: [height, 0] });\n\n if (allY.some((v) => v == null)) {\n warn(\n 'buildYScale: one or more y values are null or undefined — data must use the Datum shape { key, value }. Did you pass { x, y } instead?',\n );\n\n return linearScale({ domain: [0, 1], range: [height, 0] });\n }\n\n if (allY.some((v) => !Number.isFinite(v))) {\n warn('buildYScale: one or more y values are NaN or Infinity — check upstream data for invalid arithmetic.');\n\n return linearScale({ domain: [0, 1], range: [height, 0] });\n }\n\n const rawMin = Math.min(...allY);\n const minY = includeZero ? Math.min(0, rawMin) : rawMin;\n const maxY = Math.max(...allY);\n\n return linearScale({ domain: [minY, minY === maxY ? maxY + 1 : maxY], range: [height, 0] });\n}\n"],"mappings":";;;;AAMA,SAAgB,EAAY,GAAyB,GAA4C;CAC/F,IAAI,EAAK,WAAW,GAAG,OAAO,EAAY;EAAE,QAAQ,CAAC,GAAG,CAAC;EAAG,OAAO,CAAC,GAAG,CAAK;CAAE,CAAC;CAE/E,IAAI,EAAK,MAAM,MAAM,KAAK,IAAI,GAK5B,OAJA,EACE,wIACF,GAEO,EAAY;EAAE,QAAQ,CAAC,GAAG,CAAC;EAAG,OAAO,CAAC,GAAG,CAAK;CAAE,CAAC;CAG1D,IAAI,EAAK,MAAM,MAAM,OAAO,KAAM,YAAY,CAAC,OAAO,SAAS,CAAC,CAAC,GAG/D,OAFA,EAAK,qGAAqG,GAEnG,EAAY;EAAE,QAAQ,CAAC,GAAG,CAAC;EAAG,OAAO,CAAC,GAAG,CAAK;CAAE,CAAC;CAG1D,IAAI,EAAK,cAAc,MAAM;EAC3B,IAAM,IAAQ,GACR,IAAQ,KAAK,IAAI,GAAG,EAAM,IAAI,MAAM,CAAC,GACrC,IAAQ,KAAK,IAAI,GAAG,EAAM,IAAI,MAAM,CAAC;EAI3C,OAAO,EAAU;GAAE,QAAQ,CAAC,IAHZ,KAAK,CAGO,GAAK,IAFjB,KAAK,MAAU,IAAQ,IAAQ,IAAI,CAElB,CAAG;GAAG,OAAO,CAAC,GAAG,CAAK;EAAE,CAAC;CAC5D;CAEA,IAAM,IAAO,GACP,IAAO,KAAK,IAAI,GAAG,CAAI,GACvB,IAAO,KAAK,IAAI,GAAG,CAAI;CAE7B,OAAO,EAAY;EAAE,QAAQ,CAAC,GAAM,MAAS,IAAO,IAAO,IAAI,CAAI;EAAG,MAAM;EAAO,OAAO,CAAC,GAAG,CAAK;CAAE,CAAC;AACxG;AAEA,SAAgB,EAAY,GAAgB,GAAgB,IAAc,IAAqB;CAC7F,IAAI,EAAK,WAAW,GAAG,OAAO,EAAY;EAAE,QAAQ,CAAC,GAAG,CAAC;EAAG,OAAO,CAAC,GAAQ,CAAC;CAAE,CAAC;CAEhF,IAAI,EAAK,MAAM,MAAM,KAAK,IAAI,GAK5B,OAJA,EACE,wIACF,GAEO,EAAY;EAAE,QAAQ,CAAC,GAAG,CAAC;EAAG,OAAO,CAAC,GAAQ,CAAC;CAAE,CAAC;CAG3D,IAAI,EAAK,MAAM,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC,GAGtC,OAFA,EAAK,qGAAqG,GAEnG,EAAY;EAAE,QAAQ,CAAC,GAAG,CAAC;EAAG,OAAO,CAAC,GAAQ,CAAC;CAAE,CAAC;CAG3D,IAAM,IAAS,KAAK,IAAI,GAAG,CAAI,GACzB,IAAO,IAAc,KAAK,IAAI,GAAG,CAAM,IAAI,GAC3C,IAAO,KAAK,IAAI,GAAG,CAAI;CAE7B,OAAO,EAAY;EAAE,QAAQ,CAAC,GAAM,MAAS,IAAO,IAAO,IAAI,CAAI;EAAG,OAAO,CAAC,GAAQ,CAAC;CAAE,CAAC;AAC5F"}
@@ -0,0 +1,2 @@
1
+ const e=require("../errors.cjs"),t=require("../_dev.cjs"),n=require("../svg/element.cjs"),r=require("./layout.cjs"),i=require("./responsive.cjs");let a=require("@vielzeug/ripple");function o(o,s){if(!(typeof o==`object`&&o&&o.nodeType===1&&typeof o.appendChild==`function`&&typeof o.getBoundingClientRect==`function`)){let t=o;throw new e.PrismRenderError(`Invalid chart configuration: \`container\` must be a DOM Element, received ${t===null?`null`:typeof t==`object`?t.constructor?.name??`object`:typeof t}.`)}let c=r.resolveMargin(s.margin),l=n.createSvgElement(`svg`,{...s.ariaHidden?{"aria-hidden":`true`}:{...s.ariaLabel?{"aria-label":s.ariaLabel}:{},role:`img`},class:`prism-chart`,style:`display:block;width:100%;height:100%`}),u=n.createSvgElement(`g`,{class:`prism-chart-area`,transform:`translate(${c.left},${c.top})`});l.appendChild(u);let d=o.getBoundingClientRect();(d.width===0||d.height===0)&&t.warn(`Chart container has zero dimensions. Ensure the container has a defined width and height before mounting a chart.`);let f=typeof getComputedStyle<`u`?getComputedStyle(o):null;f&&f.position===`static`&&t.warn(`Chart container has position:static. Set position:relative (or absolute/fixed) on the container so tooltip and overlay elements are positioned correctly.`);let p=(0,a.signal)({height:d.height||300,margin:c,width:d.width||600}),m=i.observeResize(o,(e,t)=>{p.value={height:t,margin:c,width:e},n.setAttributes(l,{height:t,viewBox:`0 0 ${e} ${t}`,width:e})}),h=d.width||600,g=d.height||300;return n.setAttributes(l,{height:g,viewBox:`0 0 ${h} ${g}`,width:h}),o.appendChild(l),{chartArea:u,dimensions:p,dispose(){m(),p.dispose(),l.remove()},svg:l}}exports.createChartBase=o;
2
+ //# sourceMappingURL=chart-base.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart-base.cjs","names":[],"sources":["../../src/core/chart-base.ts"],"sourcesContent":["import type { Readable } from '@vielzeug/ripple';\n\nimport { signal } from '@vielzeug/ripple';\n\nimport type { ChartDimensions, ChartMargin } from '../types';\n\nimport { warn } from '../_dev';\nimport { PrismRenderError } from '../errors';\nimport { createSvgElement, setAttributes } from '../svg/element';\nimport { resolveMargin } from './layout';\nimport { observeResize } from './responsive';\n\nexport interface ChartBase {\n chartArea: SVGGElement;\n dimensions: Readable<ChartDimensions>;\n svg: SVGSVGElement;\n dispose(): void;\n}\n\nexport function createChartBase(\n container: HTMLElement,\n options: { ariaHidden?: boolean; ariaLabel?: string; margin?: Partial<ChartMargin> },\n): ChartBase {\n // Duck-typed rather than `instanceof Element` — an `instanceof` check would reject a\n // structurally valid Element from a different realm (e.g. an Element created via\n // `iframe.contentDocument.createElement(...)`, whose prototype chain terminates in that\n // iframe's own `Element` constructor), which is a legitimate usage pattern this package\n // doesn't otherwise restrict.\n const isElementLike =\n typeof container === 'object' &&\n container !== null &&\n container.nodeType === 1 &&\n typeof container.appendChild === 'function' &&\n typeof container.getBoundingClientRect === 'function';\n\n if (!isElementLike) {\n const received: unknown = container;\n const kind =\n received === null\n ? 'null'\n : typeof received === 'object'\n ? (received.constructor?.name ?? 'object')\n : typeof received;\n\n throw new PrismRenderError(`Invalid chart configuration: \\`container\\` must be a DOM Element, received ${kind}.`);\n }\n\n const margin = resolveMargin(options.margin);\n const svg = createSvgElement('svg', {\n ...(options.ariaHidden\n ? { 'aria-hidden': 'true' }\n : { ...(options.ariaLabel ? { 'aria-label': options.ariaLabel } : {}), role: 'img' }),\n class: 'prism-chart',\n style: 'display:block;width:100%;height:100%',\n });\n\n const chartAreaGroup = createSvgElement('g', {\n class: 'prism-chart-area',\n transform: `translate(${margin.left},${margin.top})`,\n });\n\n svg.appendChild(chartAreaGroup);\n\n const rect = container.getBoundingClientRect();\n\n if (rect.width === 0 || rect.height === 0) {\n warn(\n 'Chart container has zero dimensions. Ensure the container has a defined width and height before mounting a chart.',\n );\n }\n\n const computedStyle = typeof getComputedStyle !== 'undefined' ? getComputedStyle(container) : null;\n\n if (computedStyle && computedStyle.position === 'static') {\n warn(\n 'Chart container has position:static. Set position:relative (or absolute/fixed) on the container so tooltip and overlay elements are positioned correctly.',\n );\n }\n\n const dimensions = signal<ChartDimensions>({\n height: rect.height || 300,\n margin,\n width: rect.width || 600,\n });\n\n const stopObserving = observeResize(container, (width, height) => {\n dimensions.value = { height, margin, width };\n setAttributes(svg, { height, viewBox: `0 0 ${width} ${height}`, width });\n });\n\n const initialWidth = rect.width || 600;\n const initialHeight = rect.height || 300;\n\n setAttributes(svg, {\n height: initialHeight,\n viewBox: `0 0 ${initialWidth} ${initialHeight}`,\n width: initialWidth,\n });\n\n container.appendChild(svg);\n\n return {\n chartArea: chartAreaGroup,\n dimensions,\n dispose() {\n stopObserving();\n dimensions.dispose();\n svg.remove();\n },\n svg,\n };\n}\n"],"mappings":"oLAmBA,SAAgB,EACd,EACA,EACW,CAaX,GAAI,EANF,OAAO,GAAc,UACrB,GACA,EAAU,WAAa,GACvB,OAAO,EAAU,aAAgB,YACjC,OAAO,EAAU,uBAA0B,YAEzB,CAClB,IAAM,EAAoB,EAQ1B,MAAM,IAAI,EAAA,iBAAiB,8EANzB,IAAa,KACT,OACA,OAAO,GAAa,SACjB,EAAS,aAAa,MAAQ,SAC/B,OAAO,EAE+F,EAAE,CAClH,CAEA,IAAM,EAAS,EAAA,cAAc,EAAQ,MAAM,EACrC,EAAM,EAAA,iBAAiB,MAAO,CAClC,GAAI,EAAQ,WACR,CAAE,cAAe,MAAO,EACxB,CAAE,GAAI,EAAQ,UAAY,CAAE,aAAc,EAAQ,SAAU,EAAI,CAAC,EAAI,KAAM,KAAM,EACrF,MAAO,cACP,MAAO,sCACT,CAAC,EAEK,EAAiB,EAAA,iBAAiB,IAAK,CAC3C,MAAO,mBACP,UAAW,aAAa,EAAO,KAAK,GAAG,EAAO,IAAI,EACpD,CAAC,EAED,EAAI,YAAY,CAAc,EAE9B,IAAM,EAAO,EAAU,sBAAsB,GAEzC,EAAK,QAAU,GAAK,EAAK,SAAW,IACtC,EAAA,KACE,mHACF,EAGF,IAAM,EAAgB,OAAO,iBAAqB,IAAc,iBAAiB,CAAS,EAAI,KAE1F,GAAiB,EAAc,WAAa,UAC9C,EAAA,KACE,2JACF,EAGF,IAAM,GAAA,EAAA,EAAA,OAAA,CAAqC,CACzC,OAAQ,EAAK,QAAU,IACvB,SACA,MAAO,EAAK,OAAS,GACvB,CAAC,EAEK,EAAgB,EAAA,cAAc,GAAY,EAAO,IAAW,CAChE,EAAW,MAAQ,CAAE,SAAQ,SAAQ,OAAM,EAC3C,EAAA,cAAc,EAAK,CAAE,SAAQ,QAAS,OAAO,EAAM,GAAG,IAAU,OAAM,CAAC,CACzE,CAAC,EAEK,EAAe,EAAK,OAAS,IAC7B,EAAgB,EAAK,QAAU,IAUrC,OARA,EAAA,cAAc,EAAK,CACjB,OAAQ,EACR,QAAS,OAAO,EAAa,GAAG,IAChC,MAAO,CACT,CAAC,EAED,EAAU,YAAY,CAAG,EAElB,CACL,UAAW,EACX,aACA,SAAU,CACR,EAAc,EACd,EAAW,QAAQ,EACnB,EAAI,OAAO,CACb,EACA,KACF,CACF"}
@@ -0,0 +1,14 @@
1
+ import type { Readable } from '@vielzeug/ripple';
2
+ import type { ChartDimensions, ChartMargin } from '../types';
3
+ export interface ChartBase {
4
+ chartArea: SVGGElement;
5
+ dimensions: Readable<ChartDimensions>;
6
+ svg: SVGSVGElement;
7
+ dispose(): void;
8
+ }
9
+ export declare function createChartBase(container: HTMLElement, options: {
10
+ ariaHidden?: boolean;
11
+ ariaLabel?: string;
12
+ margin?: Partial<ChartMargin>;
13
+ }): ChartBase;
14
+ //# sourceMappingURL=chart-base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart-base.d.ts","sourceRoot":"","sources":["../../src/core/chart-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIjD,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAQ7D,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,WAAW,CAAC;IACvB,UAAU,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IACtC,GAAG,EAAE,aAAa,CAAC;IACnB,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;CAAE,GACnF,SAAS,CAyFX"}
@@ -0,0 +1,60 @@
1
+ import { PrismRenderError as e } from "../errors.js";
2
+ import { warn as t } from "../_dev.js";
3
+ import { createSvgElement as n, setAttributes as r } from "../svg/element.js";
4
+ import { resolveMargin as i } from "./layout.js";
5
+ import { observeResize as a } from "./responsive.js";
6
+ import { signal as o } from "@vielzeug/ripple";
7
+ //#region src/core/chart-base.ts
8
+ function s(s, c) {
9
+ if (!(typeof s == "object" && s && s.nodeType === 1 && typeof s.appendChild == "function" && typeof s.getBoundingClientRect == "function")) {
10
+ let t = s;
11
+ throw new e(`Invalid chart configuration: \`container\` must be a DOM Element, received ${t === null ? "null" : typeof t == "object" ? t.constructor?.name ?? "object" : typeof t}.`);
12
+ }
13
+ let l = i(c.margin), u = n("svg", {
14
+ ...c.ariaHidden ? { "aria-hidden": "true" } : {
15
+ ...c.ariaLabel ? { "aria-label": c.ariaLabel } : {},
16
+ role: "img"
17
+ },
18
+ class: "prism-chart",
19
+ style: "display:block;width:100%;height:100%"
20
+ }), d = n("g", {
21
+ class: "prism-chart-area",
22
+ transform: `translate(${l.left},${l.top})`
23
+ });
24
+ u.appendChild(d);
25
+ let f = s.getBoundingClientRect();
26
+ (f.width === 0 || f.height === 0) && t("Chart container has zero dimensions. Ensure the container has a defined width and height before mounting a chart.");
27
+ let p = typeof getComputedStyle < "u" ? getComputedStyle(s) : null;
28
+ p && p.position === "static" && t("Chart container has position:static. Set position:relative (or absolute/fixed) on the container so tooltip and overlay elements are positioned correctly.");
29
+ let m = o({
30
+ height: f.height || 300,
31
+ margin: l,
32
+ width: f.width || 600
33
+ }), h = a(s, (e, t) => {
34
+ m.value = {
35
+ height: t,
36
+ margin: l,
37
+ width: e
38
+ }, r(u, {
39
+ height: t,
40
+ viewBox: `0 0 ${e} ${t}`,
41
+ width: e
42
+ });
43
+ }), g = f.width || 600, _ = f.height || 300;
44
+ return r(u, {
45
+ height: _,
46
+ viewBox: `0 0 ${g} ${_}`,
47
+ width: g
48
+ }), s.appendChild(u), {
49
+ chartArea: d,
50
+ dimensions: m,
51
+ dispose() {
52
+ h(), m.dispose(), u.remove();
53
+ },
54
+ svg: u
55
+ };
56
+ }
57
+ //#endregion
58
+ export { s as createChartBase };
59
+
60
+ //# sourceMappingURL=chart-base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart-base.js","names":[],"sources":["../../src/core/chart-base.ts"],"sourcesContent":["import type { Readable } from '@vielzeug/ripple';\n\nimport { signal } from '@vielzeug/ripple';\n\nimport type { ChartDimensions, ChartMargin } from '../types';\n\nimport { warn } from '../_dev';\nimport { PrismRenderError } from '../errors';\nimport { createSvgElement, setAttributes } from '../svg/element';\nimport { resolveMargin } from './layout';\nimport { observeResize } from './responsive';\n\nexport interface ChartBase {\n chartArea: SVGGElement;\n dimensions: Readable<ChartDimensions>;\n svg: SVGSVGElement;\n dispose(): void;\n}\n\nexport function createChartBase(\n container: HTMLElement,\n options: { ariaHidden?: boolean; ariaLabel?: string; margin?: Partial<ChartMargin> },\n): ChartBase {\n // Duck-typed rather than `instanceof Element` — an `instanceof` check would reject a\n // structurally valid Element from a different realm (e.g. an Element created via\n // `iframe.contentDocument.createElement(...)`, whose prototype chain terminates in that\n // iframe's own `Element` constructor), which is a legitimate usage pattern this package\n // doesn't otherwise restrict.\n const isElementLike =\n typeof container === 'object' &&\n container !== null &&\n container.nodeType === 1 &&\n typeof container.appendChild === 'function' &&\n typeof container.getBoundingClientRect === 'function';\n\n if (!isElementLike) {\n const received: unknown = container;\n const kind =\n received === null\n ? 'null'\n : typeof received === 'object'\n ? (received.constructor?.name ?? 'object')\n : typeof received;\n\n throw new PrismRenderError(`Invalid chart configuration: \\`container\\` must be a DOM Element, received ${kind}.`);\n }\n\n const margin = resolveMargin(options.margin);\n const svg = createSvgElement('svg', {\n ...(options.ariaHidden\n ? { 'aria-hidden': 'true' }\n : { ...(options.ariaLabel ? { 'aria-label': options.ariaLabel } : {}), role: 'img' }),\n class: 'prism-chart',\n style: 'display:block;width:100%;height:100%',\n });\n\n const chartAreaGroup = createSvgElement('g', {\n class: 'prism-chart-area',\n transform: `translate(${margin.left},${margin.top})`,\n });\n\n svg.appendChild(chartAreaGroup);\n\n const rect = container.getBoundingClientRect();\n\n if (rect.width === 0 || rect.height === 0) {\n warn(\n 'Chart container has zero dimensions. Ensure the container has a defined width and height before mounting a chart.',\n );\n }\n\n const computedStyle = typeof getComputedStyle !== 'undefined' ? getComputedStyle(container) : null;\n\n if (computedStyle && computedStyle.position === 'static') {\n warn(\n 'Chart container has position:static. Set position:relative (or absolute/fixed) on the container so tooltip and overlay elements are positioned correctly.',\n );\n }\n\n const dimensions = signal<ChartDimensions>({\n height: rect.height || 300,\n margin,\n width: rect.width || 600,\n });\n\n const stopObserving = observeResize(container, (width, height) => {\n dimensions.value = { height, margin, width };\n setAttributes(svg, { height, viewBox: `0 0 ${width} ${height}`, width });\n });\n\n const initialWidth = rect.width || 600;\n const initialHeight = rect.height || 300;\n\n setAttributes(svg, {\n height: initialHeight,\n viewBox: `0 0 ${initialWidth} ${initialHeight}`,\n width: initialWidth,\n });\n\n container.appendChild(svg);\n\n return {\n chartArea: chartAreaGroup,\n dimensions,\n dispose() {\n stopObserving();\n dimensions.dispose();\n svg.remove();\n },\n svg,\n };\n}\n"],"mappings":";;;;;;;AAmBA,SAAgB,EACd,GACA,GACW;CAaX,IAAI,EANF,OAAO,KAAc,YACrB,KACA,EAAU,aAAa,KACvB,OAAO,EAAU,eAAgB,cACjC,OAAO,EAAU,yBAA0B,aAEzB;EAClB,IAAM,IAAoB;EAQ1B,MAAM,IAAI,EAAiB,8EANzB,MAAa,OACT,SACA,OAAO,KAAa,WACjB,EAAS,aAAa,QAAQ,WAC/B,OAAO,EAE+F,EAAE;CAClH;CAEA,IAAM,IAAS,EAAc,EAAQ,MAAM,GACrC,IAAM,EAAiB,OAAO;EAClC,GAAI,EAAQ,aACR,EAAE,eAAe,OAAO,IACxB;GAAE,GAAI,EAAQ,YAAY,EAAE,cAAc,EAAQ,UAAU,IAAI,CAAC;GAAI,MAAM;EAAM;EACrF,OAAO;EACP,OAAO;CACT,CAAC,GAEK,IAAiB,EAAiB,KAAK;EAC3C,OAAO;EACP,WAAW,aAAa,EAAO,KAAK,GAAG,EAAO,IAAI;CACpD,CAAC;CAED,EAAI,YAAY,CAAc;CAE9B,IAAM,IAAO,EAAU,sBAAsB;CAE7C,CAAI,EAAK,UAAU,KAAK,EAAK,WAAW,MACtC,EACE,mHACF;CAGF,IAAM,IAAgB,OAAO,mBAAqB,MAAc,iBAAiB,CAAS,IAAI;CAE9F,AAAI,KAAiB,EAAc,aAAa,YAC9C,EACE,2JACF;CAGF,IAAM,IAAa,EAAwB;EACzC,QAAQ,EAAK,UAAU;EACvB;EACA,OAAO,EAAK,SAAS;CACvB,CAAC,GAEK,IAAgB,EAAc,IAAY,GAAO,MAAW;EAEhE,AADA,EAAW,QAAQ;GAAE;GAAQ;GAAQ;EAAM,GAC3C,EAAc,GAAK;GAAE;GAAQ,SAAS,OAAO,EAAM,GAAG;GAAU;EAAM,CAAC;CACzE,CAAC,GAEK,IAAe,EAAK,SAAS,KAC7B,IAAgB,EAAK,UAAU;CAUrC,OARA,EAAc,GAAK;EACjB,QAAQ;EACR,SAAS,OAAO,EAAa,GAAG;EAChC,OAAO;CACT,CAAC,GAED,EAAU,YAAY,CAAG,GAElB;EACL,WAAW;EACX;EACA,UAAU;GAGR,AAFA,EAAc,GACd,EAAW,QAAQ,GACnB,EAAI,OAAO;EACb;EACA;CACF;AACF"}
@@ -0,0 +1,2 @@
1
+ const e=require("../_dev.cjs"),t=require("../svg/element.cjs"),n=require("../interaction/legend.cjs"),r=require("../interaction/tooltip.cjs"),i=require("./chart-base.cjs");let a=require("@vielzeug/ripple");function o(e,n,r,i){t.removeChildren(e.series),t.removeChildren(e.grid),t.removeChildren(e.xAxis),t.removeChildren(e.yAxis),n?.update([]),r?.hide(),i?.hide()}function s(t,o,s,l){let u=i.createChartBase(t,{ariaLabel:o.ariaLabel,margin:o.margin}),d=o.tooltip?r.createTooltip(t,o.tooltip):null,f=o.legend?n.createLegend(t,o.legend):null,p=new AbortController,m=s(u,d,f,p.signal),h=!1,g=c(u.svg),_=(0,a.scope)(()=>{(0,a.effect)(()=>{h||g.attach(l(m))},{scheduler:`microtask`})}),v=[];if(o.plugins){let n={container:t,dimensions:u.dimensions,disposalSignal:p.signal,svg:u.svg};for(let t of o.plugins)try{t.install(n),v.push(t)}catch(t){e.error(`A chart plugin threw during install() — skipping it; the rest of the chart still renders.`,t)}}return{get disposalSignal(){return p.signal},dispose(){if(!h){h=!0,p.abort(),g.detach();for(let t of v)try{t.dispose()}catch(t){e.error(`A chart plugin threw during dispose() — continuing to tear down the rest of the chart.`,t)}d?.dispose(),f?.dispose(),_.dispose(),u.dispose()}},get disposed(){return h},el:u.svg,[Symbol.dispose](){this.dispose()}}}function c(e){let t=null;return{attach(n){t&&=(t.onMouseMove&&e.removeEventListener(`mousemove`,t.onMouseMove),t.onMouseLeave&&e.removeEventListener(`mouseleave`,t.onMouseLeave),t.onClick&&e.removeEventListener(`click`,t.onClick),null),n&&(t=n,n.onMouseMove&&e.addEventListener(`mousemove`,n.onMouseMove),n.onMouseLeave&&e.addEventListener(`mouseleave`,n.onMouseLeave),n.onClick&&e.addEventListener(`click`,n.onClick))},detach(){this.attach(void 0)}}}function l(e,n,r){return s(e,n,(n,r,i,a)=>{let o={grid:t.createSvgElement(`g`,{"aria-hidden":`true`,class:`prism-grid`}),series:t.createSvgElement(`g`,{class:`prism-series`}),xAxis:t.createSvgElement(`g`,{class:`prism-x-axis`}),yAxis:t.createSvgElement(`g`,{class:`prism-y-axis`})};return n.chartArea.appendChild(o.grid),n.chartArea.appendChild(o.xAxis),n.chartArea.appendChild(o.yAxis),n.chartArea.appendChild(o.series),{chartArea:n.chartArea,container:e,dimensions:n.dimensions,disposalSignal:a,groups:o,legend:i,svg:n.svg,tooltip:r}},r)}function u(e,t,n){return s(e,t,(t,n,r,i)=>({container:e,dimensions:t.dimensions,disposalSignal:i,legend:r,svg:t.svg,tooltip:n}),n)}exports.clearCartesianDom=o,exports.createChartScaffold=l,exports.createRadialScaffold=u;
2
+ //# sourceMappingURL=chart-scaffold.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart-scaffold.cjs","names":[],"sources":["../../src/core/chart-scaffold.ts"],"sourcesContent":["import type { Readable } from '@vielzeug/ripple';\n\nimport { effect, scope } from '@vielzeug/ripple';\n\nimport type { CrosshairState } from '../interaction/crosshair';\nimport type { LegendState } from '../interaction/legend';\nimport type { TooltipState } from '../interaction/tooltip';\nimport type { BaseChartConfig, ChartDimensions, ChartHandle, ChartPlugin, ChartPluginContext } from '../types';\n\nimport { error } from '../_dev';\nimport { createLegend } from '../interaction/legend';\nimport { createTooltip } from '../interaction/tooltip';\nimport { createSvgElement, removeChildren } from '../svg/element';\nimport { createChartBase } from './chart-base';\n\nexport interface ScaffoldGroups {\n grid: SVGGElement;\n series: SVGGElement;\n xAxis: SVGGElement;\n yAxis: SVGGElement;\n}\n\n/**\n * Clears a cartesian chart's series/grid/axis groups and hides its legend/tooltip/crosshair —\n * shared by every cartesian chart factory's \"no data\" early-return so a reactive series\n * transitioning to empty leaves a fully blank chart, not a half-cleared one.\n */\nexport function clearCartesianDom(\n groups: ScaffoldGroups,\n legend: LegendState | null,\n tooltip: TooltipState | null,\n crosshair?: CrosshairState | null,\n): void {\n removeChildren(groups.series);\n removeChildren(groups.grid);\n removeChildren(groups.xAxis);\n removeChildren(groups.yAxis);\n legend?.update([]);\n tooltip?.hide();\n crosshair?.hide();\n}\n\nexport interface ScaffoldContext {\n chartArea: SVGGElement;\n container: HTMLElement;\n dimensions: Readable<ChartDimensions>;\n /** Aborted when the chart is disposed — renderers use this to stop rescheduling in-flight `requestAnimationFrame` transitions. */\n disposalSignal: AbortSignal;\n groups: ScaffoldGroups;\n legend: LegendState | null;\n svg: SVGSVGElement;\n tooltip: TooltipState | null;\n}\n\nexport interface RadialScaffoldContext {\n container: HTMLElement;\n dimensions: Readable<ChartDimensions>;\n /** Aborted when the chart is disposed — renderers use this to stop rescheduling in-flight `requestAnimationFrame` transitions. */\n disposalSignal: AbortSignal;\n legend: LegendState | null;\n svg: SVGSVGElement;\n tooltip: TooltipState | null;\n}\n\nexport interface ChartEventHandlers {\n onClick?: (event: MouseEvent) => void;\n onMouseLeave?: (event: MouseEvent) => void;\n onMouseMove?: (event: MouseEvent) => void;\n}\n\nfunction runScaffold<TCtx>(\n container: HTMLElement,\n config: BaseChartConfig,\n buildCtx: (\n base: {\n chartArea: SVGGElement;\n dimensions: Readable<ChartDimensions>;\n svg: SVGSVGElement;\n },\n tooltip: TooltipState | null,\n legend: LegendState | null,\n disposalSignal: AbortSignal,\n ) => TCtx,\n renderFn: (ctx: TCtx) => ChartEventHandlers | void,\n): ChartHandle {\n const base = createChartBase(container, { ariaLabel: config.ariaLabel, margin: config.margin });\n const tooltip = config.tooltip ? createTooltip(container, config.tooltip) : null;\n const legend = config.legend ? createLegend(container, config.legend) : null;\n const ac = new AbortController();\n const ctx = buildCtx(base, tooltip, legend, ac.signal);\n\n let disposed = false;\n const events = makeEventManager(base.svg);\n\n const s = scope(() => {\n effect(\n () => {\n if (disposed) return;\n\n events.attach(renderFn(ctx));\n },\n { scheduler: 'microtask' },\n );\n });\n\n const installedPlugins: ChartPlugin[] = [];\n\n if (config.plugins) {\n const pluginCtx: ChartPluginContext = {\n container,\n dimensions: base.dimensions,\n disposalSignal: ac.signal,\n svg: base.svg,\n };\n\n for (const plugin of config.plugins) {\n try {\n plugin.install(pluginCtx);\n installedPlugins.push(plugin);\n } catch (err) {\n error('A chart plugin threw during install() — skipping it; the rest of the chart still renders.', err);\n }\n }\n }\n\n return {\n get disposalSignal(): AbortSignal {\n return ac.signal;\n },\n\n dispose() {\n if (disposed) return;\n\n disposed = true;\n ac.abort();\n events.detach();\n\n for (const p of installedPlugins) {\n try {\n p.dispose();\n } catch (err) {\n error('A chart plugin threw during dispose() — continuing to tear down the rest of the chart.', err);\n }\n }\n\n tooltip?.dispose();\n legend?.dispose();\n s.dispose();\n base.dispose();\n },\n\n get disposed(): boolean {\n return disposed;\n },\n\n el: base.svg,\n\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n}\n\nfunction makeEventManager(svg: SVGSVGElement): {\n attach(handlers: ChartEventHandlers | void): void;\n detach(): void;\n} {\n let active: ChartEventHandlers | null = null;\n\n return {\n attach(handlers) {\n if (active) {\n if (active.onMouseMove) svg.removeEventListener('mousemove', active.onMouseMove);\n\n if (active.onMouseLeave) svg.removeEventListener('mouseleave', active.onMouseLeave);\n\n if (active.onClick) svg.removeEventListener('click', active.onClick);\n\n active = null;\n }\n\n if (!handlers) return;\n\n active = handlers;\n\n if (handlers.onMouseMove) svg.addEventListener('mousemove', handlers.onMouseMove);\n\n if (handlers.onMouseLeave) svg.addEventListener('mouseleave', handlers.onMouseLeave);\n\n if (handlers.onClick) svg.addEventListener('click', handlers.onClick);\n },\n detach() {\n this.attach(undefined);\n },\n };\n}\n\n/**\n * Cartesian scaffold: provides grid/axis/series SVG groups and a reactive\n * render loop. `renderFn` is called inside a reactive effect; it returns\n * optional `ChartEventHandlers` that are attached/replaced on every render.\n */\nexport function createChartScaffold(\n container: HTMLElement,\n config: BaseChartConfig,\n renderFn: (ctx: ScaffoldContext) => ChartEventHandlers | void,\n): ChartHandle {\n return runScaffold(\n container,\n config,\n (base, tooltip, legend, disposalSignal) => {\n const groups: ScaffoldGroups = {\n // Grid lines are purely decorative relative to the root svg's own role=\"img\"/aria-label.\n // Axis groups are NOT hidden wholesale — they can contain a meaningful `.prism-axis-title`;\n // `renderAxis` marks its own decorative tick lines/labels individually instead.\n grid: createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-grid' }),\n series: createSvgElement('g', { class: 'prism-series' }),\n xAxis: createSvgElement('g', { class: 'prism-x-axis' }),\n yAxis: createSvgElement('g', { class: 'prism-y-axis' }),\n };\n\n base.chartArea.appendChild(groups.grid);\n base.chartArea.appendChild(groups.xAxis);\n base.chartArea.appendChild(groups.yAxis);\n base.chartArea.appendChild(groups.series);\n\n return {\n chartArea: base.chartArea,\n container,\n dimensions: base.dimensions,\n disposalSignal,\n groups,\n legend,\n svg: base.svg,\n tooltip,\n } satisfies ScaffoldContext;\n },\n renderFn,\n );\n}\n\n/**\n * Radial scaffold: for charts that do not use cartesian axis groups\n * (pie, donut, semi). Provides only tooltip, legend, and the SVG root.\n */\nexport function createRadialScaffold(\n container: HTMLElement,\n config: BaseChartConfig,\n renderFn: (ctx: RadialScaffoldContext) => ChartEventHandlers | void,\n): ChartHandle {\n return runScaffold(\n container,\n config,\n (base, tooltip, legend, disposalSignal) =>\n ({\n container,\n dimensions: base.dimensions,\n disposalSignal,\n legend,\n svg: base.svg,\n tooltip,\n }) satisfies RadialScaffoldContext,\n renderFn,\n );\n}\n"],"mappings":"8MA2BA,SAAgB,EACd,EACA,EACA,EACA,EACM,CACN,EAAA,eAAe,EAAO,MAAM,EAC5B,EAAA,eAAe,EAAO,IAAI,EAC1B,EAAA,eAAe,EAAO,KAAK,EAC3B,EAAA,eAAe,EAAO,KAAK,EAC3B,GAAQ,OAAO,CAAC,CAAC,EACjB,GAAS,KAAK,EACd,GAAW,KAAK,CAClB,CA8BA,SAAS,EACP,EACA,EACA,EAUA,EACa,CACb,IAAM,EAAO,EAAA,gBAAgB,EAAW,CAAE,UAAW,EAAO,UAAW,OAAQ,EAAO,MAAO,CAAC,EACxF,EAAU,EAAO,QAAU,EAAA,cAAc,EAAW,EAAO,OAAO,EAAI,KACtE,EAAS,EAAO,OAAS,EAAA,aAAa,EAAW,EAAO,MAAM,EAAI,KAClE,EAAK,IAAI,gBACT,EAAM,EAAS,EAAM,EAAS,EAAQ,EAAG,MAAM,EAEjD,EAAW,GACT,EAAS,EAAiB,EAAK,GAAG,EAElC,GAAA,EAAA,EAAA,MAAA,KAAgB,EACpB,EAAA,EAAA,OAAA,KACQ,CACA,GAEJ,EAAO,OAAO,EAAS,CAAG,CAAC,CAC7B,EACA,CAAE,UAAW,WAAY,CAC3B,CACF,CAAC,EAEK,EAAkC,CAAC,EAEzC,GAAI,EAAO,QAAS,CAClB,IAAM,EAAgC,CACpC,YACA,WAAY,EAAK,WACjB,eAAgB,EAAG,OACnB,IAAK,EAAK,GACZ,EAEA,IAAK,IAAM,KAAU,EAAO,QAC1B,GAAI,CACF,EAAO,QAAQ,CAAS,EACxB,EAAiB,KAAK,CAAM,CAC9B,OAAS,EAAK,CACZ,EAAA,MAAM,4FAA6F,CAAG,CACxG,CAEJ,CAEA,MAAO,CACL,IAAI,gBAA8B,CAChC,OAAO,EAAG,MACZ,EAEA,SAAU,CACJ,MAIJ,CAFA,EAAW,GACX,EAAG,MAAM,EACT,EAAO,OAAO,EAEd,IAAK,IAAM,KAAK,EACd,GAAI,CACF,EAAE,QAAQ,CACZ,OAAS,EAAK,CACZ,EAAA,MAAM,yFAA0F,CAAG,CACrG,CAGF,GAAS,QAAQ,EACjB,GAAQ,QAAQ,EAChB,EAAE,QAAQ,EACV,EAAK,QAAQ,CAbC,CAchB,EAEA,IAAI,UAAoB,CACtB,OAAO,CACT,EAEA,GAAI,EAAK,IAET,CAAC,OAAO,UAAW,CACjB,KAAK,QAAQ,CACf,CACF,CACF,CAEA,SAAS,EAAiB,EAGxB,CACA,IAAI,EAAoC,KAExC,MAAO,CACL,OAAO,EAAU,CACf,AAOE,KANI,EAAO,aAAa,EAAI,oBAAoB,YAAa,EAAO,WAAW,EAE3E,EAAO,cAAc,EAAI,oBAAoB,aAAc,EAAO,YAAY,EAE9E,EAAO,SAAS,EAAI,oBAAoB,QAAS,EAAO,OAAO,EAE1D,MAGN,IAEL,EAAS,EAEL,EAAS,aAAa,EAAI,iBAAiB,YAAa,EAAS,WAAW,EAE5E,EAAS,cAAc,EAAI,iBAAiB,aAAc,EAAS,YAAY,EAE/E,EAAS,SAAS,EAAI,iBAAiB,QAAS,EAAS,OAAO,EACtE,EACA,QAAS,CACP,KAAK,OAAO,IAAA,EAAS,CACvB,CACF,CACF,CAOA,SAAgB,EACd,EACA,EACA,EACa,CACb,OAAO,EACL,EACA,GACC,EAAM,EAAS,EAAQ,IAAmB,CACzC,IAAM,EAAyB,CAI7B,KAAM,EAAA,iBAAiB,IAAK,CAAE,cAAe,OAAQ,MAAO,YAAa,CAAC,EAC1E,OAAQ,EAAA,iBAAiB,IAAK,CAAE,MAAO,cAAe,CAAC,EACvD,MAAO,EAAA,iBAAiB,IAAK,CAAE,MAAO,cAAe,CAAC,EACtD,MAAO,EAAA,iBAAiB,IAAK,CAAE,MAAO,cAAe,CAAC,CACxD,EAOA,OALA,EAAK,UAAU,YAAY,EAAO,IAAI,EACtC,EAAK,UAAU,YAAY,EAAO,KAAK,EACvC,EAAK,UAAU,YAAY,EAAO,KAAK,EACvC,EAAK,UAAU,YAAY,EAAO,MAAM,EAEjC,CACL,UAAW,EAAK,UAChB,YACA,WAAY,EAAK,WACjB,iBACA,SACA,SACA,IAAK,EAAK,IACV,SACF,CACF,EACA,CACF,CACF,CAMA,SAAgB,EACd,EACA,EACA,EACa,CACb,OAAO,EACL,EACA,GACC,EAAM,EAAS,EAAQ,KACrB,CACC,YACA,WAAY,EAAK,WACjB,iBACA,SACA,IAAK,EAAK,IACV,SACF,GACF,CACF,CACF"}
@@ -0,0 +1,54 @@
1
+ import type { Readable } from '@vielzeug/ripple';
2
+ import type { CrosshairState } from '../interaction/crosshair';
3
+ import type { LegendState } from '../interaction/legend';
4
+ import type { TooltipState } from '../interaction/tooltip';
5
+ import type { BaseChartConfig, ChartDimensions, ChartHandle } from '../types';
6
+ export interface ScaffoldGroups {
7
+ grid: SVGGElement;
8
+ series: SVGGElement;
9
+ xAxis: SVGGElement;
10
+ yAxis: SVGGElement;
11
+ }
12
+ /**
13
+ * Clears a cartesian chart's series/grid/axis groups and hides its legend/tooltip/crosshair —
14
+ * shared by every cartesian chart factory's "no data" early-return so a reactive series
15
+ * transitioning to empty leaves a fully blank chart, not a half-cleared one.
16
+ */
17
+ export declare function clearCartesianDom(groups: ScaffoldGroups, legend: LegendState | null, tooltip: TooltipState | null, crosshair?: CrosshairState | null): void;
18
+ export interface ScaffoldContext {
19
+ chartArea: SVGGElement;
20
+ container: HTMLElement;
21
+ dimensions: Readable<ChartDimensions>;
22
+ /** Aborted when the chart is disposed — renderers use this to stop rescheduling in-flight `requestAnimationFrame` transitions. */
23
+ disposalSignal: AbortSignal;
24
+ groups: ScaffoldGroups;
25
+ legend: LegendState | null;
26
+ svg: SVGSVGElement;
27
+ tooltip: TooltipState | null;
28
+ }
29
+ export interface RadialScaffoldContext {
30
+ container: HTMLElement;
31
+ dimensions: Readable<ChartDimensions>;
32
+ /** Aborted when the chart is disposed — renderers use this to stop rescheduling in-flight `requestAnimationFrame` transitions. */
33
+ disposalSignal: AbortSignal;
34
+ legend: LegendState | null;
35
+ svg: SVGSVGElement;
36
+ tooltip: TooltipState | null;
37
+ }
38
+ export interface ChartEventHandlers {
39
+ onClick?: (event: MouseEvent) => void;
40
+ onMouseLeave?: (event: MouseEvent) => void;
41
+ onMouseMove?: (event: MouseEvent) => void;
42
+ }
43
+ /**
44
+ * Cartesian scaffold: provides grid/axis/series SVG groups and a reactive
45
+ * render loop. `renderFn` is called inside a reactive effect; it returns
46
+ * optional `ChartEventHandlers` that are attached/replaced on every render.
47
+ */
48
+ export declare function createChartScaffold(container: HTMLElement, config: BaseChartConfig, renderFn: (ctx: ScaffoldContext) => ChartEventHandlers | void): ChartHandle;
49
+ /**
50
+ * Radial scaffold: for charts that do not use cartesian axis groups
51
+ * (pie, donut, semi). Provides only tooltip, legend, and the SVG root.
52
+ */
53
+ export declare function createRadialScaffold(container: HTMLElement, config: BaseChartConfig, renderFn: (ctx: RadialScaffoldContext) => ChartEventHandlers | void): ChartHandle;
54
+ //# sourceMappingURL=chart-scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart-scaffold.d.ts","sourceRoot":"","sources":["../../src/core/chart-scaffold.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAmC,MAAM,UAAU,CAAC;AAQ/G,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,WAAW,GAAG,IAAI,EAC1B,OAAO,EAAE,YAAY,GAAG,IAAI,EAC5B,SAAS,CAAC,EAAE,cAAc,GAAG,IAAI,GAChC,IAAI,CAQN;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,WAAW,CAAC;IACvB,SAAS,EAAE,WAAW,CAAC;IACvB,UAAU,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IACtC,kIAAkI;IAClI,cAAc,EAAE,WAAW,CAAC;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,GAAG,EAAE,aAAa,CAAC;IACnB,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,WAAW,CAAC;IACvB,UAAU,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IACtC,kIAAkI;IAClI,cAAc,EAAE,WAAW,CAAC;IAC5B,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,GAAG,EAAE,aAAa,CAAC;IACnB,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CAC3C;AAiID;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,WAAW,EACtB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,kBAAkB,GAAG,IAAI,GAC5D,WAAW,CAiCb;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,WAAW,EACtB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,kBAAkB,GAAG,IAAI,GAClE,WAAW,CAeb"}
@@ -0,0 +1,104 @@
1
+ import { error as e } from "../_dev.js";
2
+ import { createSvgElement as t, removeChildren as n } from "../svg/element.js";
3
+ import { createLegend as r } from "../interaction/legend.js";
4
+ import { createTooltip as i } from "../interaction/tooltip.js";
5
+ import { createChartBase as a } from "./chart-base.js";
6
+ import { effect as o, scope as s } from "@vielzeug/ripple";
7
+ //#region src/core/chart-scaffold.ts
8
+ function c(e, t, r, i) {
9
+ n(e.series), n(e.grid), n(e.xAxis), n(e.yAxis), t?.update([]), r?.hide(), i?.hide();
10
+ }
11
+ function l(t, n, c, l) {
12
+ let d = a(t, {
13
+ ariaLabel: n.ariaLabel,
14
+ margin: n.margin
15
+ }), f = n.tooltip ? i(t, n.tooltip) : null, p = n.legend ? r(t, n.legend) : null, m = new AbortController(), h = c(d, f, p, m.signal), g = !1, _ = u(d.svg), v = s(() => {
16
+ o(() => {
17
+ g || _.attach(l(h));
18
+ }, { scheduler: "microtask" });
19
+ }), y = [];
20
+ if (n.plugins) {
21
+ let r = {
22
+ container: t,
23
+ dimensions: d.dimensions,
24
+ disposalSignal: m.signal,
25
+ svg: d.svg
26
+ };
27
+ for (let t of n.plugins) try {
28
+ t.install(r), y.push(t);
29
+ } catch (t) {
30
+ e("A chart plugin threw during install() — skipping it; the rest of the chart still renders.", t);
31
+ }
32
+ }
33
+ return {
34
+ get disposalSignal() {
35
+ return m.signal;
36
+ },
37
+ dispose() {
38
+ if (!g) {
39
+ g = !0, m.abort(), _.detach();
40
+ for (let t of y) try {
41
+ t.dispose();
42
+ } catch (t) {
43
+ e("A chart plugin threw during dispose() — continuing to tear down the rest of the chart.", t);
44
+ }
45
+ f?.dispose(), p?.dispose(), v.dispose(), d.dispose();
46
+ }
47
+ },
48
+ get disposed() {
49
+ return g;
50
+ },
51
+ el: d.svg,
52
+ [Symbol.dispose]() {
53
+ this.dispose();
54
+ }
55
+ };
56
+ }
57
+ function u(e) {
58
+ let t = null;
59
+ return {
60
+ attach(n) {
61
+ t &&= (t.onMouseMove && e.removeEventListener("mousemove", t.onMouseMove), t.onMouseLeave && e.removeEventListener("mouseleave", t.onMouseLeave), t.onClick && e.removeEventListener("click", t.onClick), null), n && (t = n, n.onMouseMove && e.addEventListener("mousemove", n.onMouseMove), n.onMouseLeave && e.addEventListener("mouseleave", n.onMouseLeave), n.onClick && e.addEventListener("click", n.onClick));
62
+ },
63
+ detach() {
64
+ this.attach(void 0);
65
+ }
66
+ };
67
+ }
68
+ function d(e, n, r) {
69
+ return l(e, n, (n, r, i, a) => {
70
+ let o = {
71
+ grid: t("g", {
72
+ "aria-hidden": "true",
73
+ class: "prism-grid"
74
+ }),
75
+ series: t("g", { class: "prism-series" }),
76
+ xAxis: t("g", { class: "prism-x-axis" }),
77
+ yAxis: t("g", { class: "prism-y-axis" })
78
+ };
79
+ return n.chartArea.appendChild(o.grid), n.chartArea.appendChild(o.xAxis), n.chartArea.appendChild(o.yAxis), n.chartArea.appendChild(o.series), {
80
+ chartArea: n.chartArea,
81
+ container: e,
82
+ dimensions: n.dimensions,
83
+ disposalSignal: a,
84
+ groups: o,
85
+ legend: i,
86
+ svg: n.svg,
87
+ tooltip: r
88
+ };
89
+ }, r);
90
+ }
91
+ function f(e, t, n) {
92
+ return l(e, t, (t, n, r, i) => ({
93
+ container: e,
94
+ dimensions: t.dimensions,
95
+ disposalSignal: i,
96
+ legend: r,
97
+ svg: t.svg,
98
+ tooltip: n
99
+ }), n);
100
+ }
101
+ //#endregion
102
+ export { c as clearCartesianDom, d as createChartScaffold, f as createRadialScaffold };
103
+
104
+ //# sourceMappingURL=chart-scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart-scaffold.js","names":[],"sources":["../../src/core/chart-scaffold.ts"],"sourcesContent":["import type { Readable } from '@vielzeug/ripple';\n\nimport { effect, scope } from '@vielzeug/ripple';\n\nimport type { CrosshairState } from '../interaction/crosshair';\nimport type { LegendState } from '../interaction/legend';\nimport type { TooltipState } from '../interaction/tooltip';\nimport type { BaseChartConfig, ChartDimensions, ChartHandle, ChartPlugin, ChartPluginContext } from '../types';\n\nimport { error } from '../_dev';\nimport { createLegend } from '../interaction/legend';\nimport { createTooltip } from '../interaction/tooltip';\nimport { createSvgElement, removeChildren } from '../svg/element';\nimport { createChartBase } from './chart-base';\n\nexport interface ScaffoldGroups {\n grid: SVGGElement;\n series: SVGGElement;\n xAxis: SVGGElement;\n yAxis: SVGGElement;\n}\n\n/**\n * Clears a cartesian chart's series/grid/axis groups and hides its legend/tooltip/crosshair —\n * shared by every cartesian chart factory's \"no data\" early-return so a reactive series\n * transitioning to empty leaves a fully blank chart, not a half-cleared one.\n */\nexport function clearCartesianDom(\n groups: ScaffoldGroups,\n legend: LegendState | null,\n tooltip: TooltipState | null,\n crosshair?: CrosshairState | null,\n): void {\n removeChildren(groups.series);\n removeChildren(groups.grid);\n removeChildren(groups.xAxis);\n removeChildren(groups.yAxis);\n legend?.update([]);\n tooltip?.hide();\n crosshair?.hide();\n}\n\nexport interface ScaffoldContext {\n chartArea: SVGGElement;\n container: HTMLElement;\n dimensions: Readable<ChartDimensions>;\n /** Aborted when the chart is disposed — renderers use this to stop rescheduling in-flight `requestAnimationFrame` transitions. */\n disposalSignal: AbortSignal;\n groups: ScaffoldGroups;\n legend: LegendState | null;\n svg: SVGSVGElement;\n tooltip: TooltipState | null;\n}\n\nexport interface RadialScaffoldContext {\n container: HTMLElement;\n dimensions: Readable<ChartDimensions>;\n /** Aborted when the chart is disposed — renderers use this to stop rescheduling in-flight `requestAnimationFrame` transitions. */\n disposalSignal: AbortSignal;\n legend: LegendState | null;\n svg: SVGSVGElement;\n tooltip: TooltipState | null;\n}\n\nexport interface ChartEventHandlers {\n onClick?: (event: MouseEvent) => void;\n onMouseLeave?: (event: MouseEvent) => void;\n onMouseMove?: (event: MouseEvent) => void;\n}\n\nfunction runScaffold<TCtx>(\n container: HTMLElement,\n config: BaseChartConfig,\n buildCtx: (\n base: {\n chartArea: SVGGElement;\n dimensions: Readable<ChartDimensions>;\n svg: SVGSVGElement;\n },\n tooltip: TooltipState | null,\n legend: LegendState | null,\n disposalSignal: AbortSignal,\n ) => TCtx,\n renderFn: (ctx: TCtx) => ChartEventHandlers | void,\n): ChartHandle {\n const base = createChartBase(container, { ariaLabel: config.ariaLabel, margin: config.margin });\n const tooltip = config.tooltip ? createTooltip(container, config.tooltip) : null;\n const legend = config.legend ? createLegend(container, config.legend) : null;\n const ac = new AbortController();\n const ctx = buildCtx(base, tooltip, legend, ac.signal);\n\n let disposed = false;\n const events = makeEventManager(base.svg);\n\n const s = scope(() => {\n effect(\n () => {\n if (disposed) return;\n\n events.attach(renderFn(ctx));\n },\n { scheduler: 'microtask' },\n );\n });\n\n const installedPlugins: ChartPlugin[] = [];\n\n if (config.plugins) {\n const pluginCtx: ChartPluginContext = {\n container,\n dimensions: base.dimensions,\n disposalSignal: ac.signal,\n svg: base.svg,\n };\n\n for (const plugin of config.plugins) {\n try {\n plugin.install(pluginCtx);\n installedPlugins.push(plugin);\n } catch (err) {\n error('A chart plugin threw during install() — skipping it; the rest of the chart still renders.', err);\n }\n }\n }\n\n return {\n get disposalSignal(): AbortSignal {\n return ac.signal;\n },\n\n dispose() {\n if (disposed) return;\n\n disposed = true;\n ac.abort();\n events.detach();\n\n for (const p of installedPlugins) {\n try {\n p.dispose();\n } catch (err) {\n error('A chart plugin threw during dispose() — continuing to tear down the rest of the chart.', err);\n }\n }\n\n tooltip?.dispose();\n legend?.dispose();\n s.dispose();\n base.dispose();\n },\n\n get disposed(): boolean {\n return disposed;\n },\n\n el: base.svg,\n\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n}\n\nfunction makeEventManager(svg: SVGSVGElement): {\n attach(handlers: ChartEventHandlers | void): void;\n detach(): void;\n} {\n let active: ChartEventHandlers | null = null;\n\n return {\n attach(handlers) {\n if (active) {\n if (active.onMouseMove) svg.removeEventListener('mousemove', active.onMouseMove);\n\n if (active.onMouseLeave) svg.removeEventListener('mouseleave', active.onMouseLeave);\n\n if (active.onClick) svg.removeEventListener('click', active.onClick);\n\n active = null;\n }\n\n if (!handlers) return;\n\n active = handlers;\n\n if (handlers.onMouseMove) svg.addEventListener('mousemove', handlers.onMouseMove);\n\n if (handlers.onMouseLeave) svg.addEventListener('mouseleave', handlers.onMouseLeave);\n\n if (handlers.onClick) svg.addEventListener('click', handlers.onClick);\n },\n detach() {\n this.attach(undefined);\n },\n };\n}\n\n/**\n * Cartesian scaffold: provides grid/axis/series SVG groups and a reactive\n * render loop. `renderFn` is called inside a reactive effect; it returns\n * optional `ChartEventHandlers` that are attached/replaced on every render.\n */\nexport function createChartScaffold(\n container: HTMLElement,\n config: BaseChartConfig,\n renderFn: (ctx: ScaffoldContext) => ChartEventHandlers | void,\n): ChartHandle {\n return runScaffold(\n container,\n config,\n (base, tooltip, legend, disposalSignal) => {\n const groups: ScaffoldGroups = {\n // Grid lines are purely decorative relative to the root svg's own role=\"img\"/aria-label.\n // Axis groups are NOT hidden wholesale — they can contain a meaningful `.prism-axis-title`;\n // `renderAxis` marks its own decorative tick lines/labels individually instead.\n grid: createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-grid' }),\n series: createSvgElement('g', { class: 'prism-series' }),\n xAxis: createSvgElement('g', { class: 'prism-x-axis' }),\n yAxis: createSvgElement('g', { class: 'prism-y-axis' }),\n };\n\n base.chartArea.appendChild(groups.grid);\n base.chartArea.appendChild(groups.xAxis);\n base.chartArea.appendChild(groups.yAxis);\n base.chartArea.appendChild(groups.series);\n\n return {\n chartArea: base.chartArea,\n container,\n dimensions: base.dimensions,\n disposalSignal,\n groups,\n legend,\n svg: base.svg,\n tooltip,\n } satisfies ScaffoldContext;\n },\n renderFn,\n );\n}\n\n/**\n * Radial scaffold: for charts that do not use cartesian axis groups\n * (pie, donut, semi). Provides only tooltip, legend, and the SVG root.\n */\nexport function createRadialScaffold(\n container: HTMLElement,\n config: BaseChartConfig,\n renderFn: (ctx: RadialScaffoldContext) => ChartEventHandlers | void,\n): ChartHandle {\n return runScaffold(\n container,\n config,\n (base, tooltip, legend, disposalSignal) =>\n ({\n container,\n dimensions: base.dimensions,\n disposalSignal,\n legend,\n svg: base.svg,\n tooltip,\n }) satisfies RadialScaffoldContext,\n renderFn,\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export { createChartBase } from './chart-base';
2
+ export type { ChartBase } from './chart-base';
3
+ export { createChartScaffold, createRadialScaffold } from './chart-scaffold';
4
+ export type { ChartEventHandlers, RadialScaffoldContext, ScaffoldContext, ScaffoldGroups } from './chart-scaffold';
5
+ export { chartArea, resolveMargin } from './layout';
6
+ export { observeResize } from './responsive';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7E,YAAY,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACnH,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,2 @@
1
+ var e={bottom:40,left:50,right:20,top:20};function t(t){return{...e,...t}}function n(e,t,n){return{height:Math.max(0,t-n.top-n.bottom),width:Math.max(0,e-n.left-n.right)}}exports.chartArea=n,exports.resolveMargin=t;
2
+ //# sourceMappingURL=layout.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.cjs","names":[],"sources":["../../src/core/layout.ts"],"sourcesContent":["import type { ChartMargin } from '../types';\n\nconst DEFAULT_MARGIN: ChartMargin = { bottom: 40, left: 50, right: 20, top: 20 };\n\nexport function resolveMargin(margin?: Partial<ChartMargin>): ChartMargin {\n return { ...DEFAULT_MARGIN, ...margin };\n}\n\nexport function chartArea(width: number, height: number, margin: ChartMargin): { height: number; width: number } {\n return {\n height: Math.max(0, height - margin.top - margin.bottom),\n width: Math.max(0, width - margin.left - margin.right),\n };\n}\n"],"mappings":"AAEA,IAAM,EAA8B,CAAE,OAAQ,GAAI,KAAM,GAAI,MAAO,GAAI,IAAK,EAAG,EAE/E,SAAgB,EAAc,EAA4C,CACxE,MAAO,CAAE,GAAG,EAAgB,GAAG,CAAO,CACxC,CAEA,SAAgB,EAAU,EAAe,EAAgB,EAAwD,CAC/G,MAAO,CACL,OAAQ,KAAK,IAAI,EAAG,EAAS,EAAO,IAAM,EAAO,MAAM,EACvD,MAAO,KAAK,IAAI,EAAG,EAAQ,EAAO,KAAO,EAAO,KAAK,CACvD,CACF"}
@@ -0,0 +1,7 @@
1
+ import type { ChartMargin } from '../types';
2
+ export declare function resolveMargin(margin?: Partial<ChartMargin>): ChartMargin;
3
+ export declare function chartArea(width: number, height: number, margin: ChartMargin): {
4
+ height: number;
5
+ width: number;
6
+ };
7
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/core/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAI5C,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAExE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAK/G"}
@@ -0,0 +1,23 @@
1
+ //#region src/core/layout.ts
2
+ var e = {
3
+ bottom: 40,
4
+ left: 50,
5
+ right: 20,
6
+ top: 20
7
+ };
8
+ function t(t) {
9
+ return {
10
+ ...e,
11
+ ...t
12
+ };
13
+ }
14
+ function n(e, t, n) {
15
+ return {
16
+ height: Math.max(0, t - n.top - n.bottom),
17
+ width: Math.max(0, e - n.left - n.right)
18
+ };
19
+ }
20
+ //#endregion
21
+ export { n as chartArea, t as resolveMargin };
22
+
23
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.js","names":[],"sources":["../../src/core/layout.ts"],"sourcesContent":["import type { ChartMargin } from '../types';\n\nconst DEFAULT_MARGIN: ChartMargin = { bottom: 40, left: 50, right: 20, top: 20 };\n\nexport function resolveMargin(margin?: Partial<ChartMargin>): ChartMargin {\n return { ...DEFAULT_MARGIN, ...margin };\n}\n\nexport function chartArea(width: number, height: number, margin: ChartMargin): { height: number; width: number } {\n return {\n height: Math.max(0, height - margin.top - margin.bottom),\n width: Math.max(0, width - margin.left - margin.right),\n };\n}\n"],"mappings":";AAEA,IAAM,IAA8B;CAAE,QAAQ;CAAI,MAAM;CAAI,OAAO;CAAI,KAAK;AAAG;AAE/E,SAAgB,EAAc,GAA4C;CACxE,OAAO;EAAE,GAAG;EAAgB,GAAG;CAAO;AACxC;AAEA,SAAgB,EAAU,GAAe,GAAgB,GAAwD;CAC/G,OAAO;EACL,QAAQ,KAAK,IAAI,GAAG,IAAS,EAAO,MAAM,EAAO,MAAM;EACvD,OAAO,KAAK,IAAI,GAAG,IAAQ,EAAO,OAAO,EAAO,KAAK;CACvD;AACF"}
@@ -0,0 +1,2 @@
1
+ function e(e,t){let n=null,r=new ResizeObserver(e=>{n!==null&&cancelAnimationFrame(n),n=requestAnimationFrame(()=>{n=null;let r=e[0];if(r){let{height:e,width:n}=r.contentRect;t(n,e)}})});return r.observe(e),()=>{n!==null&&cancelAnimationFrame(n),r.disconnect()}}exports.observeResize=e;
2
+ //# sourceMappingURL=responsive.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responsive.cjs","names":[],"sources":["../../src/core/responsive.ts"],"sourcesContent":["export function observeResize(el: HTMLElement, callback: (width: number, height: number) => void): () => void {\n let rafId: number | null = null;\n\n const observer = new ResizeObserver((entries) => {\n if (rafId !== null) cancelAnimationFrame(rafId);\n\n rafId = requestAnimationFrame(() => {\n rafId = null;\n\n const entry = entries[0];\n\n if (entry) {\n const { height, width } = entry.contentRect;\n\n callback(width, height);\n }\n });\n });\n\n observer.observe(el);\n\n return () => {\n if (rafId !== null) cancelAnimationFrame(rafId);\n\n observer.disconnect();\n };\n}\n"],"mappings":"AAAA,SAAgB,EAAc,EAAiB,EAA+D,CAC5G,IAAI,EAAuB,KAErB,EAAW,IAAI,eAAgB,GAAY,CAC3C,IAAU,MAAM,qBAAqB,CAAK,EAE9C,EAAQ,0BAA4B,CAClC,EAAQ,KAER,IAAM,EAAQ,EAAQ,GAEtB,GAAI,EAAO,CACT,GAAM,CAAE,SAAQ,SAAU,EAAM,YAEhC,EAAS,EAAO,CAAM,CACxB,CACF,CAAC,CACH,CAAC,EAID,OAFA,EAAS,QAAQ,CAAE,MAEN,CACP,IAAU,MAAM,qBAAqB,CAAK,EAE9C,EAAS,WAAW,CACtB,CACF"}
@@ -0,0 +1,2 @@
1
+ export declare function observeResize(el: HTMLElement, callback: (width: number, height: number) => void): () => void;
2
+ //# sourceMappingURL=responsive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responsive.d.ts","sourceRoot":"","sources":["../../src/core/responsive.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CA0B5G"}
@@ -0,0 +1,20 @@
1
+ //#region src/core/responsive.ts
2
+ function e(e, t) {
3
+ let n = null, r = new ResizeObserver((e) => {
4
+ n !== null && cancelAnimationFrame(n), n = requestAnimationFrame(() => {
5
+ n = null;
6
+ let r = e[0];
7
+ if (r) {
8
+ let { height: e, width: n } = r.contentRect;
9
+ t(n, e);
10
+ }
11
+ });
12
+ });
13
+ return r.observe(e), () => {
14
+ n !== null && cancelAnimationFrame(n), r.disconnect();
15
+ };
16
+ }
17
+ //#endregion
18
+ export { e as observeResize };
19
+
20
+ //# sourceMappingURL=responsive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responsive.js","names":[],"sources":["../../src/core/responsive.ts"],"sourcesContent":["export function observeResize(el: HTMLElement, callback: (width: number, height: number) => void): () => void {\n let rafId: number | null = null;\n\n const observer = new ResizeObserver((entries) => {\n if (rafId !== null) cancelAnimationFrame(rafId);\n\n rafId = requestAnimationFrame(() => {\n rafId = null;\n\n const entry = entries[0];\n\n if (entry) {\n const { height, width } = entry.contentRect;\n\n callback(width, height);\n }\n });\n });\n\n observer.observe(el);\n\n return () => {\n if (rafId !== null) cancelAnimationFrame(rafId);\n\n observer.disconnect();\n };\n}\n"],"mappings":";AAAA,SAAgB,EAAc,GAAiB,GAA+D;CAC5G,IAAI,IAAuB,MAErB,IAAW,IAAI,gBAAgB,MAAY;EAG/C,AAFI,MAAU,QAAM,qBAAqB,CAAK,GAE9C,IAAQ,4BAA4B;GAClC,IAAQ;GAER,IAAM,IAAQ,EAAQ;GAEtB,IAAI,GAAO;IACT,IAAM,EAAE,WAAQ,aAAU,EAAM;IAEhC,EAAS,GAAO,CAAM;GACxB;EACF,CAAC;CACH,CAAC;CAID,OAFA,EAAS,QAAQ,CAAE,SAEN;EAGX,AAFI,MAAU,QAAM,qBAAqB,CAAK,GAE9C,EAAS,WAAW;CACtB;AACF"}