@tangle-network/charts 0.1.4 → 0.1.6
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 +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +17 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,6 +21,8 @@ Intervals without support are marked as not drawn in the data table and note.
|
|
|
21
21
|
Cost-per-pass figures print `unknown` for missing, zero, or unproven cost; zero passes print `no pass`.
|
|
22
22
|
A matrix preserves an observed zero cost as $0 and omits a null cost.
|
|
23
23
|
Rank numbers require every row to carry both a rank and a `bootstrap` estimate.
|
|
24
|
+
For an unranked descriptive report, `rankedRates` accepts `order: "input"` to retain the producer's row order and make no ranking claim.
|
|
25
|
+
The default keeps supported ranks or sorts unranked rows by observed rate.
|
|
24
26
|
Malformed rates, intervals, matrix counts, and breakdown counts return a refusal instead of a misleading mark.
|
|
25
27
|
Unmeasured and flagged matrix attempts keep distinct marks and table counts, even without tier grades.
|
|
26
28
|
An interval whisker is omitted when its bounds exclude the row's rate.
|
package/dist/index.d.ts
CHANGED
|
@@ -180,6 +180,8 @@ export declare function rateOrder<T extends Pick<RateRow, "rank" | "rate" | "est
|
|
|
180
180
|
interface RankedRatesOptions {
|
|
181
181
|
/** What the rate measures, lower case: "solve rate". */
|
|
182
182
|
measure: string;
|
|
183
|
+
/** Preserve unranked input order instead of sorting observed rates. */
|
|
184
|
+
order?: "input";
|
|
183
185
|
/** The App Grade tier a pass needs; marks the tier strip. */
|
|
184
186
|
passTier?: Tier;
|
|
185
187
|
/** Singular, lower-case nouns: what one unit of `attempts` is, and what a row is. */
|
package/dist/index.js
CHANGED
|
@@ -999,7 +999,7 @@ function costFrontier(rows, o) {
|
|
|
999
999
|
row.label,
|
|
1000
1000
|
drawable(row.estimate) ? pct(row.rate) : estimateNote(row.estimate, row.attempts),
|
|
1001
1001
|
kn(row.solved, row.attempts),
|
|
1002
|
-
rateIntervalGap(row) === null ? `${pct(row.interval.lower)}–${pct(row.interval.upper)} (${intervalName(row.interval)},
|
|
1002
|
+
rateIntervalGap(row) === null ? `${pct(row.interval.lower)}–${pct(row.interval.upper)} (${intervalName(row.interval)}, ${row.attempts} attempts)` : `not drawn (${rateIntervalGap(row)})`,
|
|
1003
1003
|
costText(row.cost, row.solved),
|
|
1004
1004
|
row.cost.basis,
|
|
1005
1005
|
row.onFront === null ? "not computed" : row.onFront ? "yes" : "no"
|
|
@@ -1065,7 +1065,7 @@ function narrowList(rows) {
|
|
|
1065
1065
|
const fact = placed ? `${count} · ${costText(row.cost, row.solved)} per pass${row.onFront ? " · on the frontier" : ""}` : `${count} · ${reason}not plotted`;
|
|
1066
1066
|
const facts = fitLines(fact.split(" · "), 358, 12, "mono");
|
|
1067
1067
|
marks += textBlock(facts, 0, cy + 12, 16, `class="tgc-ink-muted tgc-num" font-size="12"`);
|
|
1068
|
-
const interval = rateIntervalGap(row) === null ? ` · ${intervalName(row.interval)} interval ${pct(row.interval.lower)}–${pct(row.interval.upper)},
|
|
1068
|
+
const interval = rateIntervalGap(row) === null ? ` · ${intervalName(row.interval)} interval ${pct(row.interval.lower)}–${pct(row.interval.upper)}, ${row.attempts} attempts` : "";
|
|
1069
1069
|
out += titled(`${row.label} · ${fact}${interval}`, marks);
|
|
1070
1070
|
y = cy + 4 + facts.length * 16;
|
|
1071
1071
|
if (i < rows.length - 1) out += line(0, y + 2, 358, y + 2, "tgc-rule");
|
|
@@ -1228,7 +1228,7 @@ function plot(costed, unplaced, drawLine, o) {
|
|
|
1228
1228
|
}
|
|
1229
1229
|
for (const p of placed) {
|
|
1230
1230
|
const cls = p.row.onFront ? p.estimated ? "tgc-pt-est" : "tgc-pt-front" : "tgc-pt";
|
|
1231
|
-
out += titled(`${p.row.label} · ${pct(p.row.rate)} ${o.measure} · ${kn(p.row.solved, p.row.attempts)} passed · ${costText(p.row.cost, p.row.solved)} per pass${rateIntervalGap(p.row) === null ? ` · ${intervalName(p.row.interval)} interval ${pct(p.row.interval.lower)}–${pct(p.row.interval.upper)},
|
|
1231
|
+
out += titled(`${p.row.label} · ${pct(p.row.rate)} ${o.measure} · ${kn(p.row.solved, p.row.attempts)} passed · ${costText(p.row.cost, p.row.solved)} per pass${rateIntervalGap(p.row) === null ? ` · ${intervalName(p.row.interval)} interval ${pct(p.row.interval.lower)}–${pct(p.row.interval.upper)}, ${p.row.attempts} attempts` : ""}${p.row.onFront ? " · on the frontier" : ""}`, circle(p.x, p.y, 4, cls));
|
|
1232
1232
|
}
|
|
1233
1233
|
out += labels.join("");
|
|
1234
1234
|
let h = 320;
|
|
@@ -1258,7 +1258,8 @@ const chartTokensCss = ":root{--chart-ink:#2d2d2d;--chart-ink-muted:#686868;--ch
|
|
|
1258
1258
|
* cost per pass and median run. An App Grade grader adds a tier strip under
|
|
1259
1259
|
* the bar with a tick at the pass tier. Bootstrap rows with ranks keep their order;
|
|
1260
1260
|
* unranked rows sort by rate, rows with too few units last, and the finding
|
|
1261
|
-
* says no comparison backs the order.
|
|
1261
|
+
* says no comparison backs the order. Explicit input order keeps unranked rows
|
|
1262
|
+
* where the producer placed them and makes no ranking claim.
|
|
1262
1263
|
*
|
|
1263
1264
|
* Refuses: a bar when the producer labels the estimate `none` or
|
|
1264
1265
|
* `insufficient` (the row prints its count only); a whisker whose interval
|
|
@@ -1282,6 +1283,14 @@ function rankedRates(input, o) {
|
|
|
1282
1283
|
id,
|
|
1283
1284
|
refused: `No ${noun.setup} has an ${noun.attempt}.`
|
|
1284
1285
|
};
|
|
1286
|
+
if (o.order !== void 0 && o.order !== "input") return {
|
|
1287
|
+
id,
|
|
1288
|
+
refused: "Unknown row order."
|
|
1289
|
+
};
|
|
1290
|
+
if (o.order === "input" && input.some((row) => row.rank !== null)) return {
|
|
1291
|
+
id,
|
|
1292
|
+
refused: "Input order requires unranked rows."
|
|
1293
|
+
};
|
|
1285
1294
|
for (const row of input) {
|
|
1286
1295
|
const gap = rateDataGap(row);
|
|
1287
1296
|
if (gap) return {
|
|
@@ -1307,7 +1316,7 @@ function rankedRates(input, o) {
|
|
|
1307
1316
|
}
|
|
1308
1317
|
}
|
|
1309
1318
|
const ranked = input.every((row) => row.rank !== null && row.estimate === "bootstrap");
|
|
1310
|
-
const rows = rateOrder(input);
|
|
1319
|
+
const rows = o.order === "input" ? [...input] : rateOrder(input);
|
|
1311
1320
|
const layout = {
|
|
1312
1321
|
ranked,
|
|
1313
1322
|
cost: rows.some((r) => perPass(r.cost) !== null || r.cost.basis !== "unknown" || r.cost.receipts !== null),
|
|
@@ -1323,8 +1332,8 @@ function rankedRates(input, o) {
|
|
|
1323
1332
|
const setupsN = `${rows.length} ${plural(rows.length, noun.setup)}`;
|
|
1324
1333
|
const top = rows[0];
|
|
1325
1334
|
const uniqueTop = bars.length === 1 || bars.length > 1 && bars[1].rate < top.rate;
|
|
1326
|
-
const finding = ranked ? `${top.label} ranks first, passing ${pct(top.rate)} of ${plural(2, noun.attempt)}.` : bars.length === 0 ? `No ${noun.setup} has enough units to draw a ${o.measure}.` : rows.length === 1 ? `${top.label} passes ${pct(top.rate)} of ${top.attempts} ${plural(top.attempts, noun.attempt)}.` : uniqueTop ? `${top.label} has the highest ${o.measure}, ${pct(top.rate)} of ${top.attempts} ${plural(top.attempts, noun.attempt)}; no comparison backs the order.` : `Sorted by ${o.measure}; no comparison backs the order.`;
|
|
1327
|
-
const lede = `${passed} of ${attempts} ${plural(attempts, noun.attempt)} passed across ${setupsN}.` + (noBar.length && bars.length ? ` ${noBar.length} of ${setupsN} have too few units to draw a rate; they come last
|
|
1335
|
+
const finding = ranked ? `${top.label} ranks first, passing ${pct(top.rate)} of ${plural(2, noun.attempt)}.` : bars.length === 0 ? `No ${noun.setup} has enough units to draw a ${o.measure}.` : o.order === "input" ? `${capitalize(o.measure)} by ${noun.setup}; no ranking is claimed.` : rows.length === 1 ? `${top.label} passes ${pct(top.rate)} of ${top.attempts} ${plural(top.attempts, noun.attempt)}.` : uniqueTop ? `${top.label} has the highest ${o.measure}, ${pct(top.rate)} of ${top.attempts} ${plural(top.attempts, noun.attempt)}; no comparison backs the order.` : `Sorted by ${o.measure}; no comparison backs the order.`;
|
|
1336
|
+
const lede = `${passed} of ${attempts} ${plural(attempts, noun.attempt)} passed across ${setupsN}.` + (noBar.length && bars.length ? ` ${noBar.length} of ${setupsN} have too few units to draw a rate${o.order === "input" ? "." : "; they come last."}` : "");
|
|
1328
1337
|
const intervalNames = [...new Set(whiskers.map((row) => intervalName(row.interval)))];
|
|
1329
1338
|
const read = bars.length ? [`Bars show the share of ${plural(2, noun.attempt)} that passed${whiskers.length ? `; whiskers show the ${intervalNames.join(" or ")} interval` : ""}.`, tiered ? `The strip under a bar splits ${plural(2, noun.attempt)} by App Grade tier${o.passTier ? `, and the tick marks ${o.passTier} or better` : ""}.` : ""].filter(Boolean).join(" ") : `Counts show ${plural(2, noun.attempt)} passed; no ${noun.setup} has enough units to draw a rate.`;
|
|
1330
1339
|
const bases = [...new Set(rows.filter((r) => perPass(r.cost) !== null).map((r) => r.cost.basis))];
|
|
@@ -1379,7 +1388,7 @@ function rankedRates(input, o) {
|
|
|
1379
1388
|
String(row.solved),
|
|
1380
1389
|
String(row.attempts),
|
|
1381
1390
|
drawable(row.estimate) ? pct(row.rate) : estimateNote(row.estimate, row.attempts),
|
|
1382
|
-
rateIntervalGap(row) === null ? `${pct(row.interval.lower)}–${pct(row.interval.upper)} (${intervalName(row.interval)},
|
|
1391
|
+
rateIntervalGap(row) === null ? `${pct(row.interval.lower)}–${pct(row.interval.upper)} (${intervalName(row.interval)}, ${row.attempts} attempts)` : `not drawn (${rateIntervalGap(row)})`,
|
|
1383
1392
|
...tiered ? [row.tiers ? [tierSummary(row.tiers), offLadder ? `${offLadder} off the ladder` : ""].filter(Boolean).join(" · ") || "none" : "not graded"] : [],
|
|
1384
1393
|
...layout.cost ? [costText(row.cost, row.solved), row.cost.basis + (row.cost.receipts !== null ? `, ${row.cost.receipts} receipts` : "")] : [],
|
|
1385
1394
|
...layout.median ? [row.medianWallMs === null ? "unknown" : duration(row.medianWallMs)] : []
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/charts",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Benchmark figures as static SVG and HTML tables: ranked rates, cost frontier, comparison intervals, task matrix and breakdown. Draws from producer data and refuses what it cannot draw honestly.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|