@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,504 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The hybrid SVG of a dense chart: the vector axes, text, legend, and guides, over one raster layer of the points.
|
|
3
|
+
*
|
|
4
|
+
* A chart past the point bound of the export gets no staged SVG, because a vector file of many thousands of
|
|
5
|
+
* points is too large. The page builds its SVG on a click instead. It draws the export option with the SVG
|
|
6
|
+
* renderer and the point data emptied, it draws the points alone on a canvas at 300 DPI, and it puts the canvas
|
|
7
|
+
* image into the SVG at the rectangle of the grid, under the vector marks. The server has no canvas, thus only
|
|
8
|
+
* the page builds this file.
|
|
9
|
+
*
|
|
10
|
+
* The rule of a point layer and the composition of the file hold one rule each in two twins: the TypeScript
|
|
11
|
+
* function and the page function. A shared test vector runs both, thus the two cannot drift in silence. The
|
|
12
|
+
* option transforms and the two draws exist on the page alone, because the server never builds the file.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* True when one series draws a point for each row: a `scatter` whose symbol draws and which shows no series
|
|
16
|
+
* label. A scatter of size zero, or one with a shown label, carries names, and names stay vector text.
|
|
17
|
+
*/
|
|
18
|
+
export function isPointLayer(series) {
|
|
19
|
+
if (typeof series !== "object" || series === null)
|
|
20
|
+
return false;
|
|
21
|
+
const fields = series;
|
|
22
|
+
if (fields.type !== "scatter" || fields.symbolSize === 0 || fields.symbol === "none")
|
|
23
|
+
return false;
|
|
24
|
+
const label = fields.label;
|
|
25
|
+
return !(typeof label === "object" && label !== null && label.show === true);
|
|
26
|
+
}
|
|
27
|
+
/** True when an option holds a point layer. The page can then build the hybrid SVG of the option. */
|
|
28
|
+
export function holdsPointLayer(option) {
|
|
29
|
+
const series = option.series;
|
|
30
|
+
return Array.isArray(series) ? series.some(isPointLayer) : isPointLayer(series);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The SVG text with its root at the millimeter size of a column. The view box keeps the pixel space, thus a
|
|
34
|
+
* vector editor opens the file at the column width. A size with no millimeter box leaves the root as it is.
|
|
35
|
+
*/
|
|
36
|
+
export function millimeterRoot(svg, size) {
|
|
37
|
+
if (size.widthMm === undefined || size.heightMm === undefined)
|
|
38
|
+
return svg;
|
|
39
|
+
return svg.replace(`<svg width="${size.widthPx}" height="${size.heightPx}"`, `<svg width="${size.widthMm}mm" height="${size.heightMm}mm"`);
|
|
40
|
+
}
|
|
41
|
+
/** The count of decimals of a coordinate of the layer. A thousandth of a pixel is past each display. */
|
|
42
|
+
const LAYER_DECIMALS = 1000;
|
|
43
|
+
/** One coordinate of the layer, rounded to the decimals of the layer. */
|
|
44
|
+
function layerNumber(value) {
|
|
45
|
+
return Math.round(value * LAYER_DECIMALS) / LAYER_DECIMALS;
|
|
46
|
+
}
|
|
47
|
+
/** One attribute value with each character that can close it written as an entity. */
|
|
48
|
+
function attributeText(value) {
|
|
49
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
50
|
+
}
|
|
51
|
+
/** The root tag of an SVG file, and the transparent background rectangle that the chart runtime writes first. */
|
|
52
|
+
const ROOT_TAG = /^<svg\b[^>]*>/;
|
|
53
|
+
const BACKGROUND_RECT = /^\s*<rect width="[^"]*" height="[^"]*" x="0" y="0"[^>]*><\/rect>/;
|
|
54
|
+
/**
|
|
55
|
+
* The hybrid SVG file: the vector file with one `<image>` element of the point layer, and the root at the
|
|
56
|
+
* millimeter size.
|
|
57
|
+
*
|
|
58
|
+
* The image goes first after the background rectangle, thus each vector mark draws over the points: the axes,
|
|
59
|
+
* the guides, the names, and the legend. The rectangle of the image is the grid rectangle, and the image
|
|
60
|
+
* stretches to it, because the raster drew the grid at that rectangle. A text that holds no SVG root passes
|
|
61
|
+
* through with no image.
|
|
62
|
+
*/
|
|
63
|
+
export function composeHybridSvg(svg, layer, size) {
|
|
64
|
+
const root = ROOT_TAG.exec(svg);
|
|
65
|
+
if (root === null)
|
|
66
|
+
return svg;
|
|
67
|
+
let at = root[0].length;
|
|
68
|
+
const background = BACKGROUND_RECT.exec(svg.slice(at));
|
|
69
|
+
if (background !== null)
|
|
70
|
+
at += background[0].length;
|
|
71
|
+
const image = `\n<image href="${attributeText(layer.href)}" x="${layerNumber(layer.x)}" y="${layerNumber(layer.y)}" ` +
|
|
72
|
+
`width="${layerNumber(layer.width)}" height="${layerNumber(layer.height)}" preserveAspectRatio="none"></image>`;
|
|
73
|
+
return millimeterRoot(svg.slice(0, at) + image + svg.slice(at), size);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The count of halvings of the search for one edge of a grid. The chart is at most some thousand pixels wide,
|
|
77
|
+
* thus twenty halvings place the edge closer than a hundredth of a pixel.
|
|
78
|
+
*/
|
|
79
|
+
const EDGE_SEARCH_STEPS = 20;
|
|
80
|
+
/** The symbol size of a scatter that states none, in pixels: the default of the chart runtime. */
|
|
81
|
+
const RUNTIME_SYMBOL_PX = 10;
|
|
82
|
+
/**
|
|
83
|
+
* The page twin of the point-layer rule and of the composition, and the page build of the hybrid file, as
|
|
84
|
+
* browser source text.
|
|
85
|
+
*
|
|
86
|
+
* `reportHybridSvg(runtime, option, size)` is the entry point. It reads the chart runtime and the document of
|
|
87
|
+
* the page, and it gives the SVG text, or `null` when the option holds no point layer or the runtime gives no
|
|
88
|
+
* grid rectangle. The fragment reads `reportExportOption` of the renderer fragment, thus the bootstrap inlines
|
|
89
|
+
* that fragment first.
|
|
90
|
+
*
|
|
91
|
+
* The draws run in this order:
|
|
92
|
+
*
|
|
93
|
+
* 1. The vector draw takes the export option with the rows of each point layer emptied. Each point layer keeps
|
|
94
|
+
* each row that carries its own label, and two anchors with no symbol at the least and the greatest value of
|
|
95
|
+
* each dimension. Thus each axis and each color scale keeps the extent of the full rows.
|
|
96
|
+
* 2. The rectangle of each grid that holds a point layer comes from the runtime: a halving search of each edge
|
|
97
|
+
* with `containPixel` from a point inside the grid. The extent of each continuous axis of such a grid comes
|
|
98
|
+
* from `convertFromPixel` at the two edges.
|
|
99
|
+
* 3. The raster draw takes the export option with the point layers alone. Each grid stands at its measured
|
|
100
|
+
* rectangle, each axis holds its measured extent and draws nothing, and the legend, the graphics, and the
|
|
101
|
+
* color scales draw nothing. Thus each point lands on the pixel where the vector axes place it.
|
|
102
|
+
* 4. The composition crops the raster to the union of the grid rectangles at 300 DPI, and it puts the PNG into
|
|
103
|
+
* the vector file. The crop reaches past each grid edge by half of the largest symbol of a layer or of a
|
|
104
|
+
* visual map of a layer, thus a point on an edge keeps its whole symbol, as it does on the page.
|
|
105
|
+
*/
|
|
106
|
+
export const HYBRID_SVG_SOURCE = `function reportIsPointLayer(series) {
|
|
107
|
+
if (typeof series !== "object" || series === null) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
if (series.type !== "scatter" || series.symbolSize === 0 || series.symbol === "none") {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
var label = series.label;
|
|
114
|
+
return !(typeof label === "object" && label !== null && label.show === true);
|
|
115
|
+
}
|
|
116
|
+
function reportMillimeterRoot(svg, size) {
|
|
117
|
+
if (size.widthMm === undefined || size.heightMm === undefined) {
|
|
118
|
+
return svg;
|
|
119
|
+
}
|
|
120
|
+
return svg.replace('<svg width="' + size.widthPx + '" height="' + size.heightPx + '"', '<svg width="' + size.widthMm + 'mm" height="' + size.heightMm + 'mm"');
|
|
121
|
+
}
|
|
122
|
+
function reportLayerNumber(value) {
|
|
123
|
+
return Math.round(value * ${LAYER_DECIMALS}) / ${LAYER_DECIMALS};
|
|
124
|
+
}
|
|
125
|
+
function reportAttributeText(value) {
|
|
126
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
127
|
+
}
|
|
128
|
+
function reportComposeHybridSvg(svg, layer, size) {
|
|
129
|
+
var root = ${String(ROOT_TAG)}.exec(svg);
|
|
130
|
+
if (root === null) {
|
|
131
|
+
return svg;
|
|
132
|
+
}
|
|
133
|
+
var at = root[0].length;
|
|
134
|
+
var background = ${String(BACKGROUND_RECT)}.exec(svg.slice(at));
|
|
135
|
+
if (background !== null) {
|
|
136
|
+
at += background[0].length;
|
|
137
|
+
}
|
|
138
|
+
var image =
|
|
139
|
+
'\\n<image href="' + reportAttributeText(layer.href) + '" x="' + reportLayerNumber(layer.x) + '" y="' + reportLayerNumber(layer.y) + '" ' +
|
|
140
|
+
'width="' + reportLayerNumber(layer.width) + '" height="' + reportLayerNumber(layer.height) + '" preserveAspectRatio="none"></image>';
|
|
141
|
+
return reportMillimeterRoot(svg.slice(0, at) + image + svg.slice(at), size);
|
|
142
|
+
}
|
|
143
|
+
function reportList(member) {
|
|
144
|
+
if (member === undefined || member === null) {
|
|
145
|
+
return [];
|
|
146
|
+
}
|
|
147
|
+
return Array.isArray(member) ? member : [member];
|
|
148
|
+
}
|
|
149
|
+
function reportItemValue(item) {
|
|
150
|
+
return typeof item === "object" && item !== null && !Array.isArray(item) ? item.value : item;
|
|
151
|
+
}
|
|
152
|
+
function reportLabeledItem(item) {
|
|
153
|
+
return typeof item === "object" && item !== null && !Array.isArray(item) && item.label !== undefined;
|
|
154
|
+
}
|
|
155
|
+
function reportExtentAnchors(data) {
|
|
156
|
+
var least = [];
|
|
157
|
+
var most = [];
|
|
158
|
+
for (var i = 0; i < data.length; i++) {
|
|
159
|
+
var value = reportItemValue(data[i]);
|
|
160
|
+
if (!Array.isArray(value)) {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
for (var d = 0; d < value.length; d++) {
|
|
164
|
+
var cell = value[d];
|
|
165
|
+
var number = typeof cell === "number" ? cell : typeof cell === "string" && cell.trim() !== "" ? Number(cell) : NaN;
|
|
166
|
+
if (!isFinite(number)) {
|
|
167
|
+
if (least[d] === undefined) {
|
|
168
|
+
least[d] = cell;
|
|
169
|
+
most[d] = cell;
|
|
170
|
+
}
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (least[d] === undefined || typeof least[d] !== "number" || number < least[d]) {
|
|
174
|
+
least[d] = number;
|
|
175
|
+
}
|
|
176
|
+
if (most[d] === undefined || typeof most[d] !== "number" || number > most[d]) {
|
|
177
|
+
most[d] = number;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (least.length === 0) {
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
return [
|
|
185
|
+
{ value: least, symbol: "none", label: { show: false } },
|
|
186
|
+
{ value: most, symbol: "none", label: { show: false } }
|
|
187
|
+
];
|
|
188
|
+
}
|
|
189
|
+
function reportHybridVectorOption(option) {
|
|
190
|
+
var out = Object.assign({}, option);
|
|
191
|
+
var series = reportList(option.series);
|
|
192
|
+
var drawn = [];
|
|
193
|
+
for (var s = 0; s < series.length; s++) {
|
|
194
|
+
if (!reportIsPointLayer(series[s])) {
|
|
195
|
+
drawn.push(series[s]);
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
var data = Array.isArray(series[s].data) ? series[s].data : [];
|
|
199
|
+
var kept = [];
|
|
200
|
+
for (var i = 0; i < data.length; i++) {
|
|
201
|
+
if (reportLabeledItem(data[i])) {
|
|
202
|
+
kept.push(data[i]);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
drawn.push(Object.assign({}, series[s], { large: false, data: kept.concat(reportExtentAnchors(data)) }));
|
|
206
|
+
}
|
|
207
|
+
out.series = drawn;
|
|
208
|
+
return out;
|
|
209
|
+
}
|
|
210
|
+
function reportSeriesGrid(option, series) {
|
|
211
|
+
var axes = reportList(option.xAxis);
|
|
212
|
+
var axis = axes[typeof series.xAxisIndex === "number" ? series.xAxisIndex : 0];
|
|
213
|
+
return axis && typeof axis.gridIndex === "number" ? axis.gridIndex : 0;
|
|
214
|
+
}
|
|
215
|
+
function reportContinuousAxis(axis, kind) {
|
|
216
|
+
var type = axis.type === undefined ? (kind === "xAxis" ? "category" : "value") : axis.type;
|
|
217
|
+
return type === "value" || type === "log" || type === "time";
|
|
218
|
+
}
|
|
219
|
+
function reportGridBox(chart, gridIndex, seed, width, height) {
|
|
220
|
+
var finder = { gridIndex: gridIndex };
|
|
221
|
+
if (!chart.containPixel(finder, seed)) {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
function edge(inside, outside, point) {
|
|
225
|
+
for (var step = 0; step < ${EDGE_SEARCH_STEPS}; step++) {
|
|
226
|
+
var middle = (inside + outside) / 2;
|
|
227
|
+
if (chart.containPixel(finder, point(middle))) {
|
|
228
|
+
inside = middle;
|
|
229
|
+
} else {
|
|
230
|
+
outside = middle;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return inside;
|
|
234
|
+
}
|
|
235
|
+
function alongX(x) {
|
|
236
|
+
return [x, seed[1]];
|
|
237
|
+
}
|
|
238
|
+
function alongY(y) {
|
|
239
|
+
return [seed[0], y];
|
|
240
|
+
}
|
|
241
|
+
var left = edge(seed[0], -1, alongX);
|
|
242
|
+
var right = edge(seed[0], width + 1, alongX);
|
|
243
|
+
var top = edge(seed[1], -1, alongY);
|
|
244
|
+
var bottom = edge(seed[1], height + 1, alongY);
|
|
245
|
+
return { x: left, y: top, width: right - left, height: bottom - top };
|
|
246
|
+
}
|
|
247
|
+
function reportSeed(chart, option, series, index, width, height) {
|
|
248
|
+
var data = Array.isArray(series.data) ? series.data : [];
|
|
249
|
+
if (data.length === 0) {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
var first = null;
|
|
253
|
+
for (var i = 0; i < data.length && first === null; i++) {
|
|
254
|
+
var value = reportItemValue(data[i]);
|
|
255
|
+
first = Array.isArray(value) ? value : null;
|
|
256
|
+
}
|
|
257
|
+
if (first !== null) {
|
|
258
|
+
// A continuous axis covers the extent of its data, and a category axis draws each category inside the grid.
|
|
259
|
+
// Thus the middle of the extent of a continuous dimension, and the category of the first row of a category
|
|
260
|
+
// dimension, give a point inside the grid of the layer.
|
|
261
|
+
var anchors = reportExtentAnchors(data);
|
|
262
|
+
var axes = [reportList(option.xAxis)[typeof series.xAxisIndex === "number" ? series.xAxisIndex : 0], reportList(option.yAxis)[typeof series.yAxisIndex === "number" ? series.yAxisIndex : 0]];
|
|
263
|
+
var kinds = ["xAxis", "yAxis"];
|
|
264
|
+
var place = [];
|
|
265
|
+
for (var d = 0; d < 2; d++) {
|
|
266
|
+
var least = anchors[0].value[d];
|
|
267
|
+
var most = anchors[1].value[d];
|
|
268
|
+
var continuous = axes[d] !== undefined && reportContinuousAxis(axes[d], kinds[d]);
|
|
269
|
+
place.push(continuous && typeof least === "number" && typeof most === "number" ? (least + most) / 2 : first[d]);
|
|
270
|
+
}
|
|
271
|
+
var point = chart.convertToPixel({ seriesIndex: index }, place);
|
|
272
|
+
if (Array.isArray(point) && isFinite(point[0]) && isFinite(point[1])) {
|
|
273
|
+
return point;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return [width / 2, height / 2];
|
|
277
|
+
}
|
|
278
|
+
function reportLargestSize(size) {
|
|
279
|
+
if (typeof size === "number") {
|
|
280
|
+
return size;
|
|
281
|
+
}
|
|
282
|
+
if (!Array.isArray(size)) {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
var largest = 0;
|
|
286
|
+
for (var i = 0; i < size.length; i++) {
|
|
287
|
+
largest = Math.max(largest, Number(size[i]) || 0);
|
|
288
|
+
}
|
|
289
|
+
return largest;
|
|
290
|
+
}
|
|
291
|
+
function reportMapAppliesTo(map, index) {
|
|
292
|
+
var named = map.seriesIndex;
|
|
293
|
+
if (named === undefined || named === null) {
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
return Array.isArray(named) ? named.indexOf(index) >= 0 : named === index;
|
|
297
|
+
}
|
|
298
|
+
function reportSymbolReach(option, series, index) {
|
|
299
|
+
var own = reportLargestSize(series.symbolSize);
|
|
300
|
+
var largest = own === null ? ${RUNTIME_SYMBOL_PX} : own;
|
|
301
|
+
var maps = reportList(option.visualMap);
|
|
302
|
+
for (var m = 0; m < maps.length; m++) {
|
|
303
|
+
if (typeof maps[m] !== "object" || maps[m] === null || !reportMapAppliesTo(maps[m], index)) {
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
var visuals = [maps[m].inRange, maps[m].outOfRange].concat(reportList(maps[m].pieces));
|
|
307
|
+
for (var v = 0; v < visuals.length; v++) {
|
|
308
|
+
var mapped = typeof visuals[v] === "object" && visuals[v] !== null ? reportLargestSize(visuals[v].symbolSize) : null;
|
|
309
|
+
if (mapped !== null) {
|
|
310
|
+
largest = Math.max(largest, mapped);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return largest / 2;
|
|
315
|
+
}
|
|
316
|
+
function reportPointLayerBox(chart, option, width, height) {
|
|
317
|
+
var series = reportList(option.series);
|
|
318
|
+
var boxes = {};
|
|
319
|
+
var found = false;
|
|
320
|
+
var reach = 0;
|
|
321
|
+
for (var s = 0; s < series.length; s++) {
|
|
322
|
+
if (!reportIsPointLayer(series[s])) {
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
reach = Math.max(reach, Math.ceil(reportSymbolReach(option, series[s], s)));
|
|
326
|
+
var grid = reportSeriesGrid(option, series[s]);
|
|
327
|
+
if (boxes[grid] !== undefined) {
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
// A layer with no row gives no place inside its grid. A facet panel can hold no row of one category, thus
|
|
331
|
+
// the grid takes its seed from the next layer that holds rows, and a grid of empty layers draws no point.
|
|
332
|
+
var seed = reportSeed(chart, option, series[s], s, width, height);
|
|
333
|
+
if (seed === null) {
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
var box = reportGridBox(chart, grid, seed, width, height);
|
|
337
|
+
if (box === null) {
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
boxes[grid] = box;
|
|
341
|
+
found = true;
|
|
342
|
+
}
|
|
343
|
+
if (!found) {
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
var union = null;
|
|
347
|
+
for (var key in boxes) {
|
|
348
|
+
var b = boxes[key];
|
|
349
|
+
if (union === null) {
|
|
350
|
+
union = { x: b.x, y: b.y, right: b.x + b.width, bottom: b.y + b.height };
|
|
351
|
+
} else {
|
|
352
|
+
union = { x: Math.min(union.x, b.x), y: Math.min(union.y, b.y), right: Math.max(union.right, b.x + b.width), bottom: Math.max(union.bottom, b.y + b.height) };
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
var extents = { xAxis: [], yAxis: [] };
|
|
356
|
+
var kinds = ["xAxis", "yAxis"];
|
|
357
|
+
for (var k = 0; k < kinds.length; k++) {
|
|
358
|
+
var axes = reportList(option[kinds[k]]);
|
|
359
|
+
for (var a = 0; a < axes.length; a++) {
|
|
360
|
+
var place = boxes[typeof axes[a].gridIndex === "number" ? axes[a].gridIndex : 0];
|
|
361
|
+
if (place === undefined || !reportContinuousAxis(axes[a], kinds[k])) {
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
var finder = {};
|
|
365
|
+
finder[kinds[k] + "Index"] = a;
|
|
366
|
+
var ends = kinds[k] === "xAxis" ? [place.x, place.x + place.width] : [place.y + place.height, place.y];
|
|
367
|
+
var first = chart.convertFromPixel(finder, ends[0]);
|
|
368
|
+
var last = chart.convertFromPixel(finder, ends[1]);
|
|
369
|
+
extents[kinds[k]][a] = { min: Math.min(first, last), max: Math.max(first, last) };
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
var left = Math.max(0, union.x - reach);
|
|
373
|
+
var top = Math.max(0, union.y - reach);
|
|
374
|
+
var right = Math.min(width, union.right + reach);
|
|
375
|
+
var bottom = Math.min(height, union.bottom + reach);
|
|
376
|
+
return { boxes: boxes, extents: extents, box: { x: left, y: top, width: right - left, height: bottom - top } };
|
|
377
|
+
}
|
|
378
|
+
function reportUnlabeledItem(item) {
|
|
379
|
+
if (!reportLabeledItem(item)) {
|
|
380
|
+
return item;
|
|
381
|
+
}
|
|
382
|
+
var copy = Object.assign({}, item);
|
|
383
|
+
delete copy.label;
|
|
384
|
+
return copy;
|
|
385
|
+
}
|
|
386
|
+
function reportHidden(member) {
|
|
387
|
+
if (Array.isArray(member)) {
|
|
388
|
+
var list = [];
|
|
389
|
+
for (var i = 0; i < member.length; i++) {
|
|
390
|
+
list.push(Object.assign({}, member[i], { show: false }));
|
|
391
|
+
}
|
|
392
|
+
return list;
|
|
393
|
+
}
|
|
394
|
+
return Object.assign({}, member, { show: false });
|
|
395
|
+
}
|
|
396
|
+
function reportHybridRasterOption(option, layer) {
|
|
397
|
+
var out = Object.assign({}, option);
|
|
398
|
+
delete out.graphic;
|
|
399
|
+
delete out.title;
|
|
400
|
+
if (out.legend !== undefined) {
|
|
401
|
+
out.legend = reportHidden(out.legend);
|
|
402
|
+
}
|
|
403
|
+
if (out.visualMap !== undefined) {
|
|
404
|
+
out.visualMap = reportHidden(out.visualMap);
|
|
405
|
+
}
|
|
406
|
+
var series = reportList(option.series);
|
|
407
|
+
var drawn = [];
|
|
408
|
+
for (var s = 0; s < series.length; s++) {
|
|
409
|
+
var copy = Object.assign({}, series[s], { label: { show: false }, progressive: 0 });
|
|
410
|
+
delete copy.markLine;
|
|
411
|
+
delete copy.markArea;
|
|
412
|
+
delete copy.markPoint;
|
|
413
|
+
if (reportIsPointLayer(series[s])) {
|
|
414
|
+
var data = Array.isArray(series[s].data) ? series[s].data : [];
|
|
415
|
+
var points = [];
|
|
416
|
+
for (var i = 0; i < data.length; i++) {
|
|
417
|
+
points.push(reportUnlabeledItem(data[i]));
|
|
418
|
+
}
|
|
419
|
+
copy.data = points;
|
|
420
|
+
} else {
|
|
421
|
+
copy.data = [];
|
|
422
|
+
}
|
|
423
|
+
drawn.push(copy);
|
|
424
|
+
}
|
|
425
|
+
out.series = drawn;
|
|
426
|
+
var grids = reportList(option.grid);
|
|
427
|
+
var placed = [];
|
|
428
|
+
var count = grids.length > 0 ? grids.length : 1;
|
|
429
|
+
for (var g = 0; g < count; g++) {
|
|
430
|
+
var grid = Object.assign({}, grids[g] || {});
|
|
431
|
+
var box = layer.boxes[g];
|
|
432
|
+
if (box !== undefined) {
|
|
433
|
+
delete grid.right;
|
|
434
|
+
delete grid.bottom;
|
|
435
|
+
grid.left = box.x;
|
|
436
|
+
grid.top = box.y;
|
|
437
|
+
grid.width = box.width;
|
|
438
|
+
grid.height = box.height;
|
|
439
|
+
grid.containLabel = false;
|
|
440
|
+
grid.outerBoundsMode = "none";
|
|
441
|
+
}
|
|
442
|
+
placed.push(grid);
|
|
443
|
+
}
|
|
444
|
+
out.grid = placed;
|
|
445
|
+
var kinds = ["xAxis", "yAxis"];
|
|
446
|
+
for (var k = 0; k < kinds.length; k++) {
|
|
447
|
+
if (option[kinds[k]] === undefined) {
|
|
448
|
+
continue;
|
|
449
|
+
}
|
|
450
|
+
var axes = reportList(option[kinds[k]]);
|
|
451
|
+
var pinned = [];
|
|
452
|
+
for (var a = 0; a < axes.length; a++) {
|
|
453
|
+
var axis = Object.assign({}, axes[a], { show: false });
|
|
454
|
+
var extent = layer.extents[kinds[k]][a];
|
|
455
|
+
if (extent !== undefined) {
|
|
456
|
+
axis.min = extent.min;
|
|
457
|
+
axis.max = extent.max;
|
|
458
|
+
}
|
|
459
|
+
pinned.push(axis);
|
|
460
|
+
}
|
|
461
|
+
out[kinds[k]] = Array.isArray(option[kinds[k]]) ? pinned : pinned[0];
|
|
462
|
+
}
|
|
463
|
+
return out;
|
|
464
|
+
}
|
|
465
|
+
function reportCroppedLayer(chart, box, ratio) {
|
|
466
|
+
var full = chart.renderToCanvas({ pixelRatio: ratio });
|
|
467
|
+
var crop = document.createElement("canvas");
|
|
468
|
+
crop.width = Math.max(1, Math.round(box.width * ratio));
|
|
469
|
+
crop.height = Math.max(1, Math.round(box.height * ratio));
|
|
470
|
+
crop.getContext("2d").drawImage(full, box.x * ratio, box.y * ratio, box.width * ratio, box.height * ratio, 0, 0, crop.width, crop.height);
|
|
471
|
+
return crop.toDataURL("image/png");
|
|
472
|
+
}
|
|
473
|
+
function reportHybridSvg(runtime, option, size) {
|
|
474
|
+
var exported = reportExportOption(option, size.textPx, size.width, size.height);
|
|
475
|
+
if (!reportList(exported.series).some(reportIsPointLayer)) {
|
|
476
|
+
return null;
|
|
477
|
+
}
|
|
478
|
+
var vector = runtime.init(null, size.theme, { renderer: "svg", ssr: true, width: size.width, height: size.height });
|
|
479
|
+
var svg;
|
|
480
|
+
var layer;
|
|
481
|
+
try {
|
|
482
|
+
vector.setOption(reportHybridVectorOption(exported));
|
|
483
|
+
layer = reportPointLayerBox(vector, exported, size.width, size.height);
|
|
484
|
+
svg = vector.renderToSVGString();
|
|
485
|
+
} finally {
|
|
486
|
+
vector.dispose();
|
|
487
|
+
}
|
|
488
|
+
if (layer === null) {
|
|
489
|
+
return null;
|
|
490
|
+
}
|
|
491
|
+
var raster = runtime.init(document.createElement("div"), size.theme, { renderer: "canvas", width: size.width, height: size.height, devicePixelRatio: size.pixelRatio });
|
|
492
|
+
var href;
|
|
493
|
+
try {
|
|
494
|
+
raster.setOption(reportHybridRasterOption(exported, layer));
|
|
495
|
+
href = reportCroppedLayer(raster, layer.box, size.pixelRatio);
|
|
496
|
+
} finally {
|
|
497
|
+
raster.dispose();
|
|
498
|
+
}
|
|
499
|
+
return reportComposeHybridSvg(
|
|
500
|
+
svg,
|
|
501
|
+
{ href: href, x: layer.box.x, y: layer.box.y, width: layer.box.width, height: layer.box.height },
|
|
502
|
+
{ widthPx: size.width, heightPx: size.height, widthMm: size.widthMm, heightMm: size.heightMm }
|
|
503
|
+
);
|
|
504
|
+
}`;
|
|
@@ -115,3 +115,22 @@ export declare function smallestPositiveValue(cells: readonly (string | number |
|
|
|
115
115
|
* A text that carries no exponent, and a text that holds no finite number, both give false.
|
|
116
116
|
*/
|
|
117
117
|
export declare function holdsADriftedExponent(text: string): boolean;
|
|
118
|
+
/**
|
|
119
|
+
* The text of a figure with each scientific form as a power of ten, for example `1.3 × 10⁻³` from `1.3e-3`.
|
|
120
|
+
*
|
|
121
|
+
* A publication figure prints the power of ten, and a table cell and a metric card keep the short form that
|
|
122
|
+
* `formatNumberCell` gives. Thus the chart canvas and the export read this, and the page text does not. The
|
|
123
|
+
* rewrite reads the shown text, thus each kind and each bound keeps its digits, and a text with no exponent
|
|
124
|
+
* stays as it is.
|
|
125
|
+
*/
|
|
126
|
+
export declare function typographicExponent(text: string): string;
|
|
127
|
+
/**
|
|
128
|
+
* One shown form with the sign of its value as the typographic minus.
|
|
129
|
+
*
|
|
130
|
+
* The substitution reads the leading character alone. Thus the exponent of a form such as `-1.2e-4` keeps
|
|
131
|
+
* its own hyphen, and a reader of that exponent reads the notation that the module prints.
|
|
132
|
+
*
|
|
133
|
+
* The shown form then no longer parses back to the value, thus the caller carries the raw cell in the full
|
|
134
|
+
* form. A negative always names its stored digits beside the glyph.
|
|
135
|
+
*/
|
|
136
|
+
export declare function shownMinus(text: string): string;
|
|
@@ -321,6 +321,30 @@ export function holdsADriftedExponent(text) {
|
|
|
321
321
|
const shown = EXPONENT_PART.exec(formatNumberCell(value, "scientific").text);
|
|
322
322
|
return shown !== null && shown[1] !== written[1];
|
|
323
323
|
}
|
|
324
|
+
/**
|
|
325
|
+
* One scientific form inside a text: a coefficient with its sign, and an exponent. The coefficient stands
|
|
326
|
+
* alone, thus a name such as `rs1e5` holds no scientific form.
|
|
327
|
+
*/
|
|
328
|
+
const SCIENTIFIC_IN_TEXT = /(?<![\w.])([−-]?\d+(?:\.\d+)?)e([+-]?\d+)(?![\w.])/g;
|
|
329
|
+
/** The superscript form of each decimal digit, in digit order. */
|
|
330
|
+
const SUPERSCRIPT_DIGITS = ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"];
|
|
331
|
+
/** The superscript minus of a negative exponent. */
|
|
332
|
+
const SUPERSCRIPT_MINUS = "⁻";
|
|
333
|
+
/**
|
|
334
|
+
* The text of a figure with each scientific form as a power of ten, for example `1.3 × 10⁻³` from `1.3e-3`.
|
|
335
|
+
*
|
|
336
|
+
* A publication figure prints the power of ten, and a table cell and a metric card keep the short form that
|
|
337
|
+
* `formatNumberCell` gives. Thus the chart canvas and the export read this, and the page text does not. The
|
|
338
|
+
* rewrite reads the shown text, thus each kind and each bound keeps its digits, and a text with no exponent
|
|
339
|
+
* stays as it is.
|
|
340
|
+
*/
|
|
341
|
+
export function typographicExponent(text) {
|
|
342
|
+
return text.replace(SCIENTIFIC_IN_TEXT, (_form, coefficient, exponent) => {
|
|
343
|
+
const power = Number(exponent);
|
|
344
|
+
const digits = [...String(Math.abs(power))].map((digit) => SUPERSCRIPT_DIGITS[Number(digit)]).join("");
|
|
345
|
+
return `${shownMinus(coefficient)} × 10${power < 0 ? SUPERSCRIPT_MINUS : ""}${digits}`;
|
|
346
|
+
});
|
|
347
|
+
}
|
|
324
348
|
/**
|
|
325
349
|
* The bound of a stored zero, as one significant digit that rounds up, for example `4e-4` from `0.00036`.
|
|
326
350
|
*
|
|
@@ -394,7 +418,7 @@ function formatValue(value, kind) {
|
|
|
394
418
|
* The shown form then no longer parses back to the value, thus the caller carries the raw cell in the full
|
|
395
419
|
* form. A negative always names its stored digits beside the glyph.
|
|
396
420
|
*/
|
|
397
|
-
function shownMinus(text) {
|
|
421
|
+
export function shownMinus(text) {
|
|
398
422
|
return text.startsWith("-") ? TYPOGRAPHIC_MINUS + text.slice(1) : text;
|
|
399
423
|
}
|
|
400
424
|
/** The scientific form, for example `4.3e-5`. */
|
|
@@ -53,24 +53,61 @@ export declare const PAGE_READY_TIMEOUT_MS = 8000;
|
|
|
53
53
|
*
|
|
54
54
|
* The fragment writes its own constants, because a page script reads no module binding. Each rule here is
|
|
55
55
|
* the twin of one rule of the server derivation: the number read of a cell, the four transforms, the
|
|
56
|
-
* competition rank, the compare of a sort,
|
|
57
|
-
*
|
|
56
|
+
* competition rank, the compare of a sort, the classification of a preset, and the item that adds
|
|
57
|
+
* the member of a continuous color and of a size after the pair. A shared test vector runs the transforms
|
|
58
|
+
* and the items of both sides over one set of cells, thus the two cannot drift in silence.
|
|
58
59
|
*
|
|
59
60
|
* The build reads the decoded rows of the payload. The decoder runs before this script, thus a row is a
|
|
60
61
|
* record and a cell reads by its column name.
|
|
61
62
|
*/
|
|
62
63
|
export declare const CHART_SERIES_BUILDER: string;
|
|
64
|
+
/**
|
|
65
|
+
* The window global that holds the option of each chart, keyed by the id of its container.
|
|
66
|
+
*
|
|
67
|
+
* The option is plain data: its rows are built, and each renderer is still a name. The export of a chart
|
|
68
|
+
* draws it again from this entry, thus the page and each exported file read one option.
|
|
69
|
+
*/
|
|
70
|
+
export declare const CHART_OPTIONS_GLOBAL = "__REPORT_CHART_OPTIONS";
|
|
63
71
|
/**
|
|
64
72
|
* The page-side script that wires each chart. It finds every chart container, reads the option JSON from
|
|
65
73
|
* the sibling `<script type="application/json">` element, and initializes ECharts with the registered
|
|
66
74
|
* theme. The skeleton registers the theme before this script runs. A resize handler keeps each chart
|
|
67
|
-
* fit to the window.
|
|
75
|
+
* fit to the window. It draws a chart again only when the container of the chart changes size. A capture past
|
|
76
|
+
* the viewport resizes the window and keeps each container, and a redraw there restarts the chunked render of
|
|
77
|
+
* a dense chart. A container of zero width or height keeps its chart as it is: ECharts 6.1.0 throws when a
|
|
78
|
+
* Sankey draws at a zero size (apache/echarts#21706), and a capture can give a container a zero width for one
|
|
79
|
+
* resize.
|
|
80
|
+
*
|
|
81
|
+
* A custom series names its renderer as a string, because the option is JSON. The script registers each named
|
|
82
|
+
* renderer with the chart runtime before the first chart initializes, and it keeps the option under the
|
|
83
|
+
* container id.
|
|
84
|
+
*
|
|
85
|
+
* The option carries the toolbox of the chart. Each handler of the toolbox is the name of a page function, and
|
|
86
|
+
* the script binds each function after the parse and before the chart initializes. The formatter of a genome axis
|
|
87
|
+
* is such a name too. After the init the script attaches the zoom handler of the toolbox to the chart. The
|
|
88
|
+
* download control opens the download menu of the card. The print hides the canvas layer of the toolbox of each
|
|
89
|
+
* chart, because the runtime draws the toolbox inside the chart body, and the end of the print shows the layer
|
|
90
|
+
* again. The print sets no option, because a new option starts the chunked draw of a dense chart again.
|
|
91
|
+
*
|
|
92
|
+
* A click on a PNG entry of the menu draws the kept option again on a detached element, at the CSS size of the
|
|
93
|
+
* export and its pixel ratio, in the theme of its text size. The entry states the height of its export, because
|
|
94
|
+
* a taller chart body grows the height of a column export. Each series draws in one pass, because the script
|
|
95
|
+
* reads the PNG in the same task and a chunked draw ends in a later frame. Then the script reads the PNG and
|
|
96
|
+
* downloads it through an anchor. An entry that names no kept chart, or no export size, draws nothing.
|
|
97
|
+
*
|
|
98
|
+
* A click on a hybrid SVG entry builds the SVG of a dense chart from the kept option: the vector draw, the raster
|
|
99
|
+
* draw of the point layer at 300 DPI, and the composition. Then the script downloads the text through an anchor.
|
|
100
|
+
* A build that gives no file keeps the menu open and shows its fault note, thus the reader sees why the entry gave
|
|
101
|
+
* no file and can take a PNG.
|
|
68
102
|
*
|
|
69
103
|
* An option that carries the data-source member holds no row. The script then reads the registered payload
|
|
70
104
|
* of the artifact and builds the data of each series from the descriptors. A mount whose payload the
|
|
71
105
|
* registry does not hold keeps its empty card, and the walk continues.
|
|
72
106
|
*
|
|
73
|
-
* The script signals readiness when
|
|
107
|
+
* The script signals readiness when each chart that it set fires its first `finished` event, and immediately
|
|
108
|
+
* when no chart exists. A dense scatter draws in chunks over some frames, and the runtime fires `finished`
|
|
109
|
+
* after the last chunk. Thus a capture that keys on the signal sees each point. A chart whose option throws
|
|
110
|
+
* counts as finished, thus one fault never withholds the signal. It sets
|
|
74
111
|
* the `window.__inflexaThemeReady` sentinel and dispatches the `inflexa-theme-ready` event on the document.
|
|
75
112
|
* A reader that captures the page keys on this signal, thus the capture returns when the page is ready and
|
|
76
113
|
* not at a timeout. The sentinel guards a listener that registers after the dispatch, thus a late listener
|