@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":"bar-chart.js","names":[],"sources":["../../../src/charts/bar/bar-chart.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { positionAxis, renderAxis, resolveTickCount, resolveTicks } from '../../axes/axis';\nimport { renderGrid } from '../../axes/grid';\nimport { normalizeCartesianSeries } from '../../core/cartesian-model';\nimport { clearCartesianDom, createChartScaffold } from '../../core/chart-scaffold';\nimport { chartArea } from '../../core/layout';\nimport { seriesDomId } from '../../core/series-id';\nimport { describeValues } from '../../interaction/announcer';\nimport { getMousePosition } from '../../interaction/events';\nimport { comparisonContent } from '../../interaction/tooltip';\nimport { bandScale } from '../../scales/band';\nimport { linearScale } from '../../scales/linear';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { seriesColor } from '../../theme';\nimport type {\n BarChartConfig,\n BarSeriesConfig,\n BarVariant,\n ChartEvent,\n ChartHandle,\n Datum,\n SeriesValue,\n XAxisConfig,\n YAxisConfig,\n} from '../../types';\nimport { findCatIdx, findSeriesIdx } from './bar-hit-test';\nimport { renderBars } from './bar-renderer';\nimport type { BarScaleContext } from './bar-scale-context';\n\nfunction variantFlags(variant: BarVariant): { horizontal: boolean; stacked: boolean } {\n return {\n horizontal: variant === 'grouped-horizontal' || variant === 'stacked-horizontal',\n stacked: variant === 'stacked' || variant === 'stacked-horizontal',\n };\n}\n\n// ─── Chart ────────────────────────────────────────────────────────────────────\n\nexport function createBarChart(container: HTMLElement, config: BarChartConfig): ChartHandle<BarSeriesConfig[]> {\n let seriesList = config.series;\n let band: SVGRectElement | null = null;\n\n return createChartScaffold(\n container,\n config,\n (ctx, reason) => {\n const { groups, legend, tooltip } = ctx;\n legend?.update(seriesList.map((s, i) => ({ color: seriesColor(i, s.color), name: s.name })));\n const dims = ctx.dimensions;\n const area = chartArea(dims.width, dims.height, dims.margin);\n const sourceData = seriesList.map((series) => series.data);\n const model = normalizeCartesianSeries(seriesList, sourceData);\n const categories = model.domain;\n const allData = model.series.map(({ byKey }) => categories.map((key) => byKey.get(key)));\n const categoryAxis = (axis: XAxisConfig | YAxisConfig) => {\n return {\n ...axis,\n tickFormat: (value: Date | number | string) => {\n const key = String(value);\n const label = model.labels.get(key) ?? value;\n\n return axis.tickFormat ? axis.tickFormat(label) : String(label);\n },\n };\n };\n\n if (categories.length === 0) {\n clearCartesianDom(groups, legend, tooltip);\n band?.remove();\n band = null;\n\n return;\n }\n\n const { horizontal, stacked } = variantFlags(config.variant ?? 'grouped');\n\n // Axes render by default; `false` opts out. The value axis (x when horizontal, y\n // otherwise) carries gridlines by default and merges over that default, so a partial\n // config (e.g. only `tickFormat`) keeps the gridlines; the category axis defaults to none.\n const xAxisConfig: XAxisConfig | false =\n config.xAxis === false ? false : horizontal ? { grid: true, ...config.xAxis } : (config.xAxis ?? {});\n const yAxisConfig: YAxisConfig | false =\n config.yAxis === false ? false : horizontal ? (config.yAxis ?? {}) : { grid: true, ...config.yAxis };\n\n // Value domain\n let vMax: number;\n let vMin: number;\n\n if (stacked) {\n if (allData.some((seriesData) => seriesData.some((datum) => (datum?.value ?? 0) < 0))) {\n warn(\n 'createBarChart: negative values in a stacked/stacked-horizontal series are clamped to 0: stacking mixed-sign data is not supported.',\n );\n }\n\n const sums = categories.map((_, categoryIndex) =>\n allData.reduce((sum, seriesData) => sum + Math.max(0, seriesData[categoryIndex]?.value ?? 0), 0),\n );\n\n vMax = Math.max(...sums);\n vMin = 0;\n } else {\n const allY = allData.flatMap((seriesData) => seriesData.flatMap((datum) => (datum ? [datum.value] : [])));\n\n vMax = Math.max(...allY);\n vMin = Math.min(0, ...allY);\n }\n\n // Build uniform scale context\n const catScale = horizontal\n ? bandScale({ domain: categories, range: [0, area.height] })\n : bandScale({ domain: categories, range: [0, area.width] });\n\n const valScale = horizontal\n ? linearScale({ domain: [vMin, vMax], range: [0, area.width] })\n : linearScale({ domain: [vMin, vMax], range: [area.height, 0] });\n\n const stackedTops: number[][] = [];\n const stackTops = Object.create(null) as Record<string, number>;\n\n for (const cat of categories) stackTops[cat] = 0;\n\n const sc: BarScaleContext = {\n bandCenter: (cat) => catScale.map(cat) + catScale.bandwidth() / 2,\n bandwidth: catScale.bandwidth(),\n baselinePx: valScale.map(0),\n horizontal,\n stacked,\n stackedTops,\n valueScale: valScale,\n };\n\n // Axes & grid\n if (horizontal) {\n if (xAxisConfig && xAxisConfig.grid) {\n renderGrid(\n groups.grid,\n valScale,\n xAxisConfig.grid,\n area.height,\n 'vertical',\n resolveTicks(valScale, xAxisConfig, resolveTickCount(xAxisConfig, area.width, 'bottom')),\n );\n }\n\n if (yAxisConfig !== false) {\n const yAxis = categoryAxis(yAxisConfig);\n\n positionAxis(groups.yAxis, yAxis.position ?? 'left', area.width, area.height);\n renderAxis(groups.yAxis, catScale, yAxis, area.height, 'left');\n }\n\n if (xAxisConfig) {\n positionAxis(groups.xAxis, xAxisConfig.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, valScale, xAxisConfig, area.width, 'bottom');\n }\n } else {\n if (yAxisConfig && yAxisConfig.grid) {\n renderGrid(\n groups.grid,\n valScale,\n yAxisConfig.grid,\n area.width,\n 'horizontal',\n resolveTicks(valScale, yAxisConfig, resolveTickCount(yAxisConfig, area.height, 'left')),\n );\n }\n\n if (xAxisConfig !== false) {\n const xAxis = categoryAxis(xAxisConfig);\n\n positionAxis(groups.xAxis, xAxis.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, catScale, xAxis, area.width, 'bottom');\n }\n\n if (yAxisConfig) {\n positionAxis(groups.yAxis, yAxisConfig.position ?? 'left', area.width, area.height);\n renderAxis(groups.yAxis, valScale, yAxisConfig, area.height, 'left');\n }\n }\n\n // Series groups\n // Stacked segments stay square so they join cleanly.\n const themeRadius = stacked\n ? 0\n : Number.parseFloat(getComputedStyle(ctx.svg).getPropertyValue('--prism-bar-radius')) || 0;\n\n while (groups.series.children.length > seriesList.length) {\n const last = groups.series.lastElementChild;\n\n if (last) groups.series.removeChild(last);\n }\n\n for (let i = 0; i < seriesList.length; i++) {\n const series = seriesList[i];\n let group = groups.series.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-bar-series' });\n groups.series.appendChild(group);\n }\n\n group.setAttribute('data-series-id', seriesDomId(series, i));\n\n const barData = categories.map((key, categoryIndex) => {\n const datum = allData[i]?.[categoryIndex];\n\n if (stacked) {\n const base = stackTops[key] ?? 0;\n const top = base + Math.max(0, datum?.value ?? 0);\n\n stackTops[key] = top;\n\n return { base, dash: datum?.dash, key, opacity: datum?.opacity, present: datum !== undefined, y: top };\n }\n\n return {\n base: 0,\n dash: datum?.dash,\n key,\n opacity: datum?.opacity,\n present: datum !== undefined,\n y: datum?.value ?? 0,\n };\n });\n\n stackedTops[i] = barData.map((d) => d.y);\n\n const baselineYs = stacked ? barData.map((d) => valScale.map(d.base)) : undefined;\n\n renderBars(group, barData, catScale, valScale, sc.baselinePx, {\n baselineYs,\n borderRadius: series.borderRadius ?? themeRadius,\n color: seriesColor(i, series.color),\n disposalSignal: ctx.disposalSignal,\n horizontal,\n seriesCount: seriesList.length,\n seriesIndex: i,\n stacked,\n transition: reason === 'resize' ? false : config.transition,\n });\n }\n\n tooltip?.hide();\n groups.series.classList.toggle('prism-bars-stacked', stacked);\n\n if (!band || !ctx.chartArea.contains(band)) {\n band = createSvgElement('rect', { 'aria-hidden': 'true', class: 'prism-bar-band', 'pointer-events': 'none' });\n ctx.chartArea.insertBefore(band, groups.series);\n }\n\n band.style.display = 'none';\n\n // ─── Event handlers (close over render-derived state) ─────────────────────\n\n const colors = seriesList.map((s, i) => seriesColor(i, s.color));\n const labelOf = (catIdx: number): string => String(model.labels.get(categories[catIdx]) ?? categories[catIdx]);\n const tooltipFormat = typeof config.tooltip === 'object' ? config.tooltip : undefined;\n const keyOf = (catIdx: number): Datum['key'] => model.labels.get(categories[catIdx]) ?? categories[catIdx];\n const titleOf = (catIdx: number): string =>\n tooltipFormat?.titleFormat ? tooltipFormat.titleFormat(keyOf(catIdx)) : labelOf(catIdx);\n const formatValue = tooltipFormat?.valueFormat ?? String;\n let activeCat = -1;\n\n const valuesAt = (catIdx: number): SeriesValue[] =>\n seriesList.map((series, si) => ({ datum: allData[si]?.[catIdx], series }));\n\n const eventAt = (catIdx: number, seriesIdx: number, originalEvent: Event): ChartEvent | null => {\n const values = valuesAt(catIdx);\n const preferred = values[seriesIdx]?.datum ? seriesIdx : values.findIndex((v) => v.datum);\n const datum = values[preferred]?.datum;\n\n return datum ? { datum, originalEvent, series: seriesList[preferred], values } : null;\n };\n\n const setActive = (catIdx: number): void => {\n activeCat = catIdx;\n groups.series.classList.toggle('prism-bars-focused', catIdx >= 0);\n\n for (const group of groups.series.children) {\n for (const [i, rect] of [...group.children].entries())\n rect.classList.toggle('prism-bar--active', i === catIdx);\n }\n\n if (!band) return;\n\n band.style.display = catIdx < 0 ? 'none' : '';\n\n if (catIdx < 0) return;\n\n const start = sc.bandCenter(categories[catIdx]) - catScale.bandwidth() / 2 - catScale.gap() / 2;\n const size = catScale.bandwidth() + catScale.gap();\n const a = chartArea(ctx.dimensions.width, ctx.dimensions.height, ctx.dimensions.margin);\n\n setAttributes(\n band,\n horizontal\n ? { height: size, width: a.width, x: 0, y: start }\n : { height: a.height, width: size, x: start, y: 0 },\n );\n };\n\n const activate = (catIdx: number, seriesIdx: number, originalEvent: Event): void => {\n const event = eventAt(catIdx, seriesIdx, originalEvent);\n\n if (!event) return;\n\n setActive(catIdx);\n\n const values = event.values ?? [];\n const spoken = describeValues(titleOf(catIdx), values, formatValue);\n\n if (tooltip) {\n const tops = values.map((v, si) =>\n stacked ? (stackedTops[si]?.[catIdx] ?? 0) : Math.max(0, v.datum?.value ?? 0),\n );\n const valuePx = valScale.map(Math.max(...tops));\n const bandCenterPx = sc.bandCenter(categories[catIdx]);\n const { margin } = ctx.dimensions;\n const rows = values.flatMap((v, si) =>\n v.datum\n ? [{ color: colors[si], name: v.series.name, value: formatValue(v.datum.value, v.datum, v.series) }]\n : [],\n );\n\n tooltip.show(\n (horizontal ? valuePx : bandCenterPx) + margin.left,\n (horizontal ? bandCenterPx : valuePx) + margin.top,\n event.datum,\n event.series,\n comparisonContent(ctx.svg.ownerDocument, titleOf(catIdx), rows, spoken),\n );\n } else {\n ctx.announcer.announce(spoken);\n }\n\n config.onHover?.(event);\n };\n\n const deactivate = (): void => {\n setActive(-1);\n tooltip?.hide();\n ctx.announcer.clear();\n config.onHover?.(null);\n };\n\n const hit = (event: MouseEvent): { catIdx: number; seriesIdx: number } | null => {\n const d = ctx.dimensions;\n const pos = getMousePosition(ctx.svg, event, d.margin.left, d.margin.top);\n const a = chartArea(d.width, d.height, d.margin);\n\n if (pos.x < 0 || pos.x > a.width || pos.y < 0 || pos.y > a.height) return null;\n\n const catIdx = findCatIdx(horizontal ? pos.y : pos.x, categories, sc);\n\n return catIdx === -1\n ? null\n : { catIdx, seriesIdx: findSeriesIdx(pos, catIdx, categories, sc, seriesList.length) };\n };\n\n const onMouseMove = (event: MouseEvent) => {\n const target = hit(event);\n\n if (target) activate(target.catIdx, target.seriesIdx, event);\n else if (activeCat >= 0) deactivate();\n };\n\n const onClick = (event: MouseEvent) => {\n const target = config.onClick && hit(event);\n const chartEvent = target && eventAt(target.catIdx, target.seriesIdx, event);\n\n if (chartEvent) config.onClick?.(chartEvent);\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n const last = categories.length - 1;\n const prev = activeCat < 0 ? last : Math.max(0, activeCat - 1);\n const next = activeCat < 0 ? 0 : Math.min(last, activeCat + 1);\n const target: Record<string, number> = {\n ArrowDown: next,\n ArrowLeft: prev,\n ArrowRight: next,\n ArrowUp: prev,\n End: last,\n Home: 0,\n };\n\n if (event.key in target) {\n event.preventDefault();\n activate(target[event.key], 0, event);\n } else if ((event.key === 'Enter' || event.key === ' ') && activeCat >= 0 && config.onClick) {\n event.preventDefault();\n\n const chartEvent = eventAt(activeCat, 0, event);\n\n if (chartEvent) config.onClick(chartEvent);\n } else if (event.key === 'Escape') {\n deactivate();\n }\n };\n\n return { onClick, onKeyDown, onMouseLeave: deactivate, onMouseMove };\n },\n (data) => {\n seriesList = data;\n },\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bar-chart.js","names":["variant","seriesList","config","band","createChartScaffold","container","ctx","seriesColor","i","s","dims","area","chartArea","sourceData","series","model","normalizeCartesianSeries","categories","allData","byKey","key","axis","value","label","clearCartesianDom","groups","legend","tooltip","xAxisConfig","horizontal","yAxisConfig","vMax","vMin","stacked","seriesData","datum","sums","sum","categoryIndex","allY","catScale","bandScale","valScale","linearScale","stackedTops","stackTops","cat","sc","renderGrid","resolveTicks","resolveTickCount","yAxis","positionAxis","renderAxis","xAxis","themeRadius","last","group","createSvgElement","seriesDomId","barData","base","top","d","baselineYs","reason","colors","catIdx","tooltipFormat","formatValue","activeCat","si","values","preferred","seriesIdx","v","rect","start","size","a","event","originalEvent","spoken","describeValues","tops","valuePx","bandCenterPx","rows","margin","comparisonContent","pos","getMousePosition","findCatIdx","findSeriesIdx","target","chartEvent","prev","next","data"],"sources":["../../../src/charts/bar/bar-chart.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { positionAxis, renderAxis, resolveTickCount, resolveTicks } from '../../axes/axis';\nimport { renderGrid } from '../../axes/grid';\nimport { normalizeCartesianSeries } from '../../core/cartesian-model';\nimport { clearCartesianDom, createChartScaffold } from '../../core/chart-scaffold';\nimport { chartArea } from '../../core/layout';\nimport { seriesDomId } from '../../core/series-id';\nimport { describeValues } from '../../interaction/announcer';\nimport { getMousePosition } from '../../interaction/events';\nimport { comparisonContent } from '../../interaction/tooltip';\nimport { bandScale } from '../../scales/band';\nimport { linearScale } from '../../scales/linear';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { seriesColor } from '../../theme';\nimport type {\n BarChartConfig,\n BarSeriesConfig,\n BarVariant,\n ChartEvent,\n ChartHandle,\n Datum,\n SeriesValue,\n XAxisConfig,\n YAxisConfig,\n} from '../../types';\nimport { findCatIdx, findSeriesIdx } from './bar-hit-test';\nimport { renderBars } from './bar-renderer';\nimport type { BarScaleContext } from './bar-scale-context';\n\nfunction variantFlags(variant: BarVariant): { horizontal: boolean; stacked: boolean } {\n return {\n horizontal: variant === 'grouped-horizontal' || variant === 'stacked-horizontal',\n stacked: variant === 'stacked' || variant === 'stacked-horizontal',\n };\n}\n\n// ─── Chart ────────────────────────────────────────────────────────────────────\n\nexport function createBarChart(container: HTMLElement, config: BarChartConfig): ChartHandle<BarSeriesConfig[]> {\n let seriesList = config.series;\n let band: SVGRectElement | null = null;\n\n return createChartScaffold(\n container,\n config,\n (ctx, reason) => {\n const { groups, legend, tooltip } = ctx;\n legend?.update(seriesList.map((s, i) => ({ color: seriesColor(i, s.color), name: s.name })));\n const dims = ctx.dimensions;\n const area = chartArea(dims.width, dims.height, dims.margin);\n const sourceData = seriesList.map((series) => series.data);\n const model = normalizeCartesianSeries(seriesList, sourceData);\n const categories = model.domain;\n const allData = model.series.map(({ byKey }) => categories.map((key) => byKey.get(key)));\n const categoryAxis = (axis: XAxisConfig | YAxisConfig) => {\n return {\n ...axis,\n tickFormat: (value: Date | number | string) => {\n const key = String(value);\n const label = model.labels.get(key) ?? value;\n\n return axis.tickFormat ? axis.tickFormat(label) : String(label);\n },\n };\n };\n\n if (categories.length === 0) {\n clearCartesianDom(groups, legend, tooltip);\n band?.remove();\n band = null;\n\n return;\n }\n\n const { horizontal, stacked } = variantFlags(config.variant ?? 'grouped');\n\n // Axes render by default; `false` opts out. The value axis (x when horizontal, y\n // otherwise) carries gridlines by default and merges over that default, so a partial\n // config (e.g. only `tickFormat`) keeps the gridlines; the category axis defaults to none.\n const xAxisConfig: XAxisConfig | false =\n config.xAxis === false ? false : horizontal ? { grid: true, ...config.xAxis } : (config.xAxis ?? {});\n const yAxisConfig: YAxisConfig | false =\n config.yAxis === false ? false : horizontal ? (config.yAxis ?? {}) : { grid: true, ...config.yAxis };\n\n // Value domain\n let vMax: number;\n let vMin: number;\n\n if (stacked) {\n if (allData.some((seriesData) => seriesData.some((datum) => (datum?.value ?? 0) < 0))) {\n warn(\n 'createBarChart: negative values in a stacked/stacked-horizontal series are clamped to 0: stacking mixed-sign data is not supported.',\n );\n }\n\n const sums = categories.map((_, categoryIndex) =>\n allData.reduce((sum, seriesData) => sum + Math.max(0, seriesData[categoryIndex]?.value ?? 0), 0),\n );\n\n vMax = Math.max(...sums);\n vMin = 0;\n } else {\n const allY = allData.flatMap((seriesData) => seriesData.flatMap((datum) => (datum ? [datum.value] : [])));\n\n vMax = Math.max(...allY);\n vMin = Math.min(0, ...allY);\n }\n\n // Build uniform scale context\n const catScale = horizontal\n ? bandScale({ domain: categories, range: [0, area.height] })\n : bandScale({ domain: categories, range: [0, area.width] });\n\n const valScale = horizontal\n ? linearScale({ domain: [vMin, vMax], range: [0, area.width] })\n : linearScale({ domain: [vMin, vMax], range: [area.height, 0] });\n\n const stackedTops: number[][] = [];\n const stackTops = Object.create(null) as Record<string, number>;\n\n for (const cat of categories) stackTops[cat] = 0;\n\n const sc: BarScaleContext = {\n bandCenter: (cat) => catScale.map(cat) + catScale.bandwidth() / 2,\n bandwidth: catScale.bandwidth(),\n baselinePx: valScale.map(0),\n horizontal,\n stacked,\n stackedTops,\n valueScale: valScale,\n };\n\n // Axes & grid\n if (horizontal) {\n if (xAxisConfig && xAxisConfig.grid) {\n renderGrid(\n groups.grid,\n valScale,\n xAxisConfig.grid,\n area.height,\n 'vertical',\n resolveTicks(valScale, xAxisConfig, resolveTickCount(xAxisConfig, area.width, 'bottom')),\n );\n }\n\n if (yAxisConfig !== false) {\n const yAxis = categoryAxis(yAxisConfig);\n\n positionAxis(groups.yAxis, yAxis.position ?? 'left', area.width, area.height);\n renderAxis(groups.yAxis, catScale, yAxis, area.height, 'left');\n }\n\n if (xAxisConfig) {\n positionAxis(groups.xAxis, xAxisConfig.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, valScale, xAxisConfig, area.width, 'bottom');\n }\n } else {\n if (yAxisConfig && yAxisConfig.grid) {\n renderGrid(\n groups.grid,\n valScale,\n yAxisConfig.grid,\n area.width,\n 'horizontal',\n resolveTicks(valScale, yAxisConfig, resolveTickCount(yAxisConfig, area.height, 'left')),\n );\n }\n\n if (xAxisConfig !== false) {\n const xAxis = categoryAxis(xAxisConfig);\n\n positionAxis(groups.xAxis, xAxis.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, catScale, xAxis, area.width, 'bottom');\n }\n\n if (yAxisConfig) {\n positionAxis(groups.yAxis, yAxisConfig.position ?? 'left', area.width, area.height);\n renderAxis(groups.yAxis, valScale, yAxisConfig, area.height, 'left');\n }\n }\n\n // Series groups\n // Stacked segments stay square so they join cleanly.\n const themeRadius = stacked\n ? 0\n : Number.parseFloat(getComputedStyle(ctx.svg).getPropertyValue('--prism-bar-radius')) || 0;\n\n while (groups.series.children.length > seriesList.length) {\n const last = groups.series.lastElementChild;\n\n if (last) groups.series.removeChild(last);\n }\n\n for (let i = 0; i < seriesList.length; i++) {\n const series = seriesList[i];\n let group = groups.series.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-bar-series' });\n groups.series.appendChild(group);\n }\n\n group.setAttribute('data-series-id', seriesDomId(series, i));\n\n const barData = categories.map((key, categoryIndex) => {\n const datum = allData[i]?.[categoryIndex];\n\n if (stacked) {\n const base = stackTops[key] ?? 0;\n const top = base + Math.max(0, datum?.value ?? 0);\n\n stackTops[key] = top;\n\n return { base, dash: datum?.dash, key, opacity: datum?.opacity, present: datum !== undefined, y: top };\n }\n\n return {\n base: 0,\n dash: datum?.dash,\n key,\n opacity: datum?.opacity,\n present: datum !== undefined,\n y: datum?.value ?? 0,\n };\n });\n\n stackedTops[i] = barData.map((d) => d.y);\n\n const baselineYs = stacked ? barData.map((d) => valScale.map(d.base)) : undefined;\n\n renderBars(group, barData, catScale, valScale, sc.baselinePx, {\n baselineYs,\n borderRadius: series.borderRadius ?? themeRadius,\n color: seriesColor(i, series.color),\n disposalSignal: ctx.disposalSignal,\n horizontal,\n seriesCount: seriesList.length,\n seriesIndex: i,\n stacked,\n transition: reason === 'resize' ? false : config.transition,\n });\n }\n\n tooltip?.hide();\n groups.series.classList.toggle('prism-bars-stacked', stacked);\n\n if (!band || !ctx.chartArea.contains(band)) {\n band = createSvgElement('rect', { 'aria-hidden': 'true', class: 'prism-bar-band', 'pointer-events': 'none' });\n ctx.chartArea.insertBefore(band, groups.series);\n }\n\n band.style.display = 'none';\n\n // ─── Event handlers (close over render-derived state) ─────────────────────\n\n const colors = seriesList.map((s, i) => seriesColor(i, s.color));\n const labelOf = (catIdx: number): string => String(model.labels.get(categories[catIdx]) ?? categories[catIdx]);\n const tooltipFormat = typeof config.tooltip === 'object' ? config.tooltip : undefined;\n const keyOf = (catIdx: number): Datum['key'] => model.labels.get(categories[catIdx]) ?? categories[catIdx];\n const titleOf = (catIdx: number): string =>\n tooltipFormat?.titleFormat ? tooltipFormat.titleFormat(keyOf(catIdx)) : labelOf(catIdx);\n const formatValue = tooltipFormat?.valueFormat ?? String;\n let activeCat = -1;\n\n const valuesAt = (catIdx: number): SeriesValue[] =>\n seriesList.map((series, si) => ({ datum: allData[si]?.[catIdx], series }));\n\n const eventAt = (catIdx: number, seriesIdx: number, originalEvent: Event): ChartEvent | null => {\n const values = valuesAt(catIdx);\n const preferred = values[seriesIdx]?.datum ? seriesIdx : values.findIndex((v) => v.datum);\n const datum = values[preferred]?.datum;\n\n return datum ? { datum, originalEvent, series: seriesList[preferred], values } : null;\n };\n\n const setActive = (catIdx: number): void => {\n activeCat = catIdx;\n groups.series.classList.toggle('prism-bars-focused', catIdx >= 0);\n\n for (const group of groups.series.children) {\n for (const [i, rect] of [...group.children].entries())\n rect.classList.toggle('prism-bar--active', i === catIdx);\n }\n\n if (!band) return;\n\n band.style.display = catIdx < 0 ? 'none' : '';\n\n if (catIdx < 0) return;\n\n const start = sc.bandCenter(categories[catIdx]) - catScale.bandwidth() / 2 - catScale.gap() / 2;\n const size = catScale.bandwidth() + catScale.gap();\n const a = chartArea(ctx.dimensions.width, ctx.dimensions.height, ctx.dimensions.margin);\n\n setAttributes(\n band,\n horizontal\n ? { height: size, width: a.width, x: 0, y: start }\n : { height: a.height, width: size, x: start, y: 0 },\n );\n };\n\n const activate = (catIdx: number, seriesIdx: number, originalEvent: Event): void => {\n const event = eventAt(catIdx, seriesIdx, originalEvent);\n\n if (!event) return;\n\n setActive(catIdx);\n\n const values = event.values ?? [];\n const spoken = describeValues(titleOf(catIdx), values, formatValue);\n\n if (tooltip) {\n const tops = values.map((v, si) =>\n stacked ? (stackedTops[si]?.[catIdx] ?? 0) : Math.max(0, v.datum?.value ?? 0),\n );\n const valuePx = valScale.map(Math.max(...tops));\n const bandCenterPx = sc.bandCenter(categories[catIdx]);\n const { margin } = ctx.dimensions;\n const rows = values.flatMap((v, si) =>\n v.datum\n ? [{ color: colors[si], name: v.series.name, value: formatValue(v.datum.value, v.datum, v.series) }]\n : [],\n );\n\n tooltip.show(\n (horizontal ? valuePx : bandCenterPx) + margin.left,\n (horizontal ? bandCenterPx : valuePx) + margin.top,\n event.datum,\n event.series,\n comparisonContent(ctx.svg.ownerDocument, titleOf(catIdx), rows, spoken),\n );\n } else {\n ctx.announcer.announce(spoken);\n }\n\n config.onHover?.(event);\n };\n\n const deactivate = (): void => {\n setActive(-1);\n tooltip?.hide();\n ctx.announcer.clear();\n config.onHover?.(null);\n };\n\n const hit = (event: MouseEvent): { catIdx: number; seriesIdx: number } | null => {\n const d = ctx.dimensions;\n const pos = getMousePosition(ctx.svg, event, d.margin.left, d.margin.top);\n const a = chartArea(d.width, d.height, d.margin);\n\n if (pos.x < 0 || pos.x > a.width || pos.y < 0 || pos.y > a.height) return null;\n\n const catIdx = findCatIdx(horizontal ? pos.y : pos.x, categories, sc);\n\n return catIdx === -1\n ? null\n : { catIdx, seriesIdx: findSeriesIdx(pos, catIdx, categories, sc, seriesList.length) };\n };\n\n const onMouseMove = (event: MouseEvent) => {\n const target = hit(event);\n\n if (target) activate(target.catIdx, target.seriesIdx, event);\n else if (activeCat >= 0) deactivate();\n };\n\n const onClick = (event: MouseEvent) => {\n const target = config.onClick && hit(event);\n const chartEvent = target && eventAt(target.catIdx, target.seriesIdx, event);\n\n if (chartEvent) config.onClick?.(chartEvent);\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n const last = categories.length - 1;\n const prev = activeCat < 0 ? last : Math.max(0, activeCat - 1);\n const next = activeCat < 0 ? 0 : Math.min(last, activeCat + 1);\n const target: Record<string, number> = {\n ArrowDown: next,\n ArrowLeft: prev,\n ArrowRight: next,\n ArrowUp: prev,\n End: last,\n Home: 0,\n };\n\n if (event.key in target) {\n event.preventDefault();\n activate(target[event.key], 0, event);\n } else if ((event.key === 'Enter' || event.key === ' ') && activeCat >= 0 && config.onClick) {\n event.preventDefault();\n\n const chartEvent = eventAt(activeCat, 0, event);\n\n if (chartEvent) config.onClick(chartEvent);\n } else if (event.key === 'Escape') {\n deactivate();\n }\n };\n\n return { onClick, onKeyDown, onMouseLeave: deactivate, onMouseMove };\n },\n (data) => {\n seriesList = data;\n },\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"bar-hit-test.cjs","names":[],"sources":["../../../src/charts/bar/bar-hit-test.ts"],"sourcesContent":["import type { BarScaleContext } from './bar-scale-context';\n\nexport function findCatIdx(pos: number, categories: string[], sc: BarScaleContext): number {\n for (let i = 0; i < categories.length; i++) {\n const center = sc.bandCenter(categories[i]);\n const start = center - sc.bandwidth / 2;\n\n if (pos >= start && pos < start + sc.bandwidth) return i;\n }\n\n return -1;\n}\n\nexport function findSeriesIdx(\n pos: { x: number; y: number },\n catIdx: number,\n categories: string[],\n sc: BarScaleContext,\n seriesCount: number,\n): number {\n if (sc.stacked) {\n if (sc.horizontal) {\n for (let si = 0; si < seriesCount; si++) {\n const rightX = sc.valueScale.map(sc.stackedTops[si]?.[catIdx] ?? 0);\n\n if (rightX >= pos.x) return si;\n }\n\n return seriesCount - 1;\n } else {\n for (let si = 0; si < seriesCount; si++) {\n const topY = sc.valueScale.map(sc.stackedTops[si]?.[catIdx] ?? 0);\n\n if (topY <= pos.y) return si;\n }\n\n return seriesCount - 1;\n }\n } else {\n const subSize = sc.bandwidth / seriesCount;\n const bandStart = sc.bandCenter(categories[catIdx]) - sc.bandwidth / 2;\n const offset = sc.horizontal ? pos.y - bandStart : pos.x - bandStart;\n const subIdx = Math.floor(offset / subSize);\n\n return Math.max(0, Math.min(seriesCount - 1, subIdx));\n }\n}\n"],"mappings":"AAEA,SAAgB,WAAW,EAAa,EAAsB,EAA6B,CACzF,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,OAAQ,IAAK,CAE1C,IAAM,EADS,EAAG,WAAW,EAAW,EAC1B,EAAS,EAAG,UAAY,EAEtC,GAAI,GAAO,GAAS,EAAM,EAAQ,EAAG,UAAW,OAAO,CACzD,CAEA,MAAO,EACT,CAEA,SAAgB,cACd,EACA,EACA,EACA,EACA,EACQ,CACR,GAAI,EAAG,QAAS,CACd,GAAI,EAAG,WAAY,CACjB,IAAK,IAAI,EAAK,EAAG,EAAK,EAAa,IAGjC,GAFe,EAAG,WAAW,IAAI,EAAG,YAAY,EAAG,GAAG,IAAW,CAE7D,GAAU,EAAI,EAAG,OAAO,EAG9B,OAAO,EAAc,CACvB,CACE,IAAK,IAAI,EAAK,EAAG,EAAK,EAAa,IAGjC,GAFa,EAAG,WAAW,IAAI,EAAG,YAAY,EAAG,GAAG,IAAW,CAE3D,GAAQ,EAAI,EAAG,OAAO,EAG5B,OAAO,EAAc,CAEzB,CAAO,CACL,IAAM,EAAU,EAAG,UAAY,EACzB,EAAY,EAAG,WAAW,EAAW,EAAO,EAAI,EAAG,UAAY,EAC/D,EAAS,EAAG,WAAa,EAAI,EAAI,EAAY,EAAI,EAAI,EACrD,EAAS,KAAK,MAAM,EAAS,CAAO,EAE1C,OAAO,KAAK,IAAI,EAAG,KAAK,IAAI,EAAc,EAAG,CAAM,CAAC,CACtD,CACF"}
1
+ {"version":3,"file":"bar-hit-test.cjs","names":["i","categories","start","sc","pos","si","seriesCount","catIdx","subSize","bandStart","offset","subIdx"],"sources":["../../../src/charts/bar/bar-hit-test.ts"],"sourcesContent":["import type { BarScaleContext } from './bar-scale-context';\n\nexport function findCatIdx(pos: number, categories: string[], sc: BarScaleContext): number {\n for (let i = 0; i < categories.length; i++) {\n const center = sc.bandCenter(categories[i]);\n const start = center - sc.bandwidth / 2;\n\n if (pos >= start && pos < start + sc.bandwidth) return i;\n }\n\n return -1;\n}\n\nexport function findSeriesIdx(\n pos: { x: number; y: number },\n catIdx: number,\n categories: string[],\n sc: BarScaleContext,\n seriesCount: number,\n): number {\n if (sc.stacked) {\n if (sc.horizontal) {\n for (let si = 0; si < seriesCount; si++) {\n const rightX = sc.valueScale.map(sc.stackedTops[si]?.[catIdx] ?? 0);\n\n if (rightX >= pos.x) return si;\n }\n\n return seriesCount - 1;\n } else {\n for (let si = 0; si < seriesCount; si++) {\n const topY = sc.valueScale.map(sc.stackedTops[si]?.[catIdx] ?? 0);\n\n if (topY <= pos.y) return si;\n }\n\n return seriesCount - 1;\n }\n } else {\n const subSize = sc.bandwidth / seriesCount;\n const bandStart = sc.bandCenter(categories[catIdx]) - sc.bandwidth / 2;\n const offset = sc.horizontal ? pos.y - bandStart : pos.x - bandStart;\n const subIdx = Math.floor(offset / subSize);\n\n return Math.max(0, Math.min(seriesCount - 1, subIdx));\n }\n}\n"],"mappings":"AAEA,SAAgB,WAAW,EAAa,EAAsB,EAA6B,CACzF,IAAK,IAAIA,EAAI,EAAGA,EAAIC,EAAW,OAAQ,IAAK,CAE1C,IAAMC,EADSC,EAAG,WAAWF,EAAWD,EAC1B,EAASG,EAAG,UAAY,EAEtC,GAAIC,GAAOF,GAASE,EAAMF,EAAQC,EAAG,UAAW,OAAOH,CACzD,CAEA,MAAO,EACT,CAEA,SAAgB,cACd,EACA,EACA,EACA,EACA,EACQ,CACR,GAAIG,EAAG,QAAS,CACd,GAAIA,EAAG,WAAY,CACjB,IAAK,IAAIE,EAAK,EAAGA,EAAKC,EAAa,IAGjC,GAFeH,EAAG,WAAW,IAAIA,EAAG,YAAYE,EAAG,GAAGE,IAAW,CAE7D,GAAUH,EAAI,EAAG,OAAOC,EAG9B,OAAOC,EAAc,CACvB,CACE,IAAK,IAAID,EAAK,EAAGA,EAAKC,EAAa,IAGjC,GAFaH,EAAG,WAAW,IAAIA,EAAG,YAAYE,EAAG,GAAGE,IAAW,CAE3D,GAAQH,EAAI,EAAG,OAAOC,EAG5B,OAAOC,EAAc,CAEzB,CAAO,CACL,IAAME,EAAUL,EAAG,UAAYG,EACzBG,EAAYN,EAAG,WAAWF,EAAWM,EAAO,EAAIJ,EAAG,UAAY,EAC/DO,EAASP,EAAG,WAAaC,EAAI,EAAIK,EAAYL,EAAI,EAAIK,EACrDE,EAAS,KAAK,MAAMD,EAASF,CAAO,EAE1C,OAAO,KAAK,IAAI,EAAG,KAAK,IAAIF,EAAc,EAAGK,CAAM,CAAC,CACtD,CACF,C"}
@@ -1,2 +1,26 @@
1
- function findCatIdx(e,t,n){for(let r=0;r<t.length;r++){let i=n.bandCenter(t[r])-n.bandwidth/2;if(e>=i&&e<i+n.bandwidth)return r}return-1}function findSeriesIdx(e,t,n,r,i){if(r.stacked){if(r.horizontal){for(let n=0;n<i;n++)if(r.valueScale.map(r.stackedTops[n]?.[t]??0)>=e.x)return n;return i-1}for(let n=0;n<i;n++)if(r.valueScale.map(r.stackedTops[n]?.[t]??0)<=e.y)return n;return i-1}{let a=r.bandwidth/i,o=r.bandCenter(n[t])-r.bandwidth/2,s=r.horizontal?e.y-o:e.x-o,c=Math.floor(s/a);return Math.max(0,Math.min(i-1,c))}}export{findCatIdx,findSeriesIdx};
1
+ //#region src/charts/bar/bar-hit-test.ts
2
+ function findCatIdx(e, t, n) {
3
+ for (let r = 0; r < t.length; r++) {
4
+ let i = n.bandCenter(t[r]) - n.bandwidth / 2;
5
+ if (e >= i && e < i + n.bandwidth) return r;
6
+ }
7
+ return -1;
8
+ }
9
+ function findSeriesIdx(e, t, n, r, i) {
10
+ if (r.stacked) {
11
+ if (r.horizontal) {
12
+ for (let n = 0; n < i; n++) if (r.valueScale.map(r.stackedTops[n]?.[t] ?? 0) >= e.x) return n;
13
+ return i - 1;
14
+ }
15
+ for (let n = 0; n < i; n++) if (r.valueScale.map(r.stackedTops[n]?.[t] ?? 0) <= e.y) return n;
16
+ return i - 1;
17
+ }
18
+ {
19
+ let a = r.bandwidth / i, o = r.bandCenter(n[t]) - r.bandwidth / 2, s = r.horizontal ? e.y - o : e.x - o, c = Math.floor(s / a);
20
+ return Math.max(0, Math.min(i - 1, c));
21
+ }
22
+ }
23
+ //#endregion
24
+ export { findCatIdx, findSeriesIdx };
25
+
2
26
  //# sourceMappingURL=bar-hit-test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bar-hit-test.js","names":[],"sources":["../../../src/charts/bar/bar-hit-test.ts"],"sourcesContent":["import type { BarScaleContext } from './bar-scale-context';\n\nexport function findCatIdx(pos: number, categories: string[], sc: BarScaleContext): number {\n for (let i = 0; i < categories.length; i++) {\n const center = sc.bandCenter(categories[i]);\n const start = center - sc.bandwidth / 2;\n\n if (pos >= start && pos < start + sc.bandwidth) return i;\n }\n\n return -1;\n}\n\nexport function findSeriesIdx(\n pos: { x: number; y: number },\n catIdx: number,\n categories: string[],\n sc: BarScaleContext,\n seriesCount: number,\n): number {\n if (sc.stacked) {\n if (sc.horizontal) {\n for (let si = 0; si < seriesCount; si++) {\n const rightX = sc.valueScale.map(sc.stackedTops[si]?.[catIdx] ?? 0);\n\n if (rightX >= pos.x) return si;\n }\n\n return seriesCount - 1;\n } else {\n for (let si = 0; si < seriesCount; si++) {\n const topY = sc.valueScale.map(sc.stackedTops[si]?.[catIdx] ?? 0);\n\n if (topY <= pos.y) return si;\n }\n\n return seriesCount - 1;\n }\n } else {\n const subSize = sc.bandwidth / seriesCount;\n const bandStart = sc.bandCenter(categories[catIdx]) - sc.bandwidth / 2;\n const offset = sc.horizontal ? pos.y - bandStart : pos.x - bandStart;\n const subIdx = Math.floor(offset / subSize);\n\n return Math.max(0, Math.min(seriesCount - 1, subIdx));\n }\n}\n"],"mappings":"AAEA,SAAgB,WAAW,EAAa,EAAsB,EAA6B,CACzF,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,OAAQ,IAAK,CAE1C,IAAM,EADS,EAAG,WAAW,EAAW,EAC1B,EAAS,EAAG,UAAY,EAEtC,GAAI,GAAO,GAAS,EAAM,EAAQ,EAAG,UAAW,OAAO,CACzD,CAEA,MAAO,EACT,CAEA,SAAgB,cACd,EACA,EACA,EACA,EACA,EACQ,CACR,GAAI,EAAG,QAAS,CACd,GAAI,EAAG,WAAY,CACjB,IAAK,IAAI,EAAK,EAAG,EAAK,EAAa,IAGjC,GAFe,EAAG,WAAW,IAAI,EAAG,YAAY,EAAG,GAAG,IAAW,CAE7D,GAAU,EAAI,EAAG,OAAO,EAG9B,OAAO,EAAc,CACvB,CACE,IAAK,IAAI,EAAK,EAAG,EAAK,EAAa,IAGjC,GAFa,EAAG,WAAW,IAAI,EAAG,YAAY,EAAG,GAAG,IAAW,CAE3D,GAAQ,EAAI,EAAG,OAAO,EAG5B,OAAO,EAAc,CAEzB,CAAO,CACL,IAAM,EAAU,EAAG,UAAY,EACzB,EAAY,EAAG,WAAW,EAAW,EAAO,EAAI,EAAG,UAAY,EAC/D,EAAS,EAAG,WAAa,EAAI,EAAI,EAAY,EAAI,EAAI,EACrD,EAAS,KAAK,MAAM,EAAS,CAAO,EAE1C,OAAO,KAAK,IAAI,EAAG,KAAK,IAAI,EAAc,EAAG,CAAM,CAAC,CACtD,CACF"}
