@advui/charts 0.5.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.
Files changed (88) hide show
  1. package/LICENSE +49 -0
  2. package/README.md +41 -0
  3. package/dist/charts/ChartFrame.d.ts +75 -0
  4. package/dist/charts/ChartFrame.d.ts.map +1 -0
  5. package/dist/charts/ChartFrame.js +100 -0
  6. package/dist/charts/ChartFrame.js.map +1 -0
  7. package/dist/charts/LinePlot.d.ts +32 -0
  8. package/dist/charts/LinePlot.d.ts.map +1 -0
  9. package/dist/charts/LinePlot.js +93 -0
  10. package/dist/charts/LinePlot.js.map +1 -0
  11. package/dist/charts/cartesian.d.ts +35 -0
  12. package/dist/charts/cartesian.d.ts.map +1 -0
  13. package/dist/charts/cartesian.js +23 -0
  14. package/dist/charts/cartesian.js.map +1 -0
  15. package/dist/charts/format.d.ts +7 -0
  16. package/dist/charts/format.d.ts.map +1 -0
  17. package/dist/charts/format.js +12 -0
  18. package/dist/charts/format.js.map +1 -0
  19. package/dist/charts/index.d.ts +7 -0
  20. package/dist/charts/index.d.ts.map +1 -0
  21. package/dist/charts/index.js +7 -0
  22. package/dist/charts/index.js.map +1 -0
  23. package/dist/charts/scale.d.ts +20 -0
  24. package/dist/charts/scale.d.ts.map +1 -0
  25. package/dist/charts/scale.js +75 -0
  26. package/dist/charts/scale.js.map +1 -0
  27. package/dist/charts/svg.d.ts +51 -0
  28. package/dist/charts/svg.d.ts.map +1 -0
  29. package/dist/charts/svg.js +13 -0
  30. package/dist/charts/svg.js.map +1 -0
  31. package/dist/charts/svg.native.d.ts +50 -0
  32. package/dist/charts/svg.native.d.ts.map +1 -0
  33. package/dist/charts/svg.native.js +14 -0
  34. package/dist/charts/svg.native.js.map +1 -0
  35. package/dist/components/area-chart/AreaChart.d.ts +11 -0
  36. package/dist/components/area-chart/AreaChart.d.ts.map +1 -0
  37. package/dist/components/area-chart/AreaChart.js +10 -0
  38. package/dist/components/area-chart/AreaChart.js.map +1 -0
  39. package/dist/components/area-chart/index.d.ts +2 -0
  40. package/dist/components/area-chart/index.d.ts.map +1 -0
  41. package/dist/components/area-chart/index.js +2 -0
  42. package/dist/components/area-chart/index.js.map +1 -0
  43. package/dist/components/bar-chart/BarChart.d.ts +31 -0
  44. package/dist/components/bar-chart/BarChart.d.ts.map +1 -0
  45. package/dist/components/bar-chart/BarChart.js +114 -0
  46. package/dist/components/bar-chart/BarChart.js.map +1 -0
  47. package/dist/components/bar-chart/index.d.ts +2 -0
  48. package/dist/components/bar-chart/index.d.ts.map +1 -0
  49. package/dist/components/bar-chart/index.js +2 -0
  50. package/dist/components/bar-chart/index.js.map +1 -0
  51. package/dist/components/line-chart/LineChart.d.ts +8 -0
  52. package/dist/components/line-chart/LineChart.d.ts.map +1 -0
  53. package/dist/components/line-chart/LineChart.js +10 -0
  54. package/dist/components/line-chart/LineChart.js.map +1 -0
  55. package/dist/components/line-chart/index.d.ts +2 -0
  56. package/dist/components/line-chart/index.d.ts.map +1 -0
  57. package/dist/components/line-chart/index.js +2 -0
  58. package/dist/components/line-chart/index.js.map +1 -0
  59. package/dist/components/pie-chart/PieChart.d.ts +37 -0
  60. package/dist/components/pie-chart/PieChart.d.ts.map +1 -0
  61. package/dist/components/pie-chart/PieChart.js +89 -0
  62. package/dist/components/pie-chart/PieChart.js.map +1 -0
  63. package/dist/components/pie-chart/index.d.ts +2 -0
  64. package/dist/components/pie-chart/index.d.ts.map +1 -0
  65. package/dist/components/pie-chart/index.js +2 -0
  66. package/dist/components/pie-chart/index.js.map +1 -0
  67. package/dist/index.d.ts +5 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +7 -0
  70. package/dist/index.js.map +1 -0
  71. package/package.json +93 -0
  72. package/src/charts/ChartFrame.tsx +303 -0
  73. package/src/charts/LinePlot.tsx +216 -0
  74. package/src/charts/cartesian.tsx +99 -0
  75. package/src/charts/format.ts +14 -0
  76. package/src/charts/index.ts +16 -0
  77. package/src/charts/scale.ts +91 -0
  78. package/src/charts/svg.native.tsx +62 -0
  79. package/src/charts/svg.tsx +57 -0
  80. package/src/components/area-chart/AreaChart.tsx +14 -0
  81. package/src/components/area-chart/index.ts +1 -0
  82. package/src/components/bar-chart/BarChart.tsx +300 -0
  83. package/src/components/bar-chart/index.ts +1 -0
  84. package/src/components/line-chart/LineChart.tsx +11 -0
  85. package/src/components/line-chart/index.ts +1 -0
  86. package/src/components/pie-chart/PieChart.tsx +192 -0
  87. package/src/components/pie-chart/index.ts +1 -0
  88. package/src/index.ts +6 -0
