@lilt-ui/charts 0.1.0 → 0.2.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/CHANGELOG.md +43 -0
- package/README.md +75 -0
- package/dist/analysis-BJRmXHOB.js +62 -0
- package/dist/cards/box-plot-card.d.ts +30 -0
- package/dist/cards/cartesian-card.d.ts +54 -3
- package/dist/cards/range-chart-card.d.ts +28 -0
- package/dist/cartesian-card-BDZs0v6E.js +7235 -0
- package/dist/chart-context.d.ts +18 -0
- package/dist/chart-data-CCwLQeXa.js +44 -0
- package/dist/chart.d.ts +3 -1
- package/dist/data.js +3 -2
- package/dist/engine/box.d.ts +18 -0
- package/dist/engine/domains.d.ts +2 -0
- package/dist/engine/geometry.d.ts +2 -1
- package/dist/engine/normalize.d.ts +2 -4
- package/dist/engine/ranges.d.ts +59 -0
- package/dist/finance/candle-geometry.d.ts +55 -0
- package/dist/finance/candles.d.ts +18 -0
- package/dist/finance/cards/candlestick-chart-card.d.ts +41 -0
- package/dist/finance/cards/depth-chart-card.d.ts +32 -0
- package/dist/finance/cards/indicator-chart-card.d.ts +52 -0
- package/dist/finance/cards/pane.d.ts +24 -0
- package/dist/finance/cards/portfolio-chart-card.d.ts +22 -0
- package/dist/finance/cards/price-chart-card.d.ts +27 -0
- package/dist/finance/index.d.ts +17 -0
- package/dist/finance/indicators.d.ts +65 -0
- package/dist/finance/order-book.d.ts +26 -0
- package/dist/finance.d.ts +2 -0
- package/dist/finance.js +1157 -0
- package/dist/index.d.ts +10 -1
- package/dist/index.js +2235 -8793
- package/dist/interaction/field-values.d.ts +12 -0
- package/dist/interaction/inspection-layer.d.ts +4 -1
- package/dist/marks/contract.d.ts +49 -0
- package/dist/marks/use-range-mark.d.ts +19 -0
- package/dist/primitives/annotations.d.ts +1 -1
- package/dist/primitives/box-plot.d.ts +4 -0
- package/dist/primitives/error-bar.d.ts +4 -0
- package/dist/primitives/interval-band.d.ts +2 -2
- package/dist/primitives/range-bar.d.ts +4 -0
- package/dist/styles.css +1 -1
- package/dist/types.d.ts +80 -13
- package/package.json +11 -2
- package/dist/analysis-BLLWEKBw.js +0 -105
package/dist/types.d.ts
CHANGED
|
@@ -72,6 +72,11 @@ export interface ChartBarLayout {
|
|
|
72
72
|
/** Space between segments of a stack, in CSS pixels. Defaults to 0. */
|
|
73
73
|
segmentGap?: number;
|
|
74
74
|
}
|
|
75
|
+
export interface ChartSeriesField<T> {
|
|
76
|
+
/** Shown beside the value in inspection, e.g. "High". */
|
|
77
|
+
label: string;
|
|
78
|
+
accessor: (row: T) => number | null;
|
|
79
|
+
}
|
|
75
80
|
export interface ChartSeries<T> {
|
|
76
81
|
id: string;
|
|
77
82
|
label: string;
|
|
@@ -79,13 +84,19 @@ export interface ChartSeries<T> {
|
|
|
79
84
|
accessor: (row: T) => number | null;
|
|
80
85
|
/** Explicit source status. The last row is never inferred to be provisional. */
|
|
81
86
|
status?: (row: T) => ChartObservationStatus;
|
|
82
|
-
/**
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Companion values in the series' own unit, keyed by a stable ID: a candle's open, high and
|
|
89
|
+
* low, a range's ends, or quartiles. `accessor` stays the headline value. Fields fit the y
|
|
90
|
+
* range, appear in inspection, and range marks such as `IntervalBand` read them by ID. Lilt
|
|
91
|
+
* never infers them.
|
|
92
|
+
*/
|
|
93
|
+
fields?: Readonly<Record<string, ChartSeriesField<T>>>;
|
|
88
94
|
color?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Color of one observation's discrete mark (a bar, candle, range mark, or point), such as a
|
|
97
|
+
* down day in red. Return `undefined` to keep the series color. Lines and areas stay one color.
|
|
98
|
+
*/
|
|
99
|
+
colorAt?: (row: T) => string | undefined;
|
|
89
100
|
line?: ChartLineStyle;
|
|
90
101
|
area?: ChartAreaStyle;
|
|
91
102
|
bar?: ChartBarStyle;
|
|
@@ -116,6 +127,13 @@ export interface CategoryXConfig<T> {
|
|
|
116
127
|
}
|
|
117
128
|
export type ChartXConfig<T> = TimeXConfig<T> | NumericXConfig<T> | CategoryXConfig<T>;
|
|
118
129
|
export interface ChartYConfig {
|
|
130
|
+
/**
|
|
131
|
+
* `log` spaces values by ratio, so a doubling looks the same anywhere, as for prices over
|
|
132
|
+
* years. Every plotted value must be positive; bars, stacks and secondary scales need
|
|
133
|
+
* `linear` (the default).
|
|
134
|
+
*/
|
|
135
|
+
scale?: 'linear' | 'log';
|
|
136
|
+
/** Ignored on a log scale, which cannot reach zero. */
|
|
119
137
|
includeZero?: boolean;
|
|
120
138
|
domain?: readonly [number, number];
|
|
121
139
|
/** Values the fitted domain must contain, such as a target line. Ignored with `domain`. */
|
|
@@ -247,6 +265,11 @@ interface ChartPlotCommonProps {
|
|
|
247
265
|
* their observations, as in a chart surrounded by padding. Defaults to 0.
|
|
248
266
|
*/
|
|
249
267
|
labelOverhang?: number;
|
|
268
|
+
/**
|
|
269
|
+
* Give every observation a bar-width slot, as bars and column marks do, so a line pane lines
|
|
270
|
+
* up with a bar or candle pane synced beside it. Ignores `axisInset`.
|
|
271
|
+
*/
|
|
272
|
+
slots?: boolean;
|
|
250
273
|
/** Use 'fill' to size the plot from its flex container; otherwise use a pixel height. */
|
|
251
274
|
height?: number | 'fill';
|
|
252
275
|
compactHeight?: number;
|
|
@@ -321,8 +344,43 @@ export interface AreaProps {
|
|
|
321
344
|
series: string;
|
|
322
345
|
className?: string;
|
|
323
346
|
}
|
|
347
|
+
/** Range marks name the series they draw and the IDs of the fields they read. */
|
|
324
348
|
export interface IntervalBandProps {
|
|
325
349
|
series: string;
|
|
350
|
+
/** Field ID of the band's lower edge. */
|
|
351
|
+
lower: string;
|
|
352
|
+
/** Field ID of the band's upper edge. */
|
|
353
|
+
upper: string;
|
|
354
|
+
className?: string;
|
|
355
|
+
}
|
|
356
|
+
export interface RangeBarProps {
|
|
357
|
+
series: string;
|
|
358
|
+
/** Field ID of each bar's low end. */
|
|
359
|
+
low: string;
|
|
360
|
+
/** Field ID of each bar's high end. */
|
|
361
|
+
high: string;
|
|
362
|
+
className?: string;
|
|
363
|
+
}
|
|
364
|
+
export interface ErrorBarProps {
|
|
365
|
+
series: string;
|
|
366
|
+
/** Field ID of each whisker's low end. */
|
|
367
|
+
low: string;
|
|
368
|
+
/** Field ID of each whisker's high end. */
|
|
369
|
+
high: string;
|
|
370
|
+
/** Draw the series value as a dot between the whiskers. Defaults to true. */
|
|
371
|
+
point?: boolean;
|
|
372
|
+
className?: string;
|
|
373
|
+
}
|
|
374
|
+
export interface BoxPlotProps {
|
|
375
|
+
series: string;
|
|
376
|
+
/** Field IDs of the box edges; the series value is the median line. */
|
|
377
|
+
q1: string;
|
|
378
|
+
q3: string;
|
|
379
|
+
/** Field IDs of the whisker ends. */
|
|
380
|
+
min: string;
|
|
381
|
+
max: string;
|
|
382
|
+
/** Values beyond the whiskers for a row, drawn as dots. Fit them with `y.include`. */
|
|
383
|
+
outliers?(row: unknown): readonly number[];
|
|
326
384
|
className?: string;
|
|
327
385
|
}
|
|
328
386
|
export interface PrimitiveProps {
|
|
@@ -371,6 +429,12 @@ export interface TooltipProps<Row = unknown, SeriesId extends string = string> e
|
|
|
371
429
|
/** Opt in to comparison content in this tooltip. Omit to render it elsewhere. */
|
|
372
430
|
renderComparison?: (context: ChartComparisonContext<SeriesId, Row>) => ReactNode;
|
|
373
431
|
}
|
|
432
|
+
export interface ChartTooltipField {
|
|
433
|
+
id: string;
|
|
434
|
+
label: string;
|
|
435
|
+
value: number | null;
|
|
436
|
+
formattedValue: string;
|
|
437
|
+
}
|
|
374
438
|
export interface ChartTooltipContext<Row = unknown, SeriesId extends string = string> {
|
|
375
439
|
/** The series the pointer, keyboard, or legend currently points at, when there is one. */
|
|
376
440
|
activeSeriesId?: SeriesId | null;
|
|
@@ -385,11 +449,8 @@ export interface ChartTooltipContext<Row = unknown, SeriesId extends string = st
|
|
|
385
449
|
value: number | null;
|
|
386
450
|
formattedValue: string;
|
|
387
451
|
status: ChartObservationStatus;
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
upper: number;
|
|
391
|
-
meaning: string;
|
|
392
|
-
} | null;
|
|
452
|
+
/** The series' companion values, in descriptor order; empty when it has none. */
|
|
453
|
+
fields: readonly ChartTooltipField[];
|
|
393
454
|
}[];
|
|
394
455
|
}
|
|
395
456
|
export interface ChartLegendValue {
|
|
@@ -527,11 +588,17 @@ export interface AnnotationsProps extends PrimitiveProps {
|
|
|
527
588
|
onSelectionChange?: (annotation: ChartAnnotation | null) => void;
|
|
528
589
|
}
|
|
529
590
|
export interface ReferenceBandProps extends PrimitiveProps {
|
|
530
|
-
/**
|
|
591
|
+
/**
|
|
592
|
+
* The band's ends: x values by default, or y values with `axis="y"`. Pass `-Infinity` or
|
|
593
|
+
* `Infinity` for an open end that runs to the plot's edge.
|
|
594
|
+
*/
|
|
531
595
|
from: number | Date;
|
|
532
596
|
to: number | Date;
|
|
533
|
-
|
|
597
|
+
/** Shown inside the band. Optional for y bands, such as an RSI 30–70 range. */
|
|
598
|
+
label?: string;
|
|
534
599
|
color?: string;
|
|
600
|
+
/** `x` (default) spans a range of observations; `y` spans a range of values. */
|
|
601
|
+
axis?: 'x' | 'y';
|
|
535
602
|
}
|
|
536
603
|
export interface ReferenceLineProps extends PrimitiveProps {
|
|
537
604
|
/** The y value, in the primary scale's unit. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lilt-ui/charts",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Beautiful, key-typed React chart cards with linked hover, targets, forecasts, and calm motion.",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Beautiful, key-typed React chart cards with linked hover, targets, forecasts, finance charts, and calm motion.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
7
7
|
"charts",
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
"bar-chart",
|
|
13
13
|
"line-chart",
|
|
14
14
|
"sparkline",
|
|
15
|
+
"candlestick",
|
|
16
|
+
"finance",
|
|
17
|
+
"box-plot",
|
|
15
18
|
"typescript"
|
|
16
19
|
],
|
|
17
20
|
"author": "Lilt UI",
|
|
@@ -32,6 +35,11 @@
|
|
|
32
35
|
"import": "./dist/data.js",
|
|
33
36
|
"default": "./dist/data.js"
|
|
34
37
|
},
|
|
38
|
+
"./finance": {
|
|
39
|
+
"types": "./dist/finance/index.d.ts",
|
|
40
|
+
"import": "./dist/finance.js",
|
|
41
|
+
"default": "./dist/finance.js"
|
|
42
|
+
},
|
|
35
43
|
"./styles.css": "./dist/styles.css",
|
|
36
44
|
"./package.json": "./package.json"
|
|
37
45
|
},
|
|
@@ -39,6 +47,7 @@
|
|
|
39
47
|
"dist",
|
|
40
48
|
"media",
|
|
41
49
|
"README.md",
|
|
50
|
+
"CHANGELOG.md",
|
|
42
51
|
"LICENSE",
|
|
43
52
|
"THIRD_PARTY_NOTICES.md"
|
|
44
53
|
],
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
//#region src/data/chart-data.ts
|
|
2
|
-
function e(e, t) {
|
|
3
|
-
let n = t.range;
|
|
4
|
-
if (n && (!Number.isFinite(n.startX) || !Number.isFinite(n.endX))) throw Error("Range bounds must be finite.");
|
|
5
|
-
let r = n ? Math.min(n.startX, n.endX) : -Infinity, i = n ? Math.max(n.startX, n.endX) : Infinity, a = 0, o = 0, s = 0, c = Infinity, l = -Infinity, u = Infinity, d = -Infinity, f = null, p = null, m = /* @__PURE__ */ new Set();
|
|
6
|
-
for (let n of e) {
|
|
7
|
-
let e = Number(t.x(n));
|
|
8
|
-
if (!Number.isFinite(e)) throw Error("Summary positions must be finite numbers or valid dates.");
|
|
9
|
-
if (e < r || e > i) continue;
|
|
10
|
-
if (m.has(e)) throw Error("Summary positions must be unique.");
|
|
11
|
-
m.add(e);
|
|
12
|
-
let h = t.value(n);
|
|
13
|
-
if (h !== null && (typeof h != "number" || !Number.isFinite(h))) throw Error("Summary values must be finite numbers or null.");
|
|
14
|
-
if (e < u && (u = e, f = h), e > d && (d = e, p = h), h === null) {
|
|
15
|
-
o++;
|
|
16
|
-
continue;
|
|
17
|
-
}
|
|
18
|
-
a++, s += h, c = Math.min(c, h), l = Math.max(l, h);
|
|
19
|
-
}
|
|
20
|
-
if (!Number.isFinite(s)) throw Error("Summary total exceeds the finite numeric range.");
|
|
21
|
-
return {
|
|
22
|
-
count: a,
|
|
23
|
-
missing: o,
|
|
24
|
-
total: a ? s : null,
|
|
25
|
-
mean: a ? s / a : null,
|
|
26
|
-
min: a ? c : null,
|
|
27
|
-
max: a ? l : null,
|
|
28
|
-
first: f,
|
|
29
|
-
last: p,
|
|
30
|
-
change: f === null || p === null ? null : p - f
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
function t(e, t) {
|
|
34
|
-
if (!t.length) throw Error("CSV needs at least one column.");
|
|
35
|
-
let n = (e) => {
|
|
36
|
-
if (typeof e == "number" && !Number.isFinite(e)) throw Error("CSV numbers must be finite.");
|
|
37
|
-
if (e instanceof Date && !Number.isFinite(e.getTime())) throw Error("CSV dates must be valid.");
|
|
38
|
-
let t = e === null ? "" : e instanceof Date ? e.toISOString() : String(e);
|
|
39
|
-
return typeof e == "string" && /^[\s]*[=+\-@]|^[\t\r\n]/.test(t) && (t = "'" + t), /[",\r\n]/.test(t) ? `"${t.replaceAll("\"", "\"\"")}"` : t;
|
|
40
|
-
};
|
|
41
|
-
return [t.map((e) => n(e.header)).join(","), ...e.map((e) => t.map((t) => n(t.value(e))).join(","))].join("\r\n") + "\r\n";
|
|
42
|
-
}
|
|
43
|
-
//#endregion
|
|
44
|
-
//#region src/engine/ranking.ts
|
|
45
|
-
function n(e, t, n) {
|
|
46
|
-
let r = /* @__PURE__ */ new Set();
|
|
47
|
-
return e.map((e, i) => {
|
|
48
|
-
let a = t.id(e), o = t.label(e), s = n(e);
|
|
49
|
-
if (typeof a != "string" || !a.trim()) throw Error(`Invalid category at row ${i + 1}: a non-empty string ID is required.`);
|
|
50
|
-
if (r.has(a)) throw Error(`Duplicate category ID "${a}".`);
|
|
51
|
-
if (typeof o != "string" || !o.trim()) throw Error(`Invalid label for category "${a}".`);
|
|
52
|
-
if (s !== null && (typeof s != "number" || !Number.isFinite(s))) throw Error(`Invalid value for category "${a}": expected a finite number or null.`);
|
|
53
|
-
return r.add(a), {
|
|
54
|
-
id: a,
|
|
55
|
-
label: o,
|
|
56
|
-
datum: e,
|
|
57
|
-
value: s
|
|
58
|
-
};
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
function r(e, t) {
|
|
62
|
-
return t === "input" ? [...e] : [...e].sort((e, n) => {
|
|
63
|
-
if (e.value === null && n.value !== null) return 1;
|
|
64
|
-
if (n.value === null && e.value !== null) return -1;
|
|
65
|
-
let r = (e.value ?? 0) - (n.value ?? 0);
|
|
66
|
-
return r ? r * (t === "descending" ? -1 : 1) : e.id < n.id ? -1 : +(e.id > n.id);
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
function i(e) {
|
|
70
|
-
let t = 0, n = 0;
|
|
71
|
-
for (let r of e) r.value !== null && (t = Math.min(t, r.value), n = Math.max(n, r.value));
|
|
72
|
-
return t === n ? [0, 1] : [t, n];
|
|
73
|
-
}
|
|
74
|
-
function a(e, t) {
|
|
75
|
-
let n = (e) => (e - t[0]) / (t[1] - t[0]) * 100, r = n(0), i = e === null ? r : n(e);
|
|
76
|
-
return {
|
|
77
|
-
zero: r,
|
|
78
|
-
left: Math.min(r, i),
|
|
79
|
-
width: Math.abs(i - r)
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
//#endregion
|
|
83
|
-
//#region src/engine/analysis.ts
|
|
84
|
-
function o(e, t) {
|
|
85
|
-
if (e !== null && (!Number.isFinite(e) || e < 0)) throw Error(`${t} must be a non-negative finite number or null.`);
|
|
86
|
-
}
|
|
87
|
-
function s(e) {
|
|
88
|
-
let t = n(e.data, e.category, e.value), r = Infinity;
|
|
89
|
-
for (let e of t) if (o(e.value, `Stage ${e.id}`), e.value !== null) {
|
|
90
|
-
if (e.value > r) throw Error(`Stage ${e.id} exceeds a preceding stage; cumulative funnel counts must not increase.`);
|
|
91
|
-
r = e.value;
|
|
92
|
-
}
|
|
93
|
-
let i = t[0]?.value;
|
|
94
|
-
return t.map((e, n) => {
|
|
95
|
-
let r = t[n - 1]?.value;
|
|
96
|
-
return {
|
|
97
|
-
...e,
|
|
98
|
-
share: e.value !== null && i != null && i > 0 ? e.value / i : null,
|
|
99
|
-
conversion: e.value !== null && r != null && r > 0 ? e.value / r : null,
|
|
100
|
-
drop: e.value !== null && r != null ? r - e.value : null
|
|
101
|
-
};
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
//#endregion
|
|
105
|
-
export { i as a, a as i, n, e as o, r, t as s, s as t };
|