nanoplot 0.0.16 → 0.0.18

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 (89) hide show
  1. package/bun.lockb +0 -0
  2. package/dist/src/app/bar-graph/components/Rect.d.ts +10 -0
  3. package/dist/src/app/bar-graph/components/Rect.jsx +27 -0
  4. package/dist/src/components/Bars/Bars.d.ts +9 -0
  5. package/dist/src/components/Bars/Bars.jsx +18 -0
  6. package/dist/src/components/Bars/components/BarsVerticalLoading.d.ts +1 -0
  7. package/dist/src/components/Bars/components/BarsVerticalLoading.jsx +19 -0
  8. package/dist/src/components/Bars/components/HorizontalBars.d.ts +8 -0
  9. package/dist/src/components/Bars/components/HorizontalBars.jsx +47 -0
  10. package/dist/src/components/Bars/components/VerticalBars.d.ts +9 -0
  11. package/dist/src/components/Bars/components/VerticalBars.jsx +51 -0
  12. package/dist/src/components/Graph/Graph.d.ts +24 -0
  13. package/dist/src/components/Graph/Graph.jsx +60 -0
  14. package/dist/src/components/GridLines/GridLines.d.ts +9 -0
  15. package/dist/src/components/GridLines/GridLines.jsx +13 -0
  16. package/dist/src/components/Legend/Legend.d.ts +45 -0
  17. package/dist/src/components/Legend/Legend.jsx +37 -0
  18. package/dist/src/components/LinearGradient/LinearGradient.d.ts +6 -0
  19. package/dist/src/components/LinearGradient/LinearGradient.jsx +52 -0
  20. package/dist/src/components/Lines/Lines.d.ts +17 -0
  21. package/dist/src/components/Lines/Lines.jsx +53 -0
  22. package/dist/src/components/Lines/components/LinesLoading.d.ts +2 -0
  23. package/dist/src/components/Lines/components/LinesLoading.jsx +10 -0
  24. package/dist/src/components/Lines/components/LinesTooltip.d.ts +10 -0
  25. package/dist/src/components/Lines/components/LinesTooltip.jsx +109 -0
  26. package/dist/src/components/Overlay/Overlay.d.ts +9 -0
  27. package/dist/src/components/Overlay/Overlay.jsx +39 -0
  28. package/dist/src/components/Pie/Pie.d.ts +11 -0
  29. package/dist/src/components/Pie/Pie.jsx +105 -0
  30. package/dist/src/components/Pie/components/PieEmpty.d.ts +8 -0
  31. package/dist/src/components/Pie/components/PieEmpty.jsx +21 -0
  32. package/dist/src/components/Pie/components/PieLoading.d.ts +9 -0
  33. package/dist/src/components/Pie/components/PieLoading.jsx +19 -0
  34. package/dist/src/components/Radar/Radar.d.ts +9 -0
  35. package/dist/src/components/Radar/Radar.jsx +160 -0
  36. package/dist/src/components/Radar/components/RadarSkeleton.d.ts +8 -0
  37. package/dist/src/components/Radar/components/RadarSkeleton.jsx +13 -0
  38. package/dist/src/components/Scatter/Scatter.d.ts +8 -0
  39. package/dist/src/components/Scatter/Scatter.jsx +30 -0
  40. package/dist/src/components/Scatter/components/ScatterLoading.d.ts +6 -0
  41. package/dist/src/components/Scatter/components/ScatterLoading.jsx +29 -0
  42. package/dist/src/components/Sunburst/Sunburst.d.ts +21 -0
  43. package/dist/src/components/Sunburst/Sunburst.jsx +204 -0
  44. package/dist/src/components/Sunburst/SunburstLoading.d.ts +2 -0
  45. package/dist/src/components/Sunburst/SunburstLoading.jsx +11 -0
  46. package/dist/src/components/Tooltip/Popup.d.ts +9 -0
  47. package/dist/src/components/Tooltip/Popup.jsx +94 -0
  48. package/dist/src/components/Worldmap/Worldmap.d.ts +329 -0
  49. package/dist/src/components/Worldmap/Worldmap.jsx +33 -0
  50. package/dist/src/components/XAxis/XAxis.d.ts +53 -0
  51. package/dist/src/components/XAxis/XAxis.jsx +39 -0
  52. package/dist/src/components/YAxis/YAxis.d.ts +51 -0
  53. package/dist/src/components/YAxis/YAxis.jsx +27 -0
  54. package/dist/src/export/index.d.ts +14 -0
  55. package/dist/src/export/index.jsx +13 -0
  56. package/dist/src/hooks/use-graph/use-graph.d.ts +58 -0
  57. package/dist/src/hooks/use-graph/use-graph.jsx +7 -0
  58. package/dist/src/hooks/use-mouse-coordinates.d.ts +8 -0
  59. package/dist/src/hooks/use-mouse-coordinates.js +41 -0
  60. package/dist/src/hooks/use-stateful-ref.d.ts +2 -0
  61. package/dist/src/hooks/use-stateful-ref.js +11 -0
  62. package/dist/src/hooks/use-tether.d.ts +38 -0
  63. package/dist/src/hooks/use-tether.js +151 -0
  64. package/dist/src/utils/children/children.d.ts +5 -0
  65. package/dist/src/utils/children/children.js +16 -0
  66. package/dist/src/utils/color/color.d.ts +4 -0
  67. package/dist/src/utils/color/color.js +92 -0
  68. package/dist/src/utils/coordinates/coordinates.d.ts +15 -0
  69. package/dist/src/utils/coordinates/coordinates.js +67 -0
  70. package/dist/src/utils/countries.d.ts +181 -0
  71. package/dist/src/utils/countries.js +181 -0
  72. package/dist/src/utils/cx/cx.d.ts +3 -0
  73. package/dist/src/utils/cx/cx.js +11 -0
  74. package/dist/src/utils/domain/date-domain.d.ts +75 -0
  75. package/dist/src/utils/domain/date-domain.js +140 -0
  76. package/dist/src/utils/domain/domain.d.ts +20 -0
  77. package/dist/src/utils/domain/domain.js +253 -0
  78. package/dist/src/utils/graph/graph.d.ts +5 -0
  79. package/dist/src/utils/graph/graph.js +9 -0
  80. package/dist/src/utils/math/math.d.ts +5 -0
  81. package/dist/src/utils/math/math.js +12 -0
  82. package/dist/src/utils/object/object.d.ts +3 -0
  83. package/dist/src/utils/object/object.js +11 -0
  84. package/dist/src/utils/path/curve.d.ts +22 -0
  85. package/dist/src/utils/path/curve.js +111 -0
  86. package/dist/src/utils/path/path.d.ts +31 -0
  87. package/dist/src/utils/path/path.js +168 -0
  88. package/package.json +101 -101
  89. package/@types/global.d.ts +0 -5