package/LICENSE ADDED
@@ -0,0 +1,49 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Universal UI contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---------------------------------------------------------------------------
24
+
25
+ Third-party notices
26
+
27
+ Icons in packages/icons are generated from Lucide (https://lucide.dev),
28
+ licensed under the ISC License:
29
+
30
+ ISC License
31
+ Copyright (c) for portions of Lucide are held by Cole Bemis 2013-2022 as part
32
+ of Feather (MIT). All other copyright (c) for Lucide are held by Lucide
33
+ Contributors 2022.
34
+
35
+ Permission to use, copy, modify, and/or distribute this software for any
36
+ purpose with or without fee is hereby granted, provided that the above
37
+ copyright notice and this permission notice appear in all copies.
38
+
39
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
40
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
41
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
42
+ SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
43
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
44
+ OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
45
+ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
46
+
47
+ Color scales in packages/theme are based on Radix Colors
48
+ (https://github.com/radix-ui/colors), licensed under the MIT License,
49
+ Copyright (c) 2022 WorkOS.
package/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # @advui/charts
2
+
3
+ Bar, line, area and pie charts for [Adv UI](https://github.com/zinmin232/advui),
4
+ on web, iOS and Android. Charts draw SVG on web and use `react-native-svg` on
5
+ iOS and Android. Each chart has a legend, tooltips (tap on touch screens), a
6
+ screen-reader summary and a table view of its data.
7
+
8
+ > Not on npm yet: `@advui/charts` will be published with the next release.
9
+ > Until then, copy the charts into your app with the CLI:
10
+ > `npx advui add bar-chart`.
11
+
12
+ ```bash
13
+ pnpm add @advui/charts @advui/data @advui/core @advui/theme @advui/icons tamagui
14
+ # iOS and Android also need react-native-svg (Expo: npx expo install react-native-svg)
15
+ ```
16
+
17
+ ```tsx
18
+ import { BarChart } from '@advui/charts'
19
+
20
+ ;<BarChart
21
+ title="People reached"
22
+ data={[
23
+ { month: 'Jan', planned: 1200, reached: 980 },
24
+ { month: 'Feb', planned: 1400, reached: 1320 },
25
+ ]}
26
+ index="month"
27
+ series={[
28
+ { key: 'planned', label: 'Planned' },
29
+ { key: 'reached', label: 'Reached' },
30
+ ]}
31
+ />
32
+ ```
33
+
34
+ Charts render inside the app's `UniversalProvider` from `@advui/core`, which
35
+ is a peer dependency, as are `@advui/data` (the table view uses its Table),
36
+ `react`, `react-native`, `tamagui` and (on iOS and Android) `react-native-svg`.
37
+ No charting library is added.
38
+
39
+ **Exports:** AreaChart, BarChart, LineChart, PieChart and their prop types.
40
+
41
+ Docs: https://zinmin232.github.io/advui/docs/components/bar-chart. License: MIT.
@@ -0,0 +1,75 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type GetProps, View } from 'tamagui';
3
+ /** One series (a line, a set of bars): the data field it reads and its name. */
4
+ export interface ChartSeries {
5
+ key: string;
6
+ label: string;
7
+ }
8
+ export interface ChartLabels {
9
+ showTable: string;
10
+ hideTable: string;
11
+ /** Read before the arrow-key hint on the focused plot. */
12
+ keyboardHint: string;
13
+ }
14
+ export declare const defaultChartLabels: ChartLabels;
15
+ /** The chart palette, in its fixed order, as resolved colors. */
16
+ export declare function useChartColors(): string[];
17
+ /** Axis text, gridlines and the surface, as resolved colors. */
18
+ export declare function useChartInk(surface: string): {
19
+ text: string;
20
+ grid: string;
21
+ axis: string;
22
+ surface: string;
23
+ };
24
+ export interface LegendItem {
25
+ label: string;
26
+ color: string;
27
+ /** Mirrors the mark: a line for line charts, a square for bars, areas and slices. */
28
+ shape: 'line' | 'square';
29
+ /** Extra text after the label, e.g. a slice's share. */
30
+ detail?: string;
31
+ }
32
+ export interface TooltipContent {
33
+ title: string;
34
+ rows: {
35
+ label: string;
36
+ value: string;
37
+ color: string;
38
+ shape: LegendItem['shape'];
39
+ }[];
40
+ }
41
+ export interface ChartFrameProps {
42
+ /** Names the chart (its accessible name and heading). */
43
+ title: string;
44
+ description?: string;
45
+ legend: LegendItem[];
46
+ /** Plot height in pixels, including the axes. */
47
+ height: number;
48
+ /** Fixed plot width; by default the chart fills its container. */
49
+ width?: number;
50
+ /** Number of positions the arrow keys step through. */
51
+ count: number;
52
+ /** The position under a point in the plot, or null. */
53
+ hitTest: (x: number, y: number, width: number) => number | null;
54
+ tooltip: (index: number) => TooltipContent | null;
55
+ /** Where the tooltip points, in plot coordinates. */
56
+ anchor: (index: number, width: number) => {
57
+ x: number;
58
+ y: number;
59
+ };
60
+ /** Draws the plot at the measured width; `active` is the hovered position. */
61
+ children: (width: number, active: number | null) => ReactNode;
62
+ table: {
63
+ columns: string[];
64
+ rows: string[][];
65
+ numeric: boolean[];
66
+ };
67
+ labels?: Partial<ChartLabels>;
68
+ frameProps?: GetProps<typeof View>;
69
+ }
70
+ /**
71
+ * The frame every chart shares: title, legend, a measured plot with a
72
+ * tooltip (hover, tap or arrow keys), and a table view of the same data.
73
+ */
74
+ export declare function ChartFrame({ title, description, legend, height, width: fixedWidth, count, hitTest, tooltip, anchor, children, table, labels: labelsProp, frameProps, }: ChartFrameProps): import("react").JSX.Element;
75
+ //# sourceMappingURL=ChartFrame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChartFrame.d.ts","sourceRoot":"","sources":["../../src/charts/ChartFrame.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAA2B,MAAM,OAAO,CAAA;AAC/D,OAAO,EAAE,KAAK,QAAQ,EAAE,IAAI,EAAiC,MAAM,SAAS,CAAA;AAI5E,gFAAgF;AAChF,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,eAAO,MAAM,kBAAkB,EAAE,WAIhC,CAAA;AAED,iEAAiE;AACjE,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAYzC;AAED,gEAAgE;AAChE,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM;;;;;EAO1C;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,qFAAqF;IACrF,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAA;IACxB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;KAAE,EAAE,CAAA;CACpF;AAED,MAAM,WAAW,eAAe;IAC9B,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAA;IACb,uDAAuD;IACvD,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;IAC/D,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,cAAc,GAAG,IAAI,CAAA;IACjD,qDAAqD;IACrD,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAClE,8EAA8E;IAC9E,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,SAAS,CAAA;IAC7D,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;QAAC,OAAO,EAAE,OAAO,EAAE,CAAA;KAAE,CAAA;IAClE,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC7B,UAAU,CAAC,EAAE,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAA;CACnC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,MAAM,EACN,MAAM,EACN,KAAK,EAAE,UAAU,EACjB,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,QAAQ,EACR,KAAK,EACL,MAAM,EAAE,UAAU,EAClB,UAAU,GACX,EAAE,eAAe,+BAqMjB"}
@@ -0,0 +1,100 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useIconColor } from '@advui/icons';
3
+ import { useId, useRef, useState } from 'react';
4
+ import { View, VisuallyHidden, XStack, isWeb } from 'tamagui';
5
+ import { Button, Text } from '@advui/core';
6
+ import { Table } from '@advui/data';
7
+ export const defaultChartLabels = {
8
+ showTable: 'Show table',
9
+ hideTable: 'Hide table',
10
+ keyboardHint: 'Use the arrow keys to read each value.',
11
+ };
12
+ /** The chart palette, in its fixed order, as resolved colors. */
13
+ export function useChartColors() {
14
+ // Hooks in a fixed order: one per slot.
15
+ return [
16
+ useIconColor('$chart1'),
17
+ useIconColor('$chart2'),
18
+ useIconColor('$chart3'),
19
+ useIconColor('$chart4'),
20
+ useIconColor('$chart5'),
21
+ useIconColor('$chart6'),
22
+ useIconColor('$chart7'),
23
+ useIconColor('$chart8'),
24
+ ].map((color) => color ?? 'currentColor');
25
+ }
26
+ /** Axis text, gridlines and the surface, as resolved colors. */
27
+ export function useChartInk(surface) {
28
+ return {
29
+ text: useIconColor('$mutedForeground') ?? 'currentColor',
30
+ grid: useIconColor('$border') ?? 'currentColor',
31
+ axis: useIconColor('$borderStrong') ?? 'currentColor',
32
+ surface: useIconColor(surface) ?? 'transparent',
33
+ };
34
+ }
35
+ /**
36
+ * The frame every chart shares: title, legend, a measured plot with a
37
+ * tooltip (hover, tap or arrow keys), and a table view of the same data.
38
+ */
39
+ export function ChartFrame({ title, description, legend, height, width: fixedWidth, count, hitTest, tooltip, anchor, children, table, labels: labelsProp, frameProps, }) {
40
+ const labels = { ...defaultChartLabels, ...labelsProp };
41
+ const [measured, setMeasured] = useState(0);
42
+ const width = fixedWidth ?? measured;
43
+ const [active, setActive] = useState(null);
44
+ const [showTable, setShowTable] = useState(false);
45
+ const titleId = useId();
46
+ const tableId = useId();
47
+ const plotRef = useRef(null);
48
+ const content = active != null ? tooltip(active) : null;
49
+ const pointAt = (clientX, clientY) => {
50
+ const rect = plotRef.current?.getBoundingClientRect();
51
+ if (!rect)
52
+ return;
53
+ setActive(hitTest(clientX - rect.left, clientY - rect.top, width));
54
+ };
55
+ const onKeyDown = (event) => {
56
+ const last = count - 1;
57
+ const moves = {
58
+ ArrowRight: Math.min(last, (active ?? -1) + 1),
59
+ ArrowDown: Math.min(last, (active ?? -1) + 1),
60
+ ArrowLeft: Math.max(0, (active ?? count) - 1),
61
+ ArrowUp: Math.max(0, (active ?? count) - 1),
62
+ Home: 0,
63
+ End: last,
64
+ };
65
+ if (event.key in moves && count > 0) {
66
+ event.preventDefault();
67
+ setActive(moves[event.key]);
68
+ }
69
+ else if (event.key === 'Escape')
70
+ setActive(null);
71
+ };
72
+ const point = active != null && width > 0 ? anchor(active, width) : null;
73
+ const summary = content
74
+ ? `${content.title}: ${content.rows.map((r) => `${r.label} ${r.value}`).join(', ')}`
75
+ : '';
76
+ return (_jsxs(View, { render: "figure", margin: 0, gap: "$3", width: "100%", "aria-labelledby": titleId, ...frameProps, children: [_jsxs(View, { gap: "$1", children: [_jsx(Text, { id: titleId, size: "sm", weight: "semibold", children: title }), description ? (_jsx(Text, { size: "xs", tone: "muted", children: description })) : null] }), legend.length > 0 ? (_jsx(XStack, { flexWrap: "wrap", columnGap: "$4", rowGap: "$1.5", children: legend.map((item) => (_jsxs(XStack, { alignItems: "center", gap: "$1.5", children: [_jsx(View, { "aria-hidden": true, backgroundColor: item.color, width: item.shape === 'line' ? '$3' : '$2.5', height: item.shape === 'line' ? 2 : '$2.5', borderRadius: item.shape === 'line' ? '$full' : '$xs' }), _jsxs(Text, { size: "xs", tone: "muted", children: [item.label, item.detail ? ` · ${item.detail}` : ''] })] }, item.label))) })) : null, _jsxs(View, { ref: plotRef, position: "relative", height: height, width: fixedWidth ?? '100%', onLayout: (event) => setMeasured(Math.floor(event.nativeEvent.layout.width)),
77
+ // The plot is one focusable image; the arrow keys read it point by point.
78
+ role: "img", "aria-label": `${title}. ${description ? `${description}. ` : ''}${labels.keyboardHint}`, ...(isWeb
79
+ ? {
80
+ tabIndex: 0,
81
+ onKeyDown,
82
+ onBlur: () => setActive(null),
83
+ onMouseMove: (event) => pointAt(event.clientX, event.clientY),
84
+ onMouseLeave: () => setActive(null),
85
+ }
86
+ : {
87
+ accessible: true,
88
+ // Native has no live region here: the reading becomes the plot's value.
89
+ ...(summary && { accessibilityValue: { text: summary } }),
90
+ onPress: (event) => setActive(hitTest(event.nativeEvent.locationX, event.nativeEvent.locationY, width)),
91
+ }), borderRadius: "$sm", focusVisibleStyle: {
92
+ outlineColor: '$ring',
93
+ outlineStyle: 'solid',
94
+ outlineWidth: 2,
95
+ outlineOffset: 4,
96
+ }, children: [width > 0 ? children(width, active) : null, content && point ? (_jsxs(View, { "aria-hidden": true, pointerEvents: "none", position: "absolute", top: 0, ...(point.x < width / 2 ? { left: point.x + 12 } : { right: width - point.x + 12 }), backgroundColor: "$popover", borderWidth: 1, borderColor: "$border", borderRadius: "$md", paddingHorizontal: "$2.5", paddingVertical: "$2", gap: "$1", minWidth: "$32", zIndex: 1, children: [_jsx(Text, { size: "xs", tone: "muted", children: content.title }), content.rows.map((row) => (_jsxs(XStack, { alignItems: "center", gap: "$2", children: [_jsx(View, { backgroundColor: row.color, width: "$2.5", height: row.shape === 'line' ? 2 : '$2.5', borderRadius: row.shape === 'line' ? '$full' : '$xs' }), _jsx(Text, { size: "sm", weight: "semibold", children: row.value }), _jsx(Text, { size: "xs", tone: "muted", flexShrink: 1, children: row.label })] }, row.label)))] })) : null] }), isWeb ? _jsx(VisuallyHidden, { "aria-live": "polite", children: summary }) : null, _jsxs(View, { alignItems: "flex-start", gap: "$2", children: [_jsx(Button, { size: "sm", variant: "ghost",
97
+ // Lines the label up with the title above.
98
+ marginLeft: "$-3", "aria-expanded": showTable, ...(isWeb && { 'aria-controls': tableId }), onPress: () => setShowTable(!showTable), children: showTable ? labels.hideTable : labels.showTable }), showTable ? (_jsx(View, { id: tableId, width: "100%", children: _jsxs(Table, { "aria-label": title, size: "sm", minWidth: Math.max(320, table.columns.length * 96), children: [_jsx(Table.Header, { children: _jsx(Table.Row, { children: table.columns.map((column, i) => (_jsx(Table.Head, { align: table.numeric[i] ? 'end' : 'start', children: column }, column))) }) }), _jsx(Table.Body, { children: table.rows.map((row, r) => (_jsx(Table.Row, { children: row.map((cell, i) => (_jsx(Table.Cell, { align: table.numeric[i] ? 'end' : 'start', children: cell }, i))) }, r))) })] }) })) : null] })] }));
99
+ }
100
+ //# sourceMappingURL=ChartFrame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChartFrame.js","sourceRoot":"","sources":["../../src/charts/ChartFrame.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAkB,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC/D,OAAO,EAAiB,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAenC,MAAM,CAAC,MAAM,kBAAkB,GAAgB;IAC7C,SAAS,EAAE,YAAY;IACvB,SAAS,EAAE,YAAY;IACvB,YAAY,EAAE,wCAAwC;CACvD,CAAA;AAED,iEAAiE;AACjE,MAAM,UAAU,cAAc;IAC5B,wCAAwC;IACxC,OAAO;QACL,YAAY,CAAC,SAAS,CAAC;QACvB,YAAY,CAAC,SAAS,CAAC;QACvB,YAAY,CAAC,SAAS,CAAC;QACvB,YAAY,CAAC,SAAS,CAAC;QACvB,YAAY,CAAC,SAAS,CAAC;QACvB,YAAY,CAAC,SAAS,CAAC;QACvB,YAAY,CAAC,SAAS,CAAC;QACvB,YAAY,CAAC,SAAS,CAAC;KACxB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,cAAc,CAAC,CAAA;AAC3C,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,OAAO;QACL,IAAI,EAAE,YAAY,CAAC,kBAAkB,CAAC,IAAI,cAAc;QACxD,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC,IAAI,cAAc;QAC/C,IAAI,EAAE,YAAY,CAAC,eAAe,CAAC,IAAI,cAAc;QACrD,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,IAAI,aAAa;KAChD,CAAA;AACH,CAAC;AAuCD;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,MAAM,EACN,MAAM,EACN,KAAK,EAAE,UAAU,EACjB,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,QAAQ,EACR,KAAK,EACL,MAAM,EAAE,UAAU,EAClB,UAAU,GACM;IAChB,MAAM,MAAM,GAAG,EAAE,GAAG,kBAAkB,EAAE,GAAG,UAAU,EAAE,CAAA;IACvD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC3C,MAAM,KAAK,GAAG,UAAU,IAAI,QAAQ,CAAA;IACpC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAA;IACzD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACjD,MAAM,OAAO,GAAG,KAAK,EAAE,CAAA;IACvB,MAAM,OAAO,GAAG,KAAK,EAAE,CAAA;IACvB,MAAM,OAAO,GAAG,MAAM,CAAqB,IAAI,CAAC,CAAA;IAChD,MAAM,OAAO,GAAG,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAEvD,MAAM,OAAO,GAAG,CAAC,OAAe,EAAE,OAAe,EAAE,EAAE;QACnD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,qBAAqB,EAAE,CAAA;QACrD,IAAI,CAAC,IAAI;YAAE,OAAM;QACjB,SAAS,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;IACpE,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,CAAC,KAAkD,EAAE,EAAE;QACvE,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAA;QACtB,MAAM,KAAK,GAA2B;YACpC,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAC9C,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAC7C,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7C,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;YAC3C,IAAI,EAAE,CAAC;YACP,GAAG,EAAE,IAAI;SACV,CAAA;QACD,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACpC,KAAK,CAAC,cAAc,EAAE,CAAA;YACtB,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAE,CAAC,CAAA;QAC9B,CAAC;aAAM,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ;YAAE,SAAS,CAAC,IAAI,CAAC,CAAA;IACpD,CAAC,CAAA;IAED,MAAM,KAAK,GAAG,MAAM,IAAI,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACxE,MAAM,OAAO,GAAG,OAAO;QACrB,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACpF,CAAC,CAAC,EAAE,CAAA;IAEN,OAAO,CACL,MAAC,IAAI,IACH,MAAM,EAAC,QAAQ,EACf,MAAM,EAAE,CAAC,EACT,GAAG,EAAC,IAAI,EACR,KAAK,EAAC,MAAM,qBACK,OAAO,KACpB,UAAU,aAEd,MAAC,IAAI,IAAC,GAAG,EAAC,IAAI,aACZ,KAAC,IAAI,IAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAC,IAAI,EAAC,MAAM,EAAC,UAAU,YAC3C,KAAK,GACD,EACN,WAAW,CAAC,CAAC,CAAC,CACb,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,YACzB,WAAW,GACP,CACR,CAAC,CAAC,CAAC,IAAI,IACH,EAEN,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACnB,KAAC,MAAM,IAAC,QAAQ,EAAC,MAAM,EAAC,SAAS,EAAC,IAAI,EAAC,MAAM,EAAC,MAAM,YACjD,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACpB,MAAC,MAAM,IAAkB,UAAU,EAAC,QAAQ,EAAC,GAAG,EAAC,MAAM,aACrD,KAAC,IAAI,yBAEH,eAAe,EAAE,IAAI,CAAC,KAAc,EACpC,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAC5C,MAAM,EAAE,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAC1C,YAAY,EAAE,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,GACrD,EACF,MAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,aACzB,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAClC,KAXI,IAAI,CAAC,KAAK,CAYd,CACV,CAAC,GACK,CACV,CAAC,CAAC,CAAC,IAAI,EAER,MAAC,IAAI,IACH,GAAG,EAAE,OAAgB,EACrB,QAAQ,EAAC,UAAU,EACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU,IAAI,MAAM,EAC3B,QAAQ,EAAE,CAAC,KAAqD,EAAE,EAAE,CAClE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAEzD,0EAA0E;gBAC1E,IAAI,EAAC,KAAK,gBACE,GAAG,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,YAAY,EAAE,KAClF,CAAC,KAAK;oBACR,CAAC,CAAC;wBACE,QAAQ,EAAE,CAAC;wBACX,SAAS;wBACT,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC;wBAC7B,WAAW,EAAE,CAAC,KAA2C,EAAE,EAAE,CAC3D,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;wBACvC,YAAY,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC;qBACpC;oBACH,CAAC,CAAC;wBACE,UAAU,EAAE,IAAI;wBAChB,wEAAwE;wBACxE,GAAG,CAAC,OAAO,IAAI,EAAE,kBAAkB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;wBACzD,OAAO,EAAE,CAAC,KAAgE,EAAE,EAAE,CAC5E,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;qBACtF,CAAC,EACN,YAAY,EAAC,KAAK,EAClB,iBAAiB,EAAE;oBACjB,YAAY,EAAE,OAAO;oBACrB,YAAY,EAAE,OAAO;oBACrB,YAAY,EAAE,CAAC;oBACf,aAAa,EAAE,CAAC;iBACjB,aAEA,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAC1C,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAClB,MAAC,IAAI,yBAEH,aAAa,EAAC,MAAM,EACpB,QAAQ,EAAC,UAAU,EACnB,GAAG,EAAE,CAAC,KACF,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EACpF,eAAe,EAAC,UAAU,EAC1B,WAAW,EAAE,CAAC,EACd,WAAW,EAAC,SAAS,EACrB,YAAY,EAAC,KAAK,EAClB,iBAAiB,EAAC,MAAM,EACxB,eAAe,EAAC,IAAI,EACpB,GAAG,EAAC,IAAI,EACR,QAAQ,EAAC,KAAK,EACd,MAAM,EAAE,CAAC,aAET,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,YACzB,OAAO,CAAC,KAAK,GACT,EACN,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACzB,MAAC,MAAM,IAAiB,UAAU,EAAC,QAAQ,EAAC,GAAG,EAAC,IAAI,aAClD,KAAC,IAAI,IACH,eAAe,EAAE,GAAG,CAAC,KAAc,EACnC,KAAK,EAAC,MAAM,EACZ,MAAM,EAAE,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EACzC,YAAY,EAAE,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,GACpD,EACF,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,MAAM,EAAC,UAAU,YAC9B,GAAG,CAAC,KAAK,GACL,EACP,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAC,UAAU,EAAE,CAAC,YACvC,GAAG,CAAC,KAAK,GACL,KAZI,GAAG,CAAC,KAAK,CAab,CACV,CAAC,IACG,CACR,CAAC,CAAC,CAAC,IAAI,IACH,EAEN,KAAK,CAAC,CAAC,CAAC,KAAC,cAAc,iBAAW,QAAQ,YAAE,OAAO,GAAkB,CAAC,CAAC,CAAC,IAAI,EAE7E,MAAC,IAAI,IAAC,UAAU,EAAC,YAAY,EAAC,GAAG,EAAC,IAAI,aACpC,KAAC,MAAM,IACL,IAAI,EAAC,IAAI,EACT,OAAO,EAAC,OAAO;wBACf,2CAA2C;wBAC3C,UAAU,EAAC,KAAK,mBACD,SAAS,KACpB,CAAC,KAAK,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,EAC3C,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,YAEtC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,GACzC,EACR,SAAS,CAAC,CAAC,CAAC,CACX,KAAC,IAAI,IAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAC,MAAM,YAC7B,MAAC,KAAK,kBAAa,KAAK,EAAE,IAAI,EAAC,IAAI,EAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,aACpF,KAAC,KAAK,CAAC,MAAM,cACX,KAAC,KAAK,CAAC,GAAG,cACP,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAChC,KAAC,KAAK,CAAC,IAAI,IAAc,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,YAC/D,MAAM,IADQ,MAAM,CAEV,CACd,CAAC,GACQ,GACC,EACf,KAAC,KAAK,CAAC,IAAI,cACR,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAC1B,KAAC,KAAK,CAAC,GAAG,cACP,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CACpB,KAAC,KAAK,CAAC,IAAI,IAAS,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,YAC1D,IAAI,IADU,CAAC,CAEL,CACd,CAAC,IALY,CAAC,CAML,CACb,CAAC,GACS,IACP,GACH,CACR,CAAC,CAAC,CAAC,IAAI,IACH,IACF,CACR,CAAA;AACH,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { type ChartLabels, type ChartSeries } from './ChartFrame';
2
+ export interface LinePlotProps {
3
+ title: string;
4
+ description?: string;
5
+ /** One object per x position, e.g. `{ month: 'Jan', reached: 1200 }`. */
6
+ data: Record<string, unknown>[];
7
+ /** The field holding each row's x label. */
8
+ index: string;
9
+ /** Heading of the x column in the table view. Default: `index`. */
10
+ indexLabel?: string;
11
+ /** The numeric fields to plot, in color order. */
12
+ series: ChartSeries[];
13
+ /** Height in pixels, including the axes. Default: 240. */
14
+ height?: number;
15
+ width?: number;
16
+ /** Formats values in the tooltip and table. Axis ticks are compact (1.2K). */
17
+ valueFormatter?: (value: number) => string;
18
+ /** Plot area always starts at zero. Default: true for areas, false for lines. */
19
+ startAtZero?: boolean;
20
+ /**
21
+ * Color of the surface the chart sits on, for the ring around markers.
22
+ * Default: `$background`; use `$card` inside a Card.
23
+ */
24
+ surface?: string;
25
+ labels?: Partial<ChartLabels>;
26
+ }
27
+ /** Shared by LineChart and AreaChart. */
28
+ export declare function LinePlot({ title, description, data, index, indexLabel, series, height, width, valueFormatter, startAtZero, surface, labels, area, stacked, }: LinePlotProps & {
29
+ area?: boolean;
30
+ stacked?: boolean;
31
+ }): import("react").JSX.Element;
32
+ //# sourceMappingURL=LinePlot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinePlot.d.ts","sourceRoot":"","sources":["../../src/charts/LinePlot.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,WAAW,EAGjB,MAAM,cAAc,CAAA;AAKrB,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAC/B,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAA;IACb,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,kDAAkD;IAClD,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAC1C,iFAAiF;IACjF,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;CAC9B;AAED,yCAAyC;AACzC,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,WAAW,EACX,IAAI,EACJ,KAAK,EACL,UAAkB,EAClB,MAAM,EACN,MAAY,EACZ,KAAK,EACL,cAA2B,EAC3B,WAAW,EACX,OAAuB,EACvB,MAAM,EACN,IAAY,EACZ,OAAe,GAChB,EAAE,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,+BAiKvD"}
@@ -0,0 +1,93 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CategoryLabels, ValueGrid, cartesianPadding } from './cartesian';
3
+ import { ChartFrame, useChartColors, useChartInk, } from './ChartFrame';
4
+ import { formatFull, numberAt } from './format';
5
+ import { linearScale, niceTicks } from './scale';
6
+ import { Circle, G, Line, Path, Svg } from './svg';
7
+ /** Shared by LineChart and AreaChart. */
8
+ export function LinePlot({ title, description, data, index, indexLabel = index, series, height = 240, width, valueFormatter = formatFull, startAtZero, surface = '$background', labels, area = false, stacked = false, }) {
9
+ const colors = useChartColors();
10
+ const ink = useChartInk(surface);
11
+ const categories = data.map((row) => String(row[index] ?? ''));
12
+ const values = data.map((row) => series.map((s) => numberAt(row, s.key)));
13
+ // Stacked areas draw each series on top of the ones before it.
14
+ const tops = values.map((row) => {
15
+ let sum = 0;
16
+ return row.map((v) => (v == null ? null : stacked ? (sum += v) : v));
17
+ });
18
+ const all = tops.flat().filter((v) => v != null);
19
+ const zero = startAtZero ?? area;
20
+ const ticks = niceTicks(zero ? Math.min(0, ...all) : Math.min(...all), zero ? Math.max(0, ...all) : Math.max(...all));
21
+ const pad = cartesianPadding(ticks);
22
+ const n = data.length;
23
+ const scales = (w) => {
24
+ const step = (w - pad.left - pad.right) / Math.max(1, n);
25
+ return {
26
+ step,
27
+ x: (i) => pad.left + (i + 0.5) * step,
28
+ y: linearScale([ticks[0], ticks.at(-1)], [height - pad.bottom, pad.top]),
29
+ };
30
+ };
31
+ const format = (value) => (value == null ? '–' : valueFormatter(value));
32
+ const shape = area ? 'square' : 'line';
33
+ return (_jsx(ChartFrame, { title: title, description: description, legend: series.length > 1
34
+ ? series.map((s, i) => ({ label: s.label, color: colors[i % 8], shape }))
35
+ : [], height: height, width: width, count: n, hitTest: (x, _y, w) => {
36
+ const { step } = scales(w);
37
+ const i = Math.round((x - pad.left) / step - 0.5);
38
+ return Math.max(0, Math.min(n - 1, i));
39
+ }, anchor: (i, w) => ({ x: scales(w).x(i), y: pad.top }), tooltip: (i) => ({
40
+ title: categories[i],
41
+ rows: series.map((s, j) => ({
42
+ label: s.label,
43
+ value: format(values[i][j]),
44
+ color: colors[j % 8],
45
+ shape,
46
+ })),
47
+ }), table: {
48
+ columns: [indexLabel, ...series.map((s) => s.label)],
49
+ rows: data.map((_, i) => [categories[i], ...values[i].map(format)]),
50
+ numeric: [false, ...series.map(() => true)],
51
+ }, labels: labels, children: (w, active) => {
52
+ const { x, y, step } = scales(w);
53
+ const base = (i, j) => stacked && j > 0 ? (tops[i][j - 1] ?? 0) : Math.max(ticks[0], 0);
54
+ return (_jsxs(Svg, { width: w, height: height, children: [_jsx(ValueGrid, { ticks: ticks, y: y, left: pad.left, right: w - pad.right, ink: ink }), _jsx(CategoryLabels, { labels: categories, x: x, y: height - pad.bottom + 4, available: step, ink: ink }), active != null ? (_jsx(Line, { x1: x(active), x2: x(active), y1: pad.top, y2: height - pad.bottom, stroke: ink.axis, strokeWidth: 1 })) : null, series.map((s, j) => {
55
+ const color = colors[j % 8];
56
+ // A missing value breaks the line instead of dropping to zero.
57
+ const runs = [[]];
58
+ tops.forEach((row, i) => {
59
+ if (row[j] == null)
60
+ runs.push([]);
61
+ else
62
+ runs.at(-1).push(i);
63
+ });
64
+ return (_jsx(G, { children: runs
65
+ .filter((run) => run.length > 0)
66
+ .map((run) => {
67
+ const line = run
68
+ .map((i, k) => `${k === 0 ? 'M' : 'L'}${x(i)},${y(tops[i][j])}`)
69
+ .join('');
70
+ const fill = area
71
+ ? `${line}${[...run]
72
+ .reverse()
73
+ .map((i) => `L${x(i)},${y(base(i, j))}`)
74
+ .join('')}Z`
75
+ : null;
76
+ // A lone value between gaps has no line to draw: show it as a dot.
77
+ if (run.length === 1) {
78
+ const i = run[0];
79
+ return _jsx(Circle, { cx: x(i), cy: y(tops[i][j]), r: 3, fill: color }, i);
80
+ }
81
+ return (_jsxs(G, { children: [fill ? _jsx(Path, { d: fill, fill: color, fillOpacity: 0.1 }) : null, _jsx(Path, { d: line, fill: "none", stroke: color, strokeWidth: 2, strokeLinejoin: "round", strokeLinecap: "round" })] }, run[0]));
82
+ }) }, s.key));
83
+ }), series.map((s, j) => {
84
+ const color = colors[j % 8];
85
+ const lastIndex = tops.reduce((last, row, i) => (row[j] != null ? i : last), -1);
86
+ const points = new Set([lastIndex, ...(active != null ? [active] : [])]);
87
+ return [...points]
88
+ .filter((i) => i >= 0 && tops[i]?.[j] != null)
89
+ .map((i) => (_jsx(Circle, { cx: x(i), cy: y(tops[i][j]), r: 4, fill: color, stroke: ink.surface, strokeWidth: 2 }, `${s.key}-${i}`)));
90
+ })] }));
91
+ } }));
92
+ }
93
+ //# sourceMappingURL=LinePlot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinePlot.js","sourceRoot":"","sources":["../../src/charts/LinePlot.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /** Space around the plot for axis labels. */
2
+ export declare function cartesianPadding(ticks: number[], format?: (value: number) => string): {
3
+ top: number;
4
+ right: number;
5
+ bottom: number;
6
+ left: number;
7
+ };
8
+ /** Horizontal gridlines with value labels on the left. */
9
+ export declare function ValueGrid({ ticks, y, left, right, ink, format, }: {
10
+ ticks: number[];
11
+ y: (value: number) => number;
12
+ left: number;
13
+ right: number;
14
+ ink: {
15
+ text: string;
16
+ grid: string;
17
+ axis: string;
18
+ };
19
+ format?: (value: number) => string;
20
+ }): import("react").JSX.Element;
21
+ /**
22
+ * Category labels under the plot. When they would overlap, only every nth
23
+ * is drawn (the first and the rest in steps), so none collide.
24
+ */
25
+ export declare function CategoryLabels({ labels, x, y, available, ink, }: {
26
+ labels: string[];
27
+ x: (index: number) => number;
28
+ y: number;
29
+ /** Width each label may use before thinning kicks in. */
30
+ available: number;
31
+ ink: {
32
+ text: string;
33
+ };
34
+ }): import("react").JSX.Element;
35
+ //# sourceMappingURL=cartesian.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cartesian.d.ts","sourceRoot":"","sources":["../../src/charts/cartesian.tsx"],"names":[],"mappings":"AAGA,6CAA6C;AAC7C,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,GAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAsB;;;;;EAKlD;AAED,0DAA0D;AAC1D,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,CAAC,EACD,IAAI,EACJ,KAAK,EACL,GAAG,EACH,MAAsB,GACvB,EAAE;IACD,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACjD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;CACnC,+BA6BA;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,CAAC,EACD,CAAC,EACD,SAAS,EACT,GAAG,GACJ,EAAE;IACD,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAC5B,CAAC,EAAE,MAAM,CAAA;IACT,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CACtB,+BAsBA"}
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Line, SvgText } from './svg';
3
+ import { formatCompact } from './format';
4
+ /** Space around the plot for axis labels. */
5
+ export function cartesianPadding(ticks, format = formatCompact) {
6
+ // About 7px per character of the widest tick label at 12px.
7
+ const labelWidth = Math.max(...ticks.map((t) => format(t).length)) * 7;
8
+ return { top: 8, right: 8, bottom: 24, left: labelWidth + 12 };
9
+ }
10
+ /** Horizontal gridlines with value labels on the left. */
11
+ export function ValueGrid({ ticks, y, left, right, ink, format = formatCompact, }) {
12
+ return (_jsxs(_Fragment, { children: [ticks.map((tick) => (_jsx(Line, { x1: left, x2: right, y1: y(tick), y2: y(tick), stroke: tick === 0 ? ink.axis : ink.grid, strokeWidth: 1 }, `grid-${tick}`))), ticks.map((tick) => (_jsx(SvgText, { x: left - 8, y: y(tick), dy: "0.35em", fill: ink.text, fontSize: 12, textAnchor: "end", children: format(tick) }, `label-${tick}`)))] }));
13
+ }
14
+ /**
15
+ * Category labels under the plot. When they would overlap, only every nth
16
+ * is drawn (the first and the rest in steps), so none collide.
17
+ */
18
+ export function CategoryLabels({ labels, x, y, available, ink, }) {
19
+ const widest = Math.max(1, ...labels.map((l) => l.length)) * 7 + 8;
20
+ const step = Math.max(1, Math.ceil(widest / Math.max(1, available)));
21
+ return (_jsx(_Fragment, { children: labels.map((label, index) => index % step === 0 ? (_jsx(SvgText, { x: x(index), y: y, dy: "0.9em", fill: ink.text, fontSize: 12, textAnchor: "middle", children: label }, `${label}-${index}`)) : null) }));
22
+ }
23
+ //# sourceMappingURL=cartesian.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cartesian.js","sourceRoot":"","sources":["../../src/charts/cartesian.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,6CAA6C;AAC7C,MAAM,UAAU,gBAAgB,CAC9B,KAAe,EACf,SAAoC,aAAa;IAEjD,4DAA4D;IAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAA;IACtE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,GAAG,EAAE,EAAE,CAAA;AAChE,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,SAAS,CAAC,EACxB,KAAK,EACL,CAAC,EACD,IAAI,EACJ,KAAK,EACL,GAAG,EACH,MAAM,GAAG,aAAa,GAQvB;IACC,OAAO,CACL,8BACG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACnB,KAAC,IAAI,IAEH,EAAE,EAAE,IAAI,EACR,EAAE,EAAE,KAAK,EACT,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EACX,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EACX,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EACxC,WAAW,EAAE,CAAC,IANT,QAAQ,IAAI,EAAE,CAOnB,CACH,CAAC,EACD,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACnB,KAAC,OAAO,IAEN,CAAC,EAAE,IAAI,GAAG,CAAC,EACX,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EACV,EAAE,EAAC,QAAQ,EACX,IAAI,EAAE,GAAG,CAAC,IAAI,EACd,QAAQ,EAAE,EAAE,EACZ,UAAU,EAAC,KAAK,YAEf,MAAM,CAAC,IAAI,CAAC,IARR,SAAS,IAAI,EAAE,CASZ,CACX,CAAC,IACD,CACJ,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,EAC7B,MAAM,EACN,CAAC,EACD,CAAC,EACD,SAAS,EACT,GAAG,GAQJ;IACC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAClE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACpE,OAAO,CACL,4BACG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAC3B,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CACnB,KAAC,OAAO,IAEN,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EACX,CAAC,EAAE,CAAC,EACJ,EAAE,EAAC,OAAO,EACV,IAAI,EAAE,GAAG,CAAC,IAAI,EACd,QAAQ,EAAE,EAAE,EACZ,UAAU,EAAC,QAAQ,YAElB,KAAK,IARD,GAAG,KAAK,IAAI,KAAK,EAAE,CAShB,CACX,CAAC,CAAC,CAAC,IAAI,CACT,GACA,CACJ,CAAA;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ /** Axis ticks: 1.2K, 3.4M. */
2
+ export declare const formatCompact: (value: number) => string;
3
+ /** Tooltips and the table: 1,234.5. */
4
+ export declare const formatFull: (value: number) => string;
5
+ /** Reads a numeric field; anything else counts as missing. */
6
+ export declare function numberAt(row: Record<string, unknown>, key: string): number | null;
7
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/charts/format.ts"],"names":[],"mappings":"AAGA,8BAA8B;AAC9B,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,WAA0B,CAAA;AAErE,uCAAuC;AACvC,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,WAAuB,CAAA;AAE/D,8DAA8D;AAC9D,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGjF"}
@@ -0,0 +1,12 @@
1
+ const compact = new Intl.NumberFormat('en-US', { notation: 'compact', maximumFractionDigits: 1 });
2
+ const full = new Intl.NumberFormat('en-US', { maximumFractionDigits: 2 });
3
+ /** Axis ticks: 1.2K, 3.4M. */
4
+ export const formatCompact = (value) => compact.format(value);
5
+ /** Tooltips and the table: 1,234.5. */
6
+ export const formatFull = (value) => full.format(value);
7
+ /** Reads a numeric field; anything else counts as missing. */
8
+ export function numberAt(row, key) {
9
+ const value = row[key];
10
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
11
+ }
12
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/charts/format.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,qBAAqB,EAAE,CAAC,EAAE,CAAC,CAAA;AACjG,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,qBAAqB,EAAE,CAAC,EAAE,CAAC,CAAA;AAEzE,8BAA8B;AAC9B,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAErE,uCAAuC;AACvC,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAE/D,8DAA8D;AAC9D,MAAM,UAAU,QAAQ,CAAC,GAA4B,EAAE,GAAW;IAChE,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;IACtB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;AAC3E,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { ChartFrame, defaultChartLabels, useChartColors, useChartInk, type ChartFrameProps, type ChartLabels, type ChartSeries, type LegendItem, type TooltipContent, } from './ChartFrame';
2
+ export { CategoryLabels, ValueGrid, cartesianPadding } from './cartesian';
3
+ export { LinePlot, type LinePlotProps } from './LinePlot';
4
+ export { formatCompact, formatFull, numberAt } from './format';
5
+ export { arcPath, bandScale, barPath, linearScale, niceTicks } from './scale';
6
+ export { Circle, G, Line, Path, Rect, Svg, SvgText } from './svg';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/charts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,cAAc,GACpB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACzE,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAC7E,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA"}
@@ -0,0 +1,7 @@
1
+ export { ChartFrame, defaultChartLabels, useChartColors, useChartInk, } from './ChartFrame';
2
+ export { CategoryLabels, ValueGrid, cartesianPadding } from './cartesian';
3
+ export { LinePlot } from './LinePlot';
4
+ export { formatCompact, formatFull, numberAt } from './format';
5
+ export { arcPath, bandScale, barPath, linearScale, niceTicks } from './scale';
6
+ export { Circle, G, Line, Path, Rect, Svg, SvgText } from './svg';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/charts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,WAAW,GAMZ,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACzE,OAAO,EAAE,QAAQ,EAAsB,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAC7E,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA"}
@@ -0,0 +1,20 @@
1
+ /** Clean, round tick values ("nice numbers") covering [min, max]. */
2
+ export declare function niceTicks(min: number, max: number, count?: number): number[];
3
+ /** Maps a value in [d0, d1] to [r0, r1]. */
4
+ export declare function linearScale([d0, d1]: [number, number], [r0, r1]: [number, number]): (value: number) => number;
5
+ /**
6
+ * Splits [start, end] into `count` equal bands; `band(i)` is the start of
7
+ * band i and `bandwidth` its size.
8
+ */
9
+ export declare function bandScale(count: number, [start, end]: [number, number]): {
10
+ band: (index: number) => number;
11
+ bandwidth: number;
12
+ };
13
+ /**
14
+ * A rectangle with rounded corners on its data end only (the end away from
15
+ * the baseline), as an SVG path. `direction` is where the data end points.
16
+ */
17
+ export declare function barPath(x: number, y: number, width: number, height: number, radius: number, direction: 'up' | 'down' | 'right' | 'left'): string;
18
+ /** A pie or donut slice as an SVG path; angles in radians, 0 at 12 o'clock. */
19
+ export declare function arcPath(cx: number, cy: number, outer: number, inner: number, start: number, end: number): string;
20
+ //# sourceMappingURL=scale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scale.d.ts","sourceRoot":"","sources":["../../src/charts/scale.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,MAAM,EAAE,CAavE;AAUD,4CAA4C;AAC5C,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,IAExE,OAAO,MAAM,YACtB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;kBAE9C,MAAM;;EAC9B;AAED;;;GAGG;AACH,wBAAgB,OAAO,CACrB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAC1C,MAAM,CAeR;AAED,+EAA+E;AAC/E,wBAAgB,OAAO,CACrB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GACV,MAAM,CAeR"}