@cascivo/charts 0.18.0 → 1.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 +14 -0
- package/dist/chart-frame.module-CkOcXGSL.js +191 -0
- package/dist/index.d.ts +45 -44
- package/dist/index.js +2005 -2172
- package/dist/node/chart-frame.module-CkOcXGSL.js +191 -0
- package/dist/node/index.js +2005 -2172
- package/dist/node/sparkline.js +61 -0
- package/dist/sparkline.d.ts +43 -0
- package/dist/sparkline.js +62 -0
- package/package.json +9 -3
- package/readme.body.md +14 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { i as e, l as t, t as n } from "./chart-frame.module-CkOcXGSL.js";
|
|
3
|
+
import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
4
|
+
//#region src/core/mini-frame.tsx
|
|
5
|
+
var o = {
|
|
6
|
+
position: "absolute",
|
|
7
|
+
insetInlineStart: "-9999px",
|
|
8
|
+
inlineSize: "1px",
|
|
9
|
+
blockSize: "1px",
|
|
10
|
+
overflow: "hidden",
|
|
11
|
+
clipPath: "inset(50%)",
|
|
12
|
+
whiteSpace: "nowrap"
|
|
13
|
+
};
|
|
14
|
+
function s({ title: e, width: t, height: r, className: s, fallback: c, children: l }) {
|
|
15
|
+
return /* @__PURE__ */ a("div", {
|
|
16
|
+
className: [n.frame, s].filter(Boolean).join(" "),
|
|
17
|
+
"data-plain": "",
|
|
18
|
+
children: [/* @__PURE__ */ i("svg", {
|
|
19
|
+
role: "img",
|
|
20
|
+
"aria-label": e,
|
|
21
|
+
width: t,
|
|
22
|
+
height: r,
|
|
23
|
+
viewBox: `0 0 ${t} ${r}`,
|
|
24
|
+
children: l
|
|
25
|
+
}), c && /* @__PURE__ */ i("div", {
|
|
26
|
+
className: n.fallback,
|
|
27
|
+
style: o,
|
|
28
|
+
children: c
|
|
29
|
+
})]
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/charts/sparkline/sparkline-lite.tsx
|
|
34
|
+
function c({ data: n, width: o = 120, height: c = 32, label: l, ariaLabel: u, color: d = "var(--cascivo-chart-1)", endDot: f = !0, className: p }) {
|
|
35
|
+
let m = (() => {
|
|
36
|
+
if (n.length === 0) return [];
|
|
37
|
+
let e = t([0, n.length - 1], [2, o - 2]), r = Math.min(...n), i = Math.max(...n), a = t([r === i ? r - 1 : r, i], [c - 2, 2]);
|
|
38
|
+
return n.map((t, n) => [e.map(n), a.map(t)]);
|
|
39
|
+
})(), h = m[m.length - 1];
|
|
40
|
+
return /* @__PURE__ */ i(s, {
|
|
41
|
+
title: l ?? u,
|
|
42
|
+
width: o,
|
|
43
|
+
height: c,
|
|
44
|
+
...p === void 0 ? {} : { className: p },
|
|
45
|
+
children: m.length > 0 && /* @__PURE__ */ a(r, { children: [/* @__PURE__ */ i("path", {
|
|
46
|
+
d: e(m, "monotone"),
|
|
47
|
+
fill: "none",
|
|
48
|
+
stroke: d,
|
|
49
|
+
strokeWidth: 1.5,
|
|
50
|
+
strokeLinecap: "round",
|
|
51
|
+
strokeLinejoin: "round"
|
|
52
|
+
}), f && h && /* @__PURE__ */ i("circle", {
|
|
53
|
+
cx: h[0],
|
|
54
|
+
cy: h[1],
|
|
55
|
+
r: 2.5,
|
|
56
|
+
fill: d
|
|
57
|
+
})] })
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { c as Sparkline };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
interface SparklineLiteBaseProps {
|
|
2
|
+
data: readonly number[];
|
|
3
|
+
/**
|
|
4
|
+
* SVG width in px. **This chart is fixed-width by default** — it is a compact, inline
|
|
5
|
+
* chart meant to sit in a table cell or beside a label, so omitting `width` gives you
|
|
6
|
+
* 120px rather than a container-filling chart.
|
|
7
|
+
*
|
|
8
|
+
* @defaultValue `120`
|
|
9
|
+
*/
|
|
10
|
+
width?: number;
|
|
11
|
+
height?: number;
|
|
12
|
+
color?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Show dot at last data point
|
|
15
|
+
*
|
|
16
|
+
* @defaultValue `true`
|
|
17
|
+
*/
|
|
18
|
+
endDot?: boolean;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Exactly one of `label` / `ariaLabel` is required — a chart with no accessible name is a
|
|
23
|
+
* bug, so this stays enforced by the type. `ariaLabel` is the catalog's convention for an
|
|
24
|
+
* invisible accessible name; `Sparkline` predates it and shipped `label`, so both work.
|
|
25
|
+
*/
|
|
26
|
+
type SparklineLiteProps = SparklineLiteBaseProps & ({
|
|
27
|
+
label: string;
|
|
28
|
+
ariaLabel?: never;
|
|
29
|
+
} | {
|
|
30
|
+
ariaLabel: string;
|
|
31
|
+
label?: never;
|
|
32
|
+
});
|
|
33
|
+
declare function Sparkline({
|
|
34
|
+
data,
|
|
35
|
+
width,
|
|
36
|
+
height,
|
|
37
|
+
label,
|
|
38
|
+
ariaLabel,
|
|
39
|
+
color,
|
|
40
|
+
endDot,
|
|
41
|
+
className
|
|
42
|
+
}: SparklineLiteProps): import("react").JSX.Element;
|
|
43
|
+
export { Sparkline, type SparklineLiteProps as SparklineProps };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import './charts.css';
|
|
3
|
+
import { i as e, l as t, t as n } from "./chart-frame.module-CkOcXGSL.js";
|
|
4
|
+
import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
5
|
+
//#region src/core/mini-frame.tsx
|
|
6
|
+
var o = {
|
|
7
|
+
position: "absolute",
|
|
8
|
+
insetInlineStart: "-9999px",
|
|
9
|
+
inlineSize: "1px",
|
|
10
|
+
blockSize: "1px",
|
|
11
|
+
overflow: "hidden",
|
|
12
|
+
clipPath: "inset(50%)",
|
|
13
|
+
whiteSpace: "nowrap"
|
|
14
|
+
};
|
|
15
|
+
function s({ title: e, width: t, height: r, className: s, fallback: c, children: l }) {
|
|
16
|
+
return /* @__PURE__ */ a("div", {
|
|
17
|
+
className: [n.frame, s].filter(Boolean).join(" "),
|
|
18
|
+
"data-plain": "",
|
|
19
|
+
children: [/* @__PURE__ */ i("svg", {
|
|
20
|
+
role: "img",
|
|
21
|
+
"aria-label": e,
|
|
22
|
+
width: t,
|
|
23
|
+
height: r,
|
|
24
|
+
viewBox: `0 0 ${t} ${r}`,
|
|
25
|
+
children: l
|
|
26
|
+
}), c && /* @__PURE__ */ i("div", {
|
|
27
|
+
className: n.fallback,
|
|
28
|
+
style: o,
|
|
29
|
+
children: c
|
|
30
|
+
})]
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/charts/sparkline/sparkline-lite.tsx
|
|
35
|
+
function c({ data: n, width: o = 120, height: c = 32, label: l, ariaLabel: u, color: d = "var(--cascivo-chart-1)", endDot: f = !0, className: p }) {
|
|
36
|
+
let m = (() => {
|
|
37
|
+
if (n.length === 0) return [];
|
|
38
|
+
let e = t([0, n.length - 1], [2, o - 2]), r = Math.min(...n), i = Math.max(...n), a = t([r === i ? r - 1 : r, i], [c - 2, 2]);
|
|
39
|
+
return n.map((t, n) => [e.map(n), a.map(t)]);
|
|
40
|
+
})(), h = m[m.length - 1];
|
|
41
|
+
return /* @__PURE__ */ i(s, {
|
|
42
|
+
title: l ?? u,
|
|
43
|
+
width: o,
|
|
44
|
+
height: c,
|
|
45
|
+
...p === void 0 ? {} : { className: p },
|
|
46
|
+
children: m.length > 0 && /* @__PURE__ */ a(r, { children: [/* @__PURE__ */ i("path", {
|
|
47
|
+
d: e(m, "monotone"),
|
|
48
|
+
fill: "none",
|
|
49
|
+
stroke: d,
|
|
50
|
+
strokeWidth: 1.5,
|
|
51
|
+
strokeLinecap: "round",
|
|
52
|
+
strokeLinejoin: "round"
|
|
53
|
+
}), f && h && /* @__PURE__ */ i("circle", {
|
|
54
|
+
cx: h[0],
|
|
55
|
+
cy: h[1],
|
|
56
|
+
r: 2.5,
|
|
57
|
+
fill: d
|
|
58
|
+
})] })
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { c as Sparkline };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cascivo/charts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Chart components built from scratch — scales, shapes, and signal-driven rendering, zero dependencies. Colors come from @cascivo/themes; components from @cascivo/react. Docs offline: npx @cascivo/docs",
|
|
6
6
|
"keywords": [
|
|
@@ -38,6 +38,12 @@
|
|
|
38
38
|
"import": "./dist/index.js",
|
|
39
39
|
"default": "./dist/index.js"
|
|
40
40
|
},
|
|
41
|
+
"./sparkline": {
|
|
42
|
+
"types": "./dist/sparkline.d.ts",
|
|
43
|
+
"node": "./dist/node/sparkline.js",
|
|
44
|
+
"import": "./dist/sparkline.js",
|
|
45
|
+
"default": "./dist/sparkline.js"
|
|
46
|
+
},
|
|
41
47
|
"./styles.css": "./dist/charts.css"
|
|
42
48
|
},
|
|
43
49
|
"publishConfig": {
|
|
@@ -45,8 +51,8 @@
|
|
|
45
51
|
"provenance": true
|
|
46
52
|
},
|
|
47
53
|
"dependencies": {
|
|
48
|
-
"@cascivo/core": "^0.
|
|
49
|
-
"@cascivo/i18n": "^0.
|
|
54
|
+
"@cascivo/core": "^1.0.0",
|
|
55
|
+
"@cascivo/i18n": "^1.0.0"
|
|
50
56
|
},
|
|
51
57
|
"devDependencies": {
|
|
52
58
|
"@preact/signals": "^2",
|
package/readme.body.md
CHANGED
|
@@ -63,6 +63,20 @@ The charts are signal-driven. In a plain React app (no Babel signals transform),
|
|
|
63
63
|
from `@cascivo/core` as the first statement of any component that reads a signal during render. The
|
|
64
64
|
docs app (Preact) does not need this.
|
|
65
65
|
|
|
66
|
+
## One sparkline, without the engine
|
|
67
|
+
|
|
68
|
+
`import { Sparkline } from '@cascivo/charts'` pulls in the whole charting engine — tooltips, voronoi hit-testing, a canvas layer, zoom/pan, a toolbox, PNG/SVG export — because `Sparkline` is built on the same frame as every other chart. An adopter measured 44.87 kB / 14.84 kB gzip for a single trend line on a landing page.
|
|
69
|
+
|
|
70
|
+
For a page that wants a sparkline and draws no other charts, there is a subpath that does not:
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
import { Sparkline } from '@cascivo/charts/sparkline' // ~3.5 kB gzip, no engine
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Identical props, identical markup, identical styling — asserted by a DOM-parity test, and the size is held by a budget in CI. **One difference: no hover tooltip**, because the tooltip is what requires the engine.
|
|
77
|
+
|
|
78
|
+
Use the main entry when the page draws other charts anyway: the engine is already paid for and the subpath saves nothing.
|
|
79
|
+
|
|
66
80
|
## Coloring
|
|
67
81
|
|
|
68
82
|
By default every slice/series/layer is colored from the positional palette
|