package/bun.lockb CHANGED
Binary file
@@ -0,0 +1,10 @@
1
+ import { JSX } from "react";
2
+ type Props = JSX.IntrinsicElements["path"] & {
3
+ x1: number;
4
+ x2: number;
5
+ y1: number;
6
+ y2: number;
7
+ radius?: number;
8
+ };
9
+ export declare const Rect: ({ x1, x2, y1, y2, radius, ...rest }: Props) => JSX.Element;
10
+ export {};
@@ -0,0 +1,27 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import React, { useId } from "react";
13
+ import { LinearGradient } from "@/components/LinearGradient/LinearGradient";
14
+ import { PathUtils } from "@/utils/path/path";
15
+ export const Rect = (_a) => {
16
+ var _b;
17
+ var { x1, x2, y1, y2, radius } = _a, rest = __rest(_a, ["x1", "x2", "y1", "y2", "radius"]);
18
+ const id = useId();
19
+ const isFillGradient = (_b = rest.fill) === null || _b === void 0 ? void 0 : _b.includes("gradient");
20
+ const path = radius
21
+ ? PathUtils.borderRadius({ x: x1, y: y1 }, { x: x2, y: y2 }, radius)
22
+ : `M ${x1} ${y1} L ${x1} ${y2} L ${x2} ${y2} L ${x2} ${y1}`;
23
+ return (<>
24
+ {isFillGradient && rest.fill && <LinearGradient id={id} gradient={rest.fill}/>}
25
+ <path fill={isFillGradient ? `url(#${id})` : rest.fill} stroke={rest.stroke} d={path} vectorEffect={"non-scaling-stroke"} strokeWidth={1.5}/>
26
+ </>);
27
+ };
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ type ComponentProps = {
3
+ horizontal?: boolean;
4
+ loading?: boolean;
5
+ size?: number;
6
+ radius?: number;
7
+ };
8
+ export declare const Bars: ({ horizontal, loading, ...props }: ComponentProps) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,18 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import React from "react";
13
+ import { VerticalBars } from "@/components/Bars/components/VerticalBars";
14
+ import { HorizontalBars } from "./components/HorizontalBars";
15
+ export const Bars = (_a) => {
16
+ var { horizontal, loading } = _a, props = __rest(_a, ["horizontal", "loading"]);
17
+ return horizontal ? <HorizontalBars {...props}/> : <VerticalBars loading={loading} {...props}/>;
18
+ };
@@ -0,0 +1 @@
1
+ export declare const BarsVerticalLoading: () => import("react").JSX.Element;
@@ -0,0 +1,19 @@
1
+ import { cx } from "@/utils/cx/cx";
2
+ import { useGraph } from "@/hooks/use-graph/use-graph";
3
+ import { useId } from "react";
4
+ export const BarsVerticalLoading = () => {
5
+ const maskId = useId();
6
+ const { viewbox } = useGraph();
7
+ const CX = viewbox.x / 2;
8
+ const CY = viewbox.y / 2;
9
+ const BAR_GAP = 20;
10
+ const BAR_WIDTH = viewbox.x * 0.08;
11
+ return (<svg id="loading" role="status" aria-busy={true} viewBox={`0 0 ${viewbox.x} ${viewbox.y}`} className={cx("[grid-area:graph] h-full w-full")} preserveAspectRatio={"none"}>
12
+ <path vectorEffect={"non-scaling-stroke"} d={`
13
+ M${CX - BAR_WIDTH - BAR_GAP - BAR_WIDTH / 2} ${viewbox.y} L${CX - BAR_WIDTH - BAR_GAP - BAR_WIDTH / 2} ${(viewbox.y / 30) * 20} L${CX - BAR_WIDTH - BAR_GAP + BAR_WIDTH - BAR_WIDTH / 2} ${(viewbox.y / 30) * 20} L${CX - BAR_WIDTH - BAR_GAP + BAR_WIDTH - BAR_WIDTH / 2} ${viewbox.y}
14
+ M ${CX - BAR_WIDTH / 2} ${viewbox.y} L${CX - BAR_WIDTH / 2} ${(viewbox.y / 30) * 10} L${CX + BAR_WIDTH - BAR_WIDTH / 2} ${(viewbox.y / 30) * 10} L${CX + BAR_WIDTH - BAR_WIDTH / 2} ${viewbox.y}
15
+ M${BAR_GAP + CX + BAR_WIDTH - BAR_WIDTH / 2} ${viewbox.y} L${BAR_GAP + CX + BAR_WIDTH - BAR_WIDTH / 2} ${(viewbox.y / 30) * 16} L${BAR_GAP + CX + 2 * BAR_WIDTH - BAR_WIDTH / 2} ${(viewbox.y / 30) * 16} L${BAR_GAP + CX + 2 * BAR_WIDTH - BAR_WIDTH / 2} ${viewbox.y}`} className={"[filter:brightness(300%)] dark:[filter:brightness(100%)]"} mask={`url(#${maskId})`}>
16
+ <animate attributeName="fill" values="#2d2d2d; #3c3c3c; #2d2d2d; #2d2d2d; " dur="2s" repeatCount="indefinite"/>
17
+ </path>
18
+ </svg>);
19
+ };
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ type Props = React.SVGAttributes<SVGSVGElement> & {
3
+ children?: React.ReactNode;
4
+ size?: number;
5
+ radius?: number;
6
+ };
7
+ export declare const HorizontalBars: ({ children, size, radius, className }: Props) => React.JSX.Element | null;
8
+ export {};
@@ -0,0 +1,47 @@
1
+ import { ColorUtils } from "@/export";
2
+ import { useGraph } from "@/hooks/use-graph/use-graph";
3
+ import { CoordinatesUtils } from "@/utils/coordinates/coordinates";
4
+ import { cx } from "@/utils/cx/cx";
5
+ import { GraphUtils } from "@/utils/graph/graph";
6
+ import React from "react";
7
+ import { PathUtils } from "@/utils/path/path";
8
+ export const HorizontalBars = ({ children, size = 30, radius = 0, className }) => {
9
+ const context = useGraph();
10
+ if (!GraphUtils.isXYData(context.data))
11
+ return null;
12
+ const xForValue = CoordinatesUtils.xCoordinateFor(context);
13
+ const yForValue = CoordinatesUtils.yCoordinateFor(context);
14
+ const bars = context.data.map((bar, i, bars) => {
15
+ var _a, _b, _c, _d;
16
+ return Object.assign(Object.assign({}, bar), { id: (_a = bar.id) !== null && _a !== void 0 ? _a : bar.name, stroke: (_b = bar.stroke) !== null && _b !== void 0 ? _b : ColorUtils.colorFor(i, bars.length), fill: bar.fill === true ? ((_c = bar.stroke) !== null && _c !== void 0 ? _c : ColorUtils.colorFor(i, bars.length)) : bar.fill, bar: (_d = bar.group) !== null && _d !== void 0 ? _d : bar.name, data: bar.data.map((xy) => ({
17
+ x: xForValue(xy.x),
18
+ y: yForValue(xy.y),
19
+ })) });
20
+ });
21
+ const barGap = context.viewbox.x / 100; // 16% gap
22
+ const barHeight = Math.floor(((context.viewbox.y - barGap) * size) / 1000);
23
+ const groups = [...new Set(bars.map((bar) => bar.group))];
24
+ return (<svg viewBox={`0 0 ${context.viewbox.x} ${context.viewbox.y}`} className={cx("[grid-area:graph] h-full w-full", className)} preserveAspectRatio={"none"}>
25
+ {groups === null || groups === void 0 ? void 0 : groups.map((group, g) => {
26
+ const groupBars = bars.filter((b) => b.group === group);
27
+ const coordinate = [];
28
+ return groupBars.map((bar, index) => {
29
+ var _a;
30
+ if (bar.group === group)
31
+ return (_a = bar.data) === null || _a === void 0 ? void 0 : _a.map((xy, idx) => {
32
+ const y1 = xy.y + barHeight * g - barHeight * (groups.length / 2);
33
+ const y2 = y1 + barHeight;
34
+ const x1 = index === 0 ? 0 : coordinate[idx];
35
+ const x2 = index === 0 ? xy.x : coordinate[idx] + (0 + xy.x);
36
+ const candleRadius = groupBars.length === index + 1
37
+ ? PathUtils.borderRadius({ x: x1, y: y1 }, { x: x2, y: y2 }, radius, true)
38
+ : `M ${x1} ${y1} L ${x1} ${y2} L ${x2} ${y2} L ${x2} ${y1}`;
39
+ // recorde the combined x coordinate (use for next stacked bar)
40
+ coordinate[idx] = index === 0 ? xy.x : coordinate[idx] + xy.x;
41
+ return (<path key={idx + index + xy.y + xy.x} d={candleRadius} fill={bar.stroke} stroke={bar.stroke} vectorEffect={"non-scaling-stroke"} strokeWidth={1.5}/>);
42
+ });
43
+ });
44
+ })}
45
+ {children}
46
+ </svg>);
47
+ };
@@ -0,0 +1,9 @@
1
+ import React, { ReactNode } from "react";
2
+ type Props = React.SVGAttributes<SVGSVGElement> & {
3
+ children?: ReactNode;
4
+ loading?: boolean;
5
+ size?: number;
6
+ radius?: number;
7
+ };
8
+ export declare const VerticalBars: ({ children, size, radius, className, loading }: Props) => React.JSX.Element | null;
9
+ export {};
@@ -0,0 +1,51 @@
1
+ import React from "react";
2
+ import { CoordinatesUtils } from "@/utils/coordinates/coordinates";
3
+ import { GraphUtils } from "@/utils/graph/graph";
4
+ import { ColorUtils } from "@/utils/color/color";
5
+ import { cx } from "@/utils/cx/cx";
6
+ import { useGraph } from "@/hooks/use-graph/use-graph";
7
+ import { BarsVerticalLoading } from "./BarsVerticalLoading";
8
+ import { Rect } from "@/app/bar-graph/components/Rect";
9
+ export const VerticalBars = ({ children, size = 30, radius = 0, className, loading }) => {
10
+ const context = useGraph();
11
+ if (!GraphUtils.isXYData(context.data))
12
+ return null;
13
+ const xForValue = CoordinatesUtils.xCoordinateFor(context);
14
+ const yForValue = CoordinatesUtils.yCoordinateFor(context);
15
+ const bars = context.data.map((bar, i, bars) => {
16
+ var _a, _b, _c, _d, _e, _f;
17
+ return Object.assign(Object.assign({}, bar), { id: (_a = bar.id) !== null && _a !== void 0 ? _a : bar.name, group: (_c = (_b = bar.group) !== null && _b !== void 0 ? _b : bar.id) !== null && _c !== void 0 ? _c : bar.name, stroke: (_d = bar.stroke) !== null && _d !== void 0 ? _d : ColorUtils.colorFor(i, bars.length), fill: bar.fill === true ? ((_e = bar.stroke) !== null && _e !== void 0 ? _e : ColorUtils.colorFor(i, bars.length)) : bar.fill, bar: (_f = bar.group) !== null && _f !== void 0 ? _f : bar.name, data: bar.data.map((xy) => ({
18
+ x: xForValue(xy.x),
19
+ y: yForValue(xy.y),
20
+ })) });
21
+ });
22
+ // stacked AND unstacked bars is the same code path.
23
+ // always setting a group (which is how you stack).
24
+ // and because group is defaulted to id or name stacks will be commonly 1/1
25
+ // if consumers of the library use 'group' it will be stacked for members of that group.
26
+ const barGap = context.viewbox.x / 100; // 16% gap
27
+ const barWidth = Math.floor(((context.viewbox.x - barGap) * size) / 1000);
28
+ const groups = [...new Set(bars.map((bar) => bar.group))];
29
+ if (loading) {
30
+ return <BarsVerticalLoading />;
31
+ }
32
+ return (<svg viewBox={`0 0 ${context.viewbox.x} ${context.viewbox.y}`} className={cx("[grid-area:graph] h-full w-full", className)} preserveAspectRatio={"none"}>
33
+ {groups === null || groups === void 0 ? void 0 : groups.map((group, g) => {
34
+ const groupBars = bars.filter((b) => b.group === group);
35
+ const coordinate = [];
36
+ return groupBars.map((bar, index) => {
37
+ var _a;
38
+ if (bar.group === group)
39
+ return (_a = bar.data) === null || _a === void 0 ? void 0 : _a.map((xy, idx) => {
40
+ const x1 = xy.x + barWidth * g - barWidth * (groups.length / 2);
41
+ const x2 = x1 + barWidth;
42
+ const y1 = index === 0 ? context.viewbox.y : coordinate[idx];
43
+ const y2 = index === 0 ? xy.y : coordinate[idx] - (context.viewbox.y - xy.y);
44
+ coordinate[idx] = index === 0 ? xy.y : coordinate[idx] - (context.viewbox.y - xy.y);
45
+ return (<Rect key={idx} x1={x1} x2={x2} y1={y1} y2={y2} fill={bar.stroke} stroke={bar.stroke} radius={groupBars.length === index + 1 ? radius : undefined}/>);
46
+ });
47
+ });
48
+ })}
49
+ {children}
50
+ </svg>);
51
+ };
@@ -0,0 +1,24 @@
1
+ import React, { CSSProperties, HTMLAttributes, ReactNode } from "react";
2
+ import { GraphContext } from "@/hooks/use-graph/use-graph";
3
+ type Props = {
4
+ data?: GraphContext["data"];
5
+ gap?: {
6
+ top?: number;
7
+ right?: number;
8
+ bottom?: number;
9
+ left?: number;
10
+ };
11
+ interactions?: {
12
+ hovered?: string[];
13
+ pinned?: string[];
14
+ };
15
+ children: ReactNode;
16
+ style?: CSSProperties;
17
+ className?: string;
18
+ };
19
+ export declare const Graph: {
20
+ ({ data, gap, children, interactions, style, className }: Props): React.JSX.Element;
21
+ Row({ children, ...rest }: HTMLAttributes<HTMLDivElement>): React.JSX.Element;
22
+ Column({ children, ...rest }: HTMLAttributes<HTMLDivElement>): React.JSX.Element;
23
+ };
24
+ export {};
@@ -0,0 +1,60 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import React, { useId } from "react";
13
+ import { GraphContextProvider } from "@/hooks/use-graph/use-graph";
14
+ import { ChildrenUtils } from "@/utils/children/children";
15
+ import { DomainUtils } from "@/utils/domain/domain";
16
+ import { cx } from "@/utils/cx/cx";
17
+ import { ColorUtils } from "@/utils/color/color";
18
+ import { GraphUtils } from "@/utils/graph/graph";
19
+ export const Graph = ({ data = [], gap, children, interactions, style, className }) => {
20
+ var _a, _b, _c, _d, _e, _f;
21
+ const id = useId();
22
+ const X_SCALE = 3000;
23
+ const Y_SCALE = 3000;
24
+ const ctx = ChildrenUtils.context(children, {
25
+ id,
26
+ layout: { rows: "[graph] auto", columns: "[graph] auto" },
27
+ viewbox: { x: X_SCALE, y: Y_SCALE },
28
+ data: GraphUtils.isXYData(data)
29
+ ? data.map((dp, i, dps) => {
30
+ var _a, _b, _c;
31
+ return Object.assign({ id: (_a = dp.id) !== null && _a !== void 0 ? _a : dp.name, stroke: (_b = dp.stroke) !== null && _b !== void 0 ? _b : ColorUtils.colorFor(i, dps.length), fill: dp.fill === true ? ((_c = dp.stroke) !== null && _c !== void 0 ? _c : ColorUtils.colorFor(i, dps.length)) : dp.fill }, dp);
32
+ })
33
+ : data.map((dp, i, dps) => {
34
+ var _a, _b, _c;
35
+ return Object.assign({ id: (_a = dp.id) !== null && _a !== void 0 ? _a : dp.name, stroke: (_b = dp.stroke) !== null && _b !== void 0 ? _b : ColorUtils.colorFor(i, dps.length), fill: dp.fill === true ? ((_c = dp.stroke) !== null && _c !== void 0 ? _c : ColorUtils.colorFor(i, dps.length)) : dp.fill }, dp);
36
+ }),
37
+ gap: { top: (_a = gap === null || gap === void 0 ? void 0 : gap.top) !== null && _a !== void 0 ? _a : 0, left: (_b = gap === null || gap === void 0 ? void 0 : gap.left) !== null && _b !== void 0 ? _b : 0, right: (_c = gap === null || gap === void 0 ? void 0 : gap.right) !== null && _c !== void 0 ? _c : 0, bottom: (_d = gap === null || gap === void 0 ? void 0 : gap.bottom) !== null && _d !== void 0 ? _d : 0 },
38
+ attributes: {
39
+ className: "@container/graph nanoplot relative grid h-full w-full isolate",
40
+ },
41
+ domain: {
42
+ x: DomainUtils.x.ticks({ data, viewbox: { x: X_SCALE, y: Y_SCALE } }),
43
+ y: DomainUtils.y.ticks({ data, viewbox: { x: X_SCALE, y: Y_SCALE } }),
44
+ },
45
+ interactions: { hovered: (_e = interactions === null || interactions === void 0 ? void 0 : interactions.hovered) !== null && _e !== void 0 ? _e : [], pinned: (_f = interactions === null || interactions === void 0 ? void 0 : interactions.pinned) !== null && _f !== void 0 ? _f : [] },
46
+ });
47
+ return (<div id={id} {...ctx.attributes} style={Object.assign(Object.assign(Object.assign({}, style), ctx.attributes.style), { gridTemplateColumns: ctx.layout.columns, gridTemplateRows: ctx.layout.rows, padding: `${ctx.gap.top}px ${ctx.gap.right}px ${ctx.gap.bottom}px ${ctx.gap.left}px` })} className={cx(ctx.attributes.className, className)}>
48
+ <GraphContextProvider value={ctx}>{children}</GraphContextProvider>
49
+ </div>);
50
+ };
51
+ Graph.Row = (_a) => {
52
+ var { children } = _a, rest = __rest(_a, ["children"]);
53
+ return (<div {...rest} className={cx("col-span-full", rest.className)}>
54
+ {children}
55
+ </div>);
56
+ };
57
+ Graph.Column = (_a) => {
58
+ var { children } = _a, rest = __rest(_a, ["children"]);
59
+ return <div {...rest}>{children}</div>;
60
+ };
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ interface Props extends React.SVGAttributes<SVGSVGElement> {
3
+ trendline?: boolean;
4
+ border?: boolean;
5
+ horizontal?: boolean;
6
+ vertical?: boolean;
7
+ }
8
+ export declare const GridLines: ({ border, horizontal, vertical, className }: Props) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,13 @@
1
+ import { cx } from "@/utils/cx/cx";
2
+ import React from "react";
3
+ import { useGraph } from "@/hooks/use-graph/use-graph";
4
+ export const GridLines = ({ border, horizontal, vertical, className }) => {
5
+ const context = useGraph();
6
+ const { x, y } = context.viewbox;
7
+ const { domain } = context;
8
+ return (<svg viewBox={`0 0 ${x} ${y}`} className={cx("[grid-area:graph] h-full w-full", className)} preserveAspectRatio={"none"}>
9
+ {border && (<path d={`M 0 0 l${x} 0 l0 ${y} l${-x} 0 Z`} strokeWidth={1} vectorEffect={"non-scaling-stroke"} fill={"transparent"} className={cx("stroke-[#DFDFDF] dark:stroke-[#2D2D2D] grid-lines__border")}/>)}
10
+ {horizontal && (<path d={domain.y.map(({ coordinate }) => `M 0 ${coordinate} L ${x} ${coordinate}`).join(" ")} strokeWidth={1} vectorEffect={"non-scaling-stroke"} className={cx("stroke-[#DFDFDF] dark:stroke-[#2D2D2D] grid-lines__horizontal")}/>)}
11
+ {vertical && (<path d={domain.x.map(({ coordinate }) => `M ${coordinate} 0 L ${coordinate} ${y}`).join(" ")} strokeWidth={1} vectorEffect={"non-scaling-stroke"} className={cx("stroke-[#DFDFDF] dark:stroke-[#2D2D2D] grid-lines__vertical")}/>)}
12
+ </svg>);
13
+ };
@@ -0,0 +1,45 @@
1
+ import React from "react";
2
+ import { GraphContext } from "@/hooks/use-graph/use-graph";
3
+ import { ReactNode } from "react";
4
+ type Props = {
5
+ position?: "top" | "bottom" | "left" | "right";
6
+ alignment?: "center" | "start" | "end";
7
+ children?: ReactNode;
8
+ };
9
+ export declare const Legend: {
10
+ ({ position, alignment }: Props): React.JSX.Element;
11
+ context(ctx: GraphContext, props: Props): {
12
+ layout: {
13
+ rows: string;
14
+ columns: string;
15
+ };
16
+ id: string;
17
+ attributes: React.HTMLAttributes<HTMLDivElement>;
18
+ gap: {
19
+ top: number;
20
+ right: number;
21
+ bottom: number;
22
+ left: number;
23
+ };
24
+ viewbox: {
25
+ x: number;
26
+ y: number;
27
+ };
28
+ data: import("@/hooks/use-graph/use-graph").XYDataset | import("@/hooks/use-graph/use-graph").SegmentDataset;
29
+ domain: {
30
+ x: Array<{
31
+ coordinate: number;
32
+ tick: string | number | Date;
33
+ }>;
34
+ y: Array<{
35
+ coordinate: number;
36
+ tick: string | number | Date;
37
+ }>;
38
+ };
39
+ interactions: {
40
+ hovered: string[];
41
+ pinned: string[];
42
+ };
43
+ };
44
+ };
45
+ export {};
@@ -0,0 +1,37 @@
1
+ import React from "react";
2
+ import { useGraph, useGraphColumn } from "@/hooks/use-graph/use-graph";
3
+ import { Graph } from "../Graph/Graph";
4
+ import { ColorUtils } from "@/utils/color/color";
5
+ import { cx } from "@/utils/cx/cx";
6
+ export const Legend = ({ position = "top", alignment = "center" }) => {
7
+ var _a;
8
+ const context = useGraph();
9
+ const Element = position === "top" || position === "bottom" ? Graph.Row : Graph.Column;
10
+ const column = useGraphColumn(context);
11
+ return (<Element className={cx("flex", "gap-2", (position === "left" || position === "right") && "flex-col", position === "right" && "pl-4", position === "left" && "pr-4", alignment === "start" && "justify-start", alignment === "end" && "justify-end", alignment === "center" && "justify-center")} style={position === "top" || position === "bottom" ? { gridColumn: column } : undefined}>
12
+ {(_a = context.data) === null || _a === void 0 ? void 0 : _a.map(({ name, stroke }, i, dps) => {
13
+ return (<div key={i} className={"flex items-center"}>
14
+ <div className={"size-4 mr-1 rounded-full"} style={{ background: stroke !== null && stroke !== void 0 ? stroke : ColorUtils.colorFor(i, dps.length) }}/>
15
+ <div className={"text-nowrap"}>{name}</div>
16
+ </div>);
17
+ })}
18
+ </Element>);
19
+ };
20
+ Legend.context = (ctx, props) => {
21
+ const rows = (() => {
22
+ if (props.position === "top")
23
+ return "max-content " + ctx.layout.rows;
24
+ if (props.position === "bottom")
25
+ return ctx.layout.rows + " max-content";
26
+ return ctx.layout.rows;
27
+ })();
28
+ const columns = (() => {
29
+ if (props.position === "left")
30
+ return "max-content " + ctx.layout.columns;
31
+ if (props.position === "right")
32
+ return ctx.layout.columns + " max-content";
33
+ return ctx.layout.columns;
34
+ })();
35
+ return Object.assign(Object.assign({}, ctx), { layout: Object.assign(Object.assign({}, ctx.layout), { rows,
36
+ columns }) });
37
+ };
@@ -0,0 +1,6 @@
1
+ type Props = {
2
+ id: string;
3
+ gradient: string;
4
+ };
5
+ export declare const LinearGradient: ({ id, gradient }: Props) => import("react").JSX.Element;
6
+ export {};
@@ -0,0 +1,52 @@
1
+ export const LinearGradient = ({ id, gradient }) => {
2
+ const parseDirection = (direction) => {
3
+ if (direction.includes("to ")) {
4
+ switch (direction.replace("to ", "").trim()) {
5
+ case "top":
6
+ return { x1: 0, y1: 1, x2: 0, y2: 0 };
7
+ case "right":
8
+ return { x1: 0, y1: 0, x2: 1, y2: 0 };
9
+ case "bottom":
10
+ return { x1: 0, y1: 0, x2: 0, y2: 1 };
11
+ case "left":
12
+ return { x1: 1, y1: 0, x2: 0, y2: 0 };
13
+ case "top left":
14
+ return { x1: 1, y1: 1, x2: 0, y2: 0 };
15
+ case "top right":
16
+ return { x1: 0, y1: 1, x2: 1, y2: 0 };
17
+ case "bottom left":
18
+ return { x1: 1, y1: 0, x2: 0, y2: 1 };
19
+ case "bottom right":
20
+ return { x1: 0, y1: 0, x2: 1, y2: 1 };
21
+ }
22
+ }
23
+ else if (direction.match(/\d+deg/)) {
24
+ const angle = parseFloat(direction) * (Math.PI / 180);
25
+ return {
26
+ x1: 0.5 - 0.5 * Math.cos(angle),
27
+ y1: 0.5 - 0.5 * Math.sin(angle),
28
+ x2: 0.5 + 0.5 * Math.cos(angle),
29
+ y2: 0.5 + 0.5 * Math.sin(angle),
30
+ };
31
+ }
32
+ return { x1: 0, y1: 0, x2: 0, y2: 1 }; // Default to "to bottom"
33
+ };
34
+ const parseStops = (stops) => stops.map((stop, i, arr) => {
35
+ const [color, offset] = stop.trim().split(/\s+(?![^()]*\))/);
36
+ return {
37
+ color,
38
+ offset: offset || (i === 0 ? "0%" : i === arr.length - 1 ? "100%" : undefined),
39
+ };
40
+ });
41
+ const { x1, y1, x2, y2, stops } = (() => {
42
+ const match = gradient.match(/linear-gradient\(([^)]+)\)/);
43
+ if (!match)
44
+ throw new Error("Invalid gradient string");
45
+ const parts = match[1].split(/,(?![^()]*\))/).map((p) => p.trim());
46
+ const direction = parts[0].match(/^(to|\d+deg|\d+rad|\d+turn)/) ? parts.shift() : "to bottom";
47
+ return Object.assign(Object.assign({}, parseDirection(direction)), { stops: parseStops(parts) });
48
+ })();
49
+ return (<linearGradient id={id} x1={x1} y1={y1} x2={x2} y2={y2}>
50
+ {stops.map(({ color, offset }, i) => (<stop key={i} stopColor={color} offset={offset}/>))}
51
+ </linearGradient>);
52
+ };
@@ -0,0 +1,17 @@
1
+ import React, { ReactNode } from "react";
2
+ import { CurveUtils } from "@/utils/path/curve";
3
+ interface Props extends React.SVGAttributes<SVGSVGElement> {
4
+ children?: ReactNode;
5
+ curve?: keyof typeof CurveUtils;
6
+ loading?: boolean;
7
+ }
8
+ export declare const Lines: {
9
+ ({ className, curve, children, loading }: Props): React.JSX.Element | null;
10
+ Tooltip: ({ tooltip, joints }: {
11
+ tooltip?: (points: Array<Omit<import("@/hooks/use-graph/use-graph").XYDataset[number], "data"> & {
12
+ data: import("@/hooks/use-graph/use-graph").XYDataset[number]["data"][number];
13
+ }>, x: number | string | Date) => React.ReactNode;
14
+ joints?: boolean;
15
+ }) => React.JSX.Element | null;
16
+ };
17
+ export {};
@@ -0,0 +1,53 @@
1
+ import React from "react";
2
+ import { useGraph } from "@/hooks/use-graph/use-graph";
3
+ import { CoordinatesUtils } from "@/utils/coordinates/coordinates";
4
+ import { GraphUtils } from "@/utils/graph/graph";
5
+ import { ColorUtils } from "@/utils/color/color";
6
+ import { cx } from "@/utils/cx/cx";
7
+ import { LinesTooltip } from "@/components/Lines/components/LinesTooltip";
8
+ import { LinesLoading } from "@/components/Lines/components/LinesLoading";
9
+ import { CurveUtils } from "@/utils/path/curve";
10
+ export const Lines = ({ className, curve = "linear", children, loading }) => {
11
+ const { interactions: { pinned, hovered }, data, viewbox, domain, } = useGraph();
12
+ if (!GraphUtils.isXYData(data))
13
+ return null;
14
+ const xForValue = CoordinatesUtils.xCoordinateFor({ domain, viewbox });
15
+ const yForValue = CoordinatesUtils.yCoordinateFor({ domain, viewbox });
16
+ const lines = data.map((line, i, lines) => {
17
+ var _a, _b, _c;
18
+ return Object.assign(Object.assign({}, line), { id: (_a = line.id) !== null && _a !== void 0 ? _a : line.name, stroke: (_b = line.stroke) !== null && _b !== void 0 ? _b : ColorUtils.colorFor(i, lines.length), fill: line.fill === true ? ((_c = line.stroke) !== null && _c !== void 0 ? _c : ColorUtils.colorFor(i, lines.length)) : line.fill, data: line.data.map((xy) => ({
19
+ x: xForValue(xy.x),
20
+ y: yForValue(xy.y),
21
+ })) });
22
+ });
23
+ if (loading) {
24
+ return <LinesLoading />;
25
+ }
26
+ return (<svg viewBox={`0 0 ${viewbox.x} ${viewbox.y}`} height={"100%"} width={"100%"} preserveAspectRatio={"none"} className={cx("[grid-area:graph]", className)}>
27
+ {lines.map(({ id, stroke, data, fill }, i) => {
28
+ const path = CurveUtils[curve](data);
29
+ const disabled = pinned.length && !pinned.includes(id) && !hovered.includes(id);
30
+ const filled = fill || hovered.includes(id) || (pinned.includes(id) && !disabled);
31
+ const identifier = id.replace(/[^a-zA-Z0-9]/g, "");
32
+ return (<React.Fragment key={i}>
33
+ {filled && !disabled && (<linearGradient id={identifier} x1="0" y1="0" x2="0" y2="1">
34
+ <stop offset="5%" stopColor={stroke} stopOpacity={"0.5"}/>
35
+ <stop offset="95%" stopColor={stroke} stopOpacity={"0"}/>
36
+ </linearGradient>)}
37
+ <path key={i} d={path} fill={"transparent"} stroke={stroke} className={cx(disabled && "stroke-black dark:stroke-white [stroke-opacity:0.1] lines__outlined")} vectorEffect={"non-scaling-stroke"} strokeWidth={1.5}/>
38
+ {filled && (<path d={path + `L ${viewbox.x} ${viewbox.y} L 0 ${viewbox.y} Z`} stroke={stroke} fill={(() => {
39
+ if (typeof fill === "string")
40
+ return fill;
41
+ if (filled)
42
+ return `url(#${identifier})`;
43
+ return undefined;
44
+ })()} strokeOpacity={0} className="lines__filled"/>)}
45
+ </React.Fragment>);
46
+ })}
47
+ {children}
48
+ </svg>);
49
+ };
50
+ /*
51
+ Chart composition
52
+ */
53
+ Lines.Tooltip = LinesTooltip;
@@ -0,0 +1,2 @@
1
+ import React from "react";
2
+ export declare const LinesLoading: () => React.JSX.Element;
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { useGraph } from "@/hooks/use-graph/use-graph";
3
+ export const LinesLoading = () => {
4
+ const { viewbox } = useGraph();
5
+ return (<svg viewBox={`0 0 ${viewbox.x} ${viewbox.y}`} height={"100%"} width={"100%"} preserveAspectRatio={"none"} className={"[grid-area:graph] stroke-gray-600"}>
6
+ <path d={`M ${viewbox.x * 0.05} ${viewbox.y * 0.95} L ${viewbox.x * 0.2167} ${viewbox.y * 0.55} L ${viewbox.x * 0.35} ${viewbox.y * 0.75} L ${viewbox.x * 0.55} ${viewbox.y * 0.2833} L ${viewbox.x * 0.7167} ${viewbox.y * 0.5167} L ${viewbox.x * 0.95} ${viewbox.y * 0.05}`} strokeWidth={5} stroke={"stroke-gray-600"} strokeLinecap={"round"} fill="none" vectorEffect={"non-scaling-stroke"}>
7
+ <animate attributeName="stroke" values="#4b5563; #374151; #4b5563; #4b5563;" dur="2s" repeatCount="indefinite" calcMode="spline" keyTimes="0; 0.3; 0.6; 1" keySplines="0.15 0.25 0.25 0.15; 0.15 0.25 0.25 0.15; 0 0 0 0"/>
8
+ </path>
9
+ </svg>);
10
+ };
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ import { XYDataset } from "@/hooks/use-graph/use-graph";
3
+ type Props = {
4
+ tooltip?: (points: Array<Omit<XYDataset[number], "data"> & {
5
+ data: XYDataset[number]["data"][number];
6
+ }>, x: number | string | Date) => React.ReactNode;
7
+ joints?: boolean;
8
+ };
9
+ export declare const LinesTooltip: ({ tooltip, joints }: Props) => React.JSX.Element | null;
10
+ export {};