ggaction 0.0.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/CHANGELOG.md +27 -0
- package/LICENSE +21 -0
- package/README.md +108 -0
- package/package.json +84 -0
- package/src/AGENTS.md +119 -0
- package/src/ChartProgram.js +10 -0
- package/src/actions/boxPlots/components.js +88 -0
- package/src/actions/boxPlots/create.js +84 -0
- package/src/actions/boxPlots/index.js +10 -0
- package/src/actions/boxPlots/materialize.js +183 -0
- package/src/actions/boxPlots/options.js +147 -0
- package/src/actions/boxPlots/resolve.js +38 -0
- package/src/actions/canvas/actions.js +144 -0
- package/src/actions/canvas/index.js +6 -0
- package/src/actions/coordinates/actions.js +85 -0
- package/src/actions/coordinates/index.js +5 -0
- package/src/actions/data/box.js +40 -0
- package/src/actions/data/create.js +33 -0
- package/src/actions/data/density.js +62 -0
- package/src/actions/data/derived.js +52 -0
- package/src/actions/data/filter.js +168 -0
- package/src/actions/data/index.js +32 -0
- package/src/actions/data/interval.js +69 -0
- package/src/actions/data/regression.js +71 -0
- package/src/actions/data/shared.js +25 -0
- package/src/actions/encodings/appearance.js +243 -0
- package/src/actions/encodings/barWidth.js +60 -0
- package/src/actions/encodings/color.js +329 -0
- package/src/actions/encodings/density.js +225 -0
- package/src/actions/encodings/histogram.js +50 -0
- package/src/actions/encodings/index.js +23 -0
- package/src/actions/encodings/offset.js +104 -0
- package/src/actions/encodings/position/policies/area.js +24 -0
- package/src/actions/encodings/position/policies/bar.js +110 -0
- package/src/actions/encodings/position/policies/common.js +17 -0
- package/src/actions/encodings/position/policies/index.js +25 -0
- package/src/actions/encodings/position/policies/line.js +74 -0
- package/src/actions/encodings/position/policies/point.js +19 -0
- package/src/actions/encodings/position/policies/rule.js +17 -0
- package/src/actions/encodings/position/resolve.js +170 -0
- package/src/actions/encodings/position.js +176 -0
- package/src/actions/encodings/ranged.js +276 -0
- package/src/actions/encodings/ruleAppearance.js +47 -0
- package/src/actions/encodings/shared.js +164 -0
- package/src/actions/encodings/strokeDash.js +145 -0
- package/src/actions/errorBands/components.js +81 -0
- package/src/actions/errorBands/create.js +159 -0
- package/src/actions/errorBands/index.js +7 -0
- package/src/actions/errorBands/resolve.js +28 -0
- package/src/actions/errorBars/components.js +62 -0
- package/src/actions/errorBars/create.js +144 -0
- package/src/actions/errorBars/index.js +7 -0
- package/src/actions/errorBars/resolve.js +25 -0
- package/src/actions/guides/axes/axes.js +204 -0
- package/src/actions/guides/axes/axis.js +131 -0
- package/src/actions/guides/axes/index.js +17 -0
- package/src/actions/guides/axes/labels.js +231 -0
- package/src/actions/guides/axes/lines.js +149 -0
- package/src/actions/guides/axes/policy.js +155 -0
- package/src/actions/guides/axes/tickGroups.js +149 -0
- package/src/actions/guides/axes/ticks.js +179 -0
- package/src/actions/guides/axes/titles.js +264 -0
- package/src/actions/guides/grids/grid.js +228 -0
- package/src/actions/guides/grids/index.js +1 -0
- package/src/actions/guides/grids/resolve.js +258 -0
- package/src/actions/guides/guides.js +138 -0
- package/src/actions/guides/index.js +11 -0
- package/src/actions/guides/legends/categorical/actions.js +329 -0
- package/src/actions/guides/legends/categorical/components.js +140 -0
- package/src/actions/guides/legends/categorical/index.js +49 -0
- package/src/actions/guides/legends/categorical/layout.js +445 -0
- package/src/actions/guides/legends/categorical/options.js +188 -0
- package/src/actions/guides/legends/categorical/recipes.js +120 -0
- package/src/actions/guides/legends/categorical/resolve.js +131 -0
- package/src/actions/guides/legends/categorical/symbols.js +280 -0
- package/src/actions/guides/legends/categorical/validation.js +27 -0
- package/src/actions/guides/legends/continuous/common.js +273 -0
- package/src/actions/guides/legends/continuous/gradient.js +363 -0
- package/src/actions/guides/legends/continuous/index.js +25 -0
- package/src/actions/guides/legends/continuous/interval.js +234 -0
- package/src/actions/guides/legends/continuous/opacity.js +382 -0
- package/src/actions/guides/legends/edit.js +314 -0
- package/src/actions/guides/legends/index.js +9 -0
- package/src/actions/guides/legends/size.js +220 -0
- package/src/actions/guides/tickValues.js +84 -0
- package/src/actions/index.js +31 -0
- package/src/actions/intervals/resolve.js +352 -0
- package/src/actions/marks/area.js +369 -0
- package/src/actions/marks/bar/create.js +46 -0
- package/src/actions/marks/bar/edit.js +90 -0
- package/src/actions/marks/bar/index.js +9 -0
- package/src/actions/marks/bar/materialize.js +130 -0
- package/src/actions/marks/index.js +13 -0
- package/src/actions/marks/line.js +248 -0
- package/src/actions/marks/point.js +420 -0
- package/src/actions/marks/rule.js +287 -0
- package/src/actions/marks/shared.js +112 -0
- package/src/actions/primitives/createGraphics.js +163 -0
- package/src/actions/primitives/editGraphics.js +208 -0
- package/src/actions/primitives/index.js +9 -0
- package/src/actions/primitives/semantic.js +168 -0
- package/src/actions/primitives/semanticValue.js +182 -0
- package/src/actions/regression/components.js +216 -0
- package/src/actions/regression/create.js +102 -0
- package/src/actions/regression/index.js +23 -0
- package/src/actions/regression/resolve.js +57 -0
- package/src/actions/scales/consumers.js +283 -0
- package/src/actions/scales/create.js +148 -0
- package/src/actions/scales/definitions.js +319 -0
- package/src/actions/scales/edit.js +290 -0
- package/src/actions/scales/index.js +11 -0
- package/src/actions/scales/materialize.js +466 -0
- package/src/actions/scales/quantitativeColor.js +45 -0
- package/src/actions/selection/actions.js +384 -0
- package/src/actions/selection/index.js +23 -0
- package/src/actions/titles/actions.js +235 -0
- package/src/actions/titles/index.js +19 -0
- package/src/actions/titles/resolve.js +321 -0
- package/src/core/ChartProgram.js +316 -0
- package/src/core/action.js +120 -0
- package/src/core/identifiers.js +28 -0
- package/src/core/immutable.js +94 -0
- package/src/core/specs.js +29 -0
- package/src/core/textMetrics.js +23 -0
- package/src/core/validation.js +54 -0
- package/src/core/vocabulary.js +58 -0
- package/src/extension.js +2 -0
- package/src/grammar/aggregate.js +259 -0
- package/src/grammar/areaSeries.js +217 -0
- package/src/grammar/bars/aggregate.js +98 -0
- package/src/grammar/bars/geometry.js +54 -0
- package/src/grammar/bars/policy.js +90 -0
- package/src/grammar/boxPlot.js +140 -0
- package/src/grammar/coordinates.js +25 -0
- package/src/grammar/curveCommands.js +356 -0
- package/src/grammar/density.js +296 -0
- package/src/grammar/filter.js +169 -0
- package/src/grammar/histogram.js +332 -0
- package/src/grammar/interval.js +343 -0
- package/src/grammar/lineSeries.js +197 -0
- package/src/grammar/markFilter.js +46 -0
- package/src/grammar/markSelection.js +326 -0
- package/src/grammar/palettes.js +208 -0
- package/src/grammar/pathCommands.js +86 -0
- package/src/grammar/pointShapes.js +164 -0
- package/src/grammar/positionCompatibility.js +32 -0
- package/src/grammar/regression.js +578 -0
- package/src/grammar/ruleAppearance.js +12 -0
- package/src/grammar/rules.js +90 -0
- package/src/grammar/scales/appearance.js +185 -0
- package/src/grammar/scales/color.js +349 -0
- package/src/grammar/scales/continuous.js +111 -0
- package/src/grammar/scales/definition.js +153 -0
- package/src/grammar/scales/discretized.js +159 -0
- package/src/grammar/scales/fields.js +133 -0
- package/src/grammar/scales/index.js +12 -0
- package/src/grammar/scales/mapping.js +27 -0
- package/src/grammar/scales/ordinal.js +221 -0
- package/src/grammar/scales/policies.js +50 -0
- package/src/grammar/scales/temporal.js +53 -0
- package/src/grammar/scales/transformed.js +236 -0
- package/src/grammar/scales/types.js +102 -0
- package/src/grammar/scales/validation.js +66 -0
- package/src/grammar/scales.js +1 -0
- package/src/grammar/schemas/concreteGraphic.js +73 -0
- package/src/grammar/schemas/graphic.js +131 -0
- package/src/grammar/schemas/graphicBounds.js +146 -0
- package/src/grammar/schemas/graphicTree.js +133 -0
- package/src/grammar/schemas/mark.js +4 -0
- package/src/grammar/schemas/semanticPath.js +174 -0
- package/src/grammar/seriesLayout.js +76 -0
- package/src/grammar/ticks.js +149 -0
- package/src/grammar/transforms.js +37 -0
- package/src/index.js +2 -0
- package/src/layout/canvas.js +114 -0
- package/src/layout/grid.js +17 -0
- package/src/layout/legend.js +51 -0
- package/src/layout/text.js +62 -0
- package/src/layout/title.js +107 -0
- package/src/materialization/bars/aggregate.js +184 -0
- package/src/materialization/bars/grouped.js +117 -0
- package/src/materialization/bars/histogram.js +163 -0
- package/src/materialization/bars/ranged.js +53 -0
- package/src/materialization/bars/resolve.js +56 -0
- package/src/materialization/dataProvenance.js +15 -0
- package/src/materialization/density.js +29 -0
- package/src/materialization/dependencies.js +134 -0
- package/src/materialization/encodings.js +50 -0
- package/src/materialization/graphicHierarchy.js +104 -0
- package/src/materialization/legends.js +20 -0
- package/src/materialization/marks.js +110 -0
- package/src/materialization/planner.js +38 -0
- package/src/materialization/selection/filter.js +40 -0
- package/src/materialization/selection/items.js +503 -0
- package/src/materialization/selection/path.js +37 -0
- package/src/materialization/selection/point.js +118 -0
- package/src/materialization/selection/policies/area.js +10 -0
- package/src/materialization/selection/policies/bar.js +10 -0
- package/src/materialization/selection/policies/index.js +40 -0
- package/src/materialization/selection/policies/line.js +10 -0
- package/src/materialization/selection/policies/point.js +10 -0
- package/src/materialization/selection/policies/rule.js +10 -0
- package/src/materialization/selection/state.js +67 -0
- package/src/materialization/selection/styles.js +183 -0
- package/src/renderers/canvas/circle.js +62 -0
- package/src/renderers/canvas/index.js +132 -0
- package/src/renderers/canvas/line.js +54 -0
- package/src/renderers/canvas/path.js +98 -0
- package/src/renderers/canvas/rect.js +57 -0
- package/src/renderers/canvas/text.js +96 -0
- package/src/renderers/canvas/validation.js +23 -0
- package/src/renderers/png.js +29 -0
- package/src/selectors/coordinates.js +13 -0
- package/src/selectors/datasets.js +13 -0
- package/src/selectors/index.js +4 -0
- package/src/selectors/layers.js +32 -0
- package/src/selectors/scales.js +21 -0
- package/src/theme/defaults.js +13 -0
- package/types/extension.d.ts +14 -0
- package/types/index.d.ts +81 -0
- package/types/png.d.ts +14 -0
- package/types/program.d.ts +1096 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { requireFiniteProperty } from "./validation.js";
|
|
2
|
+
import { validateConcreteGraphicProperties } from
|
|
3
|
+
"../../grammar/schemas/concreteGraphic.js";
|
|
4
|
+
|
|
5
|
+
function drawRect(context, child, collectionId) {
|
|
6
|
+
const properties = child.properties ?? {};
|
|
7
|
+
const graphicId = child.id ?? collectionId;
|
|
8
|
+
validateConcreteGraphicProperties("rect", properties);
|
|
9
|
+
const x = requireFiniteProperty(properties, "x", graphicId);
|
|
10
|
+
const y = requireFiniteProperty(properties, "y", graphicId);
|
|
11
|
+
const width = requireFiniteProperty(properties, "width", graphicId);
|
|
12
|
+
const height = requireFiniteProperty(properties, "height", graphicId);
|
|
13
|
+
const strokeWidth = requireFiniteProperty(
|
|
14
|
+
properties,
|
|
15
|
+
"strokeWidth",
|
|
16
|
+
graphicId
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
if (width < 0 || height < 0 || strokeWidth < 0) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
`Graphic "${graphicId}" requires non-negative rect dimensions and strokeWidth.`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
if (typeof properties.fill !== "string") {
|
|
25
|
+
throw new Error(`Graphic "${graphicId}" requires a string fill property.`);
|
|
26
|
+
}
|
|
27
|
+
if (typeof properties.stroke !== "string") {
|
|
28
|
+
throw new Error(`Graphic "${graphicId}" requires a string stroke property.`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const opacity = properties.opacity ?? 1;
|
|
32
|
+
if (!Number.isFinite(opacity) || opacity < 0 || opacity > 1) {
|
|
33
|
+
throw new Error(`Graphic "${graphicId}" requires opacity from 0 to 1.`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
context.globalAlpha = opacity;
|
|
37
|
+
context.fillStyle = properties.fill;
|
|
38
|
+
context.fillRect(x, y, width, height);
|
|
39
|
+
context.strokeStyle = properties.stroke;
|
|
40
|
+
context.lineWidth = strokeWidth;
|
|
41
|
+
context.setLineDash([]);
|
|
42
|
+
context.beginPath();
|
|
43
|
+
context.moveTo(x, y);
|
|
44
|
+
context.lineTo(x + width, y);
|
|
45
|
+
context.lineTo(x + width, y + height);
|
|
46
|
+
context.lineTo(x, y + height);
|
|
47
|
+
context.lineTo(x, y);
|
|
48
|
+
context.stroke();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function drawRectGraphic(context, id, graphic) {
|
|
52
|
+
if (graphic.items) {
|
|
53
|
+
for (const item of graphic.items) drawRect(context, item, id);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
drawRect(context, { id, properties: graphic.properties }, id);
|
|
57
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { requireFiniteProperty, requireStringProperty } from "./validation.js";
|
|
2
|
+
import { validateConcreteGraphicProperties } from
|
|
3
|
+
"../../grammar/schemas/concreteGraphic.js";
|
|
4
|
+
|
|
5
|
+
function drawText(context, child, collectionId) {
|
|
6
|
+
const properties = child.properties ?? {};
|
|
7
|
+
const graphicId = child.id ?? collectionId;
|
|
8
|
+
validateConcreteGraphicProperties("text", properties);
|
|
9
|
+
const x = requireFiniteProperty(properties, "x", graphicId);
|
|
10
|
+
const y = requireFiniteProperty(properties, "y", graphicId);
|
|
11
|
+
const fontSize = requireFiniteProperty(properties, "fontSize", graphicId);
|
|
12
|
+
const rotation = properties.rotation ?? 0;
|
|
13
|
+
const opacity = properties.opacity ?? 1;
|
|
14
|
+
const text = requireStringProperty(properties, "text", graphicId);
|
|
15
|
+
const fill = requireStringProperty(properties, "fill", graphicId);
|
|
16
|
+
const fontFamily = requireStringProperty(
|
|
17
|
+
properties,
|
|
18
|
+
"fontFamily",
|
|
19
|
+
graphicId
|
|
20
|
+
);
|
|
21
|
+
const textAlign = requireStringProperty(
|
|
22
|
+
properties,
|
|
23
|
+
"textAlign",
|
|
24
|
+
graphicId
|
|
25
|
+
);
|
|
26
|
+
const textBaseline = requireStringProperty(
|
|
27
|
+
properties,
|
|
28
|
+
"textBaseline",
|
|
29
|
+
graphicId
|
|
30
|
+
);
|
|
31
|
+
const fontWeight = properties.fontWeight ?? "normal";
|
|
32
|
+
|
|
33
|
+
if (fontSize <= 0) {
|
|
34
|
+
throw new Error(`Graphic "${graphicId}" requires a positive fontSize.`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!Number.isFinite(rotation)) {
|
|
38
|
+
throw new Error(`Graphic "${graphicId}" requires a finite rotation.`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!Number.isFinite(opacity) || opacity < 0 || opacity > 1) {
|
|
42
|
+
throw new Error(`Graphic "${graphicId}" requires opacity from 0 to 1.`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (
|
|
46
|
+
!(
|
|
47
|
+
(typeof fontWeight === "string" && fontWeight.length > 0) ||
|
|
48
|
+
Number.isFinite(fontWeight)
|
|
49
|
+
)
|
|
50
|
+
) {
|
|
51
|
+
throw new Error(`Graphic "${graphicId}" requires a valid fontWeight.`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!["left", "right", "center", "start", "end"].includes(textAlign)) {
|
|
55
|
+
throw new Error(`Graphic "${graphicId}" has invalid textAlign.`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (
|
|
59
|
+
![
|
|
60
|
+
"top",
|
|
61
|
+
"hanging",
|
|
62
|
+
"middle",
|
|
63
|
+
"alphabetic",
|
|
64
|
+
"ideographic",
|
|
65
|
+
"bottom"
|
|
66
|
+
].includes(textBaseline)
|
|
67
|
+
) {
|
|
68
|
+
throw new Error(`Graphic "${graphicId}" has invalid textBaseline.`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
context.save();
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
context.fillStyle = fill;
|
|
75
|
+
context.globalAlpha = opacity;
|
|
76
|
+
context.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
77
|
+
context.textAlign = textAlign;
|
|
78
|
+
context.textBaseline = textBaseline;
|
|
79
|
+
context.translate(x, y);
|
|
80
|
+
context.rotate(rotation);
|
|
81
|
+
context.fillText(text, 0, 0);
|
|
82
|
+
} finally {
|
|
83
|
+
context.restore();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function drawTextGraphic(context, id, graphic) {
|
|
88
|
+
if (graphic.items) {
|
|
89
|
+
for (const item of graphic.items) {
|
|
90
|
+
drawText(context, item, id);
|
|
91
|
+
}
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
drawText(context, { id, properties: graphic.properties }, id);
|
|
96
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function requireFiniteProperty(properties, property, graphicId) {
|
|
2
|
+
const value = properties[property];
|
|
3
|
+
|
|
4
|
+
if (!Number.isFinite(value)) {
|
|
5
|
+
throw new Error(
|
|
6
|
+
`Graphic "${graphicId}" requires a finite ${property} property.`
|
|
7
|
+
);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function requireStringProperty(properties, property, graphicId) {
|
|
14
|
+
const value = properties[property];
|
|
15
|
+
|
|
16
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Graphic "${graphicId}" requires a non-empty ${property} property.`
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { createCanvas } from "@napi-rs/canvas";
|
|
5
|
+
|
|
6
|
+
import { render } from "./canvas/index.js";
|
|
7
|
+
|
|
8
|
+
export async function renderToPNG(program, { output, pixelRatio = 1 } = {}) {
|
|
9
|
+
if (typeof output !== "string" || output.length === 0) {
|
|
10
|
+
throw new TypeError("renderToPNG requires a non-empty output path.");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const canvas = createCanvas(1, 1);
|
|
14
|
+
const context = canvas.getContext("2d");
|
|
15
|
+
render(program, context, { pixelRatio });
|
|
16
|
+
|
|
17
|
+
const path = resolve(output);
|
|
18
|
+
const buffer = canvas.toBuffer("image/png");
|
|
19
|
+
await mkdir(dirname(path), { recursive: true });
|
|
20
|
+
await writeFile(path, buffer);
|
|
21
|
+
|
|
22
|
+
return Object.freeze({
|
|
23
|
+
output: path,
|
|
24
|
+
width: canvas.width,
|
|
25
|
+
height: canvas.height,
|
|
26
|
+
pixelRatio,
|
|
27
|
+
bytes: buffer.length
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function findCoordinate(program, id) {
|
|
2
|
+
return program.semanticSpec.coordinates.find(coordinate => coordinate.id === id);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function hasCoordinate(program, id) {
|
|
6
|
+
return findCoordinate(program, id) !== undefined;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function requireCoordinate(program, id) {
|
|
10
|
+
const coordinate = findCoordinate(program, id);
|
|
11
|
+
if (coordinate === undefined) throw new Error(`Unknown coordinate "${id}".`);
|
|
12
|
+
return coordinate;
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function findDataset(program, id) {
|
|
2
|
+
return program.semanticSpec.datasets.find(dataset => dataset.id === id);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function hasDataset(program, id) {
|
|
6
|
+
return findDataset(program, id) !== undefined;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function requireDataset(program, id, label = `Dataset "${id}"`) {
|
|
10
|
+
const dataset = findDataset(program, id);
|
|
11
|
+
if (dataset === undefined) throw new Error(`${label} does not exist.`);
|
|
12
|
+
return dataset;
|
|
13
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function findLayer(program, id) {
|
|
2
|
+
return program.semanticSpec.layers.find(layer => layer.id === id);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function hasLayer(program, id) {
|
|
6
|
+
return findLayer(program, id) !== undefined;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function requireLayer(program, id, label = `Layer "${id}"`) {
|
|
10
|
+
const layer = findLayer(program, id);
|
|
11
|
+
if (layer === undefined) throw new Error(`${label} does not exist.`);
|
|
12
|
+
return layer;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function resolveEligibleLayer(program, {
|
|
16
|
+
target,
|
|
17
|
+
predicate,
|
|
18
|
+
label,
|
|
19
|
+
current = program.context.currentMark
|
|
20
|
+
}) {
|
|
21
|
+
const candidates = program.semanticSpec.layers.filter(predicate);
|
|
22
|
+
if (target !== undefined) {
|
|
23
|
+
const selected = candidates.find(layer => layer.id === target);
|
|
24
|
+
if (selected === undefined) throw new Error(`Unknown ${label} target "${target}".`);
|
|
25
|
+
return selected;
|
|
26
|
+
}
|
|
27
|
+
const selected = candidates.find(layer => layer.id === current);
|
|
28
|
+
if (selected !== undefined) return selected;
|
|
29
|
+
if (candidates.length === 1) return candidates[0];
|
|
30
|
+
if (candidates.length === 0) throw new Error(`${label} requires an eligible layer.`);
|
|
31
|
+
throw new Error(`${label} target is ambiguous; provide target.`);
|
|
32
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function findSemanticScale(program, id) {
|
|
2
|
+
return program.semanticSpec.scales.find(scale => scale.id === id);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function requireSemanticScale(program, id) {
|
|
6
|
+
const scale = findSemanticScale(program, id);
|
|
7
|
+
if (scale === undefined) throw new Error(`Unknown scale "${id}".`);
|
|
8
|
+
return scale;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function requireResolvedScale(program, id, type) {
|
|
12
|
+
const scale = program.resolvedScales[id];
|
|
13
|
+
if (scale === undefined || (type !== undefined && scale.type !== type)) {
|
|
14
|
+
throw new Error(
|
|
15
|
+
type === undefined
|
|
16
|
+
? `Unknown resolved scale "${id}".`
|
|
17
|
+
: `Expected resolved ${type} scale "${id}".`
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
return scale;
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const DEFAULT_FONT_FAMILY = "sans-serif";
|
|
2
|
+
|
|
3
|
+
export const DEFAULT_COLORS = Object.freeze({
|
|
4
|
+
mark: "#4c78a8",
|
|
5
|
+
text: "#334155",
|
|
6
|
+
strongText: "#0f172a",
|
|
7
|
+
mutedText: "#64748b",
|
|
8
|
+
grid: "#e2e8f0",
|
|
9
|
+
border: "#cbd5e1",
|
|
10
|
+
sizeSymbol: "#94a3b8",
|
|
11
|
+
regressionBand: "#111111",
|
|
12
|
+
highlight: "#dc2626"
|
|
13
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ActionOptions } from "./program.js";
|
|
2
|
+
import { ChartProgram } from "./program.js";
|
|
3
|
+
|
|
4
|
+
export { ChartProgram };
|
|
5
|
+
|
|
6
|
+
export interface ActionMetadata {
|
|
7
|
+
op: string;
|
|
8
|
+
description: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function action<TOptions extends ActionOptions = ActionOptions>(
|
|
12
|
+
metadata: ActionMetadata,
|
|
13
|
+
implementation: (this: ChartProgram, options: TOptions) => ChartProgram
|
|
14
|
+
): (this: ChartProgram, options?: TOptions) => ChartProgram;
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { ChartProgram } from "./program.js";
|
|
2
|
+
|
|
3
|
+
export type {
|
|
4
|
+
ActionOptions,
|
|
5
|
+
AxisFormat,
|
|
6
|
+
AxisFormatString,
|
|
7
|
+
AxisLabelOptions,
|
|
8
|
+
AxisLabelStyleOptions,
|
|
9
|
+
AxisLineStyleOptions,
|
|
10
|
+
AxisTickOptions,
|
|
11
|
+
AxisTicksAndLabelsOptions,
|
|
12
|
+
AxisTickStyleOptions,
|
|
13
|
+
AxisTitleOptions,
|
|
14
|
+
AxisValue,
|
|
15
|
+
BarWidthOptions,
|
|
16
|
+
CanvasOptions,
|
|
17
|
+
CategoricalEncodingOptions,
|
|
18
|
+
ColorLayout,
|
|
19
|
+
ColorEncodingOptions,
|
|
20
|
+
CompleteAxisOptions,
|
|
21
|
+
ChartProgram,
|
|
22
|
+
ConcretePathCommand,
|
|
23
|
+
CurveInterpolation,
|
|
24
|
+
CreateAxesOptions,
|
|
25
|
+
CreateGridOptions,
|
|
26
|
+
DashPattern,
|
|
27
|
+
DashScaleOptions,
|
|
28
|
+
DashStyle,
|
|
29
|
+
EditGraphicsOptions,
|
|
30
|
+
EditGridOptions,
|
|
31
|
+
EditScaleOptions,
|
|
32
|
+
EditSemanticOptions,
|
|
33
|
+
FieldType,
|
|
34
|
+
GraphicObject,
|
|
35
|
+
GraphicSpec,
|
|
36
|
+
GraphicType,
|
|
37
|
+
GridDirectionOptions,
|
|
38
|
+
HistogramEncodingOptions,
|
|
39
|
+
HighlightMarksOptions,
|
|
40
|
+
LegendOptions,
|
|
41
|
+
EditLegendOptions,
|
|
42
|
+
ContinuousColorInterpolation,
|
|
43
|
+
ContinuousColorScaleOptions,
|
|
44
|
+
OpacityEncodingOptions,
|
|
45
|
+
OpacityScaleOptions,
|
|
46
|
+
OffsetScaleOptions,
|
|
47
|
+
PointShape,
|
|
48
|
+
MarkSelector,
|
|
49
|
+
MarkGraphicProperty,
|
|
50
|
+
Palette,
|
|
51
|
+
PaletteName,
|
|
52
|
+
PositionEncodingOptions,
|
|
53
|
+
RulePositionEncodingOptions,
|
|
54
|
+
SecondaryPositionEncodingOptions,
|
|
55
|
+
RegressionBandOptions,
|
|
56
|
+
RegressionDataOptions,
|
|
57
|
+
RegressionInterval,
|
|
58
|
+
RegressionMethod,
|
|
59
|
+
RegressionOptions,
|
|
60
|
+
ScaleRange,
|
|
61
|
+
ScaleOptions,
|
|
62
|
+
ScaleType,
|
|
63
|
+
StackMode,
|
|
64
|
+
SemanticSpec,
|
|
65
|
+
SelectMarksOptions,
|
|
66
|
+
StrokeDashEncodingOptions,
|
|
67
|
+
TraceNode,
|
|
68
|
+
TitleOptions,
|
|
69
|
+
EditTitleOptions,
|
|
70
|
+
TitleTextStyleOptions,
|
|
71
|
+
XAxisPosition,
|
|
72
|
+
YAxisPosition,
|
|
73
|
+
XOffsetEncodingOptions
|
|
74
|
+
} from "./program.js";
|
|
75
|
+
|
|
76
|
+
export function chart(): ChartProgram;
|
|
77
|
+
export function render(
|
|
78
|
+
program: Pick<ChartProgram, "graphicSpec">,
|
|
79
|
+
context: CanvasRenderingContext2D,
|
|
80
|
+
options?: { pixelRatio?: number }
|
|
81
|
+
): void;
|
package/types/png.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ChartProgram } from "./program.js";
|
|
2
|
+
|
|
3
|
+
export interface PNGRenderResult {
|
|
4
|
+
readonly output: string;
|
|
5
|
+
readonly width: number;
|
|
6
|
+
readonly height: number;
|
|
7
|
+
readonly pixelRatio: number;
|
|
8
|
+
readonly bytes: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function renderToPNG(
|
|
12
|
+
program: Pick<ChartProgram, "graphicSpec">,
|
|
13
|
+
options: { output: string; pixelRatio?: number }
|
|
14
|
+
): Promise<PNGRenderResult>;
|