@vielzeug/prism 26.11.4 → 26.11.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -10
- package/dist/_dev.js +1 -2
- package/dist/_tappers.js +1 -2
- package/dist/animation/easing.js +1 -2
- package/dist/animation/motion.js +0 -1
- package/dist/animation/reveal.cjs +1 -1
- package/dist/animation/reveal.cjs.map +1 -1
- package/dist/animation/reveal.js +29 -30
- package/dist/animation/transition.js +1 -2
- package/dist/animation/tween.js +1 -2
- package/dist/axes/axis.js +1 -2
- package/dist/axes/grid.js +1 -2
- package/dist/axes/scale-utils.js +1 -2
- package/dist/charts/area/area-chart.cjs +1 -1
- package/dist/charts/area/area-chart.cjs.map +1 -1
- package/dist/charts/area/area-chart.js +34 -35
- package/dist/charts/area/area-renderer.cjs +1 -1
- package/dist/charts/area/area-renderer.cjs.map +1 -1
- package/dist/charts/area/area-renderer.js +56 -57
- package/dist/charts/area/area-renderer.js.map +1 -1
- package/dist/charts/bar/bar-chart.cjs +1 -1
- package/dist/charts/bar/bar-chart.cjs.map +1 -1
- package/dist/charts/bar/bar-chart.js +80 -81
- package/dist/charts/bar/bar-chart.js.map +1 -1
- package/dist/charts/bar/bar-hit-test.js +1 -2
- package/dist/charts/bar/bar-renderer.cjs +1 -1
- package/dist/charts/bar/bar-renderer.cjs.map +1 -1
- package/dist/charts/bar/bar-renderer.js +42 -43
- package/dist/charts/bar/bar-value-labels.cjs +1 -1
- package/dist/charts/bar/bar-value-labels.cjs.map +1 -1
- package/dist/charts/bar/bar-value-labels.js +17 -18
- package/dist/charts/heatmap/heatmap-chart.cjs +1 -1
- package/dist/charts/heatmap/heatmap-chart.cjs.map +1 -1
- package/dist/charts/heatmap/heatmap-chart.js +43 -44
- package/dist/charts/heatmap/heatmap-color.js +1 -2
- package/dist/charts/line/line-chart.cjs +1 -1
- package/dist/charts/line/line-chart.cjs.map +1 -1
- package/dist/charts/line/line-chart.js +41 -42
- package/dist/charts/line/line-renderer.cjs +1 -1
- package/dist/charts/line/line-renderer.cjs.map +1 -1
- package/dist/charts/line/line-renderer.js +81 -82
- package/dist/charts/line/line-renderer.js.map +1 -1
- package/dist/charts/pie/pie-chart.cjs +1 -1
- package/dist/charts/pie/pie-chart.cjs.map +1 -1
- package/dist/charts/pie/pie-chart.js +69 -70
- package/dist/charts/pie/pie-renderer.js +1 -2
- package/dist/charts/radar/radar-chart.cjs +1 -1
- package/dist/charts/radar/radar-chart.cjs.map +1 -1
- package/dist/charts/radar/radar-chart.js +118 -119
- package/dist/charts/radar/radar-chart.js.map +1 -1
- package/dist/charts/radar/radar-geometry.cjs +1 -1
- package/dist/charts/radar/radar-geometry.cjs.map +1 -1
- package/dist/charts/radar/radar-geometry.js +15 -16
- package/dist/charts/scatter/scatter-chart.cjs +1 -1
- package/dist/charts/scatter/scatter-chart.cjs.map +1 -1
- package/dist/charts/scatter/scatter-chart.js +33 -34
- package/dist/charts/scatter/scatter-renderer.cjs +1 -1
- package/dist/charts/scatter/scatter-renderer.cjs.map +1 -1
- package/dist/charts/scatter/scatter-renderer.js +22 -23
- package/dist/charts/sparkline/sparkline.cjs +1 -1
- package/dist/charts/sparkline/sparkline.cjs.map +1 -1
- package/dist/charts/sparkline/sparkline.js +87 -88
- package/dist/charts/sparkline/sparkline.js.map +1 -1
- package/dist/core/cartesian-model.js +1 -2
- package/dist/core/cartesian-scales.js +1 -2
- package/dist/core/chart-base.cjs +1 -1
- package/dist/core/chart-base.cjs.map +1 -1
- package/dist/core/chart-base.js +13 -14
- package/dist/core/chart-scaffold.cjs +1 -1
- package/dist/core/chart-scaffold.cjs.map +1 -1
- package/dist/core/chart-scaffold.js +33 -34
- package/dist/core/datum-style.js +1 -2
- package/dist/core/ids.js +1 -2
- package/dist/core/layout.js +1 -2
- package/dist/core/polar.js +1 -2
- package/dist/core/responsive.js +1 -2
- package/dist/core/series-id.js +1 -2
- package/dist/errors.js +1 -2
- package/dist/index.cjs +1 -1
- package/dist/index.js +14 -14
- package/dist/interaction/announcer.js +1 -2
- package/dist/interaction/crosshair.js +1 -2
- package/dist/interaction/events.js +1 -2
- package/dist/interaction/legend.js +1 -2
- package/dist/interaction/scatter-interaction.cjs +1 -1
- package/dist/interaction/scatter-interaction.cjs.map +1 -1
- package/dist/interaction/scatter-interaction.js +26 -27
- package/dist/interaction/series-interaction.cjs +1 -1
- package/dist/interaction/series-interaction.cjs.map +1 -1
- package/dist/interaction/series-interaction.js +40 -41
- package/dist/interaction/tooltip.js +1 -2
- package/dist/prism.cjs +1 -1
- package/dist/prism.cjs.map +1 -1
- package/dist/prism.iife.js +1 -1
- package/dist/prism.iife.js.map +1 -1
- package/dist/prism.js +52 -103
- package/dist/prism.js.map +1 -1
- package/dist/scales/band.js +1 -2
- package/dist/scales/linear.js +1 -2
- package/dist/scales/time.js +1 -2
- package/dist/svg/element.js +1 -2
- package/dist/svg/path.js +1 -2
- package/dist/svg/text.js +1 -2
- package/dist/theme/index.js +1 -2
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"series-interaction.cjs","names":["keyId","createSvgElement","chartArea","describeValues","comparisonContent","getMousePosition","require_element","require_announcer","require_tooltip","require_layout","require_cartesian_model","require_events","key","nearest","minXDistance","seriesIndex","allPoints","datumIndex","datum","allData","point","distance","posX","keyboardIndex","active","target","event","opts","group","id","data","best","minDistance","entries","posY","index","colors","groups","emphasised","hit","originalEvent","seriesList","values","entry","i","found","pos","dims","area","raw","label","valueFormat","spoken","rows","series","rendered","points","a","b","keys","last","current","parent"],"sources":["../../src/interaction/series-interaction.ts"],"sourcesContent":["import { keyId } from '../core/cartesian-model';\nimport type { ChartEventHandlers } from '../core/chart-scaffold';\nimport { chartArea } from '../core/layout';\nimport { createSvgElement } from '../svg/element';\nimport type { Point } from '../svg/path';\nimport type { ChartDimensions, ChartEvent, ChartMargin, Datum, Series, SeriesValue, TooltipConfig } from '../types';\nimport { type Announcer, describeValues } from './announcer';\nimport type { CrosshairState } from './crosshair';\nimport { getMousePosition } from './events';\nimport { comparisonContent, type TooltipState } from './tooltip';\n\nexport interface SeriesInteractionOptions {\n announcer: Announcer;\n colors: () => string[];\n crosshair?: CrosshairState | null;\n dims: () => ChartDimensions;\n getData: () => Datum[][];\n getPoints: () => Point[][];\n getSeriesList: () => Series[];\n /** Effective chart margin (including any dual-axis widening): hit bounds and tooltip offsets use this, never the shared dimensions. */\n margin: ChartMargin;\n /** Receives one marker per series at the active key. */\n markers: SVGGElement;\n onClick?: ((event: ChartEvent) => void) | undefined;\n onHover?: ((event: ChartEvent | null) => void) | undefined;\n /** Parent of the per-series groups; the nearest series is emphasised and the rest dim. */\n seriesGroup: SVGGElement;\n svg: SVGSVGElement;\n tooltip?: TooltipState | null;\n /** Value/title formatters from the tooltip config, applied to rows and spoken text alike. */\n tooltipFormat?: Pick<TooltipConfig, 'titleFormat' | 'valueFormat'>;\n}\n\ninterface KeyEntry {\n datum: Datum | undefined;\n point: Point | undefined;\n}\n\nconst keyOrder = (key: Datum['key']): number => (key instanceof Date ? key.getTime() : Number(key));\n\nexport function keyLabel(key: Datum['key']): string {\n return key instanceof Date ? key.toLocaleDateString() : String(key);\n}\n\nfunction findNearestKey(allData: Datum[][], allPoints: Point[][], posX: number): Datum['key'] | null {\n let nearest: Datum['key'] | null = null;\n let minXDistance = Infinity;\n\n for (let seriesIndex = 0; seriesIndex < allPoints.length; seriesIndex++) {\n for (let datumIndex = 0; datumIndex < (allPoints[seriesIndex]?.length ?? 0); datumIndex++) {\n const datum = allData[seriesIndex]?.[datumIndex];\n const point = allPoints[seriesIndex]?.[datumIndex];\n\n if (!datum || !point) continue;\n\n const distance = Math.abs(point.x - posX);\n\n if (distance < minXDistance) {\n minXDistance = distance;\n nearest = datum.key;\n }\n }\n }\n\n return nearest;\n}\n\nexport function createSeriesInteraction(opts: SeriesInteractionOptions): ChartEventHandlers {\n let keyboardIndex = -1;\n let active = false;\n\n const renderedHit = (event: Event): { datum: Datum; point: Point; seriesIndex: number } | null => {\n const target = event.target;\n if (\n !(target instanceof SVGElement) ||\n target.tagName.toLowerCase() !== 'circle' ||\n !opts.seriesGroup.contains(target) ||\n !target.parentElement\n )\n return null;\n let group: Element | null = target.parentElement;\n while (group && group.parentNode !== opts.seriesGroup) group = group.parentElement;\n if (!group) return null;\n const seriesIndex = [...opts.seriesGroup.children].indexOf(group);\n const datumIndex = [...target.parentElement.children].indexOf(target);\n const datum = opts.getData()[seriesIndex]?.[datumIndex];\n const point = opts.getPoints()[seriesIndex]?.[datumIndex];\n return datum && point ? { datum, point, seriesIndex } : null;\n };\n\n const entriesAt = (key: Datum['key']): KeyEntry[] => {\n const id = keyId(key);\n const allPoints = opts.getPoints();\n\n return opts.getData().map((data, seriesIndex) => {\n const datumIndex = data.findIndex((datum) => keyId(datum.key) === id);\n\n return datumIndex === -1\n ? { datum: undefined, point: undefined }\n : { datum: data[datumIndex], point: allPoints[seriesIndex]?.[datumIndex] };\n });\n };\n\n const nearestIndex = (entries: KeyEntry[], posY: number): number => {\n let best = -1;\n let minDistance = Infinity;\n\n entries.forEach(({ point }, index) => {\n if (!point) return;\n\n const distance = Number.isFinite(posY) ? Math.abs(point.y - posY) : 0;\n\n if (distance < minDistance) {\n minDistance = distance;\n best = index;\n }\n });\n\n return best;\n };\n\n const highlight = (entries: KeyEntry[], emphasised: number): void => {\n const colors = opts.colors();\n\n opts.markers.replaceChildren();\n entries.forEach(({ point }, index) => {\n if (!point) return;\n\n opts.markers.appendChild(\n createSvgElement('circle', {\n class: 'prism-active-point',\n cx: point.x,\n cy: point.y,\n fill: colors[index],\n r: 4,\n }),\n );\n });\n\n const groups = [...opts.seriesGroup.children];\n\n opts.seriesGroup.classList.toggle('prism-series-focused', emphasised >= 0 && groups.length > 1);\n for (const [index, group] of groups.entries()) group.classList.toggle('prism-series-active', index === emphasised);\n };\n\n const clear = (): void => {\n opts.crosshair?.hide();\n opts.tooltip?.hide();\n opts.announcer.clear();\n highlight([], -1);\n active = false;\n opts.onHover?.(null);\n };\n\n const eventFor = (\n key: Datum['key'],\n posY: number,\n originalEvent: Event,\n ): { entries: KeyEntry[]; event: ChartEvent; index: number } | null => {\n const entries = entriesAt(key);\n const hit = renderedHit(originalEvent);\n const index = hit?.seriesIndex ?? nearestIndex(entries, posY);\n if (hit) entries[index] = { datum: hit.datum, point: hit.point };\n const seriesList = opts.getSeriesList();\n const datum = entries[index]?.datum;\n\n if (index < 0 || !datum) return null;\n\n const values: SeriesValue[] = entries.map((entry, i) => ({ datum: entry.datum, series: seriesList[i] }));\n\n return { entries, event: { datum, originalEvent, series: seriesList[index], values }, index };\n };\n\n const focus = (key: Datum['key'], pos: Point | null, originalEvent: Event): void => {\n const found = eventFor(key, pos?.y ?? Number.NaN, originalEvent);\n\n if (!found) return;\n\n const { entries, event, index } = found;\n const point = entries[index].point!;\n const dims = opts.dims();\n const area = chartArea(dims.width, dims.height, opts.margin);\n const raw = opts.crosshair?.snap === false && pos;\n const label = opts.tooltipFormat?.titleFormat ? opts.tooltipFormat.titleFormat(key) : keyLabel(key);\n const values = event.values ?? [];\n const colors = opts.colors();\n const valueFormat = opts.tooltipFormat?.valueFormat;\n\n opts.crosshair?.show(raw ? pos.x : point.x, raw ? pos.y : point.y, area.width, area.height);\n highlight(entries, index);\n\n const spoken = describeValues(label, values, valueFormat ?? String);\n\n if (opts.tooltip) {\n const rows = values.flatMap(({ datum, series }, i) =>\n datum\n ? [\n {\n color: colors[i],\n name: series.name,\n value: valueFormat ? valueFormat(datum.value, datum, series) : String(datum.value),\n },\n ]\n : [],\n );\n\n opts.tooltip.show(\n point.x + opts.margin.left,\n point.y + opts.margin.top,\n event.datum,\n event.series,\n comparisonContent(opts.svg.ownerDocument, label, rows, spoken),\n );\n } else {\n opts.announcer.announce(spoken);\n }\n\n active = true;\n opts.onHover?.(event);\n };\n\n const pointerKey = (event: MouseEvent): { key: Datum['key']; pos: Point } | null => {\n const rendered = renderedHit(event);\n if (rendered) return { key: rendered.datum.key, pos: rendered.point };\n const allPoints = opts.getPoints();\n\n if (allPoints.every((points) => points.length === 0)) return null;\n\n const dims = opts.dims();\n const pos = getMousePosition(opts.svg, event, opts.margin.left, opts.margin.top);\n const area = chartArea(dims.width, dims.height, opts.margin);\n\n if (pos.x < 0 || pos.x > area.width || pos.y < 0 || pos.y > area.height) return null;\n\n const key = findNearestKey(opts.getData(), allPoints, pos.x);\n\n return key === null ? null : { key, pos };\n };\n\n const sortedKeys = (): Datum['key'][] =>\n [\n ...new Map(\n opts\n .getData()\n .flat()\n .map((datum) => [keyId(datum.key), datum.key]),\n ).values(),\n ].sort((a, b) => keyOrder(a) - keyOrder(b));\n\n const onMouseMove = (event: MouseEvent): void => {\n const hit = pointerKey(event);\n\n if (hit) focus(hit.key, hit.pos, event);\n else if (active) clear();\n };\n\n const onClick = (event: MouseEvent): void => {\n if (!opts.onClick) return;\n\n const hit = pointerKey(event);\n const found = hit && eventFor(hit.key, hit.pos.y, event);\n\n if (found) opts.onClick(found.event);\n };\n\n const onKeyDown = (event: KeyboardEvent): void => {\n const keys = sortedKeys();\n\n if (keys.length === 0) return;\n\n const last = keys.length - 1;\n const target: Record<string, number> = {\n ArrowLeft: keyboardIndex < 0 ? last : Math.max(0, keyboardIndex - 1),\n ArrowRight: keyboardIndex < 0 ? 0 : Math.min(last, keyboardIndex + 1),\n End: last,\n Home: 0,\n };\n\n if (event.key in target) {\n event.preventDefault();\n keyboardIndex = target[event.key];\n focus(keys[keyboardIndex], null, event);\n } else if ((event.key === 'Enter' || event.key === ' ') && keyboardIndex >= 0 && opts.onClick) {\n event.preventDefault();\n\n const found = eventFor(keys[keyboardIndex], Number.NaN, event);\n\n if (found) opts.onClick(found.event);\n } else if (event.key === 'Escape') {\n keyboardIndex = -1;\n clear();\n }\n };\n\n return { onClick, onKeyDown, onMouseLeave: clear, onMouseMove };\n}\n\n/** Group for the per-series active markers, reused across renders. */\nexport function ensureMarkerGroup(parent: SVGGElement, current: SVGGElement | null): SVGGElement {\n if (current && parent.contains(current)) return current;\n\n const group = createSvgElement('g', {\n 'aria-hidden': 'true',\n class: 'prism-active-points',\n 'pointer-events': 'none',\n });\n\n parent.appendChild(group);\n\n return group;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"series-interaction.cjs","names":["keyId","createSvgElement","chartArea","describeValues","comparisonContent","getMousePosition","require_cartesian_model","require_layout","require_element","require_announcer","require_events","require_tooltip","key","nearest","minXDistance","seriesIndex","allPoints","datumIndex","datum","allData","point","distance","posX","keyboardIndex","active","target","event","opts","group","id","data","best","minDistance","entries","posY","index","colors","groups","emphasised","hit","originalEvent","seriesList","values","entry","i","found","pos","dims","area","raw","label","valueFormat","spoken","rows","series","rendered","points","a","b","keys","last","current","parent"],"sources":["../../src/interaction/series-interaction.ts"],"sourcesContent":["import { keyId } from '../core/cartesian-model';\nimport type { ChartEventHandlers } from '../core/chart-scaffold';\nimport { chartArea } from '../core/layout';\nimport { createSvgElement } from '../svg/element';\nimport type { Point } from '../svg/path';\nimport type { ChartDimensions, ChartEvent, ChartMargin, Datum, Series, SeriesValue, TooltipConfig } from '../types';\nimport { type Announcer, describeValues } from './announcer';\nimport type { CrosshairState } from './crosshair';\nimport { getMousePosition } from './events';\nimport { comparisonContent, type TooltipState } from './tooltip';\n\nexport interface SeriesInteractionOptions {\n announcer: Announcer;\n colors: () => string[];\n crosshair?: CrosshairState | null;\n dims: () => ChartDimensions;\n getData: () => Datum[][];\n getPoints: () => Point[][];\n getSeriesList: () => Series[];\n /** Effective chart margin (including any dual-axis widening): hit bounds and tooltip offsets use this, never the shared dimensions. */\n margin: ChartMargin;\n /** Receives one marker per series at the active key. */\n markers: SVGGElement;\n onClick?: ((event: ChartEvent) => void) | undefined;\n onHover?: ((event: ChartEvent | null) => void) | undefined;\n /** Parent of the per-series groups; the nearest series is emphasised and the rest dim. */\n seriesGroup: SVGGElement;\n svg: SVGSVGElement;\n tooltip?: TooltipState | null;\n /** Value/title formatters from the tooltip config, applied to rows and spoken text alike. */\n tooltipFormat?: Pick<TooltipConfig, 'titleFormat' | 'valueFormat'>;\n}\n\ninterface KeyEntry {\n datum: Datum | undefined;\n point: Point | undefined;\n}\n\nconst keyOrder = (key: Datum['key']): number => (key instanceof Date ? key.getTime() : Number(key));\n\nexport function keyLabel(key: Datum['key']): string {\n return key instanceof Date ? key.toLocaleDateString() : String(key);\n}\n\nfunction findNearestKey(allData: Datum[][], allPoints: Point[][], posX: number): Datum['key'] | null {\n let nearest: Datum['key'] | null = null;\n let minXDistance = Infinity;\n\n for (let seriesIndex = 0; seriesIndex < allPoints.length; seriesIndex++) {\n for (let datumIndex = 0; datumIndex < (allPoints[seriesIndex]?.length ?? 0); datumIndex++) {\n const datum = allData[seriesIndex]?.[datumIndex];\n const point = allPoints[seriesIndex]?.[datumIndex];\n\n if (!datum || !point) continue;\n\n const distance = Math.abs(point.x - posX);\n\n if (distance < minXDistance) {\n minXDistance = distance;\n nearest = datum.key;\n }\n }\n }\n\n return nearest;\n}\n\nexport function createSeriesInteraction(opts: SeriesInteractionOptions): ChartEventHandlers {\n let keyboardIndex = -1;\n let active = false;\n\n const renderedHit = (event: Event): { datum: Datum; point: Point; seriesIndex: number } | null => {\n const target = event.target;\n if (\n !(target instanceof SVGElement) ||\n target.tagName.toLowerCase() !== 'circle' ||\n !opts.seriesGroup.contains(target) ||\n !target.parentElement\n )\n return null;\n let group: Element | null = target.parentElement;\n while (group && group.parentNode !== opts.seriesGroup) group = group.parentElement;\n if (!group) return null;\n const seriesIndex = [...opts.seriesGroup.children].indexOf(group);\n const datumIndex = [...target.parentElement.children].indexOf(target);\n const datum = opts.getData()[seriesIndex]?.[datumIndex];\n const point = opts.getPoints()[seriesIndex]?.[datumIndex];\n return datum && point ? { datum, point, seriesIndex } : null;\n };\n\n const entriesAt = (key: Datum['key']): KeyEntry[] => {\n const id = keyId(key);\n const allPoints = opts.getPoints();\n\n return opts.getData().map((data, seriesIndex) => {\n const datumIndex = data.findIndex((datum) => keyId(datum.key) === id);\n\n return datumIndex === -1\n ? { datum: undefined, point: undefined }\n : { datum: data[datumIndex], point: allPoints[seriesIndex]?.[datumIndex] };\n });\n };\n\n const nearestIndex = (entries: KeyEntry[], posY: number): number => {\n let best = -1;\n let minDistance = Infinity;\n\n entries.forEach(({ point }, index) => {\n if (!point) return;\n\n const distance = Number.isFinite(posY) ? Math.abs(point.y - posY) : 0;\n\n if (distance < minDistance) {\n minDistance = distance;\n best = index;\n }\n });\n\n return best;\n };\n\n const highlight = (entries: KeyEntry[], emphasised: number): void => {\n const colors = opts.colors();\n\n opts.markers.replaceChildren();\n entries.forEach(({ point }, index) => {\n if (!point) return;\n\n opts.markers.appendChild(\n createSvgElement('circle', {\n class: 'prism-active-point',\n cx: point.x,\n cy: point.y,\n fill: colors[index],\n r: 4,\n }),\n );\n });\n\n const groups = [...opts.seriesGroup.children];\n\n opts.seriesGroup.classList.toggle('prism-series-focused', emphasised >= 0 && groups.length > 1);\n for (const [index, group] of groups.entries()) group.classList.toggle('prism-series-active', index === emphasised);\n };\n\n const clear = (): void => {\n opts.crosshair?.hide();\n opts.tooltip?.hide();\n opts.announcer.clear();\n highlight([], -1);\n active = false;\n opts.onHover?.(null);\n };\n\n const eventFor = (\n key: Datum['key'],\n posY: number,\n originalEvent: Event,\n ): { entries: KeyEntry[]; event: ChartEvent; index: number } | null => {\n const entries = entriesAt(key);\n const hit = renderedHit(originalEvent);\n const index = hit?.seriesIndex ?? nearestIndex(entries, posY);\n if (hit) entries[index] = { datum: hit.datum, point: hit.point };\n const seriesList = opts.getSeriesList();\n const datum = entries[index]?.datum;\n\n if (index < 0 || !datum) return null;\n\n const values: SeriesValue[] = entries.map((entry, i) => ({ datum: entry.datum, series: seriesList[i] }));\n\n return { entries, event: { datum, originalEvent, series: seriesList[index], values }, index };\n };\n\n const focus = (key: Datum['key'], pos: Point | null, originalEvent: Event): void => {\n const found = eventFor(key, pos?.y ?? Number.NaN, originalEvent);\n\n if (!found) return;\n\n const { entries, event, index } = found;\n const point = entries[index].point!;\n const dims = opts.dims();\n const area = chartArea(dims.width, dims.height, opts.margin);\n const raw = opts.crosshair?.snap === false && pos;\n const label = opts.tooltipFormat?.titleFormat ? opts.tooltipFormat.titleFormat(key) : keyLabel(key);\n const values = event.values ?? [];\n const colors = opts.colors();\n const valueFormat = opts.tooltipFormat?.valueFormat;\n\n opts.crosshair?.show(raw ? pos.x : point.x, raw ? pos.y : point.y, area.width, area.height);\n highlight(entries, index);\n\n const spoken = describeValues(label, values, valueFormat ?? String);\n\n if (opts.tooltip) {\n const rows = values.flatMap(({ datum, series }, i) =>\n datum\n ? [\n {\n color: colors[i],\n name: series.name,\n value: valueFormat ? valueFormat(datum.value, datum, series) : String(datum.value),\n },\n ]\n : [],\n );\n\n opts.tooltip.show(\n point.x + opts.margin.left,\n point.y + opts.margin.top,\n event.datum,\n event.series,\n comparisonContent(opts.svg.ownerDocument, label, rows, spoken),\n );\n } else {\n opts.announcer.announce(spoken);\n }\n\n active = true;\n opts.onHover?.(event);\n };\n\n const pointerKey = (event: MouseEvent): { key: Datum['key']; pos: Point } | null => {\n const rendered = renderedHit(event);\n if (rendered) return { key: rendered.datum.key, pos: rendered.point };\n const allPoints = opts.getPoints();\n\n if (allPoints.every((points) => points.length === 0)) return null;\n\n const dims = opts.dims();\n const pos = getMousePosition(opts.svg, event, opts.margin.left, opts.margin.top);\n const area = chartArea(dims.width, dims.height, opts.margin);\n\n if (pos.x < 0 || pos.x > area.width || pos.y < 0 || pos.y > area.height) return null;\n\n const key = findNearestKey(opts.getData(), allPoints, pos.x);\n\n return key === null ? null : { key, pos };\n };\n\n const sortedKeys = (): Datum['key'][] =>\n [\n ...new Map(\n opts\n .getData()\n .flat()\n .map((datum) => [keyId(datum.key), datum.key]),\n ).values(),\n ].sort((a, b) => keyOrder(a) - keyOrder(b));\n\n const onMouseMove = (event: MouseEvent): void => {\n const hit = pointerKey(event);\n\n if (hit) focus(hit.key, hit.pos, event);\n else if (active) clear();\n };\n\n const onClick = (event: MouseEvent): void => {\n if (!opts.onClick) return;\n\n const hit = pointerKey(event);\n const found = hit && eventFor(hit.key, hit.pos.y, event);\n\n if (found) opts.onClick(found.event);\n };\n\n const onKeyDown = (event: KeyboardEvent): void => {\n const keys = sortedKeys();\n\n if (keys.length === 0) return;\n\n const last = keys.length - 1;\n const target: Record<string, number> = {\n ArrowLeft: keyboardIndex < 0 ? last : Math.max(0, keyboardIndex - 1),\n ArrowRight: keyboardIndex < 0 ? 0 : Math.min(last, keyboardIndex + 1),\n End: last,\n Home: 0,\n };\n\n if (event.key in target) {\n event.preventDefault();\n keyboardIndex = target[event.key];\n focus(keys[keyboardIndex], null, event);\n } else if ((event.key === 'Enter' || event.key === ' ') && keyboardIndex >= 0 && opts.onClick) {\n event.preventDefault();\n\n const found = eventFor(keys[keyboardIndex], Number.NaN, event);\n\n if (found) opts.onClick(found.event);\n } else if (event.key === 'Escape') {\n keyboardIndex = -1;\n clear();\n }\n };\n\n return { onClick, onKeyDown, onMouseLeave: clear, onMouseMove };\n}\n\n/** Group for the per-series active markers, reused across renders. */\nexport function ensureMarkerGroup(parent: SVGGElement, current: SVGGElement | null): SVGGElement {\n if (current && parent.contains(current)) return current;\n\n const group = createSvgElement('g', {\n 'aria-hidden': 'true',\n class: 'prism-active-points',\n 'pointer-events': 'none',\n });\n\n parent.appendChild(group);\n\n return group;\n}\n"],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
1
|
+
import { keyId as e } from "../core/cartesian-model.js";
|
|
2
|
+
import { chartArea as t } from "../core/layout.js";
|
|
3
|
+
import { createSvgElement as n } from "../svg/element.js";
|
|
4
|
+
import { describeValues as r } from "./announcer.js";
|
|
5
|
+
import { getMousePosition as i } from "./events.js";
|
|
6
|
+
import { comparisonContent as a } from "./tooltip.js";
|
|
7
|
+
// src/interaction/series-interaction.ts
|
|
8
8
|
var keyOrder = (e) => e instanceof Date ? e.getTime() : Number(e);
|
|
9
9
|
function keyLabel(e) {
|
|
10
10
|
return e instanceof Date ? e.toLocaleDateString() : String(e);
|
|
@@ -32,16 +32,16 @@ function createSeriesInteraction(o) {
|
|
|
32
32
|
point: s,
|
|
33
33
|
seriesIndex: r
|
|
34
34
|
} : null;
|
|
35
|
-
}, entriesAt = (
|
|
36
|
-
let
|
|
37
|
-
return o.getData().map((
|
|
38
|
-
let a =
|
|
35
|
+
}, entriesAt = (t) => {
|
|
36
|
+
let n = e(t), r = o.getPoints();
|
|
37
|
+
return o.getData().map((t, i) => {
|
|
38
|
+
let a = t.findIndex((t) => e(t.key) === n);
|
|
39
39
|
return a === -1 ? {
|
|
40
40
|
datum: void 0,
|
|
41
41
|
point: void 0
|
|
42
42
|
} : {
|
|
43
|
-
datum:
|
|
44
|
-
point:
|
|
43
|
+
datum: t[a],
|
|
44
|
+
point: r[i]?.[a]
|
|
45
45
|
};
|
|
46
46
|
});
|
|
47
47
|
}, nearestIndex = (e, t) => {
|
|
@@ -51,20 +51,20 @@ function createSeriesInteraction(o) {
|
|
|
51
51
|
let a = Number.isFinite(t) ? Math.abs(e.y - t) : 0;
|
|
52
52
|
a < r && (r = a, n = i);
|
|
53
53
|
}), n;
|
|
54
|
-
}, highlight = (
|
|
54
|
+
}, highlight = (e, t) => {
|
|
55
55
|
let r = o.colors();
|
|
56
|
-
o.markers.replaceChildren(),
|
|
57
|
-
|
|
56
|
+
o.markers.replaceChildren(), e.forEach(({ point: e }, t) => {
|
|
57
|
+
e && o.markers.appendChild(n("circle", {
|
|
58
58
|
class: "prism-active-point",
|
|
59
|
-
cx:
|
|
60
|
-
cy:
|
|
61
|
-
fill: r[
|
|
59
|
+
cx: e.x,
|
|
60
|
+
cy: e.y,
|
|
61
|
+
fill: r[t],
|
|
62
62
|
r: 4
|
|
63
63
|
}));
|
|
64
64
|
});
|
|
65
65
|
let i = [...o.seriesGroup.children];
|
|
66
|
-
o.seriesGroup.classList.toggle("prism-series-focused",
|
|
67
|
-
for (let [e,
|
|
66
|
+
o.seriesGroup.classList.toggle("prism-series-focused", t >= 0 && i.length > 1);
|
|
67
|
+
for (let [e, n] of i.entries()) n.classList.toggle("prism-series-active", e === t);
|
|
68
68
|
}, clear = () => {
|
|
69
69
|
o.crosshair?.hide(), o.tooltip?.hide(), o.announcer.clear(), highlight([], -1), c = !1, o.onHover?.(null);
|
|
70
70
|
}, eventFor = (e, t, n) => {
|
|
@@ -89,37 +89,37 @@ function createSeriesInteraction(o) {
|
|
|
89
89
|
},
|
|
90
90
|
index: a
|
|
91
91
|
};
|
|
92
|
-
}, focus = (e,
|
|
93
|
-
let s = eventFor(e,
|
|
92
|
+
}, focus = (e, n, i) => {
|
|
93
|
+
let s = eventFor(e, n?.y ?? NaN, i);
|
|
94
94
|
if (!s) return;
|
|
95
|
-
let { entries: l, event: u, index: d } = s, f = l[d].point, p = o.dims(), m =
|
|
96
|
-
o.crosshair?.show(h ?
|
|
97
|
-
let b =
|
|
95
|
+
let { entries: l, event: u, index: d } = s, f = l[d].point, p = o.dims(), m = t(p.width, p.height, o.margin), h = o.crosshair?.snap === !1 && n, g = o.tooltipFormat?.titleFormat ? o.tooltipFormat.titleFormat(e) : keyLabel(e), _ = u.values ?? [], v = o.colors(), y = o.tooltipFormat?.valueFormat;
|
|
96
|
+
o.crosshair?.show(h ? n.x : f.x, h ? n.y : f.y, m.width, m.height), highlight(l, d);
|
|
97
|
+
let b = r(g, _, y ?? String);
|
|
98
98
|
if (o.tooltip) {
|
|
99
99
|
let e = _.flatMap(({ datum: e, series: t }, n) => e ? [{
|
|
100
100
|
color: v[n],
|
|
101
101
|
name: t.name,
|
|
102
102
|
value: y ? y(e.value, e, t) : String(e.value)
|
|
103
103
|
}] : []);
|
|
104
|
-
o.tooltip.show(f.x + o.margin.left, f.y + o.margin.top, u.datum, u.series,
|
|
104
|
+
o.tooltip.show(f.x + o.margin.left, f.y + o.margin.top, u.datum, u.series, a(o.svg.ownerDocument, g, e, b));
|
|
105
105
|
} else o.announcer.announce(b);
|
|
106
106
|
c = !0, o.onHover?.(u);
|
|
107
107
|
}, pointerKey = (e) => {
|
|
108
|
-
let
|
|
109
|
-
if (
|
|
110
|
-
key:
|
|
111
|
-
pos:
|
|
108
|
+
let n = renderedHit(e);
|
|
109
|
+
if (n) return {
|
|
110
|
+
key: n.datum.key,
|
|
111
|
+
pos: n.point
|
|
112
112
|
};
|
|
113
|
-
let
|
|
114
|
-
if (
|
|
115
|
-
let
|
|
113
|
+
let r = o.getPoints();
|
|
114
|
+
if (r.every((e) => e.length === 0)) return null;
|
|
115
|
+
let a = o.dims(), s = i(o.svg, e, o.margin.left, o.margin.top), c = t(a.width, a.height, o.margin);
|
|
116
116
|
if (s.x < 0 || s.x > c.width || s.y < 0 || s.y > c.height) return null;
|
|
117
|
-
let l = findNearestKey(o.getData(),
|
|
117
|
+
let l = findNearestKey(o.getData(), r, s.x);
|
|
118
118
|
return l === null ? null : {
|
|
119
119
|
key: l,
|
|
120
120
|
pos: s
|
|
121
121
|
};
|
|
122
|
-
}, sortedKeys = () => [...new Map(o.getData().flat().map((
|
|
122
|
+
}, sortedKeys = () => [...new Map(o.getData().flat().map((t) => [e(t.key), t.key])).values()].sort((e, t) => keyOrder(e) - keyOrder(t)), onMouseMove = (e) => {
|
|
123
123
|
let t = pointerKey(e);
|
|
124
124
|
t ? focus(t.key, t.pos, e) : c && clear();
|
|
125
125
|
}, onClick = (e) => {
|
|
@@ -149,16 +149,15 @@ function createSeriesInteraction(o) {
|
|
|
149
149
|
onMouseMove
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
|
-
function ensureMarkerGroup(
|
|
153
|
-
if (
|
|
154
|
-
let r =
|
|
152
|
+
function ensureMarkerGroup(e, t) {
|
|
153
|
+
if (t && e.contains(t)) return t;
|
|
154
|
+
let r = n("g", {
|
|
155
155
|
"aria-hidden": "true",
|
|
156
156
|
class: "prism-active-points",
|
|
157
157
|
"pointer-events": "none"
|
|
158
158
|
});
|
|
159
|
-
return
|
|
159
|
+
return e.appendChild(r), r;
|
|
160
160
|
}
|
|
161
|
-
//#endregion
|
|
162
161
|
export { createSeriesInteraction, ensureMarkerGroup, keyLabel };
|
|
163
162
|
|
|
164
163
|
//# sourceMappingURL=series-interaction.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computePosition as e, flip as t, getClippingAncestorRect as n, offset as r, shift as i } from "@vielzeug/orbit";
|
|
2
|
-
|
|
2
|
+
// src/interaction/tooltip.ts
|
|
3
3
|
var a = "position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap";
|
|
4
4
|
function shiftBoundary(e, t) {
|
|
5
5
|
let r = e.getBoundingClientRect(), i = {
|
|
@@ -82,7 +82,6 @@ function createTooltip(n, a) {
|
|
|
82
82
|
[Symbol.dispose]: disposeHandle
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
//#endregion
|
|
86
85
|
export { comparisonContent, createTooltip };
|
|
87
86
|
|
|
88
87
|
//# sourceMappingURL=tooltip.js.map
|