@tangle-network/charts 0.3.1 → 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/dist/figure.css CHANGED
@@ -18,9 +18,9 @@
18
18
 
19
19
  .tgc-finding {
20
20
  margin: 0 0 8px;
21
- font-size: 16px;
22
- line-height: 24px;
23
- font-weight: 600;
21
+ font-size: 18px;
22
+ line-height: 25px;
23
+ font-weight: 650;
24
24
  color: var(--chart-ink);
25
25
  }
26
26
 
@@ -40,8 +40,8 @@
40
40
 
41
41
  .tgc-lede {
42
42
  margin: 0 0 16px;
43
- font-size: 14px;
44
- line-height: 22px;
43
+ font-size: 15px;
44
+ line-height: 23px;
45
45
  color: var(--text-secondary, var(--chart-ink));
46
46
  }
47
47
 
@@ -71,8 +71,8 @@
71
71
 
72
72
  .tgc-read {
73
73
  margin: 8px 0 0;
74
- font-size: 12px;
75
- line-height: 16px;
74
+ font-size: 13px;
75
+ line-height: 18px;
76
76
  color: var(--chart-ink-muted);
77
77
  }
78
78
 
@@ -217,7 +217,7 @@
217
217
  .tgc-whisker,
218
218
  .tgc-tick {
219
219
  stroke: var(--chart-ink);
220
- stroke-width: 1.5;
220
+ stroke-width: 2;
221
221
  stroke-linecap: round;
222
222
  }
