@santi020k/lumen-core 0.3.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 +22 -0
- package/dist/charts.d.ts +106 -0
- package/dist/charts.d.ts.map +1 -0
- package/dist/charts.js +380 -0
- package/dist/code.d.ts.map +1 -1
- package/dist/code.js +45 -34
- package/dist/components.d.ts +864 -2
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +284 -2
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +3 -3
- package/dist/figma.d.ts.map +1 -1
- package/dist/forms.d.ts +29 -0
- package/dist/forms.d.ts.map +1 -0
- package/dist/forms.js +75 -0
- package/dist/icons.d.ts +9 -1
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +58 -11
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/props.d.ts +1 -2
- package/dist/props.d.ts.map +1 -1
- package/dist/props.js +1 -1
- package/dist/schedule.d.ts.map +1 -1
- package/dist/schedule.js +7 -7
- package/dist/theme-builder.d.ts.map +1 -1
- package/dist/theme-builder.js +23 -8
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +23 -8
- package/dist/tokens.d.ts +19 -1
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +19 -1
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -7,6 +7,28 @@ Most consumers should install a framework package such as `@santi020k/lumen-astr
|
|
|
7
7
|
The package exports `lumenColors` and `lumenGlass` for consumers that need to mirror Lumen theme
|
|
8
8
|
tokens outside the shared stylesheet.
|
|
9
9
|
|
|
10
|
+
## Chart Helpers
|
|
11
|
+
|
|
12
|
+
`@santi020k/lumen-core/charts` exports the shared `LumenChartSeries` contract plus deterministic
|
|
13
|
+
domain, tick, scaling, line/area, grouped/stacked bar, and pie/donut geometry helpers. They render
|
|
14
|
+
no DOM and perform no statistical analysis; framework packages use them to keep chart output
|
|
15
|
+
aligned.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import {
|
|
19
|
+
createLumenLineGeometry,
|
|
20
|
+
type LumenChartSeries
|
|
21
|
+
} from '@santi020k/lumen-core/charts'
|
|
22
|
+
|
|
23
|
+
const series: LumenChartSeries = {
|
|
24
|
+
id: 'views',
|
|
25
|
+
label: 'Views',
|
|
26
|
+
data: [{ x: 'Mon', y: 42 }, { x: 'Tue', y: 68 }]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
createLumenLineGeometry(series.data)
|
|
30
|
+
```
|
|
31
|
+
|
|
10
32
|
It also exports the Lucide-backed icon map (`lumenIcons`, `lumenIconNames`) and helpers such as
|
|
11
33
|
`renderLumenIconSvg` so framework adapters can render icons by name.
|
|
12
34
|
|
package/dist/charts.d.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export declare const lumenChartTones: readonly ["series-1", "series-2", "series-3", "series-4", "series-5", "series-6", "series-7", "series-8", "brand", "accent", "success", "warning", "danger", "neutral"];
|
|
2
|
+
export type LumenChartTone = (typeof lumenChartTones)[number];
|
|
3
|
+
export interface LumenChartDatum {
|
|
4
|
+
label?: string;
|
|
5
|
+
tone?: LumenChartTone;
|
|
6
|
+
x: number | string;
|
|
7
|
+
xLabel?: string;
|
|
8
|
+
y: number | null;
|
|
9
|
+
}
|
|
10
|
+
export interface LumenChartSeries {
|
|
11
|
+
data: readonly LumenChartDatum[];
|
|
12
|
+
id: string;
|
|
13
|
+
label: string;
|
|
14
|
+
tone?: LumenChartTone;
|
|
15
|
+
}
|
|
16
|
+
export interface LumenChartDomain {
|
|
17
|
+
max: number;
|
|
18
|
+
min: number;
|
|
19
|
+
}
|
|
20
|
+
export interface LumenChartGeometryPoint extends LumenChartDatum {
|
|
21
|
+
xCoordinate: number;
|
|
22
|
+
yCoordinate: number;
|
|
23
|
+
}
|
|
24
|
+
export interface LumenLineGeometry {
|
|
25
|
+
areaPaths: readonly string[];
|
|
26
|
+
domain: LumenChartDomain;
|
|
27
|
+
path: string;
|
|
28
|
+
points: readonly LumenChartGeometryPoint[];
|
|
29
|
+
}
|
|
30
|
+
export interface LumenLineGeometryOptions {
|
|
31
|
+
domain?: Partial<LumenChartDomain>;
|
|
32
|
+
height?: number;
|
|
33
|
+
includeZero?: boolean;
|
|
34
|
+
padding?: number;
|
|
35
|
+
width?: number;
|
|
36
|
+
}
|
|
37
|
+
export type LumenBarChartLayout = 'grouped' | 'stacked';
|
|
38
|
+
export type LumenChartOrientation = 'horizontal' | 'vertical';
|
|
39
|
+
export interface LumenBarGeometryMark {
|
|
40
|
+
category: number | string;
|
|
41
|
+
height: number;
|
|
42
|
+
seriesId: string;
|
|
43
|
+
seriesLabel: string;
|
|
44
|
+
tone: LumenChartTone;
|
|
45
|
+
value: number;
|
|
46
|
+
width: number;
|
|
47
|
+
x: number;
|
|
48
|
+
y: number;
|
|
49
|
+
}
|
|
50
|
+
export interface LumenBarGeometryCategory {
|
|
51
|
+
category: number | string;
|
|
52
|
+
label: number | string;
|
|
53
|
+
x: number;
|
|
54
|
+
y: number;
|
|
55
|
+
}
|
|
56
|
+
export interface LumenBarGeometry {
|
|
57
|
+
categories: readonly LumenBarGeometryCategory[];
|
|
58
|
+
domain: LumenChartDomain;
|
|
59
|
+
height: number;
|
|
60
|
+
marks: readonly LumenBarGeometryMark[];
|
|
61
|
+
width: number;
|
|
62
|
+
}
|
|
63
|
+
export interface LumenBarGeometryOptions {
|
|
64
|
+
categoryWidth?: number;
|
|
65
|
+
height?: number;
|
|
66
|
+
layout?: LumenBarChartLayout;
|
|
67
|
+
orientation?: LumenChartOrientation;
|
|
68
|
+
width?: number;
|
|
69
|
+
}
|
|
70
|
+
export type LumenPieChartVariant = 'donut' | 'pie';
|
|
71
|
+
export interface LumenPieGeometrySlice {
|
|
72
|
+
label: string;
|
|
73
|
+
path: string;
|
|
74
|
+
percentage: number;
|
|
75
|
+
tone: LumenChartTone;
|
|
76
|
+
value: number;
|
|
77
|
+
x: number | string;
|
|
78
|
+
}
|
|
79
|
+
export interface LumenPieGeometry {
|
|
80
|
+
center: number;
|
|
81
|
+
innerRadius: number;
|
|
82
|
+
outerRadius: number;
|
|
83
|
+
size: number;
|
|
84
|
+
slices: readonly LumenPieGeometrySlice[];
|
|
85
|
+
total: number;
|
|
86
|
+
}
|
|
87
|
+
export interface LumenPieGeometryOptions {
|
|
88
|
+
padding?: number;
|
|
89
|
+
size?: number;
|
|
90
|
+
variant?: LumenPieChartVariant;
|
|
91
|
+
}
|
|
92
|
+
export declare const hasLumenChartData: (series: readonly LumenChartSeries[]) => boolean;
|
|
93
|
+
export declare const hasLumenPieData: (data: readonly LumenChartDatum[]) => boolean;
|
|
94
|
+
export declare const getLumenChartDomain: (values: readonly (number | null)[], includeZero?: boolean) => LumenChartDomain;
|
|
95
|
+
export declare const scaleLumenChartValue: (value: number, domain: LumenChartDomain, rangeStart: number, rangeEnd: number) => number;
|
|
96
|
+
export declare const getLumenChartTicks: (domain: LumenChartDomain, count?: number) => number[];
|
|
97
|
+
export declare const resolveLumenChartTone: (tone: LumenChartTone | undefined, index?: number) => LumenChartTone;
|
|
98
|
+
export declare const getLumenChartToneClassName: (tone: LumenChartTone | undefined, index?: number) => string;
|
|
99
|
+
export declare const getLumenPieChartVariantClassName: (variant: LumenPieChartVariant) => string;
|
|
100
|
+
export declare const createLumenPieGeometry: (data: readonly LumenChartDatum[], options?: LumenPieGeometryOptions) => LumenPieGeometry;
|
|
101
|
+
export declare const createLumenLineGeometry: (data: readonly LumenChartDatum[], options?: LumenLineGeometryOptions) => LumenLineGeometry;
|
|
102
|
+
export declare const getLumenChartValueRatio: (value: number, domain: LumenChartDomain) => number;
|
|
103
|
+
export declare const getLumenChartCategories: (series: readonly LumenChartSeries[]) => (number | string)[];
|
|
104
|
+
export declare const alignLumenChartSeries: (series: LumenChartSeries, categories: readonly (number | string)[]) => LumenChartSeries;
|
|
105
|
+
export declare const createLumenBarGeometry: (series: readonly LumenChartSeries[], options?: LumenBarGeometryOptions) => LumenBarGeometry;
|
|
106
|
+
//# sourceMappingURL=charts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"charts.d.ts","sourceRoot":"","sources":["../src/charts.ts"],"names":[],"mappings":"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"}
|
package/dist/charts.js
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
export const lumenChartTones = [
|
|
2
|
+
'series-1',
|
|
3
|
+
'series-2',
|
|
4
|
+
'series-3',
|
|
5
|
+
'series-4',
|
|
6
|
+
'series-5',
|
|
7
|
+
'series-6',
|
|
8
|
+
'series-7',
|
|
9
|
+
'series-8',
|
|
10
|
+
'brand',
|
|
11
|
+
'accent',
|
|
12
|
+
'success',
|
|
13
|
+
'warning',
|
|
14
|
+
'danger',
|
|
15
|
+
'neutral'
|
|
16
|
+
];
|
|
17
|
+
const lumenChartToneClassNames = {
|
|
18
|
+
accent: 'ui-chart-tone--accent',
|
|
19
|
+
brand: 'ui-chart-tone--brand',
|
|
20
|
+
danger: 'ui-chart-tone--danger',
|
|
21
|
+
neutral: 'ui-chart-tone--neutral',
|
|
22
|
+
'series-1': 'ui-chart-tone--series-1',
|
|
23
|
+
'series-2': 'ui-chart-tone--series-2',
|
|
24
|
+
'series-3': 'ui-chart-tone--series-3',
|
|
25
|
+
'series-4': 'ui-chart-tone--series-4',
|
|
26
|
+
'series-5': 'ui-chart-tone--series-5',
|
|
27
|
+
'series-6': 'ui-chart-tone--series-6',
|
|
28
|
+
'series-7': 'ui-chart-tone--series-7',
|
|
29
|
+
'series-8': 'ui-chart-tone--series-8',
|
|
30
|
+
success: 'ui-chart-tone--success',
|
|
31
|
+
warning: 'ui-chart-tone--warning'
|
|
32
|
+
};
|
|
33
|
+
const lumenPieChartVariantClassNames = {
|
|
34
|
+
donut: 'ui-pie-chart--donut',
|
|
35
|
+
pie: 'ui-pie-chart--pie'
|
|
36
|
+
};
|
|
37
|
+
const defaultChartSize = 100;
|
|
38
|
+
const defaultChartPadding = 4;
|
|
39
|
+
const finiteValues = (values) => values.filter((value) => value !== null && Number.isFinite(value));
|
|
40
|
+
export const hasLumenChartData = (series) => series.some(item => item.data.some(datum => datum.y !== null && Number.isFinite(datum.y)));
|
|
41
|
+
export const hasLumenPieData = (data) => data.some(datum => datum.y !== null && Number.isFinite(datum.y) && datum.y > 0);
|
|
42
|
+
export const getLumenChartDomain = (values, includeZero = true) => {
|
|
43
|
+
const available = finiteValues(values);
|
|
44
|
+
if (available.length === 0)
|
|
45
|
+
return { max: 1, min: 0 };
|
|
46
|
+
let min = Math.min(...available);
|
|
47
|
+
let max = Math.max(...available);
|
|
48
|
+
if (includeZero) {
|
|
49
|
+
min = Math.min(0, min);
|
|
50
|
+
max = Math.max(0, max);
|
|
51
|
+
}
|
|
52
|
+
if (min === max) {
|
|
53
|
+
const offset = Math.abs(min || 1) * 0.1;
|
|
54
|
+
min -= offset;
|
|
55
|
+
max += offset;
|
|
56
|
+
}
|
|
57
|
+
return { max, min };
|
|
58
|
+
};
|
|
59
|
+
export const scaleLumenChartValue = (value, domain, rangeStart, rangeEnd) => {
|
|
60
|
+
const domainSize = domain.max - domain.min;
|
|
61
|
+
if (!Number.isFinite(value) || domainSize === 0)
|
|
62
|
+
return rangeStart;
|
|
63
|
+
const ratio = (value - domain.min) / domainSize;
|
|
64
|
+
return rangeStart + ratio * (rangeEnd - rangeStart);
|
|
65
|
+
};
|
|
66
|
+
export const getLumenChartTicks = (domain, count = 5) => {
|
|
67
|
+
const safeCount = Math.max(2, Math.round(count));
|
|
68
|
+
const step = (domain.max - domain.min) / (safeCount - 1);
|
|
69
|
+
return Array.from({ length: safeCount }, (_, index) => domain.min + step * index);
|
|
70
|
+
};
|
|
71
|
+
export const resolveLumenChartTone = (tone, index = 0) => tone ?? lumenChartTones[index % 8] ?? 'series-1';
|
|
72
|
+
export const getLumenChartToneClassName = (tone, index = 0) => lumenChartToneClassNames[resolveLumenChartTone(tone, index)];
|
|
73
|
+
export const getLumenPieChartVariantClassName = (variant) => lumenPieChartVariantClassNames[variant];
|
|
74
|
+
const polarPoint = (center, radius, angle) => {
|
|
75
|
+
const radians = (angle * Math.PI) / 180;
|
|
76
|
+
return {
|
|
77
|
+
x: center + Math.cos(radians) * radius,
|
|
78
|
+
y: center + Math.sin(radians) * radius
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
const formatPieCoordinate = (value) => value.toFixed(3);
|
|
82
|
+
const pieArc = (radius, largeArc, sweep, point) => [
|
|
83
|
+
'A',
|
|
84
|
+
formatPieCoordinate(radius),
|
|
85
|
+
formatPieCoordinate(radius),
|
|
86
|
+
0,
|
|
87
|
+
largeArc ? 1 : 0,
|
|
88
|
+
sweep,
|
|
89
|
+
formatPieCoordinate(point.x),
|
|
90
|
+
formatPieCoordinate(point.y)
|
|
91
|
+
].join(' ');
|
|
92
|
+
const fullPiePath = (center, outerRadius, innerRadius) => {
|
|
93
|
+
const topOuter = polarPoint(center, outerRadius, -90);
|
|
94
|
+
const bottomOuter = polarPoint(center, outerRadius, 90);
|
|
95
|
+
const outer = [
|
|
96
|
+
`M ${formatPieCoordinate(topOuter.x)} ${formatPieCoordinate(topOuter.y)}`,
|
|
97
|
+
pieArc(outerRadius, true, 1, bottomOuter),
|
|
98
|
+
pieArc(outerRadius, true, 1, topOuter),
|
|
99
|
+
'Z'
|
|
100
|
+
];
|
|
101
|
+
if (innerRadius === 0)
|
|
102
|
+
return outer.join(' ');
|
|
103
|
+
const topInner = polarPoint(center, innerRadius, -90);
|
|
104
|
+
const bottomInner = polarPoint(center, innerRadius, 90);
|
|
105
|
+
return [
|
|
106
|
+
...outer,
|
|
107
|
+
`M ${formatPieCoordinate(topInner.x)} ${formatPieCoordinate(topInner.y)}`,
|
|
108
|
+
pieArc(innerRadius, true, 0, bottomInner),
|
|
109
|
+
pieArc(innerRadius, true, 0, topInner),
|
|
110
|
+
'Z'
|
|
111
|
+
].join(' ');
|
|
112
|
+
};
|
|
113
|
+
const pieSlicePath = (center, outerRadius, innerRadius, startAngle, endAngle) => {
|
|
114
|
+
if (endAngle - startAngle >= 359.999) {
|
|
115
|
+
return fullPiePath(center, outerRadius, innerRadius);
|
|
116
|
+
}
|
|
117
|
+
const outerStart = polarPoint(center, outerRadius, startAngle);
|
|
118
|
+
const outerEnd = polarPoint(center, outerRadius, endAngle);
|
|
119
|
+
const largeArc = endAngle - startAngle > 180;
|
|
120
|
+
if (innerRadius === 0) {
|
|
121
|
+
return [
|
|
122
|
+
`M ${formatPieCoordinate(center)} ${formatPieCoordinate(center)}`,
|
|
123
|
+
`L ${formatPieCoordinate(outerStart.x)} ${formatPieCoordinate(outerStart.y)}`,
|
|
124
|
+
pieArc(outerRadius, largeArc, 1, outerEnd),
|
|
125
|
+
'Z'
|
|
126
|
+
].join(' ');
|
|
127
|
+
}
|
|
128
|
+
const innerStart = polarPoint(center, innerRadius, startAngle);
|
|
129
|
+
const innerEnd = polarPoint(center, innerRadius, endAngle);
|
|
130
|
+
return [
|
|
131
|
+
`M ${formatPieCoordinate(outerStart.x)} ${formatPieCoordinate(outerStart.y)}`,
|
|
132
|
+
pieArc(outerRadius, largeArc, 1, outerEnd),
|
|
133
|
+
`L ${formatPieCoordinate(innerEnd.x)} ${formatPieCoordinate(innerEnd.y)}`,
|
|
134
|
+
pieArc(innerRadius, largeArc, 0, innerStart),
|
|
135
|
+
'Z'
|
|
136
|
+
].join(' ');
|
|
137
|
+
};
|
|
138
|
+
export const createLumenPieGeometry = (data, options = {}) => {
|
|
139
|
+
const size = Math.max(1, options.size ?? 320);
|
|
140
|
+
const padding = Math.max(0, options.padding ?? 12);
|
|
141
|
+
const center = size / 2;
|
|
142
|
+
const outerRadius = Math.max(0, center - padding);
|
|
143
|
+
const innerRadius = options.variant === 'pie' ? 0 : outerRadius * 0.58;
|
|
144
|
+
const available = data.filter((datum) => datum.y !== null && Number.isFinite(datum.y) && datum.y > 0);
|
|
145
|
+
const total = available.reduce((sum, datum) => sum + datum.y, 0);
|
|
146
|
+
let angle = -90;
|
|
147
|
+
const slices = available.map((datum, index) => {
|
|
148
|
+
const percentage = total === 0 ? 0 : datum.y / total;
|
|
149
|
+
const startAngle = angle;
|
|
150
|
+
const endAngle = index === available.length - 1 ? 270 : startAngle + percentage * 360;
|
|
151
|
+
angle = endAngle;
|
|
152
|
+
return {
|
|
153
|
+
label: datum.label ?? datum.xLabel ?? String(datum.x),
|
|
154
|
+
path: pieSlicePath(center, outerRadius, innerRadius, startAngle, endAngle),
|
|
155
|
+
percentage,
|
|
156
|
+
tone: resolveLumenChartTone(datum.tone, index),
|
|
157
|
+
value: datum.y,
|
|
158
|
+
x: datum.x
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
return {
|
|
162
|
+
center,
|
|
163
|
+
innerRadius,
|
|
164
|
+
outerRadius,
|
|
165
|
+
size,
|
|
166
|
+
slices,
|
|
167
|
+
total
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
const splitGeometrySegments = (data, domain, width, height, padding) => {
|
|
171
|
+
const drawableWidth = Math.max(0, width - padding * 2);
|
|
172
|
+
const drawableHeight = Math.max(0, height - padding * 2);
|
|
173
|
+
const denominator = Math.max(1, data.length - 1);
|
|
174
|
+
const segments = [];
|
|
175
|
+
let current = [];
|
|
176
|
+
for (const [index, datum] of data.entries()) {
|
|
177
|
+
if (datum.y === null || !Number.isFinite(datum.y)) {
|
|
178
|
+
if (current.length > 0)
|
|
179
|
+
segments.push(current);
|
|
180
|
+
current = [];
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
current.push({
|
|
184
|
+
...datum,
|
|
185
|
+
xCoordinate: padding +
|
|
186
|
+
(data.length === 1 ? 0.5 : index / denominator) * drawableWidth,
|
|
187
|
+
yCoordinate: scaleLumenChartValue(datum.y, domain, padding + drawableHeight, padding)
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
if (current.length > 0)
|
|
191
|
+
segments.push(current);
|
|
192
|
+
return segments;
|
|
193
|
+
};
|
|
194
|
+
const segmentPath = (points) => points
|
|
195
|
+
.map((point, index) => `${index === 0 ? 'M' : 'L'} ${point.xCoordinate.toFixed(3)} ${point.yCoordinate.toFixed(3)}`)
|
|
196
|
+
.join(' ');
|
|
197
|
+
export const createLumenLineGeometry = (data, options = {}) => {
|
|
198
|
+
const width = options.width ?? defaultChartSize;
|
|
199
|
+
const height = options.height ?? defaultChartSize;
|
|
200
|
+
const padding = options.padding ?? defaultChartPadding;
|
|
201
|
+
const calculatedDomain = getLumenChartDomain(data.map(datum => datum.y), options.includeZero ?? false);
|
|
202
|
+
const domain = {
|
|
203
|
+
max: options.domain?.max ?? calculatedDomain.max,
|
|
204
|
+
min: options.domain?.min ?? calculatedDomain.min
|
|
205
|
+
};
|
|
206
|
+
const segments = splitGeometrySegments(data, domain, width, height, padding);
|
|
207
|
+
const baseline = scaleLumenChartValue(Math.max(domain.min, Math.min(domain.max, 0)), domain, height - padding, padding);
|
|
208
|
+
return {
|
|
209
|
+
areaPaths: segments
|
|
210
|
+
.map(points => {
|
|
211
|
+
const first = points[0];
|
|
212
|
+
const last = points[points.length - 1];
|
|
213
|
+
if (!first || !last)
|
|
214
|
+
return '';
|
|
215
|
+
return [
|
|
216
|
+
segmentPath(points),
|
|
217
|
+
'L',
|
|
218
|
+
last.xCoordinate.toFixed(3),
|
|
219
|
+
baseline.toFixed(3),
|
|
220
|
+
'L',
|
|
221
|
+
first.xCoordinate.toFixed(3),
|
|
222
|
+
baseline.toFixed(3),
|
|
223
|
+
'Z'
|
|
224
|
+
].join(' ');
|
|
225
|
+
})
|
|
226
|
+
.filter(Boolean),
|
|
227
|
+
domain,
|
|
228
|
+
path: segments.map(segmentPath).join(' '),
|
|
229
|
+
points: segments.flat()
|
|
230
|
+
};
|
|
231
|
+
};
|
|
232
|
+
export const getLumenChartValueRatio = (value, domain) => {
|
|
233
|
+
const ratio = scaleLumenChartValue(value, domain, 0, 1);
|
|
234
|
+
return Math.max(0, Math.min(1, ratio));
|
|
235
|
+
};
|
|
236
|
+
export const getLumenChartCategories = (series) => {
|
|
237
|
+
const categories = new Map();
|
|
238
|
+
for (const item of series) {
|
|
239
|
+
for (const datum of item.data) {
|
|
240
|
+
const key = `${typeof datum.x}:${String(datum.x)}`;
|
|
241
|
+
if (!categories.has(key))
|
|
242
|
+
categories.set(key, datum.x);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return [...categories.values()];
|
|
246
|
+
};
|
|
247
|
+
export const alignLumenChartSeries = (series, categories) => ({
|
|
248
|
+
...series,
|
|
249
|
+
data: categories.map(category => series.data.find(datum => datum.x === category) ?? {
|
|
250
|
+
x: category,
|
|
251
|
+
y: null
|
|
252
|
+
})
|
|
253
|
+
});
|
|
254
|
+
const getDatumValue = (series, category) => series.data.find(datum => datum.x === category)?.y ?? 0;
|
|
255
|
+
const getStackedDomain = (series, categories) => {
|
|
256
|
+
const totals = categories.flatMap(category => {
|
|
257
|
+
let positive = 0;
|
|
258
|
+
let negative = 0;
|
|
259
|
+
for (const item of series) {
|
|
260
|
+
const value = getDatumValue(item, category);
|
|
261
|
+
if (value >= 0)
|
|
262
|
+
positive += value;
|
|
263
|
+
else
|
|
264
|
+
negative += value;
|
|
265
|
+
}
|
|
266
|
+
return [negative, positive];
|
|
267
|
+
});
|
|
268
|
+
return getLumenChartDomain(totals);
|
|
269
|
+
};
|
|
270
|
+
const getBarStartValue = (layout, value, positiveOffset, negativeOffset) => {
|
|
271
|
+
if (layout !== 'stacked')
|
|
272
|
+
return 0;
|
|
273
|
+
return value >= 0 ? positiveOffset : negativeOffset;
|
|
274
|
+
};
|
|
275
|
+
/* eslint-disable complexity -- Bar geometry deliberately keeps both orientations and layouts in one deterministic pass. */
|
|
276
|
+
export const createLumenBarGeometry = (series, options = {}) => {
|
|
277
|
+
const width = options.width ?? 640;
|
|
278
|
+
const height = options.height ?? 320;
|
|
279
|
+
const orientation = options.orientation ?? 'vertical';
|
|
280
|
+
const layout = options.layout ?? 'grouped';
|
|
281
|
+
const categories = getLumenChartCategories(series);
|
|
282
|
+
const values = series.flatMap(item => item.data.map(datum => datum.y));
|
|
283
|
+
const domain = layout === 'stacked' ?
|
|
284
|
+
getStackedDomain(series, categories) :
|
|
285
|
+
getLumenChartDomain(values);
|
|
286
|
+
const margin = orientation === 'horizontal' ?
|
|
287
|
+
{
|
|
288
|
+
bottom: 24,
|
|
289
|
+
left: Math.max(64, Math.min(240, options.categoryWidth ?? 112)),
|
|
290
|
+
right: 20,
|
|
291
|
+
top: 16
|
|
292
|
+
} :
|
|
293
|
+
{ bottom: 52, left: 52, right: 16, top: 16 };
|
|
294
|
+
const plotWidth = Math.max(1, width - margin.left - margin.right);
|
|
295
|
+
const plotHeight = Math.max(1, height - margin.top - margin.bottom);
|
|
296
|
+
const categorySize = (orientation === 'horizontal' ? plotHeight : plotWidth) /
|
|
297
|
+
Math.max(1, categories.length);
|
|
298
|
+
const categoryGap = Math.min(16, categorySize * 0.24);
|
|
299
|
+
const usableCategorySize = Math.max(1, categorySize - categoryGap);
|
|
300
|
+
const seriesSize = usableCategorySize / Math.max(1, series.length);
|
|
301
|
+
const marks = [];
|
|
302
|
+
const categoryPositions = [];
|
|
303
|
+
for (const [categoryIndex, category] of categories.entries()) {
|
|
304
|
+
const categoryStart = (orientation === 'horizontal' ? margin.top : margin.left) +
|
|
305
|
+
categoryIndex * categorySize +
|
|
306
|
+
categoryGap / 2;
|
|
307
|
+
let positiveOffset = 0;
|
|
308
|
+
let negativeOffset = 0;
|
|
309
|
+
categoryPositions.push({
|
|
310
|
+
category,
|
|
311
|
+
label: series
|
|
312
|
+
.flatMap(item => item.data)
|
|
313
|
+
.find(datum => datum.x === category)?.xLabel ?? category,
|
|
314
|
+
x: orientation === 'horizontal' ?
|
|
315
|
+
margin.left - 8 :
|
|
316
|
+
categoryStart + usableCategorySize / 2,
|
|
317
|
+
y: orientation === 'horizontal' ?
|
|
318
|
+
categoryStart + usableCategorySize / 2 :
|
|
319
|
+
height - 20
|
|
320
|
+
});
|
|
321
|
+
for (const [seriesIndex, item] of series.entries()) {
|
|
322
|
+
const value = getDatumValue(item, category);
|
|
323
|
+
const tone = resolveLumenChartTone(item.tone, seriesIndex);
|
|
324
|
+
if (orientation === 'horizontal') {
|
|
325
|
+
const startValue = getBarStartValue(layout, value, positiveOffset, negativeOffset);
|
|
326
|
+
const endValue = startValue + value;
|
|
327
|
+
const start = scaleLumenChartValue(startValue, domain, margin.left, margin.left + plotWidth);
|
|
328
|
+
const end = scaleLumenChartValue(endValue, domain, margin.left, margin.left + plotWidth);
|
|
329
|
+
marks.push({
|
|
330
|
+
category,
|
|
331
|
+
height: layout === 'stacked' ?
|
|
332
|
+
usableCategorySize :
|
|
333
|
+
Math.max(1, seriesSize - 2),
|
|
334
|
+
seriesId: item.id,
|
|
335
|
+
seriesLabel: item.label,
|
|
336
|
+
tone,
|
|
337
|
+
value,
|
|
338
|
+
width: Math.abs(end - start),
|
|
339
|
+
x: Math.min(start, end),
|
|
340
|
+
y: categoryStart +
|
|
341
|
+
(layout === 'stacked' ? 0 : seriesIndex * seriesSize + 1)
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
const startValue = getBarStartValue(layout, value, positiveOffset, negativeOffset);
|
|
346
|
+
const endValue = startValue + value;
|
|
347
|
+
const start = scaleLumenChartValue(startValue, domain, margin.top + plotHeight, margin.top);
|
|
348
|
+
const end = scaleLumenChartValue(endValue, domain, margin.top + plotHeight, margin.top);
|
|
349
|
+
marks.push({
|
|
350
|
+
category,
|
|
351
|
+
height: Math.abs(end - start),
|
|
352
|
+
seriesId: item.id,
|
|
353
|
+
seriesLabel: item.label,
|
|
354
|
+
tone,
|
|
355
|
+
value,
|
|
356
|
+
width: layout === 'stacked' ?
|
|
357
|
+
usableCategorySize :
|
|
358
|
+
Math.max(1, seriesSize - 2),
|
|
359
|
+
x: categoryStart +
|
|
360
|
+
(layout === 'stacked' ? 0 : seriesIndex * seriesSize + 1),
|
|
361
|
+
y: Math.min(start, end)
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
if (layout === 'stacked') {
|
|
365
|
+
if (value >= 0)
|
|
366
|
+
positiveOffset += value;
|
|
367
|
+
else
|
|
368
|
+
negativeOffset += value;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
categories: categoryPositions,
|
|
374
|
+
domain,
|
|
375
|
+
height,
|
|
376
|
+
marks,
|
|
377
|
+
width
|
|
378
|
+
};
|
|
379
|
+
};
|
|
380
|
+
/* eslint-enable complexity */
|
package/dist/code.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../src/code.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../src/code.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAC5B,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEjE,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,kBAAkB,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,eAAO,MAAM,wBAAwB;;;;;;;CAOkB,CAAA;AAiPvD,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,WAc9C,CAAA;AA0LD,eAAO,MAAM,iBAAiB,GAC5B,MAAM,MAAM,EACZ,iBAAa,KACZ,cAAc,EA0BhB,CAAA;AAeD,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,EAAE,iBAAa,WAA6E,CAAA"}
|
package/dist/code.js
CHANGED
|
@@ -14,11 +14,7 @@ const bashLikeLanguages = new Set([
|
|
|
14
14
|
'terminal',
|
|
15
15
|
'zsh'
|
|
16
16
|
]);
|
|
17
|
-
const jsonLikeLanguages = new Set([
|
|
18
|
-
'json',
|
|
19
|
-
'json5',
|
|
20
|
-
'jsonc'
|
|
21
|
-
]);
|
|
17
|
+
const jsonLikeLanguages = new Set(['json', 'json5', 'jsonc']);
|
|
22
18
|
const javascriptLikeLanguages = new Set([
|
|
23
19
|
'js',
|
|
24
20
|
'jsx',
|
|
@@ -28,14 +24,8 @@ const javascriptLikeLanguages = new Set([
|
|
|
28
24
|
'tsx',
|
|
29
25
|
'typescript'
|
|
30
26
|
]);
|
|
31
|
-
const luaLikeLanguages = new Set([
|
|
32
|
-
|
|
33
|
-
]);
|
|
34
|
-
const markdownLikeLanguages = new Set([
|
|
35
|
-
'md',
|
|
36
|
-
'markdown',
|
|
37
|
-
'mdx'
|
|
38
|
-
]);
|
|
27
|
+
const luaLikeLanguages = new Set(['lua']);
|
|
28
|
+
const markdownLikeLanguages = new Set(['md', 'markdown', 'mdx']);
|
|
39
29
|
const markupLikeLanguages = new Set([
|
|
40
30
|
'astro',
|
|
41
31
|
'html',
|
|
@@ -44,13 +34,8 @@ const markupLikeLanguages = new Set([
|
|
|
44
34
|
'vue',
|
|
45
35
|
'xml'
|
|
46
36
|
]);
|
|
47
|
-
const sqlLikeLanguages = new Set([
|
|
48
|
-
|
|
49
|
-
]);
|
|
50
|
-
const yamlLikeLanguages = new Set([
|
|
51
|
-
'yaml',
|
|
52
|
-
'yml'
|
|
53
|
-
]);
|
|
37
|
+
const sqlLikeLanguages = new Set(['sql']);
|
|
38
|
+
const yamlLikeLanguages = new Set(['yaml', 'yml']);
|
|
54
39
|
const javascriptKeywords = new Set([
|
|
55
40
|
'as',
|
|
56
41
|
'async',
|
|
@@ -123,11 +108,7 @@ const bashKeywords = new Set([
|
|
|
123
108
|
'unset',
|
|
124
109
|
'while'
|
|
125
110
|
]);
|
|
126
|
-
const jsonKeywords = new Set([
|
|
127
|
-
'false',
|
|
128
|
-
'null',
|
|
129
|
-
'true'
|
|
130
|
-
]);
|
|
111
|
+
const jsonKeywords = new Set(['false', 'null', 'true']);
|
|
131
112
|
const luaKeywords = new Set([
|
|
132
113
|
'and',
|
|
133
114
|
'break',
|
|
@@ -192,14 +173,41 @@ const yamlKeywords = new Set([
|
|
|
192
173
|
'true',
|
|
193
174
|
'yes'
|
|
194
175
|
]);
|
|
195
|
-
const bashTokenPattern =
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
176
|
+
const bashTokenPattern = new RegExp([
|
|
177
|
+
String.raw `#[^\n]*|"(?:\\.|[^"\\])*"|'[^']*'|\$\{?[A-Za-z_][\w]*\}?|`,
|
|
178
|
+
String.raw `--?[A-Za-z][\w-]*|\b[A-Za-z_][\w]*\b|\b\d+(?:\.\d+)?\b|[|&;<>()[\]{}=]+`
|
|
179
|
+
].join(''), 'g');
|
|
180
|
+
const javascriptTokenPattern = new RegExp([
|
|
181
|
+
String.raw `\/\/[^\n]*|\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`,
|
|
182
|
+
'`(?:\\\\.|[^`\\\\])*`|',
|
|
183
|
+
String.raw `\b\d[\d._]*\b|\b[A-Za-z_$][\w$]*\b|[=+\-*%<>!?:.,;()[\]{}|&/]+`
|
|
184
|
+
].join(''), 'g');
|
|
185
|
+
const jsonTokenPattern = new RegExp([
|
|
186
|
+
String.raw `\/\/[^\n]*|\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\])*"|`,
|
|
187
|
+
String.raw `\b(?:false|null|true)\b|-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b|[{},:]|\[|\]`
|
|
188
|
+
].join(''), 'gi');
|
|
189
|
+
const luaTokenPattern = new RegExp([
|
|
190
|
+
String.raw `--\[\[[\s\S]*?\]\]|--[^\n]*|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`,
|
|
191
|
+
String.raw `\b[A-Za-z_][\w]*\b|\b\d+(?:\.\d+)?\b|[=+\-*%<>~#.,:;()[\]{}]+`
|
|
192
|
+
].join(''), 'g');
|
|
193
|
+
const markdownTokenPattern = new RegExp([
|
|
194
|
+
'```[\\s\\S]*?```|`[^`\\n]+`|',
|
|
195
|
+
String.raw `<!--[\s\S]*?-->|^#{1,6}(?=\s)|^>\s?|^\s*(?:[-+*]|\d+\.)\s+|`,
|
|
196
|
+
String.raw `\*\*|__|\*|_|\[[^\]]+\]\([^)]+\)`
|
|
197
|
+
].join(''), 'gm');
|
|
198
|
+
const markupTokenPattern = new RegExp([
|
|
199
|
+
String.raw `<!--[\s\S]*?-->|---|<\/?|\/?>|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`,
|
|
200
|
+
String.raw `\b[A-Za-z_][\w:.-]*\b|[{}=]`
|
|
201
|
+
].join(''), 'g');
|
|
202
|
+
const sqlTokenPattern = new RegExp([
|
|
203
|
+
String.raw `--[^\n]*|\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\])*"|'(?:''|[^'])*'|`,
|
|
204
|
+
String.raw `\b[A-Za-z_][\w$]*\b|\b\d+(?:\.\d+)?\b|[=+\-*%<>!.,;()[\]]+`
|
|
205
|
+
].join(''), 'g');
|
|
206
|
+
const yamlTokenPattern = new RegExp([
|
|
207
|
+
String.raw `#[^\n]*|"(?:\\.|[^"\\])*"|'(?:''|[^'])*'|\b[A-Za-z_][\w.-]*(?=\s*:)|`,
|
|
208
|
+
String.raw `\b(?:false|no|null|off|on|true|yes)\b|\b\d+(?:\.\d+)?\b|`,
|
|
209
|
+
'[{},:&*!?|>@`~-]+|\\[|\\]'
|
|
210
|
+
].join(''), 'gi');
|
|
203
211
|
const leadingWhitespacePattern = /^[\t ]*/;
|
|
204
212
|
const normalizeLanguage = (language = '') => language.trim().toLowerCase();
|
|
205
213
|
const startsWithIdentifierPattern = /^[A-Za-z_$]/;
|
|
@@ -301,7 +309,10 @@ const getMarkupTokenKind = (value, source, start) => {
|
|
|
301
309
|
const closingTagIndex = source.lastIndexOf('>', start);
|
|
302
310
|
if (openingTagIndex < closingTagIndex)
|
|
303
311
|
return undefined;
|
|
304
|
-
const beforeValue = source
|
|
312
|
+
const beforeValue = source
|
|
313
|
+
.slice(openingTagIndex + 1, start)
|
|
314
|
+
.replace('/', '')
|
|
315
|
+
.trim();
|
|
305
316
|
return beforeValue === '' ? 'keyword' : 'type';
|
|
306
317
|
};
|
|
307
318
|
const getSqlTokenKind = (value) => {
|