@vielzeug/prism 26.10.14 → 26.10.16

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 (162) hide show
  1. package/dist/_dev.cjs.map +1 -1
  2. package/dist/_dev.js +6 -1
  3. package/dist/_dev.js.map +1 -1
  4. package/dist/_tappers.cjs.map +1 -1
  5. package/dist/_tappers.js +25 -1
  6. package/dist/_tappers.js.map +1 -1
  7. package/dist/animation/easing.cjs.map +1 -1
  8. package/dist/animation/easing.js +15 -1
  9. package/dist/animation/easing.js.map +1 -1
  10. package/dist/animation/motion.cjs.map +1 -1
  11. package/dist/animation/motion.js +15 -1
  12. package/dist/animation/motion.js.map +1 -1
  13. package/dist/animation/reveal.cjs.map +1 -1
  14. package/dist/animation/reveal.js +97 -1
  15. package/dist/animation/reveal.js.map +1 -1
  16. package/dist/animation/transition.cjs.map +1 -1
  17. package/dist/animation/transition.js +39 -1
  18. package/dist/animation/transition.js.map +1 -1
  19. package/dist/animation/tween.cjs.map +1 -1
  20. package/dist/animation/tween.js +7 -1
  21. package/dist/animation/tween.js.map +1 -1
  22. package/dist/axes/axis.cjs.map +1 -1
  23. package/dist/axes/axis.js +76 -1
  24. package/dist/axes/axis.js.map +1 -1
  25. package/dist/axes/grid.cjs.map +1 -1
  26. package/dist/axes/grid.js +29 -1
  27. package/dist/axes/grid.js.map +1 -1
  28. package/dist/axes/scale-utils.cjs.map +1 -1
  29. package/dist/axes/scale-utils.js +10 -1
  30. package/dist/axes/scale-utils.js.map +1 -1
  31. package/dist/charts/area/area-chart.cjs.map +1 -1
  32. package/dist/charts/area/area-chart.js +71 -1
  33. package/dist/charts/area/area-chart.js.map +1 -1
  34. package/dist/charts/area/area-renderer.cjs.map +1 -1
  35. package/dist/charts/area/area-renderer.js +128 -1
  36. package/dist/charts/area/area-renderer.js.map +1 -1
  37. package/dist/charts/bar/bar-chart.cjs.map +1 -1
  38. package/dist/charts/bar/bar-chart.js +228 -1
  39. package/dist/charts/bar/bar-chart.js.map +1 -1
  40. package/dist/charts/bar/bar-hit-test.cjs.map +1 -1
  41. package/dist/charts/bar/bar-hit-test.js +25 -1
  42. package/dist/charts/bar/bar-hit-test.js.map +1 -1
  43. package/dist/charts/bar/bar-renderer.cjs.map +1 -1
  44. package/dist/charts/bar/bar-renderer.js +139 -1
  45. package/dist/charts/bar/bar-renderer.js.map +1 -1
  46. package/dist/charts/line/line-chart.cjs.map +1 -1
  47. package/dist/charts/line/line-chart.js +93 -1
  48. package/dist/charts/line/line-chart.js.map +1 -1
  49. package/dist/charts/line/line-renderer.cjs.map +1 -1
  50. package/dist/charts/line/line-renderer.js +143 -1
  51. package/dist/charts/line/line-renderer.js.map +1 -1
  52. package/dist/charts/pie/pie-chart.cjs +1 -1
  53. package/dist/charts/pie/pie-chart.cjs.map +1 -1
  54. package/dist/charts/pie/pie-chart.js +207 -1
  55. package/dist/charts/pie/pie-chart.js.map +1 -1
  56. package/dist/charts/pie/pie-renderer.cjs.map +1 -1
  57. package/dist/charts/pie/pie-renderer.js +68 -1
  58. package/dist/charts/pie/pie-renderer.js.map +1 -1
  59. package/dist/charts/radar/radar-chart.cjs +1 -1
  60. package/dist/charts/radar/radar-chart.cjs.map +1 -1
  61. package/dist/charts/radar/radar-chart.js +281 -1
  62. package/dist/charts/radar/radar-chart.js.map +1 -1
  63. package/dist/charts/radar/radar-geometry.cjs.map +1 -1
  64. package/dist/charts/radar/radar-geometry.js +69 -1
  65. package/dist/charts/radar/radar-geometry.js.map +1 -1
  66. package/dist/charts/scatter/scatter-chart.cjs.map +1 -1
  67. package/dist/charts/scatter/scatter-chart.js +69 -1
  68. package/dist/charts/scatter/scatter-chart.js.map +1 -1
  69. package/dist/charts/scatter/scatter-renderer.cjs.map +1 -1
  70. package/dist/charts/scatter/scatter-renderer.js +57 -1
  71. package/dist/charts/scatter/scatter-renderer.js.map +1 -1
  72. package/dist/charts/sparkline/sparkline.cjs +1 -1
  73. package/dist/charts/sparkline/sparkline.cjs.map +1 -1
  74. package/dist/charts/sparkline/sparkline.js +251 -1
  75. package/dist/charts/sparkline/sparkline.js.map +1 -1
  76. package/dist/core/cartesian-model.cjs +1 -1
  77. package/dist/core/cartesian-model.cjs.map +1 -1
  78. package/dist/core/cartesian-model.js +26 -1
  79. package/dist/core/cartesian-model.js.map +1 -1
  80. package/dist/core/cartesian-scales.cjs.map +1 -1
  81. package/dist/core/cartesian-scales.js +38 -1
  82. package/dist/core/cartesian-scales.js.map +1 -1
  83. package/dist/core/chart-base.cjs.map +1 -1
  84. package/dist/core/chart-base.js +62 -1
  85. package/dist/core/chart-base.js.map +1 -1
  86. package/dist/core/chart-scaffold.cjs.map +1 -1
  87. package/dist/core/chart-scaffold.js +103 -1
  88. package/dist/core/chart-scaffold.js.map +1 -1
  89. package/dist/core/datum-style.cjs +1 -1
  90. package/dist/core/datum-style.cjs.map +1 -1
  91. package/dist/core/datum-style.js +22 -1
  92. package/dist/core/datum-style.js.map +1 -1
  93. package/dist/core/ids.cjs.map +1 -1
  94. package/dist/core/ids.js +8 -1
  95. package/dist/core/ids.js.map +1 -1
  96. package/dist/core/layout.cjs.map +1 -1
  97. package/dist/core/layout.js +22 -1
  98. package/dist/core/layout.js.map +1 -1
  99. package/dist/core/polar.cjs.map +1 -1
  100. package/dist/core/polar.js +13 -1
  101. package/dist/core/polar.js.map +1 -1
  102. package/dist/core/responsive.cjs.map +1 -1
  103. package/dist/core/responsive.js +20 -1
  104. package/dist/core/responsive.js.map +1 -1
  105. package/dist/core/series-id.cjs.map +1 -1
  106. package/dist/core/series-id.js +7 -1
  107. package/dist/core/series-id.js.map +1 -1
  108. package/dist/errors.cjs.map +1 -1
  109. package/dist/errors.js +9 -1
  110. package/dist/errors.js.map +1 -1
  111. package/dist/index.js +13 -1
  112. package/dist/interaction/announcer.cjs.map +1 -1
  113. package/dist/interaction/announcer.js +25 -1
  114. package/dist/interaction/announcer.js.map +1 -1
  115. package/dist/interaction/crosshair.cjs.map +1 -1
  116. package/dist/interaction/crosshair.js +37 -1
  117. package/dist/interaction/crosshair.js.map +1 -1
  118. package/dist/interaction/events.cjs.map +1 -1
  119. package/dist/interaction/events.js +11 -1
  120. package/dist/interaction/events.js.map +1 -1
  121. package/dist/interaction/legend.cjs.map +1 -1
  122. package/dist/interaction/legend.js +31 -1
  123. package/dist/interaction/legend.js.map +1 -1
  124. package/dist/interaction/scatter-interaction.cjs.map +1 -1
  125. package/dist/interaction/scatter-interaction.js +105 -1
  126. package/dist/interaction/scatter-interaction.js.map +1 -1
  127. package/dist/interaction/series-interaction.cjs.map +1 -1
  128. package/dist/interaction/series-interaction.js +163 -1
  129. package/dist/interaction/series-interaction.js.map +1 -1
  130. package/dist/interaction/tooltip.cjs +1 -1
  131. package/dist/interaction/tooltip.cjs.map +1 -1
  132. package/dist/interaction/tooltip.js +87 -1
  133. package/dist/interaction/tooltip.js.map +1 -1
  134. package/dist/prism.cjs +1 -1
  135. package/dist/prism.cjs.map +1 -1
  136. package/dist/prism.iife.js +1 -1
  137. package/dist/prism.iife.js.map +1 -1
  138. package/dist/prism.js +2930 -1
  139. package/dist/prism.js.map +1 -1
  140. package/dist/scales/band.cjs.map +1 -1
  141. package/dist/scales/band.js +39 -1
  142. package/dist/scales/band.js.map +1 -1
  143. package/dist/scales/linear.cjs.map +1 -1
  144. package/dist/scales/linear.js +43 -1
  145. package/dist/scales/linear.js.map +1 -1
  146. package/dist/scales/time.cjs.map +1 -1
  147. package/dist/scales/time.js +61 -1
  148. package/dist/scales/time.js.map +1 -1
  149. package/dist/svg/element.cjs +1 -1
  150. package/dist/svg/element.cjs.map +1 -1
  151. package/dist/svg/element.js +16 -1
  152. package/dist/svg/element.js.map +1 -1
  153. package/dist/svg/path.cjs.map +1 -1
  154. package/dist/svg/path.js +48 -1
  155. package/dist/svg/path.js.map +1 -1
  156. package/dist/svg/text.cjs.map +1 -1
  157. package/dist/svg/text.js +13 -1
  158. package/dist/svg/text.js.map +1 -1
  159. package/dist/theme/index.cjs.map +1 -1
  160. package/dist/theme/index.js +37 -1
  161. package/dist/theme/index.js.map +1 -1
  162. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"radar-chart.cjs","names":[],"sources":["../../../src/charts/radar/radar-chart.ts"],"sourcesContent":["import { devOnly, warn } from '../../_dev';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { startTween } from '../../animation/transition';\nimport { tweenNumber } from '../../animation/tween';\nimport type { ChartEventHandlers } from '../../core/chart-scaffold';\nimport { createRadialScaffold } from '../../core/chart-scaffold';\nimport { uniqueId } from '../../core/ids';\nimport { polarX, polarY } from '../../core/polar';\nimport { seriesDomId } from '../../core/series-id';\nimport { describeValues } from '../../interaction/announcer';\nimport { comparisonContent } from '../../interaction/tooltip';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { seriesColor } from '../../theme';\nimport type {\n ChartHandle,\n RadarAxisConfig,\n RadarAxisValue,\n RadarChartConfig,\n RadarEvent,\n RadarGridConfig,\n RadarSeriesConfig,\n} from '../../types';\nimport {\n axisAngles,\n closedPath,\n fitRadius,\n labelPlacement,\n nearestAxis,\n normalize,\n radarPoints,\n resolveAxisDomains,\n ringPath,\n toRadians,\n} from './radar-geometry';\n\n/** Default `--prism-font-size-label` (0.6875rem) in px, used to reserve label room. */\nconst LABEL_FONT_SIZE = 11;\nconst LABEL_GAP = 12;\nconst VALUE_OFFSET = 10;\nconst ARROW_STEPS: Record<string, number> = { ArrowDown: 1, ArrowLeft: -1, ArrowRight: 1, ArrowUp: -1 };\n\nfunction warnOnInvalid(axes: readonly RadarAxisConfig[], series: readonly RadarSeriesConfig[]): void {\n devOnly(() => {\n if (axes.length < 3) warn(`Radar chart needs at least 3 axes, received ${axes.length}.`);\n\n const keys = new Set(axes.map((axis) => axis.key));\n\n if (keys.size !== axes.length) warn('Radar chart axis keys must be unique.');\n\n for (const s of series) {\n for (const d of s.data) {\n if (!keys.has(d.key)) warn(`Radar series \"${s.name}\" has a value for unknown axis \"${d.key}\".`);\n }\n }\n });\n}\n\nfunction resolveGrid(grid: RadarChartConfig['grid']): Required<RadarGridConfig> | null {\n if (grid === false) return null;\n\n return { bands: true, labels: false, levels: 4, shape: 'polygon', ...(typeof grid === 'object' ? grid : {}) };\n}\n\nexport function createRadarChart(container: HTMLElement, config: RadarChartConfig): ChartHandle<RadarSeriesConfig[]> {\n const { axes } = config;\n const curve = config.curve ?? 'linear';\n const fill = config.fill ?? 'solid';\n const showPoints = config.showPoints ?? true;\n const grid = resolveGrid(config.grid);\n const startAngle = toRadians(config.startAngle ?? 0);\n const angles = axisAngles(axes.length, startAngle);\n const labelGap = LABEL_GAP + (config.showValues ? VALUE_OFFSET : 0);\n const id = uniqueId('prism-radar');\n let series = config.series;\n\n warnOnInvalid(axes, series);\n\n const root = createSvgElement('g', { class: 'prism-radar' });\n const defs = createSvgElement('defs');\n const gridGroup = createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-radar-grid' });\n const seriesGroup = createSvgElement('g', { class: 'prism-radar-series-group' });\n const labelGroup = createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-radar-labels' });\n\n root.append(defs, gridGroup, seriesGroup, labelGroup);\n\n let drawn: number[][] = [];\n let activeTween: (() => void) | null = null;\n let activeIndex = -1;\n let layout = { cx: 0, cy: 0, radius: 0 };\n\n const datumAt = (s: RadarSeriesConfig, index: number) => s.data.find((d) => d.key === axes[index].key);\n const valuesAt = (index: number): RadarAxisValue[] => series.map((s) => ({ datum: datumAt(s, index), series: s }));\n const formatValue = (index: number, value: number): string => axes[index].format?.(value) ?? String(value);\n const describe = (index: number): string =>\n describeValues(axes[index].label, valuesAt(index), (value) => formatValue(index, value));\n\n function draw(fractions: number[][]): void {\n const { cx, cy, radius } = layout;\n\n fractions.forEach((row, i) => {\n const group = seriesGroup.children[i];\n\n if (!group) return;\n\n const points = radarPoints(row, cx, cy, radius, angles);\n\n group.querySelector('.prism-radar-area')?.setAttribute('d', closedPath(points, curve));\n group.querySelectorAll<SVGCircleElement>('.prism-radar-point').forEach((dot, j) => {\n setAttributes(dot, { cx: points[j].x, cy: points[j].y });\n });\n group.querySelectorAll<SVGTextElement>('.prism-radar-value').forEach((text, j) => {\n const r = radius * row[j] + VALUE_OFFSET;\n\n setAttributes(text, { x: polarX(cx, r, angles[j]), y: polarY(cy, r, angles[j]) });\n });\n });\n }\n\n function renderGrid(domains: [number, number][]): void {\n gridGroup.replaceChildren();\n\n if (!grid) return;\n\n const { cx, cy, radius } = layout;\n const levels = Math.max(1, Math.round(grid.levels));\n const rings = Array.from({ length: levels }, (_, k) =>\n ringPath(grid.shape, cx, cy, (radius * (k + 1)) / levels, angles),\n );\n\n if (grid.bands) {\n // Shade alternate rings, starting from the outermost.\n for (let k = levels - 1; k >= 0; k -= 2) {\n gridGroup.appendChild(\n createSvgElement('path', {\n class: 'prism-radar-band',\n d: `${rings[k]}${rings[k - 1] ?? ''}`,\n 'fill-rule': 'evenodd',\n }),\n );\n }\n }\n\n for (const d of rings)\n gridGroup.appendChild(createSvgElement('path', { class: 'prism-radar-ring', d, fill: 'none' }));\n\n angles.forEach((angle, i) => {\n gridGroup.appendChild(\n createSvgElement('line', {\n class: 'prism-radar-spoke',\n 'data-axis': i,\n x1: cx,\n x2: polarX(cx, radius, angle),\n y1: cy,\n y2: polarY(cy, radius, angle),\n }),\n );\n });\n\n const [d0, d1] = domains[0];\n const shared = domains.every(([a, b]) => a === d0 && b === d1);\n\n if (!grid.labels || !shared) return;\n\n // Between the first two spokes, so level values never collide with vertex values.\n const angle = angles[0] + Math.PI / angles.length;\n\n for (let k = 1; k <= levels; k++) {\n const r = (radius * k) / levels;\n const text = createSvgElement('text', {\n class: 'prism-radar-level',\n 'dominant-baseline': 'middle',\n 'text-anchor': 'middle',\n x: polarX(cx, r, angle),\n y: polarY(cy, r, angle),\n });\n\n text.textContent = formatValue(0, Math.round((d0 + ((d1 - d0) * k) / levels) * 100) / 100);\n gridGroup.appendChild(text);\n }\n }\n\n function renderLabels(): void {\n labelGroup.replaceChildren();\n\n const { cx, cy, radius } = layout;\n\n axes.forEach((axis, i) => {\n const { anchor, baseline } = labelPlacement(angles[i]);\n const text = createSvgElement('text', {\n class: 'prism-radar-axis-label',\n 'dominant-baseline': baseline,\n 'text-anchor': anchor,\n x: polarX(cx, radius + labelGap, angles[i]),\n y: polarY(cy, radius + labelGap, angles[i]),\n });\n\n text.textContent = axis.label;\n labelGroup.appendChild(text);\n });\n }\n\n function renderSeries(): void {\n const { cx, cy, radius } = layout;\n\n defs.replaceChildren();\n\n while (seriesGroup.children.length > series.length) seriesGroup.lastChild?.remove();\n\n series.forEach((s, i) => {\n const color = s.color ?? seriesColor(i);\n let group = seriesGroup.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-radar-series' });\n seriesGroup.appendChild(group);\n }\n\n group.setAttribute('data-series-id', seriesDomId(s, i));\n\n group.replaceChildren();\n\n const area = createSvgElement('path', {\n class: `prism-radar-area prism-radar-area--${fill}`,\n stroke: color,\n 'stroke-linejoin': 'round',\n 'stroke-width': 2,\n });\n\n if (fill === 'gradient') {\n const gradientId = `${id}-fill-${i}`;\n const gradient = createSvgElement('radialGradient', {\n cx,\n cy,\n gradientUnits: 'userSpaceOnUse',\n id: gradientId,\n r: radius,\n });\n\n for (const [offset, opacity] of [\n [0, 0.08],\n [1, 0.55],\n ]) {\n gradient.appendChild(\n createSvgElement('stop', {\n offset,\n 'stop-color': color,\n 'stop-opacity': opacity,\n style: `stop-color:${color}`,\n }),\n );\n }\n\n defs.appendChild(gradient);\n setAttributes(area, { fill: `url(#${gradientId})` });\n } else {\n setAttributes(area, { fill: fill === 'none' ? 'none' : color, 'fill-opacity': 0.25 });\n }\n\n group.appendChild(area);\n\n if (showPoints) {\n axes.forEach((_, j) => {\n const missing = !Number.isFinite(datumAt(s, j)?.value);\n\n group.appendChild(\n createSvgElement('circle', {\n class: `prism-radar-point${missing ? ' prism-radar-point--missing' : ''}`,\n 'data-axis': j,\n fill: missing ? 'none' : color,\n r: 3,\n stroke: color,\n }),\n );\n });\n }\n\n if (config.showValues) {\n axes.forEach((_, j) => {\n const datum = datumAt(s, j);\n const { anchor, baseline } = labelPlacement(angles[j]);\n const text = createSvgElement('text', {\n 'aria-hidden': 'true',\n class: 'prism-radar-value',\n 'dominant-baseline': baseline,\n 'text-anchor': anchor,\n });\n\n text.textContent = datum && Number.isFinite(datum.value) ? formatValue(j, datum.value) : '';\n group.appendChild(text);\n });\n }\n });\n }\n\n function setActive(index: number): void {\n activeIndex = index;\n for (const el of root.querySelectorAll('[data-axis]')) {\n const active = Number(el.getAttribute('data-axis')) === index;\n\n el.classList.toggle(el.tagName === 'line' ? 'prism-radar-spoke--active' : 'prism-radar-point--active', active);\n }\n }\n\n function animateTo(targets: number[][], signal: AbortSignal): void {\n activeTween?.();\n\n const from = targets.map((row, i) => row.map((_, j) => drawn[i]?.[j] ?? 0));\n // Radar morphs a whole polygon, so it reads better slightly slower than the shared default.\n const motion = resolveMotion(config.transition, { defaultDuration: 400 });\n const easing = resolveEasing(motion.easing ?? 'ease-out');\n const unchanged = from.every((row, i) => row.every((v, j) => v === targets[i][j]));\n\n if (motion.duration === 0 || unchanged) {\n drawn = targets;\n draw(targets);\n\n return;\n }\n\n activeTween = startTween({\n count: targets.length,\n duration: motion.duration,\n easing,\n onFrame: (progress) => {\n drawn = targets.map((row, i) => {\n const e = progress(i);\n\n return row.map((to, j) => tweenNumber(from[i][j], to, e));\n });\n draw(drawn);\n },\n signal,\n stagger: motion.stagger,\n });\n }\n\n return createRadialScaffold(\n container,\n { a11y: config.a11y, legend: config.legend, tooltip: config.tooltip },\n (ctx): ChartEventHandlers | undefined => {\n const { legend, svg, tooltip } = ctx;\n\n if (!svg.contains(root)) svg.appendChild(root);\n\n tooltip?.hide();\n legend?.update(series.map((s, i) => ({ color: s.color ?? seriesColor(i), name: s.name })));\n\n if (axes.length < 3) {\n for (const group of [defs, gridGroup, seriesGroup, labelGroup]) group.replaceChildren();\n drawn = [];\n\n return undefined;\n }\n\n const { height, width } = ctx.dimensions;\n const radius = fitRadius(\n width,\n height,\n axes.map((axis) => axis.label),\n angles,\n LABEL_FONT_SIZE,\n labelGap,\n );\n\n layout = { cx: width / 2, cy: height / 2, radius };\n\n const domains = resolveAxisDomains(axes, series, config.domain);\n\n renderGrid(domains);\n renderLabels();\n renderSeries();\n animateTo(\n series.map((s) =>\n axes.map((_, j) => {\n const value = datumAt(s, j)?.value;\n\n return value !== undefined && Number.isFinite(value) ? normalize(value, domains[j]) : 0;\n }),\n ),\n ctx.disposalSignal,\n );\n setActive(activeIndex);\n\n const eventFor = (index: number, originalEvent: Event): RadarEvent => ({\n axis: axes[index],\n index,\n originalEvent,\n values: valuesAt(index),\n });\n\n const activate = (index: number, originalEvent: Event): void => {\n setActive(index);\n config.onHover?.(eventFor(index, originalEvent));\n\n const text = describe(index);\n\n if (!tooltip) {\n ctx.announcer.announce(text);\n\n return;\n }\n\n const reach = Math.max(0, ...drawn.map((row) => row[index] ?? 0));\n const svgRect = svg.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n const values = valuesAt(index);\n const first = values.find((v) => v.datum)?.datum;\n const rows = values.flatMap(({ datum, series: s }) =>\n datum\n ? [\n {\n color: s.color ?? seriesColor(series.indexOf(s)),\n name: s.name,\n value: formatValue(index, datum.value),\n },\n ]\n : [],\n );\n\n tooltip.show(\n polarX(layout.cx, layout.radius * reach, angles[index]) + (svgRect.left - containerRect.left),\n polarY(layout.cy, layout.radius * reach, angles[index]) + (svgRect.top - containerRect.top),\n { key: axes[index].key, meta: { axis: axes[index], text, values }, value: first?.value ?? 0 },\n { color: series[0]?.color ?? seriesColor(0), data: [], name: axes[index].label },\n comparisonContent(svg.ownerDocument, axes[index].label, rows, text),\n );\n };\n\n const deactivate = (): void => {\n setActive(-1);\n config.onHover?.(null);\n tooltip?.hide();\n ctx.announcer.clear();\n };\n\n const hitIndex = (event: MouseEvent): number => {\n const rect = svg.getBoundingClientRect();\n const dx = event.clientX - rect.left - layout.cx;\n const dy = event.clientY - rect.top - layout.cy;\n\n if (Math.hypot(dx, dy) > layout.radius + labelGap + LABEL_FONT_SIZE * 2) return -1;\n\n return nearestAxis(dx, dy, axes.length, startAngle);\n };\n\n return {\n onClick(event) {\n const index = hitIndex(event);\n\n if (index >= 0) config.onClick?.(eventFor(index, event));\n },\n onKeyDown(event) {\n const step = ARROW_STEPS[event.key];\n\n if (step !== undefined) {\n event.preventDefault();\n activate(activeIndex < 0 ? 0 : (activeIndex + step + axes.length) % axes.length, event);\n } else if ((event.key === 'Enter' || event.key === ' ') && activeIndex >= 0 && config.onClick) {\n event.preventDefault();\n config.onClick(eventFor(activeIndex, event));\n } else if (event.key === 'Escape') {\n deactivate();\n }\n },\n onMouseLeave: deactivate,\n onMouseMove(event) {\n const index = hitIndex(event);\n\n if (index < 0) {\n if (activeIndex >= 0) deactivate();\n } else if (index !== activeIndex) {\n activate(index, event);\n }\n },\n };\n },\n (next) => {\n series = next;\n warnOnInvalid(axes, series);\n },\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"radar-chart.cjs","names":["toRadians","axisAngles","uniqueId","createSvgElement","describeValues","radarPoints","closedPath","polarX","polarY","ringPath","labelPlacement","seriesColor","seriesDomId","resolveMotion","resolveEasing","startTween","tweenNumber","createRadialScaffold","fitRadius","resolveAxisDomains","normalize","comparisonContent","nearestAxis","require_element","require_announcer","require_tooltip","require_chart_scaffold","require_series_id","require_index","require_easing","require_motion","require_tween","require_transition","require_ids","require_polar","require_radar_geometry","LABEL_FONT_SIZE","LABEL_GAP","VALUE_OFFSET","ARROW_STEPS","grid","config","curve","fill","showPoints","startAngle","angles","axes","labelGap","id","series","root","defs","gridGroup","seriesGroup","labelGroup","drawn","activeTween","activeIndex","layout","s","d","index","value","fractions","group","i","points","row","cx","cy","radius","dot","j","r","text","levels","rings","k","angle","d0","d1","domains","shared","a","b","baseline","anchor","axis","color","area","gradientId","gradient","offset","opacity","missing","datum","el","active","from","targets","motion","easing","unchanged","v","e","progress","to","container","ctx","svg","tooltip","legend","width","height","originalEvent","reach","svgRect","containerRect","values","first","rows","rect","dx","event","dy","step","next"],"sources":["../../../src/charts/radar/radar-chart.ts"],"sourcesContent":["import { devOnly, warn } from '../../_dev';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { startTween } from '../../animation/transition';\nimport { tweenNumber } from '../../animation/tween';\nimport type { ChartEventHandlers } from '../../core/chart-scaffold';\nimport { createRadialScaffold } from '../../core/chart-scaffold';\nimport { uniqueId } from '../../core/ids';\nimport { polarX, polarY } from '../../core/polar';\nimport { seriesDomId } from '../../core/series-id';\nimport { describeValues } from '../../interaction/announcer';\nimport { comparisonContent } from '../../interaction/tooltip';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { seriesColor } from '../../theme';\nimport type {\n ChartHandle,\n RadarAxisConfig,\n RadarAxisValue,\n RadarChartConfig,\n RadarEvent,\n RadarGridConfig,\n RadarSeriesConfig,\n} from '../../types';\nimport {\n axisAngles,\n closedPath,\n fitRadius,\n labelPlacement,\n nearestAxis,\n normalize,\n radarPoints,\n resolveAxisDomains,\n ringPath,\n toRadians,\n} from './radar-geometry';\n\n/** Default `--prism-font-size-label` (0.6875rem) in px, used to reserve label room. */\nconst LABEL_FONT_SIZE = 11;\nconst LABEL_GAP = 12;\nconst VALUE_OFFSET = 10;\nconst ARROW_STEPS: Record<string, number> = { ArrowDown: 1, ArrowLeft: -1, ArrowRight: 1, ArrowUp: -1 };\n\nfunction warnOnInvalid(axes: readonly RadarAxisConfig[], series: readonly RadarSeriesConfig[]): void {\n devOnly(() => {\n if (axes.length < 3) warn(`Radar chart needs at least 3 axes, received ${axes.length}.`);\n\n const keys = new Set(axes.map((axis) => axis.key));\n\n if (keys.size !== axes.length) warn('Radar chart axis keys must be unique.');\n\n for (const s of series) {\n for (const d of s.data) {\n if (!keys.has(d.key)) warn(`Radar series \"${s.name}\" has a value for unknown axis \"${d.key}\".`);\n }\n }\n });\n}\n\nfunction resolveGrid(grid: RadarChartConfig['grid']): Required<RadarGridConfig> | null {\n if (grid === false) return null;\n\n return { bands: true, labels: false, levels: 4, shape: 'polygon', ...(typeof grid === 'object' ? grid : {}) };\n}\n\nexport function createRadarChart(container: HTMLElement, config: RadarChartConfig): ChartHandle<RadarSeriesConfig[]> {\n const { axes } = config;\n const curve = config.curve ?? 'linear';\n const fill = config.fill ?? 'solid';\n const showPoints = config.showPoints ?? true;\n const grid = resolveGrid(config.grid);\n const startAngle = toRadians(config.startAngle ?? 0);\n const angles = axisAngles(axes.length, startAngle);\n const labelGap = LABEL_GAP + (config.showValues ? VALUE_OFFSET : 0);\n const id = uniqueId('prism-radar');\n let series = config.series;\n\n warnOnInvalid(axes, series);\n\n const root = createSvgElement('g', { class: 'prism-radar' });\n const defs = createSvgElement('defs');\n const gridGroup = createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-radar-grid' });\n const seriesGroup = createSvgElement('g', { class: 'prism-radar-series-group' });\n const labelGroup = createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-radar-labels' });\n\n root.append(defs, gridGroup, seriesGroup, labelGroup);\n\n let drawn: number[][] = [];\n let activeTween: (() => void) | null = null;\n let activeIndex = -1;\n let layout = { cx: 0, cy: 0, radius: 0 };\n\n const datumAt = (s: RadarSeriesConfig, index: number) => s.data.find((d) => d.key === axes[index].key);\n const valuesAt = (index: number): RadarAxisValue[] => series.map((s) => ({ datum: datumAt(s, index), series: s }));\n const formatValue = (index: number, value: number): string => axes[index].format?.(value) ?? String(value);\n const describe = (index: number): string =>\n describeValues(axes[index].label, valuesAt(index), (value) => formatValue(index, value));\n\n function draw(fractions: number[][]): void {\n const { cx, cy, radius } = layout;\n\n fractions.forEach((row, i) => {\n const group = seriesGroup.children[i];\n\n if (!group) return;\n\n const points = radarPoints(row, cx, cy, radius, angles);\n\n group.querySelector('.prism-radar-area')?.setAttribute('d', closedPath(points, curve));\n group.querySelectorAll<SVGCircleElement>('.prism-radar-point').forEach((dot, j) => {\n setAttributes(dot, { cx: points[j].x, cy: points[j].y });\n });\n group.querySelectorAll<SVGTextElement>('.prism-radar-value').forEach((text, j) => {\n const r = radius * row[j] + VALUE_OFFSET;\n\n setAttributes(text, { x: polarX(cx, r, angles[j]), y: polarY(cy, r, angles[j]) });\n });\n });\n }\n\n function renderGrid(domains: [number, number][]): void {\n gridGroup.replaceChildren();\n\n if (!grid) return;\n\n const { cx, cy, radius } = layout;\n const levels = Math.max(1, Math.round(grid.levels));\n const rings = Array.from({ length: levels }, (_, k) =>\n ringPath(grid.shape, cx, cy, (radius * (k + 1)) / levels, angles),\n );\n\n if (grid.bands) {\n // Shade alternate rings, starting from the outermost.\n for (let k = levels - 1; k >= 0; k -= 2) {\n gridGroup.appendChild(\n createSvgElement('path', {\n class: 'prism-radar-band',\n d: `${rings[k]}${rings[k - 1] ?? ''}`,\n 'fill-rule': 'evenodd',\n }),\n );\n }\n }\n\n for (const d of rings)\n gridGroup.appendChild(createSvgElement('path', { class: 'prism-radar-ring', d, fill: 'none' }));\n\n angles.forEach((angle, i) => {\n gridGroup.appendChild(\n createSvgElement('line', {\n class: 'prism-radar-spoke',\n 'data-axis': i,\n x1: cx,\n x2: polarX(cx, radius, angle),\n y1: cy,\n y2: polarY(cy, radius, angle),\n }),\n );\n });\n\n const [d0, d1] = domains[0];\n const shared = domains.every(([a, b]) => a === d0 && b === d1);\n\n if (!grid.labels || !shared) return;\n\n // Between the first two spokes, so level values never collide with vertex values.\n const angle = angles[0] + Math.PI / angles.length;\n\n for (let k = 1; k <= levels; k++) {\n const r = (radius * k) / levels;\n const text = createSvgElement('text', {\n class: 'prism-radar-level',\n 'dominant-baseline': 'middle',\n 'text-anchor': 'middle',\n x: polarX(cx, r, angle),\n y: polarY(cy, r, angle),\n });\n\n text.textContent = formatValue(0, Math.round((d0 + ((d1 - d0) * k) / levels) * 100) / 100);\n gridGroup.appendChild(text);\n }\n }\n\n function renderLabels(): void {\n labelGroup.replaceChildren();\n\n const { cx, cy, radius } = layout;\n\n axes.forEach((axis, i) => {\n const { anchor, baseline } = labelPlacement(angles[i]);\n const text = createSvgElement('text', {\n class: 'prism-radar-axis-label',\n 'dominant-baseline': baseline,\n 'text-anchor': anchor,\n x: polarX(cx, radius + labelGap, angles[i]),\n y: polarY(cy, radius + labelGap, angles[i]),\n });\n\n text.textContent = axis.label;\n labelGroup.appendChild(text);\n });\n }\n\n function renderSeries(): void {\n const { cx, cy, radius } = layout;\n\n defs.replaceChildren();\n\n while (seriesGroup.children.length > series.length) seriesGroup.lastChild?.remove();\n\n series.forEach((s, i) => {\n const color = s.color ?? seriesColor(i);\n let group = seriesGroup.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-radar-series' });\n seriesGroup.appendChild(group);\n }\n\n group.setAttribute('data-series-id', seriesDomId(s, i));\n\n group.replaceChildren();\n\n const area = createSvgElement('path', {\n class: `prism-radar-area prism-radar-area--${fill}`,\n stroke: color,\n 'stroke-linejoin': 'round',\n 'stroke-width': 2,\n });\n\n if (fill === 'gradient') {\n const gradientId = `${id}-fill-${i}`;\n const gradient = createSvgElement('radialGradient', {\n cx,\n cy,\n gradientUnits: 'userSpaceOnUse',\n id: gradientId,\n r: radius,\n });\n\n for (const [offset, opacity] of [\n [0, 0.08],\n [1, 0.55],\n ]) {\n gradient.appendChild(\n createSvgElement('stop', {\n offset,\n 'stop-color': color,\n 'stop-opacity': opacity,\n style: `stop-color:${color}`,\n }),\n );\n }\n\n defs.appendChild(gradient);\n setAttributes(area, { fill: `url(#${gradientId})` });\n } else {\n setAttributes(area, { fill: fill === 'none' ? 'none' : color, 'fill-opacity': 0.25 });\n }\n\n group.appendChild(area);\n\n if (showPoints) {\n axes.forEach((_, j) => {\n const missing = !Number.isFinite(datumAt(s, j)?.value);\n\n group.appendChild(\n createSvgElement('circle', {\n class: `prism-radar-point${missing ? ' prism-radar-point--missing' : ''}`,\n 'data-axis': j,\n fill: missing ? 'none' : color,\n r: 3,\n stroke: color,\n }),\n );\n });\n }\n\n if (config.showValues) {\n axes.forEach((_, j) => {\n const datum = datumAt(s, j);\n const { anchor, baseline } = labelPlacement(angles[j]);\n const text = createSvgElement('text', {\n 'aria-hidden': 'true',\n class: 'prism-radar-value',\n 'dominant-baseline': baseline,\n 'text-anchor': anchor,\n });\n\n text.textContent = datum && Number.isFinite(datum.value) ? formatValue(j, datum.value) : '';\n group.appendChild(text);\n });\n }\n });\n }\n\n function setActive(index: number): void {\n activeIndex = index;\n for (const el of root.querySelectorAll('[data-axis]')) {\n const active = Number(el.getAttribute('data-axis')) === index;\n\n el.classList.toggle(el.tagName === 'line' ? 'prism-radar-spoke--active' : 'prism-radar-point--active', active);\n }\n }\n\n function animateTo(targets: number[][], signal: AbortSignal): void {\n activeTween?.();\n\n const from = targets.map((row, i) => row.map((_, j) => drawn[i]?.[j] ?? 0));\n // Radar morphs a whole polygon, so it reads better slightly slower than the shared default.\n const motion = resolveMotion(config.transition, { defaultDuration: 400 });\n const easing = resolveEasing(motion.easing ?? 'ease-out');\n const unchanged = from.every((row, i) => row.every((v, j) => v === targets[i][j]));\n\n if (motion.duration === 0 || unchanged) {\n drawn = targets;\n draw(targets);\n\n return;\n }\n\n activeTween = startTween({\n count: targets.length,\n duration: motion.duration,\n easing,\n onFrame: (progress) => {\n drawn = targets.map((row, i) => {\n const e = progress(i);\n\n return row.map((to, j) => tweenNumber(from[i][j], to, e));\n });\n draw(drawn);\n },\n signal,\n stagger: motion.stagger,\n });\n }\n\n return createRadialScaffold(\n container,\n { a11y: config.a11y, legend: config.legend, tooltip: config.tooltip },\n (ctx): ChartEventHandlers | undefined => {\n const { legend, svg, tooltip } = ctx;\n\n if (!svg.contains(root)) svg.appendChild(root);\n\n tooltip?.hide();\n legend?.update(series.map((s, i) => ({ color: s.color ?? seriesColor(i), name: s.name })));\n\n if (axes.length < 3) {\n for (const group of [defs, gridGroup, seriesGroup, labelGroup]) group.replaceChildren();\n drawn = [];\n\n return undefined;\n }\n\n const { height, width } = ctx.dimensions;\n const radius = fitRadius(\n width,\n height,\n axes.map((axis) => axis.label),\n angles,\n LABEL_FONT_SIZE,\n labelGap,\n );\n\n layout = { cx: width / 2, cy: height / 2, radius };\n\n const domains = resolveAxisDomains(axes, series, config.domain);\n\n renderGrid(domains);\n renderLabels();\n renderSeries();\n animateTo(\n series.map((s) =>\n axes.map((_, j) => {\n const value = datumAt(s, j)?.value;\n\n return value !== undefined && Number.isFinite(value) ? normalize(value, domains[j]) : 0;\n }),\n ),\n ctx.disposalSignal,\n );\n setActive(activeIndex);\n\n const eventFor = (index: number, originalEvent: Event): RadarEvent => ({\n axis: axes[index],\n index,\n originalEvent,\n values: valuesAt(index),\n });\n\n const activate = (index: number, originalEvent: Event): void => {\n setActive(index);\n config.onHover?.(eventFor(index, originalEvent));\n\n const text = describe(index);\n\n if (!tooltip) {\n ctx.announcer.announce(text);\n\n return;\n }\n\n const reach = Math.max(0, ...drawn.map((row) => row[index] ?? 0));\n const svgRect = svg.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n const values = valuesAt(index);\n const first = values.find((v) => v.datum)?.datum;\n const rows = values.flatMap(({ datum, series: s }) =>\n datum\n ? [\n {\n color: s.color ?? seriesColor(series.indexOf(s)),\n name: s.name,\n value: formatValue(index, datum.value),\n },\n ]\n : [],\n );\n\n tooltip.show(\n polarX(layout.cx, layout.radius * reach, angles[index]) + (svgRect.left - containerRect.left),\n polarY(layout.cy, layout.radius * reach, angles[index]) + (svgRect.top - containerRect.top),\n { key: axes[index].key, meta: { axis: axes[index], text, values }, value: first?.value ?? 0 },\n { color: series[0]?.color ?? seriesColor(0), data: [], name: axes[index].label },\n comparisonContent(svg.ownerDocument, axes[index].label, rows, text),\n );\n };\n\n const deactivate = (): void => {\n setActive(-1);\n config.onHover?.(null);\n tooltip?.hide();\n ctx.announcer.clear();\n };\n\n const hitIndex = (event: MouseEvent): number => {\n const rect = svg.getBoundingClientRect();\n const dx = event.clientX - rect.left - layout.cx;\n const dy = event.clientY - rect.top - layout.cy;\n\n if (Math.hypot(dx, dy) > layout.radius + labelGap + LABEL_FONT_SIZE * 2) return -1;\n\n return nearestAxis(dx, dy, axes.length, startAngle);\n };\n\n return {\n onClick(event) {\n const index = hitIndex(event);\n\n if (index >= 0) config.onClick?.(eventFor(index, event));\n },\n onKeyDown(event) {\n const step = ARROW_STEPS[event.key];\n\n if (step !== undefined) {\n event.preventDefault();\n activate(activeIndex < 0 ? 0 : (activeIndex + step + axes.length) % axes.length, event);\n } else if ((event.key === 'Enter' || event.key === ' ') && activeIndex >= 0 && config.onClick) {\n event.preventDefault();\n config.onClick(eventFor(activeIndex, event));\n } else if (event.key === 'Escape') {\n deactivate();\n }\n },\n onMouseLeave: deactivate,\n onMouseMove(event) {\n const index = hitIndex(event);\n\n if (index < 0) {\n if (activeIndex >= 0) deactivate();\n } else if (index !== activeIndex) {\n activate(index, event);\n }\n },\n };\n },\n (next) => {\n series = next;\n warnOnInvalid(axes, series);\n },\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,282 @@
1
- import"../../_dev.js";import{createSvgElement as e,setAttributes as t}from"../../svg/element.js";import{describeValues as n}from"../../interaction/announcer.js";import{comparisonContent as r}from"../../interaction/tooltip.js";import{createRadialScaffold as i}from"../../core/chart-scaffold.js";import{seriesDomId as a}from"../../core/series-id.js";import{seriesColor as o}from"../../theme/index.js";import{resolveEasing as s}from"../../animation/easing.js";import{resolveMotion as c}from"../../animation/motion.js";import{tweenNumber as l}from"../../animation/tween.js";import{startTween as u}from"../../animation/transition.js";import{uniqueId as d}from"../../core/ids.js";import{polarX as f,polarY as p}from"../../core/polar.js";import{axisAngles as m,closedPath as h,fitRadius as g,labelPlacement as _,nearestAxis as v,normalize as y,radarPoints as b,resolveAxisDomains as x,ringPath as S,toRadians as C}from"./radar-geometry.js";var w=11,T=12,E=10,D={ArrowDown:1,ArrowLeft:-1,ArrowRight:1,ArrowUp:-1};function resolveGrid(e){return e===!1?null:{bands:!0,labels:!1,levels:4,shape:`polygon`,...typeof e==`object`?e:{}}}function createRadarChart(O,k){let{axes:A}=k,j=k.curve??`linear`,M=k.fill??`solid`,N=k.showPoints??!0,P=resolveGrid(k.grid),F=C(k.startAngle??0),I=m(A.length,F),L=T+(k.showValues?E:0),R=d(`prism-radar`),z=k.series,B=e(`g`,{class:`prism-radar`}),V=e(`defs`),H=e(`g`,{"aria-hidden":`true`,class:`prism-radar-grid`}),U=e(`g`,{class:`prism-radar-series-group`}),W=e(`g`,{"aria-hidden":`true`,class:`prism-radar-labels`});B.append(V,H,U,W);let G=[],K=null,q=-1,J={cx:0,cy:0,radius:0},datumAt=(e,t)=>e.data.find(e=>e.key===A[t].key),valuesAt=e=>z.map(t=>({datum:datumAt(t,e),series:t})),formatValue=(e,t)=>A[e].format?.(t)??String(t),describe=e=>n(A[e].label,valuesAt(e),t=>formatValue(e,t));function draw(e){let{cx:n,cy:r,radius:i}=J;e.forEach((e,a)=>{let o=U.children[a];if(!o)return;let s=b(e,n,r,i,I);o.querySelector(`.prism-radar-area`)?.setAttribute(`d`,h(s,j)),o.querySelectorAll(`.prism-radar-point`).forEach((e,n)=>{t(e,{cx:s[n].x,cy:s[n].y})}),o.querySelectorAll(`.prism-radar-value`).forEach((a,o)=>{let s=i*e[o]+E;t(a,{x:f(n,s,I[o]),y:p(r,s,I[o])})})})}function renderGrid(t){if(H.replaceChildren(),!P)return;let{cx:n,cy:r,radius:i}=J,a=Math.max(1,Math.round(P.levels)),o=Array.from({length:a},(e,t)=>S(P.shape,n,r,i*(t+1)/a,I));if(P.bands)for(let t=a-1;t>=0;t-=2)H.appendChild(e(`path`,{class:`prism-radar-band`,d:`${o[t]}${o[t-1]??``}`,"fill-rule":`evenodd`}));for(let t of o)H.appendChild(e(`path`,{class:`prism-radar-ring`,d:t,fill:`none`}));I.forEach((t,a)=>{H.appendChild(e(`line`,{class:`prism-radar-spoke`,"data-axis":a,x1:n,x2:f(n,i,t),y1:r,y2:p(r,i,t)}))});let[s,c]=t[0],l=t.every(([e,t])=>e===s&&t===c);if(!P.labels||!l)return;let u=I[0]+Math.PI/I.length;for(let t=1;t<=a;t++){let o=i*t/a,l=e(`text`,{class:`prism-radar-level`,"dominant-baseline":`middle`,"text-anchor":`middle`,x:f(n,o,u),y:p(r,o,u)});l.textContent=formatValue(0,Math.round((s+(c-s)*t/a)*100)/100),H.appendChild(l)}}function renderLabels(){W.replaceChildren();let{cx:t,cy:n,radius:r}=J;A.forEach((i,a)=>{let{anchor:o,baseline:s}=_(I[a]),c=e(`text`,{class:`prism-radar-axis-label`,"dominant-baseline":s,"text-anchor":o,x:f(t,r+L,I[a]),y:p(n,r+L,I[a])});c.textContent=i.label,W.appendChild(c)})}function renderSeries(){let{cx:n,cy:r,radius:i}=J;for(V.replaceChildren();U.children.length>z.length;)U.lastChild?.remove();z.forEach((s,c)=>{let l=s.color??o(c),u=U.children[c];u||(u=e(`g`,{class:`prism-radar-series`}),U.appendChild(u)),u.setAttribute(`data-series-id`,a(s,c)),u.replaceChildren();let d=e(`path`,{class:`prism-radar-area prism-radar-area--${M}`,stroke:l,"stroke-linejoin":`round`,"stroke-width":2});if(M===`gradient`){let a=`${R}-fill-${c}`,o=e(`radialGradient`,{cx:n,cy:r,gradientUnits:`userSpaceOnUse`,id:a,r:i});for(let[t,n]of[[0,.08],[1,.55]])o.appendChild(e(`stop`,{offset:t,"stop-color":l,"stop-opacity":n,style:`stop-color:${l}`}));V.appendChild(o),t(d,{fill:`url(#${a})`})}else t(d,{fill:M===`none`?`none`:l,"fill-opacity":.25});u.appendChild(d),N&&A.forEach((t,n)=>{let r=!Number.isFinite(datumAt(s,n)?.value);u.appendChild(e(`circle`,{class:`prism-radar-point${r?` prism-radar-point--missing`:``}`,"data-axis":n,fill:r?`none`:l,r:3,stroke:l}))}),k.showValues&&A.forEach((t,n)=>{let r=datumAt(s,n),{anchor:i,baseline:a}=_(I[n]),o=e(`text`,{"aria-hidden":`true`,class:`prism-radar-value`,"dominant-baseline":a,"text-anchor":i});o.textContent=r&&Number.isFinite(r.value)?formatValue(n,r.value):``,u.appendChild(o)})})}function setActive(e){q=e;for(let t of B.querySelectorAll(`[data-axis]`)){let n=Number(t.getAttribute(`data-axis`))===e;t.classList.toggle(t.tagName===`line`?`prism-radar-spoke--active`:`prism-radar-point--active`,n)}}function animateTo(e,t){K?.();let n=e.map((e,t)=>e.map((e,n)=>G[t]?.[n]??0)),r=c(k.transition,{defaultDuration:400}),i=s(r.easing??`ease-out`),a=n.every((t,n)=>t.every((t,r)=>t===e[n][r]));if(r.duration===0||a){G=e,draw(e);return}K=u({count:e.length,duration:r.duration,easing:i,onFrame:t=>{G=e.map((e,r)=>{let i=t(r);return e.map((e,t)=>l(n[r][t],e,i))}),draw(G)},signal:t,stagger:r.stagger})}return i(O,{a11y:k.a11y,legend:k.legend,tooltip:k.tooltip},e=>{let{legend:t,svg:n,tooltip:i}=e;if(n.contains(B)||n.appendChild(B),i?.hide(),t?.update(z.map((e,t)=>({color:e.color??o(t),name:e.name}))),A.length<3){for(let e of[V,H,U,W])e.replaceChildren();G=[];return}let{height:a,width:s}=e.dimensions,c=g(s,a,A.map(e=>e.label),I,w,L);J={cx:s/2,cy:a/2,radius:c};let l=x(A,z,k.domain);renderGrid(l),renderLabels(),renderSeries(),animateTo(z.map(e=>A.map((t,n)=>{let r=datumAt(e,n)?.value;return r!==void 0&&Number.isFinite(r)?y(r,l[n]):0})),e.disposalSignal),setActive(q);let eventFor=(e,t)=>({axis:A[e],index:e,originalEvent:t,values:valuesAt(e)}),activate=(t,a)=>{setActive(t),k.onHover?.(eventFor(t,a));let s=describe(t);if(!i){e.announcer.announce(s);return}let c=Math.max(0,...G.map(e=>e[t]??0)),l=n.getBoundingClientRect(),u=O.getBoundingClientRect(),d=valuesAt(t),m=d.find(e=>e.datum)?.datum,h=d.flatMap(({datum:e,series:n})=>e?[{color:n.color??o(z.indexOf(n)),name:n.name,value:formatValue(t,e.value)}]:[]);i.show(f(J.cx,J.radius*c,I[t])+(l.left-u.left),p(J.cy,J.radius*c,I[t])+(l.top-u.top),{key:A[t].key,meta:{axis:A[t],text:s,values:d},value:m?.value??0},{color:z[0]?.color??o(0),data:[],name:A[t].label},r(n.ownerDocument,A[t].label,h,s))},deactivate=()=>{setActive(-1),k.onHover?.(null),i?.hide(),e.announcer.clear()},hitIndex=e=>{let t=n.getBoundingClientRect(),r=e.clientX-t.left-J.cx,i=e.clientY-t.top-J.cy;return Math.hypot(r,i)>J.radius+L+22?-1:v(r,i,A.length,F)};return{onClick(e){let t=hitIndex(e);t>=0&&k.onClick?.(eventFor(t,e))},onKeyDown(e){let t=D[e.key];t===void 0?(e.key===`Enter`||e.key===` `)&&q>=0&&k.onClick?(e.preventDefault(),k.onClick(eventFor(q,e))):e.key===`Escape`&&deactivate():(e.preventDefault(),activate(q<0?0:(q+t+A.length)%A.length,e))},onMouseLeave:deactivate,onMouseMove(e){let t=hitIndex(e);t<0?q>=0&&deactivate():t!==q&&activate(t,e)}}},e=>{z=e})}export{createRadarChart};
1
+ import "../../_dev.js";
2
+ import { createSvgElement as e, setAttributes as t } from "../../svg/element.js";
3
+ import { describeValues as n } from "../../interaction/announcer.js";
4
+ import { comparisonContent as r } from "../../interaction/tooltip.js";
5
+ import { createRadialScaffold as i } from "../../core/chart-scaffold.js";
6
+ import { seriesDomId as a } from "../../core/series-id.js";
7
+ import { seriesColor as o } from "../../theme/index.js";
8
+ import { resolveEasing as s } from "../../animation/easing.js";
9
+ import { resolveMotion as c } from "../../animation/motion.js";
10
+ import { tweenNumber as l } from "../../animation/tween.js";
11
+ import { startTween as u } from "../../animation/transition.js";
12
+ import { uniqueId as d } from "../../core/ids.js";
13
+ import { polarX as f, polarY as p } from "../../core/polar.js";
14
+ import { axisAngles as m, closedPath as h, fitRadius as g, labelPlacement as _, nearestAxis as v, normalize as y, radarPoints as b, resolveAxisDomains as x, ringPath as S, toRadians as C } from "./radar-geometry.js";
15
+ //#region src/charts/radar/radar-chart.ts
16
+ var w = 11, T = 12, E = 10, D = {
17
+ ArrowDown: 1,
18
+ ArrowLeft: -1,
19
+ ArrowRight: 1,
20
+ ArrowUp: -1
21
+ };
22
+ function resolveGrid(e) {
23
+ return e === !1 ? null : {
24
+ bands: !0,
25
+ labels: !1,
26
+ levels: 4,
27
+ shape: "polygon",
28
+ ...typeof e == "object" ? e : {}
29
+ };
30
+ }
31
+ function createRadarChart(O, k) {
32
+ let { axes: A } = k, j = k.curve ?? "linear", M = k.fill ?? "solid", N = k.showPoints ?? !0, P = resolveGrid(k.grid), F = C(k.startAngle ?? 0), I = m(A.length, F), L = T + (k.showValues ? E : 0), R = d("prism-radar"), z = k.series, B = e("g", { class: "prism-radar" }), V = e("defs"), H = e("g", {
33
+ "aria-hidden": "true",
34
+ class: "prism-radar-grid"
35
+ }), U = e("g", { class: "prism-radar-series-group" }), W = e("g", {
36
+ "aria-hidden": "true",
37
+ class: "prism-radar-labels"
38
+ });
39
+ B.append(V, H, U, W);
40
+ let G = [], K = null, q = -1, J = {
41
+ cx: 0,
42
+ cy: 0,
43
+ radius: 0
44
+ }, datumAt = (e, t) => e.data.find((e) => e.key === A[t].key), valuesAt = (e) => z.map((t) => ({
45
+ datum: datumAt(t, e),
46
+ series: t
47
+ })), formatValue = (e, t) => A[e].format?.(t) ?? String(t), describe = (e) => n(A[e].label, valuesAt(e), (t) => formatValue(e, t));
48
+ function draw(e) {
49
+ let { cx: n, cy: r, radius: i } = J;
50
+ e.forEach((e, a) => {
51
+ let o = U.children[a];
52
+ if (!o) return;
53
+ let s = b(e, n, r, i, I);
54
+ o.querySelector(".prism-radar-area")?.setAttribute("d", h(s, j)), o.querySelectorAll(".prism-radar-point").forEach((e, n) => {
55
+ t(e, {
56
+ cx: s[n].x,
57
+ cy: s[n].y
58
+ });
59
+ }), o.querySelectorAll(".prism-radar-value").forEach((a, o) => {
60
+ let s = i * e[o] + E;
61
+ t(a, {
62
+ x: f(n, s, I[o]),
63
+ y: p(r, s, I[o])
64
+ });
65
+ });
66
+ });
67
+ }
68
+ function renderGrid(t) {
69
+ if (H.replaceChildren(), !P) return;
70
+ let { cx: n, cy: r, radius: i } = J, a = Math.max(1, Math.round(P.levels)), o = Array.from({ length: a }, (e, t) => S(P.shape, n, r, i * (t + 1) / a, I));
71
+ if (P.bands) for (let t = a - 1; t >= 0; t -= 2) H.appendChild(e("path", {
72
+ class: "prism-radar-band",
73
+ d: `${o[t]}${o[t - 1] ?? ""}`,
74
+ "fill-rule": "evenodd"
75
+ }));
76
+ for (let t of o) H.appendChild(e("path", {
77
+ class: "prism-radar-ring",
78
+ d: t,
79
+ fill: "none"
80
+ }));
81
+ I.forEach((t, a) => {
82
+ H.appendChild(e("line", {
83
+ class: "prism-radar-spoke",
84
+ "data-axis": a,
85
+ x1: n,
86
+ x2: f(n, i, t),
87
+ y1: r,
88
+ y2: p(r, i, t)
89
+ }));
90
+ });
91
+ let [s, c] = t[0], l = t.every(([e, t]) => e === s && t === c);
92
+ if (!P.labels || !l) return;
93
+ let u = I[0] + Math.PI / I.length;
94
+ for (let t = 1; t <= a; t++) {
95
+ let o = i * t / a, l = e("text", {
96
+ class: "prism-radar-level",
97
+ "dominant-baseline": "middle",
98
+ "text-anchor": "middle",
99
+ x: f(n, o, u),
100
+ y: p(r, o, u)
101
+ });
102
+ l.textContent = formatValue(0, Math.round((s + (c - s) * t / a) * 100) / 100), H.appendChild(l);
103
+ }
104
+ }
105
+ function renderLabels() {
106
+ W.replaceChildren();
107
+ let { cx: t, cy: n, radius: r } = J;
108
+ A.forEach((i, a) => {
109
+ let { anchor: o, baseline: s } = _(I[a]), c = e("text", {
110
+ class: "prism-radar-axis-label",
111
+ "dominant-baseline": s,
112
+ "text-anchor": o,
113
+ x: f(t, r + L, I[a]),
114
+ y: p(n, r + L, I[a])
115
+ });
116
+ c.textContent = i.label, W.appendChild(c);
117
+ });
118
+ }
119
+ function renderSeries() {
120
+ let { cx: n, cy: r, radius: i } = J;
121
+ for (V.replaceChildren(); U.children.length > z.length;) U.lastChild?.remove();
122
+ z.forEach((s, c) => {
123
+ let l = s.color ?? o(c), u = U.children[c];
124
+ u || (u = e("g", { class: "prism-radar-series" }), U.appendChild(u)), u.setAttribute("data-series-id", a(s, c)), u.replaceChildren();
125
+ let d = e("path", {
126
+ class: `prism-radar-area prism-radar-area--${M}`,
127
+ stroke: l,
128
+ "stroke-linejoin": "round",
129
+ "stroke-width": 2
130
+ });
131
+ if (M === "gradient") {
132
+ let a = `${R}-fill-${c}`, o = e("radialGradient", {
133
+ cx: n,
134
+ cy: r,
135
+ gradientUnits: "userSpaceOnUse",
136
+ id: a,
137
+ r: i
138
+ });
139
+ for (let [t, n] of [[0, .08], [1, .55]]) o.appendChild(e("stop", {
140
+ offset: t,
141
+ "stop-color": l,
142
+ "stop-opacity": n,
143
+ style: `stop-color:${l}`
144
+ }));
145
+ V.appendChild(o), t(d, { fill: `url(#${a})` });
146
+ } else t(d, {
147
+ fill: M === "none" ? "none" : l,
148
+ "fill-opacity": .25
149
+ });
150
+ u.appendChild(d), N && A.forEach((t, n) => {
151
+ let r = !Number.isFinite(datumAt(s, n)?.value);
152
+ u.appendChild(e("circle", {
153
+ class: `prism-radar-point${r ? " prism-radar-point--missing" : ""}`,
154
+ "data-axis": n,
155
+ fill: r ? "none" : l,
156
+ r: 3,
157
+ stroke: l
158
+ }));
159
+ }), k.showValues && A.forEach((t, n) => {
160
+ let r = datumAt(s, n), { anchor: i, baseline: a } = _(I[n]), o = e("text", {
161
+ "aria-hidden": "true",
162
+ class: "prism-radar-value",
163
+ "dominant-baseline": a,
164
+ "text-anchor": i
165
+ });
166
+ o.textContent = r && Number.isFinite(r.value) ? formatValue(n, r.value) : "", u.appendChild(o);
167
+ });
168
+ });
169
+ }
170
+ function setActive(e) {
171
+ q = e;
172
+ for (let t of B.querySelectorAll("[data-axis]")) {
173
+ let n = Number(t.getAttribute("data-axis")) === e;
174
+ t.classList.toggle(t.tagName === "line" ? "prism-radar-spoke--active" : "prism-radar-point--active", n);
175
+ }
176
+ }
177
+ function animateTo(e, t) {
178
+ K?.();
179
+ let n = e.map((e, t) => e.map((e, n) => G[t]?.[n] ?? 0)), r = c(k.transition, { defaultDuration: 400 }), i = s(r.easing ?? "ease-out"), a = n.every((t, n) => t.every((t, r) => t === e[n][r]));
180
+ r.duration === 0 || a ? (G = e, draw(e)) : K = u({
181
+ count: e.length,
182
+ duration: r.duration,
183
+ easing: i,
184
+ onFrame: (t) => {
185
+ G = e.map((e, r) => {
186
+ let i = t(r);
187
+ return e.map((e, t) => l(n[r][t], e, i));
188
+ }), draw(G);
189
+ },
190
+ signal: t,
191
+ stagger: r.stagger
192
+ });
193
+ }
194
+ return i(O, {
195
+ a11y: k.a11y,
196
+ legend: k.legend,
197
+ tooltip: k.tooltip
198
+ }, (e) => {
199
+ let { legend: t, svg: n, tooltip: i } = e;
200
+ if (n.contains(B) || n.appendChild(B), i?.hide(), t?.update(z.map((e, t) => ({
201
+ color: e.color ?? o(t),
202
+ name: e.name
203
+ }))), A.length < 3) {
204
+ for (let e of [
205
+ V,
206
+ H,
207
+ U,
208
+ W
209
+ ]) e.replaceChildren();
210
+ G = [];
211
+ return;
212
+ }
213
+ let { height: a, width: s } = e.dimensions, c = g(s, a, A.map((e) => e.label), I, w, L);
214
+ J = {
215
+ cx: s / 2,
216
+ cy: a / 2,
217
+ radius: c
218
+ };
219
+ let l = x(A, z, k.domain);
220
+ renderGrid(l), renderLabels(), renderSeries(), animateTo(z.map((e) => A.map((t, n) => {
221
+ let r = datumAt(e, n)?.value;
222
+ return r !== void 0 && Number.isFinite(r) ? y(r, l[n]) : 0;
223
+ })), e.disposalSignal), setActive(q);
224
+ let eventFor = (e, t) => ({
225
+ axis: A[e],
226
+ index: e,
227
+ originalEvent: t,
228
+ values: valuesAt(e)
229
+ }), activate = (t, a) => {
230
+ setActive(t), k.onHover?.(eventFor(t, a));
231
+ let s = describe(t);
232
+ if (!i) {
233
+ e.announcer.announce(s);
234
+ return;
235
+ }
236
+ let c = Math.max(0, ...G.map((e) => e[t] ?? 0)), l = n.getBoundingClientRect(), u = O.getBoundingClientRect(), d = valuesAt(t), m = d.find((e) => e.datum)?.datum, h = d.flatMap(({ datum: e, series: n }) => e ? [{
237
+ color: n.color ?? o(z.indexOf(n)),
238
+ name: n.name,
239
+ value: formatValue(t, e.value)
240
+ }] : []);
241
+ i.show(f(J.cx, J.radius * c, I[t]) + (l.left - u.left), p(J.cy, J.radius * c, I[t]) + (l.top - u.top), {
242
+ key: A[t].key,
243
+ meta: {
244
+ axis: A[t],
245
+ text: s,
246
+ values: d
247
+ },
248
+ value: m?.value ?? 0
249
+ }, {
250
+ color: z[0]?.color ?? o(0),
251
+ data: [],
252
+ name: A[t].label
253
+ }, r(n.ownerDocument, A[t].label, h, s));
254
+ }, deactivate = () => {
255
+ setActive(-1), k.onHover?.(null), i?.hide(), e.announcer.clear();
256
+ }, hitIndex = (e) => {
257
+ let t = n.getBoundingClientRect(), r = e.clientX - t.left - J.cx, i = e.clientY - t.top - J.cy;
258
+ return Math.hypot(r, i) > J.radius + L + 22 ? -1 : v(r, i, A.length, F);
259
+ };
260
+ return {
261
+ onClick(e) {
262
+ let t = hitIndex(e);
263
+ t >= 0 && k.onClick?.(eventFor(t, e));
264
+ },
265
+ onKeyDown(e) {
266
+ let t = D[e.key];
267
+ t === void 0 ? (e.key === "Enter" || e.key === " ") && q >= 0 && k.onClick ? (e.preventDefault(), k.onClick(eventFor(q, e))) : e.key === "Escape" && deactivate() : (e.preventDefault(), activate(q < 0 ? 0 : (q + t + A.length) % A.length, e));
268
+ },
269
+ onMouseLeave: deactivate,
270
+ onMouseMove(e) {
271
+ let t = hitIndex(e);
272
+ t < 0 ? q >= 0 && deactivate() : t !== q && activate(t, e);
273
+ }
274
+ };
275
+ }, (e) => {
276
+ z = e;
277
+ });
278
+ }
279
+ //#endregion
280
+ export { createRadarChart };
281
+
2
282
  //# sourceMappingURL=radar-chart.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"radar-chart.js","names":[],"sources":["../../../src/charts/radar/radar-chart.ts"],"sourcesContent":["import { devOnly, warn } from '../../_dev';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { startTween } from '../../animation/transition';\nimport { tweenNumber } from '../../animation/tween';\nimport type { ChartEventHandlers } from '../../core/chart-scaffold';\nimport { createRadialScaffold } from '../../core/chart-scaffold';\nimport { uniqueId } from '../../core/ids';\nimport { polarX, polarY } from '../../core/polar';\nimport { seriesDomId } from '../../core/series-id';\nimport { describeValues } from '../../interaction/announcer';\nimport { comparisonContent } from '../../interaction/tooltip';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { seriesColor } from '../../theme';\nimport type {\n ChartHandle,\n RadarAxisConfig,\n RadarAxisValue,\n RadarChartConfig,\n RadarEvent,\n RadarGridConfig,\n RadarSeriesConfig,\n} from '../../types';\nimport {\n axisAngles,\n closedPath,\n fitRadius,\n labelPlacement,\n nearestAxis,\n normalize,\n radarPoints,\n resolveAxisDomains,\n ringPath,\n toRadians,\n} from './radar-geometry';\n\n/** Default `--prism-font-size-label` (0.6875rem) in px, used to reserve label room. */\nconst LABEL_FONT_SIZE = 11;\nconst LABEL_GAP = 12;\nconst VALUE_OFFSET = 10;\nconst ARROW_STEPS: Record<string, number> = { ArrowDown: 1, ArrowLeft: -1, ArrowRight: 1, ArrowUp: -1 };\n\nfunction warnOnInvalid(axes: readonly RadarAxisConfig[], series: readonly RadarSeriesConfig[]): void {\n devOnly(() => {\n if (axes.length < 3) warn(`Radar chart needs at least 3 axes, received ${axes.length}.`);\n\n const keys = new Set(axes.map((axis) => axis.key));\n\n if (keys.size !== axes.length) warn('Radar chart axis keys must be unique.');\n\n for (const s of series) {\n for (const d of s.data) {\n if (!keys.has(d.key)) warn(`Radar series \"${s.name}\" has a value for unknown axis \"${d.key}\".`);\n }\n }\n });\n}\n\nfunction resolveGrid(grid: RadarChartConfig['grid']): Required<RadarGridConfig> | null {\n if (grid === false) return null;\n\n return { bands: true, labels: false, levels: 4, shape: 'polygon', ...(typeof grid === 'object' ? grid : {}) };\n}\n\nexport function createRadarChart(container: HTMLElement, config: RadarChartConfig): ChartHandle<RadarSeriesConfig[]> {\n const { axes } = config;\n const curve = config.curve ?? 'linear';\n const fill = config.fill ?? 'solid';\n const showPoints = config.showPoints ?? true;\n const grid = resolveGrid(config.grid);\n const startAngle = toRadians(config.startAngle ?? 0);\n const angles = axisAngles(axes.length, startAngle);\n const labelGap = LABEL_GAP + (config.showValues ? VALUE_OFFSET : 0);\n const id = uniqueId('prism-radar');\n let series = config.series;\n\n warnOnInvalid(axes, series);\n\n const root = createSvgElement('g', { class: 'prism-radar' });\n const defs = createSvgElement('defs');\n const gridGroup = createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-radar-grid' });\n const seriesGroup = createSvgElement('g', { class: 'prism-radar-series-group' });\n const labelGroup = createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-radar-labels' });\n\n root.append(defs, gridGroup, seriesGroup, labelGroup);\n\n let drawn: number[][] = [];\n let activeTween: (() => void) | null = null;\n let activeIndex = -1;\n let layout = { cx: 0, cy: 0, radius: 0 };\n\n const datumAt = (s: RadarSeriesConfig, index: number) => s.data.find((d) => d.key === axes[index].key);\n const valuesAt = (index: number): RadarAxisValue[] => series.map((s) => ({ datum: datumAt(s, index), series: s }));\n const formatValue = (index: number, value: number): string => axes[index].format?.(value) ?? String(value);\n const describe = (index: number): string =>\n describeValues(axes[index].label, valuesAt(index), (value) => formatValue(index, value));\n\n function draw(fractions: number[][]): void {\n const { cx, cy, radius } = layout;\n\n fractions.forEach((row, i) => {\n const group = seriesGroup.children[i];\n\n if (!group) return;\n\n const points = radarPoints(row, cx, cy, radius, angles);\n\n group.querySelector('.prism-radar-area')?.setAttribute('d', closedPath(points, curve));\n group.querySelectorAll<SVGCircleElement>('.prism-radar-point').forEach((dot, j) => {\n setAttributes(dot, { cx: points[j].x, cy: points[j].y });\n });\n group.querySelectorAll<SVGTextElement>('.prism-radar-value').forEach((text, j) => {\n const r = radius * row[j] + VALUE_OFFSET;\n\n setAttributes(text, { x: polarX(cx, r, angles[j]), y: polarY(cy, r, angles[j]) });\n });\n });\n }\n\n function renderGrid(domains: [number, number][]): void {\n gridGroup.replaceChildren();\n\n if (!grid) return;\n\n const { cx, cy, radius } = layout;\n const levels = Math.max(1, Math.round(grid.levels));\n const rings = Array.from({ length: levels }, (_, k) =>\n ringPath(grid.shape, cx, cy, (radius * (k + 1)) / levels, angles),\n );\n\n if (grid.bands) {\n // Shade alternate rings, starting from the outermost.\n for (let k = levels - 1; k >= 0; k -= 2) {\n gridGroup.appendChild(\n createSvgElement('path', {\n class: 'prism-radar-band',\n d: `${rings[k]}${rings[k - 1] ?? ''}`,\n 'fill-rule': 'evenodd',\n }),\n );\n }\n }\n\n for (const d of rings)\n gridGroup.appendChild(createSvgElement('path', { class: 'prism-radar-ring', d, fill: 'none' }));\n\n angles.forEach((angle, i) => {\n gridGroup.appendChild(\n createSvgElement('line', {\n class: 'prism-radar-spoke',\n 'data-axis': i,\n x1: cx,\n x2: polarX(cx, radius, angle),\n y1: cy,\n y2: polarY(cy, radius, angle),\n }),\n );\n });\n\n const [d0, d1] = domains[0];\n const shared = domains.every(([a, b]) => a === d0 && b === d1);\n\n if (!grid.labels || !shared) return;\n\n // Between the first two spokes, so level values never collide with vertex values.\n const angle = angles[0] + Math.PI / angles.length;\n\n for (let k = 1; k <= levels; k++) {\n const r = (radius * k) / levels;\n const text = createSvgElement('text', {\n class: 'prism-radar-level',\n 'dominant-baseline': 'middle',\n 'text-anchor': 'middle',\n x: polarX(cx, r, angle),\n y: polarY(cy, r, angle),\n });\n\n text.textContent = formatValue(0, Math.round((d0 + ((d1 - d0) * k) / levels) * 100) / 100);\n gridGroup.appendChild(text);\n }\n }\n\n function renderLabels(): void {\n labelGroup.replaceChildren();\n\n const { cx, cy, radius } = layout;\n\n axes.forEach((axis, i) => {\n const { anchor, baseline } = labelPlacement(angles[i]);\n const text = createSvgElement('text', {\n class: 'prism-radar-axis-label',\n 'dominant-baseline': baseline,\n 'text-anchor': anchor,\n x: polarX(cx, radius + labelGap, angles[i]),\n y: polarY(cy, radius + labelGap, angles[i]),\n });\n\n text.textContent = axis.label;\n labelGroup.appendChild(text);\n });\n }\n\n function renderSeries(): void {\n const { cx, cy, radius } = layout;\n\n defs.replaceChildren();\n\n while (seriesGroup.children.length > series.length) seriesGroup.lastChild?.remove();\n\n series.forEach((s, i) => {\n const color = s.color ?? seriesColor(i);\n let group = seriesGroup.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-radar-series' });\n seriesGroup.appendChild(group);\n }\n\n group.setAttribute('data-series-id', seriesDomId(s, i));\n\n group.replaceChildren();\n\n const area = createSvgElement('path', {\n class: `prism-radar-area prism-radar-area--${fill}`,\n stroke: color,\n 'stroke-linejoin': 'round',\n 'stroke-width': 2,\n });\n\n if (fill === 'gradient') {\n const gradientId = `${id}-fill-${i}`;\n const gradient = createSvgElement('radialGradient', {\n cx,\n cy,\n gradientUnits: 'userSpaceOnUse',\n id: gradientId,\n r: radius,\n });\n\n for (const [offset, opacity] of [\n [0, 0.08],\n [1, 0.55],\n ]) {\n gradient.appendChild(\n createSvgElement('stop', {\n offset,\n 'stop-color': color,\n 'stop-opacity': opacity,\n style: `stop-color:${color}`,\n }),\n );\n }\n\n defs.appendChild(gradient);\n setAttributes(area, { fill: `url(#${gradientId})` });\n } else {\n setAttributes(area, { fill: fill === 'none' ? 'none' : color, 'fill-opacity': 0.25 });\n }\n\n group.appendChild(area);\n\n if (showPoints) {\n axes.forEach((_, j) => {\n const missing = !Number.isFinite(datumAt(s, j)?.value);\n\n group.appendChild(\n createSvgElement('circle', {\n class: `prism-radar-point${missing ? ' prism-radar-point--missing' : ''}`,\n 'data-axis': j,\n fill: missing ? 'none' : color,\n r: 3,\n stroke: color,\n }),\n );\n });\n }\n\n if (config.showValues) {\n axes.forEach((_, j) => {\n const datum = datumAt(s, j);\n const { anchor, baseline } = labelPlacement(angles[j]);\n const text = createSvgElement('text', {\n 'aria-hidden': 'true',\n class: 'prism-radar-value',\n 'dominant-baseline': baseline,\n 'text-anchor': anchor,\n });\n\n text.textContent = datum && Number.isFinite(datum.value) ? formatValue(j, datum.value) : '';\n group.appendChild(text);\n });\n }\n });\n }\n\n function setActive(index: number): void {\n activeIndex = index;\n for (const el of root.querySelectorAll('[data-axis]')) {\n const active = Number(el.getAttribute('data-axis')) === index;\n\n el.classList.toggle(el.tagName === 'line' ? 'prism-radar-spoke--active' : 'prism-radar-point--active', active);\n }\n }\n\n function animateTo(targets: number[][], signal: AbortSignal): void {\n activeTween?.();\n\n const from = targets.map((row, i) => row.map((_, j) => drawn[i]?.[j] ?? 0));\n // Radar morphs a whole polygon, so it reads better slightly slower than the shared default.\n const motion = resolveMotion(config.transition, { defaultDuration: 400 });\n const easing = resolveEasing(motion.easing ?? 'ease-out');\n const unchanged = from.every((row, i) => row.every((v, j) => v === targets[i][j]));\n\n if (motion.duration === 0 || unchanged) {\n drawn = targets;\n draw(targets);\n\n return;\n }\n\n activeTween = startTween({\n count: targets.length,\n duration: motion.duration,\n easing,\n onFrame: (progress) => {\n drawn = targets.map((row, i) => {\n const e = progress(i);\n\n return row.map((to, j) => tweenNumber(from[i][j], to, e));\n });\n draw(drawn);\n },\n signal,\n stagger: motion.stagger,\n });\n }\n\n return createRadialScaffold(\n container,\n { a11y: config.a11y, legend: config.legend, tooltip: config.tooltip },\n (ctx): ChartEventHandlers | undefined => {\n const { legend, svg, tooltip } = ctx;\n\n if (!svg.contains(root)) svg.appendChild(root);\n\n tooltip?.hide();\n legend?.update(series.map((s, i) => ({ color: s.color ?? seriesColor(i), name: s.name })));\n\n if (axes.length < 3) {\n for (const group of [defs, gridGroup, seriesGroup, labelGroup]) group.replaceChildren();\n drawn = [];\n\n return undefined;\n }\n\n const { height, width } = ctx.dimensions;\n const radius = fitRadius(\n width,\n height,\n axes.map((axis) => axis.label),\n angles,\n LABEL_FONT_SIZE,\n labelGap,\n );\n\n layout = { cx: width / 2, cy: height / 2, radius };\n\n const domains = resolveAxisDomains(axes, series, config.domain);\n\n renderGrid(domains);\n renderLabels();\n renderSeries();\n animateTo(\n series.map((s) =>\n axes.map((_, j) => {\n const value = datumAt(s, j)?.value;\n\n return value !== undefined && Number.isFinite(value) ? normalize(value, domains[j]) : 0;\n }),\n ),\n ctx.disposalSignal,\n );\n setActive(activeIndex);\n\n const eventFor = (index: number, originalEvent: Event): RadarEvent => ({\n axis: axes[index],\n index,\n originalEvent,\n values: valuesAt(index),\n });\n\n const activate = (index: number, originalEvent: Event): void => {\n setActive(index);\n config.onHover?.(eventFor(index, originalEvent));\n\n const text = describe(index);\n\n if (!tooltip) {\n ctx.announcer.announce(text);\n\n return;\n }\n\n const reach = Math.max(0, ...drawn.map((row) => row[index] ?? 0));\n const svgRect = svg.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n const values = valuesAt(index);\n const first = values.find((v) => v.datum)?.datum;\n const rows = values.flatMap(({ datum, series: s }) =>\n datum\n ? [\n {\n color: s.color ?? seriesColor(series.indexOf(s)),\n name: s.name,\n value: formatValue(index, datum.value),\n },\n ]\n : [],\n );\n\n tooltip.show(\n polarX(layout.cx, layout.radius * reach, angles[index]) + (svgRect.left - containerRect.left),\n polarY(layout.cy, layout.radius * reach, angles[index]) + (svgRect.top - containerRect.top),\n { key: axes[index].key, meta: { axis: axes[index], text, values }, value: first?.value ?? 0 },\n { color: series[0]?.color ?? seriesColor(0), data: [], name: axes[index].label },\n comparisonContent(svg.ownerDocument, axes[index].label, rows, text),\n );\n };\n\n const deactivate = (): void => {\n setActive(-1);\n config.onHover?.(null);\n tooltip?.hide();\n ctx.announcer.clear();\n };\n\n const hitIndex = (event: MouseEvent): number => {\n const rect = svg.getBoundingClientRect();\n const dx = event.clientX - rect.left - layout.cx;\n const dy = event.clientY - rect.top - layout.cy;\n\n if (Math.hypot(dx, dy) > layout.radius + labelGap + LABEL_FONT_SIZE * 2) return -1;\n\n return nearestAxis(dx, dy, axes.length, startAngle);\n };\n\n return {\n onClick(event) {\n const index = hitIndex(event);\n\n if (index >= 0) config.onClick?.(eventFor(index, event));\n },\n onKeyDown(event) {\n const step = ARROW_STEPS[event.key];\n\n if (step !== undefined) {\n event.preventDefault();\n activate(activeIndex < 0 ? 0 : (activeIndex + step + axes.length) % axes.length, event);\n } else if ((event.key === 'Enter' || event.key === ' ') && activeIndex >= 0 && config.onClick) {\n event.preventDefault();\n config.onClick(eventFor(activeIndex, event));\n } else if (event.key === 'Escape') {\n deactivate();\n }\n },\n onMouseLeave: deactivate,\n onMouseMove(event) {\n const index = hitIndex(event);\n\n if (index < 0) {\n if (activeIndex >= 0) deactivate();\n } else if (index !== activeIndex) {\n activate(index, event);\n }\n },\n };\n },\n (next) => {\n series = next;\n warnOnInvalid(axes, series);\n },\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"radar-chart.js","names":["LABEL_FONT_SIZE","LABEL_GAP","VALUE_OFFSET","ARROW_STEPS","grid","config","curve","fill","showPoints","startAngle","toRadians","angles","axisAngles","axes","labelGap","id","uniqueId","series","root","createSvgElement","defs","gridGroup","seriesGroup","labelGroup","drawn","activeTween","activeIndex","layout","s","d","index","value","describeValues","group","i","points","radarPoints","row","cx","cy","radius","closedPath","dot","j","r","text","polarX","polarY","levels","rings","ringPath","k","angle","d0","d1","domains","shared","a","b","labelPlacement","baseline","anchor","axis","color","seriesColor","seriesDomId","area","gradientId","gradient","offset","opacity","setAttributes","missing","datum","el","active","from","targets","motion","resolveMotion","easing","resolveEasing","unchanged","v","startTween","e","progress","tweenNumber","to","createRadialScaffold","container","ctx","svg","tooltip","legend","fitRadius","width","height","resolveAxisDomains","normalize","originalEvent","reach","svgRect","containerRect","values","first","rows","comparisonContent","rect","dx","event","dy","nearestAxis","step","next"],"sources":["../../../src/charts/radar/radar-chart.ts"],"sourcesContent":["import { devOnly, warn } from '../../_dev';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { startTween } from '../../animation/transition';\nimport { tweenNumber } from '../../animation/tween';\nimport type { ChartEventHandlers } from '../../core/chart-scaffold';\nimport { createRadialScaffold } from '../../core/chart-scaffold';\nimport { uniqueId } from '../../core/ids';\nimport { polarX, polarY } from '../../core/polar';\nimport { seriesDomId } from '../../core/series-id';\nimport { describeValues } from '../../interaction/announcer';\nimport { comparisonContent } from '../../interaction/tooltip';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { seriesColor } from '../../theme';\nimport type {\n ChartHandle,\n RadarAxisConfig,\n RadarAxisValue,\n RadarChartConfig,\n RadarEvent,\n RadarGridConfig,\n RadarSeriesConfig,\n} from '../../types';\nimport {\n axisAngles,\n closedPath,\n fitRadius,\n labelPlacement,\n nearestAxis,\n normalize,\n radarPoints,\n resolveAxisDomains,\n ringPath,\n toRadians,\n} from './radar-geometry';\n\n/** Default `--prism-font-size-label` (0.6875rem) in px, used to reserve label room. */\nconst LABEL_FONT_SIZE = 11;\nconst LABEL_GAP = 12;\nconst VALUE_OFFSET = 10;\nconst ARROW_STEPS: Record<string, number> = { ArrowDown: 1, ArrowLeft: -1, ArrowRight: 1, ArrowUp: -1 };\n\nfunction warnOnInvalid(axes: readonly RadarAxisConfig[], series: readonly RadarSeriesConfig[]): void {\n devOnly(() => {\n if (axes.length < 3) warn(`Radar chart needs at least 3 axes, received ${axes.length}.`);\n\n const keys = new Set(axes.map((axis) => axis.key));\n\n if (keys.size !== axes.length) warn('Radar chart axis keys must be unique.');\n\n for (const s of series) {\n for (const d of s.data) {\n if (!keys.has(d.key)) warn(`Radar series \"${s.name}\" has a value for unknown axis \"${d.key}\".`);\n }\n }\n });\n}\n\nfunction resolveGrid(grid: RadarChartConfig['grid']): Required<RadarGridConfig> | null {\n if (grid === false) return null;\n\n return { bands: true, labels: false, levels: 4, shape: 'polygon', ...(typeof grid === 'object' ? grid : {}) };\n}\n\nexport function createRadarChart(container: HTMLElement, config: RadarChartConfig): ChartHandle<RadarSeriesConfig[]> {\n const { axes } = config;\n const curve = config.curve ?? 'linear';\n const fill = config.fill ?? 'solid';\n const showPoints = config.showPoints ?? true;\n const grid = resolveGrid(config.grid);\n const startAngle = toRadians(config.startAngle ?? 0);\n const angles = axisAngles(axes.length, startAngle);\n const labelGap = LABEL_GAP + (config.showValues ? VALUE_OFFSET : 0);\n const id = uniqueId('prism-radar');\n let series = config.series;\n\n warnOnInvalid(axes, series);\n\n const root = createSvgElement('g', { class: 'prism-radar' });\n const defs = createSvgElement('defs');\n const gridGroup = createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-radar-grid' });\n const seriesGroup = createSvgElement('g', { class: 'prism-radar-series-group' });\n const labelGroup = createSvgElement('g', { 'aria-hidden': 'true', class: 'prism-radar-labels' });\n\n root.append(defs, gridGroup, seriesGroup, labelGroup);\n\n let drawn: number[][] = [];\n let activeTween: (() => void) | null = null;\n let activeIndex = -1;\n let layout = { cx: 0, cy: 0, radius: 0 };\n\n const datumAt = (s: RadarSeriesConfig, index: number) => s.data.find((d) => d.key === axes[index].key);\n const valuesAt = (index: number): RadarAxisValue[] => series.map((s) => ({ datum: datumAt(s, index), series: s }));\n const formatValue = (index: number, value: number): string => axes[index].format?.(value) ?? String(value);\n const describe = (index: number): string =>\n describeValues(axes[index].label, valuesAt(index), (value) => formatValue(index, value));\n\n function draw(fractions: number[][]): void {\n const { cx, cy, radius } = layout;\n\n fractions.forEach((row, i) => {\n const group = seriesGroup.children[i];\n\n if (!group) return;\n\n const points = radarPoints(row, cx, cy, radius, angles);\n\n group.querySelector('.prism-radar-area')?.setAttribute('d', closedPath(points, curve));\n group.querySelectorAll<SVGCircleElement>('.prism-radar-point').forEach((dot, j) => {\n setAttributes(dot, { cx: points[j].x, cy: points[j].y });\n });\n group.querySelectorAll<SVGTextElement>('.prism-radar-value').forEach((text, j) => {\n const r = radius * row[j] + VALUE_OFFSET;\n\n setAttributes(text, { x: polarX(cx, r, angles[j]), y: polarY(cy, r, angles[j]) });\n });\n });\n }\n\n function renderGrid(domains: [number, number][]): void {\n gridGroup.replaceChildren();\n\n if (!grid) return;\n\n const { cx, cy, radius } = layout;\n const levels = Math.max(1, Math.round(grid.levels));\n const rings = Array.from({ length: levels }, (_, k) =>\n ringPath(grid.shape, cx, cy, (radius * (k + 1)) / levels, angles),\n );\n\n if (grid.bands) {\n // Shade alternate rings, starting from the outermost.\n for (let k = levels - 1; k >= 0; k -= 2) {\n gridGroup.appendChild(\n createSvgElement('path', {\n class: 'prism-radar-band',\n d: `${rings[k]}${rings[k - 1] ?? ''}`,\n 'fill-rule': 'evenodd',\n }),\n );\n }\n }\n\n for (const d of rings)\n gridGroup.appendChild(createSvgElement('path', { class: 'prism-radar-ring', d, fill: 'none' }));\n\n angles.forEach((angle, i) => {\n gridGroup.appendChild(\n createSvgElement('line', {\n class: 'prism-radar-spoke',\n 'data-axis': i,\n x1: cx,\n x2: polarX(cx, radius, angle),\n y1: cy,\n y2: polarY(cy, radius, angle),\n }),\n );\n });\n\n const [d0, d1] = domains[0];\n const shared = domains.every(([a, b]) => a === d0 && b === d1);\n\n if (!grid.labels || !shared) return;\n\n // Between the first two spokes, so level values never collide with vertex values.\n const angle = angles[0] + Math.PI / angles.length;\n\n for (let k = 1; k <= levels; k++) {\n const r = (radius * k) / levels;\n const text = createSvgElement('text', {\n class: 'prism-radar-level',\n 'dominant-baseline': 'middle',\n 'text-anchor': 'middle',\n x: polarX(cx, r, angle),\n y: polarY(cy, r, angle),\n });\n\n text.textContent = formatValue(0, Math.round((d0 + ((d1 - d0) * k) / levels) * 100) / 100);\n gridGroup.appendChild(text);\n }\n }\n\n function renderLabels(): void {\n labelGroup.replaceChildren();\n\n const { cx, cy, radius } = layout;\n\n axes.forEach((axis, i) => {\n const { anchor, baseline } = labelPlacement(angles[i]);\n const text = createSvgElement('text', {\n class: 'prism-radar-axis-label',\n 'dominant-baseline': baseline,\n 'text-anchor': anchor,\n x: polarX(cx, radius + labelGap, angles[i]),\n y: polarY(cy, radius + labelGap, angles[i]),\n });\n\n text.textContent = axis.label;\n labelGroup.appendChild(text);\n });\n }\n\n function renderSeries(): void {\n const { cx, cy, radius } = layout;\n\n defs.replaceChildren();\n\n while (seriesGroup.children.length > series.length) seriesGroup.lastChild?.remove();\n\n series.forEach((s, i) => {\n const color = s.color ?? seriesColor(i);\n let group = seriesGroup.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-radar-series' });\n seriesGroup.appendChild(group);\n }\n\n group.setAttribute('data-series-id', seriesDomId(s, i));\n\n group.replaceChildren();\n\n const area = createSvgElement('path', {\n class: `prism-radar-area prism-radar-area--${fill}`,\n stroke: color,\n 'stroke-linejoin': 'round',\n 'stroke-width': 2,\n });\n\n if (fill === 'gradient') {\n const gradientId = `${id}-fill-${i}`;\n const gradient = createSvgElement('radialGradient', {\n cx,\n cy,\n gradientUnits: 'userSpaceOnUse',\n id: gradientId,\n r: radius,\n });\n\n for (const [offset, opacity] of [\n [0, 0.08],\n [1, 0.55],\n ]) {\n gradient.appendChild(\n createSvgElement('stop', {\n offset,\n 'stop-color': color,\n 'stop-opacity': opacity,\n style: `stop-color:${color}`,\n }),\n );\n }\n\n defs.appendChild(gradient);\n setAttributes(area, { fill: `url(#${gradientId})` });\n } else {\n setAttributes(area, { fill: fill === 'none' ? 'none' : color, 'fill-opacity': 0.25 });\n }\n\n group.appendChild(area);\n\n if (showPoints) {\n axes.forEach((_, j) => {\n const missing = !Number.isFinite(datumAt(s, j)?.value);\n\n group.appendChild(\n createSvgElement('circle', {\n class: `prism-radar-point${missing ? ' prism-radar-point--missing' : ''}`,\n 'data-axis': j,\n fill: missing ? 'none' : color,\n r: 3,\n stroke: color,\n }),\n );\n });\n }\n\n if (config.showValues) {\n axes.forEach((_, j) => {\n const datum = datumAt(s, j);\n const { anchor, baseline } = labelPlacement(angles[j]);\n const text = createSvgElement('text', {\n 'aria-hidden': 'true',\n class: 'prism-radar-value',\n 'dominant-baseline': baseline,\n 'text-anchor': anchor,\n });\n\n text.textContent = datum && Number.isFinite(datum.value) ? formatValue(j, datum.value) : '';\n group.appendChild(text);\n });\n }\n });\n }\n\n function setActive(index: number): void {\n activeIndex = index;\n for (const el of root.querySelectorAll('[data-axis]')) {\n const active = Number(el.getAttribute('data-axis')) === index;\n\n el.classList.toggle(el.tagName === 'line' ? 'prism-radar-spoke--active' : 'prism-radar-point--active', active);\n }\n }\n\n function animateTo(targets: number[][], signal: AbortSignal): void {\n activeTween?.();\n\n const from = targets.map((row, i) => row.map((_, j) => drawn[i]?.[j] ?? 0));\n // Radar morphs a whole polygon, so it reads better slightly slower than the shared default.\n const motion = resolveMotion(config.transition, { defaultDuration: 400 });\n const easing = resolveEasing(motion.easing ?? 'ease-out');\n const unchanged = from.every((row, i) => row.every((v, j) => v === targets[i][j]));\n\n if (motion.duration === 0 || unchanged) {\n drawn = targets;\n draw(targets);\n\n return;\n }\n\n activeTween = startTween({\n count: targets.length,\n duration: motion.duration,\n easing,\n onFrame: (progress) => {\n drawn = targets.map((row, i) => {\n const e = progress(i);\n\n return row.map((to, j) => tweenNumber(from[i][j], to, e));\n });\n draw(drawn);\n },\n signal,\n stagger: motion.stagger,\n });\n }\n\n return createRadialScaffold(\n container,\n { a11y: config.a11y, legend: config.legend, tooltip: config.tooltip },\n (ctx): ChartEventHandlers | undefined => {\n const { legend, svg, tooltip } = ctx;\n\n if (!svg.contains(root)) svg.appendChild(root);\n\n tooltip?.hide();\n legend?.update(series.map((s, i) => ({ color: s.color ?? seriesColor(i), name: s.name })));\n\n if (axes.length < 3) {\n for (const group of [defs, gridGroup, seriesGroup, labelGroup]) group.replaceChildren();\n drawn = [];\n\n return undefined;\n }\n\n const { height, width } = ctx.dimensions;\n const radius = fitRadius(\n width,\n height,\n axes.map((axis) => axis.label),\n angles,\n LABEL_FONT_SIZE,\n labelGap,\n );\n\n layout = { cx: width / 2, cy: height / 2, radius };\n\n const domains = resolveAxisDomains(axes, series, config.domain);\n\n renderGrid(domains);\n renderLabels();\n renderSeries();\n animateTo(\n series.map((s) =>\n axes.map((_, j) => {\n const value = datumAt(s, j)?.value;\n\n return value !== undefined && Number.isFinite(value) ? normalize(value, domains[j]) : 0;\n }),\n ),\n ctx.disposalSignal,\n );\n setActive(activeIndex);\n\n const eventFor = (index: number, originalEvent: Event): RadarEvent => ({\n axis: axes[index],\n index,\n originalEvent,\n values: valuesAt(index),\n });\n\n const activate = (index: number, originalEvent: Event): void => {\n setActive(index);\n config.onHover?.(eventFor(index, originalEvent));\n\n const text = describe(index);\n\n if (!tooltip) {\n ctx.announcer.announce(text);\n\n return;\n }\n\n const reach = Math.max(0, ...drawn.map((row) => row[index] ?? 0));\n const svgRect = svg.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n const values = valuesAt(index);\n const first = values.find((v) => v.datum)?.datum;\n const rows = values.flatMap(({ datum, series: s }) =>\n datum\n ? [\n {\n color: s.color ?? seriesColor(series.indexOf(s)),\n name: s.name,\n value: formatValue(index, datum.value),\n },\n ]\n : [],\n );\n\n tooltip.show(\n polarX(layout.cx, layout.radius * reach, angles[index]) + (svgRect.left - containerRect.left),\n polarY(layout.cy, layout.radius * reach, angles[index]) + (svgRect.top - containerRect.top),\n { key: axes[index].key, meta: { axis: axes[index], text, values }, value: first?.value ?? 0 },\n { color: series[0]?.color ?? seriesColor(0), data: [], name: axes[index].label },\n comparisonContent(svg.ownerDocument, axes[index].label, rows, text),\n );\n };\n\n const deactivate = (): void => {\n setActive(-1);\n config.onHover?.(null);\n tooltip?.hide();\n ctx.announcer.clear();\n };\n\n const hitIndex = (event: MouseEvent): number => {\n const rect = svg.getBoundingClientRect();\n const dx = event.clientX - rect.left - layout.cx;\n const dy = event.clientY - rect.top - layout.cy;\n\n if (Math.hypot(dx, dy) > layout.radius + labelGap + LABEL_FONT_SIZE * 2) return -1;\n\n return nearestAxis(dx, dy, axes.length, startAngle);\n };\n\n return {\n onClick(event) {\n const index = hitIndex(event);\n\n if (index >= 0) config.onClick?.(eventFor(index, event));\n },\n onKeyDown(event) {\n const step = ARROW_STEPS[event.key];\n\n if (step !== undefined) {\n event.preventDefault();\n activate(activeIndex < 0 ? 0 : (activeIndex + step + axes.length) % axes.length, event);\n } else if ((event.key === 'Enter' || event.key === ' ') && activeIndex >= 0 && config.onClick) {\n event.preventDefault();\n config.onClick(eventFor(activeIndex, event));\n } else if (event.key === 'Escape') {\n deactivate();\n }\n },\n onMouseLeave: deactivate,\n onMouseMove(event) {\n const index = hitIndex(event);\n\n if (index < 0) {\n if (activeIndex >= 0) deactivate();\n } else if (index !== activeIndex) {\n activate(index, event);\n }\n },\n };\n },\n (next) => {\n series = next;\n warnOnInvalid(axes, series);\n },\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"radar-geometry.cjs","names":[],"sources":["../../../src/charts/radar/radar-geometry.ts"],"sourcesContent":["import { polarX, polarY } from '../../core/polar';\nimport { linearScale } from '../../scales/linear';\nimport type { Point } from '../../svg/path';\nimport { estimateTextWidth } from '../../svg/text';\nimport type { RadarAxisConfig, RadarSeriesConfig } from '../../types';\n\nconst TWO_PI = 2 * Math.PI;\n\nexport type LabelAnchor = 'end' | 'middle' | 'start';\nexport type LabelBaseline = 'auto' | 'hanging' | 'middle';\n\nexport function toRadians(degrees: number): number {\n return (degrees * Math.PI) / 180;\n}\n\nexport function axisAngles(count: number, startAngle = 0): number[] {\n return Array.from({ length: count }, (_, i) => startAngle + (i * TWO_PI) / count);\n}\n\n/** Per-axis `[min, max]`: axis overrides win over `domain`, which wins over a nice range around the data. */\nexport function resolveAxisDomains(\n axes: readonly RadarAxisConfig[],\n series: readonly RadarSeriesConfig[],\n domain?: [number, number],\n): [number, number][] {\n let shared = domain;\n\n if (!shared) {\n const values = series.flatMap((s) => s.data.map((d) => d.value)).filter(Number.isFinite);\n const min = Math.min(0, ...values);\n const max = values.length ? Math.max(...values) : 1;\n\n shared = linearScale({ domain: [min, max > min ? max : min + 1], range: [0, 1] }).domain as [number, number];\n }\n\n return axes.map((axis) => [axis.min ?? shared[0], axis.max ?? shared[1]]);\n}\n\nexport function normalize(value: number, [min, max]: readonly [number, number]): number {\n if (max === min) return 0;\n\n return Math.max(0, Math.min(1, (value - min) / (max - min)));\n}\n\nexport function radarPoints(\n fractions: readonly number[],\n cx: number,\n cy: number,\n radius: number,\n angles: readonly number[],\n): Point[] {\n return fractions.map((f, i) => ({ x: polarX(cx, radius * f, angles[i]), y: polarY(cy, radius * f, angles[i]) }));\n}\n\n/** Closed outline through every point; `rounded` uses a closed Catmull–Rom spline. */\nexport function closedPath(points: readonly Point[], curve: 'linear' | 'rounded' = 'linear'): string {\n const n = points.length;\n\n if (n === 0) return '';\n\n const [first] = points;\n\n if (curve === 'linear' || n < 3) {\n return `M${first.x},${first.y}${points\n .slice(1)\n .map((p) => `L${p.x},${p.y}`)\n .join('')}Z`;\n }\n\n let d = `M${first.x},${first.y}`;\n\n for (let i = 0; i < n; i++) {\n const p0 = points[(i - 1 + n) % n];\n const p1 = points[i];\n const p2 = points[(i + 1) % n];\n const p3 = points[(i + 2) % n];\n\n d += `C${p1.x + (p2.x - p0.x) / 6},${p1.y + (p2.y - p0.y) / 6} ${p2.x - (p3.x - p1.x) / 6},${p2.y - (p3.y - p1.y) / 6} ${p2.x},${p2.y}`;\n }\n\n return `${d}Z`;\n}\n\nexport function ringPath(\n shape: 'circle' | 'polygon',\n cx: number,\n cy: number,\n r: number,\n angles: readonly number[],\n): string {\n if (r <= 0) return '';\n\n if (shape === 'circle') return `M${cx},${cy - r}A${r},${r} 0 1 1 ${cx},${cy + r}A${r},${r} 0 1 1 ${cx},${cy - r}Z`;\n\n return closedPath(\n radarPoints(\n angles.map(() => 1),\n cx,\n cy,\n r,\n angles,\n ),\n );\n}\n\nexport function labelPlacement(angle: number): { anchor: LabelAnchor; baseline: LabelBaseline } {\n const sin = Math.sin(angle);\n const cos = Math.cos(angle);\n\n return {\n anchor: Math.abs(sin) < 0.1 ? 'middle' : sin > 0 ? 'start' : 'end',\n baseline: cos > 0.9 ? 'auto' : cos < -0.9 ? 'hanging' : 'middle',\n };\n}\n\n/** Largest radius that leaves room for the axis labels around it. */\nexport function fitRadius(\n width: number,\n height: number,\n labels: readonly string[],\n angles: readonly number[],\n fontSize: number,\n gap: number,\n): number {\n let side = 0;\n\n labels.forEach((label, i) => {\n if (labelPlacement(angles[i]).anchor !== 'middle') side = Math.max(side, estimateTextWidth(label, fontSize));\n });\n\n const lineHeight = fontSize * 1.3;\n\n return Math.max(8, Math.min(width / 2 - gap - side, height / 2 - gap - lineHeight));\n}\n\n/** Index of the axis closest in angle to the offset `(dx, dy)` from the centre. */\nexport function nearestAxis(dx: number, dy: number, count: number, startAngle = 0): number {\n if (count === 0) return -1;\n\n const step = TWO_PI / count;\n const angle = (((Math.atan2(dx, -dy) - startAngle) % TWO_PI) + TWO_PI) % TWO_PI;\n\n return Math.round(angle / step) % count;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"radar-geometry.cjs","names":["linearScale","polarX","polarY","estimateTextWidth","require_text","require_linear","require_polar","TWO_PI","degrees","count","startAngle","shared","domain","values","series","s","d","min","max","axes","axis","value","fractions","cx","radius","f","angles","i","cy","points","first","curve","p","p0","p1","p2","p3","shape","sin","angle","cos","side","labels","label","fontSize","lineHeight","width","gap","height","step","dx","dy"],"sources":["../../../src/charts/radar/radar-geometry.ts"],"sourcesContent":["import { polarX, polarY } from '../../core/polar';\nimport { linearScale } from '../../scales/linear';\nimport type { Point } from '../../svg/path';\nimport { estimateTextWidth } from '../../svg/text';\nimport type { RadarAxisConfig, RadarSeriesConfig } from '../../types';\n\nconst TWO_PI = 2 * Math.PI;\n\nexport type LabelAnchor = 'end' | 'middle' | 'start';\nexport type LabelBaseline = 'auto' | 'hanging' | 'middle';\n\nexport function toRadians(degrees: number): number {\n return (degrees * Math.PI) / 180;\n}\n\nexport function axisAngles(count: number, startAngle = 0): number[] {\n return Array.from({ length: count }, (_, i) => startAngle + (i * TWO_PI) / count);\n}\n\n/** Per-axis `[min, max]`: axis overrides win over `domain`, which wins over a nice range around the data. */\nexport function resolveAxisDomains(\n axes: readonly RadarAxisConfig[],\n series: readonly RadarSeriesConfig[],\n domain?: [number, number],\n): [number, number][] {\n let shared = domain;\n\n if (!shared) {\n const values = series.flatMap((s) => s.data.map((d) => d.value)).filter(Number.isFinite);\n const min = Math.min(0, ...values);\n const max = values.length ? Math.max(...values) : 1;\n\n shared = linearScale({ domain: [min, max > min ? max : min + 1], range: [0, 1] }).domain as [number, number];\n }\n\n return axes.map((axis) => [axis.min ?? shared[0], axis.max ?? shared[1]]);\n}\n\nexport function normalize(value: number, [min, max]: readonly [number, number]): number {\n if (max === min) return 0;\n\n return Math.max(0, Math.min(1, (value - min) / (max - min)));\n}\n\nexport function radarPoints(\n fractions: readonly number[],\n cx: number,\n cy: number,\n radius: number,\n angles: readonly number[],\n): Point[] {\n return fractions.map((f, i) => ({ x: polarX(cx, radius * f, angles[i]), y: polarY(cy, radius * f, angles[i]) }));\n}\n\n/** Closed outline through every point; `rounded` uses a closed Catmull–Rom spline. */\nexport function closedPath(points: readonly Point[], curve: 'linear' | 'rounded' = 'linear'): string {\n const n = points.length;\n\n if (n === 0) return '';\n\n const [first] = points;\n\n if (curve === 'linear' || n < 3) {\n return `M${first.x},${first.y}${points\n .slice(1)\n .map((p) => `L${p.x},${p.y}`)\n .join('')}Z`;\n }\n\n let d = `M${first.x},${first.y}`;\n\n for (let i = 0; i < n; i++) {\n const p0 = points[(i - 1 + n) % n];\n const p1 = points[i];\n const p2 = points[(i + 1) % n];\n const p3 = points[(i + 2) % n];\n\n d += `C${p1.x + (p2.x - p0.x) / 6},${p1.y + (p2.y - p0.y) / 6} ${p2.x - (p3.x - p1.x) / 6},${p2.y - (p3.y - p1.y) / 6} ${p2.x},${p2.y}`;\n }\n\n return `${d}Z`;\n}\n\nexport function ringPath(\n shape: 'circle' | 'polygon',\n cx: number,\n cy: number,\n r: number,\n angles: readonly number[],\n): string {\n if (r <= 0) return '';\n\n if (shape === 'circle') return `M${cx},${cy - r}A${r},${r} 0 1 1 ${cx},${cy + r}A${r},${r} 0 1 1 ${cx},${cy - r}Z`;\n\n return closedPath(\n radarPoints(\n angles.map(() => 1),\n cx,\n cy,\n r,\n angles,\n ),\n );\n}\n\nexport function labelPlacement(angle: number): { anchor: LabelAnchor; baseline: LabelBaseline } {\n const sin = Math.sin(angle);\n const cos = Math.cos(angle);\n\n return {\n anchor: Math.abs(sin) < 0.1 ? 'middle' : sin > 0 ? 'start' : 'end',\n baseline: cos > 0.9 ? 'auto' : cos < -0.9 ? 'hanging' : 'middle',\n };\n}\n\n/** Largest radius that leaves room for the axis labels around it. */\nexport function fitRadius(\n width: number,\n height: number,\n labels: readonly string[],\n angles: readonly number[],\n fontSize: number,\n gap: number,\n): number {\n let side = 0;\n\n labels.forEach((label, i) => {\n if (labelPlacement(angles[i]).anchor !== 'middle') side = Math.max(side, estimateTextWidth(label, fontSize));\n });\n\n const lineHeight = fontSize * 1.3;\n\n return Math.max(8, Math.min(width / 2 - gap - side, height / 2 - gap - lineHeight));\n}\n\n/** Index of the axis closest in angle to the offset `(dx, dy)` from the centre. */\nexport function nearestAxis(dx: number, dy: number, count: number, startAngle = 0): number {\n if (count === 0) return -1;\n\n const step = TWO_PI / count;\n const angle = (((Math.atan2(dx, -dy) - startAngle) % TWO_PI) + TWO_PI) % TWO_PI;\n\n return Math.round(angle / step) % count;\n}\n"],"mappings":"A,6GAMA,IAAMO,EAAS,EAAI,KAAK,GAKxB,SAAgB,UAAU,EAAyB,CACjD,OAAQC,EAAU,KAAK,GAAM,GAC/B,CAEA,SAAgB,WAAW,EAAe,EAAa,EAAa,CAClE,OAAO,MAAM,KAAK,CAAE,OAAQC,CAAM,GAAI,EAAG,IAAMC,EAAc,EAAIH,EAAUE,CAAK,CAClF,CAGA,SAAgB,mBACd,EACA,EACA,EACoB,CACpB,IAAIE,EAASC,EAEb,GAAI,CAACD,EAAQ,CACX,IAAME,EAASC,EAAO,QAAS,GAAMC,EAAE,KAAK,IAAK,GAAMC,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,OAAO,QAAQ,EACjFC,EAAM,KAAK,IAAI,EAAG,GAAGJ,CAAM,EAC3BK,EAAML,EAAO,OAAS,KAAK,IAAI,GAAGA,CAAM,EAAI,EAElD,EAASb,EAAAA,YAAY,CAAE,OAAQ,CAACiB,EAAKC,EAAMD,EAAMC,EAAMD,EAAM,CAAC,EAAG,MAAO,CAAC,EAAG,CAAC,CAAE,CAAC,CAAC,CAAC,MACpF,CAEA,OAAOE,EAAK,IAAK,GAAS,CAACC,EAAK,KAAOT,EAAO,GAAIS,EAAK,KAAOT,EAAO,EAAE,CAAC,CAC1E,CAEA,SAAgB,UAAU,EAAe,CAACM,EAAKC,GAAyC,CAGtF,OAFIA,IAAQD,EAAY,EAEjB,KAAK,IAAI,EAAG,KAAK,IAAI,GAAII,EAAQJ,IAAQC,EAAMD,EAAI,CAAC,CAC7D,CAEA,SAAgB,YACd,EACA,EACA,EACA,EACA,EACS,CACT,OAAOK,EAAU,KAAK,EAAG,KAAO,CAAE,EAAGrB,EAAAA,OAAOsB,EAAIC,EAASC,EAAGC,EAAOC,EAAE,EAAG,EAAGzB,EAAAA,OAAO0B,EAAIJ,EAASC,EAAGC,EAAOC,EAAE,CAAE,EAAE,CACjH,CAGA,SAAgB,WAAW,EAA0B,EAA8B,SAAkB,CACnG,IAAM,EAAIE,EAAO,OAEjB,GAAI,IAAM,EAAG,MAAO,GAEpB,GAAM,CAACC,GAASD,EAEhB,GAAIE,IAAU,UAAY,EAAI,EAC5B,MAAO,IAAID,EAAM,EAAE,GAAGA,EAAM,IAAID,EAC7B,MAAM,CAAC,CAAC,CACR,IAAK,GAAM,IAAIG,EAAE,EAAE,GAAGA,EAAE,GAAG,CAAC,CAC5B,KAAK,EAAE,EAAE,GAGd,IAAIhB,EAAI,IAAIc,EAAM,EAAE,GAAGA,EAAM,IAE7B,IAAK,IAAIH,EAAI,EAAGA,EAAI,EAAG,IAAK,CAC1B,IAAMM,EAAKJ,GAAQF,EAAI,EAAI,GAAK,GAC1BO,EAAKL,EAAOF,GACZQ,EAAKN,GAAQF,EAAI,GAAK,GACtBS,EAAKP,GAAQF,EAAI,GAAK,GAE5B,GAAK,IAAIO,EAAG,GAAKC,EAAG,EAAIF,EAAG,GAAK,EAAE,GAAGC,EAAG,GAAKC,EAAG,EAAIF,EAAG,GAAK,EAAE,GAAGE,EAAG,GAAKC,EAAG,EAAIF,EAAG,GAAK,EAAE,GAAGC,EAAG,GAAKC,EAAG,EAAIF,EAAG,GAAK,EAAE,GAAGC,EAAG,EAAE,GAAGA,EAAG,GACtI,CAEA,MAAO,GAAGnB,EAAE,EACd,CAEA,SAAgB,SACd,EACA,EACA,EACA,EACA,EACQ,CAKR,OAJI,GAAK,EAAU,GAEfqB,IAAU,SAAiB,IAAId,EAAG,GAAGK,EAAK,EAAE,GAAG,EAAE,GAAG,EAAE,SAASL,EAAG,GAAGK,EAAK,EAAE,GAAG,EAAE,GAAG,EAAE,SAASL,EAAG,GAAGK,EAAK,EAAE,GAEzG,WACL,YACEF,EAAO,QAAU,CAAC,EAClBH,EACAK,EACA,EACAF,CACF,CACF,CACF,CAEA,SAAgB,eAAe,EAAiE,CAC9F,IAAMY,EAAM,KAAK,IAAIC,CAAK,EACpBC,EAAM,KAAK,IAAID,CAAK,EAE1B,MAAO,CACL,OAAQ,KAAK,IAAID,CAAG,EAAI,GAAM,SAAWA,EAAM,EAAI,QAAU,MAC7D,SAAUE,EAAM,GAAM,OAASA,EAAM,IAAO,UAAY,QAC1D,CACF,CAGA,SAAgB,UACd,EACA,EACA,EACA,EACA,EACA,EACQ,CACR,IAAIC,EAAO,EAEXC,EAAO,SAAS,EAAO,IAAM,CACvB,eAAehB,EAAOC,EAAE,CAAC,CAAC,SAAW,WAAU,EAAO,KAAK,IAAIc,EAAMtC,EAAAA,kBAAkBwC,EAAOC,CAAQ,CAAC,EAC7G,CAAC,EAED,IAAMC,EAAaD,EAAW,IAE9B,OAAO,KAAK,IAAI,EAAG,KAAK,IAAIE,EAAQ,EAAIC,EAAMN,EAAMO,EAAS,EAAID,EAAMF,CAAU,CAAC,CACpF,CAGA,SAAgB,YAAY,EAAY,EAAY,EAAe,EAAa,EAAW,CACzF,GAAIpC,IAAU,EAAG,MAAO,GAExB,IAAMwC,EAAO1C,EAASE,EAChB8B,IAAW,KAAK,MAAMW,EAAI,CAACC,CAAE,EAAIzC,GAAcH,EAAUA,GAAUA,EAEzE,OAAO,KAAK,MAAMgC,EAAQU,CAAI,EAAIxC,CACpC,C"}