@voila.dev/chart 4.0.0
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 +85 -0
- package/dist/brush/brush-layer.d.ts +16 -0
- package/dist/brush/brush-layer.d.ts.map +1 -0
- package/dist/brush/brush-layer.js +137 -0
- package/dist/brush/brush-layer.js.map +7 -0
- package/dist/brush/index.d.ts +10 -0
- package/dist/brush/index.d.ts.map +1 -0
- package/dist/brush/index.js +8 -0
- package/dist/brush/index.js.map +7 -0
- package/dist/canvas/canvas-renderer.d.ts +11 -0
- package/dist/canvas/canvas-renderer.d.ts.map +1 -0
- package/dist/canvas/canvas-renderer.js +49 -0
- package/dist/canvas/canvas-renderer.js.map +7 -0
- package/dist/canvas/index.d.ts +2 -0
- package/dist/canvas/index.d.ts.map +1 -0
- package/dist/canvas/index.js +5 -0
- package/dist/canvas/index.js.map +7 -0
- package/dist/canvas/paint-scene.d.ts +4 -0
- package/dist/canvas/paint-scene.d.ts.map +1 -0
- package/dist/canvas/paint-scene.js +130 -0
- package/dist/canvas/paint-scene.js.map +7 -0
- package/dist/canvas/resolve-color.d.ts +18 -0
- package/dist/canvas/resolve-color.d.ts.map +1 -0
- package/dist/canvas/resolve-color.js +52 -0
- package/dist/canvas/resolve-color.js.map +7 -0
- package/dist/contour/density.d.ts +20 -0
- package/dist/contour/density.d.ts.map +1 -0
- package/dist/contour/density.js +59 -0
- package/dist/contour/density.js.map +7 -0
- package/dist/contour/index.d.ts +2 -0
- package/dist/contour/index.d.ts.map +1 -0
- package/dist/contour/index.js +5 -0
- package/dist/contour/index.js.map +7 -0
- package/dist/core/channel.d.ts +11 -0
- package/dist/core/channel.d.ts.map +1 -0
- package/dist/core/channel.js +44 -0
- package/dist/core/channel.js.map +7 -0
- package/dist/core/compile.d.ts +22 -0
- package/dist/core/compile.d.ts.map +1 -0
- package/dist/core/compile.js +295 -0
- package/dist/core/compile.js.map +7 -0
- package/dist/core/define-chart.d.ts +96 -0
- package/dist/core/define-chart.d.ts.map +1 -0
- package/dist/core/define-chart.js +7 -0
- package/dist/core/define-chart.js.map +7 -0
- package/dist/core/facet.d.ts +7 -0
- package/dist/core/facet.d.ts.map +1 -0
- package/dist/core/facet.js +134 -0
- package/dist/core/facet.js.map +7 -0
- package/dist/core/format.d.ts +37 -0
- package/dist/core/format.d.ts.map +1 -0
- package/dist/core/format.js +108 -0
- package/dist/core/format.js.map +7 -0
- package/dist/core/guides/axes.d.ts +25 -0
- package/dist/core/guides/axes.d.ts.map +1 -0
- package/dist/core/guides/axes.js +204 -0
- package/dist/core/guides/axes.js.map +7 -0
- package/dist/core/marks/area.d.ts +23 -0
- package/dist/core/marks/area.d.ts.map +1 -0
- package/dist/core/marks/area.js +187 -0
- package/dist/core/marks/area.js.map +7 -0
- package/dist/core/marks/bar.d.ts +26 -0
- package/dist/core/marks/bar.d.ts.map +1 -0
- package/dist/core/marks/bar.js +200 -0
- package/dist/core/marks/bar.js.map +7 -0
- package/dist/core/marks/cell.d.ts +16 -0
- package/dist/core/marks/cell.d.ts.map +1 -0
- package/dist/core/marks/cell.js +98 -0
- package/dist/core/marks/cell.js.map +7 -0
- package/dist/core/marks/dot.d.ts +17 -0
- package/dist/core/marks/dot.d.ts.map +1 -0
- package/dist/core/marks/dot.js +125 -0
- package/dist/core/marks/dot.js.map +7 -0
- package/dist/core/marks/funnel-layout.d.ts +37 -0
- package/dist/core/marks/funnel-layout.d.ts.map +1 -0
- package/dist/core/marks/funnel-layout.js +61 -0
- package/dist/core/marks/funnel-layout.js.map +7 -0
- package/dist/core/marks/funnel.d.ts +19 -0
- package/dist/core/marks/funnel.d.ts.map +1 -0
- package/dist/core/marks/funnel.js +143 -0
- package/dist/core/marks/funnel.js.map +7 -0
- package/dist/core/marks/line.d.ts +17 -0
- package/dist/core/marks/line.d.ts.map +1 -0
- package/dist/core/marks/line.js +150 -0
- package/dist/core/marks/line.js.map +7 -0
- package/dist/core/marks/polar.d.ts +61 -0
- package/dist/core/marks/polar.d.ts.map +1 -0
- package/dist/core/marks/polar.js +436 -0
- package/dist/core/marks/polar.js.map +7 -0
- package/dist/core/marks/rect.d.ts +22 -0
- package/dist/core/marks/rect.d.ts.map +1 -0
- package/dist/core/marks/rect.js +119 -0
- package/dist/core/marks/rect.js.map +7 -0
- package/dist/core/marks/rule.d.ts +17 -0
- package/dist/core/marks/rule.d.ts.map +1 -0
- package/dist/core/marks/rule.js +73 -0
- package/dist/core/marks/rule.js.map +7 -0
- package/dist/core/marks/shared.d.ts +41 -0
- package/dist/core/marks/shared.d.ts.map +1 -0
- package/dist/core/marks/shared.js +74 -0
- package/dist/core/marks/shared.js.map +7 -0
- package/dist/core/marks/stack.d.ts +13 -0
- package/dist/core/marks/stack.d.ts.map +1 -0
- package/dist/core/marks/stack.js +28 -0
- package/dist/core/marks/stack.js.map +7 -0
- package/dist/core/marks/stats/difference.d.ts +20 -0
- package/dist/core/marks/stats/difference.d.ts.map +1 -0
- package/dist/core/marks/stats/difference.js +168 -0
- package/dist/core/marks/stats/difference.js.map +7 -0
- package/dist/core/marks/stats/distribution.d.ts +41 -0
- package/dist/core/marks/stats/distribution.d.ts.map +1 -0
- package/dist/core/marks/stats/distribution.js +354 -0
- package/dist/core/marks/stats/distribution.js.map +7 -0
- package/dist/core/marks/stats/dodge.d.ts +16 -0
- package/dist/core/marks/stats/dodge.d.ts.map +1 -0
- package/dist/core/marks/stats/dodge.js +104 -0
- package/dist/core/marks/stats/dodge.js.map +7 -0
- package/dist/core/marks/stats/hexbin.d.ts +26 -0
- package/dist/core/marks/stats/hexbin.d.ts.map +1 -0
- package/dist/core/marks/stats/hexbin.js +113 -0
- package/dist/core/marks/stats/hexbin.js.map +7 -0
- package/dist/core/marks/stats/histogram.d.ts +27 -0
- package/dist/core/marks/stats/histogram.d.ts.map +1 -0
- package/dist/core/marks/stats/histogram.js +70 -0
- package/dist/core/marks/stats/histogram.js.map +7 -0
- package/dist/core/marks/stats/regression.d.ts +13 -0
- package/dist/core/marks/stats/regression.d.ts.map +1 -0
- package/dist/core/marks/stats/regression.js +80 -0
- package/dist/core/marks/stats/regression.js.map +7 -0
- package/dist/core/marks/stats/statistics.d.ts +34 -0
- package/dist/core/marks/stats/statistics.d.ts.map +1 -0
- package/dist/core/marks/stats/statistics.js +111 -0
- package/dist/core/marks/stats/statistics.js.map +7 -0
- package/dist/core/marks/stats/waffle.d.ts +18 -0
- package/dist/core/marks/stats/waffle.d.ts.map +1 -0
- package/dist/core/marks/stats/waffle.js +117 -0
- package/dist/core/marks/stats/waffle.js.map +7 -0
- package/dist/core/marks/text.d.ts +19 -0
- package/dist/core/marks/text.d.ts.map +1 -0
- package/dist/core/marks/text.js +60 -0
- package/dist/core/marks/text.js.map +7 -0
- package/dist/core/motion/tween.d.ts +6 -0
- package/dist/core/motion/tween.d.ts.map +1 -0
- package/dist/core/motion/tween.js +98 -0
- package/dist/core/motion/tween.js.map +7 -0
- package/dist/core/nearest.d.ts +25 -0
- package/dist/core/nearest.d.ts.map +1 -0
- package/dist/core/nearest.js +151 -0
- package/dist/core/nearest.js.map +7 -0
- package/dist/core/paths.d.ts +65 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +192 -0
- package/dist/core/paths.js.map +7 -0
- package/dist/core/scales/color.d.ts +11 -0
- package/dist/core/scales/color.d.ts.map +1 -0
- package/dist/core/scales/color.js +35 -0
- package/dist/core/scales/color.js.map +7 -0
- package/dist/core/scales/continuous.d.ts +18 -0
- package/dist/core/scales/continuous.d.ts.map +1 -0
- package/dist/core/scales/continuous.js +82 -0
- package/dist/core/scales/continuous.js.map +7 -0
- package/dist/core/scales/discrete.d.ts +22 -0
- package/dist/core/scales/discrete.d.ts.map +1 -0
- package/dist/core/scales/discrete.js +103 -0
- package/dist/core/scales/discrete.js.map +7 -0
- package/dist/core/scales/resolve.d.ts +18 -0
- package/dist/core/scales/resolve.d.ts.map +1 -0
- package/dist/core/scales/resolve.js +112 -0
- package/dist/core/scales/resolve.js.map +7 -0
- package/dist/core/scales/time.d.ts +4 -0
- package/dist/core/scales/time.d.ts.map +1 -0
- package/dist/core/scales/time.js +140 -0
- package/dist/core/scales/time.js.map +7 -0
- package/dist/core/text.d.ts +3 -0
- package/dist/core/text.d.ts.map +1 -0
- package/dist/core/text.js +29 -0
- package/dist/core/text.js.map +7 -0
- package/dist/core/theme.d.ts +8 -0
- package/dist/core/theme.d.ts.map +1 -0
- package/dist/core/theme.js +21 -0
- package/dist/core/theme.js.map +7 -0
- package/dist/core/ticks.d.ts +27 -0
- package/dist/core/ticks.d.ts.map +1 -0
- package/dist/core/ticks.js +76 -0
- package/dist/core/ticks.js.map +7 -0
- package/dist/core/types.d.ts +305 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +1 -0
- package/dist/core/types.js.map +7 -0
- package/dist/force/force.d.ts +30 -0
- package/dist/force/force.d.ts.map +1 -0
- package/dist/force/force.js +143 -0
- package/dist/force/force.js.map +7 -0
- package/dist/force/index.d.ts +2 -0
- package/dist/force/index.d.ts.map +1 -0
- package/dist/force/index.js +7 -0
- package/dist/force/index.js.map +7 -0
- package/dist/geo/geo.d.ts +59 -0
- package/dist/geo/geo.d.ts.map +1 -0
- package/dist/geo/geo.js +231 -0
- package/dist/geo/geo.js.map +7 -0
- package/dist/geo/index.d.ts +2 -0
- package/dist/geo/index.d.ts.map +1 -0
- package/dist/geo/index.js +13 -0
- package/dist/geo/index.js.map +7 -0
- package/dist/hierarchy/hierarchy.d.ts +24 -0
- package/dist/hierarchy/hierarchy.d.ts.map +1 -0
- package/dist/hierarchy/hierarchy.js +279 -0
- package/dist/hierarchy/hierarchy.js.map +7 -0
- package/dist/hierarchy/index.d.ts +2 -0
- package/dist/hierarchy/index.d.ts.map +1 -0
- package/dist/hierarchy/index.js +11 -0
- package/dist/hierarchy/index.js.map +7 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +96 -0
- package/dist/index.js.map +7 -0
- package/dist/react/brush-contract.d.ts +23 -0
- package/dist/react/brush-contract.d.ts.map +1 -0
- package/dist/react/brush-contract.js +7 -0
- package/dist/react/brush-contract.js.map +7 -0
- package/dist/react/chart-data-table.d.ts +18 -0
- package/dist/react/chart-data-table.d.ts.map +1 -0
- package/dist/react/chart-data-table.js +55 -0
- package/dist/react/chart-data-table.js.map +7 -0
- package/dist/react/chart-legend.d.ts +17 -0
- package/dist/react/chart-legend.d.ts.map +1 -0
- package/dist/react/chart-legend.js +126 -0
- package/dist/react/chart-legend.js.map +7 -0
- package/dist/react/chart-tooltip.d.ts +18 -0
- package/dist/react/chart-tooltip.d.ts.map +1 -0
- package/dist/react/chart-tooltip.js +95 -0
- package/dist/react/chart-tooltip.js.map +7 -0
- package/dist/react/chart.d.ts +45 -0
- package/dist/react/chart.d.ts.map +1 -0
- package/dist/react/chart.js +383 -0
- package/dist/react/chart.js.map +7 -0
- package/dist/react/focus-overlay.d.ts +14 -0
- package/dist/react/focus-overlay.d.ts.map +1 -0
- package/dist/react/focus-overlay.js +147 -0
- package/dist/react/focus-overlay.js.map +7 -0
- package/dist/react/index.d.ts +7 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +11 -0
- package/dist/react/index.js.map +7 -0
- package/dist/react/messages.d.ts +16 -0
- package/dist/react/messages.d.ts.map +1 -0
- package/dist/react/messages.js +33 -0
- package/dist/react/messages.js.map +7 -0
- package/dist/react/renderer.d.ts +14 -0
- package/dist/react/renderer.d.ts.map +1 -0
- package/dist/react/renderer.js +1 -0
- package/dist/react/renderer.js.map +7 -0
- package/dist/react/sr-only.d.ts +4 -0
- package/dist/react/sr-only.d.ts.map +1 -0
- package/dist/react/sr-only.js +15 -0
- package/dist/react/sr-only.js.map +7 -0
- package/dist/react/svg-renderer.d.ts +4 -0
- package/dist/react/svg-renderer.d.ts.map +1 -0
- package/dist/react/svg-renderer.js +20 -0
- package/dist/react/svg-renderer.js.map +7 -0
- package/dist/react/svg-scene.d.ts +8 -0
- package/dist/react/svg-scene.d.ts.map +1 -0
- package/dist/react/svg-scene.js +121 -0
- package/dist/react/svg-scene.js.map +7 -0
- package/dist/react/use-animated-scene.d.ts +10 -0
- package/dist/react/use-animated-scene.d.ts.map +1 -0
- package/dist/react/use-animated-scene.js +41 -0
- package/dist/react/use-animated-scene.js.map +7 -0
- package/dist/react/use-chart-focus.d.ts +29 -0
- package/dist/react/use-chart-focus.d.ts.map +1 -0
- package/dist/react/use-chart-focus.js +180 -0
- package/dist/react/use-chart-focus.js.map +7 -0
- package/dist/react/use-chart-width.d.ts +12 -0
- package/dist/react/use-chart-width.d.ts.map +1 -0
- package/dist/react/use-chart-width.js +23 -0
- package/dist/react/use-chart-width.js.map +7 -0
- package/dist/react/use-chart-zoom.d.ts +13 -0
- package/dist/react/use-chart-zoom.d.ts.map +1 -0
- package/dist/react/use-chart-zoom.js +52 -0
- package/dist/react/use-chart-zoom.js.map +7 -0
- package/dist/react/use-text-measurer.d.ts +8 -0
- package/dist/react/use-text-measurer.d.ts.map +1 -0
- package/dist/react/use-text-measurer.js +44 -0
- package/dist/react/use-text-measurer.js.map +7 -0
- package/dist/sankey/index.d.ts +2 -0
- package/dist/sankey/index.d.ts.map +1 -0
- package/dist/sankey/index.js +7 -0
- package/dist/sankey/index.js.map +7 -0
- package/dist/sankey/sankey.d.ts +29 -0
- package/dist/sankey/sankey.d.ts.map +1 -0
- package/dist/sankey/sankey.js +127 -0
- package/dist/sankey/sankey.js.map +7 -0
- package/dist/voronoi/index.d.ts +2 -0
- package/dist/voronoi/index.d.ts.map +1 -0
- package/dist/voronoi/index.js +5 -0
- package/dist/voronoi/index.js.map +7 -0
- package/dist/voronoi/voronoi.d.ts +16 -0
- package/dist/voronoi/voronoi.d.ts.map +1 -0
- package/dist/voronoi/voronoi.js +62 -0
- package/dist/voronoi/voronoi.js.map +7 -0
- package/package.json +74 -0
- package/src/brush/brush-layer.tsx +174 -0
- package/src/brush/index.ts +14 -0
- package/src/canvas/canvas-renderer.tsx +56 -0
- package/src/canvas/index.ts +1 -0
- package/src/canvas/paint-scene.ts +152 -0
- package/src/canvas/resolve-color.ts +65 -0
- package/src/contour/density.ts +90 -0
- package/src/contour/index.ts +1 -0
- package/src/core/channel.ts +53 -0
- package/src/core/compile.ts +436 -0
- package/src/core/define-chart.ts +128 -0
- package/src/core/facet.ts +189 -0
- package/src/core/format.ts +163 -0
- package/src/core/guides/axes.ts +283 -0
- package/src/core/marks/area.ts +238 -0
- package/src/core/marks/bar.ts +278 -0
- package/src/core/marks/cell.ts +123 -0
- package/src/core/marks/dot.ts +157 -0
- package/src/core/marks/funnel-layout.ts +113 -0
- package/src/core/marks/funnel.ts +172 -0
- package/src/core/marks/line.ts +206 -0
- package/src/core/marks/polar.ts +568 -0
- package/src/core/marks/rect.ts +156 -0
- package/src/core/marks/rule.ts +104 -0
- package/src/core/marks/shared.ts +134 -0
- package/src/core/marks/stack.ts +42 -0
- package/src/core/marks/stats/difference.ts +205 -0
- package/src/core/marks/stats/distribution.ts +425 -0
- package/src/core/marks/stats/dodge.ts +136 -0
- package/src/core/marks/stats/hexbin.ts +152 -0
- package/src/core/marks/stats/histogram.ts +108 -0
- package/src/core/marks/stats/regression.ts +108 -0
- package/src/core/marks/stats/statistics.ts +153 -0
- package/src/core/marks/stats/waffle.ts +141 -0
- package/src/core/marks/text.ts +97 -0
- package/src/core/motion/tween.ts +131 -0
- package/src/core/nearest.ts +223 -0
- package/src/core/paths.ts +323 -0
- package/src/core/scales/color.ts +51 -0
- package/src/core/scales/continuous.ts +111 -0
- package/src/core/scales/discrete.ts +156 -0
- package/src/core/scales/resolve.ts +158 -0
- package/src/core/scales/time.ts +180 -0
- package/src/core/text.ts +42 -0
- package/src/core/theme.ts +26 -0
- package/src/core/ticks.ts +118 -0
- package/src/core/types.ts +358 -0
- package/src/force/force.ts +200 -0
- package/src/force/index.ts +6 -0
- package/src/geo/geo.ts +346 -0
- package/src/geo/index.ts +10 -0
- package/src/hierarchy/hierarchy.ts +377 -0
- package/src/hierarchy/index.ts +6 -0
- package/src/index.ts +70 -0
- package/src/react/brush-contract.ts +35 -0
- package/src/react/chart-data-table.tsx +98 -0
- package/src/react/chart-legend.tsx +130 -0
- package/src/react/chart-tooltip.tsx +111 -0
- package/src/react/chart.tsx +489 -0
- package/src/react/focus-overlay.tsx +164 -0
- package/src/react/index.ts +9 -0
- package/src/react/messages.ts +49 -0
- package/src/react/renderer.ts +15 -0
- package/src/react/sr-only.ts +14 -0
- package/src/react/svg-renderer.tsx +18 -0
- package/src/react/svg-scene.tsx +146 -0
- package/src/react/use-animated-scene.ts +57 -0
- package/src/react/use-chart-focus.ts +245 -0
- package/src/react/use-chart-width.ts +27 -0
- package/src/react/use-chart-zoom.ts +67 -0
- package/src/react/use-text-measurer.ts +49 -0
- package/src/sankey/index.ts +6 -0
- package/src/sankey/sankey.ts +179 -0
- package/src/voronoi/index.ts +1 -0
- package/src/voronoi/voronoi.ts +84 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { ChartDefinition } from "../core/define-chart.js";
|
|
3
|
+
import type { ChartPoint } from "../core/types.js";
|
|
4
|
+
import { type ChartBrush } from "./brush-contract.js";
|
|
5
|
+
import { type ChartTooltipRenderProps } from "./chart-tooltip.js";
|
|
6
|
+
import type { ChartRenderer } from "./renderer.js";
|
|
7
|
+
interface Props extends Omit<React.ComponentProps<"div">, "children" | "onSelect" | "title"> {
|
|
8
|
+
readonly definition: ChartDefinition;
|
|
9
|
+
/** What the chart shows, in a sentence: the screen reader's name for it. Required. */
|
|
10
|
+
readonly ariaLabel: string;
|
|
11
|
+
/** The takeaway, when the label alone does not carry it. */
|
|
12
|
+
readonly ariaDescription?: string;
|
|
13
|
+
/** Pixels. Ignored when `aspectRatio` is set. */
|
|
14
|
+
readonly height?: number;
|
|
15
|
+
/** Height as a share of the width: `0.5` is twice as wide as tall. */
|
|
16
|
+
readonly aspectRatio?: number;
|
|
17
|
+
/** Width used on the server and for the first client render, before the container is measured. */
|
|
18
|
+
readonly initialWidth?: number;
|
|
19
|
+
readonly renderer?: ChartRenderer;
|
|
20
|
+
/** `false` turns the tooltip off; a function replaces its content. */
|
|
21
|
+
readonly tooltip?: boolean | ((props: ChartTooltipRenderProps) => React.ReactNode);
|
|
22
|
+
/** Shown by default when there is more than one series. */
|
|
23
|
+
readonly legend?: boolean;
|
|
24
|
+
/** The visually hidden table of the values. On by default; turn it off only when the page shows the same table. */
|
|
25
|
+
readonly dataTable?: boolean;
|
|
26
|
+
/** Tween a data update, in milliseconds; `false` snaps. Reduced motion always snaps. */
|
|
27
|
+
readonly animate?: boolean | number;
|
|
28
|
+
/**
|
|
29
|
+
* Zoom a continuous x: the wheel while the chart has focus, + and −,
|
|
30
|
+
* Shift and the arrows to pan, a drag to pan when zoomed, 0 to reset.
|
|
31
|
+
*/
|
|
32
|
+
readonly zoom?: boolean;
|
|
33
|
+
/** Select a range of x by dragging or from the keyboard: `brushX({ onBrush })` from `@voila.dev/chart/brush`. */
|
|
34
|
+
readonly brush?: ChartBrush;
|
|
35
|
+
readonly onFocusChange?: (point: ChartPoint | null) => void;
|
|
36
|
+
readonly onSelect?: (point: ChartPoint | null) => void;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Draws a definition. Everything a reader needs beyond the picture comes with
|
|
40
|
+
* it: keyboard focus on every value, a live region that reads the focused
|
|
41
|
+
* value, a legend that toggles series, and the values as a hidden table.
|
|
42
|
+
*/
|
|
43
|
+
export declare function Chart({ definition, ariaLabel, ariaDescription, height, aspectRatio, initialWidth, renderer: Renderer, tooltip, legend, dataTable, animate, zoom, brush: brushBehavior, onFocusChange, onSelect, style, ...props }: Props): React.JSX.Element;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=chart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../../src/react/chart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EACN,KAAK,UAAU,EAGf,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAGN,KAAK,uBAAuB,EAC5B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA6BzD,UAAU,KACT,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;IAC5E,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,sFAAsF;IACtF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,iDAAiD;IACjD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,sEAAsE;IACtE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,kGAAkG;IAClG,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC;IAClC,sEAAsE;IACtE,QAAQ,CAAC,OAAO,CAAC,EACd,OAAO,GACP,CAAC,CAAC,KAAK,EAAE,uBAAuB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IACzD,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,mHAAmH;IACnH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,wFAAwF;IACxF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,iHAAiH;IACjH,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5D,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;CACvD;AAOD;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,EACrB,UAAU,EACV,SAAS,EACT,eAAe,EACf,MAAuB,EACvB,WAAW,EACX,YAAoC,EACpC,QAAQ,EAAE,QAAsB,EAChC,OAAc,EACd,MAAM,EACN,SAAgB,EAChB,OAAc,EACd,IAAY,EACZ,KAAK,EAAE,aAAa,EACpB,aAAa,EACb,QAAQ,EACR,KAAK,EACL,GAAG,KAAK,EACR,EAAE,KAAK,qBAwXP"}
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { compileChart } from "../core/compile.js";
|
|
4
|
+
import { findNearest, focusStops } from "../core/nearest.js";
|
|
5
|
+
import { toNumber } from "../core/scales/continuous.js";
|
|
6
|
+
import {
|
|
7
|
+
ordered
|
|
8
|
+
} from "./brush-contract.js";
|
|
9
|
+
import { ChartDataTable } from "./chart-data-table.js";
|
|
10
|
+
import { ChartColorRamp, ChartLegend } from "./chart-legend.js";
|
|
11
|
+
import {
|
|
12
|
+
ChartTooltip,
|
|
13
|
+
ChartTooltipContent
|
|
14
|
+
} from "./chart-tooltip.js";
|
|
15
|
+
import { FocusOverlay } from "./focus-overlay.js";
|
|
16
|
+
import { messagesFor } from "./messages.js";
|
|
17
|
+
import { SR_ONLY } from "./sr-only.js";
|
|
18
|
+
import { SvgRenderer } from "./svg-renderer.js";
|
|
19
|
+
import { useAnimatedScene } from "./use-animated-scene.js";
|
|
20
|
+
import { useChartFocus } from "./use-chart-focus.js";
|
|
21
|
+
import { useChartWidth } from "./use-chart-width.js";
|
|
22
|
+
import { useChartZoom } from "./use-chart-zoom.js";
|
|
23
|
+
import { useTextMeasurer } from "./use-text-measurer.js";
|
|
24
|
+
const DEFAULT_HEIGHT = 300;
|
|
25
|
+
const DEFAULT_INITIAL_WIDTH = 640;
|
|
26
|
+
const DEFAULT_DURATION = 300;
|
|
27
|
+
const CHART_CSS = `
|
|
28
|
+
[data-slot="chart-surface"]:focus-visible{outline:2px solid var(--ring,Highlight);outline-offset:2px;border-radius:4px}
|
|
29
|
+
@media (forced-colors:active){
|
|
30
|
+
[data-slot="chart-svg"] [data-role="axis"],[data-slot="chart-svg"] [data-role="axis-title"]{fill:CanvasText}
|
|
31
|
+
[data-slot="chart-svg"] [data-role="grid"]{stroke:GrayText}
|
|
32
|
+
[data-slot="chart-focus-ring"]{stroke:Highlight}
|
|
33
|
+
[data-slot="chart-tooltip"]{border-color:CanvasText}
|
|
34
|
+
}
|
|
35
|
+
@media (prefers-reduced-motion:no-preference){
|
|
36
|
+
[data-slot="chart-tooltip"]{transition:transform 80ms ease-out}
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
const DRAG_THRESHOLD = 3;
|
|
40
|
+
const ZOOM_STEP = 0.8;
|
|
41
|
+
const PAN_SHARE = 0.1;
|
|
42
|
+
function Chart({
|
|
43
|
+
definition,
|
|
44
|
+
ariaLabel,
|
|
45
|
+
ariaDescription,
|
|
46
|
+
height = DEFAULT_HEIGHT,
|
|
47
|
+
aspectRatio,
|
|
48
|
+
initialWidth = DEFAULT_INITIAL_WIDTH,
|
|
49
|
+
renderer: Renderer = SvgRenderer,
|
|
50
|
+
tooltip = true,
|
|
51
|
+
legend,
|
|
52
|
+
dataTable = true,
|
|
53
|
+
animate = true,
|
|
54
|
+
zoom = false,
|
|
55
|
+
brush: brushBehavior,
|
|
56
|
+
onFocusChange,
|
|
57
|
+
onSelect,
|
|
58
|
+
style,
|
|
59
|
+
...props
|
|
60
|
+
}) {
|
|
61
|
+
const chartId = React.useId().replaceAll(":", "");
|
|
62
|
+
const { ref, width, node } = useChartWidth(initialWidth);
|
|
63
|
+
const measureText = useTextMeasurer(node);
|
|
64
|
+
const [hidden, setHidden] = React.useState(
|
|
65
|
+
() => /* @__PURE__ */ new Set()
|
|
66
|
+
);
|
|
67
|
+
const chartHeight = aspectRatio === void 0 ? height : Math.round(width * aspectRatio);
|
|
68
|
+
const baseScene = React.useMemo(
|
|
69
|
+
() => compileChart(definition, {
|
|
70
|
+
width,
|
|
71
|
+
height: chartHeight,
|
|
72
|
+
measureText,
|
|
73
|
+
hiddenSeries: hidden
|
|
74
|
+
}),
|
|
75
|
+
[definition, width, chartHeight, measureText, hidden]
|
|
76
|
+
);
|
|
77
|
+
const baseX = baseScene.scales.x;
|
|
78
|
+
const fullX = React.useMemo(
|
|
79
|
+
() => baseX && baseX.kind !== "band" && baseX.kind !== "point" ? [toNumber(baseX.domain[0]), toNumber(baseX.domain[1])] : void 0,
|
|
80
|
+
[baseX]
|
|
81
|
+
);
|
|
82
|
+
const viewport = useChartZoom(zoom ? fullX : void 0, definition);
|
|
83
|
+
const scene = React.useMemo(
|
|
84
|
+
() => viewport.domain === null ? baseScene : compileChart(definition, {
|
|
85
|
+
width,
|
|
86
|
+
height: chartHeight,
|
|
87
|
+
measureText,
|
|
88
|
+
hiddenSeries: hidden,
|
|
89
|
+
xDomain: viewport.domain
|
|
90
|
+
}),
|
|
91
|
+
[
|
|
92
|
+
baseScene,
|
|
93
|
+
viewport.domain,
|
|
94
|
+
definition,
|
|
95
|
+
width,
|
|
96
|
+
chartHeight,
|
|
97
|
+
measureText,
|
|
98
|
+
hidden
|
|
99
|
+
]
|
|
100
|
+
);
|
|
101
|
+
const [brush, setBrush] = React.useState(null);
|
|
102
|
+
const [zoomAnnouncement, setZoomAnnouncement] = React.useState("");
|
|
103
|
+
const drag = React.useRef(null);
|
|
104
|
+
const stops = React.useMemo(() => focusStops(scene), [scene]);
|
|
105
|
+
const animationTrigger = React.useMemo(
|
|
106
|
+
() => [definition, hidden],
|
|
107
|
+
[definition, hidden]
|
|
108
|
+
);
|
|
109
|
+
const shown = useAnimatedScene(
|
|
110
|
+
scene,
|
|
111
|
+
animationTrigger,
|
|
112
|
+
animate === false ? 0 : animate === true ? DEFAULT_DURATION : animate
|
|
113
|
+
);
|
|
114
|
+
const messages = messagesFor(scene.locale);
|
|
115
|
+
const { active, handlers } = useChartFocus({
|
|
116
|
+
stops,
|
|
117
|
+
order: scene.focusOrder,
|
|
118
|
+
hitTest: (x, y) => findNearest(scene, stops, x, y),
|
|
119
|
+
onFocusChange,
|
|
120
|
+
onSelect
|
|
121
|
+
});
|
|
122
|
+
const xScale = scene.scales.x;
|
|
123
|
+
const xContinuous = xScale !== void 0 && xScale.kind !== "band" && xScale.kind !== "point";
|
|
124
|
+
function updateBrush(range) {
|
|
125
|
+
setBrush(range);
|
|
126
|
+
brushBehavior?.onBrush(range);
|
|
127
|
+
}
|
|
128
|
+
function localX(event) {
|
|
129
|
+
return event.clientX - event.currentTarget.getBoundingClientRect().left;
|
|
130
|
+
}
|
|
131
|
+
function onPointerDown(event) {
|
|
132
|
+
if (!brushBehavior && !(zoom && viewport.domain !== null)) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
136
|
+
handlers.onPointerLeave();
|
|
137
|
+
drag.current = {
|
|
138
|
+
startX: localX(event),
|
|
139
|
+
domain: viewport.domain,
|
|
140
|
+
moved: false
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function onPointerMove(event) {
|
|
144
|
+
const current = drag.current;
|
|
145
|
+
if (current === null || xScale === void 0) {
|
|
146
|
+
handlers.onPointerMove(event);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const x = localX(event);
|
|
150
|
+
if (Math.abs(x - current.startX) > DRAG_THRESHOLD) {
|
|
151
|
+
current.moved = true;
|
|
152
|
+
}
|
|
153
|
+
if (!current.moved) return;
|
|
154
|
+
if (brushBehavior) {
|
|
155
|
+
updateBrush(
|
|
156
|
+
ordered(xScale, [xScale.invert(current.startX), xScale.invert(x)])
|
|
157
|
+
);
|
|
158
|
+
} else if (current.domain !== null) {
|
|
159
|
+
const [from, to] = current.domain;
|
|
160
|
+
const perPixel = (to - from) / Math.max(1, scene.plot.width);
|
|
161
|
+
viewport.pan(
|
|
162
|
+
(current.startX - x) * perPixel - ((viewport.domain?.[0] ?? from) - from)
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function onPointerUp(event) {
|
|
167
|
+
if (drag.current !== null && event.currentTarget.hasPointerCapture(event.pointerId)) {
|
|
168
|
+
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function onClick(event) {
|
|
172
|
+
const dragged = drag.current?.moved === true;
|
|
173
|
+
drag.current = null;
|
|
174
|
+
if (!dragged) {
|
|
175
|
+
handlers.onClick(event);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
function announceViewport(next) {
|
|
179
|
+
if (xScale === void 0) return;
|
|
180
|
+
const [from, to] = next ?? fullX ?? [0, 0];
|
|
181
|
+
const asValue = (value) => xScale.kind === "time" ? new Date(value) : value;
|
|
182
|
+
setZoomAnnouncement(
|
|
183
|
+
messages.showing(
|
|
184
|
+
xScale.format(asValue(from)),
|
|
185
|
+
xScale.format(asValue(to))
|
|
186
|
+
)
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
function onKeyDown(event) {
|
|
190
|
+
if (zoom && xContinuous && fullX !== void 0) {
|
|
191
|
+
const focused = active?.point.xValue;
|
|
192
|
+
const [from, to] = viewport.domain ?? fullX;
|
|
193
|
+
const center = focused === void 0 ? (from + to) / 2 : toNumber(focused);
|
|
194
|
+
if (event.key === "+" || event.key === "=") {
|
|
195
|
+
event.preventDefault();
|
|
196
|
+
viewport.zoomAround(center, ZOOM_STEP);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (event.key === "-" || event.key === "_") {
|
|
200
|
+
event.preventDefault();
|
|
201
|
+
viewport.zoomAround(center, 1 / ZOOM_STEP);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (event.key === "0") {
|
|
205
|
+
event.preventDefault();
|
|
206
|
+
viewport.reset();
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (event.shiftKey && (event.key === "ArrowLeft" || event.key === "ArrowRight")) {
|
|
210
|
+
event.preventDefault();
|
|
211
|
+
viewport.pan(
|
|
212
|
+
(event.key === "ArrowRight" ? 1 : -1) * viewport.span() * PAN_SHARE
|
|
213
|
+
);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
handlers.onKeyDown(event);
|
|
218
|
+
}
|
|
219
|
+
const activeKey = active?.point.key;
|
|
220
|
+
React.useEffect(() => {
|
|
221
|
+
setZoomAnnouncement("");
|
|
222
|
+
}, [activeKey]);
|
|
223
|
+
const viewportKey = viewport.domain?.join(":") ?? "full";
|
|
224
|
+
const previousViewport = React.useRef(viewportKey);
|
|
225
|
+
React.useEffect(() => {
|
|
226
|
+
if (previousViewport.current !== viewportKey) {
|
|
227
|
+
previousViewport.current = viewportKey;
|
|
228
|
+
announceViewport(viewport.domain);
|
|
229
|
+
}
|
|
230
|
+
}, [viewportKey]);
|
|
231
|
+
const zoomRef = React.useRef({
|
|
232
|
+
viewport,
|
|
233
|
+
xScale,
|
|
234
|
+
enabled: zoom && xContinuous
|
|
235
|
+
});
|
|
236
|
+
zoomRef.current = { viewport, xScale, enabled: zoom && xContinuous };
|
|
237
|
+
React.useEffect(() => {
|
|
238
|
+
if (node === null) return;
|
|
239
|
+
function onWheel(event) {
|
|
240
|
+
const { viewport: current, xScale: scale, enabled } = zoomRef.current;
|
|
241
|
+
if (!enabled || scale === void 0 || document.activeElement !== node || node === null)
|
|
242
|
+
return;
|
|
243
|
+
event.preventDefault();
|
|
244
|
+
const x = event.clientX - node.getBoundingClientRect().left;
|
|
245
|
+
current.zoomAround(
|
|
246
|
+
toNumber(scale.invert(x)),
|
|
247
|
+
event.deltaY > 0 ? 1 / ZOOM_STEP : ZOOM_STEP
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
node.addEventListener("wheel", onWheel, { passive: false });
|
|
251
|
+
return () => node.removeEventListener("wheel", onWheel);
|
|
252
|
+
}, [node]);
|
|
253
|
+
const announcement = active?.source === "keyboard" ? `${active.point.title} : ${(active.stop.points.length > 1 ? active.stop.points : [active.point]).map((point) => `${point.seriesLabel ?? scene.yLabel} ${point.value}`).join(", ")}` : "";
|
|
254
|
+
const showLegend = legend ?? scene.legend.length > 1;
|
|
255
|
+
const descriptionId = `${chartId}-description`;
|
|
256
|
+
const renderTooltip = typeof tooltip === "function" ? tooltip : ChartTooltipContent;
|
|
257
|
+
function toggle(key) {
|
|
258
|
+
setHidden((current) => {
|
|
259
|
+
const next = new Set(current);
|
|
260
|
+
if (!next.delete(key)) {
|
|
261
|
+
next.add(key);
|
|
262
|
+
}
|
|
263
|
+
return next;
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
return /* @__PURE__ */ jsxs(
|
|
267
|
+
"div",
|
|
268
|
+
{
|
|
269
|
+
"data-slot": "chart",
|
|
270
|
+
style: { display: "grid", gap: 8, ...style },
|
|
271
|
+
...props,
|
|
272
|
+
children: [
|
|
273
|
+
/* @__PURE__ */ jsx("style", { href: "voila-chart", precedence: "default", children: CHART_CSS }),
|
|
274
|
+
/* @__PURE__ */ jsxs(
|
|
275
|
+
"div",
|
|
276
|
+
{
|
|
277
|
+
"data-slot": "chart-frame",
|
|
278
|
+
style: { position: "relative", height: chartHeight },
|
|
279
|
+
children: [
|
|
280
|
+
/* @__PURE__ */ jsxs(
|
|
281
|
+
"div",
|
|
282
|
+
{
|
|
283
|
+
ref,
|
|
284
|
+
role: "img",
|
|
285
|
+
"aria-roledescription": messages.roleDescription,
|
|
286
|
+
"aria-label": ariaLabel,
|
|
287
|
+
"aria-describedby": descriptionId,
|
|
288
|
+
tabIndex: 0,
|
|
289
|
+
"data-slot": "chart-surface",
|
|
290
|
+
style: {
|
|
291
|
+
position: "absolute",
|
|
292
|
+
inset: 0,
|
|
293
|
+
touchAction: brushBehavior || zoom ? "none" : "pan-y",
|
|
294
|
+
// Dragging across the plot brushes or pans; without this it
|
|
295
|
+
// also selected the tick labels and the tooltip as text.
|
|
296
|
+
...brushBehavior || zoom ? { userSelect: "none", WebkitUserSelect: "none" } : {}
|
|
297
|
+
},
|
|
298
|
+
...handlers,
|
|
299
|
+
onKeyDown,
|
|
300
|
+
onPointerDown,
|
|
301
|
+
onPointerMove,
|
|
302
|
+
onPointerUp,
|
|
303
|
+
onClick,
|
|
304
|
+
children: [
|
|
305
|
+
/* @__PURE__ */ jsx(Renderer, { scene: shown, chartId }),
|
|
306
|
+
/* @__PURE__ */ jsx(FocusOverlay, { scene, active, theme: scene.theme }),
|
|
307
|
+
tooltip !== false && active !== null ? /* @__PURE__ */ jsx(
|
|
308
|
+
ChartTooltip,
|
|
309
|
+
{
|
|
310
|
+
active,
|
|
311
|
+
scene,
|
|
312
|
+
render: renderTooltip
|
|
313
|
+
}
|
|
314
|
+
) : null
|
|
315
|
+
]
|
|
316
|
+
}
|
|
317
|
+
),
|
|
318
|
+
brushBehavior && xScale ? /* @__PURE__ */ jsx(
|
|
319
|
+
brushBehavior.Layer,
|
|
320
|
+
{
|
|
321
|
+
scale: xScale,
|
|
322
|
+
plot: scene.plot,
|
|
323
|
+
range: brush,
|
|
324
|
+
messages,
|
|
325
|
+
onChange: updateBrush
|
|
326
|
+
}
|
|
327
|
+
) : null
|
|
328
|
+
]
|
|
329
|
+
}
|
|
330
|
+
),
|
|
331
|
+
/* @__PURE__ */ jsxs("div", { id: descriptionId, style: SR_ONLY, children: [
|
|
332
|
+
ariaDescription ? `${ariaDescription} ` : "",
|
|
333
|
+
messages.keyboardHint,
|
|
334
|
+
zoom && xContinuous ? messages.zoomHint : ""
|
|
335
|
+
] }),
|
|
336
|
+
/* @__PURE__ */ jsx("div", { "aria-live": "polite", "aria-atomic": "true", style: SR_ONLY, children: zoomAnnouncement || announcement }),
|
|
337
|
+
viewport.domain !== null ? /* @__PURE__ */ jsx(
|
|
338
|
+
"button",
|
|
339
|
+
{
|
|
340
|
+
type: "button",
|
|
341
|
+
"data-slot": "chart-reset-zoom",
|
|
342
|
+
onClick: () => viewport.reset(),
|
|
343
|
+
style: {
|
|
344
|
+
justifySelf: "end",
|
|
345
|
+
border: "1px solid var(--border, color-mix(in oklab, currentColor 20%, transparent))",
|
|
346
|
+
borderRadius: 6,
|
|
347
|
+
background: "transparent",
|
|
348
|
+
color: "inherit",
|
|
349
|
+
font: "inherit",
|
|
350
|
+
fontSize: 12,
|
|
351
|
+
padding: "2px 8px",
|
|
352
|
+
cursor: "pointer"
|
|
353
|
+
},
|
|
354
|
+
children: messages.resetZoom
|
|
355
|
+
}
|
|
356
|
+
) : null,
|
|
357
|
+
showLegend && scene.legend.length > 0 ? /* @__PURE__ */ jsx(
|
|
358
|
+
ChartLegend,
|
|
359
|
+
{
|
|
360
|
+
items: scene.legend,
|
|
361
|
+
hidden,
|
|
362
|
+
label: messages.legend,
|
|
363
|
+
onToggle: toggle
|
|
364
|
+
}
|
|
365
|
+
) : null,
|
|
366
|
+
scene.colorRamp && legend !== false ? /* @__PURE__ */ jsx(ChartColorRamp, { ramp: scene.colorRamp, label: messages.legend }) : null,
|
|
367
|
+
dataTable ? /* @__PURE__ */ jsx(
|
|
368
|
+
ChartDataTable,
|
|
369
|
+
{
|
|
370
|
+
scene,
|
|
371
|
+
stops,
|
|
372
|
+
caption: messages.dataTable(ariaLabel),
|
|
373
|
+
seriesHeading: messages.series
|
|
374
|
+
}
|
|
375
|
+
) : null
|
|
376
|
+
]
|
|
377
|
+
}
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
export {
|
|
381
|
+
Chart
|
|
382
|
+
};
|
|
383
|
+
//# sourceMappingURL=chart.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/react/chart.tsx"],
|
|
4
|
+
"sourcesContent": ["import * as React from \"react\";\nimport { compileChart } from \"#/core/compile.ts\";\nimport type { ChartDefinition } from \"#/core/define-chart.ts\";\nimport { findNearest, focusStops } from \"#/core/nearest.ts\";\nimport { toNumber } from \"#/core/scales/continuous.ts\";\nimport type { ChartPoint } from \"#/core/types.ts\";\nimport {\n\ttype ChartBrush,\n\ttype ChartBrushRange,\n\tordered,\n} from \"#/react/brush-contract.ts\";\nimport { ChartDataTable } from \"#/react/chart-data-table.tsx\";\nimport { ChartColorRamp, ChartLegend } from \"#/react/chart-legend.tsx\";\nimport {\n\tChartTooltip,\n\tChartTooltipContent,\n\ttype ChartTooltipRenderProps,\n} from \"#/react/chart-tooltip.tsx\";\nimport { FocusOverlay } from \"#/react/focus-overlay.tsx\";\nimport { messagesFor } from \"#/react/messages.ts\";\nimport type { ChartRenderer } from \"#/react/renderer.ts\";\nimport { SR_ONLY } from \"#/react/sr-only.ts\";\nimport { SvgRenderer } from \"#/react/svg-renderer.tsx\";\nimport { useAnimatedScene } from \"#/react/use-animated-scene.ts\";\nimport { useChartFocus } from \"#/react/use-chart-focus.ts\";\nimport { useChartWidth } from \"#/react/use-chart-width.ts\";\nimport { useChartZoom } from \"#/react/use-chart-zoom.ts\";\nimport { useTextMeasurer } from \"#/react/use-text-measurer.ts\";\n\nconst DEFAULT_HEIGHT = 300;\nconst DEFAULT_INITIAL_WIDTH = 640;\nconst DEFAULT_DURATION = 300;\n\n/** Focus ring, forced colours and reduced motion: what inline styles cannot say. */\nconst CHART_CSS = `\n[data-slot=\"chart-surface\"]:focus-visible{outline:2px solid var(--ring,Highlight);outline-offset:2px;border-radius:4px}\n@media (forced-colors:active){\n[data-slot=\"chart-svg\"] [data-role=\"axis\"],[data-slot=\"chart-svg\"] [data-role=\"axis-title\"]{fill:CanvasText}\n[data-slot=\"chart-svg\"] [data-role=\"grid\"]{stroke:GrayText}\n[data-slot=\"chart-focus-ring\"]{stroke:Highlight}\n[data-slot=\"chart-tooltip\"]{border-color:CanvasText}\n}\n@media (prefers-reduced-motion:no-preference){\n[data-slot=\"chart-tooltip\"]{transition:transform 80ms ease-out}\n}\n`;\n\n// `title` would put a native tooltip on the whole chart; the props carry the\n// accessible name as `ariaLabel` instead.\ninterface Props\n\textends Omit<React.ComponentProps<\"div\">, \"children\" | \"onSelect\" | \"title\"> {\n\treadonly definition: ChartDefinition;\n\t/** What the chart shows, in a sentence: the screen reader's name for it. Required. */\n\treadonly ariaLabel: string;\n\t/** The takeaway, when the label alone does not carry it. */\n\treadonly ariaDescription?: string;\n\t/** Pixels. Ignored when `aspectRatio` is set. */\n\treadonly height?: number;\n\t/** Height as a share of the width: `0.5` is twice as wide as tall. */\n\treadonly aspectRatio?: number;\n\t/** Width used on the server and for the first client render, before the container is measured. */\n\treadonly initialWidth?: number;\n\treadonly renderer?: ChartRenderer;\n\t/** `false` turns the tooltip off; a function replaces its content. */\n\treadonly tooltip?:\n\t\t| boolean\n\t\t| ((props: ChartTooltipRenderProps) => React.ReactNode);\n\t/** Shown by default when there is more than one series. */\n\treadonly legend?: boolean;\n\t/** The visually hidden table of the values. On by default; turn it off only when the page shows the same table. */\n\treadonly dataTable?: boolean;\n\t/** Tween a data update, in milliseconds; `false` snaps. Reduced motion always snaps. */\n\treadonly animate?: boolean | number;\n\t/**\n\t * Zoom a continuous x: the wheel while the chart has focus, + and \u2212,\n\t * Shift and the arrows to pan, a drag to pan when zoomed, 0 to reset.\n\t */\n\treadonly zoom?: boolean;\n\t/** Select a range of x by dragging or from the keyboard: `brushX({ onBrush })` from `@voila.dev/chart/brush`. */\n\treadonly brush?: ChartBrush;\n\treadonly onFocusChange?: (point: ChartPoint | null) => void;\n\treadonly onSelect?: (point: ChartPoint | null) => void;\n}\n\n/** A pointer that moved less than this between down and up clicked rather than dragged. */\nconst DRAG_THRESHOLD = 3;\nconst ZOOM_STEP = 0.8;\nconst PAN_SHARE = 0.1;\n\n/**\n * Draws a definition. Everything a reader needs beyond the picture comes with\n * it: keyboard focus on every value, a live region that reads the focused\n * value, a legend that toggles series, and the values as a hidden table.\n */\nexport function Chart({\n\tdefinition,\n\tariaLabel,\n\tariaDescription,\n\theight = DEFAULT_HEIGHT,\n\taspectRatio,\n\tinitialWidth = DEFAULT_INITIAL_WIDTH,\n\trenderer: Renderer = SvgRenderer,\n\ttooltip = true,\n\tlegend,\n\tdataTable = true,\n\tanimate = true,\n\tzoom = false,\n\tbrush: brushBehavior,\n\tonFocusChange,\n\tonSelect,\n\tstyle,\n\t...props\n}: Props) {\n\tconst chartId = React.useId().replaceAll(\":\", \"\");\n\tconst { ref, width, node } = useChartWidth(initialWidth);\n\tconst measureText = useTextMeasurer(node);\n\tconst [hidden, setHidden] = React.useState<ReadonlySet<string>>(\n\t\t() => new Set(),\n\t);\n\tconst chartHeight =\n\t\taspectRatio === undefined ? height : Math.round(width * aspectRatio);\n\n\tconst baseScene = React.useMemo(\n\t\t() =>\n\t\t\tcompileChart(definition, {\n\t\t\t\twidth,\n\t\t\t\theight: chartHeight,\n\t\t\t\tmeasureText,\n\t\t\t\thiddenSeries: hidden,\n\t\t\t}),\n\t\t[definition, width, chartHeight, measureText, hidden],\n\t);\n\tconst baseX = baseScene.scales.x;\n\tconst fullX = React.useMemo<readonly [number, number] | undefined>(\n\t\t() =>\n\t\t\tbaseX && baseX.kind !== \"band\" && baseX.kind !== \"point\"\n\t\t\t\t? [toNumber(baseX.domain[0]), toNumber(baseX.domain[1])]\n\t\t\t\t: undefined,\n\t\t[baseX],\n\t);\n\tconst viewport = useChartZoom(zoom ? fullX : undefined, definition);\n\tconst scene = React.useMemo(\n\t\t() =>\n\t\t\tviewport.domain === null\n\t\t\t\t? baseScene\n\t\t\t\t: compileChart(definition, {\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight: chartHeight,\n\t\t\t\t\t\tmeasureText,\n\t\t\t\t\t\thiddenSeries: hidden,\n\t\t\t\t\t\txDomain: viewport.domain,\n\t\t\t\t\t}),\n\t\t[\n\t\t\tbaseScene,\n\t\t\tviewport.domain,\n\t\t\tdefinition,\n\t\t\twidth,\n\t\t\tchartHeight,\n\t\t\tmeasureText,\n\t\t\thidden,\n\t\t],\n\t);\n\tconst [brush, setBrush] = React.useState<ChartBrushRange | null>(null);\n\tconst [zoomAnnouncement, setZoomAnnouncement] = React.useState(\"\");\n\tconst drag = React.useRef<{\n\t\treadonly startX: number;\n\t\treadonly domain: readonly [number, number] | null;\n\t\tmoved: boolean;\n\t} | null>(null);\n\tconst stops = React.useMemo(() => focusStops(scene), [scene]);\n\tconst animationTrigger = React.useMemo(\n\t\t() => [definition, hidden],\n\t\t[definition, hidden],\n\t);\n\tconst shown = useAnimatedScene(\n\t\tscene,\n\t\tanimationTrigger,\n\t\tanimate === false ? 0 : animate === true ? DEFAULT_DURATION : animate,\n\t);\n\tconst messages = messagesFor(scene.locale);\n\tconst { active, handlers } = useChartFocus({\n\t\tstops,\n\t\torder: scene.focusOrder,\n\t\thitTest: (x, y) => findNearest(scene, stops, x, y),\n\t\tonFocusChange,\n\t\tonSelect,\n\t});\n\n\tconst xScale = scene.scales.x;\n\tconst xContinuous =\n\t\txScale !== undefined && xScale.kind !== \"band\" && xScale.kind !== \"point\";\n\n\tfunction updateBrush(range: ChartBrushRange | null) {\n\t\tsetBrush(range);\n\t\tbrushBehavior?.onBrush(range);\n\t}\n\n\tfunction localX(event: React.PointerEvent<HTMLElement>): number {\n\t\treturn event.clientX - event.currentTarget.getBoundingClientRect().left;\n\t}\n\n\tfunction onPointerDown(event: React.PointerEvent<HTMLDivElement>) {\n\t\tif (!brushBehavior && !(zoom && viewport.domain !== null)) {\n\t\t\treturn;\n\t\t}\n\t\tevent.currentTarget.setPointerCapture(event.pointerId);\n\t\t// A drag selects a range, not a value: the hover tooltip gives way.\n\t\thandlers.onPointerLeave();\n\t\tdrag.current = {\n\t\t\tstartX: localX(event),\n\t\t\tdomain: viewport.domain,\n\t\t\tmoved: false,\n\t\t};\n\t}\n\n\tfunction onPointerMove(event: React.PointerEvent<HTMLDivElement>) {\n\t\tconst current = drag.current;\n\t\tif (current === null || xScale === undefined) {\n\t\t\thandlers.onPointerMove(event);\n\t\t\treturn;\n\t\t}\n\t\tconst x = localX(event);\n\t\tif (Math.abs(x - current.startX) > DRAG_THRESHOLD) {\n\t\t\tcurrent.moved = true;\n\t\t}\n\t\tif (!current.moved) return;\n\t\tif (brushBehavior) {\n\t\t\tupdateBrush(\n\t\t\t\tordered(xScale, [xScale.invert(current.startX), xScale.invert(x)]),\n\t\t\t);\n\t\t} else if (current.domain !== null) {\n\t\t\tconst [from, to] = current.domain;\n\t\t\tconst perPixel = (to - from) / Math.max(1, scene.plot.width);\n\t\t\tviewport.pan(\n\t\t\t\t(current.startX - x) * perPixel -\n\t\t\t\t\t((viewport.domain?.[0] ?? from) - from),\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction onPointerUp(event: React.PointerEvent<HTMLDivElement>) {\n\t\tif (\n\t\t\tdrag.current !== null &&\n\t\t\tevent.currentTarget.hasPointerCapture(event.pointerId)\n\t\t) {\n\t\t\tevent.currentTarget.releasePointerCapture(event.pointerId);\n\t\t}\n\t}\n\n\tfunction onClick(event: React.MouseEvent<HTMLDivElement>) {\n\t\tconst dragged = drag.current?.moved === true;\n\t\tdrag.current = null;\n\t\tif (!dragged) {\n\t\t\thandlers.onClick(event);\n\t\t}\n\t}\n\n\tfunction announceViewport(next: readonly [number, number] | null) {\n\t\tif (xScale === undefined) return;\n\t\tconst [from, to] = next ?? fullX ?? [0, 0];\n\t\tconst asValue = (value: number) =>\n\t\t\txScale.kind === \"time\" ? new Date(value) : value;\n\t\tsetZoomAnnouncement(\n\t\t\tmessages.showing(\n\t\t\t\txScale.format(asValue(from)),\n\t\t\t\txScale.format(asValue(to)),\n\t\t\t),\n\t\t);\n\t}\n\n\tfunction onKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {\n\t\tif (zoom && xContinuous && fullX !== undefined) {\n\t\t\tconst focused = active?.point.xValue;\n\t\t\tconst [from, to] = viewport.domain ?? fullX;\n\t\t\tconst center =\n\t\t\t\tfocused === undefined ? (from + to) / 2 : toNumber(focused);\n\t\t\tif (event.key === \"+\" || event.key === \"=\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tviewport.zoomAround(center, ZOOM_STEP);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (event.key === \"-\" || event.key === \"_\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tviewport.zoomAround(center, 1 / ZOOM_STEP);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (event.key === \"0\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tviewport.reset();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tevent.shiftKey &&\n\t\t\t\t(event.key === \"ArrowLeft\" || event.key === \"ArrowRight\")\n\t\t\t) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tviewport.pan(\n\t\t\t\t\t(event.key === \"ArrowRight\" ? 1 : -1) * viewport.span() * PAN_SHARE,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\thandlers.onKeyDown(event);\n\t}\n\n\t// Moving the focus says the new value; the last zoom's message gives way.\n\tconst activeKey = active?.point.key;\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: clears on a change of focused point only\n\tReact.useEffect(() => {\n\t\tsetZoomAnnouncement(\"\");\n\t}, [activeKey]);\n\n\tconst viewportKey = viewport.domain?.join(\":\") ?? \"full\";\n\tconst previousViewport = React.useRef(viewportKey);\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: announce a change of viewport, once\n\tReact.useEffect(() => {\n\t\tif (previousViewport.current !== viewportKey) {\n\t\t\tpreviousViewport.current = viewportKey;\n\t\t\tannounceViewport(viewport.domain);\n\t\t}\n\t}, [viewportKey]);\n\n\t// The wheel zooms only while the chart has focus: scrolling past a chart\n\t// must keep scrolling the page.\n\tconst zoomRef = React.useRef({\n\t\tviewport,\n\t\txScale,\n\t\tenabled: zoom && xContinuous,\n\t});\n\tzoomRef.current = { viewport, xScale, enabled: zoom && xContinuous };\n\tReact.useEffect(() => {\n\t\tif (node === null) return;\n\t\tfunction onWheel(event: WheelEvent) {\n\t\t\tconst { viewport: current, xScale: scale, enabled } = zoomRef.current;\n\t\t\tif (\n\t\t\t\t!enabled ||\n\t\t\t\tscale === undefined ||\n\t\t\t\tdocument.activeElement !== node ||\n\t\t\t\tnode === null\n\t\t\t)\n\t\t\t\treturn;\n\t\t\tevent.preventDefault();\n\t\t\tconst x = event.clientX - node.getBoundingClientRect().left;\n\t\t\tcurrent.zoomAround(\n\t\t\t\ttoNumber(scale.invert(x)),\n\t\t\t\tevent.deltaY > 0 ? 1 / ZOOM_STEP : ZOOM_STEP,\n\t\t\t);\n\t\t}\n\t\tnode.addEventListener(\"wheel\", onWheel, { passive: false });\n\t\treturn () => node.removeEventListener(\"wheel\", onWheel);\n\t}, [node]);\n\n\tconst announcement =\n\t\tactive?.source === \"keyboard\"\n\t\t\t? `${active.point.title} : ${(active.stop.points.length > 1\n\t\t\t\t\t? active.stop.points\n\t\t\t\t\t: [active.point]\n\t\t\t\t)\n\t\t\t\t\t.map((point) => `${point.seriesLabel ?? scene.yLabel} ${point.value}`)\n\t\t\t\t\t.join(\", \")}`\n\t\t\t: \"\";\n\tconst showLegend = legend ?? scene.legend.length > 1;\n\tconst descriptionId = `${chartId}-description`;\n\tconst renderTooltip =\n\t\ttypeof tooltip === \"function\" ? tooltip : ChartTooltipContent;\n\n\tfunction toggle(key: string) {\n\t\tsetHidden((current) => {\n\t\t\tconst next = new Set(current);\n\t\t\tif (!next.delete(key)) {\n\t\t\t\tnext.add(key);\n\t\t\t}\n\t\t\treturn next;\n\t\t});\n\t}\n\n\treturn (\n\t\t<div\n\t\t\tdata-slot=\"chart\"\n\t\t\tstyle={{ display: \"grid\", gap: 8, ...style }}\n\t\t\t{...props}\n\t\t>\n\t\t\t<style href=\"voila-chart\" precedence=\"default\">\n\t\t\t\t{CHART_CSS}\n\t\t\t</style>\n\t\t\t<div\n\t\t\t\tdata-slot=\"chart-frame\"\n\t\t\t\tstyle={{ position: \"relative\", height: chartHeight }}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tref={ref}\n\t\t\t\t\trole=\"img\"\n\t\t\t\t\taria-roledescription={messages.roleDescription}\n\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\taria-describedby={descriptionId}\n\t\t\t\t\t// The chart is one focus stop; the arrow keys move inside it, the way\n\t\t\t\t\t// a reader walks the values. role=\"img\" keeps it a single named\n\t\t\t\t\t// graphic, the live region speaks the focused value.\n\t\t\t\t\t// biome-ignore lint/a11y/noNoninteractiveTabindex: keyboard exploration of the values\n\t\t\t\t\ttabIndex={0}\n\t\t\t\t\tdata-slot=\"chart-surface\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\tinset: 0,\n\t\t\t\t\t\ttouchAction: brushBehavior || zoom ? \"none\" : \"pan-y\",\n\t\t\t\t\t\t// Dragging across the plot brushes or pans; without this it\n\t\t\t\t\t\t// also selected the tick labels and the tooltip as text.\n\t\t\t\t\t\t...(brushBehavior || zoom\n\t\t\t\t\t\t\t? { userSelect: \"none\", WebkitUserSelect: \"none\" }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t}}\n\t\t\t\t\t{...handlers}\n\t\t\t\t\tonKeyDown={onKeyDown}\n\t\t\t\t\tonPointerDown={onPointerDown}\n\t\t\t\t\tonPointerMove={onPointerMove}\n\t\t\t\t\tonPointerUp={onPointerUp}\n\t\t\t\t\tonClick={onClick}\n\t\t\t\t>\n\t\t\t\t\t<Renderer scene={shown} chartId={chartId} />\n\t\t\t\t\t<FocusOverlay scene={scene} active={active} theme={scene.theme} />\n\t\t\t\t\t{tooltip !== false && active !== null ? (\n\t\t\t\t\t\t<ChartTooltip\n\t\t\t\t\t\t\tactive={active}\n\t\t\t\t\t\t\tscene={scene}\n\t\t\t\t\t\t\trender={renderTooltip}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t\t{brushBehavior && xScale ? (\n\t\t\t\t\t<brushBehavior.Layer\n\t\t\t\t\t\tscale={xScale}\n\t\t\t\t\t\tplot={scene.plot}\n\t\t\t\t\t\trange={brush}\n\t\t\t\t\t\tmessages={messages}\n\t\t\t\t\t\tonChange={updateBrush}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t\t<div id={descriptionId} style={SR_ONLY}>\n\t\t\t\t{ariaDescription ? `${ariaDescription} ` : \"\"}\n\t\t\t\t{messages.keyboardHint}\n\t\t\t\t{zoom && xContinuous ? messages.zoomHint : \"\"}\n\t\t\t</div>\n\t\t\t<div aria-live=\"polite\" aria-atomic=\"true\" style={SR_ONLY}>\n\t\t\t\t{zoomAnnouncement || announcement}\n\t\t\t</div>\n\t\t\t{viewport.domain !== null ? (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tdata-slot=\"chart-reset-zoom\"\n\t\t\t\t\tonClick={() => viewport.reset()}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tjustifySelf: \"end\",\n\t\t\t\t\t\tborder:\n\t\t\t\t\t\t\t\"1px solid var(--border, color-mix(in oklab, currentColor 20%, transparent))\",\n\t\t\t\t\t\tborderRadius: 6,\n\t\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\t\tcolor: \"inherit\",\n\t\t\t\t\t\tfont: \"inherit\",\n\t\t\t\t\t\tfontSize: 12,\n\t\t\t\t\t\tpadding: \"2px 8px\",\n\t\t\t\t\t\tcursor: \"pointer\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{messages.resetZoom}\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t\t{showLegend && scene.legend.length > 0 ? (\n\t\t\t\t<ChartLegend\n\t\t\t\t\titems={scene.legend}\n\t\t\t\t\thidden={hidden}\n\t\t\t\t\tlabel={messages.legend}\n\t\t\t\t\tonToggle={toggle}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t{scene.colorRamp && legend !== false ? (\n\t\t\t\t<ChartColorRamp ramp={scene.colorRamp} label={messages.legend} />\n\t\t\t) : null}\n\t\t\t{dataTable ? (\n\t\t\t\t<ChartDataTable\n\t\t\t\t\tscene={scene}\n\t\t\t\t\tstops={stops}\n\t\t\t\t\tcaption={messages.dataTable(ariaLabel)}\n\t\t\t\t\tseriesHeading={messages.series}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type * as React from "react";
|
|
2
|
+
import type { ChartScene, ChartTheme } from "../core/types.js";
|
|
3
|
+
import type { ActiveFocus } from "./use-chart-focus.js";
|
|
4
|
+
/**
|
|
5
|
+
* The focus layer, drawn over the marks whichever renderer drew them: the
|
|
6
|
+
* column or row band under the pointer, and a ring on the focused point.
|
|
7
|
+
* Hidden from assistive tech: the live region says what it shows.
|
|
8
|
+
*/
|
|
9
|
+
export declare function FocusOverlay({ scene, active, theme, }: {
|
|
10
|
+
scene: ChartScene;
|
|
11
|
+
active: ActiveFocus | null;
|
|
12
|
+
theme: ChartTheme;
|
|
13
|
+
}): React.JSX.Element | null;
|
|
14
|
+
//# sourceMappingURL=focus-overlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus-overlay.d.ts","sourceRoot":"","sources":["../../src/react/focus-overlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,OAAO,KAAK,EAAc,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AA+D9D;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAC5B,KAAK,EACL,MAAM,EACN,KAAK,GACL,EAAE;IACF,KAAK,EAAE,UAAU,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,UAAU,CAAC;CAClB,4BAoFA"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { arcPath, roundedBarPath } from "../core/paths.js";
|
|
3
|
+
const RING_RADIUS = 4.5;
|
|
4
|
+
const RING_OUTSET = 2;
|
|
5
|
+
function PointRing({
|
|
6
|
+
point,
|
|
7
|
+
keyboard,
|
|
8
|
+
theme
|
|
9
|
+
}) {
|
|
10
|
+
const ring = keyboard ? "var(--ring, Highlight)" : theme.background;
|
|
11
|
+
if (point.hit?.kind === "rect" && point.hit.rect.width > RING_RADIUS * 4) {
|
|
12
|
+
if (!keyboard) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const { rect } = point.hit;
|
|
16
|
+
return /* @__PURE__ */ jsx(
|
|
17
|
+
"path",
|
|
18
|
+
{
|
|
19
|
+
"data-slot": "chart-focus-ring",
|
|
20
|
+
d: roundedBarPath({
|
|
21
|
+
x: rect.x - RING_OUTSET,
|
|
22
|
+
y: rect.y - RING_OUTSET,
|
|
23
|
+
width: rect.width + RING_OUTSET * 2,
|
|
24
|
+
height: rect.height + RING_OUTSET * 2,
|
|
25
|
+
radius: 4
|
|
26
|
+
}),
|
|
27
|
+
fill: "none",
|
|
28
|
+
stroke: ring,
|
|
29
|
+
strokeWidth: 2
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
if (point.hit?.kind === "arc") {
|
|
34
|
+
return /* @__PURE__ */ jsx(
|
|
35
|
+
"path",
|
|
36
|
+
{
|
|
37
|
+
"data-slot": "chart-focus-ring",
|
|
38
|
+
d: arcPath({
|
|
39
|
+
...point.hit,
|
|
40
|
+
outerRadius: point.hit.outerRadius + RING_OUTSET
|
|
41
|
+
}),
|
|
42
|
+
fill: "none",
|
|
43
|
+
stroke: keyboard ? ring : theme.foreground,
|
|
44
|
+
strokeWidth: 2
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
return /* @__PURE__ */ jsx(
|
|
49
|
+
"circle",
|
|
50
|
+
{
|
|
51
|
+
"data-slot": "chart-focus-ring",
|
|
52
|
+
cx: point.x,
|
|
53
|
+
cy: point.y,
|
|
54
|
+
r: RING_RADIUS,
|
|
55
|
+
fill: point.color,
|
|
56
|
+
stroke: ring,
|
|
57
|
+
strokeWidth: 2
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
function FocusOverlay({
|
|
62
|
+
scene,
|
|
63
|
+
active,
|
|
64
|
+
theme
|
|
65
|
+
}) {
|
|
66
|
+
if (active === null) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const { focusOrder, scales } = scene;
|
|
70
|
+
const plot = scene.cells?.find((cell) => cell.key === active.point.facet)?.plot ?? scene.plot;
|
|
71
|
+
const keyboard = active.source === "keyboard";
|
|
72
|
+
const along = focusOrder === "y" ? scales.y : scales.x;
|
|
73
|
+
const band = along?.kind === "band" ? along.bandwidth : 0;
|
|
74
|
+
let cursor = null;
|
|
75
|
+
if (focusOrder !== "point") {
|
|
76
|
+
cursor = band > 0 ? /* @__PURE__ */ jsx(
|
|
77
|
+
"rect",
|
|
78
|
+
{
|
|
79
|
+
"data-slot": "chart-cursor",
|
|
80
|
+
...focusOrder === "y" ? {
|
|
81
|
+
x: plot.x,
|
|
82
|
+
y: active.stop.at - band / 2,
|
|
83
|
+
width: plot.width,
|
|
84
|
+
height: band
|
|
85
|
+
} : {
|
|
86
|
+
x: active.stop.at - band / 2,
|
|
87
|
+
y: plot.y,
|
|
88
|
+
width: band,
|
|
89
|
+
height: plot.height
|
|
90
|
+
},
|
|
91
|
+
fill: "currentColor",
|
|
92
|
+
opacity: 0.06
|
|
93
|
+
}
|
|
94
|
+
) : /* @__PURE__ */ jsx(
|
|
95
|
+
"line",
|
|
96
|
+
{
|
|
97
|
+
"data-slot": "chart-cursor",
|
|
98
|
+
...focusOrder === "y" ? {
|
|
99
|
+
x1: plot.x,
|
|
100
|
+
x2: plot.x + plot.width,
|
|
101
|
+
y1: active.stop.at,
|
|
102
|
+
y2: active.stop.at
|
|
103
|
+
} : {
|
|
104
|
+
x1: active.stop.at,
|
|
105
|
+
x2: active.stop.at,
|
|
106
|
+
y1: plot.y,
|
|
107
|
+
y2: plot.y + plot.height
|
|
108
|
+
},
|
|
109
|
+
stroke: theme.muted,
|
|
110
|
+
strokeWidth: 1,
|
|
111
|
+
strokeDasharray: "3 3"
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
const ringed = focusOrder === "point" || keyboard && active.stop.points.length > 1 ? [active.point] : active.stop.points;
|
|
116
|
+
return /* @__PURE__ */ jsxs(
|
|
117
|
+
"svg",
|
|
118
|
+
{
|
|
119
|
+
"aria-hidden": "true",
|
|
120
|
+
"data-slot": "chart-focus",
|
|
121
|
+
width: scene.width,
|
|
122
|
+
height: scene.height,
|
|
123
|
+
style: {
|
|
124
|
+
position: "absolute",
|
|
125
|
+
inset: 0,
|
|
126
|
+
overflow: "visible",
|
|
127
|
+
pointerEvents: "none"
|
|
128
|
+
},
|
|
129
|
+
children: [
|
|
130
|
+
cursor,
|
|
131
|
+
ringed.map((point) => /* @__PURE__ */ jsx(
|
|
132
|
+
PointRing,
|
|
133
|
+
{
|
|
134
|
+
point,
|
|
135
|
+
keyboard,
|
|
136
|
+
theme
|
|
137
|
+
},
|
|
138
|
+
point.key
|
|
139
|
+
))
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
export {
|
|
145
|
+
FocusOverlay
|
|
146
|
+
};
|
|
147
|
+
//# sourceMappingURL=focus-overlay.js.map
|