@inflexa-ai/harness 0.42.2 → 0.43.1
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 -2
- package/dist/agents/sandbox/shared.d.ts +1 -6
- package/dist/agents/sandbox/shared.js +0 -15
- package/dist/app/chat-turn.js +13 -1
- package/dist/config/environment-stores.d.ts +4 -2
- package/dist/contracts/chat-events.d.ts +9 -1
- package/dist/contracts/chat-frame.d.ts +3 -3
- package/dist/contracts/chat-frame.js +8 -3
- package/dist/contracts/chat-parts.d.ts +4 -1
- package/dist/contracts/data-profile.d.ts +4 -6
- package/dist/contracts/index.d.ts +1 -1
- package/dist/contracts/report-blocks.d.ts +1364 -75
- package/dist/contracts/report-blocks.js +221 -29
- package/dist/contracts/report-reference.js +1 -1
- package/dist/contracts/schemas/chat-events.d.ts +13 -0
- package/dist/contracts/schemas/chat-events.js +5 -0
- package/dist/contracts/schemas/chat-parts.d.ts +2 -2
- package/dist/contracts/schemas/index.d.ts +1 -1
- package/dist/contracts/schemas/index.js +1 -1
- package/dist/execution/input-signature.d.ts +7 -13
- package/dist/execution/input-signature.js +0 -0
- package/dist/execution/run-canceler.d.ts +3 -2
- package/dist/execution/run-canceler.js +3 -2
- package/dist/execution/run-event-stream.d.ts +16 -2
- package/dist/execution/run-event-stream.js +54 -3
- package/dist/index.d.ts +1 -8
- package/dist/index.js +5 -16
- package/dist/input-scan/enrich.d.ts +0 -2
- package/dist/input-scan/enrich.js +0 -1
- package/dist/lib/metrics.js +6 -7
- package/dist/lib/otel-spans.d.ts +4 -9
- package/dist/lib/otel-spans.js +3 -8
- package/dist/loop/run-agent.d.ts +4 -2
- package/dist/loop/run-agent.js +38 -23
- package/dist/memory/thread-history.d.ts +1 -1
- package/dist/prompts/report-session.d.ts +1 -1
- package/dist/prompts/report-session.js +17 -0
- package/dist/provenance/exec-frame.d.ts +1 -1
- package/dist/report-model/authoring-grammar.d.ts +416 -17
- package/dist/report-model/authoring-grammar.js +25 -4
- package/dist/report-model/block-walk.d.ts +20 -4
- package/dist/report-model/block-walk.js +64 -7
- package/dist/report-model/draft-finish.d.ts +6 -2
- package/dist/report-model/draft-finish.js +6 -1
- package/dist/report-model/production-resolver.d.ts +8 -0
- package/dist/report-model/production-resolver.js +1 -1
- package/dist/report-model/validate.d.ts +20 -10
- package/dist/report-model/validate.js +29 -13
- package/dist/report-render/chart-export.d.ts +52 -0
- package/dist/report-render/chart-export.js +192 -0
- package/dist/report-render/chart-presets.d.ts +46 -47
- package/dist/report-render/chart-presets.js +31 -101
- package/dist/report-render/chart-renderers.d.ts +163 -0
- package/dist/report-render/chart-renderers.js +1055 -0
- package/dist/report-render/chart-toolbox.d.ts +124 -0
- package/dist/report-render/chart-toolbox.js +595 -0
- package/dist/report-render/chart.d.ts +60 -27
- package/dist/report-render/chart.js +2323 -524
- package/dist/report-render/design.d.ts +476 -16
- package/dist/report-render/design.js +390 -56
- package/dist/report-render/figures/common.d.ts +321 -0
- package/dist/report-render/figures/common.js +759 -0
- package/dist/report-render/figures/dendrogram.d.ts +36 -0
- package/dist/report-render/figures/dendrogram.js +130 -0
- package/dist/report-render/figures/dense.d.ts +111 -0
- package/dist/report-render/figures/dense.js +204 -0
- package/dist/report-render/figures/dotplot.d.ts +28 -0
- package/dist/report-render/figures/dotplot.js +234 -0
- package/dist/report-render/figures/embedding.d.ts +43 -0
- package/dist/report-render/figures/embedding.js +360 -0
- package/dist/report-render/figures/equal-units.d.ts +101 -0
- package/dist/report-render/figures/equal-units.js +215 -0
- package/dist/report-render/figures/forest.d.ts +20 -0
- package/dist/report-render/figures/forest.js +398 -0
- package/dist/report-render/figures/gsea.d.ts +30 -0
- package/dist/report-render/figures/gsea.js +391 -0
- package/dist/report-render/figures/heatmap.d.ts +40 -0
- package/dist/report-render/figures/heatmap.js +395 -0
- package/dist/report-render/figures/index.d.ts +135 -0
- package/dist/report-render/figures/index.js +100 -0
- package/dist/report-render/figures/km.d.ts +16 -0
- package/dist/report-render/figures/km.js +406 -0
- package/dist/report-render/figures/label-room.d.ts +130 -0
- package/dist/report-render/figures/label-room.js +341 -0
- package/dist/report-render/figures/locuszoom.d.ts +50 -0
- package/dist/report-render/figures/locuszoom.js +675 -0
- package/dist/report-render/figures/lollipop.d.ts +16 -0
- package/dist/report-render/figures/lollipop.js +247 -0
- package/dist/report-render/figures/ma.d.ts +20 -0
- package/dist/report-render/figures/ma.js +114 -0
- package/dist/report-render/figures/manhattan.d.ts +60 -0
- package/dist/report-render/figures/manhattan.js +343 -0
- package/dist/report-render/figures/oncoprint.d.ts +41 -0
- package/dist/report-render/figures/oncoprint.js +420 -0
- package/dist/report-render/figures/pca.d.ts +37 -0
- package/dist/report-render/figures/pca.js +241 -0
- package/dist/report-render/figures/qq.d.ts +30 -0
- package/dist/report-render/figures/qq.js +182 -0
- package/dist/report-render/figures/roc.d.ts +17 -0
- package/dist/report-render/figures/roc.js +116 -0
- package/dist/report-render/figures/sankey.d.ts +48 -0
- package/dist/report-render/figures/sankey.js +353 -0
- package/dist/report-render/figures/upset.d.ts +60 -0
- package/dist/report-render/figures/upset.js +316 -0
- package/dist/report-render/figures/volcano.d.ts +25 -0
- package/dist/report-render/figures/volcano.js +166 -0
- package/dist/report-render/hybrid-svg.d.ts +75 -0
- package/dist/report-render/hybrid-svg.js +504 -0
- package/dist/report-render/number-format.d.ts +19 -0
- package/dist/report-render/number-format.js +25 -1
- package/dist/report-render/page.d.ts +41 -4
- package/dist/report-render/page.js +247 -12
- package/dist/report-render/render.d.ts +13 -4
- package/dist/report-render/render.js +37 -6
- package/dist/report-render/types.d.ts +23 -2
- package/dist/report-render/value-bridge.d.ts +38 -3
- package/dist/report-render/value-bridge.js +137 -6
- package/dist/report-render/views/chart-view.d.ts +42 -6
- package/dist/report-render/views/chart-view.js +70 -9
- package/dist/report-render/views/page-view.js +9 -10
- package/dist/runtime/assemble.js +2 -2
- package/dist/sandbox/client.d.ts +23 -32
- package/dist/sandbox/client.js +3 -11
- package/dist/sandbox/create-sandbox.d.ts +9 -24
- package/dist/sandbox/create-sandbox.js +15 -30
- package/dist/sandbox/docker-client.d.ts +12 -22
- package/dist/sandbox/docker-client.js +29 -43
- package/dist/sandbox/exec.d.ts +58 -0
- package/dist/sandbox/exec.js +197 -0
- package/dist/sandbox/identity.d.ts +5 -5
- package/dist/sandbox/identity.js +7 -10
- package/dist/sandbox/k8s-client.d.ts +4 -10
- package/dist/sandbox/k8s-client.js +5 -12
- package/dist/sandbox/liveness.d.ts +5 -12
- package/dist/sandbox/liveness.js +5 -12
- package/dist/sandbox/notification-sweep.d.ts +4 -7
- package/dist/sandbox/notification-sweep.js +4 -7
- package/dist/sandbox/reaper.d.ts +3 -3
- package/dist/sandbox/reaper.js +3 -3
- package/dist/sandbox/sandbox-error.d.ts +10 -11
- package/dist/sandbox/sandbox-error.js +10 -11
- package/dist/sandbox/sandbox-step-translate.d.ts +1 -1
- package/dist/sandbox/sandbox-step-translate.js +1 -1
- package/dist/sandbox/types.d.ts +31 -99
- package/dist/sandbox/types.js +17 -84
- package/dist/state/active-sandboxes.d.ts +7 -32
- package/dist/state/active-sandboxes.js +11 -46
- package/dist/state/index.d.ts +1 -2
- package/dist/state/index.js +1 -1
- package/dist/state/migrations/20261005120000_drop_the_active_exec_tracking.d.ts +7 -0
- package/dist/state/migrations/20261005120000_drop_the_active_exec_tracking.js +12 -0
- package/dist/state/migrations/index.js +2 -0
- package/dist/state/schema.d.ts +1 -5
- package/dist/state/schema.js +1 -6
- package/dist/state/step-executions.js +1 -2
- package/dist/tasks/data-profile.js +7 -20
- package/dist/tasks/derive-table-exec.d.ts +4 -14
- package/dist/tasks/derive-table-exec.js +9 -24
- package/dist/tasks/extract-values.d.ts +2 -2
- package/dist/tasks/extract-values.js +4 -7
- package/dist/tools/define-tool.d.ts +56 -13
- package/dist/tools/define-tool.js +28 -1
- package/dist/tools/execute-analysis.js +3 -3
- package/dist/tools/report-session/derive-table.d.ts +8 -9
- package/dist/tools/report-session/derive-table.js +3 -4
- package/dist/tools/report-session/preview-report.js +4 -49
- package/dist/tools/sandbox/list-available-packages.d.ts +1 -1
- package/dist/tools/sandbox/list-available-packages.js +5 -4
- package/dist/tools/workspace/edit-file.d.ts +5 -4
- package/dist/tools/workspace/edit-file.js +10 -13
- package/dist/tools/workspace/execute-command.d.ts +27 -42
- package/dist/tools/workspace/execute-command.js +42 -38
- package/dist/tools/workspace/index.d.ts +5 -6
- package/dist/tools/workspace/index.js +5 -6
- package/dist/tools/workspace/mutator.d.ts +43 -8
- package/dist/tools/workspace/mutator.js +45 -34
- package/dist/tools/workspace/run-exec.d.ts +3 -12
- package/dist/tools/workspace/run-exec.js +7 -24
- package/dist/tools/workspace/scan-inputs.d.ts +0 -3
- package/dist/tools/workspace/scan-inputs.js +0 -1
- package/dist/tools/workspace/write-file.d.ts +12 -3
- package/dist/tools/workspace/write-file.js +17 -13
- package/dist/workflows/sandbox-step.d.ts +7 -11
- package/dist/workflows/sandbox-step.js +24 -27
- package/package.json +5 -3
- package/dist/sandbox/await-exec.d.ts +0 -143
- package/dist/sandbox/await-exec.js +0 -417
- package/dist/sandbox/deliver-exec-event.d.ts +0 -25
- package/dist/sandbox/deliver-exec-event.js +0 -29
- package/dist/sandbox/digest.d.ts +0 -14
- package/dist/sandbox/digest.js +0 -17
- package/dist/sandbox/exec-id.d.ts +0 -12
- package/dist/sandbox/exec-id.js +0 -20
- package/dist/sandbox/hmac.d.ts +0 -62
- package/dist/sandbox/hmac.js +0 -72
- package/dist/sandbox/submit-exec.d.ts +0 -38
- package/dist/sandbox/submit-exec.js +0 -80
- package/dist/sandbox/watchdog.d.ts +0 -71
- package/dist/sandbox/watchdog.js +0 -161
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The layout of a figure whose two axes share one unit: a PCA, an embedding, and a ROC curve.
|
|
3
|
+
*
|
|
4
|
+
* One unit on x equals one unit on y when the two axes span one length of data and the plot is a square. The
|
|
5
|
+
* option rides to the page as JSON, and the chart runtime knows the size of its container at the draw alone.
|
|
6
|
+
* No grid field of the runtime keeps an aspect, and a percentage of the width is no percentage of the height.
|
|
7
|
+
* Thus the grid states its width and its height in pixels, as one number, and the square holds in every
|
|
8
|
+
* container.
|
|
9
|
+
*
|
|
10
|
+
* The size of the square follows the container through the media rules of the runtime. Each rule names the
|
|
11
|
+
* smallest container that holds one square size with its margins, and the runtime applies each rule that
|
|
12
|
+
* matches, in order. The rules grow, thus the largest square that fits wins. The first rule matches every
|
|
13
|
+
* container, thus a container that shrinks falls back to the smallest square. A rule states every place that
|
|
14
|
+
* the square moves: each grid, the legend, and each color scale in the band at the right of the squares. A
|
|
15
|
+
* rule also states the point size of a square smaller than the page square.
|
|
16
|
+
*
|
|
17
|
+
* The page narrows its chart body to the block of the largest square that fits the body height, and it
|
|
18
|
+
* centers the body in the card. Thus the toolbox of the page sits over the top right corner of the block, and
|
|
19
|
+
* the top margin of a page rule is the band of the toolbox at least. An export has a fixed size and no
|
|
20
|
+
* toolbox, thus one rule for each export size places the largest square that fits it, with the margins at the
|
|
21
|
+
* text size of the export, in the middle of the width. Such a rule names its size as the smallest and the
|
|
22
|
+
* largest container, thus no other container meets it.
|
|
23
|
+
*/
|
|
24
|
+
import type { EchartOption } from "../chart.js";
|
|
25
|
+
/** The margins around the squares, in pixels at the page text size. */
|
|
26
|
+
export interface SquareMargins {
|
|
27
|
+
readonly top: number;
|
|
28
|
+
readonly bottom: number;
|
|
29
|
+
readonly left: number;
|
|
30
|
+
readonly right: number;
|
|
31
|
+
}
|
|
32
|
+
/** What one square layout places: the panels, their margins, and the members of the band at their right. */
|
|
33
|
+
export interface SquareLayoutFields {
|
|
34
|
+
readonly panels: number;
|
|
35
|
+
readonly margins: SquareMargins;
|
|
36
|
+
/** The width in pixels of the band at the right of the squares, or 0 for no band. */
|
|
37
|
+
readonly side: number;
|
|
38
|
+
/** True when the band holds the legend. */
|
|
39
|
+
readonly legend?: boolean;
|
|
40
|
+
/** The count of color scales in the band. */
|
|
41
|
+
readonly visualMaps?: number;
|
|
42
|
+
/** The leading series whose points shrink with a small square, and their point size at the page square. */
|
|
43
|
+
readonly points?: {
|
|
44
|
+
readonly series: number;
|
|
45
|
+
readonly px: number;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* A legend in a band under the squares instead of the band at their right: the names of its entries. The
|
|
49
|
+
* band holds the lines that the entries fill at the width of the square block.
|
|
50
|
+
*/
|
|
51
|
+
readonly legendBand?: {
|
|
52
|
+
readonly place: "bottom";
|
|
53
|
+
readonly entries: readonly string[];
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* The series whose label wraps inside the square, for example the statistics text of a corner. The label
|
|
57
|
+
* takes the width of the square less its insets, thus a long statistic breaks into lines and never crosses
|
|
58
|
+
* an axis of a small square.
|
|
59
|
+
*/
|
|
60
|
+
readonly squareLabel?: {
|
|
61
|
+
readonly series: number;
|
|
62
|
+
readonly insetPx: number;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** The grids of a square layout, the places of the band members, and the media rules that resize them. */
|
|
66
|
+
export interface SquareLayout {
|
|
67
|
+
readonly grid: EchartOption[];
|
|
68
|
+
readonly legend?: EchartOption;
|
|
69
|
+
readonly visualMap?: EchartOption[];
|
|
70
|
+
readonly media: EchartOption[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The layout of some square panels, and of the band at their right.
|
|
74
|
+
*
|
|
75
|
+
* The panels lay out three to a row, as a facet does, from the top left corner. Each grid draws no label past
|
|
76
|
+
* its box, thus the runtime never shrinks a square to fit a label.
|
|
77
|
+
*/
|
|
78
|
+
export declare function squareLayout(fields: SquareLayoutFields): SquareLayout;
|
|
79
|
+
/** The range of one axis. */
|
|
80
|
+
export interface AxisRange {
|
|
81
|
+
readonly min: number;
|
|
82
|
+
readonly max: number;
|
|
83
|
+
}
|
|
84
|
+
/** The ranges of the two axes of one unit, and the tick step of a rounded pair. */
|
|
85
|
+
export interface EqualRanges {
|
|
86
|
+
readonly x: AxisRange;
|
|
87
|
+
readonly y: AxisRange;
|
|
88
|
+
readonly step?: number;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The ranges of two axes that share one unit: each axis spans one length, around its own data.
|
|
92
|
+
*
|
|
93
|
+
* `pad` widens the longer span by that share on each side. `round` ends each axis on a multiple of one round
|
|
94
|
+
* step, and it states the step, thus the ticks of the two axes stand one step apart. The shorter axis grows by
|
|
95
|
+
* whole steps on its two sides, an odd step on the low side, until its span matches. Each extent reads its
|
|
96
|
+
* values in one pass.
|
|
97
|
+
*/
|
|
98
|
+
export declare function equalRanges(xs: readonly number[], ys: readonly number[], fields: {
|
|
99
|
+
readonly pad: number;
|
|
100
|
+
readonly round: boolean;
|
|
101
|
+
}): EqualRanges;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The layout of a figure whose two axes share one unit: a PCA, an embedding, and a ROC curve.
|
|
3
|
+
*
|
|
4
|
+
* One unit on x equals one unit on y when the two axes span one length of data and the plot is a square. The
|
|
5
|
+
* option rides to the page as JSON, and the chart runtime knows the size of its container at the draw alone.
|
|
6
|
+
* No grid field of the runtime keeps an aspect, and a percentage of the width is no percentage of the height.
|
|
7
|
+
* Thus the grid states its width and its height in pixels, as one number, and the square holds in every
|
|
8
|
+
* container.
|
|
9
|
+
*
|
|
10
|
+
* The size of the square follows the container through the media rules of the runtime. Each rule names the
|
|
11
|
+
* smallest container that holds one square size with its margins, and the runtime applies each rule that
|
|
12
|
+
* matches, in order. The rules grow, thus the largest square that fits wins. The first rule matches every
|
|
13
|
+
* container, thus a container that shrinks falls back to the smallest square. A rule states every place that
|
|
14
|
+
* the square moves: each grid, the legend, and each color scale in the band at the right of the squares. A
|
|
15
|
+
* rule also states the point size of a square smaller than the page square.
|
|
16
|
+
*
|
|
17
|
+
* The page narrows its chart body to the block of the largest square that fits the body height, and it
|
|
18
|
+
* centers the body in the card. Thus the toolbox of the page sits over the top right corner of the block, and
|
|
19
|
+
* the top margin of a page rule is the band of the toolbox at least. An export has a fixed size and no
|
|
20
|
+
* toolbox, thus one rule for each export size places the largest square that fits it, with the margins at the
|
|
21
|
+
* text size of the export, in the middle of the width. Such a rule names its size as the smallest and the
|
|
22
|
+
* largest container, thus no other container meets it.
|
|
23
|
+
*/
|
|
24
|
+
import { TOOLBOX_BAND_PX } from "../chart-toolbox.js";
|
|
25
|
+
import { CHART_EXPORT_SIZES, CHART_PAGE_TEXT_PX, FACET_COLUMNS } from "../design.js";
|
|
26
|
+
import { legendLineCount, legendLinePx } from "./common.js";
|
|
27
|
+
/** The smallest square side, in pixels. A container smaller than its rule still draws this square. */
|
|
28
|
+
const SQUARE_MIN_PX = 120;
|
|
29
|
+
/** The largest square side, in pixels. The slide export is the largest container. */
|
|
30
|
+
const SQUARE_MAX_PX = 1100;
|
|
31
|
+
/** The ratio between two neighbor square sizes. The largest square that fits leaves at most this share unused. */
|
|
32
|
+
const SQUARE_STEP = 1.1;
|
|
33
|
+
/** The gap between two panels, and between the squares and their band, in pixels. */
|
|
34
|
+
const PANEL_GAP_PX = 16;
|
|
35
|
+
/**
|
|
36
|
+
* The square side from which the margins grow with the square. The slide export draws its text at two
|
|
37
|
+
* times the page size, thus the margins of a large square grow up to two times.
|
|
38
|
+
*/
|
|
39
|
+
const MARGIN_SCALE_FROM_PX = 330;
|
|
40
|
+
const MARGIN_SCALE_MAX = 2;
|
|
41
|
+
/** The square sides of the media rules, smallest first. The list is a constant, thus each option holds the same rules. */
|
|
42
|
+
const SQUARE_SIDES = (() => {
|
|
43
|
+
const sides = [];
|
|
44
|
+
for (let side = SQUARE_MIN_PX; side <= SQUARE_MAX_PX; side *= SQUARE_STEP)
|
|
45
|
+
sides.push(Math.round(side));
|
|
46
|
+
return sides;
|
|
47
|
+
})();
|
|
48
|
+
/**
|
|
49
|
+
* The square side at which a point takes its full size. A smaller square, for example the one of the column
|
|
50
|
+
* export, shrinks each point in proportion, thus a cloud keeps its density at the size of a journal column. A
|
|
51
|
+
* larger square keeps the full size, as a plot in points keeps its dot size on a larger figure.
|
|
52
|
+
*/
|
|
53
|
+
const POINT_SCALE_FROM_PX = 330;
|
|
54
|
+
/** The smallest point size of a square that shrinks its points, in pixels. */
|
|
55
|
+
const POINT_MIN_PX = 1;
|
|
56
|
+
/**
|
|
57
|
+
* The layout of some square panels, and of the band at their right.
|
|
58
|
+
*
|
|
59
|
+
* The panels lay out three to a row, as a facet does, from the top left corner. Each grid draws no label past
|
|
60
|
+
* its box, thus the runtime never shrinks a square to fit a label.
|
|
61
|
+
*/
|
|
62
|
+
export function squareLayout(fields) {
|
|
63
|
+
const placements = SQUARE_SIDES.map((side) => placement(side, fields, marginScale(side), TOOLBOX_BAND_PX));
|
|
64
|
+
const smallest = placements[0];
|
|
65
|
+
const media = placements.map((entry, index) => ({
|
|
66
|
+
// The first rule matches every container, thus a container that shrinks past a rule falls back to it.
|
|
67
|
+
query: index === 0 ? { minWidth: 0 } : { minWidth: entry.minWidth, minHeight: entry.minHeight },
|
|
68
|
+
option: placedOption(entry),
|
|
69
|
+
}));
|
|
70
|
+
for (const size of EXPORT_SIZES) {
|
|
71
|
+
const scale = size.textPx / CHART_PAGE_TEXT_PX;
|
|
72
|
+
const fitting = SQUARE_SIDES.map((side) => placement(side, fields, scale, 0)).filter((entry) => entry.minWidth <= size.widthPx && entry.minHeight <= size.heightPx);
|
|
73
|
+
const chosen = fitting.length > 0 ? fitting[fitting.length - 1] : placement(SQUARE_MIN_PX, fields, scale, 0);
|
|
74
|
+
media.push({
|
|
75
|
+
query: { minWidth: size.widthPx, maxWidth: size.widthPx, minHeight: size.heightPx, maxHeight: size.heightPx },
|
|
76
|
+
option: placedOption(shifted(chosen, Math.max(0, Math.floor((size.widthPx - chosen.minWidth) / 2)))),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
grid: smallest.grid,
|
|
81
|
+
...(smallest.legend !== undefined ? { legend: smallest.legend } : {}),
|
|
82
|
+
...(smallest.visualMap !== undefined ? { visualMap: smallest.visualMap } : {}),
|
|
83
|
+
media,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/** The export sizes that take a rule of their own: the two journal columns and the slide. */
|
|
87
|
+
const EXPORT_SIZES = [CHART_EXPORT_SIZES.single, CHART_EXPORT_SIZES.double, CHART_EXPORT_SIZES.slide];
|
|
88
|
+
/** The scale of the margins of a page square: one up to the page square, and larger with a larger square. */
|
|
89
|
+
function marginScale(side) {
|
|
90
|
+
return Math.min(MARGIN_SCALE_MAX, Math.max(1, side / MARGIN_SCALE_FROM_PX));
|
|
91
|
+
}
|
|
92
|
+
/** The option of one media rule: the point size, the grids, the legend, and the color scales of one placement. */
|
|
93
|
+
function placedOption(entry) {
|
|
94
|
+
return {
|
|
95
|
+
...(entry.series !== undefined ? { series: entry.series } : {}),
|
|
96
|
+
grid: entry.grid,
|
|
97
|
+
...(entry.legend !== undefined ? { legend: entry.legend } : {}),
|
|
98
|
+
...(entry.visualMap !== undefined ? { visualMap: entry.visualMap } : {}),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/** One placement moved right by some pixels: each grid, the legend, and each color scale. */
|
|
102
|
+
function shifted(entry, by) {
|
|
103
|
+
const move = (member) => ({ ...member, left: member.left + by });
|
|
104
|
+
return {
|
|
105
|
+
...entry,
|
|
106
|
+
grid: entry.grid.map(move),
|
|
107
|
+
...(entry.legend !== undefined ? { legend: move(entry.legend) } : {}),
|
|
108
|
+
...(entry.visualMap !== undefined ? { visualMap: entry.visualMap.map(move) } : {}),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The place of each member of the layout at one square side. `scale` is the scale of the margins: the text
|
|
113
|
+
* size of the container over the page text size. `leastTop` is the least top margin, in pixels.
|
|
114
|
+
*/
|
|
115
|
+
function placement(side, fields, scale, leastTop) {
|
|
116
|
+
const margin = (value) => Math.round(value * scale);
|
|
117
|
+
const top = Math.max(margin(fields.margins.top), leastTop);
|
|
118
|
+
const left = margin(fields.margins.left);
|
|
119
|
+
const columns = Math.max(1, Math.min(fields.panels, FACET_COLUMNS));
|
|
120
|
+
const rows = Math.max(1, Math.ceil(fields.panels / columns));
|
|
121
|
+
const gap = margin(PANEL_GAP_PX);
|
|
122
|
+
const grid = [];
|
|
123
|
+
for (let panel = 0; panel < Math.max(1, fields.panels); panel += 1) {
|
|
124
|
+
grid.push({
|
|
125
|
+
left: left + (panel % columns) * (side + gap),
|
|
126
|
+
top: top + Math.floor(panel / columns) * (side + gap),
|
|
127
|
+
width: side,
|
|
128
|
+
height: side,
|
|
129
|
+
outerBoundsMode: "none",
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
const blockRight = left + columns * side + (columns - 1) * gap;
|
|
133
|
+
const bandLeft = blockRight + gap;
|
|
134
|
+
const band = fields.side > 0 ? margin(fields.side) + gap : 0;
|
|
135
|
+
const points = fields.points;
|
|
136
|
+
const pointPx = points === undefined ? 0 : Math.max(POINT_MIN_PX, Math.round(points.px * Math.min(1, side / POINT_SCALE_FROM_PX) * 10) / 10);
|
|
137
|
+
const squareLabel = fields.squareLabel;
|
|
138
|
+
const series = Array.from({ length: Math.max(points?.series ?? 0, squareLabel === undefined ? 0 : squareLabel.series + 1) }, (_entry, index) => ({
|
|
139
|
+
...(points !== undefined && index < points.series ? { symbolSize: pointPx } : {}),
|
|
140
|
+
...(squareLabel !== undefined && index === squareLabel.series ? { label: { width: side - 2 * squareLabel.insetPx, overflow: "break" } } : {}),
|
|
141
|
+
}));
|
|
142
|
+
const blockBottom = top + rows * side + (rows - 1) * gap + margin(fields.margins.bottom);
|
|
143
|
+
const bottomBand = fields.legendBand;
|
|
144
|
+
const textPx = CHART_PAGE_TEXT_PX * scale;
|
|
145
|
+
const legendHeight = bottomBand === undefined ? 0 : Math.round(legendLineCount(bottomBand.entries, blockRight - left, textPx) * legendLinePx(textPx));
|
|
146
|
+
const legend = fields.legend !== true
|
|
147
|
+
? {}
|
|
148
|
+
: bottomBand === undefined
|
|
149
|
+
? { legend: { left: bandLeft, top } }
|
|
150
|
+
: { legend: { left, top: blockBottom, width: blockRight - left, orient: "horizontal" } };
|
|
151
|
+
return {
|
|
152
|
+
...(series.length > 0 ? { series } : {}),
|
|
153
|
+
grid,
|
|
154
|
+
...legend,
|
|
155
|
+
...(fields.visualMaps !== undefined && fields.visualMaps > 0
|
|
156
|
+
? { visualMap: Array.from({ length: fields.visualMaps }, () => ({ left: bandLeft, top })) }
|
|
157
|
+
: {}),
|
|
158
|
+
minWidth: blockRight + band + margin(fields.margins.right),
|
|
159
|
+
minHeight: blockBottom + legendHeight,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* The ranges of two axes that share one unit: each axis spans one length, around its own data.
|
|
164
|
+
*
|
|
165
|
+
* `pad` widens the longer span by that share on each side. `round` ends each axis on a multiple of one round
|
|
166
|
+
* step, and it states the step, thus the ticks of the two axes stand one step apart. The shorter axis grows by
|
|
167
|
+
* whole steps on its two sides, an odd step on the low side, until its span matches. Each extent reads its
|
|
168
|
+
* values in one pass.
|
|
169
|
+
*/
|
|
170
|
+
export function equalRanges(xs, ys, fields) {
|
|
171
|
+
const x = extent(xs);
|
|
172
|
+
const y = extent(ys);
|
|
173
|
+
const span = Math.max(x.max - x.min, y.max - y.min);
|
|
174
|
+
const length = span > 0 ? span * (1 + 2 * fields.pad) : 1;
|
|
175
|
+
if (!fields.round) {
|
|
176
|
+
return { x: around(x, length), y: around(y, length) };
|
|
177
|
+
}
|
|
178
|
+
const step = roundStep(length / 5);
|
|
179
|
+
const snapped = [x, y].map((range) => ({ min: Math.floor(range.min / step), max: Math.ceil(range.max / step) }));
|
|
180
|
+
const steps = Math.max(...snapped.map((range) => range.max - range.min), 1);
|
|
181
|
+
const [xRange, yRange] = snapped.map((range) => {
|
|
182
|
+
const short = steps - (range.max - range.min);
|
|
183
|
+
return { min: exact((range.min - Math.ceil(short / 2)) * step), max: exact((range.max + Math.floor(short / 2)) * step) };
|
|
184
|
+
});
|
|
185
|
+
return { x: xRange, y: yRange, step };
|
|
186
|
+
}
|
|
187
|
+
/** The extent of some values, or the unit range for no value. */
|
|
188
|
+
function extent(values) {
|
|
189
|
+
if (values.length === 0)
|
|
190
|
+
return { min: 0, max: 1 };
|
|
191
|
+
let min = values[0];
|
|
192
|
+
let max = values[0];
|
|
193
|
+
for (const value of values) {
|
|
194
|
+
if (value < min)
|
|
195
|
+
min = value;
|
|
196
|
+
if (value > max)
|
|
197
|
+
max = value;
|
|
198
|
+
}
|
|
199
|
+
return { min, max };
|
|
200
|
+
}
|
|
201
|
+
/** One range of the given length around the middle of an extent. */
|
|
202
|
+
function around(range, length) {
|
|
203
|
+
const middle = (range.min + range.max) / 2;
|
|
204
|
+
return { min: exact(middle - length / 2), max: exact(middle + length / 2) };
|
|
205
|
+
}
|
|
206
|
+
/** The round step at or above a raw step: one, two, two and a half, five, or ten times a power of ten. */
|
|
207
|
+
function roundStep(raw) {
|
|
208
|
+
const base = Math.pow(10, Math.floor(Math.log10(raw)));
|
|
209
|
+
const fraction = raw / base;
|
|
210
|
+
return exact((fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 2.5 ? 2.5 : fraction <= 5 ? 5 : 10) * base);
|
|
211
|
+
}
|
|
212
|
+
/** A number rounded to twelve significant digits, thus a float residue never reaches an axis. */
|
|
213
|
+
function exact(value) {
|
|
214
|
+
return Number(value.toPrecision(12));
|
|
215
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The forest figure: one row for each term, top-down, with the estimate as a square, its interval as a line,
|
|
3
|
+
* the line of no effect, and a text column at the right that prints each estimate with its interval, and a
|
|
4
|
+
* second text column that prints the p value.
|
|
5
|
+
*
|
|
6
|
+
* A ratio reads on a log axis, thus the axis is logarithmic when each value is positive, and its line of no
|
|
7
|
+
* effect sits at 1. A table with a value at or under zero holds differences, thus its axis is linear and the
|
|
8
|
+
* line sits at 0. The log axis ends at the nice ratios just past the data and 1, thus it spans no empty decade.
|
|
9
|
+
* An interval past the widest log axis ends at the axis with an arrow, as `forestplot` clips it, and its text
|
|
10
|
+
* prints the bound of the table.
|
|
11
|
+
*/
|
|
12
|
+
import type { FigureModule } from "./index.js";
|
|
13
|
+
/** The forest figure of a table of ratios or differences. */
|
|
14
|
+
export declare const FOREST_FIGURE: FigureModule;
|
|
15
|
+
/**
|
|
16
|
+
* One term broken at its spaces into lines of `TERM_LINE_CHARACTERS` at most, and `TERM_LINES` lines at most.
|
|
17
|
+
* A word longer than a line stays whole on its own line. A term that needs more lines keeps the first lines,
|
|
18
|
+
* and its last line ends with an ellipsis.
|
|
19
|
+
*/
|
|
20
|
+
export declare function termLines(term: string): string;
|