@tangle-network/charts 0.4.0 → 0.6.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 +69 -24
- package/dist/events-Cw6abvgR.js +491 -0
- package/dist/figure.css +45 -9
- package/dist/index.d.ts +104 -135
- package/dist/index.js +735 -371
- package/dist/react/index.d.ts +50 -15
- package/dist/react/index.js +522 -152
- package/dist/react/live.css +29 -0
- package/dist/timeline-BAjzF-wL.d.ts +183 -0
- package/package.json +25 -13
- package/LICENSE +0 -21
package/dist/react/live.css
CHANGED
|
@@ -25,3 +25,32 @@ line.ov-gridline { stroke: color-mix(in srgb, var(--chart-live-faint, #777) 22%,
|
|
|
25
25
|
.ov-spark { display: block; width: 8em; height: 1.6em; }
|
|
26
26
|
.ov-spark-empty { font-size: .8em; color: var(--chart-live-faint, #777); }
|
|
27
27
|
.ov-tip-line i { display: inline-block; width: .7em; height: .7em; border-radius: 3px; margin-right: .4em; vertical-align: -.05em; }
|
|
28
|
+
/* Recorded events and spans. Colours come from Brand tokens; kinds also differ by stroke pattern and glyph. */
|
|
29
|
+
.ov-mark { stroke-width: 1.5; fill: none; }
|
|
30
|
+
.ov-mark-pass { stroke: var(--chart-live-pass, var(--chart-pass, var(--status-running))); }
|
|
31
|
+
.ov-mark-deadline { stroke: var(--chart-live-fg, var(--chart-ink)); stroke-dasharray: 5 3; }
|
|
32
|
+
.ov-mark-died { stroke: var(--chart-live-danger, var(--chart-breach, var(--status-error))); stroke-width: 2; }
|
|
33
|
+
.ov-mark-event { stroke: var(--chart-live-muted, var(--chart-ink-muted)); stroke-dasharray: 1 3; stroke-linecap: round; }
|
|
34
|
+
.ov-mark-label { fill: var(--chart-live-fg, var(--chart-ink)); font-size: .75em; paint-order: stroke; stroke: var(--chart-live-surface, var(--chart-canvas)); stroke-width: 3px; stroke-linejoin: round; }
|
|
35
|
+
.ov-band-after-pass { fill: color-mix(in srgb, var(--chart-live-pass, var(--chart-pass, var(--status-running))) 12%, transparent); }
|
|
36
|
+
.ov-band-idle { fill: var(--chart-live-hover, var(--chart-shade)); }
|
|
37
|
+
/* Missing data is hatched, never drawn as zero. */
|
|
38
|
+
.ov-hatch-bg { fill: color-mix(in srgb, var(--chart-live-faint, var(--chart-muted)) 10%, transparent); }
|
|
39
|
+
.ov-hatch { fill: none; stroke: var(--chart-live-faint, var(--chart-muted)); stroke-width: 1; }
|
|
40
|
+
.ov-hatched { background: repeating-linear-gradient(135deg, var(--chart-live-faint, var(--chart-muted)) 0 1px, transparent 1px 5px), color-mix(in srgb, var(--chart-live-faint, var(--chart-muted)) 10%, transparent); }
|
|
41
|
+
.ov-now { stroke: var(--chart-live-fg, var(--chart-ink)); stroke-width: 1.5; }
|
|
42
|
+
.ov-gantt-open { stroke: var(--chart-live-fg, var(--chart-ink)); stroke-width: 1.5; stroke-dasharray: 3 2; }
|
|
43
|
+
.ov-events, .ov-key, .ov-meter-key { list-style: none; margin: .4em 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: .2em 1em; font-size: .8em; color: var(--chart-live-muted, var(--chart-ink-muted)); }
|
|
44
|
+
.ov-key li, .ov-events li, .ov-meter-key li { display: inline-flex; align-items: center; gap: .4em; }
|
|
45
|
+
.ov-meter-key b { font-weight: 500; color: var(--chart-live-fg, var(--chart-ink)); font-family: var(--chart-live-font-mono, monospace); font-variant-numeric: tabular-nums; }
|
|
46
|
+
.ov-meter-key i, .ov-event-swatch { display: inline-block; width: .8em; height: .8em; border-radius: 2px; }
|
|
47
|
+
[data-segmented] > .ov-meter-track { display: flex; }
|
|
48
|
+
[data-segmented] > .ov-meter-track > span { flex: none; border-radius: 0; }
|
|
49
|
+
.ov-event-pass { border-left: 2px solid var(--chart-live-pass, var(--chart-pass, var(--status-running))); border-radius: 0; width: 0; }
|
|
50
|
+
.ov-event-deadline { border-left: 2px dashed var(--chart-live-fg, var(--chart-ink)); border-radius: 0; width: 0; }
|
|
51
|
+
.ov-event-died { border-left: 2px solid var(--chart-live-danger, var(--chart-breach, var(--status-error))); border-radius: 0; width: 0; }
|
|
52
|
+
.ov-event-event { border-left: 2px dotted var(--chart-live-muted, var(--chart-ink-muted)); border-radius: 0; width: 0; }
|
|
53
|
+
.ov-event-after-pass { background: color-mix(in srgb, var(--chart-live-pass, var(--chart-pass, var(--status-running))) 25%, transparent); }
|
|
54
|
+
.ov-event-idle { background: var(--chart-live-hover, var(--chart-shade)); }
|
|
55
|
+
.ov-event-missing { background: repeating-linear-gradient(135deg, var(--chart-live-faint, var(--chart-muted)) 0 1px, transparent 1px 4px); }
|
|
56
|
+
.ov-refusal { margin: 0; color: var(--chart-live-muted, var(--chart-ink-muted)); font-size: .9em; }
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
//#region src/types.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Inputs and outputs of the figure functions.
|
|
4
|
+
*
|
|
5
|
+
* The library draws and never decides. Ranks, intervals, frontier membership,
|
|
6
|
+
* estimate labels and pass counts arrive from the producer (a board record, a
|
|
7
|
+
* VerticalBench report, an agent-eval lens). A figure function returns a
|
|
8
|
+
* `Refusal` instead of a figure it cannot draw honestly.
|
|
9
|
+
*/
|
|
10
|
+
/** agent-eval `SearchEstimateMethod`, the same strings: what a unit count supports. */
|
|
11
|
+
type Estimate = "none" | "insufficient" | "descriptive" | "bootstrap";
|
|
12
|
+
type IntervalMethod = "task-cluster-bootstrap" | "mcnemar-exact" | "wilson";
|
|
13
|
+
/**
|
|
14
|
+
* A confidence interval as the producer recorded it. `level` and `method` are
|
|
15
|
+
* nullable because real records omit them; a figure refuses to draw an
|
|
16
|
+
* interval that does not name both.
|
|
17
|
+
*/
|
|
18
|
+
interface Interval {
|
|
19
|
+
lower: number;
|
|
20
|
+
upper: number;
|
|
21
|
+
level: number | null;
|
|
22
|
+
method: IntervalMethod | null;
|
|
23
|
+
}
|
|
24
|
+
/** The App Grade ladder, lowest first. U (unable to measure) is not on it. */
|
|
25
|
+
type Tier = "F" | "C" | "B" | "A" | "S";
|
|
26
|
+
type TierCounts = Record<Tier, number>;
|
|
27
|
+
/** Where a cost comes from. Only `receipts` is billed spend. */
|
|
28
|
+
type CostBasis = "receipts" | "estimated" | "unknown";
|
|
29
|
+
/** A column or row identity: an AgentProfile, a model, a judge, a search node. */
|
|
30
|
+
interface Setup {
|
|
31
|
+
id: string;
|
|
32
|
+
label: string;
|
|
33
|
+
/** Null when the order is a sort, not a ranking backed by comparisons. */
|
|
34
|
+
rank: number | null;
|
|
35
|
+
}
|
|
36
|
+
/** One setup's rate. Field names follow the board record's `BoardProfile`. */
|
|
37
|
+
interface RateRow extends Setup {
|
|
38
|
+
solved: number;
|
|
39
|
+
attempts: number;
|
|
40
|
+
rate: number;
|
|
41
|
+
/** The producer's label for what `attempts` supports; the library holds no threshold. */
|
|
42
|
+
estimate: Estimate;
|
|
43
|
+
interval: Interval | null;
|
|
44
|
+
tiers: TierCounts | null;
|
|
45
|
+
cost: {
|
|
46
|
+
perSolvedUsd: number | null;
|
|
47
|
+
basis: CostBasis;
|
|
48
|
+
receipts: number | null;
|
|
49
|
+
};
|
|
50
|
+
medianWallMs: number | null;
|
|
51
|
+
/** Null when the producer computed no frontier. */
|
|
52
|
+
onFront: boolean | null;
|
|
53
|
+
}
|
|
54
|
+
/** One task × setup cell. */
|
|
55
|
+
interface MatrixCell {
|
|
56
|
+
task: string;
|
|
57
|
+
setup: string;
|
|
58
|
+
/** Attempts that count; null when the cell never ran. */
|
|
59
|
+
attempts: number | null;
|
|
60
|
+
/** Attempts that passed; null when no pass rule applies. */
|
|
61
|
+
solved: number | null;
|
|
62
|
+
/** Attempts graded on the App Grade ladder. */
|
|
63
|
+
tiers: TierCounts | null;
|
|
64
|
+
/** Attempts graded U: no floor check failed, but one could not be observed. */
|
|
65
|
+
unmeasured?: number;
|
|
66
|
+
/** Attempts whose grade failed an integrity check and awaits human review. */
|
|
67
|
+
flagged?: number;
|
|
68
|
+
/** A lens cell's mean score; null when the setup never scored the task. */
|
|
69
|
+
mean: number | null;
|
|
70
|
+
costUsd: number | null;
|
|
71
|
+
}
|
|
72
|
+
interface ComparisonRow {
|
|
73
|
+
/** Setup ids. */
|
|
74
|
+
favored: string;
|
|
75
|
+
other: string;
|
|
76
|
+
pairs: number | null;
|
|
77
|
+
minimumEffect: number | null;
|
|
78
|
+
/** The clustered interval on the difference, in the measure's units. */
|
|
79
|
+
interval: Interval | null;
|
|
80
|
+
/** The exact interval, drawn under the clustered one when present. */
|
|
81
|
+
exactInterval: Interval | null;
|
|
82
|
+
}
|
|
83
|
+
interface BreakdownInput {
|
|
84
|
+
reasons: string[];
|
|
85
|
+
setups: Array<{
|
|
86
|
+
id: string;
|
|
87
|
+
label: string;
|
|
88
|
+
n: number | null;
|
|
89
|
+
}>;
|
|
90
|
+
counts: Array<{
|
|
91
|
+
reason: string;
|
|
92
|
+
setup: string;
|
|
93
|
+
count: number | null;
|
|
94
|
+
}>;
|
|
95
|
+
excluded: {
|
|
96
|
+
count: number;
|
|
97
|
+
why: string;
|
|
98
|
+
} | null;
|
|
99
|
+
/** True when one attempt can count under several reasons. */
|
|
100
|
+
overlapping?: boolean;
|
|
101
|
+
}
|
|
102
|
+
/** Attempts left out of a figure, stated in its note. */
|
|
103
|
+
interface Exclusion {
|
|
104
|
+
count: number;
|
|
105
|
+
why: string;
|
|
106
|
+
}
|
|
107
|
+
interface Figure {
|
|
108
|
+
id: string;
|
|
109
|
+
/** Generated from the input; no function accepts heading text. */
|
|
110
|
+
finding: string;
|
|
111
|
+
/** One quantified sentence. */
|
|
112
|
+
lede: string;
|
|
113
|
+
/** How to read the marks. */
|
|
114
|
+
read: string;
|
|
115
|
+
/** Wide and phone renders; vertical columns retain a readable minimum width. Null means the phone view uses the table. */
|
|
116
|
+
svg: {
|
|
117
|
+
wide: string;
|
|
118
|
+
narrow: string | null;
|
|
119
|
+
interactive?: boolean;
|
|
120
|
+
};
|
|
121
|
+
/** An HTML table with every number the plot shows. */
|
|
122
|
+
table: string;
|
|
123
|
+
note: {
|
|
124
|
+
method: string;
|
|
125
|
+
n: string;
|
|
126
|
+
exclusions: string[];
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
interface Refusal {
|
|
130
|
+
id: string;
|
|
131
|
+
refused: string;
|
|
132
|
+
}
|
|
133
|
+
declare function isRefusal(value: Figure | Refusal): value is Refusal;
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region src/events.d.ts
|
|
136
|
+
/** `pass` is solid, `deadline` dashed, `died` ends in a cross and `event` is dotted, so kinds read without colour. */
|
|
137
|
+
type MarkKind = "pass" | "deadline" | "died" | "event";
|
|
138
|
+
interface ChartMark {
|
|
139
|
+
at: number;
|
|
140
|
+
label: string;
|
|
141
|
+
kind: MarkKind;
|
|
142
|
+
}
|
|
143
|
+
/** `missing` is hatched: a span with no data is never drawn as zero. */
|
|
144
|
+
type BandKind = "after-pass" | "idle" | "missing";
|
|
145
|
+
interface ChartBand {
|
|
146
|
+
from: number;
|
|
147
|
+
to: number;
|
|
148
|
+
label: string;
|
|
149
|
+
kind: BandKind;
|
|
150
|
+
}
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/timeline.d.ts
|
|
153
|
+
/** Epoch milliseconds. `end: null` is an open span; it needs the figure's `now`. */
|
|
154
|
+
interface TimelineSpan {
|
|
155
|
+
start: number;
|
|
156
|
+
end: number | null;
|
|
157
|
+
state: string;
|
|
158
|
+
note?: string;
|
|
159
|
+
}
|
|
160
|
+
interface TimelineLane {
|
|
161
|
+
id: string;
|
|
162
|
+
label: string;
|
|
163
|
+
spans: TimelineSpan[];
|
|
164
|
+
}
|
|
165
|
+
interface TimelineOptions {
|
|
166
|
+
measure: string;
|
|
167
|
+
/** The recorded window; defaults to the extent of spans, marks, bands and `now`. Everything must fall inside it. */
|
|
168
|
+
start?: number;
|
|
169
|
+
end?: number;
|
|
170
|
+
/** The time an open span is drawn to. Required when any span is open. */
|
|
171
|
+
now?: number;
|
|
172
|
+
marks?: ChartMark[];
|
|
173
|
+
bands?: ChartBand[];
|
|
174
|
+
/** States drawn hatched because their time has no data. Default: missing, untraced. */
|
|
175
|
+
hatch?: string[];
|
|
176
|
+
/** States drawn in the muted tone, such as idle. Default: idle. */
|
|
177
|
+
muted?: string[];
|
|
178
|
+
formatTime?: (ms: number) => string;
|
|
179
|
+
id?: string;
|
|
180
|
+
}
|
|
181
|
+
declare function timeline(lanes: TimelineLane[], o: TimelineOptions): Figure | Refusal;
|
|
182
|
+
//#endregion
|
|
183
|
+
export { isRefusal as C, TierCounts as S, MatrixCell as _, BandKind as a, Setup as b, MarkKind as c, CostBasis as d, Estimate as f, IntervalMethod as g, Interval as h, timeline as i, BreakdownInput as l, Figure as m, TimelineOptions as n, ChartBand as o, Exclusion as p, TimelineSpan as r, ChartMark as s, TimelineLane as t, ComparisonRow as u, RateRow as v, Tier as x, Refusal as y };
|
package/package.json
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/charts",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Static SVG and HTML figures for benchmarks and operational timing. Draws from producer data and refuses what it cannot draw honestly.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/tangle-network/
|
|
10
|
-
"directory": "packages/charts"
|
|
9
|
+
"url": "git+https://github.com/tangle-network/charts.git"
|
|
11
10
|
},
|
|
12
11
|
"bugs": {
|
|
13
|
-
"url": "https://github.com/tangle-network/
|
|
12
|
+
"url": "https://github.com/tangle-network/charts/issues"
|
|
14
13
|
},
|
|
15
|
-
"homepage": "https://github.com/tangle-network/
|
|
14
|
+
"homepage": "https://github.com/tangle-network/charts",
|
|
16
15
|
"sideEffects": [
|
|
17
16
|
"./dist/figure.css",
|
|
18
17
|
"./dist/react/live.css"
|
|
@@ -43,18 +42,31 @@
|
|
|
43
42
|
"optional": true
|
|
44
43
|
}
|
|
45
44
|
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"gen:css": "node scripts/gen-css.mjs",
|
|
47
|
+
"build": "node scripts/gen-css.mjs --check && tsdown && cp src/figure.css dist/figure.css && cp src/react/live.css dist/react/live.css",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"test": "vitest run"
|
|
50
|
+
},
|
|
46
51
|
"devDependencies": {
|
|
52
|
+
"@tangle-network/brand": "1.24.2",
|
|
53
|
+
"@testing-library/react": "^16.3.3",
|
|
54
|
+
"@testing-library/user-event": "^14.6.7",
|
|
55
|
+
"@types/node": "^26.6.3",
|
|
56
|
+
"@types/react": "^19.3.0",
|
|
57
|
+
"@types/react-dom": "^19.2.3",
|
|
58
|
+
"jsdom": "^30.1.1",
|
|
59
|
+
"playwright": "^1.63.0",
|
|
60
|
+
"react": "^19.3.0",
|
|
61
|
+
"react-dom": "^19.3.0",
|
|
47
62
|
"tsdown": "^0.23.0",
|
|
48
|
-
"typescript": "^7.0.2"
|
|
63
|
+
"typescript": "^7.0.2",
|
|
64
|
+
"vitest": "^5.0.2"
|
|
49
65
|
},
|
|
50
66
|
"keywords": [
|
|
51
67
|
"tangle",
|
|
52
68
|
"charts",
|
|
53
69
|
"benchmarks",
|
|
54
70
|
"svg"
|
|
55
|
-
]
|
|
56
|
-
|
|
57
|
-
"gen:css": "node scripts/gen-css.mjs",
|
|
58
|
-
"build": "node scripts/gen-css.mjs --check && tsdown && cp src/figure.css dist/figure.css && cp src/react/live.css dist/react/live.css"
|
|
59
|
-
}
|
|
60
|
-
}
|
|
71
|
+
]
|
|
72
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Tangle Network
|
|
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.
|