@vielzeug/prism 26.11.4 → 26.11.6

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 (105) hide show
  1. package/README.md +25 -10
  2. package/dist/_dev.js +1 -2
  3. package/dist/_tappers.js +1 -2
  4. package/dist/animation/easing.js +1 -2
  5. package/dist/animation/motion.js +0 -1
  6. package/dist/animation/reveal.cjs +1 -1
  7. package/dist/animation/reveal.cjs.map +1 -1
  8. package/dist/animation/reveal.js +29 -30
  9. package/dist/animation/transition.js +1 -2
  10. package/dist/animation/tween.js +1 -2
  11. package/dist/axes/axis.js +1 -2
  12. package/dist/axes/grid.js +1 -2
  13. package/dist/axes/scale-utils.js +1 -2
  14. package/dist/charts/area/area-chart.cjs +1 -1
  15. package/dist/charts/area/area-chart.cjs.map +1 -1
  16. package/dist/charts/area/area-chart.js +34 -35
  17. package/dist/charts/area/area-renderer.cjs +1 -1
  18. package/dist/charts/area/area-renderer.cjs.map +1 -1
  19. package/dist/charts/area/area-renderer.js +56 -57
  20. package/dist/charts/area/area-renderer.js.map +1 -1
  21. package/dist/charts/bar/bar-chart.cjs +1 -1
  22. package/dist/charts/bar/bar-chart.cjs.map +1 -1
  23. package/dist/charts/bar/bar-chart.js +80 -81
  24. package/dist/charts/bar/bar-chart.js.map +1 -1
  25. package/dist/charts/bar/bar-hit-test.js +1 -2
  26. package/dist/charts/bar/bar-renderer.cjs +1 -1
  27. package/dist/charts/bar/bar-renderer.cjs.map +1 -1
  28. package/dist/charts/bar/bar-renderer.js +42 -43
  29. package/dist/charts/bar/bar-value-labels.cjs +1 -1
  30. package/dist/charts/bar/bar-value-labels.cjs.map +1 -1
  31. package/dist/charts/bar/bar-value-labels.js +17 -18
  32. package/dist/charts/heatmap/heatmap-chart.cjs +1 -1
  33. package/dist/charts/heatmap/heatmap-chart.cjs.map +1 -1
  34. package/dist/charts/heatmap/heatmap-chart.js +43 -44
  35. package/dist/charts/heatmap/heatmap-color.js +1 -2
  36. package/dist/charts/line/line-chart.cjs +1 -1
  37. package/dist/charts/line/line-chart.cjs.map +1 -1
  38. package/dist/charts/line/line-chart.js +41 -42
  39. package/dist/charts/line/line-renderer.cjs +1 -1
  40. package/dist/charts/line/line-renderer.cjs.map +1 -1
  41. package/dist/charts/line/line-renderer.js +81 -82
  42. package/dist/charts/line/line-renderer.js.map +1 -1
  43. package/dist/charts/pie/pie-chart.cjs +1 -1
  44. package/dist/charts/pie/pie-chart.cjs.map +1 -1
  45. package/dist/charts/pie/pie-chart.js +69 -70
  46. package/dist/charts/pie/pie-renderer.js +1 -2
  47. package/dist/charts/radar/radar-chart.cjs +1 -1
  48. package/dist/charts/radar/radar-chart.cjs.map +1 -1
  49. package/dist/charts/radar/radar-chart.js +118 -119
  50. package/dist/charts/radar/radar-chart.js.map +1 -1
  51. package/dist/charts/radar/radar-geometry.cjs +1 -1
  52. package/dist/charts/radar/radar-geometry.cjs.map +1 -1
  53. package/dist/charts/radar/radar-geometry.js +15 -16
  54. package/dist/charts/scatter/scatter-chart.cjs +1 -1
  55. package/dist/charts/scatter/scatter-chart.cjs.map +1 -1
  56. package/dist/charts/scatter/scatter-chart.js +33 -34
  57. package/dist/charts/scatter/scatter-renderer.cjs +1 -1
  58. package/dist/charts/scatter/scatter-renderer.cjs.map +1 -1
  59. package/dist/charts/scatter/scatter-renderer.js +22 -23
  60. package/dist/charts/sparkline/sparkline.cjs +1 -1
  61. package/dist/charts/sparkline/sparkline.cjs.map +1 -1
  62. package/dist/charts/sparkline/sparkline.js +87 -88
  63. package/dist/charts/sparkline/sparkline.js.map +1 -1
  64. package/dist/core/cartesian-model.js +1 -2
  65. package/dist/core/cartesian-scales.js +1 -2
  66. package/dist/core/chart-base.cjs +1 -1
  67. package/dist/core/chart-base.cjs.map +1 -1
  68. package/dist/core/chart-base.js +13 -14
  69. package/dist/core/chart-scaffold.cjs +1 -1
  70. package/dist/core/chart-scaffold.cjs.map +1 -1
  71. package/dist/core/chart-scaffold.js +33 -34
  72. package/dist/core/datum-style.js +1 -2
  73. package/dist/core/ids.js +1 -2
  74. package/dist/core/layout.js +1 -2
  75. package/dist/core/polar.js +1 -2
  76. package/dist/core/responsive.js +1 -2
  77. package/dist/core/series-id.js +1 -2
  78. package/dist/errors.js +1 -2
  79. package/dist/index.cjs +1 -1
  80. package/dist/index.js +14 -14
  81. package/dist/interaction/announcer.js +1 -2
  82. package/dist/interaction/crosshair.js +1 -2
  83. package/dist/interaction/events.js +1 -2
  84. package/dist/interaction/legend.js +1 -2
  85. package/dist/interaction/scatter-interaction.cjs +1 -1
  86. package/dist/interaction/scatter-interaction.cjs.map +1 -1
  87. package/dist/interaction/scatter-interaction.js +26 -27
  88. package/dist/interaction/series-interaction.cjs +1 -1
  89. package/dist/interaction/series-interaction.cjs.map +1 -1
  90. package/dist/interaction/series-interaction.js +40 -41
  91. package/dist/interaction/tooltip.js +1 -2
  92. package/dist/prism.cjs +1 -1
  93. package/dist/prism.cjs.map +1 -1
  94. package/dist/prism.iife.js +1 -1
  95. package/dist/prism.iife.js.map +1 -1
  96. package/dist/prism.js +52 -103
  97. package/dist/prism.js.map +1 -1
  98. package/dist/scales/band.js +1 -2
  99. package/dist/scales/linear.js +1 -2
  100. package/dist/scales/time.js +1 -2
  101. package/dist/svg/element.js +1 -2
  102. package/dist/svg/path.js +1 -2
  103. package/dist/svg/text.js +1 -2
  104. package/dist/theme/index.js +1 -2
  105. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"chart-scaffold.cjs","names":["createTappers","createChartBase","createTooltip","createLegend","createAnnouncer","PrismRenderError","createSvgElement","require_element","require__tappers","require_errors","require_announcer","require_legend","require_tooltip","require_chart_base","groups","legend","tooltip","crosshair","tappers","base","container","config","ac","ctx","buildCtx","disposed","events","renderFn","reason","error","updateData","data","active","svg","handlers"],"sources":["../../src/core/chart-scaffold.ts"],"sourcesContent":["import { createTappers } from '../_tappers';\nimport { PrismRenderError } from '../errors';\nimport { type Announcer, createAnnouncer } from '../interaction/announcer';\nimport type { CrosshairState } from '../interaction/crosshair';\nimport type { LegendState } from '../interaction/legend';\nimport { createLegend } from '../interaction/legend';\nimport type { TooltipState } from '../interaction/tooltip';\nimport { createTooltip } from '../interaction/tooltip';\nimport { createSvgElement, removeChildren } from '../svg/element';\nimport type { BaseChartConfig, ChartDimensions, ChartHandle, PrismEvent } from '../types';\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 an update\n * to empty data 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 /** Speaks hover/keyboard values when no tooltip is shown (the tooltip is its own live region). */\n announcer: Announcer;\n chartArea: SVGGElement;\n container: HTMLElement;\n dimensions: 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 announcer: Announcer;\n container: HTMLElement;\n dimensions: 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 onKeyDown?: (event: KeyboardEvent) => void;\n onMouseLeave?: (event: MouseEvent) => void;\n onMouseMove?: (event: MouseEvent) => void;\n}\n\ntype RenderReason = 'mount' | 'resize' | 'update';\n\nfunction runScaffold<TCtx, TData>(\n container: HTMLElement,\n config: BaseChartConfig,\n buildCtx: (\n base: {\n chartArea: SVGGElement;\n dimensions: ChartDimensions;\n svg: SVGSVGElement;\n },\n tooltip: TooltipState | null,\n legend: LegendState | null,\n disposalSignal: AbortSignal,\n announcer: Announcer,\n ) => TCtx,\n renderFn: (ctx: TCtx, reason: RenderReason) => ChartEventHandlers | undefined,\n updateData: (data: TData) => void,\n): ChartHandle<TData> {\n let render = (_reason: RenderReason) => {};\n const tappers = createTappers<PrismEvent>();\n // Bottom legends follow the SVG. Populate them before measuring chart geometry,\n // so the first observer notification does not interrupt the entrance.\n let legend: LegendState | null = null;\n const base = createChartBase(\n container,\n { a11y: config.a11y, chrome: () => legend?.el ?? null, margin: config.margin },\n () => {\n tappers.emit({ height: base.dimensions.height, type: 'resize', width: base.dimensions.width });\n render('resize');\n },\n );\n const tooltip = config.tooltip ? createTooltip(container, config.tooltip) : null;\n legend = config.legend ? createLegend(container, config.legend, () => base.syncChrome()) : null;\n const ac = new AbortController();\n const ctx = buildCtx(base, tooltip, legend, ac.signal, createAnnouncer(base.svg, 'prism-live'));\n\n let disposed = false;\n const events = makeEventManager(base.svg);\n\n render = (reason) => {\n if (disposed) return;\n events.attach(renderFn(ctx, reason));\n };\n\n try {\n render('mount');\n } catch (error) {\n disposed = true;\n ac.abort();\n events.detach();\n tooltip?.dispose();\n legend?.dispose();\n base.dispose();\n throw error instanceof PrismRenderError ? error : new PrismRenderError('Failed to render chart.', { cause: error });\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 tappers.emit({ type: 'dispose' });\n tappers.stop();\n ac.abort();\n events.detach();\n tooltip?.dispose();\n legend?.dispose();\n base.dispose();\n },\n\n get disposed(): boolean {\n return disposed;\n },\n\n el: base.svg,\n\n tap: tappers.tap,\n\n update(data) {\n if (disposed) throw new PrismRenderError('Cannot update a disposed chart.');\n updateData(data);\n render('update');\n },\n\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n}\n\nfunction makeEventManager(svg: SVGSVGElement): {\n attach(handlers: ChartEventHandlers | undefined): 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 if (active.onKeyDown) svg.removeEventListener('keydown', active.onKeyDown);\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 if (handlers.onKeyDown) svg.addEventListener('keydown', handlers.onKeyDown);\n },\n detach() {\n this.attach(undefined);\n },\n };\n}\n\n/**\n * Cartesian scaffold: provides grid/axis/series SVG groups and a render loop.\n * `renderFn` returns optional `ChartEventHandlers` that are attached/replaced\n * after every data update or resize.\n */\nexport function createChartScaffold<TData>(\n container: HTMLElement,\n config: BaseChartConfig,\n renderFn: (ctx: ScaffoldContext, reason: RenderReason) => ChartEventHandlers | undefined,\n updateData: (data: TData) => void,\n): ChartHandle<TData> {\n return runScaffold(\n container,\n config,\n (base, tooltip, legend, disposalSignal, announcer) => {\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 announcer,\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 updateData,\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<TData>(\n container: HTMLElement,\n config: BaseChartConfig,\n renderFn: (ctx: RadialScaffoldContext, reason: RenderReason) => ChartEventHandlers | undefined,\n updateData: (data: TData) => void,\n): ChartHandle<TData> {\n return runScaffold(\n container,\n config,\n (base, tooltip, legend, disposalSignal, announcer) =>\n ({\n announcer,\n container,\n dimensions: base.dimensions,\n disposalSignal,\n legend,\n svg: base.svg,\n tooltip,\n }) satisfies RadialScaffoldContext,\n renderFn,\n updateData,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"chart-scaffold.cjs","names":["createTappers","createChartBase","createTooltip","createLegend","createAnnouncer","PrismRenderError","createSvgElement","require__tappers","require_errors","require_announcer","require_legend","require_tooltip","require_element","require_chart_base","groups","legend","tooltip","crosshair","tappers","base","container","config","ac","ctx","buildCtx","disposed","events","renderFn","reason","error","updateData","data","active","svg","handlers"],"sources":["../../src/core/chart-scaffold.ts"],"sourcesContent":["import { createTappers } from '../_tappers';\nimport { PrismRenderError } from '../errors';\nimport { type Announcer, createAnnouncer } from '../interaction/announcer';\nimport type { CrosshairState } from '../interaction/crosshair';\nimport type { LegendState } from '../interaction/legend';\nimport { createLegend } from '../interaction/legend';\nimport type { TooltipState } from '../interaction/tooltip';\nimport { createTooltip } from '../interaction/tooltip';\nimport { createSvgElement, removeChildren } from '../svg/element';\nimport type { BaseChartConfig, ChartDimensions, ChartHandle, PrismEvent } from '../types';\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 an update\n * to empty data 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 /** Speaks hover/keyboard values when no tooltip is shown (the tooltip is its own live region). */\n announcer: Announcer;\n chartArea: SVGGElement;\n container: HTMLElement;\n dimensions: 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 announcer: Announcer;\n container: HTMLElement;\n dimensions: 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 onKeyDown?: (event: KeyboardEvent) => void;\n onMouseLeave?: (event: MouseEvent) => void;\n onMouseMove?: (event: MouseEvent) => void;\n}\n\ntype RenderReason = 'mount' | 'resize' | 'update';\n\nfunction runScaffold<TCtx, TData>(\n container: HTMLElement,\n config: BaseChartConfig,\n buildCtx: (\n base: {\n chartArea: SVGGElement;\n dimensions: ChartDimensions;\n svg: SVGSVGElement;\n },\n tooltip: TooltipState | null,\n legend: LegendState | null,\n disposalSignal: AbortSignal,\n announcer: Announcer,\n ) => TCtx,\n renderFn: (ctx: TCtx, reason: RenderReason) => ChartEventHandlers | undefined,\n updateData: (data: TData) => void,\n): ChartHandle<TData> {\n let render = (_reason: RenderReason) => {};\n const tappers = createTappers<PrismEvent>();\n // Bottom legends follow the SVG. Populate them before measuring chart geometry,\n // so the first observer notification does not interrupt the entrance.\n let legend: LegendState | null = null;\n const base = createChartBase(\n container,\n { a11y: config.a11y, chrome: () => legend?.el ?? null, margin: config.margin },\n () => {\n tappers.emit({ height: base.dimensions.height, type: 'resize', width: base.dimensions.width });\n render('resize');\n },\n );\n const tooltip = config.tooltip ? createTooltip(container, config.tooltip) : null;\n legend = config.legend ? createLegend(container, config.legend, () => base.syncChrome()) : null;\n const ac = new AbortController();\n const ctx = buildCtx(base, tooltip, legend, ac.signal, createAnnouncer(base.svg, 'prism-live'));\n\n let disposed = false;\n const events = makeEventManager(base.svg);\n\n render = (reason) => {\n if (disposed) return;\n events.attach(renderFn(ctx, reason));\n };\n\n try {\n render('mount');\n } catch (error) {\n disposed = true;\n ac.abort();\n events.detach();\n tooltip?.dispose();\n legend?.dispose();\n base.dispose();\n throw error instanceof PrismRenderError ? error : new PrismRenderError('Failed to render chart.', { cause: error });\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 tappers.emit({ type: 'dispose' });\n tappers.stop();\n ac.abort();\n events.detach();\n tooltip?.dispose();\n legend?.dispose();\n base.dispose();\n },\n\n get disposed(): boolean {\n return disposed;\n },\n\n el: base.svg,\n\n tap: tappers.tap,\n\n update(data) {\n if (disposed) throw new PrismRenderError('Cannot update a disposed chart.');\n updateData(data);\n render('update');\n },\n\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n}\n\nfunction makeEventManager(svg: SVGSVGElement): {\n attach(handlers: ChartEventHandlers | undefined): 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 if (active.onKeyDown) svg.removeEventListener('keydown', active.onKeyDown);\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 if (handlers.onKeyDown) svg.addEventListener('keydown', handlers.onKeyDown);\n },\n detach() {\n this.attach(undefined);\n },\n };\n}\n\n/**\n * Cartesian scaffold: provides grid/axis/series SVG groups and a render loop.\n * `renderFn` returns optional `ChartEventHandlers` that are attached/replaced\n * after every data update or resize.\n */\nexport function createChartScaffold<TData>(\n container: HTMLElement,\n config: BaseChartConfig,\n renderFn: (ctx: ScaffoldContext, reason: RenderReason) => ChartEventHandlers | undefined,\n updateData: (data: TData) => void,\n): ChartHandle<TData> {\n return runScaffold(\n container,\n config,\n (base, tooltip, legend, disposalSignal, announcer) => {\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 announcer,\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 updateData,\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<TData>(\n container: HTMLElement,\n config: BaseChartConfig,\n renderFn: (ctx: RadialScaffoldContext, reason: RenderReason) => ChartEventHandlers | undefined,\n updateData: (data: TData) => void,\n): ChartHandle<TData> {\n return runScaffold(\n container,\n config,\n (base, tooltip, legend, disposalSignal, announcer) =>\n ({\n announcer,\n container,\n dimensions: base.dimensions,\n disposalSignal,\n legend,\n svg: base.svg,\n tooltip,\n }) satisfies RadialScaffoldContext,\n renderFn,\n updateData,\n );\n}\n"],"mappings":"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"}
@@ -1,35 +1,35 @@
1
- import { createSvgElement as e, removeChildren as t } from "../svg/element.js";
2
- import { createTappers as n } from "../_tappers.js";
3
- import { PrismRenderError as r } from "../errors.js";
4
- import { createAnnouncer as i } from "../interaction/announcer.js";
5
- import { createLegend as a } from "../interaction/legend.js";
6
- import { createTooltip as o } from "../interaction/tooltip.js";
1
+ import { createTappers as e } from "../_tappers.js";
2
+ import { PrismRenderError as t } from "../errors.js";
3
+ import { createAnnouncer as n } from "../interaction/announcer.js";
4
+ import { createLegend as r } from "../interaction/legend.js";
5
+ import { createTooltip as i } from "../interaction/tooltip.js";
6
+ import { createSvgElement as a, removeChildren as o } from "../svg/element.js";
7
7
  import { createChartBase as s } from "./chart-base.js";
8
- //#region src/core/chart-scaffold.ts
9
- function clearCartesianDom(e, n, r, i) {
10
- t(e.series), t(e.grid), t(e.xAxis), t(e.yAxis), n?.update([]), r?.hide(), i?.hide();
8
+ // src/core/chart-scaffold.ts
9
+ function clearCartesianDom(e, t, n, r) {
10
+ o(e.series), o(e.grid), o(e.xAxis), o(e.yAxis), t?.update([]), n?.hide(), r?.hide();
11
11
  }
12
- function runScaffold(e, t, c, l, u) {
13
- let render = (e) => {}, d = n(), f = null, p = s(e, {
14
- a11y: t.a11y,
12
+ function runScaffold(a, o, c, l, u) {
13
+ let render = (e) => {}, d = e(), f = null, p = s(a, {
14
+ a11y: o.a11y,
15
15
  chrome: () => f?.el ?? null,
16
- margin: t.margin
16
+ margin: o.margin
17
17
  }, () => {
18
18
  d.emit({
19
19
  height: p.dimensions.height,
20
20
  type: "resize",
21
21
  width: p.dimensions.width
22
22
  }), render("resize");
23
- }), m = t.tooltip ? o(e, t.tooltip) : null;
24
- f = t.legend ? a(e, t.legend, () => p.syncChrome()) : null;
25
- let h = new AbortController(), g = c(p, m, f, h.signal, i(p.svg, "prism-live")), _ = !1, v = makeEventManager(p.svg);
23
+ }), m = o.tooltip ? i(a, o.tooltip) : null;
24
+ f = o.legend ? r(a, o.legend, () => p.syncChrome()) : null;
25
+ let h = new AbortController(), g = c(p, m, f, h.signal, n(p.svg, "prism-live")), _ = !1, v = makeEventManager(p.svg);
26
26
  render = (e) => {
27
27
  _ || v.attach(l(g, e));
28
28
  };
29
29
  try {
30
30
  render("mount");
31
31
  } catch (e) {
32
- throw _ = !0, h.abort(), v.detach(), m?.dispose(), f?.dispose(), p.dispose(), e instanceof r ? e : new r("Failed to render chart.", { cause: e });
32
+ throw _ = !0, h.abort(), v.detach(), m?.dispose(), f?.dispose(), p.dispose(), e instanceof t ? e : new t("Failed to render chart.", { cause: e });
33
33
  }
34
34
  return {
35
35
  get disposalSignal() {
@@ -44,7 +44,7 @@ function runScaffold(e, t, c, l, u) {
44
44
  el: p.svg,
45
45
  tap: d.tap,
46
46
  update(e) {
47
- if (_) throw new r("Cannot update a disposed chart.");
47
+ if (_) throw new t("Cannot update a disposed chart.");
48
48
  u(e), render("update");
49
49
  },
50
50
  [Symbol.dispose]() {
@@ -63,29 +63,29 @@ function makeEventManager(e) {
63
63
  }
64
64
  };
65
65
  }
66
- function createChartScaffold(t, n, r, i) {
67
- return runScaffold(t, n, (n, r, i, a, o) => {
66
+ function createChartScaffold(e, t, n, r) {
67
+ return runScaffold(e, t, (t, n, r, i, o) => {
68
68
  let s = {
69
- grid: e("g", {
69
+ grid: a("g", {
70
70
  "aria-hidden": "true",
71
71
  class: "prism-grid"
72
72
  }),
73
- series: e("g", { class: "prism-series" }),
74
- xAxis: e("g", { class: "prism-x-axis" }),
75
- yAxis: e("g", { class: "prism-y-axis" })
73
+ series: a("g", { class: "prism-series" }),
74
+ xAxis: a("g", { class: "prism-x-axis" }),
75
+ yAxis: a("g", { class: "prism-y-axis" })
76
76
  };
77
- return n.chartArea.appendChild(s.grid), n.chartArea.appendChild(s.xAxis), n.chartArea.appendChild(s.yAxis), n.chartArea.appendChild(s.series), {
77
+ return t.chartArea.appendChild(s.grid), t.chartArea.appendChild(s.xAxis), t.chartArea.appendChild(s.yAxis), t.chartArea.appendChild(s.series), {
78
78
  announcer: o,
79
- chartArea: n.chartArea,
80
- container: t,
81
- dimensions: n.dimensions,
82
- disposalSignal: a,
79
+ chartArea: t.chartArea,
80
+ container: e,
81
+ dimensions: t.dimensions,
82
+ disposalSignal: i,
83
83
  groups: s,
84
- legend: i,
85
- svg: n.svg,
86
- tooltip: r
84
+ legend: r,
85
+ svg: t.svg,
86
+ tooltip: n
87
87
  };
88
- }, r, i);
88
+ }, n, r);
89
89
  }
90
90
  function createRadialScaffold(e, t, n, r) {
91
91
  return runScaffold(e, t, (t, n, r, i, a) => ({
@@ -98,7 +98,6 @@ function createRadialScaffold(e, t, n, r) {
98
98
  tooltip: n
99
99
  }), n, r);
100
100
  }
101
- //#endregion
102
101
  export { clearCartesianDom, createChartScaffold, createRadialScaffold };
103
102
 
104
103
  //# sourceMappingURL=chart-scaffold.js.map
@@ -1,4 +1,4 @@
1
- //#region src/core/datum-style.ts
1
+ // src/core/datum-style.ts
2
2
  function hasStyledRuns(e) {
3
3
  return e?.some((e) => e && (e.dash !== void 0 || e.opacity !== void 0)) ?? !1;
4
4
  }
@@ -17,7 +17,6 @@ function computeStyleRuns(e, t) {
17
17
  }
18
18
  return r;
19
19
  }
20
- //#endregion
21
20
  export { computeStyleRuns, hasStyledRuns };
22
21
 
23
22
  //# sourceMappingURL=datum-style.js.map
package/dist/core/ids.js CHANGED
@@ -1,9 +1,8 @@
1
- //#region src/core/ids.ts
1
+ // src/core/ids.ts
2
2
  var e = 0;
3
3
  function uniqueId(t) {
4
4
  return e += 1, `${t}-${e}`;
5
5
  }
6
- //#endregion
7
6
  export { uniqueId };
8
7
 
9
8
  //# sourceMappingURL=ids.js.map
@@ -1,4 +1,4 @@
1
- //#region src/core/layout.ts
1
+ // src/core/layout.ts
2
2
  var e = {
3
3
  bottom: 48,
4
4
  left: 50,
@@ -17,7 +17,6 @@ function chartArea(e, t, n) {
17
17
  width: Math.max(0, e - n.left - n.right)
18
18
  };
19
19
  }
20
- //#endregion
21
20
  export { chartArea, resolveMargin };
22
21
 
23
22
  //# sourceMappingURL=layout.js.map
@@ -1,4 +1,4 @@
1
- //#region src/core/polar.ts
1
+ // src/core/polar.ts
2
2
  function polarX(e, t, n) {
3
3
  return e + t * Math.sin(n);
4
4
  }
@@ -8,7 +8,6 @@ function polarY(e, t, n) {
8
8
  function polarPoint(e, t, n, r) {
9
9
  return `${polarX(e, n, r)},${polarY(t, n, r)}`;
10
10
  }
11
- //#endregion
12
11
  export { polarPoint, polarX, polarY };
13
12
 
14
13
  //# sourceMappingURL=polar.js.map
@@ -1,4 +1,4 @@
1
- //#region src/core/responsive.ts
1
+ // src/core/responsive.ts
2
2
  function observeResize(e, t) {
3
3
  if (typeof ResizeObserver > "u") return () => {};
4
4
  let n = null, r = new ResizeObserver((e) => {
@@ -15,7 +15,6 @@ function observeResize(e, t) {
15
15
  n !== null && cancelAnimationFrame(n), r.disconnect();
16
16
  };
17
17
  }
18
- //#endregion
19
18
  export { observeResize };
20
19
 
21
20
  //# sourceMappingURL=responsive.js.map
@@ -1,8 +1,7 @@
1
- //#region src/core/series-id.ts
1
+ // src/core/series-id.ts
2
2
  function seriesDomId(e, t) {
3
3
  return e?.id ? e.id.replace(/[^A-Za-z0-9_-]/g, "-") : `series-${t}`;
4
4
  }
5
- //#endregion
6
5
  export { seriesDomId };
7
6
 
8
7
  //# sourceMappingURL=series-id.js.map
package/dist/errors.js CHANGED
@@ -1,10 +1,9 @@
1
- //#region src/errors.ts
1
+ // src/errors.ts
2
2
  var PrismError = class extends Error {
3
3
  constructor(e, t) {
4
4
  super(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);
5
5
  }
6
6
  }, PrismRenderError = class extends PrismError {};
7
- //#endregion
8
7
  export { PrismError, PrismRenderError };
9
8
 
10
9
  //# sourceMappingURL=errors.js.map
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./scales/linear.cjs"),t=require("./scales/time.cjs"),n=require("./errors.cjs"),r=require("./theme/index.cjs"),i=require("./charts/area/area-chart.cjs"),a=require("./scales/band.cjs"),o=require("./charts/bar/bar-chart.cjs"),s=require("./charts/heatmap/heatmap-chart.cjs"),c=require("./charts/line/line-chart.cjs"),l=require("./charts/pie/pie-chart.cjs"),u=require("./charts/radar/radar-chart.cjs"),d=require("./charts/scatter/scatter-chart.cjs"),f=require("./charts/sparkline/sparkline.cjs");exports.PrismError=n.PrismError,exports.PrismRenderError=n.PrismRenderError,exports.bandScale=a.bandScale,exports.createAreaChart=i.createAreaChart,exports.createBarChart=o.createBarChart,exports.createHeatmapChart=s.createHeatmapChart,exports.createLineChart=c.createLineChart,exports.createPieChart=l.createPieChart,exports.createRadarChart=u.createRadarChart,exports.createScatterChart=d.createScatterChart,exports.createSparkline=f.createSparkline,exports.linearScale=e.linearScale,exports.resetTheme=r.resetTheme,exports.seriesColor=r.seriesColor,exports.setTheme=r.setTheme,exports.timeScale=t.timeScale;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./charts/area/area-chart.cjs"),t=require("./charts/bar/bar-chart.cjs"),n=require("./charts/heatmap/heatmap-chart.cjs"),r=require("./charts/line/line-chart.cjs"),i=require("./charts/pie/pie-chart.cjs"),a=require("./charts/radar/radar-chart.cjs"),o=require("./charts/scatter/scatter-chart.cjs"),s=require("./charts/sparkline/sparkline.cjs"),c=require("./errors.cjs"),l=require("./scales/band.cjs"),u=require("./scales/linear.cjs"),d=require("./scales/time.cjs"),f=require("./theme/index.cjs");exports.PrismError=c.PrismError,exports.PrismRenderError=c.PrismRenderError,exports.bandScale=l.bandScale,exports.createAreaChart=e.createAreaChart,exports.createBarChart=t.createBarChart,exports.createHeatmapChart=n.createHeatmapChart,exports.createLineChart=r.createLineChart,exports.createPieChart=i.createPieChart,exports.createRadarChart=a.createRadarChart,exports.createScatterChart=o.createScatterChart,exports.createSparkline=s.createSparkline,exports.linearScale=u.linearScale,exports.resetTheme=f.resetTheme,exports.seriesColor=f.seriesColor,exports.setTheme=f.setTheme,exports.timeScale=d.timeScale;
package/dist/index.js CHANGED
@@ -1,14 +1,14 @@
1
- import { linearScale as e } from "./scales/linear.js";
2
- import { timeScale as t } from "./scales/time.js";
3
- import { PrismError as n, PrismRenderError as r } from "./errors.js";
4
- import { resetTheme as i, seriesColor as a, setTheme as o } from "./theme/index.js";
5
- import { createAreaChart as s } from "./charts/area/area-chart.js";
6
- import { bandScale as c } from "./scales/band.js";
7
- import { createBarChart as l } from "./charts/bar/bar-chart.js";
8
- import { createHeatmapChart as u } from "./charts/heatmap/heatmap-chart.js";
9
- import { createLineChart as d } from "./charts/line/line-chart.js";
10
- import { createPieChart as f } from "./charts/pie/pie-chart.js";
11
- import { createRadarChart as p } from "./charts/radar/radar-chart.js";
12
- import { createScatterChart as m } from "./charts/scatter/scatter-chart.js";
13
- import { createSparkline as h } from "./charts/sparkline/sparkline.js";
14
- export { n as PrismError, r as PrismRenderError, c as bandScale, s as createAreaChart, l as createBarChart, u as createHeatmapChart, d as createLineChart, f as createPieChart, p as createRadarChart, m as createScatterChart, h as createSparkline, e as linearScale, i as resetTheme, a as seriesColor, o as setTheme, t as timeScale };
1
+ import { createAreaChart as e } from "./charts/area/area-chart.js";
2
+ import { createBarChart as t } from "./charts/bar/bar-chart.js";
3
+ import { createHeatmapChart as n } from "./charts/heatmap/heatmap-chart.js";
4
+ import { createLineChart as r } from "./charts/line/line-chart.js";
5
+ import { createPieChart as i } from "./charts/pie/pie-chart.js";
6
+ import { createRadarChart as a } from "./charts/radar/radar-chart.js";
7
+ import { createScatterChart as o } from "./charts/scatter/scatter-chart.js";
8
+ import { createSparkline as s } from "./charts/sparkline/sparkline.js";
9
+ import { PrismError as c, PrismRenderError as l } from "./errors.js";
10
+ import { bandScale as u } from "./scales/band.js";
11
+ import { linearScale as d } from "./scales/linear.js";
12
+ import { timeScale as f } from "./scales/time.js";
13
+ import { resetTheme as p, seriesColor as m, setTheme as h } from "./theme/index.js";
14
+ export { c as PrismError, l as PrismRenderError, u as bandScale, e as createAreaChart, t as createBarChart, n as createHeatmapChart, r as createLineChart, i as createPieChart, a as createRadarChart, o as createScatterChart, s as createSparkline, d as linearScale, p as resetTheme, m as seriesColor, h as setTheme, f as timeScale };
@@ -1,5 +1,5 @@
1
1
  import { createSvgElement as e } from "../svg/element.js";
2
- //#region src/interaction/announcer.ts
2
+ // src/interaction/announcer.ts
3
3
  function describeValues(e, t, n = String) {
4
4
  return `${e}: ${t.map(({ datum: e, series: t }) => `${t.name} ${e ? n(e.value, e, t) : "n/a"}`).join(", ")}`;
5
5
  }
@@ -20,7 +20,6 @@ function createAnnouncer(t, n) {
20
20
  }
21
21
  };
22
22
  }
23
- //#endregion
24
23
  export { createAnnouncer, describeValues };
25
24
 
26
25
  //# sourceMappingURL=announcer.js.map
@@ -1,5 +1,5 @@
1
1
  import { createSvgElement as e, setAttributes as t } from "../svg/element.js";
2
- //#region src/interaction/crosshair.ts
2
+ // src/interaction/crosshair.ts
3
3
  function createCrosshair(n, r) {
4
4
  let i = r === !0 || r?.vertical !== !1, a = r !== !0 && r?.horizontal === !0, o = r === !0 || r?.snap !== !1, s = e("g", {
5
5
  "aria-hidden": "true",
@@ -32,7 +32,6 @@ function createCrosshair(n, r) {
32
32
  snap: o
33
33
  };
34
34
  }
35
- //#endregion
36
35
  export { createCrosshair };
37
36
 
38
37
  //# sourceMappingURL=crosshair.js.map
@@ -1,4 +1,4 @@
1
- //#region src/interaction/events.ts
1
+ // src/interaction/events.ts
2
2
  function getMousePosition(e, t, n, r) {
3
3
  let i = e.getBoundingClientRect();
4
4
  return {
@@ -6,7 +6,6 @@ function getMousePosition(e, t, n, r) {
6
6
  y: t.clientY - i.top - r
7
7
  };
8
8
  }
9
- //#endregion
10
9
  export { getMousePosition };
11
10
 
12
11
  //# sourceMappingURL=events.js.map
@@ -1,4 +1,4 @@
1
- //#region src/interaction/legend.ts
1
+ // src/interaction/legend.ts
2
2
  function resolvePosition(e) {
3
3
  return e === !0 ? "bottom" : e.position ?? "bottom";
4
4
  }
@@ -26,7 +26,6 @@ function createLegend(e, t, n) {
26
26
  }
27
27
  };
28
28
  }
29
- //#endregion
30
29
  export { createLegend };
31
30
 
32
31
  //# sourceMappingURL=legend.js.map
@@ -1,2 +1,2 @@
1
- const e=require("../svg/element.cjs"),t=require("./announcer.cjs"),n=require("./tooltip.cjs"),r=require("../core/layout.cjs"),i=require("./events.cjs"),a=require("./series-interaction.cjs");function createScatterInteraction(o){let s=-1,c=!1,hitAt=(e,t)=>{let n=o.getData()[e]?.[t],r=o.getPoints()[e]?.[t];return n&&r?{datum:n,point:r,seriesIndex:e}:null},renderedHit=e=>{let t=e.target;return!(t instanceof SVGElement)||!t.classList.contains(`prism-scatter-point`)||!t.parentElement||t.parentElement.parentNode!==o.seriesGroup?null:hitAt([...o.seriesGroup.children].indexOf(t.parentElement),[...t.parentElement.children].indexOf(t))},nearestHit=e=>{let t=null,n=1/0;for(let[r,i]of o.getPoints().entries())for(let a of i.keys()){let i=hitAt(r,a);if(!i)continue;let o=Math.hypot(i.point.x-e.x,i.point.y-e.y);o<n&&(n=o,t=i)}return t},orderedHits=()=>{let e=[];for(let[t,n]of o.getData().entries())for(let r of n.keys()){let n=hitAt(t,r);n&&e.push(n)}return e.sort((e,t)=>e.point.x-t.point.x||e.point.y-t.point.y||e.seriesIndex-t.seriesIndex)},eventFor=(e,t)=>({datum:e.datum,originalEvent:t,series:o.getSeriesList()[e.seriesIndex]}),highlight=t=>{let n=[...o.seriesGroup.children];o.markers.replaceChildren(),t&&o.markers.appendChild(e.createSvgElement(`circle`,{class:`prism-active-point`,cx:t.point.x,cy:t.point.y,fill:o.colors()[t.seriesIndex],r:4})),o.seriesGroup.classList.toggle(`prism-series-focused`,t!==null&&n.length>1);for(let[e,r]of n.entries())r.classList.toggle(`prism-series-active`,e===t?.seriesIndex)},clear=()=>{o.crosshair?.hide(),o.tooltip?.hide(),o.announcer.clear(),highlight(null),c=!1,o.onHover?.(null)},focus=(e,i,s)=>{let l=o.dims(),u=r.chartArea(l.width,l.height,o.margin),d=o.crosshair?.snap===!1&&i,f=eventFor(e,s),{datum:p,series:m}=f,h=o.tooltipFormat?.titleFormat?o.tooltipFormat.titleFormat(p.key):a.keyLabel(p.key),g=o.tooltipFormat?.valueFormat,_=t.describeValues(h,[{datum:p,series:m}],g??String);if(o.crosshair?.show(d?i.x:e.point.x,d?i.y:e.point.y,u.width,u.height),highlight(e),o.tooltip){let t={color:o.colors()[e.seriesIndex],name:m.name,value:g?g(p.value,p,m):String(p.value)};o.tooltip.show(e.point.x+o.margin.left,e.point.y+o.margin.top,p,m,n.comparisonContent(o.svg.ownerDocument,h,[t],_))}else o.announcer.announce(_);c=!0,o.onHover?.(f)},pointerHit=e=>{let t=renderedHit(e);if(t)return{hit:t,raw:t.point};let n=o.dims(),a=i.getMousePosition(o.svg,e,o.margin.left,o.margin.top),s=r.chartArea(n.width,n.height,o.margin);if(a.x<0||a.x>s.width||a.y<0||a.y>s.height)return null;let c=nearestHit(a);return c?{hit:c,raw:a}:null},onMouseMove=e=>{let t=pointerHit(e);t?focus(t.hit,t.raw,e):c&&clear()},onClick=e=>{if(!o.onClick)return;let t=pointerHit(e);t&&o.onClick(eventFor(t.hit,e))},onKeyDown=e=>{let t=orderedHits();if(t.length===0)return;let n=t.length-1,r={ArrowLeft:s<0?n:Math.max(0,s-1),ArrowRight:s<0?0:Math.min(n,s+1),End:n,Home:0};e.key in r?(e.preventDefault(),s=r[e.key],focus(t[s],null,e)):(e.key===`Enter`||e.key===` `)&&s>=0&&o.onClick?(e.preventDefault(),o.onClick(eventFor(t[s],e))):e.key===`Escape`&&(s=-1,clear())};return{onClick,onKeyDown,onMouseLeave:clear,onMouseMove}}exports.createScatterInteraction=createScatterInteraction;
1
+ const e=require("../core/layout.cjs"),t=require("../svg/element.cjs"),n=require("./announcer.cjs"),r=require("./events.cjs"),i=require("./series-interaction.cjs"),a=require("./tooltip.cjs");function createScatterInteraction(o){let s=-1,c=!1,hitAt=(e,t)=>{let n=o.getData()[e]?.[t],r=o.getPoints()[e]?.[t];return n&&r?{datum:n,point:r,seriesIndex:e}:null},renderedHit=e=>{let t=e.target;return!(t instanceof SVGElement)||!t.classList.contains(`prism-scatter-point`)||!t.parentElement||t.parentElement.parentNode!==o.seriesGroup?null:hitAt([...o.seriesGroup.children].indexOf(t.parentElement),[...t.parentElement.children].indexOf(t))},nearestHit=e=>{let t=null,n=1/0;for(let[r,i]of o.getPoints().entries())for(let a of i.keys()){let i=hitAt(r,a);if(!i)continue;let o=Math.hypot(i.point.x-e.x,i.point.y-e.y);o<n&&(n=o,t=i)}return t},orderedHits=()=>{let e=[];for(let[t,n]of o.getData().entries())for(let r of n.keys()){let n=hitAt(t,r);n&&e.push(n)}return e.sort((e,t)=>e.point.x-t.point.x||e.point.y-t.point.y||e.seriesIndex-t.seriesIndex)},eventFor=(e,t)=>({datum:e.datum,originalEvent:t,series:o.getSeriesList()[e.seriesIndex]}),highlight=e=>{let n=[...o.seriesGroup.children];o.markers.replaceChildren(),e&&o.markers.appendChild(t.createSvgElement(`circle`,{class:`prism-active-point`,cx:e.point.x,cy:e.point.y,fill:o.colors()[e.seriesIndex],r:4})),o.seriesGroup.classList.toggle(`prism-series-focused`,e!==null&&n.length>1);for(let[t,r]of n.entries())r.classList.toggle(`prism-series-active`,t===e?.seriesIndex)},clear=()=>{o.crosshair?.hide(),o.tooltip?.hide(),o.announcer.clear(),highlight(null),c=!1,o.onHover?.(null)},focus=(t,r,s)=>{let l=o.dims(),u=e.chartArea(l.width,l.height,o.margin),d=o.crosshair?.snap===!1&&r,f=eventFor(t,s),{datum:p,series:m}=f,h=o.tooltipFormat?.titleFormat?o.tooltipFormat.titleFormat(p.key):i.keyLabel(p.key),g=o.tooltipFormat?.valueFormat,_=n.describeValues(h,[{datum:p,series:m}],g??String);if(o.crosshair?.show(d?r.x:t.point.x,d?r.y:t.point.y,u.width,u.height),highlight(t),o.tooltip){let e={color:o.colors()[t.seriesIndex],name:m.name,value:g?g(p.value,p,m):String(p.value)};o.tooltip.show(t.point.x+o.margin.left,t.point.y+o.margin.top,p,m,a.comparisonContent(o.svg.ownerDocument,h,[e],_))}else o.announcer.announce(_);c=!0,o.onHover?.(f)},pointerHit=t=>{let n=renderedHit(t);if(n)return{hit:n,raw:n.point};let i=o.dims(),a=r.getMousePosition(o.svg,t,o.margin.left,o.margin.top),s=e.chartArea(i.width,i.height,o.margin);if(a.x<0||a.x>s.width||a.y<0||a.y>s.height)return null;let c=nearestHit(a);return c?{hit:c,raw:a}:null},onMouseMove=e=>{let t=pointerHit(e);t?focus(t.hit,t.raw,e):c&&clear()},onClick=e=>{if(!o.onClick)return;let t=pointerHit(e);t&&o.onClick(eventFor(t.hit,e))},onKeyDown=e=>{let t=orderedHits();if(t.length===0)return;let n=t.length-1,r={ArrowLeft:s<0?n:Math.max(0,s-1),ArrowRight:s<0?0:Math.min(n,s+1),End:n,Home:0};e.key in r?(e.preventDefault(),s=r[e.key],focus(t[s],null,e)):(e.key===`Enter`||e.key===` `)&&s>=0&&o.onClick?(e.preventDefault(),o.onClick(eventFor(t[s],e))):e.key===`Escape`&&(s=-1,clear())};return{onClick,onKeyDown,onMouseLeave:clear,onMouseMove}}exports.createScatterInteraction=createScatterInteraction;
2
2
  //# sourceMappingURL=scatter-interaction.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"scatter-interaction.cjs","names":["createSvgElement","chartArea","keyLabel","describeValues","comparisonContent","getMousePosition","require_element","require_announcer","require_tooltip","require_layout","require_events","require_series_interaction","keyboardIndex","active","datum","opts","seriesIndex","pointIndex","point","target","event","best","minDistance","points","hit","distance","pos","hits","data","a","b","groups","index","group","dims","area","follow","raw","originalEvent","label","valueFormat","spoken","row","series","rendered","found","last"],"sources":["../../src/interaction/scatter-interaction.ts"],"sourcesContent":["import type { ChartEventHandlers } from '../core/chart-scaffold';\nimport { chartArea } from '../core/layout';\nimport { createSvgElement } from '../svg/element';\nimport type { Point } from '../svg/path';\nimport type { ChartDimensions, ChartEvent, ChartMargin, ContinuousDatum, Series, TooltipConfig } from '../types';\nimport { type Announcer, describeValues } from './announcer';\nimport type { CrosshairState } from './crosshair';\nimport { getMousePosition } from './events';\nimport { keyLabel } from './series-interaction';\nimport { comparisonContent, type TooltipState } from './tooltip';\n\nexport interface ScatterInteractionOptions {\n announcer: Announcer;\n colors: () => string[];\n crosshair?: CrosshairState | null;\n dims: () => ChartDimensions;\n /** Per-series data, parallel to `getPoints`; each datum is one independent point. */\n getData: () => ContinuousDatum[][];\n getPoints: () => Point[][];\n getSeriesList: () => Series[];\n /** Effective chart margin: hit bounds and tooltip offsets use this, never the shared dimensions. */\n margin: ChartMargin;\n /** Receives the single active-point marker. */\n markers: SVGGElement;\n onClick?: ((event: ChartEvent) => void) | undefined;\n onHover?: ((event: ChartEvent | null) => void) | undefined;\n /** Parent of the per-series point groups; the active series is emphasised and the rest dim. */\n seriesGroup: SVGGElement;\n svg: SVGSVGElement;\n tooltip?: TooltipState | null;\n /** Value/title formatters from the tooltip config, applied to the row and spoken text alike. */\n tooltipFormat?: Pick<TooltipConfig, 'titleFormat' | 'valueFormat'>;\n}\n\ninterface Hit {\n datum: ContinuousDatum;\n point: Point;\n seriesIndex: number;\n}\n\n/**\n * Pointer and keyboard interaction for a scatter plot. A scatter point is an\n * independent `(x, y)` pair rather than one sample at a shared key, so the active\n * point is the one nearest the pointer in two dimensions, events carry no\n * cross-series `values`, and keyboard navigation walks every point in x order.\n */\nexport function createScatterInteraction(opts: ScatterInteractionOptions): ChartEventHandlers {\n let keyboardIndex = -1;\n let active = false;\n\n const hitAt = (seriesIndex: number, pointIndex: number): Hit | null => {\n const datum = opts.getData()[seriesIndex]?.[pointIndex];\n const point = opts.getPoints()[seriesIndex]?.[pointIndex];\n\n return datum && point ? { datum, point, seriesIndex } : null;\n };\n\n const renderedHit = (event: Event): Hit | null => {\n const target = event.target;\n\n if (\n !(target instanceof SVGElement) ||\n !target.classList.contains('prism-scatter-point') ||\n !target.parentElement ||\n target.parentElement.parentNode !== opts.seriesGroup\n )\n return null;\n\n return hitAt(\n [...opts.seriesGroup.children].indexOf(target.parentElement),\n [...target.parentElement.children].indexOf(target),\n );\n };\n\n const nearestHit = (pos: Point): Hit | null => {\n let best: Hit | null = null;\n let minDistance = Infinity;\n\n for (const [seriesIndex, points] of opts.getPoints().entries()) {\n for (const pointIndex of points.keys()) {\n const hit = hitAt(seriesIndex, pointIndex);\n\n if (!hit) continue;\n\n const distance = Math.hypot(hit.point.x - pos.x, hit.point.y - pos.y);\n\n if (distance < minDistance) {\n minDistance = distance;\n best = hit;\n }\n }\n }\n\n return best;\n };\n\n // Every point across every series in x order (then y, then series order), for keyboard traversal.\n const orderedHits = (): Hit[] => {\n const hits: Hit[] = [];\n\n for (const [seriesIndex, data] of opts.getData().entries()) {\n for (const pointIndex of data.keys()) {\n const hit = hitAt(seriesIndex, pointIndex);\n\n if (hit) hits.push(hit);\n }\n }\n\n return hits.sort((a, b) => a.point.x - b.point.x || a.point.y - b.point.y || a.seriesIndex - b.seriesIndex);\n };\n\n const eventFor = (hit: Hit, originalEvent: Event): ChartEvent => ({\n datum: hit.datum,\n originalEvent,\n series: opts.getSeriesList()[hit.seriesIndex],\n });\n\n const highlight = (hit: Hit | null): void => {\n const groups = [...opts.seriesGroup.children];\n\n opts.markers.replaceChildren();\n\n if (hit) {\n opts.markers.appendChild(\n createSvgElement('circle', {\n class: 'prism-active-point',\n cx: hit.point.x,\n cy: hit.point.y,\n fill: opts.colors()[hit.seriesIndex],\n r: 4,\n }),\n );\n }\n\n opts.seriesGroup.classList.toggle('prism-series-focused', hit !== null && groups.length > 1);\n for (const [index, group] of groups.entries())\n group.classList.toggle('prism-series-active', index === hit?.seriesIndex);\n };\n\n const clear = (): void => {\n opts.crosshair?.hide();\n opts.tooltip?.hide();\n opts.announcer.clear();\n highlight(null);\n active = false;\n opts.onHover?.(null);\n };\n\n const focus = (hit: Hit, raw: Point | null, originalEvent: Event): void => {\n const dims = opts.dims();\n const area = chartArea(dims.width, dims.height, opts.margin);\n const follow = opts.crosshair?.snap === false && raw;\n const event = eventFor(hit, originalEvent);\n const { datum, series } = event;\n const label = opts.tooltipFormat?.titleFormat ? opts.tooltipFormat.titleFormat(datum.key) : keyLabel(datum.key);\n const valueFormat = opts.tooltipFormat?.valueFormat;\n const spoken = describeValues(label, [{ datum, series }], valueFormat ?? String);\n\n opts.crosshair?.show(follow ? raw.x : hit.point.x, follow ? raw.y : hit.point.y, area.width, area.height);\n highlight(hit);\n\n if (opts.tooltip) {\n const row = {\n color: opts.colors()[hit.seriesIndex],\n name: series.name,\n value: valueFormat ? valueFormat(datum.value, datum, series) : String(datum.value),\n };\n\n opts.tooltip.show(\n hit.point.x + opts.margin.left,\n hit.point.y + opts.margin.top,\n datum,\n series,\n comparisonContent(opts.svg.ownerDocument, label, [row], spoken),\n );\n } else {\n opts.announcer.announce(spoken);\n }\n\n active = true;\n opts.onHover?.(event);\n };\n\n const pointerHit = (event: MouseEvent): { hit: Hit; raw: Point } | null => {\n const rendered = renderedHit(event);\n\n if (rendered) return { hit: rendered, raw: rendered.point };\n\n const dims = opts.dims();\n const raw = getMousePosition(opts.svg, event, opts.margin.left, opts.margin.top);\n const area = chartArea(dims.width, dims.height, opts.margin);\n\n if (raw.x < 0 || raw.x > area.width || raw.y < 0 || raw.y > area.height) return null;\n\n const hit = nearestHit(raw);\n\n return hit ? { hit, raw } : null;\n };\n\n const onMouseMove = (event: MouseEvent): void => {\n const found = pointerHit(event);\n\n if (found) focus(found.hit, found.raw, event);\n else if (active) clear();\n };\n\n const onClick = (event: MouseEvent): void => {\n if (!opts.onClick) return;\n\n const found = pointerHit(event);\n\n if (found) opts.onClick(eventFor(found.hit, event));\n };\n\n const onKeyDown = (event: KeyboardEvent): void => {\n const hits = orderedHits();\n\n if (hits.length === 0) return;\n\n const last = hits.length - 1;\n const target: Record<string, number> = {\n ArrowLeft: keyboardIndex < 0 ? last : Math.max(0, keyboardIndex - 1),\n ArrowRight: keyboardIndex < 0 ? 0 : Math.min(last, keyboardIndex + 1),\n End: last,\n Home: 0,\n };\n\n if (event.key in target) {\n event.preventDefault();\n keyboardIndex = target[event.key];\n focus(hits[keyboardIndex], null, event);\n } else if ((event.key === 'Enter' || event.key === ' ') && keyboardIndex >= 0 && opts.onClick) {\n event.preventDefault();\n opts.onClick(eventFor(hits[keyboardIndex], event));\n } else if (event.key === 'Escape') {\n keyboardIndex = -1;\n clear();\n }\n };\n\n return { onClick, onKeyDown, onMouseLeave: clear, onMouseMove };\n}\n"],"mappings":"A,8LA8CA,SAAgB,yBAAyB,EAAqD,CAC5F,IAAIY,EAAgB,GAChBC,EAAS,GAEP,OAAS,EAAqB,IAAmC,CACrE,IAAMC,EAAQC,EAAK,QAAQ,CAAC,CAACC,EAAY,GAAGC,GACtCC,EAAQH,EAAK,UAAU,CAAC,CAACC,EAAY,GAAGC,GAE9C,OAAOH,GAASI,EAAQ,CAAE,QAAO,QAAO,aAAY,EAAI,IAC1D,EAEM,YAAe,GAA6B,CAChD,IAAMC,EAASC,EAAM,OAUrB,MAPE,EAAED,aAAkB,aACpB,CAACA,EAAO,UAAU,SAAS,qBAAqB,GAChD,CAACA,EAAO,eACRA,EAAO,cAAc,aAAeJ,EAAK,YAElC,KAEF,MACL,CAAC,GAAGA,EAAK,YAAY,QAAQ,CAAC,CAAC,QAAQI,EAAO,aAAa,EAC3D,CAAC,GAAGA,EAAO,cAAc,QAAQ,CAAC,CAAC,QAAQA,CAAM,CACnD,CACF,EAEM,WAAc,GAA2B,CAC7C,IAAIE,EAAmB,KACnBC,EAAc,IAElB,IAAK,GAAM,CAACN,EAAaO,KAAWR,EAAK,UAAU,CAAC,CAAC,QAAQ,EAC3D,IAAK,IAAME,KAAcM,EAAO,KAAK,EAAG,CACtC,IAAMC,EAAM,MAAMR,EAAaC,CAAU,EAEzC,GAAI,CAACO,EAAK,SAEV,IAAMC,EAAW,KAAK,MAAMD,EAAI,MAAM,EAAIE,EAAI,EAAGF,EAAI,MAAM,EAAIE,EAAI,CAAC,EAEhED,EAAWH,IACb,EAAcG,EACd,EAAOD,EAEX,CAGF,OAAOH,CACT,EAGM,gBAA2B,CAC/B,IAAMM,EAAc,CAAC,EAErB,IAAK,GAAM,CAACX,EAAaY,KAASb,EAAK,QAAQ,CAAC,CAAC,QAAQ,EACvD,IAAK,IAAME,KAAcW,EAAK,KAAK,EAAG,CACpC,IAAMJ,EAAM,MAAMR,EAAaC,CAAU,EAErCO,GAAKG,EAAK,KAAKH,CAAG,CACxB,CAGF,OAAOG,EAAK,MAAM,EAAG,IAAME,EAAE,MAAM,EAAIC,EAAE,MAAM,GAAKD,EAAE,MAAM,EAAIC,EAAE,MAAM,GAAKD,EAAE,YAAcC,EAAE,WAAW,CAC5G,EAEM,UAAY,EAAU,KAAsC,CAChE,MAAON,EAAI,MACX,gBACA,OAAQT,EAAK,cAAc,CAAC,CAACS,EAAI,YACnC,GAEM,UAAa,GAA0B,CAC3C,IAAMO,EAAS,CAAC,GAAGhB,EAAK,YAAY,QAAQ,EAE5CA,EAAK,QAAQ,gBAAgB,EAEzBS,GACFT,EAAK,QAAQ,YACXf,EAAAA,iBAAiB,SAAU,CACzB,MAAO,qBACP,GAAIwB,EAAI,MAAM,EACd,GAAIA,EAAI,MAAM,EACd,KAAMT,EAAK,OAAO,CAAC,CAACS,EAAI,aACxB,EAAG,CACL,CAAC,CACH,EAGFT,EAAK,YAAY,UAAU,OAAO,uBAAwBS,IAAQ,MAAQO,EAAO,OAAS,CAAC,EAC3F,IAAK,GAAM,CAACC,EAAOC,KAAUF,EAAO,QAAQ,EAC1CE,EAAM,UAAU,OAAO,sBAAuBD,IAAUR,GAAK,WAAW,CAC5E,EAEM,UAAoB,CACxBT,EAAK,WAAW,KAAK,EACrBA,EAAK,SAAS,KAAK,EACnBA,EAAK,UAAU,MAAM,EACrB,UAAU,IAAI,EACd,EAAS,GACTA,EAAK,UAAU,IAAI,CACrB,EAEM,OAAS,EAAU,EAAmB,IAA+B,CACzE,IAAMmB,EAAOnB,EAAK,KAAK,EACjBoB,EAAOlC,EAAAA,UAAUiC,EAAK,MAAOA,EAAK,OAAQnB,EAAK,MAAM,EACrDqB,EAASrB,EAAK,WAAW,OAAS,IAASsB,EAC3CjB,EAAQ,SAASI,EAAKc,CAAa,EACnC,CAAE,QAAO,UAAWlB,EACpBmB,EAAQxB,EAAK,eAAe,YAAcA,EAAK,cAAc,YAAYD,EAAM,GAAG,EAAIZ,EAAAA,SAASY,EAAM,GAAG,EACxG0B,EAAczB,EAAK,eAAe,YAClC0B,EAAStC,EAAAA,eAAeoC,EAAO,CAAC,CAAE,QAAO,QAAO,CAAC,EAAGC,GAAe,MAAM,EAK/E,GAHAzB,EAAK,WAAW,KAAKqB,EAASC,EAAI,EAAIb,EAAI,MAAM,EAAGY,EAASC,EAAI,EAAIb,EAAI,MAAM,EAAGW,EAAK,MAAOA,EAAK,MAAM,EACxG,UAAUX,CAAG,EAETT,EAAK,QAAS,CAChB,IAAM2B,EAAM,CACV,MAAO3B,EAAK,OAAO,CAAC,CAACS,EAAI,aACzB,KAAMmB,EAAO,KACb,MAAOH,EAAcA,EAAY1B,EAAM,MAAOA,EAAO6B,CAAM,EAAI,OAAO7B,EAAM,KAAK,CACnF,EAEAC,EAAK,QAAQ,KACXS,EAAI,MAAM,EAAIT,EAAK,OAAO,KAC1BS,EAAI,MAAM,EAAIT,EAAK,OAAO,IAC1BD,EACA6B,EACAvC,EAAAA,kBAAkBW,EAAK,IAAI,cAAewB,EAAO,CAACG,CAAG,EAAGD,CAAM,CAChE,CACF,MACE1B,EAAK,UAAU,SAAS0B,CAAM,EAGhC,EAAS,GACT1B,EAAK,UAAUK,CAAK,CACtB,EAEM,WAAc,GAAuD,CACzE,IAAMwB,EAAW,YAAYxB,CAAK,EAElC,GAAIwB,EAAU,MAAO,CAAE,IAAKA,EAAU,IAAKA,EAAS,KAAM,EAE1D,IAAMV,EAAOnB,EAAK,KAAK,EACjBsB,EAAMhC,EAAAA,iBAAiBU,EAAK,IAAKK,EAAOL,EAAK,OAAO,KAAMA,EAAK,OAAO,GAAG,EACzEoB,EAAOlC,EAAAA,UAAUiC,EAAK,MAAOA,EAAK,OAAQnB,EAAK,MAAM,EAE3D,GAAIsB,EAAI,EAAI,GAAKA,EAAI,EAAIF,EAAK,OAASE,EAAI,EAAI,GAAKA,EAAI,EAAIF,EAAK,OAAQ,OAAO,KAEhF,IAAMX,EAAM,WAAWa,CAAG,EAE1B,OAAOb,EAAM,CAAE,MAAK,KAAI,EAAI,IAC9B,EAEM,YAAe,GAA4B,CAC/C,IAAMqB,EAAQ,WAAWzB,CAAK,EAE1ByB,EAAO,MAAMA,EAAM,IAAKA,EAAM,IAAKzB,CAAK,EACnCP,GAAQ,MAAM,CACzB,EAEM,QAAW,GAA4B,CAC3C,GAAI,CAACE,EAAK,QAAS,OAEnB,IAAM8B,EAAQ,WAAWzB,CAAK,EAE1ByB,GAAO9B,EAAK,QAAQ,SAAS8B,EAAM,IAAKzB,CAAK,CAAC,CACpD,EAEM,UAAa,GAA+B,CAChD,IAAMO,EAAO,YAAY,EAEzB,GAAIA,EAAK,SAAW,EAAG,OAEvB,IAAMmB,EAAOnB,EAAK,OAAS,EACrBR,EAAiC,CACrC,UAAWP,EAAgB,EAAIkC,EAAO,KAAK,IAAI,EAAGlC,EAAgB,CAAC,EACnE,WAAYA,EAAgB,EAAI,EAAI,KAAK,IAAIkC,EAAMlC,EAAgB,CAAC,EACpE,IAAKkC,EACL,KAAM,CACR,EAEI1B,EAAM,OAAOD,GACfC,EAAM,eAAe,EACrB,EAAgBD,EAAOC,EAAM,KAC7B,MAAMO,EAAKf,GAAgB,KAAMQ,CAAK,IAC5BA,EAAM,MAAQ,SAAWA,EAAM,MAAQ,MAAQR,GAAiB,GAAKG,EAAK,SACpFK,EAAM,eAAe,EACrBL,EAAK,QAAQ,SAASY,EAAKf,GAAgBQ,CAAK,CAAC,GACxCA,EAAM,MAAQ,WACvB,EAAgB,GAChB,MAAM,EAEV,EAEA,MAAO,CAAE,QAAS,UAAW,aAAc,MAAO,WAAY,CAChE,C"}
1
+ {"version":3,"file":"scatter-interaction.cjs","names":["createSvgElement","chartArea","keyLabel","describeValues","comparisonContent","getMousePosition","require_layout","require_element","require_announcer","require_events","require_series_interaction","require_tooltip","keyboardIndex","active","datum","opts","seriesIndex","pointIndex","point","target","event","best","minDistance","points","hit","distance","pos","hits","data","a","b","groups","index","group","dims","area","follow","raw","originalEvent","label","valueFormat","spoken","row","series","rendered","found","last"],"sources":["../../src/interaction/scatter-interaction.ts"],"sourcesContent":["import type { ChartEventHandlers } from '../core/chart-scaffold';\nimport { chartArea } from '../core/layout';\nimport { createSvgElement } from '../svg/element';\nimport type { Point } from '../svg/path';\nimport type { ChartDimensions, ChartEvent, ChartMargin, ContinuousDatum, Series, TooltipConfig } from '../types';\nimport { type Announcer, describeValues } from './announcer';\nimport type { CrosshairState } from './crosshair';\nimport { getMousePosition } from './events';\nimport { keyLabel } from './series-interaction';\nimport { comparisonContent, type TooltipState } from './tooltip';\n\nexport interface ScatterInteractionOptions {\n announcer: Announcer;\n colors: () => string[];\n crosshair?: CrosshairState | null;\n dims: () => ChartDimensions;\n /** Per-series data, parallel to `getPoints`; each datum is one independent point. */\n getData: () => ContinuousDatum[][];\n getPoints: () => Point[][];\n getSeriesList: () => Series[];\n /** Effective chart margin: hit bounds and tooltip offsets use this, never the shared dimensions. */\n margin: ChartMargin;\n /** Receives the single active-point marker. */\n markers: SVGGElement;\n onClick?: ((event: ChartEvent) => void) | undefined;\n onHover?: ((event: ChartEvent | null) => void) | undefined;\n /** Parent of the per-series point groups; the active series is emphasised and the rest dim. */\n seriesGroup: SVGGElement;\n svg: SVGSVGElement;\n tooltip?: TooltipState | null;\n /** Value/title formatters from the tooltip config, applied to the row and spoken text alike. */\n tooltipFormat?: Pick<TooltipConfig, 'titleFormat' | 'valueFormat'>;\n}\n\ninterface Hit {\n datum: ContinuousDatum;\n point: Point;\n seriesIndex: number;\n}\n\n/**\n * Pointer and keyboard interaction for a scatter plot. A scatter point is an\n * independent `(x, y)` pair rather than one sample at a shared key, so the active\n * point is the one nearest the pointer in two dimensions, events carry no\n * cross-series `values`, and keyboard navigation walks every point in x order.\n */\nexport function createScatterInteraction(opts: ScatterInteractionOptions): ChartEventHandlers {\n let keyboardIndex = -1;\n let active = false;\n\n const hitAt = (seriesIndex: number, pointIndex: number): Hit | null => {\n const datum = opts.getData()[seriesIndex]?.[pointIndex];\n const point = opts.getPoints()[seriesIndex]?.[pointIndex];\n\n return datum && point ? { datum, point, seriesIndex } : null;\n };\n\n const renderedHit = (event: Event): Hit | null => {\n const target = event.target;\n\n if (\n !(target instanceof SVGElement) ||\n !target.classList.contains('prism-scatter-point') ||\n !target.parentElement ||\n target.parentElement.parentNode !== opts.seriesGroup\n )\n return null;\n\n return hitAt(\n [...opts.seriesGroup.children].indexOf(target.parentElement),\n [...target.parentElement.children].indexOf(target),\n );\n };\n\n const nearestHit = (pos: Point): Hit | null => {\n let best: Hit | null = null;\n let minDistance = Infinity;\n\n for (const [seriesIndex, points] of opts.getPoints().entries()) {\n for (const pointIndex of points.keys()) {\n const hit = hitAt(seriesIndex, pointIndex);\n\n if (!hit) continue;\n\n const distance = Math.hypot(hit.point.x - pos.x, hit.point.y - pos.y);\n\n if (distance < minDistance) {\n minDistance = distance;\n best = hit;\n }\n }\n }\n\n return best;\n };\n\n // Every point across every series in x order (then y, then series order), for keyboard traversal.\n const orderedHits = (): Hit[] => {\n const hits: Hit[] = [];\n\n for (const [seriesIndex, data] of opts.getData().entries()) {\n for (const pointIndex of data.keys()) {\n const hit = hitAt(seriesIndex, pointIndex);\n\n if (hit) hits.push(hit);\n }\n }\n\n return hits.sort((a, b) => a.point.x - b.point.x || a.point.y - b.point.y || a.seriesIndex - b.seriesIndex);\n };\n\n const eventFor = (hit: Hit, originalEvent: Event): ChartEvent => ({\n datum: hit.datum,\n originalEvent,\n series: opts.getSeriesList()[hit.seriesIndex],\n });\n\n const highlight = (hit: Hit | null): void => {\n const groups = [...opts.seriesGroup.children];\n\n opts.markers.replaceChildren();\n\n if (hit) {\n opts.markers.appendChild(\n createSvgElement('circle', {\n class: 'prism-active-point',\n cx: hit.point.x,\n cy: hit.point.y,\n fill: opts.colors()[hit.seriesIndex],\n r: 4,\n }),\n );\n }\n\n opts.seriesGroup.classList.toggle('prism-series-focused', hit !== null && groups.length > 1);\n for (const [index, group] of groups.entries())\n group.classList.toggle('prism-series-active', index === hit?.seriesIndex);\n };\n\n const clear = (): void => {\n opts.crosshair?.hide();\n opts.tooltip?.hide();\n opts.announcer.clear();\n highlight(null);\n active = false;\n opts.onHover?.(null);\n };\n\n const focus = (hit: Hit, raw: Point | null, originalEvent: Event): void => {\n const dims = opts.dims();\n const area = chartArea(dims.width, dims.height, opts.margin);\n const follow = opts.crosshair?.snap === false && raw;\n const event = eventFor(hit, originalEvent);\n const { datum, series } = event;\n const label = opts.tooltipFormat?.titleFormat ? opts.tooltipFormat.titleFormat(datum.key) : keyLabel(datum.key);\n const valueFormat = opts.tooltipFormat?.valueFormat;\n const spoken = describeValues(label, [{ datum, series }], valueFormat ?? String);\n\n opts.crosshair?.show(follow ? raw.x : hit.point.x, follow ? raw.y : hit.point.y, area.width, area.height);\n highlight(hit);\n\n if (opts.tooltip) {\n const row = {\n color: opts.colors()[hit.seriesIndex],\n name: series.name,\n value: valueFormat ? valueFormat(datum.value, datum, series) : String(datum.value),\n };\n\n opts.tooltip.show(\n hit.point.x + opts.margin.left,\n hit.point.y + opts.margin.top,\n datum,\n series,\n comparisonContent(opts.svg.ownerDocument, label, [row], spoken),\n );\n } else {\n opts.announcer.announce(spoken);\n }\n\n active = true;\n opts.onHover?.(event);\n };\n\n const pointerHit = (event: MouseEvent): { hit: Hit; raw: Point } | null => {\n const rendered = renderedHit(event);\n\n if (rendered) return { hit: rendered, raw: rendered.point };\n\n const dims = opts.dims();\n const raw = getMousePosition(opts.svg, event, opts.margin.left, opts.margin.top);\n const area = chartArea(dims.width, dims.height, opts.margin);\n\n if (raw.x < 0 || raw.x > area.width || raw.y < 0 || raw.y > area.height) return null;\n\n const hit = nearestHit(raw);\n\n return hit ? { hit, raw } : null;\n };\n\n const onMouseMove = (event: MouseEvent): void => {\n const found = pointerHit(event);\n\n if (found) focus(found.hit, found.raw, event);\n else if (active) clear();\n };\n\n const onClick = (event: MouseEvent): void => {\n if (!opts.onClick) return;\n\n const found = pointerHit(event);\n\n if (found) opts.onClick(eventFor(found.hit, event));\n };\n\n const onKeyDown = (event: KeyboardEvent): void => {\n const hits = orderedHits();\n\n if (hits.length === 0) return;\n\n const last = hits.length - 1;\n const target: Record<string, number> = {\n ArrowLeft: keyboardIndex < 0 ? last : Math.max(0, keyboardIndex - 1),\n ArrowRight: keyboardIndex < 0 ? 0 : Math.min(last, keyboardIndex + 1),\n End: last,\n Home: 0,\n };\n\n if (event.key in target) {\n event.preventDefault();\n keyboardIndex = target[event.key];\n focus(hits[keyboardIndex], null, event);\n } else if ((event.key === 'Enter' || event.key === ' ') && keyboardIndex >= 0 && opts.onClick) {\n event.preventDefault();\n opts.onClick(eventFor(hits[keyboardIndex], event));\n } else if (event.key === 'Escape') {\n keyboardIndex = -1;\n clear();\n }\n };\n\n return { onClick, onKeyDown, onMouseLeave: clear, onMouseMove };\n}\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
- import { createSvgElement as e } from "../svg/element.js";
2
- import { describeValues as t } from "./announcer.js";
3
- import { comparisonContent as n } from "./tooltip.js";
4
- import { chartArea as r } from "../core/layout.js";
5
- import { getMousePosition as i } from "./events.js";
6
- import { keyLabel as a } from "./series-interaction.js";
7
- //#region src/interaction/scatter-interaction.ts
1
+ import { chartArea as e } from "../core/layout.js";
2
+ import { createSvgElement as t } from "../svg/element.js";
3
+ import { describeValues as n } from "./announcer.js";
4
+ import { getMousePosition as r } from "./events.js";
5
+ import { keyLabel as i } from "./series-interaction.js";
6
+ import { comparisonContent as a } from "./tooltip.js";
7
+ // src/interaction/scatter-interaction.ts
8
8
  function createScatterInteraction(o) {
9
9
  let s = -1, c = !1, hitAt = (e, t) => {
10
10
  let n = o.getData()[e]?.[t], r = o.getPoints()[e]?.[t];
@@ -36,39 +36,39 @@ function createScatterInteraction(o) {
36
36
  datum: e.datum,
37
37
  originalEvent: t,
38
38
  series: o.getSeriesList()[e.seriesIndex]
39
- }), highlight = (t) => {
39
+ }), highlight = (e) => {
40
40
  let n = [...o.seriesGroup.children];
41
- o.markers.replaceChildren(), t && o.markers.appendChild(e("circle", {
41
+ o.markers.replaceChildren(), e && o.markers.appendChild(t("circle", {
42
42
  class: "prism-active-point",
43
- cx: t.point.x,
44
- cy: t.point.y,
45
- fill: o.colors()[t.seriesIndex],
43
+ cx: e.point.x,
44
+ cy: e.point.y,
45
+ fill: o.colors()[e.seriesIndex],
46
46
  r: 4
47
- })), o.seriesGroup.classList.toggle("prism-series-focused", t !== null && n.length > 1);
48
- for (let [e, r] of n.entries()) r.classList.toggle("prism-series-active", e === t?.seriesIndex);
47
+ })), o.seriesGroup.classList.toggle("prism-series-focused", e !== null && n.length > 1);
48
+ for (let [t, r] of n.entries()) r.classList.toggle("prism-series-active", t === e?.seriesIndex);
49
49
  }, clear = () => {
50
50
  o.crosshair?.hide(), o.tooltip?.hide(), o.announcer.clear(), highlight(null), c = !1, o.onHover?.(null);
51
- }, focus = (e, i, s) => {
52
- let l = o.dims(), u = r(l.width, l.height, o.margin), d = o.crosshair?.snap === !1 && i, f = eventFor(e, s), { datum: p, series: m } = f, h = o.tooltipFormat?.titleFormat ? o.tooltipFormat.titleFormat(p.key) : a(p.key), g = o.tooltipFormat?.valueFormat, _ = t(h, [{
51
+ }, focus = (t, r, s) => {
52
+ let l = o.dims(), u = e(l.width, l.height, o.margin), d = o.crosshair?.snap === !1 && r, f = eventFor(t, s), { datum: p, series: m } = f, h = o.tooltipFormat?.titleFormat ? o.tooltipFormat.titleFormat(p.key) : i(p.key), g = o.tooltipFormat?.valueFormat, _ = n(h, [{
53
53
  datum: p,
54
54
  series: m
55
55
  }], g ?? String);
56
- if (o.crosshair?.show(d ? i.x : e.point.x, d ? i.y : e.point.y, u.width, u.height), highlight(e), o.tooltip) {
57
- let t = {
58
- color: o.colors()[e.seriesIndex],
56
+ if (o.crosshair?.show(d ? r.x : t.point.x, d ? r.y : t.point.y, u.width, u.height), highlight(t), o.tooltip) {
57
+ let e = {
58
+ color: o.colors()[t.seriesIndex],
59
59
  name: m.name,
60
60
  value: g ? g(p.value, p, m) : String(p.value)
61
61
  };
62
- o.tooltip.show(e.point.x + o.margin.left, e.point.y + o.margin.top, p, m, n(o.svg.ownerDocument, h, [t], _));
62
+ o.tooltip.show(t.point.x + o.margin.left, t.point.y + o.margin.top, p, m, a(o.svg.ownerDocument, h, [e], _));
63
63
  } else o.announcer.announce(_);
64
64
  c = !0, o.onHover?.(f);
65
- }, pointerHit = (e) => {
66
- let t = renderedHit(e);
67
- if (t) return {
68
- hit: t,
69
- raw: t.point
65
+ }, pointerHit = (t) => {
66
+ let n = renderedHit(t);
67
+ if (n) return {
68
+ hit: n,
69
+ raw: n.point
70
70
  };
71
- let n = o.dims(), a = i(o.svg, e, o.margin.left, o.margin.top), s = r(n.width, n.height, o.margin);
71
+ let i = o.dims(), a = r(o.svg, t, o.margin.left, o.margin.top), s = e(i.width, i.height, o.margin);
72
72
  if (a.x < 0 || a.x > s.width || a.y < 0 || a.y > s.height) return null;
73
73
  let c = nearestHit(a);
74
74
  return c ? {
@@ -100,7 +100,6 @@ function createScatterInteraction(o) {
100
100
  onMouseMove
101
101
  };
102
102
  }
103
- //#endregion
104
103
  export { createScatterInteraction };
105
104
 
106
105
  //# sourceMappingURL=scatter-interaction.js.map
@@ -1,2 +1,2 @@
1
- const e=require("../svg/element.cjs"),t=require("./announcer.cjs"),n=require("./tooltip.cjs"),r=require("../core/layout.cjs"),i=require("../core/cartesian-model.cjs"),a=require("./events.cjs");var keyOrder=e=>e instanceof Date?e.getTime():Number(e);function keyLabel(e){return e instanceof Date?e.toLocaleDateString():String(e)}function findNearestKey(e,t,n){let r=null,i=1/0;for(let a=0;a<t.length;a++)for(let o=0;o<(t[a]?.length??0);o++){let s=e[a]?.[o],c=t[a]?.[o];if(!s||!c)continue;let l=Math.abs(c.x-n);l<i&&(i=l,r=s.key)}return r}function createSeriesInteraction(o){let s=-1,c=!1,renderedHit=e=>{let t=e.target;if(!(t instanceof SVGElement)||t.tagName.toLowerCase()!==`circle`||!o.seriesGroup.contains(t)||!t.parentElement)return null;let n=t.parentElement;for(;n&&n.parentNode!==o.seriesGroup;)n=n.parentElement;if(!n)return null;let r=[...o.seriesGroup.children].indexOf(n),i=[...t.parentElement.children].indexOf(t),a=o.getData()[r]?.[i],s=o.getPoints()[r]?.[i];return a&&s?{datum:a,point:s,seriesIndex:r}:null},entriesAt=e=>{let t=i.keyId(e),n=o.getPoints();return o.getData().map((e,r)=>{let a=e.findIndex(e=>i.keyId(e.key)===t);return a===-1?{datum:void 0,point:void 0}:{datum:e[a],point:n[r]?.[a]}})},nearestIndex=(e,t)=>{let n=-1,r=1/0;return e.forEach(({point:e},i)=>{if(!e)return;let a=Number.isFinite(t)?Math.abs(e.y-t):0;a<r&&(r=a,n=i)}),n},highlight=(t,n)=>{let r=o.colors();o.markers.replaceChildren(),t.forEach(({point:t},n)=>{t&&o.markers.appendChild(e.createSvgElement(`circle`,{class:`prism-active-point`,cx:t.x,cy:t.y,fill:r[n],r:4}))});let i=[...o.seriesGroup.children];o.seriesGroup.classList.toggle(`prism-series-focused`,n>=0&&i.length>1);for(let[e,t]of i.entries())t.classList.toggle(`prism-series-active`,e===n)},clear=()=>{o.crosshair?.hide(),o.tooltip?.hide(),o.announcer.clear(),highlight([],-1),c=!1,o.onHover?.(null)},eventFor=(e,t,n)=>{let r=entriesAt(e),i=renderedHit(n),a=i?.seriesIndex??nearestIndex(r,t);i&&(r[a]={datum:i.datum,point:i.point});let s=o.getSeriesList(),c=r[a]?.datum;if(a<0||!c)return null;let l=r.map((e,t)=>({datum:e.datum,series:s[t]}));return{entries:r,event:{datum:c,originalEvent:n,series:s[a],values:l},index:a}},focus=(e,i,a)=>{let s=eventFor(e,i?.y??NaN,a);if(!s)return;let{entries:l,event:u,index:d}=s,f=l[d].point,p=o.dims(),m=r.chartArea(p.width,p.height,o.margin),h=o.crosshair?.snap===!1&&i,g=o.tooltipFormat?.titleFormat?o.tooltipFormat.titleFormat(e):keyLabel(e),_=u.values??[],v=o.colors(),y=o.tooltipFormat?.valueFormat;o.crosshair?.show(h?i.x:f.x,h?i.y:f.y,m.width,m.height),highlight(l,d);let b=t.describeValues(g,_,y??String);if(o.tooltip){let e=_.flatMap(({datum:e,series:t},n)=>e?[{color:v[n],name:t.name,value:y?y(e.value,e,t):String(e.value)}]:[]);o.tooltip.show(f.x+o.margin.left,f.y+o.margin.top,u.datum,u.series,n.comparisonContent(o.svg.ownerDocument,g,e,b))}else o.announcer.announce(b);c=!0,o.onHover?.(u)},pointerKey=e=>{let t=renderedHit(e);if(t)return{key:t.datum.key,pos:t.point};let n=o.getPoints();if(n.every(e=>e.length===0))return null;let i=o.dims(),s=a.getMousePosition(o.svg,e,o.margin.left,o.margin.top),c=r.chartArea(i.width,i.height,o.margin);if(s.x<0||s.x>c.width||s.y<0||s.y>c.height)return null;let l=findNearestKey(o.getData(),n,s.x);return l===null?null:{key:l,pos:s}},sortedKeys=()=>[...new Map(o.getData().flat().map(e=>[i.keyId(e.key),e.key])).values()].sort((e,t)=>keyOrder(e)-keyOrder(t)),onMouseMove=e=>{let t=pointerKey(e);t?focus(t.key,t.pos,e):c&&clear()},onClick=e=>{if(!o.onClick)return;let t=pointerKey(e),n=t&&eventFor(t.key,t.pos.y,e);n&&o.onClick(n.event)},onKeyDown=e=>{let t=sortedKeys();if(t.length===0)return;let n=t.length-1,r={ArrowLeft:s<0?n:Math.max(0,s-1),ArrowRight:s<0?0:Math.min(n,s+1),End:n,Home:0};if(e.key in r)e.preventDefault(),s=r[e.key],focus(t[s],null,e);else if((e.key===`Enter`||e.key===` `)&&s>=0&&o.onClick){e.preventDefault();let n=eventFor(t[s],NaN,e);n&&o.onClick(n.event)}else e.key===`Escape`&&(s=-1,clear())};return{onClick,onKeyDown,onMouseLeave:clear,onMouseMove}}function ensureMarkerGroup(t,n){if(n&&t.contains(n))return n;let r=e.createSvgElement(`g`,{"aria-hidden":`true`,class:`prism-active-points`,"pointer-events":`none`});return t.appendChild(r),r}exports.createSeriesInteraction=createSeriesInteraction,exports.ensureMarkerGroup=ensureMarkerGroup,exports.keyLabel=keyLabel;
1
+ const e=require("../core/cartesian-model.cjs"),t=require("../core/layout.cjs"),n=require("../svg/element.cjs"),r=require("./announcer.cjs"),i=require("./events.cjs"),a=require("./tooltip.cjs");var keyOrder=e=>e instanceof Date?e.getTime():Number(e);function keyLabel(e){return e instanceof Date?e.toLocaleDateString():String(e)}function findNearestKey(e,t,n){let r=null,i=1/0;for(let a=0;a<t.length;a++)for(let o=0;o<(t[a]?.length??0);o++){let s=e[a]?.[o],c=t[a]?.[o];if(!s||!c)continue;let l=Math.abs(c.x-n);l<i&&(i=l,r=s.key)}return r}function createSeriesInteraction(o){let s=-1,c=!1,renderedHit=e=>{let t=e.target;if(!(t instanceof SVGElement)||t.tagName.toLowerCase()!==`circle`||!o.seriesGroup.contains(t)||!t.parentElement)return null;let n=t.parentElement;for(;n&&n.parentNode!==o.seriesGroup;)n=n.parentElement;if(!n)return null;let r=[...o.seriesGroup.children].indexOf(n),i=[...t.parentElement.children].indexOf(t),a=o.getData()[r]?.[i],s=o.getPoints()[r]?.[i];return a&&s?{datum:a,point:s,seriesIndex:r}:null},entriesAt=t=>{let n=e.keyId(t),r=o.getPoints();return o.getData().map((t,i)=>{let a=t.findIndex(t=>e.keyId(t.key)===n);return a===-1?{datum:void 0,point:void 0}:{datum:t[a],point:r[i]?.[a]}})},nearestIndex=(e,t)=>{let n=-1,r=1/0;return e.forEach(({point:e},i)=>{if(!e)return;let a=Number.isFinite(t)?Math.abs(e.y-t):0;a<r&&(r=a,n=i)}),n},highlight=(e,t)=>{let r=o.colors();o.markers.replaceChildren(),e.forEach(({point:e},t)=>{e&&o.markers.appendChild(n.createSvgElement(`circle`,{class:`prism-active-point`,cx:e.x,cy:e.y,fill:r[t],r:4}))});let i=[...o.seriesGroup.children];o.seriesGroup.classList.toggle(`prism-series-focused`,t>=0&&i.length>1);for(let[e,n]of i.entries())n.classList.toggle(`prism-series-active`,e===t)},clear=()=>{o.crosshair?.hide(),o.tooltip?.hide(),o.announcer.clear(),highlight([],-1),c=!1,o.onHover?.(null)},eventFor=(e,t,n)=>{let r=entriesAt(e),i=renderedHit(n),a=i?.seriesIndex??nearestIndex(r,t);i&&(r[a]={datum:i.datum,point:i.point});let s=o.getSeriesList(),c=r[a]?.datum;if(a<0||!c)return null;let l=r.map((e,t)=>({datum:e.datum,series:s[t]}));return{entries:r,event:{datum:c,originalEvent:n,series:s[a],values:l},index:a}},focus=(e,n,i)=>{let s=eventFor(e,n?.y??NaN,i);if(!s)return;let{entries:l,event:u,index:d}=s,f=l[d].point,p=o.dims(),m=t.chartArea(p.width,p.height,o.margin),h=o.crosshair?.snap===!1&&n,g=o.tooltipFormat?.titleFormat?o.tooltipFormat.titleFormat(e):keyLabel(e),_=u.values??[],v=o.colors(),y=o.tooltipFormat?.valueFormat;o.crosshair?.show(h?n.x:f.x,h?n.y:f.y,m.width,m.height),highlight(l,d);let b=r.describeValues(g,_,y??String);if(o.tooltip){let e=_.flatMap(({datum:e,series:t},n)=>e?[{color:v[n],name:t.name,value:y?y(e.value,e,t):String(e.value)}]:[]);o.tooltip.show(f.x+o.margin.left,f.y+o.margin.top,u.datum,u.series,a.comparisonContent(o.svg.ownerDocument,g,e,b))}else o.announcer.announce(b);c=!0,o.onHover?.(u)},pointerKey=e=>{let n=renderedHit(e);if(n)return{key:n.datum.key,pos:n.point};let r=o.getPoints();if(r.every(e=>e.length===0))return null;let a=o.dims(),s=i.getMousePosition(o.svg,e,o.margin.left,o.margin.top),c=t.chartArea(a.width,a.height,o.margin);if(s.x<0||s.x>c.width||s.y<0||s.y>c.height)return null;let l=findNearestKey(o.getData(),r,s.x);return l===null?null:{key:l,pos:s}},sortedKeys=()=>[...new Map(o.getData().flat().map(t=>[e.keyId(t.key),t.key])).values()].sort((e,t)=>keyOrder(e)-keyOrder(t)),onMouseMove=e=>{let t=pointerKey(e);t?focus(t.key,t.pos,e):c&&clear()},onClick=e=>{if(!o.onClick)return;let t=pointerKey(e),n=t&&eventFor(t.key,t.pos.y,e);n&&o.onClick(n.event)},onKeyDown=e=>{let t=sortedKeys();if(t.length===0)return;let n=t.length-1,r={ArrowLeft:s<0?n:Math.max(0,s-1),ArrowRight:s<0?0:Math.min(n,s+1),End:n,Home:0};if(e.key in r)e.preventDefault(),s=r[e.key],focus(t[s],null,e);else if((e.key===`Enter`||e.key===` `)&&s>=0&&o.onClick){e.preventDefault();let n=eventFor(t[s],NaN,e);n&&o.onClick(n.event)}else e.key===`Escape`&&(s=-1,clear())};return{onClick,onKeyDown,onMouseLeave:clear,onMouseMove}}function ensureMarkerGroup(e,t){if(t&&e.contains(t))return t;let r=n.createSvgElement(`g`,{"aria-hidden":`true`,class:`prism-active-points`,"pointer-events":`none`});return e.appendChild(r),r}exports.createSeriesInteraction=createSeriesInteraction,exports.ensureMarkerGroup=ensureMarkerGroup,exports.keyLabel=keyLabel;
2
2
  //# sourceMappingURL=series-interaction.cjs.map