1
+ {"version":3,"file":"bar-hit-test.js","names":["i","categories","start","sc","pos","si","seriesCount","catIdx","subSize","bandStart","offset","subIdx"],"sources":["../../../src/charts/bar/bar-hit-test.ts"],"sourcesContent":["import type { BarScaleContext } from './bar-scale-context';\n\nexport function findCatIdx(pos: number, categories: string[], sc: BarScaleContext): number {\n for (let i = 0; i < categories.length; i++) {\n const center = sc.bandCenter(categories[i]);\n const start = center - sc.bandwidth / 2;\n\n if (pos >= start && pos < start + sc.bandwidth) return i;\n }\n\n return -1;\n}\n\nexport function findSeriesIdx(\n pos: { x: number; y: number },\n catIdx: number,\n categories: string[],\n sc: BarScaleContext,\n seriesCount: number,\n): number {\n if (sc.stacked) {\n if (sc.horizontal) {\n for (let si = 0; si < seriesCount; si++) {\n const rightX = sc.valueScale.map(sc.stackedTops[si]?.[catIdx] ?? 0);\n\n if (rightX >= pos.x) return si;\n }\n\n return seriesCount - 1;\n } else {\n for (let si = 0; si < seriesCount; si++) {\n const topY = sc.valueScale.map(sc.stackedTops[si]?.[catIdx] ?? 0);\n\n if (topY <= pos.y) return si;\n }\n\n return seriesCount - 1;\n }\n } else {\n const subSize = sc.bandwidth / seriesCount;\n const bandStart = sc.bandCenter(categories[catIdx]) - sc.bandwidth / 2;\n const offset = sc.horizontal ? pos.y - bandStart : pos.x - bandStart;\n const subIdx = Math.floor(offset / subSize);\n\n return Math.max(0, Math.min(seriesCount - 1, subIdx));\n }\n}\n"],"mappings":";AAEA,SAAgB,WAAW,GAAa,GAAsB,GAA6B;CACzF,KAAK,IAAIA,IAAI,GAAGA,IAAIC,EAAW,QAAQ,KAAK;EAE1C,IAAMC,IADSC,EAAG,WAAWF,EAAWD,EAC1B,IAASG,EAAG,YAAY;EAEtC,IAAIC,KAAOF,KAASE,IAAMF,IAAQC,EAAG,WAAW,OAAOH;CACzD;CAEA,OAAO;AACT;AAEA,SAAgB,cACd,GACA,GACA,GACA,GACA,GACQ;CACR,IAAIG,EAAG,SAAS;EACd,IAAIA,EAAG,YAAY;GACjB,KAAK,IAAIE,IAAK,GAAGA,IAAKC,GAAa,KAGjC,IAFeH,EAAG,WAAW,IAAIA,EAAG,YAAYE,EAAG,GAAGE,MAAW,CAE7D,KAAUH,EAAI,GAAG,OAAOC;GAG9B,OAAOC,IAAc;EACvB;EACE,KAAK,IAAID,IAAK,GAAGA,IAAKC,GAAa,KAGjC,IAFaH,EAAG,WAAW,IAAIA,EAAG,YAAYE,EAAG,GAAGE,MAAW,CAE3D,KAAQH,EAAI,GAAG,OAAOC;EAG5B,OAAOC,IAAc;CAEzB;CAAO;EACL,IAAME,IAAUL,EAAG,YAAYG,GACzBG,IAAYN,EAAG,WAAWF,EAAWM,EAAO,IAAIJ,EAAG,YAAY,GAC/DO,IAASP,EAAG,aAAaC,EAAI,IAAIK,IAAYL,EAAI,IAAIK,GACrDE,IAAS,KAAK,MAAMD,IAASF,CAAO;EAE1C,OAAO,KAAK,IAAI,GAAG,KAAK,IAAIF,IAAc,GAAGK,CAAM,CAAC;CACtD;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"bar-renderer.cjs","names":[],"sources":["../../../src/charts/bar/bar-renderer.ts"],"sourcesContent":["import { resolveMotion } from '../../animation/motion';\nimport { type GrowRevealLane, playGrowReveal } from '../../animation/reveal';\nimport type { AnimationTarget } from '../../animation/transition';\nimport { animate } from '../../animation/transition';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { BandScale, Scale, TransitionOption } from '../../types';\n\nexport interface BarRenderOptions {\n baselineYs?: number[];\n borderRadius: number;\n color: string;\n /** Aborted when the owning chart is disposed: stops in-flight transitions from rescheduling. */\n disposalSignal?: AbortSignal;\n horizontal?: boolean;\n seriesCount: number;\n seriesIndex: number;\n stacked?: boolean;\n transition?: TransitionOption;\n}\n\n/** Preserve the stagger for bars inserted by a data update, not the initial entrance. */\nconst DEFAULT_NEW_BAR_STAGGER = 20;\n/** Upper bound on the total staggered delay a bar chart may add, whatever the per-bar value. */\nconst MAX_STAGGER_TOTAL = 400;\n\nconst activeBarAnimations = new WeakMap<SVGGElement, () => void>();\n\n/**\n * The group's bars in data order. Queried by class rather than by `children` index\n * because a mount reveal injects a `<defs>` into the same group.\n */\nfunction barsOf(parent: SVGGElement): SVGRectElement[] {\n return [...parent.children].filter((child): child is SVGRectElement => child.classList.contains('prism-bar'));\n}\n\nexport function renderBars(\n parent: SVGGElement,\n data: { base: number; dash?: string; key: string; opacity?: number; present: boolean; y: number }[],\n xScale: BandScale,\n yScale: Scale<number>,\n baselineY: number,\n options: BarRenderOptions,\n): void {\n activeBarAnimations.get(parent)?.();\n activeBarAnimations.delete(parent);\n const existingBars = barsOf(parent);\n\n for (const extra of existingBars.slice(data.length)) extra.remove();\n\n const bandwidth = xScale.bandwidth();\n const barBand = options.stacked ? bandwidth : bandwidth / options.seriesCount;\n const bandSize = Math.max(0, barBand - 1);\n const offset = options.stacked ? 0 : barBand * options.seriesIndex;\n const horizontal = options.horizontal ?? false;\n // A group with no bars yet is mounting: every bar enters together through a grow\n // reveal. A group that already has bars updates in place (with per-bar attr tweens).\n const isMount = existingBars.length === 0;\n\n const enterTargets: AnimationTarget[] = [];\n const updateTargets: AnimationTarget[] = [];\n const lanes: GrowRevealLane[] = [];\n const motion = resolveMotion(options.transition, { defaultStagger: isMount ? 0 : DEFAULT_NEW_BAR_STAGGER });\n const animateBars = motion.duration > 0;\n // A long category axis must not stretch the entrance past ~400 ms of added delay.\n const enterStagger = Math.min(motion.stagger, MAX_STAGGER_TOTAL / Math.max(1, data.length));\n\n for (let i = 0; i < data.length; i++) {\n const d = data[i];\n const bandPos = xScale.map(d.key) + offset;\n const barBaselineY = options.baselineYs ? options.baselineYs[i] : baselineY;\n const valuePx = yScale.map(d.y);\n\n let rect = existingBars[i];\n\n const isNew = !rect;\n\n if (!rect) {\n rect = createSvgElement('rect', { class: 'prism-bar' });\n parent.appendChild(rect);\n }\n\n rect.style.display = d.present ? '' : 'none';\n\n // Presentation attributes (not inline styles) so CSS interaction states\n // like the focus-dim rule keep winning over per-datum styling.\n setAttributes(rect, {\n opacity: d.opacity,\n stroke: d.dash ? options.color : undefined,\n 'stroke-dasharray': d.dash,\n 'stroke-width': d.dash ? 1 : undefined,\n });\n\n if (horizontal) {\n // Horizontal: category on Y axis, value on X axis\n // baselineY here is actually the baseline X (yScale.map(0) in value-space mapped to screen X)\n const finalWidth = Math.max(0, Math.abs(barBaselineY - valuePx));\n const finalX = Math.min(valuePx, barBaselineY);\n\n setAttributes(rect, {\n fill: options.color,\n height: bandSize,\n rx: options.borderRadius,\n ry: options.borderRadius,\n y: bandPos,\n });\n\n if (isMount) {\n // Final geometry now; the grow reveal below uncovers it lane by lane.\n setAttributes(rect, { width: finalWidth, x: finalX });\n\n if (animateBars) {\n lanes.push({ anchor: barBaselineY, height: bandSize, width: finalWidth, x: finalX, y: bandPos });\n }\n } else if (animateBars) {\n if (isNew) {\n setAttributes(rect, { width: 0, x: barBaselineY });\n enterTargets.push({\n attrs: { width: { from: 0, to: finalWidth }, x: { from: barBaselineY, to: finalX } },\n el: rect,\n });\n } else {\n updateTargets.push({\n attrs: {\n width: { from: Number(rect.getAttribute('width') ?? finalWidth), to: finalWidth },\n x: { from: Number(rect.getAttribute('x') ?? finalX), to: finalX },\n },\n el: rect,\n });\n }\n } else {\n setAttributes(rect, { width: finalWidth, x: finalX });\n }\n } else {\n // Vertical (default)\n const finalHeight = Math.max(0, Math.abs(barBaselineY - valuePx));\n const finalY = Math.min(valuePx, barBaselineY);\n\n setAttributes(rect, {\n fill: options.color,\n rx: options.borderRadius,\n ry: options.borderRadius,\n width: bandSize,\n x: bandPos,\n });\n\n if (isMount) {\n // Final geometry now; the grow reveal below uncovers it lane by lane, so a\n // rounded bar never renders as a corner-clamped 1-3 px sliver mid-grow.\n setAttributes(rect, { height: finalHeight, y: finalY });\n\n if (animateBars) {\n lanes.push({ anchor: barBaselineY, height: finalHeight, width: bandSize, x: bandPos, y: finalY });\n }\n } else if (animateBars) {\n if (isNew) {\n setAttributes(rect, { height: 0, y: barBaselineY });\n enterTargets.push({\n attrs: { height: { from: 0, to: finalHeight }, y: { from: barBaselineY, to: finalY } },\n el: rect,\n });\n } else {\n updateTargets.push({\n attrs: {\n height: { from: Number(rect.getAttribute('height') ?? finalHeight), to: finalHeight },\n y: { from: Number(rect.getAttribute('y') ?? finalY), to: finalY },\n },\n el: rect,\n });\n }\n } else {\n setAttributes(rect, { height: finalHeight, y: finalY });\n }\n }\n }\n\n if (animateBars) {\n const cancels: (() => void)[] = [];\n\n if (isMount && lanes.length > 0) {\n cancels.push(\n playGrowReveal(parent, lanes, () => {}, motion, {\n axis: horizontal ? 'x' : 'y',\n signal: options.disposalSignal,\n stagger: enterStagger,\n }),\n );\n }\n\n if (enterTargets.length > 0) {\n cancels.push(animate(enterTargets, { ...motion, stagger: enterStagger }, undefined, options.disposalSignal));\n }\n\n if (updateTargets.length > 0) {\n cancels.push(animate(updateTargets, { ...motion, stagger: 0 }, undefined, options.disposalSignal));\n }\n\n activeBarAnimations.set(parent, () => {\n for (const cancel of cancels) cancel();\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bar-renderer.cjs","names":["resolveMotion","createSvgElement","playGrowReveal","animate","require_element","require_motion","require_transition","require_reveal","DEFAULT_NEW_BAR_STAGGER","MAX_STAGGER_TOTAL","activeBarAnimations","parent","child","existingBars","extra","data","bandwidth","xScale","barBand","options","bandSize","offset","horizontal","isMount","enterTargets","updateTargets","lanes","motion","animateBars","enterStagger","i","d","bandPos","barBaselineY","baselineY","valuePx","yScale","rect","isNew","finalWidth","finalX","finalHeight","finalY","cancels","cancel"],"sources":["../../../src/charts/bar/bar-renderer.ts"],"sourcesContent":["import { resolveMotion } from '../../animation/motion';\nimport { type GrowRevealLane, playGrowReveal } from '../../animation/reveal';\nimport type { AnimationTarget } from '../../animation/transition';\nimport { animate } from '../../animation/transition';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { BandScale, Scale, TransitionOption } from '../../types';\n\nexport interface BarRenderOptions {\n baselineYs?: number[];\n borderRadius: number;\n color: string;\n /** Aborted when the owning chart is disposed: stops in-flight transitions from rescheduling. */\n disposalSignal?: AbortSignal;\n horizontal?: boolean;\n seriesCount: number;\n seriesIndex: number;\n stacked?: boolean;\n transition?: TransitionOption;\n}\n\n/** Preserve the stagger for bars inserted by a data update, not the initial entrance. */\nconst DEFAULT_NEW_BAR_STAGGER = 20;\n/** Upper bound on the total staggered delay a bar chart may add, whatever the per-bar value. */\nconst MAX_STAGGER_TOTAL = 400;\n\nconst activeBarAnimations = new WeakMap<SVGGElement, () => void>();\n\n/**\n * The group's bars in data order. Queried by class rather than by `children` index\n * because a mount reveal injects a `<defs>` into the same group.\n */\nfunction barsOf(parent: SVGGElement): SVGRectElement[] {\n return [...parent.children].filter((child): child is SVGRectElement => child.classList.contains('prism-bar'));\n}\n\nexport function renderBars(\n parent: SVGGElement,\n data: { base: number; dash?: string; key: string; opacity?: number; present: boolean; y: number }[],\n xScale: BandScale,\n yScale: Scale<number>,\n baselineY: number,\n options: BarRenderOptions,\n): void {\n activeBarAnimations.get(parent)?.();\n activeBarAnimations.delete(parent);\n const existingBars = barsOf(parent);\n\n for (const extra of existingBars.slice(data.length)) extra.remove();\n\n const bandwidth = xScale.bandwidth();\n const barBand = options.stacked ? bandwidth : bandwidth / options.seriesCount;\n const bandSize = Math.max(0, barBand - 1);\n const offset = options.stacked ? 0 : barBand * options.seriesIndex;\n const horizontal = options.horizontal ?? false;\n // A group with no bars yet is mounting: every bar enters together through a grow\n // reveal. A group that already has bars updates in place (with per-bar attr tweens).\n const isMount = existingBars.length === 0;\n\n const enterTargets: AnimationTarget[] = [];\n const updateTargets: AnimationTarget[] = [];\n const lanes: GrowRevealLane[] = [];\n const motion = resolveMotion(options.transition, { defaultStagger: isMount ? 0 : DEFAULT_NEW_BAR_STAGGER });\n const animateBars = motion.duration > 0;\n // A long category axis must not stretch the entrance past ~400 ms of added delay.\n const enterStagger = Math.min(motion.stagger, MAX_STAGGER_TOTAL / Math.max(1, data.length));\n\n for (let i = 0; i < data.length; i++) {\n const d = data[i];\n const bandPos = xScale.map(d.key) + offset;\n const barBaselineY = options.baselineYs ? options.baselineYs[i] : baselineY;\n const valuePx = yScale.map(d.y);\n\n let rect = existingBars[i];\n\n const isNew = !rect;\n\n if (!rect) {\n rect = createSvgElement('rect', { class: 'prism-bar' });\n parent.appendChild(rect);\n }\n\n rect.style.display = d.present ? '' : 'none';\n\n // Presentation attributes (not inline styles) so CSS interaction states\n // like the focus-dim rule keep winning over per-datum styling.\n setAttributes(rect, {\n opacity: d.opacity,\n stroke: d.dash ? options.color : undefined,\n 'stroke-dasharray': d.dash,\n 'stroke-width': d.dash ? 1 : undefined,\n });\n\n if (horizontal) {\n // Horizontal: category on Y axis, value on X axis\n // baselineY here is actually the baseline X (yScale.map(0) in value-space mapped to screen X)\n const finalWidth = Math.max(0, Math.abs(barBaselineY - valuePx));\n const finalX = Math.min(valuePx, barBaselineY);\n\n setAttributes(rect, {\n fill: options.color,\n height: bandSize,\n rx: options.borderRadius,\n ry: options.borderRadius,\n y: bandPos,\n });\n\n if (isMount) {\n // Final geometry now; the grow reveal below uncovers it lane by lane.\n setAttributes(rect, { width: finalWidth, x: finalX });\n\n if (animateBars) {\n lanes.push({ anchor: barBaselineY, height: bandSize, width: finalWidth, x: finalX, y: bandPos });\n }\n } else if (animateBars) {\n if (isNew) {\n setAttributes(rect, { width: 0, x: barBaselineY });\n enterTargets.push({\n attrs: { width: { from: 0, to: finalWidth }, x: { from: barBaselineY, to: finalX } },\n el: rect,\n });\n } else {\n updateTargets.push({\n attrs: {\n width: { from: Number(rect.getAttribute('width') ?? finalWidth), to: finalWidth },\n x: { from: Number(rect.getAttribute('x') ?? finalX), to: finalX },\n },\n el: rect,\n });\n }\n } else {\n setAttributes(rect, { width: finalWidth, x: finalX });\n }\n } else {\n // Vertical (default)\n const finalHeight = Math.max(0, Math.abs(barBaselineY - valuePx));\n const finalY = Math.min(valuePx, barBaselineY);\n\n setAttributes(rect, {\n fill: options.color,\n rx: options.borderRadius,\n ry: options.borderRadius,\n width: bandSize,\n x: bandPos,\n });\n\n if (isMount) {\n // Final geometry now; the grow reveal below uncovers it lane by lane, so a\n // rounded bar never renders as a corner-clamped 1-3 px sliver mid-grow.\n setAttributes(rect, { height: finalHeight, y: finalY });\n\n if (animateBars) {\n lanes.push({ anchor: barBaselineY, height: finalHeight, width: bandSize, x: bandPos, y: finalY });\n }\n } else if (animateBars) {\n if (isNew) {\n setAttributes(rect, { height: 0, y: barBaselineY });\n enterTargets.push({\n attrs: { height: { from: 0, to: finalHeight }, y: { from: barBaselineY, to: finalY } },\n el: rect,\n });\n } else {\n updateTargets.push({\n attrs: {\n height: { from: Number(rect.getAttribute('height') ?? finalHeight), to: finalHeight },\n y: { from: Number(rect.getAttribute('y') ?? finalY), to: finalY },\n },\n el: rect,\n });\n }\n } else {\n setAttributes(rect, { height: finalHeight, y: finalY });\n }\n }\n }\n\n if (animateBars) {\n const cancels: (() => void)[] = [];\n\n if (isMount && lanes.length > 0) {\n cancels.push(\n playGrowReveal(parent, lanes, () => {}, motion, {\n axis: horizontal ? 'x' : 'y',\n signal: options.disposalSignal,\n stagger: enterStagger,\n }),\n );\n }\n\n if (enterTargets.length > 0) {\n cancels.push(animate(enterTargets, { ...motion, stagger: enterStagger }, undefined, options.disposalSignal));\n }\n\n if (updateTargets.length > 0) {\n cancels.push(animate(updateTargets, { ...motion, stagger: 0 }, undefined, options.disposalSignal));\n }\n\n activeBarAnimations.set(parent, () => {\n for (const cancel of cancels) cancel();\n });\n }\n}\n"],"mappings":"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"}
@@ -1,2 +1,140 @@
1
- import{createSvgElement as e,setAttributes as t}from"../../svg/element.js";import{resolveMotion as n}from"../../animation/motion.js";import{animate as r}from"../../animation/transition.js";import{playGrowReveal as i}from"../../animation/reveal.js";var a=20,o=400,s=new WeakMap;function barsOf(e){return[...e.children].filter(e=>e.classList.contains(`prism-bar`))}function renderBars(c,l,u,d,f,p){s.get(c)?.(),s.delete(c);let m=barsOf(c);for(let e of m.slice(l.length))e.remove();let h=u.bandwidth(),g=p.stacked?h:h/p.seriesCount,_=Math.max(0,g-1),v=p.stacked?0:g*p.seriesIndex,y=p.horizontal??!1,b=m.length===0,x=[],S=[],C=[],w=n(p.transition,{defaultStagger:b?0:a}),T=w.duration>0,E=Math.min(w.stagger,o/Math.max(1,l.length));for(let n=0;n<l.length;n++){let r=l[n],i=u.map(r.key)+v,a=p.baselineYs?p.baselineYs[n]:f,o=d.map(r.y),s=m[n],h=!s;if(s||(s=e(`rect`,{class:`prism-bar`}),c.appendChild(s)),s.style.display=r.present?``:`none`,t(s,{opacity:r.opacity,stroke:r.dash?p.color:void 0,"stroke-dasharray":r.dash,"stroke-width":r.dash?1:void 0}),y){let e=Math.max(0,Math.abs(a-o)),n=Math.min(o,a);t(s,{fill:p.color,height:_,rx:p.borderRadius,ry:p.borderRadius,y:i}),b?(t(s,{width:e,x:n}),T&&C.push({anchor:a,height:_,width:e,x:n,y:i})):T?h?(t(s,{width:0,x:a}),x.push({attrs:{width:{from:0,to:e},x:{from:a,to:n}},el:s})):S.push({attrs:{width:{from:Number(s.getAttribute(`width`)??e),to:e},x:{from:Number(s.getAttribute(`x`)??n),to:n}},el:s}):t(s,{width:e,x:n})}else{let e=Math.max(0,Math.abs(a-o)),n=Math.min(o,a);t(s,{fill:p.color,rx:p.borderRadius,ry:p.borderRadius,width:_,x:i}),b?(t(s,{height:e,y:n}),T&&C.push({anchor:a,height:e,width:_,x:i,y:n})):T?h?(t(s,{height:0,y:a}),x.push({attrs:{height:{from:0,to:e},y:{from:a,to:n}},el:s})):S.push({attrs:{height:{from:Number(s.getAttribute(`height`)??e),to:e},y:{from:Number(s.getAttribute(`y`)??n),to:n}},el:s}):t(s,{height:e,y:n})}}if(T){let e=[];b&&C.length>0&&e.push(i(c,C,()=>{},w,{axis:y?`x`:`y`,signal:p.disposalSignal,stagger:E})),x.length>0&&e.push(r(x,{...w,stagger:E},void 0,p.disposalSignal)),S.length>0&&e.push(r(S,{...w,stagger:0},void 0,p.disposalSignal)),s.set(c,()=>{for(let t of e)t()})}}export{renderBars};
1
+ import { createSvgElement as e, setAttributes as t } from "../../svg/element.js";
2
+ import { resolveMotion as n } from "../../animation/motion.js";
3
+ import { animate as r } from "../../animation/transition.js";
4
+ import { playGrowReveal as i } from "../../animation/reveal.js";
5
+ //#region src/charts/bar/bar-renderer.ts
6
+ var a = 20, o = 400, s = /* @__PURE__ */ new WeakMap();
7
+ function barsOf(e) {
8
+ return [...e.children].filter((e) => e.classList.contains("prism-bar"));
9
+ }
10
+ function renderBars(c, l, u, d, f, p) {
11
+ s.get(c)?.(), s.delete(c);
12
+ let m = barsOf(c);
13
+ for (let e of m.slice(l.length)) e.remove();
14
+ let h = u.bandwidth(), g = p.stacked ? h : h / p.seriesCount, _ = Math.max(0, g - 1), v = p.stacked ? 0 : g * p.seriesIndex, y = p.horizontal ?? !1, b = m.length === 0, x = [], S = [], C = [], w = n(p.transition, { defaultStagger: b ? 0 : a }), T = w.duration > 0, E = Math.min(w.stagger, o / Math.max(1, l.length));
15
+ for (let n = 0; n < l.length; n++) {
16
+ let r = l[n], i = u.map(r.key) + v, a = p.baselineYs ? p.baselineYs[n] : f, o = d.map(r.y), s = m[n], h = !s;
17
+ if (s || (s = e("rect", { class: "prism-bar" }), c.appendChild(s)), s.style.display = r.present ? "" : "none", t(s, {
18
+ opacity: r.opacity,
19
+ stroke: r.dash ? p.color : void 0,
20
+ "stroke-dasharray": r.dash,
21
+ "stroke-width": r.dash ? 1 : void 0
22
+ }), y) {
23
+ let e = Math.max(0, Math.abs(a - o)), n = Math.min(o, a);
24
+ t(s, {
25
+ fill: p.color,
26
+ height: _,
27
+ rx: p.borderRadius,
28
+ ry: p.borderRadius,
29
+ y: i
30
+ }), b ? (t(s, {
31
+ width: e,
32
+ x: n
33
+ }), T && C.push({
34
+ anchor: a,
35
+ height: _,
36
+ width: e,
37
+ x: n,
38
+ y: i
39
+ })) : T ? h ? (t(s, {
40
+ width: 0,
41
+ x: a
42
+ }), x.push({
43
+ attrs: {
44
+ width: {
45
+ from: 0,
46
+ to: e
47
+ },
48
+ x: {
49
+ from: a,
50
+ to: n
51
+ }
52
+ },
53
+ el: s
54
+ })) : S.push({
55
+ attrs: {
56
+ width: {
57
+ from: Number(s.getAttribute("width") ?? e),
58
+ to: e
59
+ },
60
+ x: {
61
+ from: Number(s.getAttribute("x") ?? n),
62
+ to: n
63
+ }
64
+ },
65
+ el: s
66
+ }) : t(s, {
67
+ width: e,
68
+ x: n
69
+ });
70
+ } else {
71
+ let e = Math.max(0, Math.abs(a - o)), n = Math.min(o, a);
72
+ t(s, {
73
+ fill: p.color,
74
+ rx: p.borderRadius,
75
+ ry: p.borderRadius,
76
+ width: _,
77
+ x: i
78
+ }), b ? (t(s, {
79
+ height: e,
80
+ y: n
81
+ }), T && C.push({
82
+ anchor: a,
83
+ height: e,
84
+ width: _,
85
+ x: i,
86
+ y: n
87
+ })) : T ? h ? (t(s, {
88
+ height: 0,
89
+ y: a
90
+ }), x.push({
91
+ attrs: {
92
+ height: {
93
+ from: 0,
94
+ to: e
95
+ },
96
+ y: {
97
+ from: a,
98
+ to: n
99
+ }
100
+ },
101
+ el: s
102
+ })) : S.push({
103
+ attrs: {
104
+ height: {
105
+ from: Number(s.getAttribute("height") ?? e),
106
+ to: e
107
+ },
108
+ y: {
109
+ from: Number(s.getAttribute("y") ?? n),
110
+ to: n
111
+ }
112
+ },
113
+ el: s
114
+ }) : t(s, {
115
+ height: e,
116
+ y: n
117
+ });
118
+ }
119
+ }
120
+ if (T) {
121
+ let e = [];
122
+ b && C.length > 0 && e.push(i(c, C, () => {}, w, {
123
+ axis: y ? "x" : "y",
124
+ signal: p.disposalSignal,
125
+ stagger: E
126
+ })), x.length > 0 && e.push(r(x, {
127
+ ...w,
128
+ stagger: E
129
+ }, void 0, p.disposalSignal)), S.length > 0 && e.push(r(S, {
130
+ ...w,
131
+ stagger: 0
132
+ }, void 0, p.disposalSignal)), s.set(c, () => {
133
+ for (let t of e) t();
134
+ });
135
+ }
136
+ }
137
+ //#endregion
138
+ export { renderBars };
139
+
2
140
  //# sourceMappingURL=bar-renderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bar-renderer.js","names":[],"sources":["../../../src/charts/bar/bar-renderer.ts"],"sourcesContent":["import { resolveMotion } from '../../animation/motion';\nimport { type GrowRevealLane, playGrowReveal } from '../../animation/reveal';\nimport type { AnimationTarget } from '../../animation/transition';\nimport { animate } from '../../animation/transition';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { BandScale, Scale, TransitionOption } from '../../types';\n\nexport interface BarRenderOptions {\n baselineYs?: number[];\n borderRadius: number;\n color: string;\n /** Aborted when the owning chart is disposed: stops in-flight transitions from rescheduling. */\n disposalSignal?: AbortSignal;\n horizontal?: boolean;\n seriesCount: number;\n seriesIndex: number;\n stacked?: boolean;\n transition?: TransitionOption;\n}\n\n/** Preserve the stagger for bars inserted by a data update, not the initial entrance. */\nconst DEFAULT_NEW_BAR_STAGGER = 20;\n/** Upper bound on the total staggered delay a bar chart may add, whatever the per-bar value. */\nconst MAX_STAGGER_TOTAL = 400;\n\nconst activeBarAnimations = new WeakMap<SVGGElement, () => void>();\n\n/**\n * The group's bars in data order. Queried by class rather than by `children` index\n * because a mount reveal injects a `<defs>` into the same group.\n */\nfunction barsOf(parent: SVGGElement): SVGRectElement[] {\n return [...parent.children].filter((child): child is SVGRectElement => child.classList.contains('prism-bar'));\n}\n\nexport function renderBars(\n parent: SVGGElement,\n data: { base: number; dash?: string; key: string; opacity?: number; present: boolean; y: number }[],\n xScale: BandScale,\n yScale: Scale<number>,\n baselineY: number,\n options: BarRenderOptions,\n): void {\n activeBarAnimations.get(parent)?.();\n activeBarAnimations.delete(parent);\n const existingBars = barsOf(parent);\n\n for (const extra of existingBars.slice(data.length)) extra.remove();\n\n const bandwidth = xScale.bandwidth();\n const barBand = options.stacked ? bandwidth : bandwidth / options.seriesCount;\n const bandSize = Math.max(0, barBand - 1);\n const offset = options.stacked ? 0 : barBand * options.seriesIndex;\n const horizontal = options.horizontal ?? false;\n // A group with no bars yet is mounting: every bar enters together through a grow\n // reveal. A group that already has bars updates in place (with per-bar attr tweens).\n const isMount = existingBars.length === 0;\n\n const enterTargets: AnimationTarget[] = [];\n const updateTargets: AnimationTarget[] = [];\n const lanes: GrowRevealLane[] = [];\n const motion = resolveMotion(options.transition, { defaultStagger: isMount ? 0 : DEFAULT_NEW_BAR_STAGGER });\n const animateBars = motion.duration > 0;\n // A long category axis must not stretch the entrance past ~400 ms of added delay.\n const enterStagger = Math.min(motion.stagger, MAX_STAGGER_TOTAL / Math.max(1, data.length));\n\n for (let i = 0; i < data.length; i++) {\n const d = data[i];\n const bandPos = xScale.map(d.key) + offset;\n const barBaselineY = options.baselineYs ? options.baselineYs[i] : baselineY;\n const valuePx = yScale.map(d.y);\n\n let rect = existingBars[i];\n\n const isNew = !rect;\n\n if (!rect) {\n rect = createSvgElement('rect', { class: 'prism-bar' });\n parent.appendChild(rect);\n }\n\n rect.style.display = d.present ? '' : 'none';\n\n // Presentation attributes (not inline styles) so CSS interaction states\n // like the focus-dim rule keep winning over per-datum styling.\n setAttributes(rect, {\n opacity: d.opacity,\n stroke: d.dash ? options.color : undefined,\n 'stroke-dasharray': d.dash,\n 'stroke-width': d.dash ? 1 : undefined,\n });\n\n if (horizontal) {\n // Horizontal: category on Y axis, value on X axis\n // baselineY here is actually the baseline X (yScale.map(0) in value-space mapped to screen X)\n const finalWidth = Math.max(0, Math.abs(barBaselineY - valuePx));\n const finalX = Math.min(valuePx, barBaselineY);\n\n setAttributes(rect, {\n fill: options.color,\n height: bandSize,\n rx: options.borderRadius,\n ry: options.borderRadius,\n y: bandPos,\n });\n\n if (isMount) {\n // Final geometry now; the grow reveal below uncovers it lane by lane.\n setAttributes(rect, { width: finalWidth, x: finalX });\n\n if (animateBars) {\n lanes.push({ anchor: barBaselineY, height: bandSize, width: finalWidth, x: finalX, y: bandPos });\n }\n } else if (animateBars) {\n if (isNew) {\n setAttributes(rect, { width: 0, x: barBaselineY });\n enterTargets.push({\n attrs: { width: { from: 0, to: finalWidth }, x: { from: barBaselineY, to: finalX } },\n el: rect,\n });\n } else {\n updateTargets.push({\n attrs: {\n width: { from: Number(rect.getAttribute('width') ?? finalWidth), to: finalWidth },\n x: { from: Number(rect.getAttribute('x') ?? finalX), to: finalX },\n },\n el: rect,\n });\n }\n } else {\n setAttributes(rect, { width: finalWidth, x: finalX });\n }\n } else {\n // Vertical (default)\n const finalHeight = Math.max(0, Math.abs(barBaselineY - valuePx));\n const finalY = Math.min(valuePx, barBaselineY);\n\n setAttributes(rect, {\n fill: options.color,\n rx: options.borderRadius,\n ry: options.borderRadius,\n width: bandSize,\n x: bandPos,\n });\n\n if (isMount) {\n // Final geometry now; the grow reveal below uncovers it lane by lane, so a\n // rounded bar never renders as a corner-clamped 1-3 px sliver mid-grow.\n setAttributes(rect, { height: finalHeight, y: finalY });\n\n if (animateBars) {\n lanes.push({ anchor: barBaselineY, height: finalHeight, width: bandSize, x: bandPos, y: finalY });\n }\n } else if (animateBars) {\n if (isNew) {\n setAttributes(rect, { height: 0, y: barBaselineY });\n enterTargets.push({\n attrs: { height: { from: 0, to: finalHeight }, y: { from: barBaselineY, to: finalY } },\n el: rect,\n });\n } else {\n updateTargets.push({\n attrs: {\n height: { from: Number(rect.getAttribute('height') ?? finalHeight), to: finalHeight },\n y: { from: Number(rect.getAttribute('y') ?? finalY), to: finalY },\n },\n el: rect,\n });\n }\n } else {\n setAttributes(rect, { height: finalHeight, y: finalY });\n }\n }\n }\n\n if (animateBars) {\n const cancels: (() => void)[] = [];\n\n if (isMount && lanes.length > 0) {\n cancels.push(\n playGrowReveal(parent, lanes, () => {}, motion, {\n axis: horizontal ? 'x' : 'y',\n signal: options.disposalSignal,\n stagger: enterStagger,\n }),\n );\n }\n\n if (enterTargets.length > 0) {\n cancels.push(animate(enterTargets, { ...motion, stagger: enterStagger }, undefined, options.disposalSignal));\n }\n\n if (updateTargets.length > 0) {\n cancels.push(animate(updateTargets, { ...motion, stagger: 0 }, undefined, options.disposalSignal));\n }\n\n activeBarAnimations.set(parent, () => {\n for (const cancel of cancels) cancel();\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bar-renderer.js","names":["DEFAULT_NEW_BAR_STAGGER","MAX_STAGGER_TOTAL","activeBarAnimations","parent","child","existingBars","extra","data","bandwidth","xScale","barBand","options","bandSize","offset","horizontal","isMount","enterTargets","updateTargets","lanes","motion","resolveMotion","animateBars","enterStagger","i","d","bandPos","barBaselineY","baselineY","valuePx","yScale","rect","isNew","createSvgElement","setAttributes","finalWidth","finalX","finalHeight","finalY","cancels","playGrowReveal","animate","cancel"],"sources":["../../../src/charts/bar/bar-renderer.ts"],"sourcesContent":["import { resolveMotion } from '../../animation/motion';\nimport { type GrowRevealLane, playGrowReveal } from '../../animation/reveal';\nimport type { AnimationTarget } from '../../animation/transition';\nimport { animate } from '../../animation/transition';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { BandScale, Scale, TransitionOption } from '../../types';\n\nexport interface BarRenderOptions {\n baselineYs?: number[];\n borderRadius: number;\n color: string;\n /** Aborted when the owning chart is disposed: stops in-flight transitions from rescheduling. */\n disposalSignal?: AbortSignal;\n horizontal?: boolean;\n seriesCount: number;\n seriesIndex: number;\n stacked?: boolean;\n transition?: TransitionOption;\n}\n\n/** Preserve the stagger for bars inserted by a data update, not the initial entrance. */\nconst DEFAULT_NEW_BAR_STAGGER = 20;\n/** Upper bound on the total staggered delay a bar chart may add, whatever the per-bar value. */\nconst MAX_STAGGER_TOTAL = 400;\n\nconst activeBarAnimations = new WeakMap<SVGGElement, () => void>();\n\n/**\n * The group's bars in data order. Queried by class rather than by `children` index\n * because a mount reveal injects a `<defs>` into the same group.\n */\nfunction barsOf(parent: SVGGElement): SVGRectElement[] {\n return [...parent.children].filter((child): child is SVGRectElement => child.classList.contains('prism-bar'));\n}\n\nexport function renderBars(\n parent: SVGGElement,\n data: { base: number; dash?: string; key: string; opacity?: number; present: boolean; y: number }[],\n xScale: BandScale,\n yScale: Scale<number>,\n baselineY: number,\n options: BarRenderOptions,\n): void {\n activeBarAnimations.get(parent)?.();\n activeBarAnimations.delete(parent);\n const existingBars = barsOf(parent);\n\n for (const extra of existingBars.slice(data.length)) extra.remove();\n\n const bandwidth = xScale.bandwidth();\n const barBand = options.stacked ? bandwidth : bandwidth / options.seriesCount;\n const bandSize = Math.max(0, barBand - 1);\n const offset = options.stacked ? 0 : barBand * options.seriesIndex;\n const horizontal = options.horizontal ?? false;\n // A group with no bars yet is mounting: every bar enters together through a grow\n // reveal. A group that already has bars updates in place (with per-bar attr tweens).\n const isMount = existingBars.length === 0;\n\n const enterTargets: AnimationTarget[] = [];\n const updateTargets: AnimationTarget[] = [];\n const lanes: GrowRevealLane[] = [];\n const motion = resolveMotion(options.transition, { defaultStagger: isMount ? 0 : DEFAULT_NEW_BAR_STAGGER });\n const animateBars = motion.duration > 0;\n // A long category axis must not stretch the entrance past ~400 ms of added delay.\n const enterStagger = Math.min(motion.stagger, MAX_STAGGER_TOTAL / Math.max(1, data.length));\n\n for (let i = 0; i < data.length; i++) {\n const d = data[i];\n const bandPos = xScale.map(d.key) + offset;\n const barBaselineY = options.baselineYs ? options.baselineYs[i] : baselineY;\n const valuePx = yScale.map(d.y);\n\n let rect = existingBars[i];\n\n const isNew = !rect;\n\n if (!rect) {\n rect = createSvgElement('rect', { class: 'prism-bar' });\n parent.appendChild(rect);\n }\n\n rect.style.display = d.present ? '' : 'none';\n\n // Presentation attributes (not inline styles) so CSS interaction states\n // like the focus-dim rule keep winning over per-datum styling.\n setAttributes(rect, {\n opacity: d.opacity,\n stroke: d.dash ? options.color : undefined,\n 'stroke-dasharray': d.dash,\n 'stroke-width': d.dash ? 1 : undefined,\n });\n\n if (horizontal) {\n // Horizontal: category on Y axis, value on X axis\n // baselineY here is actually the baseline X (yScale.map(0) in value-space mapped to screen X)\n const finalWidth = Math.max(0, Math.abs(barBaselineY - valuePx));\n const finalX = Math.min(valuePx, barBaselineY);\n\n setAttributes(rect, {\n fill: options.color,\n height: bandSize,\n rx: options.borderRadius,\n ry: options.borderRadius,\n y: bandPos,\n });\n\n if (isMount) {\n // Final geometry now; the grow reveal below uncovers it lane by lane.\n setAttributes(rect, { width: finalWidth, x: finalX });\n\n if (animateBars) {\n lanes.push({ anchor: barBaselineY, height: bandSize, width: finalWidth, x: finalX, y: bandPos });\n }\n } else if (animateBars) {\n if (isNew) {\n setAttributes(rect, { width: 0, x: barBaselineY });\n enterTargets.push({\n attrs: { width: { from: 0, to: finalWidth }, x: { from: barBaselineY, to: finalX } },\n el: rect,\n });\n } else {\n updateTargets.push({\n attrs: {\n width: { from: Number(rect.getAttribute('width') ?? finalWidth), to: finalWidth },\n x: { from: Number(rect.getAttribute('x') ?? finalX), to: finalX },\n },\n el: rect,\n });\n }\n } else {\n setAttributes(rect, { width: finalWidth, x: finalX });\n }\n } else {\n // Vertical (default)\n const finalHeight = Math.max(0, Math.abs(barBaselineY - valuePx));\n const finalY = Math.min(valuePx, barBaselineY);\n\n setAttributes(rect, {\n fill: options.color,\n rx: options.borderRadius,\n ry: options.borderRadius,\n width: bandSize,\n x: bandPos,\n });\n\n if (isMount) {\n // Final geometry now; the grow reveal below uncovers it lane by lane, so a\n // rounded bar never renders as a corner-clamped 1-3 px sliver mid-grow.\n setAttributes(rect, { height: finalHeight, y: finalY });\n\n if (animateBars) {\n lanes.push({ anchor: barBaselineY, height: finalHeight, width: bandSize, x: bandPos, y: finalY });\n }\n } else if (animateBars) {\n if (isNew) {\n setAttributes(rect, { height: 0, y: barBaselineY });\n enterTargets.push({\n attrs: { height: { from: 0, to: finalHeight }, y: { from: barBaselineY, to: finalY } },\n el: rect,\n });\n } else {\n updateTargets.push({\n attrs: {\n height: { from: Number(rect.getAttribute('height') ?? finalHeight), to: finalHeight },\n y: { from: Number(rect.getAttribute('y') ?? finalY), to: finalY },\n },\n el: rect,\n });\n }\n } else {\n setAttributes(rect, { height: finalHeight, y: finalY });\n }\n }\n }\n\n if (animateBars) {\n const cancels: (() => void)[] = [];\n\n if (isMount && lanes.length > 0) {\n cancels.push(\n playGrowReveal(parent, lanes, () => {}, motion, {\n axis: horizontal ? 'x' : 'y',\n signal: options.disposalSignal,\n stagger: enterStagger,\n }),\n );\n }\n\n if (enterTargets.length > 0) {\n cancels.push(animate(enterTargets, { ...motion, stagger: enterStagger }, undefined, options.disposalSignal));\n }\n\n if (updateTargets.length > 0) {\n cancels.push(animate(updateTargets, { ...motion, stagger: 0 }, undefined, options.disposalSignal));\n }\n\n activeBarAnimations.set(parent, () => {\n for (const cancel of cancels) cancel();\n });\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"line-chart.cjs","names":[],"sources":["../../../src/charts/line/line-chart.ts"],"sourcesContent":["import { positionAxis, renderAxis, resolveTickCount, resolveTicks } from '../../axes/axis';\nimport { renderGrid } from '../../axes/grid';\nimport { buildXScale, buildYScale } from '../../core/cartesian-scales';\nimport { clearCartesianDom, createChartScaffold } from '../../core/chart-scaffold';\nimport { chartArea, resolveMargin } from '../../core/layout';\nimport { seriesDomId } from '../../core/series-id';\nimport { createCrosshair } from '../../interaction/crosshair';\nimport { createSeriesInteraction, ensureMarkerGroup } from '../../interaction/series-interaction';\nimport { createSvgElement } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { seriesColor } from '../../theme';\nimport type { ChartHandle, LineChartConfig, LineSeriesConfig, XAxisConfig, YAxisConfig } from '../../types';\nimport { computePoints, renderLine } from './line-renderer';\n\nexport function createLineChart(container: HTMLElement, config: LineChartConfig): ChartHandle<LineSeriesConfig[]> {\n let crosshair: ReturnType<typeof createCrosshair> | null = null;\n let markers: SVGGElement | null = null;\n let rightAxis: SVGGElement | null = null;\n let seriesList = config.series;\n\n return createChartScaffold(\n container,\n config,\n (ctx, reason) => {\n const { groups, legend, tooltip } = ctx;\n legend?.update(seriesList.map((s, i) => ({ color: seriesColor(i, s.color), name: s.name })));\n const dims = ctx.dimensions;\n const hasRight = seriesList.some((series) => series.yAxis === 'right');\n const hasLeftData = seriesList.some((series) => series.yAxis !== 'right' && series.data.length > 0);\n // The right axis widens the right margin; the effective margin stays local to this\n // render pass (and is handed to the interaction layer) instead of mutating shared dims.\n const margin = {\n ...resolveMargin(config.margin),\n right:\n config.margin?.right ??\n (hasRight ? (config.rightYAxis?.label ? 72 : 50) : resolveMargin(config.margin).right),\n };\n const area = chartArea(dims.width, dims.height, margin);\n const allData = seriesList.map((series) => series.data);\n const allX = allData.flat().map((datum) => datum.key);\n const leftY = seriesList\n .filter((series) => series.yAxis !== 'right')\n .flatMap((series) => series.data.map((datum) => datum.value));\n const rightY = seriesList\n .filter((series) => series.yAxis === 'right')\n .flatMap((series) => series.data.map((datum) => datum.value));\n\n if (allX.length === 0) {\n clearCartesianDom(groups, legend, tooltip, crosshair);\n markers?.replaceChildren();\n rightAxis?.replaceChildren();\n\n return;\n }\n\n if (config.crosshair && !crosshair) {\n crosshair = createCrosshair(ctx.chartArea, config.crosshair);\n }\n\n const xScale = buildXScale(allX, area.width);\n const yScale = buildYScale(leftY, area.height);\n const rightYScale = buildYScale(rightY, area.height);\n\n // Axes render by default (value axis with gridlines); `false` opts out. The value\n // axis merges over its default so a partial config (e.g. only `tickFormat`) keeps\n // the default gridlines.\n const xAxisConfig: XAxisConfig | false = config.xAxis === false ? false : (config.xAxis ?? {});\n const yAxisConfig: YAxisConfig | false = config.yAxis === false ? false : { grid: true, ...config.yAxis };\n\n if (yAxisConfig && yAxisConfig.grid && (!hasRight || hasLeftData)) {\n renderGrid(\n groups.grid,\n yScale,\n yAxisConfig.grid,\n area.width,\n 'horizontal',\n resolveTicks(yScale, yAxisConfig, resolveTickCount(yAxisConfig, area.height, 'left')),\n );\n } else {\n groups.grid.replaceChildren();\n }\n\n if (xAxisConfig && xAxisConfig.grid) {\n renderGrid(\n groups.grid,\n xScale,\n xAxisConfig.grid,\n area.height,\n 'vertical',\n resolveTicks(xScale, xAxisConfig, resolveTickCount(xAxisConfig, area.width, 'bottom')),\n );\n }\n\n if (xAxisConfig) {\n positionAxis(groups.xAxis, xAxisConfig.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, xScale, xAxisConfig, area.width, 'bottom');\n } else {\n groups.xAxis.replaceChildren();\n }\n\n if (yAxisConfig && (!hasRight || hasLeftData)) {\n const axis = { ...yAxisConfig, position: hasRight ? ('left' as const) : (yAxisConfig.position ?? 'left') };\n positionAxis(groups.yAxis, axis.position, area.width, area.height);\n renderAxis(groups.yAxis, yScale, axis, area.height, 'left');\n } else {\n groups.yAxis.replaceChildren();\n }\n\n if (hasRight) {\n if (!rightAxis) {\n rightAxis = createSvgElement('g', { class: 'prism-y-axis-right' });\n ctx.chartArea.appendChild(rightAxis);\n }\n const axis = { ...config.rightYAxis, position: 'right' as const };\n positionAxis(rightAxis, 'right', area.width, area.height);\n renderAxis(rightAxis, rightYScale, axis, area.height, 'right');\n } else {\n rightAxis?.replaceChildren();\n }\n\n while (groups.series.children.length > seriesList.length) {\n groups.series.removeChild(groups.series.lastChild!);\n }\n\n const allPoints: Point[][] = [];\n\n for (let i = 0; i < seriesList.length; i++) {\n const series = seriesList[i];\n let group = groups.series.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-line-series' });\n groups.series.appendChild(group);\n }\n\n group.setAttribute('data-series-id', seriesDomId(series, i));\n\n const seriesScale = series.yAxis === 'right' ? rightYScale : yScale;\n const points = computePoints(allData[i], xScale, seriesScale);\n\n allPoints.push(points);\n\n renderLine(group, points, {\n bounds: { height: area.height, width: area.width },\n color: seriesColor(i, series.color),\n curve: series.curve ?? 'linear',\n disposalSignal: ctx.disposalSignal,\n marks: series.data,\n pointRadius: series.pointRadius ?? 3,\n showPoints: series.showPoints ?? false,\n strokeWidth: series.strokeWidth,\n transition: reason === 'resize' ? false : config.transition,\n });\n }\n\n tooltip?.hide();\n markers = ensureMarkerGroup(ctx.chartArea, markers);\n\n return createSeriesInteraction({\n announcer: ctx.announcer,\n colors: () => seriesList.map((s, i) => seriesColor(i, s.color)),\n crosshair,\n dims: () => ctx.dimensions,\n getData: () => allData,\n getPoints: () => allPoints,\n getSeriesList: () => seriesList,\n margin,\n markers,\n onClick: config.onClick,\n onHover: config.onHover,\n seriesGroup: groups.series,\n svg: ctx.svg,\n tooltip,\n tooltipFormat: typeof config.tooltip === 'object' ? config.tooltip : undefined,\n });\n },\n (data) => {\n seriesList = data;\n },\n );\n}\n"],"mappings":"mbAcA,SAAgB,gBAAgB,EAAwB,EAA0D,CAChH,IAAI,EAAuD,KACvD,EAA8B,KAC9B,EAAgC,KAChC,EAAa,EAAO,OAExB,OAAO,EAAA,oBACL,EACA,GACC,EAAK,IAAW,CACf,GAAM,CAAE,SAAQ,SAAQ,WAAY,EACpC,GAAQ,OAAO,EAAW,KAAK,EAAG,KAAO,CAAE,MAAO,EAAA,YAAY,EAAG,EAAE,KAAK,EAAG,KAAM,EAAE,IAAK,EAAE,CAAC,EAC3F,IAAM,EAAO,EAAI,WACX,EAAW,EAAW,KAAM,GAAW,EAAO,QAAU,OAAO,EAC/D,EAAc,EAAW,KAAM,GAAW,EAAO,QAAU,SAAW,EAAO,KAAK,OAAS,CAAC,EAG5F,EAAS,CACb,GAAG,EAAA,cAAc,EAAO,MAAM,EAC9B,MACE,EAAO,QAAQ,QACd,EAAY,EAAO,YAAY,MAAQ,GAAK,GAAM,EAAA,cAAc,EAAO,MAAM,CAAC,CAAC,MACpF,EACM,EAAO,EAAA,UAAU,EAAK,MAAO,EAAK,OAAQ,CAAM,EAChD,EAAU,EAAW,IAAK,GAAW,EAAO,IAAI,EAChD,EAAO,EAAQ,KAAK,CAAC,CAAC,IAAK,GAAU,EAAM,GAAG,EAC9C,EAAQ,EACX,OAAQ,GAAW,EAAO,QAAU,OAAO,CAAC,CAC5C,QAAS,GAAW,EAAO,KAAK,IAAK,GAAU,EAAM,KAAK,CAAC,EACxD,EAAS,EACZ,OAAQ,GAAW,EAAO,QAAU,OAAO,CAAC,CAC5C,QAAS,GAAW,EAAO,KAAK,IAAK,GAAU,EAAM,KAAK,CAAC,EAE9D,GAAI,EAAK,SAAW,EAAG,CACrB,EAAA,kBAAkB,EAAQ,EAAQ,EAAS,CAAS,EACpD,GAAS,gBAAgB,EACzB,GAAW,gBAAgB,EAE3B,MACF,CAEI,EAAO,WAAa,CAAC,IACvB,EAAY,EAAA,gBAAgB,EAAI,UAAW,EAAO,SAAS,GAG7D,IAAM,EAAS,EAAA,YAAY,EAAM,EAAK,KAAK,EACrC,EAAS,EAAA,YAAY,EAAO,EAAK,MAAM,EACvC,EAAc,EAAA,YAAY,EAAQ,EAAK,MAAM,EAK7C,EAAmC,EAAO,QAAU,GAAQ,GAAS,EAAO,OAAS,CAAC,EACtF,EAAmC,EAAO,QAAU,IAAgB,CAAE,KAAM,GAAM,GAAG,EAAO,KAAM,EAiCxG,GA/BI,GAAe,EAAY,OAAS,CAAC,GAAY,GACnD,EAAA,WACE,EAAO,KACP,EACA,EAAY,KACZ,EAAK,MACL,aACA,EAAA,aAAa,EAAQ,EAAa,EAAA,iBAAiB,EAAa,EAAK,OAAQ,MAAM,CAAC,CACtF,EAEA,EAAO,KAAK,gBAAgB,EAG1B,GAAe,EAAY,MAC7B,EAAA,WACE,EAAO,KACP,EACA,EAAY,KACZ,EAAK,OACL,WACA,EAAA,aAAa,EAAQ,EAAa,EAAA,iBAAiB,EAAa,EAAK,MAAO,QAAQ,CAAC,CACvF,EAGE,GACF,EAAA,aAAa,EAAO,MAAO,EAAY,UAAY,SAAU,EAAK,MAAO,EAAK,MAAM,EACpF,EAAA,WAAW,EAAO,MAAO,EAAQ,EAAa,EAAK,MAAO,QAAQ,GAElE,EAAO,MAAM,gBAAgB,EAG3B,IAAgB,CAAC,GAAY,GAAc,CAC7C,IAAM,EAAO,CAAE,GAAG,EAAa,SAAU,EAAY,OAAoB,EAAY,UAAY,MAAQ,EACzG,EAAA,aAAa,EAAO,MAAO,EAAK,SAAU,EAAK,MAAO,EAAK,MAAM,EACjE,EAAA,WAAW,EAAO,MAAO,EAAQ,EAAM,EAAK,OAAQ,MAAM,CAC5D,MACE,EAAO,MAAM,gBAAgB,EAG/B,GAAI,EAAU,CACP,IACH,EAAY,EAAA,iBAAiB,IAAK,CAAE,MAAO,oBAAqB,CAAC,EACjE,EAAI,UAAU,YAAY,CAAS,GAErC,IAAM,EAAO,CAAE,GAAG,EAAO,WAAY,SAAU,OAAiB,EAChE,EAAA,aAAa,EAAW,QAAS,EAAK,MAAO,EAAK,MAAM,EACxD,EAAA,WAAW,EAAW,EAAa,EAAM,EAAK,OAAQ,OAAO,CAC/D,MACE,GAAW,gBAAgB,EAG7B,KAAO,EAAO,OAAO,SAAS,OAAS,EAAW,QAChD,EAAO,OAAO,YAAY,EAAO,OAAO,SAAU,EAGpD,IAAM,EAAuB,CAAC,EAE9B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,OAAQ,IAAK,CAC1C,IAAM,EAAS,EAAW,GACtB,EAAQ,EAAO,OAAO,SAAS,GAE9B,IACH,EAAQ,EAAA,iBAAiB,IAAK,CAAE,MAAO,mBAAoB,CAAC,EAC5D,EAAO,OAAO,YAAY,CAAK,GAGjC,EAAM,aAAa,iBAAkB,EAAA,YAAY,EAAQ,CAAC,CAAC,EAE3D,IAAM,EAAc,EAAO,QAAU,QAAU,EAAc,EACvD,EAAS,EAAA,cAAc,EAAQ,GAAI,EAAQ,CAAW,EAE5D,EAAU,KAAK,CAAM,EAErB,EAAA,WAAW,EAAO,EAAQ,CACxB,OAAQ,CAAE,OAAQ,EAAK,OAAQ,MAAO,EAAK,KAAM,EACjD,MAAO,EAAA,YAAY,EAAG,EAAO,KAAK,EAClC,MAAO,EAAO,OAAS,SACvB,eAAgB,EAAI,eACpB,MAAO,EAAO,KACd,YAAa,EAAO,aAAe,EACnC,WAAY,EAAO,YAAc,GACjC,YAAa,EAAO,YACpB,WAAY,IAAW,UAAmB,EAAO,UACnD,CAAC,CACH,CAKA,OAHA,GAAS,KAAK,EACd,EAAU,EAAA,kBAAkB,EAAI,UAAW,CAAO,EAE3C,EAAA,wBAAwB,CAC7B,UAAW,EAAI,UACf,WAAc,EAAW,KAAK,EAAG,IAAM,EAAA,YAAY,EAAG,EAAE,KAAK,CAAC,EAC9D,YACA,SAAY,EAAI,WAChB,YAAe,EACf,cAAiB,EACjB,kBAAqB,EACrB,SACA,UACA,QAAS,EAAO,QAChB,QAAS,EAAO,QAChB,YAAa,EAAO,OACpB,IAAK,EAAI,IACT,UACA,cAAe,OAAO,EAAO,SAAY,SAAW,EAAO,QAAU,IAAA,EACvE,CAAC,CACH,EACC,GAAS,CACR,EAAa,CACf,CACF,CACF"}
1
+ {"version":3,"file":"line-chart.cjs","names":["createChartScaffold","seriesColor","resolveMargin","chartArea","createCrosshair","buildXScale","buildYScale","resolveTicks","resolveTickCount","createSvgElement","seriesDomId","computePoints","ensureMarkerGroup","createSeriesInteraction","require_element","require_axis","require_grid","require_cartesian_scales","require_layout","require_chart_scaffold","require_series_id","require_crosshair","require_series_interaction","require_index","require_line_renderer","crosshair","markers","rightAxis","seriesList","config","container","ctx","legend","i","s","dims","hasRight","series","hasLeftData","margin","area","allData","allX","datum","leftY","rightY","groups","tooltip","xScale","yScale","rightYScale","xAxisConfig","yAxisConfig","axis","allPoints","group","seriesScale","points","reason","data"],"sources":["../../../src/charts/line/line-chart.ts"],"sourcesContent":["import { positionAxis, renderAxis, resolveTickCount, resolveTicks } from '../../axes/axis';\nimport { renderGrid } from '../../axes/grid';\nimport { buildXScale, buildYScale } from '../../core/cartesian-scales';\nimport { clearCartesianDom, createChartScaffold } from '../../core/chart-scaffold';\nimport { chartArea, resolveMargin } from '../../core/layout';\nimport { seriesDomId } from '../../core/series-id';\nimport { createCrosshair } from '../../interaction/crosshair';\nimport { createSeriesInteraction, ensureMarkerGroup } from '../../interaction/series-interaction';\nimport { createSvgElement } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { seriesColor } from '../../theme';\nimport type { ChartHandle, LineChartConfig, LineSeriesConfig, XAxisConfig, YAxisConfig } from '../../types';\nimport { computePoints, renderLine } from './line-renderer';\n\nexport function createLineChart(container: HTMLElement, config: LineChartConfig): ChartHandle<LineSeriesConfig[]> {\n let crosshair: ReturnType<typeof createCrosshair> | null = null;\n let markers: SVGGElement | null = null;\n let rightAxis: SVGGElement | null = null;\n let seriesList = config.series;\n\n return createChartScaffold(\n container,\n config,\n (ctx, reason) => {\n const { groups, legend, tooltip } = ctx;\n legend?.update(seriesList.map((s, i) => ({ color: seriesColor(i, s.color), name: s.name })));\n const dims = ctx.dimensions;\n const hasRight = seriesList.some((series) => series.yAxis === 'right');\n const hasLeftData = seriesList.some((series) => series.yAxis !== 'right' && series.data.length > 0);\n // The right axis widens the right margin; the effective margin stays local to this\n // render pass (and is handed to the interaction layer) instead of mutating shared dims.\n const margin = {\n ...resolveMargin(config.margin),\n right:\n config.margin?.right ??\n (hasRight ? (config.rightYAxis?.label ? 72 : 50) : resolveMargin(config.margin).right),\n };\n const area = chartArea(dims.width, dims.height, margin);\n const allData = seriesList.map((series) => series.data);\n const allX = allData.flat().map((datum) => datum.key);\n const leftY = seriesList\n .filter((series) => series.yAxis !== 'right')\n .flatMap((series) => series.data.map((datum) => datum.value));\n const rightY = seriesList\n .filter((series) => series.yAxis === 'right')\n .flatMap((series) => series.data.map((datum) => datum.value));\n\n if (allX.length === 0) {\n clearCartesianDom(groups, legend, tooltip, crosshair);\n markers?.replaceChildren();\n rightAxis?.replaceChildren();\n\n return;\n }\n\n if (config.crosshair && !crosshair) {\n crosshair = createCrosshair(ctx.chartArea, config.crosshair);\n }\n\n const xScale = buildXScale(allX, area.width);\n const yScale = buildYScale(leftY, area.height);\n const rightYScale = buildYScale(rightY, area.height);\n\n // Axes render by default (value axis with gridlines); `false` opts out. The value\n // axis merges over its default so a partial config (e.g. only `tickFormat`) keeps\n // the default gridlines.\n const xAxisConfig: XAxisConfig | false = config.xAxis === false ? false : (config.xAxis ?? {});\n const yAxisConfig: YAxisConfig | false = config.yAxis === false ? false : { grid: true, ...config.yAxis };\n\n if (yAxisConfig && yAxisConfig.grid && (!hasRight || hasLeftData)) {\n renderGrid(\n groups.grid,\n yScale,\n yAxisConfig.grid,\n area.width,\n 'horizontal',\n resolveTicks(yScale, yAxisConfig, resolveTickCount(yAxisConfig, area.height, 'left')),\n );\n } else {\n groups.grid.replaceChildren();\n }\n\n if (xAxisConfig && xAxisConfig.grid) {\n renderGrid(\n groups.grid,\n xScale,\n xAxisConfig.grid,\n area.height,\n 'vertical',\n resolveTicks(xScale, xAxisConfig, resolveTickCount(xAxisConfig, area.width, 'bottom')),\n );\n }\n\n if (xAxisConfig) {\n positionAxis(groups.xAxis, xAxisConfig.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, xScale, xAxisConfig, area.width, 'bottom');\n } else {\n groups.xAxis.replaceChildren();\n }\n\n if (yAxisConfig && (!hasRight || hasLeftData)) {\n const axis = { ...yAxisConfig, position: hasRight ? ('left' as const) : (yAxisConfig.position ?? 'left') };\n positionAxis(groups.yAxis, axis.position, area.width, area.height);\n renderAxis(groups.yAxis, yScale, axis, area.height, 'left');\n } else {\n groups.yAxis.replaceChildren();\n }\n\n if (hasRight) {\n if (!rightAxis) {\n rightAxis = createSvgElement('g', { class: 'prism-y-axis-right' });\n ctx.chartArea.appendChild(rightAxis);\n }\n const axis = { ...config.rightYAxis, position: 'right' as const };\n positionAxis(rightAxis, 'right', area.width, area.height);\n renderAxis(rightAxis, rightYScale, axis, area.height, 'right');\n } else {\n rightAxis?.replaceChildren();\n }\n\n while (groups.series.children.length > seriesList.length) {\n groups.series.removeChild(groups.series.lastChild!);\n }\n\n const allPoints: Point[][] = [];\n\n for (let i = 0; i < seriesList.length; i++) {\n const series = seriesList[i];\n let group = groups.series.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-line-series' });\n groups.series.appendChild(group);\n }\n\n group.setAttribute('data-series-id', seriesDomId(series, i));\n\n const seriesScale = series.yAxis === 'right' ? rightYScale : yScale;\n const points = computePoints(allData[i], xScale, seriesScale);\n\n allPoints.push(points);\n\n renderLine(group, points, {\n bounds: { height: area.height, width: area.width },\n color: seriesColor(i, series.color),\n curve: series.curve ?? 'linear',\n disposalSignal: ctx.disposalSignal,\n marks: series.data,\n pointRadius: series.pointRadius ?? 3,\n showPoints: series.showPoints ?? false,\n strokeWidth: series.strokeWidth,\n transition: reason === 'resize' ? false : config.transition,\n });\n }\n\n tooltip?.hide();\n markers = ensureMarkerGroup(ctx.chartArea, markers);\n\n return createSeriesInteraction({\n announcer: ctx.announcer,\n colors: () => seriesList.map((s, i) => seriesColor(i, s.color)),\n crosshair,\n dims: () => ctx.dimensions,\n getData: () => allData,\n getPoints: () => allPoints,\n getSeriesList: () => seriesList,\n margin,\n markers,\n onClick: config.onClick,\n onHover: config.onHover,\n seriesGroup: groups.series,\n svg: ctx.svg,\n tooltip,\n tooltipFormat: typeof config.tooltip === 'object' ? config.tooltip : undefined,\n });\n },\n (data) => {\n seriesList = data;\n },\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,94 @@
1
- import{createSvgElement as e}from"../../svg/element.js";import{positionAxis as t,renderAxis as n,resolveTickCount as r,resolveTicks as i}from"../../axes/axis.js";import{renderGrid as a}from"../../axes/grid.js";import{buildXScale as o,buildYScale as s}from"../../core/cartesian-scales.js";import{chartArea as c,resolveMargin as l}from"../../core/layout.js";import{clearCartesianDom as u,createChartScaffold as d}from"../../core/chart-scaffold.js";import{seriesDomId as f}from"../../core/series-id.js";import{createCrosshair as p}from"../../interaction/crosshair.js";import{createSeriesInteraction as m,ensureMarkerGroup as h}from"../../interaction/series-interaction.js";import{seriesColor as g}from"../../theme/index.js";import{computePoints as _,renderLine as v}from"./line-renderer.js";function createLineChart(y,b){let x=null,S=null,C=null,w=b.series;return d(y,b,(d,y)=>{let{groups:T,legend:E,tooltip:D}=d;E?.update(w.map((e,t)=>({color:g(t,e.color),name:e.name})));let O=d.dimensions,k=w.some(e=>e.yAxis===`right`),A=w.some(e=>e.yAxis!==`right`&&e.data.length>0),j={...l(b.margin),right:b.margin?.right??(k?b.rightYAxis?.label?72:50:l(b.margin).right)},M=c(O.width,O.height,j),N=w.map(e=>e.data),P=N.flat().map(e=>e.key),F=w.filter(e=>e.yAxis!==`right`).flatMap(e=>e.data.map(e=>e.value)),I=w.filter(e=>e.yAxis===`right`).flatMap(e=>e.data.map(e=>e.value));if(P.length===0){u(T,E,D,x),S?.replaceChildren(),C?.replaceChildren();return}b.crosshair&&!x&&(x=p(d.chartArea,b.crosshair));let L=o(P,M.width),R=s(F,M.height),z=s(I,M.height),B=b.xAxis===!1?!1:b.xAxis??{},V=b.yAxis!==!1&&{grid:!0,...b.yAxis};if(V&&V.grid&&(!k||A)?a(T.grid,R,V.grid,M.width,`horizontal`,i(R,V,r(V,M.height,`left`))):T.grid.replaceChildren(),B&&B.grid&&a(T.grid,L,B.grid,M.height,`vertical`,i(L,B,r(B,M.width,`bottom`))),B?(t(T.xAxis,B.position??`bottom`,M.width,M.height),n(T.xAxis,L,B,M.width,`bottom`)):T.xAxis.replaceChildren(),V&&(!k||A)){let e={...V,position:k?`left`:V.position??`left`};t(T.yAxis,e.position,M.width,M.height),n(T.yAxis,R,e,M.height,`left`)}else T.yAxis.replaceChildren();if(k){C||(C=e(`g`,{class:`prism-y-axis-right`}),d.chartArea.appendChild(C));let r={...b.rightYAxis,position:`right`};t(C,`right`,M.width,M.height),n(C,z,r,M.height,`right`)}else C?.replaceChildren();for(;T.series.children.length>w.length;)T.series.removeChild(T.series.lastChild);let H=[];for(let t=0;t<w.length;t++){let n=w[t],r=T.series.children[t];r||(r=e(`g`,{class:`prism-line-series`}),T.series.appendChild(r)),r.setAttribute(`data-series-id`,f(n,t));let i=n.yAxis===`right`?z:R,a=_(N[t],L,i);H.push(a),v(r,a,{bounds:{height:M.height,width:M.width},color:g(t,n.color),curve:n.curve??`linear`,disposalSignal:d.disposalSignal,marks:n.data,pointRadius:n.pointRadius??3,showPoints:n.showPoints??!1,strokeWidth:n.strokeWidth,transition:y!==`resize`&&b.transition})}return D?.hide(),S=h(d.chartArea,S),m({announcer:d.announcer,colors:()=>w.map((e,t)=>g(t,e.color)),crosshair:x,dims:()=>d.dimensions,getData:()=>N,getPoints:()=>H,getSeriesList:()=>w,margin:j,markers:S,onClick:b.onClick,onHover:b.onHover,seriesGroup:T.series,svg:d.svg,tooltip:D,tooltipFormat:typeof b.tooltip==`object`?b.tooltip:void 0})},e=>{w=e})}export{createLineChart};
1
+ import { createSvgElement as e } from "../../svg/element.js";
2
+ import { positionAxis as t, renderAxis as n, resolveTickCount as r, resolveTicks as i } from "../../axes/axis.js";
3
+ import { renderGrid as a } from "../../axes/grid.js";
4
+ import { buildXScale as o, buildYScale as s } from "../../core/cartesian-scales.js";
5
+ import { chartArea as c, resolveMargin as l } from "../../core/layout.js";
6
+ import { clearCartesianDom as u, createChartScaffold as d } from "../../core/chart-scaffold.js";
7
+ import { seriesDomId as f } from "../../core/series-id.js";
8
+ import { createCrosshair as p } from "../../interaction/crosshair.js";
9
+ import { createSeriesInteraction as m, ensureMarkerGroup as h } from "../../interaction/series-interaction.js";
10
+ import { seriesColor as g } from "../../theme/index.js";
11
+ import { computePoints as _, renderLine as v } from "./line-renderer.js";
12
+ //#region src/charts/line/line-chart.ts
13
+ function createLineChart(y, b) {
14
+ let x = null, S = null, C = null, w = b.series;
15
+ return d(y, b, (d, y) => {
16
+ let { groups: T, legend: E, tooltip: D } = d;
17
+ E?.update(w.map((e, t) => ({
18
+ color: g(t, e.color),
19
+ name: e.name
20
+ })));
21
+ let O = d.dimensions, k = w.some((e) => e.yAxis === "right"), A = w.some((e) => e.yAxis !== "right" && e.data.length > 0), j = {
22
+ ...l(b.margin),
23
+ right: b.margin?.right ?? (k ? b.rightYAxis?.label ? 72 : 50 : l(b.margin).right)
24
+ }, M = c(O.width, O.height, j), N = w.map((e) => e.data), P = N.flat().map((e) => e.key), F = w.filter((e) => e.yAxis !== "right").flatMap((e) => e.data.map((e) => e.value)), I = w.filter((e) => e.yAxis === "right").flatMap((e) => e.data.map((e) => e.value));
25
+ if (P.length === 0) {
26
+ u(T, E, D, x), S?.replaceChildren(), C?.replaceChildren();
27
+ return;
28
+ }
29
+ b.crosshair && !x && (x = p(d.chartArea, b.crosshair));
30
+ let L = o(P, M.width), R = s(F, M.height), z = s(I, M.height), B = b.xAxis === !1 ? !1 : b.xAxis ?? {}, V = b.yAxis !== !1 && {
31
+ grid: !0,
32
+ ...b.yAxis
33
+ };
34
+ if (V && V.grid && (!k || A) ? a(T.grid, R, V.grid, M.width, "horizontal", i(R, V, r(V, M.height, "left"))) : T.grid.replaceChildren(), B && B.grid && a(T.grid, L, B.grid, M.height, "vertical", i(L, B, r(B, M.width, "bottom"))), B ? (t(T.xAxis, B.position ?? "bottom", M.width, M.height), n(T.xAxis, L, B, M.width, "bottom")) : T.xAxis.replaceChildren(), V && (!k || A)) {
35
+ let e = {
36
+ ...V,
37
+ position: k ? "left" : V.position ?? "left"
38
+ };
39
+ t(T.yAxis, e.position, M.width, M.height), n(T.yAxis, R, e, M.height, "left");
40
+ } else T.yAxis.replaceChildren();
41
+ if (k) {
42
+ C || (C = e("g", { class: "prism-y-axis-right" }), d.chartArea.appendChild(C));
43
+ let r = {
44
+ ...b.rightYAxis,
45
+ position: "right"
46
+ };
47
+ t(C, "right", M.width, M.height), n(C, z, r, M.height, "right");
48
+ } else C?.replaceChildren();
49
+ for (; T.series.children.length > w.length;) T.series.removeChild(T.series.lastChild);
50
+ let H = [];
51
+ for (let t = 0; t < w.length; t++) {
52
+ let n = w[t], r = T.series.children[t];
53
+ r || (r = e("g", { class: "prism-line-series" }), T.series.appendChild(r)), r.setAttribute("data-series-id", f(n, t));
54
+ let i = n.yAxis === "right" ? z : R, a = _(N[t], L, i);
55
+ H.push(a), v(r, a, {
56
+ bounds: {
57
+ height: M.height,
58
+ width: M.width
59
+ },
60
+ color: g(t, n.color),
61
+ curve: n.curve ?? "linear",
62
+ disposalSignal: d.disposalSignal,
63
+ marks: n.data,
64
+ pointRadius: n.pointRadius ?? 3,
65
+ showPoints: n.showPoints ?? !1,
66
+ strokeWidth: n.strokeWidth,
67
+ transition: y !== "resize" && b.transition
68
+ });
69
+ }
70
+ return D?.hide(), S = h(d.chartArea, S), m({
71
+ announcer: d.announcer,
72
+ colors: () => w.map((e, t) => g(t, e.color)),
73
+ crosshair: x,
74
+ dims: () => d.dimensions,
75
+ getData: () => N,
76
+ getPoints: () => H,
77
+ getSeriesList: () => w,
78
+ margin: j,
79
+ markers: S,
80
+ onClick: b.onClick,
81
+ onHover: b.onHover,
82
+ seriesGroup: T.series,
83
+ svg: d.svg,
84
+ tooltip: D,
85
+ tooltipFormat: typeof b.tooltip == "object" ? b.tooltip : void 0
86
+ });
87
+ }, (e) => {
88
+ w = e;
89
+ });
90
+ }
91
+ //#endregion
92
+ export { createLineChart };
93
+
2
94
  //# sourceMappingURL=line-chart.js.map