223
223
  .tgc-threshold {
@@ -311,7 +311,20 @@
311
311
  .tgc-tip-ink { fill: var(--chart-canvas); }
312
312
 
313
313
  .tgc-series-line { fill: none; stroke: var(--chart-accent); stroke-width: 2; stroke-linejoin: round; }
314
- .tgc-series-point { fill: var(--chart-accent); stroke: var(--chart-canvas); stroke-width: 1; }
314
+ .tgc-series-point, .tgc-series-key { fill: var(--chart-accent); stroke: var(--chart-canvas); stroke-width: 2; }
315
+
316
+ /* Semantic states stay tied to Brand status tokens. No-data has its own neutral mark. */
317
+ .tgc-heat-pass { fill: color-mix(in srgb, var(--chart-pass, var(--status-running)) 19%, var(--chart-canvas)); stroke: var(--chart-pass, var(--status-running)); stroke-width: .8; }
318
+ .tgc-heat-breach { fill: color-mix(in srgb, var(--chart-breach, var(--status-error)) 17%, var(--chart-canvas)); stroke: var(--chart-breach, var(--status-error)); stroke-width: .8; }
319
+ .tgc-heat-no-data { fill: var(--chart-grid); stroke: var(--chart-rule); stroke-width: .8; }
320
+ .tgc-heat-label { fill: var(--chart-ink); }
321
+ .tgc-heat-missing { fill: var(--chart-ink-muted); }
322
+ .tgc-wide:has(.tgc-heat-pass), .tgc-wide:has(.tgc-heat-breach) { overflow-x: auto; }
323
+ .tgc-range-pass { fill: var(--chart-pass, var(--status-running)); }
324
+ .tgc-range-breach { fill: var(--chart-breach, var(--status-error)); }
325
+ .tgc-range-dot-pass { fill: var(--chart-canvas); stroke: var(--chart-pass, var(--status-running)); stroke-width: 3; }
326
+ .tgc-range-dot-breach { fill: var(--chart-canvas); stroke: var(--chart-breach, var(--status-error)); stroke-width: 3; }
327
+ .tgc-waterfall-bar { fill: var(--chart-accent); }
315
328
  .tgc-series-hit { fill: transparent; stroke: transparent; }
316
329
  .tgc-series-observation:focus-visible { outline: none; }
317
330
  .tgc-series-observation:focus-visible .tgc-series-hit { stroke: var(--chart-ink); stroke-width: 2; }
@@ -332,3 +345,26 @@
332
345
 
333
346
  .tgc-figure-plot .tgc-wide-fallback svg { min-width: var(--tgc-fallback-width); }
334
347
  .tgc-phone-plot:focus-visible, .tgc-wide-fallback:focus-visible { outline: 2px solid var(--chart-accent); outline-offset: 2px; }
348
+
349
+ /* Recorded events and spans. Kinds differ by stroke pattern as well as token, so they read without colour. */
350
+ .tgc-mark { stroke-width: 1.5; }
351
+ .tgc-mark-pass { stroke: var(--chart-pass, var(--status-running)); }
352
+ .tgc-mark-deadline { stroke: var(--chart-ink); stroke-dasharray: 5 3; }
353
+ .tgc-mark-died { stroke: var(--chart-breach, var(--status-error)); stroke-width: 2; }
354
+ .tgc-mark-event { stroke: var(--chart-ink-muted); stroke-dasharray: 1 3; stroke-linecap: round; }
355
+ .tgc-mark-label { fill: var(--chart-ink); paint-order: stroke; stroke: var(--chart-canvas); stroke-width: 3px; stroke-linejoin: round; }
356
+ .tgc-band-after-pass { fill: color-mix(in srgb, var(--chart-pass, var(--status-running)) 12%, transparent); }
357
+ .tgc-band-idle { fill: var(--chart-shade); }
358
+ /* Missing data: a neutral wash under hatch lines, never a zero-height mark. */
359
+ .tgc-hatch-bg { fill: color-mix(in srgb, var(--chart-muted) 10%, transparent); }
360
+ .tgc-hatch { fill: none; stroke: var(--chart-muted); stroke-width: 1; }
361
+ .tgc-span { fill: var(--chart-accent); }
362
+ .tgc-span-muted { fill: var(--chart-muted); }
363
+ .tgc-span-open { stroke: var(--chart-ink); stroke-width: 1.5; stroke-dasharray: 3 2; }
364
+ .tgc-now { stroke: var(--chart-ink); stroke-width: 1.5; }
365
+
366
+ /* FigureView (React) picks the render by measured width; the wide plot fills its container. */
367
+ .tgc-figure-view { max-width: none; margin: 0; }
368
+ .tgc-view-plot svg { display: block; overflow: visible; }
369
+ .tgc-view-wide svg { width: 100%; height: auto; }
370
+ .tgc-view-narrow svg { max-width: 100%; height: auto; }
package/dist/index.d.ts CHANGED
@@ -1,137 +1,4 @@
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
- export declare function isRefusal(value: Figure | Refusal): value is Refusal;
134
- //#endregion
1
+ import { C as isRefusal, S as TierCounts, _ as MatrixCell, a as BandKind, b as Setup, c as MarkKind, d as CostBasis, f as Estimate, g as IntervalMethod, h as Interval, i as timeline, l as BreakdownInput, m as Figure, n as TimelineOptions, o as ChartBand, p as Exclusion, r as TimelineSpan, s as ChartMark, t as TimelineLane, u as ComparisonRow, v as RateRow, x as Tier, y as Refusal } from "./timeline-BAjzF-wL.js";
135
2
  //#region src/block.d.ts
136
3
  interface RenderFigureOptions {
137
4
  /** Chart uses a closed data disclosure; plot keeps only the SVG and accessible data. */
@@ -151,6 +18,62 @@ interface BreakdownOptions {
151
18
  }
152
19
  export declare function breakdown(input: BreakdownInput, o: BreakdownOptions): Figure | Refusal;
153
20
  //#endregion
21
+ //#region src/heatmap.d.ts
22
+ type HeatmapStatus = "pass" | "breach" | "no-data";
23
+ interface HeatmapCell {
24
+ status: HeatmapStatus;
25
+ value: number | null;
26
+ }
27
+ interface HeatmapRow {
28
+ id: string;
29
+ label: string;
30
+ cells: HeatmapCell[];
31
+ }
32
+ interface HeatmapColumn {
33
+ id: string;
34
+ label: string;
35
+ }
36
+ interface HeatmapOptions {
37
+ measure: string;
38
+ unit: string;
39
+ formatValue?: (value: number) => string;
40
+ /** Explain what the producer's pass and breach states mean. */
41
+ statusRule: string;
42
+ id?: string;
43
+ }
44
+ export declare function heatmap(columns: HeatmapColumn[], rows: HeatmapRow[], o: HeatmapOptions): Figure | Refusal;
45
+ //#endregion
46
+ //#region src/latency-range.d.ts
47
+ interface LatencyRangeRow {
48
+ id: string;
49
+ label: string;
50
+ p50Ms: number;
51
+ p95Ms: number;
52
+ n: number;
53
+ }
54
+ interface LatencyRangeOptions {
55
+ measure: string;
56
+ sloMs: number;
57
+ minN: number;
58
+ excluded?: string[];
59
+ id?: string;
60
+ }
61
+ export declare function latencyRange(rows: LatencyRangeRow[], o: LatencyRangeOptions): Figure | Refusal;
62
+ //#endregion
63
+ //#region src/phase-waterfall.d.ts
64
+ interface WaterfallPhase {
65
+ id: string;
66
+ label: string;
67
+ ms: number;
68
+ kind?: "measured" | "unaccounted";
69
+ }
70
+ interface PhaseWaterfallOptions {
71
+ measure: string;
72
+ totalMs: number;
73
+ id?: string;
74
+ }
75
+ export declare function phaseWaterfall(phases: WaterfallPhase[], o: PhaseWaterfallOptions): Figure | Refusal;
76
+ //#endregion
154
77
  //#region src/comparison-intervals.d.ts
155
78
  interface ComparisonIntervalsOptions {
156
79
  /** The measure the difference is in, lower case: "solve rate". */
@@ -287,8 +210,54 @@ interface TimeSeriesOptions {
287
210
  };
288
211
  formatX?: (value: number) => string;
289
212
  formatY?: (value: number) => string;
213
+ /** Recorded vertical events on the x axis, such as the first pass, a deadline or a death. Listed in the table. */
214
+ marks?: ChartMark[];
215
+ /** Recorded shaded spans on the x axis, such as time after the first pass or idle time; `missing` is hatched. */
216
+ bands?: ChartBand[];
290
217
  id?: string;
291
218
  }
292
219
  export declare function timeSeries(rows: TimeSeriesRow[], o: TimeSeriesOptions): Figure | Refusal;
293
220
  //#endregion
294
- export type { BreakdownInput, BreakdownOptions, ComparisonIntervalsOptions, ComparisonRow, CostBasis, CostFrontierOptions, Estimate, Exclusion, Figure, Interval, IntervalMethod, MatrixCell, MetricBarsOptions, MetricRow, Observations, RankedRatesOptions, RateIdentity, RateRow, Refusal, RenderFigureOptions, Setup, TaskMatrixOptions, Tier, TierCounts, TimePoint, TimeSeriesOptions, TimeSeriesRow };
221
+ //#region src/small-multiples.d.ts
222
+ interface MultiplePanel {
223
+ id: string;
224
+ label: string;
225
+ /** The panel's recorded unit. Every panel must match the figure's y unit. */
226
+ unit?: string;
227
+ /** The panel's own y domain; required when only the x axis is shared. */
228
+ domain?: [number, number];
229
+ points?: TimePoint[];
230
+ /** The arm produced no data. The panel is hatched and names the reason. */
231
+ missing?: {
232
+ why: string;
233
+ detail?: string;
234
+ };
235
+ /** The arm stopped before the window closed, for example `{ at, kind: "died" }`. */
236
+ end?: {
237
+ at: number;
238
+ kind: MarkKind;
239
+ label?: string;
240
+ };
241
+ marks?: ChartMark[];
242
+ }
243
+ interface SmallMultiplesOptions {
244
+ x: {
245
+ label: string;
246
+ domain: [number, number];
247
+ };
248
+ y: {
249
+ label: string;
250
+ unit: string;
251
+ domain: [number, number];
252
+ };
253
+ /** `both`: every panel on one x and y domain. `x`: one x domain; each panel supplies its own y domain. */
254
+ shared: "both" | "x";
255
+ /** What one panel is, for the lede: "3 of 4 arms have data". Default: panel. */
256
+ noun?: string;
257
+ formatX?: (value: number) => string;
258
+ formatY?: (value: number) => string;
259
+ id?: string;
260
+ }
261
+ export declare function smallMultiples(panels: MultiplePanel[], o: SmallMultiplesOptions): Figure | Refusal;
262
+ //#endregion
263
+ export { type BandKind, type BreakdownInput, type BreakdownOptions, type ChartBand, type ChartMark, type ComparisonIntervalsOptions, type ComparisonRow, type CostBasis, type CostFrontierOptions, type Estimate, type Exclusion, type Figure, type HeatmapCell, type HeatmapColumn, type HeatmapOptions, type HeatmapRow, type HeatmapStatus, type Interval, type IntervalMethod, type LatencyRangeOptions, type LatencyRangeRow, type MarkKind, type MatrixCell, type MetricBarsOptions, type MetricRow, type MultiplePanel, type Observations, type PhaseWaterfallOptions, type RankedRatesOptions, type RateIdentity, type RateRow, type Refusal, type RenderFigureOptions, type Setup, type SmallMultiplesOptions, type TaskMatrixOptions, type Tier, type TierCounts, type TimePoint, type TimeSeriesOptions, type TimeSeriesRow, type TimelineLane, type TimelineOptions, type TimelineSpan, type WaterfallPhase, isRefusal, timeline };