graphein 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1374 -3
- package/dist/index.js +12324 -6819
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -764,6 +764,269 @@ type FilterClause = {
|
|
|
764
764
|
param: string;
|
|
765
765
|
} | LiteralPredicate;
|
|
766
766
|
|
|
767
|
+
/**
|
|
768
|
+
* Declarative data transforms.
|
|
769
|
+
*
|
|
770
|
+
* A `transform` is an ordered pipeline that reshapes the `data` array *inside*
|
|
771
|
+
* the spec — so an agent fixes data shape by editing validatable JSON instead of
|
|
772
|
+
* pre-massaging rows in code. Every transform is plain JSON (no functions) and
|
|
773
|
+
* pure: `applyTransforms` never mutates its input.
|
|
774
|
+
*
|
|
775
|
+
* The pipeline is applied before the chart model is built (and before any
|
|
776
|
+
* cross-filter selection), so encodings can reference fields the transforms
|
|
777
|
+
* produce (e.g. an `aggregate` output column).
|
|
778
|
+
*/
|
|
779
|
+
|
|
780
|
+
/** One aggregation within an {@link AggregateTransform}. */
|
|
781
|
+
interface AggregateOp {
|
|
782
|
+
/** Aggregation operation. `count` needs no `field`. */
|
|
783
|
+
op: AggOp;
|
|
784
|
+
/** Source column to aggregate (omit only for `count`). */
|
|
785
|
+
field?: string;
|
|
786
|
+
/** Output column receiving the aggregated value. */
|
|
787
|
+
as: string;
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Group rows by `groupby` and summarize each group into a single output row.
|
|
791
|
+
* Omitting `groupby` collapses the whole dataset into one row.
|
|
792
|
+
*/
|
|
793
|
+
interface AggregateTransform {
|
|
794
|
+
aggregate: AggregateOp[];
|
|
795
|
+
groupby?: string[];
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* Bucket a quantitative `bin` field into evenly sized bins. Drives the histogram
|
|
799
|
+
* chart and any "distribution" view without pre-binning in user code.
|
|
800
|
+
*/
|
|
801
|
+
interface BinTransform {
|
|
802
|
+
/** Numeric column to bin. */
|
|
803
|
+
bin: string;
|
|
804
|
+
/**
|
|
805
|
+
* Output column(s). A single name receives the bin **start**; a `[start, end]`
|
|
806
|
+
* pair receives both edges (handy for histogram bars and range labels).
|
|
807
|
+
*/
|
|
808
|
+
as: string | [string, string];
|
|
809
|
+
/** Target bin count; a "nice" step approximates it. Default 10. */
|
|
810
|
+
maxbins?: number;
|
|
811
|
+
/** Explicit bin width. Overrides `maxbins` when set. */
|
|
812
|
+
step?: number;
|
|
813
|
+
/** Restrict binning to this `[min, max]`; values outside get a `null` bin. */
|
|
814
|
+
extent?: [number, number];
|
|
815
|
+
/** Snap the bin domain to round numbers (default true). */
|
|
816
|
+
nice?: boolean;
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* A declarative, JSON predicate for {@link FilterTransform}. Leaf predicates test
|
|
820
|
+
* one `field`; `and` / `or` / `not` compose them. Comparisons coerce numerically
|
|
821
|
+
* (numbers first, then dates), so temporal bounds work as ISO strings.
|
|
822
|
+
*/
|
|
823
|
+
type FilterPredicate = {
|
|
824
|
+
field: string;
|
|
825
|
+
equals: unknown;
|
|
826
|
+
} | {
|
|
827
|
+
field: string;
|
|
828
|
+
ne: unknown;
|
|
829
|
+
} | {
|
|
830
|
+
field: string;
|
|
831
|
+
oneOf: unknown[];
|
|
832
|
+
} | {
|
|
833
|
+
field: string;
|
|
834
|
+
range: [number | string, number | string];
|
|
835
|
+
} | {
|
|
836
|
+
field: string;
|
|
837
|
+
contains: string;
|
|
838
|
+
} | {
|
|
839
|
+
field: string;
|
|
840
|
+
gt: number | string;
|
|
841
|
+
} | {
|
|
842
|
+
field: string;
|
|
843
|
+
gte: number | string;
|
|
844
|
+
} | {
|
|
845
|
+
field: string;
|
|
846
|
+
lt: number | string;
|
|
847
|
+
} | {
|
|
848
|
+
field: string;
|
|
849
|
+
lte: number | string;
|
|
850
|
+
} | {
|
|
851
|
+
field: string;
|
|
852
|
+
valid: boolean;
|
|
853
|
+
} | {
|
|
854
|
+
and: FilterPredicate[];
|
|
855
|
+
} | {
|
|
856
|
+
or: FilterPredicate[];
|
|
857
|
+
} | {
|
|
858
|
+
not: FilterPredicate;
|
|
859
|
+
};
|
|
860
|
+
/** Keep only rows matching `filter`. */
|
|
861
|
+
interface FilterTransform {
|
|
862
|
+
filter: FilterPredicate;
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Gather several columns into key/value rows (wide → long). Each input row is
|
|
866
|
+
* repeated once per folded column. Use it to turn a wide table into a tidy one a
|
|
867
|
+
* `series` channel can split.
|
|
868
|
+
*/
|
|
869
|
+
interface FoldTransform {
|
|
870
|
+
fold: string[];
|
|
871
|
+
/** Output `[key, value]` column names. Default `['key', 'value']`. */
|
|
872
|
+
as?: [string, string];
|
|
873
|
+
}
|
|
874
|
+
/** Calendar unit a {@link TimeUnitTransform} truncates a timestamp to. */
|
|
875
|
+
type TimeUnit = 'year' | 'quarter' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second';
|
|
876
|
+
/**
|
|
877
|
+
* Truncate a temporal `field` to the start of a calendar unit (e.g. month),
|
|
878
|
+
* writing a `Date` to `as`. Lets agents aggregate by period without date math.
|
|
879
|
+
*/
|
|
880
|
+
interface TimeUnitTransform {
|
|
881
|
+
timeUnit: TimeUnit;
|
|
882
|
+
field: string;
|
|
883
|
+
as: string;
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Derive a new column from a **safe expression** evaluated per row, writing the
|
|
887
|
+
* result to `as`. The expression language supports arithmetic, comparison,
|
|
888
|
+
* logical and ternary operators, string concatenation, member access
|
|
889
|
+
* (`datum['my field']`), and a whitelist of functions (e.g. `round`, `lower`,
|
|
890
|
+
* `if`, `coalesce`). Bare identifiers reference row columns. It is parsed to an
|
|
891
|
+
* AST and evaluated with **no `eval`/`Function`** and no access to globals.
|
|
892
|
+
*/
|
|
893
|
+
interface CalculateTransform {
|
|
894
|
+
calculate: string;
|
|
895
|
+
as: string;
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* A single declarative transform step. Distinguished by its operator key
|
|
899
|
+
* (`aggregate` / `bin` / `filter` / `fold` / `timeUnit` / `calculate`); a step
|
|
900
|
+
* carries exactly one. Applied in array order by {@link applyTransforms}.
|
|
901
|
+
*/
|
|
902
|
+
type Transform = AggregateTransform | BinTransform | FilterTransform | FoldTransform | TimeUnitTransform | CalculateTransform;
|
|
903
|
+
/** Operator keys that identify a transform step (one per step). */
|
|
904
|
+
declare const TRANSFORM_KINDS: readonly ["aggregate", "bin", "filter", "fold", "timeUnit", "calculate"];
|
|
905
|
+
/** Supported {@link TimeUnit} values, for validation/UX. */
|
|
906
|
+
declare const TIME_UNITS: readonly TimeUnit[];
|
|
907
|
+
|
|
908
|
+
/** The transform pipeline: dispatch each step by its operator key, in order. */
|
|
909
|
+
|
|
910
|
+
/** Apply a single {@link Transform} step, returning a new array (never mutating). */
|
|
911
|
+
declare function applyTransform(transform: Transform, data: Datum[]): Datum[];
|
|
912
|
+
/**
|
|
913
|
+
* Apply a transform pipeline in array order. Pure — the input array and rows are
|
|
914
|
+
* never mutated. Returns the original reference unchanged when there are no
|
|
915
|
+
* transforms, so callers can cheaply detect a no-op.
|
|
916
|
+
*/
|
|
917
|
+
declare function applyTransforms(transforms: Transform[] | undefined, data: Datum[]): Datum[];
|
|
918
|
+
|
|
919
|
+
/** The `filter` transform: keep rows satisfying a declarative JSON predicate. */
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* Compile a {@link FilterPredicate} into a fast `row → boolean` tester, hoisting
|
|
923
|
+
* accessors and lookup sets out of the per-row path. An unrecognized leaf shape
|
|
924
|
+
* compiles to "match nothing" (validation flags it as an error first).
|
|
925
|
+
*/
|
|
926
|
+
declare function compilePredicate(pred: FilterPredicate): (row: Datum) => boolean;
|
|
927
|
+
/** Apply a {@link FilterTransform}, returning a new array of matching rows. */
|
|
928
|
+
declare function applyFilter(transform: FilterTransform, data: Datum[]): Datum[];
|
|
929
|
+
|
|
930
|
+
/** The `aggregate` transform: group rows and summarize each group into one row. */
|
|
931
|
+
|
|
932
|
+
/**
|
|
933
|
+
* Apply an {@link AggregateTransform}. Groups are emitted in first-seen order and
|
|
934
|
+
* keep the **original** group-key values (not stringified). With no `groupby`,
|
|
935
|
+
* the whole dataset collapses to a single summary row.
|
|
936
|
+
*/
|
|
937
|
+
declare function applyAggregate(transform: AggregateTransform, data: Datum[]): Datum[];
|
|
938
|
+
|
|
939
|
+
/** The `bin` transform: bucket a quantitative field into evenly sized bins. */
|
|
940
|
+
|
|
941
|
+
interface BinLayout {
|
|
942
|
+
/** Lower edge of the first bin. */
|
|
943
|
+
start: number;
|
|
944
|
+
/** Bin width. */
|
|
945
|
+
step: number;
|
|
946
|
+
/** Number of bins. */
|
|
947
|
+
count: number;
|
|
948
|
+
}
|
|
949
|
+
/**
|
|
950
|
+
* Choose a bin layout for `values`. Honors an explicit `step`, otherwise picks a
|
|
951
|
+
* "nice" step approximating `maxbins` (default 10). Returns `null` when there is
|
|
952
|
+
* no finite data to bin.
|
|
953
|
+
*/
|
|
954
|
+
declare function computeBins(values: readonly number[], opts?: {
|
|
955
|
+
maxbins?: number;
|
|
956
|
+
step?: number;
|
|
957
|
+
extent?: [number, number];
|
|
958
|
+
nice?: boolean;
|
|
959
|
+
}): BinLayout | null;
|
|
960
|
+
/**
|
|
961
|
+
* Apply a {@link BinTransform}, writing the bin start (and optional end) onto each
|
|
962
|
+
* row. Rows whose value is non-numeric or outside an explicit `extent` get `null`.
|
|
963
|
+
*/
|
|
964
|
+
declare function applyBin(transform: BinTransform, data: Datum[]): Datum[];
|
|
965
|
+
|
|
966
|
+
/** The `fold` transform: gather several columns into key/value rows (wide → long). */
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* Apply a {@link FoldTransform}. Each input row is repeated once per folded
|
|
970
|
+
* column, carrying all original fields plus the `[key, value]` pair (default
|
|
971
|
+
* names `key` / `value`).
|
|
972
|
+
*/
|
|
973
|
+
declare function applyFold(transform: FoldTransform, data: Datum[]): Datum[];
|
|
974
|
+
|
|
975
|
+
/** The `timeUnit` transform: truncate a timestamp to the start of a calendar unit. */
|
|
976
|
+
|
|
977
|
+
/** Truncate `date` to the start of `unit` (local time). */
|
|
978
|
+
declare function truncateTo(date: Date, unit: TimeUnit): Date;
|
|
979
|
+
/**
|
|
980
|
+
* Apply a {@link TimeUnitTransform}, writing a truncated `Date` to `as`. Rows whose
|
|
981
|
+
* field can't be parsed as a date receive `null`.
|
|
982
|
+
*/
|
|
983
|
+
declare function applyTimeUnit(transform: TimeUnitTransform, data: Datum[]): Datum[];
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* `calculate` transform: derive a new column from a safe expression evaluated
|
|
987
|
+
* per row. The expression is compiled once and never uses `eval`/`Function`.
|
|
988
|
+
*/
|
|
989
|
+
|
|
990
|
+
/** Apply a {@link CalculateTransform}, returning new rows with the `as` column. */
|
|
991
|
+
declare function applyCalculate(transform: CalculateTransform, data: Datum[]): Datum[];
|
|
992
|
+
|
|
993
|
+
/** Error thrown by the `calculate` expression tokenizer/parser/evaluator. */
|
|
994
|
+
declare class ExpressionError extends Error {
|
|
995
|
+
/** Source offset where the problem was detected, when known. */
|
|
996
|
+
readonly pos: number | undefined;
|
|
997
|
+
constructor(message: string, pos?: number);
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
/**
|
|
1001
|
+
* Evaluator for the `calculate` AST. Pure and sandboxed: the only callable names
|
|
1002
|
+
* are the {@link FUNCTIONS} whitelist, member access is guarded against prototype
|
|
1003
|
+
* keys, and there is no access to `eval`, `Function`, globals, or row mutation.
|
|
1004
|
+
* All functions are deterministic (no `now()`/`random()`), per the transform
|
|
1005
|
+
* determinism convention.
|
|
1006
|
+
*/
|
|
1007
|
+
|
|
1008
|
+
/** Names the parser may treat as callable — exposed for validation. */
|
|
1009
|
+
declare const FUNCTION_NAMES: readonly string[];
|
|
1010
|
+
|
|
1011
|
+
/**
|
|
1012
|
+
* Safe `calculate` expression engine — public surface.
|
|
1013
|
+
*
|
|
1014
|
+
* `compileExpression(src)` parses once and returns a pure `(row) => value`
|
|
1015
|
+
* function used by the calculate transform. No `eval`/`Function` is ever used;
|
|
1016
|
+
* see {@link evaluate} for the sandbox guarantees.
|
|
1017
|
+
*/
|
|
1018
|
+
|
|
1019
|
+
/** Parse `src` once; returns a reusable, pure evaluator over a row. */
|
|
1020
|
+
declare function compileExpression(src: string): (row: Datum) => unknown;
|
|
1021
|
+
/**
|
|
1022
|
+
* Validate an expression's syntax without evaluating it. Returns an error message
|
|
1023
|
+
* (and source offset) when the expression cannot be parsed, else `null`.
|
|
1024
|
+
*/
|
|
1025
|
+
declare function checkExpression(src: string): {
|
|
1026
|
+
message: string;
|
|
1027
|
+
pos: number | undefined;
|
|
1028
|
+
} | null;
|
|
1029
|
+
|
|
767
1030
|
/**
|
|
768
1031
|
* Graphein declarative chart specs.
|
|
769
1032
|
*
|
|
@@ -902,6 +1165,13 @@ interface SketchConfig {
|
|
|
902
1165
|
interface BaseSpec {
|
|
903
1166
|
/** Row-oriented (tidy) data. Required for all charts/tables. */
|
|
904
1167
|
data?: Datum[];
|
|
1168
|
+
/**
|
|
1169
|
+
* Declarative data transforms applied to `data` (in order) before the chart is
|
|
1170
|
+
* built — aggregate, bin, filter, fold, timeUnit. Reshape data *inside* the
|
|
1171
|
+
* spec instead of pre-massaging the array, so encodings can reference fields
|
|
1172
|
+
* the pipeline produces. Pure JSON; see {@link Transform}.
|
|
1173
|
+
*/
|
|
1174
|
+
transform?: Transform[];
|
|
905
1175
|
/** Theme name ('light' | 'dark') or a partial override object. */
|
|
906
1176
|
theme?: ThemeInput;
|
|
907
1177
|
dimensions?: Dimensions;
|
|
@@ -946,6 +1216,103 @@ interface BaseSpec {
|
|
|
946
1216
|
filter?: FilterClause[];
|
|
947
1217
|
}
|
|
948
1218
|
type CurveType = 'linear' | 'monotone' | 'step' | 'stepBefore' | 'stepAfter' | 'catmullRom';
|
|
1219
|
+
/**
|
|
1220
|
+
* A reference annotation overlaid on a cartesian chart: a single reference
|
|
1221
|
+
* **line** at a value, or a filled **band** / threshold **zone** between two
|
|
1222
|
+
* values. Useful for targets, goals, averages, control limits, and "danger"
|
|
1223
|
+
* ranges. Drawn over the gridlines and data marks; labels render in the overlay.
|
|
1224
|
+
*/
|
|
1225
|
+
interface Annotation {
|
|
1226
|
+
/**
|
|
1227
|
+
* What to draw. Omit to infer: a `line` when `value` is set, a `band` when
|
|
1228
|
+
* `from`/`to` are set. `zone` is a band — a semantic alias for a threshold band.
|
|
1229
|
+
* A `point` marks a single (`x`, `y`) data coordinate with a labeled dot.
|
|
1230
|
+
*/
|
|
1231
|
+
type?: 'line' | 'band' | 'zone' | 'point';
|
|
1232
|
+
/**
|
|
1233
|
+
* Which axis the value(s) are measured against. `y` (default) draws a
|
|
1234
|
+
* horizontal line / full-width band; `x` draws a vertical line / full-height band.
|
|
1235
|
+
*/
|
|
1236
|
+
axis?: 'x' | 'y';
|
|
1237
|
+
/** Reference value for a `line` (number, category, or date — matching the axis). */
|
|
1238
|
+
value?: number | string | Date;
|
|
1239
|
+
/** Start of the span for a `band`/`zone`. */
|
|
1240
|
+
from?: number | string | Date;
|
|
1241
|
+
/** End of the span for a `band`/`zone`. */
|
|
1242
|
+
to?: number | string | Date;
|
|
1243
|
+
/** X coordinate of a `point` callout (a data value on the x-axis). */
|
|
1244
|
+
x?: number | string | Date;
|
|
1245
|
+
/** Y coordinate of a `point` callout (a data value on the y-axis). */
|
|
1246
|
+
y?: number | string | Date;
|
|
1247
|
+
/** Marker radius in pixels for a `point` (default 3.5). */
|
|
1248
|
+
markerRadius?: number;
|
|
1249
|
+
/** Short text label drawn beside the annotation. */
|
|
1250
|
+
label?: string;
|
|
1251
|
+
/** Stroke (line) / fill (band) color. Defaults to a muted theme color. */
|
|
1252
|
+
color?: string;
|
|
1253
|
+
/** Line width in pixels for a `line` (default 1.5). */
|
|
1254
|
+
strokeWidth?: number;
|
|
1255
|
+
/** Dash pattern for the stroke; `[]` is solid. Lines/bands default to dashed. */
|
|
1256
|
+
strokeDash?: number[];
|
|
1257
|
+
/** Fill opacity for a `band`/`zone` (0..1, default 0.12). */
|
|
1258
|
+
fillOpacity?: number;
|
|
1259
|
+
/** Where the label anchors along the annotation (default `end`). */
|
|
1260
|
+
labelPosition?: 'start' | 'middle' | 'end';
|
|
1261
|
+
}
|
|
1262
|
+
/**
|
|
1263
|
+
* Which automatic data insights to mark on a cartesian plot. Enable via a
|
|
1264
|
+
* chart's `insights` field — `true` marks the max and min; an object opts into
|
|
1265
|
+
* specific callouts. The library derives the points and draws labeled markers,
|
|
1266
|
+
* so an agent never has to reason out (or hardcode) where the peak is.
|
|
1267
|
+
*/
|
|
1268
|
+
interface InsightOptions {
|
|
1269
|
+
/** Mark the maximum point (default true). */
|
|
1270
|
+
max?: boolean;
|
|
1271
|
+
/** Mark the minimum point (default true). */
|
|
1272
|
+
min?: boolean;
|
|
1273
|
+
/** Mark statistical outliers beyond the 1.5×IQR fences (default false). */
|
|
1274
|
+
outliers?: boolean;
|
|
1275
|
+
}
|
|
1276
|
+
/**
|
|
1277
|
+
* A derived **trendline** (line of best fit) overlaid on a cartesian plot.
|
|
1278
|
+
* Enable via a chart's `trendline` field — `true` fits a single linear
|
|
1279
|
+
* regression; an object configures the fit and its styling. The library
|
|
1280
|
+
* computes the regression from the plotted rows, so an agent never has to
|
|
1281
|
+
* derive slope/intercept coordinates by hand. Requires a continuous or temporal
|
|
1282
|
+
* x-axis (scatter, line, area) — it is meaningless on a categorical/band axis.
|
|
1283
|
+
*/
|
|
1284
|
+
interface TrendlineConfig {
|
|
1285
|
+
/** Fit method. Currently `'linear'` (ordinary least squares). */
|
|
1286
|
+
method?: 'linear';
|
|
1287
|
+
/**
|
|
1288
|
+
* Fit a separate line per color/series group. Defaults to `true` when the
|
|
1289
|
+
* chart splits into multiple series, `false` (one overall fit) otherwise.
|
|
1290
|
+
*/
|
|
1291
|
+
groupBy?: boolean;
|
|
1292
|
+
/** Draw an `R²=…` label at the end of each fitted line (default false). */
|
|
1293
|
+
label?: boolean;
|
|
1294
|
+
/** Line color. Defaults to the series color (grouped) or a muted ink. */
|
|
1295
|
+
color?: string;
|
|
1296
|
+
/** Line width in px (default 2). */
|
|
1297
|
+
strokeWidth?: number;
|
|
1298
|
+
/** Dash pattern; `[]` is solid (the default). */
|
|
1299
|
+
strokeDash?: number[];
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* **Faceting** (small multiples): split a chart into a trellis grid of panels,
|
|
1303
|
+
* one per distinct value of a field, all sharing identical x/y/color scales so
|
|
1304
|
+
* the panels are directly comparable. Enable via a chart's `facet` field — a
|
|
1305
|
+
* single field reference yields a whole comparison grid, which is why it is so
|
|
1306
|
+
* agent-friendly. Supported on `line`, `area`, `bar`, and `scatter`.
|
|
1307
|
+
*/
|
|
1308
|
+
interface FacetConfig {
|
|
1309
|
+
/** The field whose distinct values become one panel each. */
|
|
1310
|
+
field: string;
|
|
1311
|
+
/** Number of grid columns. Defaults to roughly √n, capped for readability. */
|
|
1312
|
+
columns?: number;
|
|
1313
|
+
/** Order the panels by their facet value (default `ascending`). */
|
|
1314
|
+
sort?: 'ascending' | 'descending' | 'none';
|
|
1315
|
+
}
|
|
949
1316
|
interface LineSpec extends BaseSpec {
|
|
950
1317
|
type: 'line';
|
|
951
1318
|
encoding: Encoding & {
|
|
@@ -957,6 +1324,14 @@ interface LineSpec extends BaseSpec {
|
|
|
957
1324
|
points?: boolean;
|
|
958
1325
|
/** Fill the area under the line. */
|
|
959
1326
|
area?: boolean;
|
|
1327
|
+
/** Reference lines, bands, and threshold zones overlaid on the plot. */
|
|
1328
|
+
annotations?: Annotation[];
|
|
1329
|
+
/** Auto-mark notable data points (`true` = max + min). See {@link InsightOptions}. */
|
|
1330
|
+
insights?: boolean | InsightOptions;
|
|
1331
|
+
/** Overlay a linear line of best fit. See {@link TrendlineConfig}. */
|
|
1332
|
+
trendline?: boolean | TrendlineConfig;
|
|
1333
|
+
/** Split into a trellis grid of small multiples. See {@link FacetConfig}. */
|
|
1334
|
+
facet?: FacetConfig;
|
|
960
1335
|
}
|
|
961
1336
|
interface AreaSpec extends BaseSpec {
|
|
962
1337
|
type: 'area';
|
|
@@ -967,6 +1342,14 @@ interface AreaSpec extends BaseSpec {
|
|
|
967
1342
|
curve?: CurveType;
|
|
968
1343
|
/** Stack multiple series. */
|
|
969
1344
|
stack?: boolean;
|
|
1345
|
+
/** Reference lines, bands, and threshold zones overlaid on the plot. */
|
|
1346
|
+
annotations?: Annotation[];
|
|
1347
|
+
/** Auto-mark notable data points (`true` = max + min). See {@link InsightOptions}. */
|
|
1348
|
+
insights?: boolean | InsightOptions;
|
|
1349
|
+
/** Overlay a linear line of best fit. See {@link TrendlineConfig}. */
|
|
1350
|
+
trendline?: boolean | TrendlineConfig;
|
|
1351
|
+
/** Split into a trellis grid of small multiples. See {@link FacetConfig}. */
|
|
1352
|
+
facet?: FacetConfig;
|
|
970
1353
|
}
|
|
971
1354
|
interface BarSpec extends BaseSpec {
|
|
972
1355
|
type: 'bar';
|
|
@@ -980,6 +1363,12 @@ interface BarSpec extends BaseSpec {
|
|
|
980
1363
|
/** Group series side-by-side (default when `series` present and not stacked). */
|
|
981
1364
|
group?: boolean;
|
|
982
1365
|
cornerRadius?: number;
|
|
1366
|
+
/** Reference lines, bands, and threshold zones overlaid on the plot. */
|
|
1367
|
+
annotations?: Annotation[];
|
|
1368
|
+
/** Auto-mark notable data points (`true` = top + bottom category). See {@link InsightOptions}. */
|
|
1369
|
+
insights?: boolean | InsightOptions;
|
|
1370
|
+
/** Split into a trellis grid of small multiples. See {@link FacetConfig}. */
|
|
1371
|
+
facet?: FacetConfig;
|
|
983
1372
|
}
|
|
984
1373
|
interface ScatterSpec extends BaseSpec {
|
|
985
1374
|
type: 'scatter';
|
|
@@ -987,6 +1376,87 @@ interface ScatterSpec extends BaseSpec {
|
|
|
987
1376
|
x: FieldDef;
|
|
988
1377
|
y: FieldDef;
|
|
989
1378
|
};
|
|
1379
|
+
/** Reference lines, bands, and threshold zones overlaid on the plot. */
|
|
1380
|
+
annotations?: Annotation[];
|
|
1381
|
+
/** Overlay a linear line of best fit. See {@link TrendlineConfig}. */
|
|
1382
|
+
trendline?: boolean | TrendlineConfig;
|
|
1383
|
+
/** Split into a trellis grid of small multiples. See {@link FacetConfig}. */
|
|
1384
|
+
facet?: FacetConfig;
|
|
1385
|
+
}
|
|
1386
|
+
/** The mark a single combo layer draws. */
|
|
1387
|
+
type ComboMark = 'line' | 'bar' | 'area' | 'scatter';
|
|
1388
|
+
/**
|
|
1389
|
+
* One layer of a {@link ComboSpec}: a mark plus the measure it plots on `y`. All
|
|
1390
|
+
* layers share the combo's `x`. A layer can be measured against the primary
|
|
1391
|
+
* (`left`) y-axis or an independent secondary (`right`) axis — the basis of a
|
|
1392
|
+
* dual-axis bar+line chart.
|
|
1393
|
+
*/
|
|
1394
|
+
interface ComboLayer {
|
|
1395
|
+
/** Which mark to draw for this layer. */
|
|
1396
|
+
mark: ComboMark;
|
|
1397
|
+
/** The measure (and optional per-layer formatting) plotted on `y`. */
|
|
1398
|
+
encoding: {
|
|
1399
|
+
y: FieldDef;
|
|
1400
|
+
};
|
|
1401
|
+
/** Which y-axis this layer is measured against. Defaults to `left`. */
|
|
1402
|
+
axis?: 'left' | 'right';
|
|
1403
|
+
/** Curve interpolation for `line`/`area` layers. */
|
|
1404
|
+
curve?: CurveType;
|
|
1405
|
+
/** Show point markers (line/area layers). */
|
|
1406
|
+
points?: boolean;
|
|
1407
|
+
/** Fill under the line (line layers — equivalent to an `area` mark). */
|
|
1408
|
+
area?: boolean;
|
|
1409
|
+
/** Bar corner radius (bar layers). */
|
|
1410
|
+
cornerRadius?: number;
|
|
1411
|
+
/** Legend label for the layer. Defaults to the y field's title or name. */
|
|
1412
|
+
name?: string;
|
|
1413
|
+
/** Override the layer's color (otherwise drawn from the theme palette). */
|
|
1414
|
+
color?: string;
|
|
1415
|
+
}
|
|
1416
|
+
/**
|
|
1417
|
+
* Combo / dual-axis chart: composes multiple cartesian {@link ComboLayer}s over a
|
|
1418
|
+
* shared `x` axis — the canonical BI "bar + line" view. Layers may target a primary
|
|
1419
|
+
* (`left`) or secondary (`right`) y-axis, each with its own independent scale.
|
|
1420
|
+
* Bars require a categorical `x`; lines/areas/points align to category centers.
|
|
1421
|
+
*/
|
|
1422
|
+
interface ComboSpec extends BaseSpec {
|
|
1423
|
+
type: 'combo';
|
|
1424
|
+
encoding: {
|
|
1425
|
+
x: FieldDef;
|
|
1426
|
+
};
|
|
1427
|
+
layers: ComboLayer[];
|
|
1428
|
+
}
|
|
1429
|
+
/** Binning controls for a {@link HistogramSpec} (mirror the `bin` transform). */
|
|
1430
|
+
interface HistogramBin {
|
|
1431
|
+
/** Target bin count (approximate — a "nice" step is chosen). Default 10. */
|
|
1432
|
+
maxbins?: number;
|
|
1433
|
+
/** Explicit bin width (overrides `maxbins`). */
|
|
1434
|
+
step?: number;
|
|
1435
|
+
/** Restrict binning to `[min, max]`; values outside are dropped. */
|
|
1436
|
+
extent?: [number, number];
|
|
1437
|
+
/** Snap bin edges to nice round numbers (default true). */
|
|
1438
|
+
nice?: boolean;
|
|
1439
|
+
}
|
|
1440
|
+
/**
|
|
1441
|
+
* Histogram: bins a single quantitative field and draws the per-bin frequency as
|
|
1442
|
+
* gapless bars. Binning happens inside the chart (reusing the `bin` transform), so
|
|
1443
|
+
* an agent passes raw observations — no manual pre-binning. Bar height is the bin
|
|
1444
|
+
* count by default, or a probability density (area sums to 1) when `density:true`.
|
|
1445
|
+
*/
|
|
1446
|
+
interface HistogramSpec extends BaseSpec {
|
|
1447
|
+
type: 'histogram';
|
|
1448
|
+
/** `x` is the quantitative field to bin (also carries the axis title/format). */
|
|
1449
|
+
encoding: {
|
|
1450
|
+
x: FieldDef;
|
|
1451
|
+
};
|
|
1452
|
+
/** Binning controls (default ~10 nice bins, or an explicit `step`/`extent`). */
|
|
1453
|
+
bin?: HistogramBin;
|
|
1454
|
+
/** Normalize bar heights to a probability density (area sums to 1). */
|
|
1455
|
+
density?: boolean;
|
|
1456
|
+
/** Bar colour (defaults to the first theme palette colour). */
|
|
1457
|
+
color?: string;
|
|
1458
|
+
/** Bar corner radius. */
|
|
1459
|
+
cornerRadius?: number;
|
|
990
1460
|
}
|
|
991
1461
|
interface PieSpec extends BaseSpec {
|
|
992
1462
|
type: 'pie';
|
|
@@ -1073,6 +1543,173 @@ interface KpiSpec extends BaseSpec {
|
|
|
1073
1543
|
field: string;
|
|
1074
1544
|
};
|
|
1075
1545
|
}
|
|
1546
|
+
/**
|
|
1547
|
+
* Treemap — part-to-whole as nested rectangles sized by a measure. Pass tidy
|
|
1548
|
+
* rows (one per leaf); the area of each tile is proportional to `value`. An
|
|
1549
|
+
* optional `group` field nests leaves under parent tiles (one level), and
|
|
1550
|
+
* `color` overrides the default per-group/leaf fill (numeric → sequential scale,
|
|
1551
|
+
* categorical → palette).
|
|
1552
|
+
*/
|
|
1553
|
+
interface TreemapSpec extends BaseSpec {
|
|
1554
|
+
type: 'treemap';
|
|
1555
|
+
encoding: Encoding & {
|
|
1556
|
+
/** Leaf tile label + identity. */
|
|
1557
|
+
category: FieldDef;
|
|
1558
|
+
/** Numeric field sizing each tile's area (summed per leaf). */
|
|
1559
|
+
value: FieldDef;
|
|
1560
|
+
/** Optional parent grouping → nested parent tiles (one level deep). */
|
|
1561
|
+
group?: FieldDef;
|
|
1562
|
+
/** Optional field driving tile color (numeric → sequential, else palette). */
|
|
1563
|
+
color?: FieldDef;
|
|
1564
|
+
};
|
|
1565
|
+
/** Sequential color scheme name when `color` is numeric (default 'teal'). */
|
|
1566
|
+
scheme?: string;
|
|
1567
|
+
/** Show the value beneath the label inside each tile (default true). */
|
|
1568
|
+
labels?: boolean;
|
|
1569
|
+
}
|
|
1570
|
+
/**
|
|
1571
|
+
* Gauge — a radial dial showing a single value against a `[min, max]` scale,
|
|
1572
|
+
* with an optional `target` needle and qualitative background `bands`. The
|
|
1573
|
+
* value is a literal or a field (optionally aggregated, like {@link KpiSpec}).
|
|
1574
|
+
*/
|
|
1575
|
+
interface GaugeSpec extends BaseSpec {
|
|
1576
|
+
type: 'gauge';
|
|
1577
|
+
/** The measured value (literal or a field, optionally aggregated over data). */
|
|
1578
|
+
value: ValueRef;
|
|
1579
|
+
/** Scale start (default 0). */
|
|
1580
|
+
min?: number;
|
|
1581
|
+
/** Scale end — the gauge's full-scale (required). */
|
|
1582
|
+
max: number;
|
|
1583
|
+
/** Optional target/threshold marker drawn as a needle/tick. */
|
|
1584
|
+
target?: ValueRef;
|
|
1585
|
+
/** Caption under the value (defaults to the spec title or value field). */
|
|
1586
|
+
label?: string;
|
|
1587
|
+
/** Number format for the value + scale ticks (e.g. ',.0f', '.0%'). */
|
|
1588
|
+
format?: string;
|
|
1589
|
+
/** Qualitative arc bands, each filling the scale up to `to`. */
|
|
1590
|
+
bands?: {
|
|
1591
|
+
to: number;
|
|
1592
|
+
color?: string;
|
|
1593
|
+
}[];
|
|
1594
|
+
}
|
|
1595
|
+
/**
|
|
1596
|
+
* Bullet graph — a compact linear KPI-vs-target: a measure bar over qualitative
|
|
1597
|
+
* `ranges` (poor/ok/good background bands) with a `target` comparative marker.
|
|
1598
|
+
* The featured value/target are literals or fields (optionally aggregated).
|
|
1599
|
+
*/
|
|
1600
|
+
interface BulletSpec extends BaseSpec {
|
|
1601
|
+
type: 'bullet';
|
|
1602
|
+
/** The featured measure (literal or a field, optionally aggregated). */
|
|
1603
|
+
value: ValueRef;
|
|
1604
|
+
/** Target/comparative marker (literal or field) drawn as a vertical tick. */
|
|
1605
|
+
target?: ValueRef;
|
|
1606
|
+
/** Scale start (default 0). */
|
|
1607
|
+
min?: number;
|
|
1608
|
+
/** Scale end (default: derived from value/target/ranges). */
|
|
1609
|
+
max?: number;
|
|
1610
|
+
/** Qualitative range boundaries on the scale (e.g. [50, 75, 100]). */
|
|
1611
|
+
ranges?: number[];
|
|
1612
|
+
/** Caption to the left of the bar (defaults to the spec title or value field). */
|
|
1613
|
+
label?: string;
|
|
1614
|
+
/** Number format for the value + axis ticks. */
|
|
1615
|
+
format?: string;
|
|
1616
|
+
}
|
|
1617
|
+
/**
|
|
1618
|
+
* Calendar heatmap — a GitHub-contributions-style grid of one cell per day,
|
|
1619
|
+
* colored by a value via a sequential scale, with weekday rows and month
|
|
1620
|
+
* labels. Pass tidy rows of `{ date, value }`; dates may be `Date` objects or
|
|
1621
|
+
* ISO strings.
|
|
1622
|
+
*/
|
|
1623
|
+
interface CalendarHeatmapSpec extends BaseSpec {
|
|
1624
|
+
type: 'calendarHeatmap';
|
|
1625
|
+
encoding: Encoding & {
|
|
1626
|
+
/** Date field (Date or ISO string) → one cell per day. */
|
|
1627
|
+
date: FieldDef;
|
|
1628
|
+
/** Numeric value field → cell color via a sequential scale. */
|
|
1629
|
+
color: FieldDef;
|
|
1630
|
+
};
|
|
1631
|
+
/** Sequential color scheme name for the value scale (default 'teal'). */
|
|
1632
|
+
scheme?: string;
|
|
1633
|
+
}
|
|
1634
|
+
/**
|
|
1635
|
+
* Waterfall — a column chart of signed steps where each bar floats from the
|
|
1636
|
+
* running total to its new level, showing how sequential increases and decreases
|
|
1637
|
+
* build to a final value. Each `value` is the **signed change** at that stage
|
|
1638
|
+
* (positive rises, negative falls). Stages named in `totals` (and an optional
|
|
1639
|
+
* appended grand total) draw as absolute bars from the baseline. Increases,
|
|
1640
|
+
* decreases, and totals are colored distinctly and joined by connector lines.
|
|
1641
|
+
*/
|
|
1642
|
+
interface WaterfallSpec extends BaseSpec {
|
|
1643
|
+
type: 'waterfall';
|
|
1644
|
+
encoding: Encoding & {
|
|
1645
|
+
/** Stage label along the x-axis (one bar per row, in data order). */
|
|
1646
|
+
stage: FieldDef;
|
|
1647
|
+
/** Signed change at each stage (positive rises, negative falls). */
|
|
1648
|
+
value: FieldDef;
|
|
1649
|
+
};
|
|
1650
|
+
/** Stage labels to draw as absolute running-total bars from the baseline. */
|
|
1651
|
+
totals?: string[];
|
|
1652
|
+
/** Append a final bar summing every step (default false). */
|
|
1653
|
+
showTotal?: boolean;
|
|
1654
|
+
/** Label for the appended total bar (default 'Total'). */
|
|
1655
|
+
totalLabel?: string;
|
|
1656
|
+
/** Show the per-bar value labels (default true). */
|
|
1657
|
+
labels?: boolean;
|
|
1658
|
+
/** Bar corner radius in pixels (default 2). */
|
|
1659
|
+
cornerRadius?: number;
|
|
1660
|
+
/** Color for upward steps (default theme positive/green). */
|
|
1661
|
+
increaseColor?: string;
|
|
1662
|
+
/** Color for downward steps (default theme negative/red). */
|
|
1663
|
+
decreaseColor?: string;
|
|
1664
|
+
/** Color for total/subtotal bars (default theme accent). */
|
|
1665
|
+
totalColor?: string;
|
|
1666
|
+
}
|
|
1667
|
+
/**
|
|
1668
|
+
* Slope graph — a minimal "before/after" chart: each `series` is a line joining
|
|
1669
|
+
* its `y` value across two (or a few) ordinal `x` positions, with direct end
|
|
1670
|
+
* labels instead of a legend. Reads change-in-rank and rise/fall at a glance.
|
|
1671
|
+
* Pass tidy rows of `{ x, y, series }` (one row per series per x position).
|
|
1672
|
+
*/
|
|
1673
|
+
interface SlopeSpec extends BaseSpec {
|
|
1674
|
+
type: 'slope';
|
|
1675
|
+
encoding: Encoding & {
|
|
1676
|
+
/** The ordinal positions along the x-axis (typically two: e.g. start/end). */
|
|
1677
|
+
x: FieldDef;
|
|
1678
|
+
/** Numeric value plotted on the y-axis. */
|
|
1679
|
+
y: FieldDef;
|
|
1680
|
+
/** One line per series (the entity whose change is traced). */
|
|
1681
|
+
series: FieldDef;
|
|
1682
|
+
};
|
|
1683
|
+
/** Direct labels (series name + value) at each line's ends (default true). */
|
|
1684
|
+
labels?: boolean;
|
|
1685
|
+
/** Color each line green/red by its net rise/fall instead of by series. */
|
|
1686
|
+
colorByChange?: boolean;
|
|
1687
|
+
/** Number format for value labels and the y-axis. */
|
|
1688
|
+
format?: string;
|
|
1689
|
+
}
|
|
1690
|
+
/**
|
|
1691
|
+
* Dumbbell / connected dot plot — for each `category`, a dot per `group` placed
|
|
1692
|
+
* on a shared horizontal value axis and joined by a connector, so the gap between
|
|
1693
|
+
* groups (e.g. before vs. after, male vs. female) reads directly. Categories run
|
|
1694
|
+
* down the y-axis. Pass tidy rows of `{ category, value, group }`.
|
|
1695
|
+
*/
|
|
1696
|
+
interface DumbbellSpec extends BaseSpec {
|
|
1697
|
+
type: 'dumbbell';
|
|
1698
|
+
encoding: Encoding & {
|
|
1699
|
+
/** The category for each row (one band down the y-axis). */
|
|
1700
|
+
category: FieldDef;
|
|
1701
|
+
/** Numeric value → dot position on the horizontal axis. */
|
|
1702
|
+
value: FieldDef;
|
|
1703
|
+
/** The group each dot belongs to (2+ levels → one dot each, connected). */
|
|
1704
|
+
group: FieldDef;
|
|
1705
|
+
};
|
|
1706
|
+
/** Value labels beside the dots (default false). */
|
|
1707
|
+
labels?: boolean;
|
|
1708
|
+
/** Number format for value labels and the x-axis. */
|
|
1709
|
+
format?: string;
|
|
1710
|
+
/** Order the category rows (default: data order). `gap` sorts by dot spread. */
|
|
1711
|
+
sort?: 'ascending' | 'descending' | 'gap';
|
|
1712
|
+
}
|
|
1076
1713
|
type ConditionalFormat = {
|
|
1077
1714
|
type: 'colorScale';
|
|
1078
1715
|
scheme?: string;
|
|
@@ -1193,6 +1830,8 @@ interface BoxSpec extends BaseSpec {
|
|
|
1193
1830
|
whisker?: 'tukey' | 'minMax';
|
|
1194
1831
|
/** Draw outlier points beyond the whiskers (tukey only; default true). */
|
|
1195
1832
|
outliers?: boolean;
|
|
1833
|
+
/** Reference lines, bands, and threshold zones overlaid on the plot. */
|
|
1834
|
+
annotations?: Annotation[];
|
|
1196
1835
|
}
|
|
1197
1836
|
interface SankeySpec extends BaseSpec {
|
|
1198
1837
|
type: 'sankey';
|
|
@@ -1335,7 +1974,7 @@ interface DateRangeSlicerSpec extends BaseSlicerSpec {
|
|
|
1335
1974
|
type SlicerSpec = DropdownSlicerSpec | SearchSlicerSpec | ListSlicerSpec | RangeSlicerSpec | DateRangeSlicerSpec;
|
|
1336
1975
|
type SlicerType = SlicerSpec['type'];
|
|
1337
1976
|
declare const SLICER_TYPES: readonly SlicerType[];
|
|
1338
|
-
type ChartSpec = LineSpec | AreaSpec | BarSpec | ScatterSpec | PieSpec | HeatmapSpec | FunnelSpec | KpiSpec | TableSpec | MatrixSpec | BoxSpec | SankeySpec | ChoroplethSpec | DropdownSlicerSpec | SearchSlicerSpec | ListSlicerSpec | RangeSlicerSpec | DateRangeSlicerSpec;
|
|
1977
|
+
type ChartSpec = LineSpec | AreaSpec | BarSpec | ScatterSpec | ComboSpec | HistogramSpec | PieSpec | HeatmapSpec | FunnelSpec | KpiSpec | TreemapSpec | GaugeSpec | BulletSpec | CalendarHeatmapSpec | WaterfallSpec | SlopeSpec | DumbbellSpec | TableSpec | MatrixSpec | BoxSpec | SankeySpec | ChoroplethSpec | DropdownSlicerSpec | SearchSlicerSpec | ListSlicerSpec | RangeSlicerSpec | DateRangeSlicerSpec;
|
|
1339
1978
|
type ChartType = ChartSpec['type'];
|
|
1340
1979
|
declare const CHART_TYPES: readonly ChartType[];
|
|
1341
1980
|
|
|
@@ -1486,6 +2125,13 @@ declare class Surface {
|
|
|
1486
2125
|
width: number;
|
|
1487
2126
|
height: number;
|
|
1488
2127
|
dpr: number;
|
|
2128
|
+
/**
|
|
2129
|
+
* When true, overlay text (axis labels, titles, legends, annotation labels) is
|
|
2130
|
+
* painted onto the `marks` canvas instead of the HTML overlay. Set by headless
|
|
2131
|
+
* renderers (`@graphein/node`) where there is no DOM to host crisp text.
|
|
2132
|
+
* Defaults to false (browser).
|
|
2133
|
+
*/
|
|
2134
|
+
headless: boolean;
|
|
1489
2135
|
constructor(container: HTMLElement);
|
|
1490
2136
|
resize(width: number, height: number, dpr?: number): void;
|
|
1491
2137
|
/** Clear both canvas layers and empty the HTML overlay. */
|
|
@@ -1503,6 +2149,211 @@ declare class Surface {
|
|
|
1503
2149
|
|
|
1504
2150
|
declare function applyA11y(surface: Surface, spec: ChartSpec): void;
|
|
1505
2151
|
|
|
2152
|
+
/**
|
|
2153
|
+
* Data insight analysis — the pure analytical core behind self-explaining charts.
|
|
2154
|
+
*
|
|
2155
|
+
* Given a {@link ChartSpec} (spec + its `data`), {@link analyzeChart} derives a
|
|
2156
|
+
* structured, dependency-free set of facts about what the numbers *say*: the
|
|
2157
|
+
* trend and net change of a series, the largest/smallest category and its share,
|
|
2158
|
+
* outliers, scatter correlation, a value vs. its target. Two consumers build on
|
|
2159
|
+
* it without re-deriving anything:
|
|
2160
|
+
* - {@link summarize} turns insights into a deterministic plain-English summary
|
|
2161
|
+
* (doubles as alt-text — no LLM).
|
|
2162
|
+
* - auto-insight annotations turn the same `PointRef`s into on-chart callouts.
|
|
2163
|
+
*
|
|
2164
|
+
* The analysis is a pure function of the spec; it reads rows as-is (charts plot
|
|
2165
|
+
* rows in data order, so first/last reflect data order) and never mutates input.
|
|
2166
|
+
*/
|
|
2167
|
+
|
|
2168
|
+
/** A single salient point in a series: its value, its x-label, and row index. */
|
|
2169
|
+
interface PointRef {
|
|
2170
|
+
/** The x-axis label for this point (formatted as a string). */
|
|
2171
|
+
label: string;
|
|
2172
|
+
/** The numeric value at this point. */
|
|
2173
|
+
value: number;
|
|
2174
|
+
/** Index of the originating row within its series. */
|
|
2175
|
+
index: number;
|
|
2176
|
+
/**
|
|
2177
|
+
* The raw x-axis domain value (a `Date`, string, or number) for this point,
|
|
2178
|
+
* suitable for mapping back to a pixel via a chart's x-scale. Undefined when
|
|
2179
|
+
* the analysis had no x channel (e.g. a raw distribution).
|
|
2180
|
+
*/
|
|
2181
|
+
raw?: unknown;
|
|
2182
|
+
}
|
|
2183
|
+
/** Trend + spread facts for one ordered numeric series. */
|
|
2184
|
+
interface SeriesInsights {
|
|
2185
|
+
/** Series name (`''` for a single, unsplit series). */
|
|
2186
|
+
key: string;
|
|
2187
|
+
/** Number of points. */
|
|
2188
|
+
count: number;
|
|
2189
|
+
first: PointRef;
|
|
2190
|
+
last: PointRef;
|
|
2191
|
+
min: PointRef;
|
|
2192
|
+
max: PointRef;
|
|
2193
|
+
/** Arithmetic mean of the values. */
|
|
2194
|
+
mean: number;
|
|
2195
|
+
/** Sum of the values. */
|
|
2196
|
+
sum: number;
|
|
2197
|
+
/** `last - first`. */
|
|
2198
|
+
netChange: number;
|
|
2199
|
+
/** `(last - first) / |first|`, or `null` when `first` is 0. */
|
|
2200
|
+
pctChange: number | null;
|
|
2201
|
+
/** Overall direction of travel from first to last. */
|
|
2202
|
+
direction: 'up' | 'down' | 'flat';
|
|
2203
|
+
/** The largest single step between consecutive points (by absolute delta). */
|
|
2204
|
+
biggestJump: {
|
|
2205
|
+
from: PointRef;
|
|
2206
|
+
to: PointRef;
|
|
2207
|
+
delta: number;
|
|
2208
|
+
} | null;
|
|
2209
|
+
/** Points beyond the 1.5×IQR Tukey fences (empty when none). */
|
|
2210
|
+
outliers: PointRef[];
|
|
2211
|
+
}
|
|
2212
|
+
/** Part-to-whole facts for a categorical measure. */
|
|
2213
|
+
interface CategoryInsights {
|
|
2214
|
+
/** Number of categories. */
|
|
2215
|
+
count: number;
|
|
2216
|
+
/** Sum of the measure across all categories. */
|
|
2217
|
+
total: number;
|
|
2218
|
+
/** The largest category. */
|
|
2219
|
+
top: PointRef;
|
|
2220
|
+
/** The smallest category. */
|
|
2221
|
+
bottom: PointRef;
|
|
2222
|
+
/** `top.value / total` (0..1), or 0 when the total is not positive. */
|
|
2223
|
+
topShare: number;
|
|
2224
|
+
}
|
|
2225
|
+
/** Relationship facts for an x/y point cloud. */
|
|
2226
|
+
interface ScatterInsights {
|
|
2227
|
+
count: number;
|
|
2228
|
+
xExtent: [number, number];
|
|
2229
|
+
yExtent: [number, number];
|
|
2230
|
+
/** Pearson correlation coefficient (−1..1), or `null` when undefined. */
|
|
2231
|
+
correlation: number | null;
|
|
2232
|
+
}
|
|
2233
|
+
/** A single value measured against an optional target. */
|
|
2234
|
+
interface ValueInsights {
|
|
2235
|
+
value: number;
|
|
2236
|
+
target: number | null;
|
|
2237
|
+
/** `value - target`, or `null` when there is no target. */
|
|
2238
|
+
toTarget: number | null;
|
|
2239
|
+
/** `value / target`, or `null` when there is no (non-zero) target. */
|
|
2240
|
+
pctOfTarget: number | null;
|
|
2241
|
+
}
|
|
2242
|
+
type InsightFamily = 'series' | 'category' | 'scatter' | 'value' | 'distribution';
|
|
2243
|
+
/** The structured insight payload for a chart (see {@link analyzeChart}). */
|
|
2244
|
+
interface ChartInsights {
|
|
2245
|
+
type: ChartType;
|
|
2246
|
+
family: InsightFamily;
|
|
2247
|
+
/** Rows backing the chart. */
|
|
2248
|
+
rowCount: number;
|
|
2249
|
+
/** The measure field name (y / value / theta), when there is one. */
|
|
2250
|
+
measureField?: string;
|
|
2251
|
+
/** The measure's number-format hint (for downstream formatting). */
|
|
2252
|
+
measureFormat?: string;
|
|
2253
|
+
/** Display title for the measure (field title or field name). */
|
|
2254
|
+
measureLabel?: string;
|
|
2255
|
+
/** The category / x field name, when there is one. */
|
|
2256
|
+
categoryField?: string;
|
|
2257
|
+
/** Inferred type of the x / category field. */
|
|
2258
|
+
categoryType?: FieldType;
|
|
2259
|
+
/** Per-series trend facts (family `series`). */
|
|
2260
|
+
series?: SeriesInsights[];
|
|
2261
|
+
/** Highest-ending series (multi-series only). */
|
|
2262
|
+
leader?: {
|
|
2263
|
+
key: string;
|
|
2264
|
+
value: number;
|
|
2265
|
+
};
|
|
2266
|
+
/** The series that moved most from first→last (multi-series only). */
|
|
2267
|
+
biggestMover?: {
|
|
2268
|
+
key: string;
|
|
2269
|
+
delta: number;
|
|
2270
|
+
};
|
|
2271
|
+
/** Part-to-whole facts (family `category`). */
|
|
2272
|
+
category?: CategoryInsights;
|
|
2273
|
+
/** Point-cloud facts (family `scatter`). */
|
|
2274
|
+
scatter?: ScatterInsights;
|
|
2275
|
+
/** Single value vs. target (family `value`). */
|
|
2276
|
+
value?: ValueInsights;
|
|
2277
|
+
/** Distribution of one measure (family `distribution`, e.g. histogram). */
|
|
2278
|
+
distribution?: SeriesInsights;
|
|
2279
|
+
}
|
|
2280
|
+
/**
|
|
2281
|
+
* Compute trend + spread insights for a parallel `values`/`labels` series.
|
|
2282
|
+
* Returns `null` when there are no finite values.
|
|
2283
|
+
*/
|
|
2284
|
+
declare function computeSeriesInsights(values: readonly number[], labels: readonly string[], key?: string, raws?: readonly unknown[]): SeriesInsights | null;
|
|
2285
|
+
/**
|
|
2286
|
+
* Derive structured insights from a chart spec, or `null` when the chart type
|
|
2287
|
+
* carries no summarizable trend (e.g. table, matrix, sankey, maps).
|
|
2288
|
+
*/
|
|
2289
|
+
declare function analyzeChart(spec: ChartSpec): ChartInsights | null;
|
|
2290
|
+
|
|
2291
|
+
/**
|
|
2292
|
+
* Deterministic natural-language chart summaries — the chart explains itself.
|
|
2293
|
+
*
|
|
2294
|
+
* {@link summarize} turns the structured facts from {@link analyzeChart} into one
|
|
2295
|
+
* or two plain-English sentences ("Users rose 46% from 4,200 to 6,150…"). It is
|
|
2296
|
+
* a pure, LLM-free function of the spec, so the same string is reproducible in a
|
|
2297
|
+
* report, an email, or — crucially — as the alt-text behind a canvas chart.
|
|
2298
|
+
*
|
|
2299
|
+
* Returns `''` for chart types that carry no summarizable trend (tables, maps,
|
|
2300
|
+
* sankey), so callers can treat an empty string as "nothing worth narrating".
|
|
2301
|
+
*/
|
|
2302
|
+
|
|
2303
|
+
/**
|
|
2304
|
+
* Build a deterministic, plain-English summary of what a chart's data shows.
|
|
2305
|
+
* Doubles as alt-text. Returns `''` when the chart type isn't summarizable.
|
|
2306
|
+
*/
|
|
2307
|
+
declare function summarize(spec: ChartSpec): string;
|
|
2308
|
+
|
|
2309
|
+
/**
|
|
2310
|
+
* Auto-insight annotations — turn a chart's {@link analyzeChart} facts into
|
|
2311
|
+
* on-chart callouts. A cartesian chart opts in with `insights: true` (or an
|
|
2312
|
+
* {@link InsightOptions} object); the library finds the notable points (the peak,
|
|
2313
|
+
* the trough, statistical outliers, or the top/bottom category) and emits labeled
|
|
2314
|
+
* `point` {@link Annotation}s — so an agent never has to reason out *where* the
|
|
2315
|
+
* maximum is or hardcode its coordinates.
|
|
2316
|
+
*
|
|
2317
|
+
* Pure and deterministic: a function of the spec + its data, reusing the same
|
|
2318
|
+
* analytical core as {@link summarize}. Multi-series charts are skipped (markers
|
|
2319
|
+
* on every series would clutter the plot); use `insights` on a single series.
|
|
2320
|
+
*/
|
|
2321
|
+
|
|
2322
|
+
/** Normalize the `insights` field to concrete flags, or `null` when disabled. */
|
|
2323
|
+
declare function resolveInsightOptions(insights: boolean | InsightOptions | undefined): Required<InsightOptions> | null;
|
|
2324
|
+
/**
|
|
2325
|
+
* Expand a chart's `insights` option into `point` annotations for its notable
|
|
2326
|
+
* data points. Returns `[]` when insights are disabled, the chart has no
|
|
2327
|
+
* summarizable trend, or it splits into multiple series.
|
|
2328
|
+
*/
|
|
2329
|
+
declare function autoInsightAnnotations(spec: ChartSpec): Annotation[];
|
|
2330
|
+
|
|
2331
|
+
/**
|
|
2332
|
+
* Pure linear-regression helpers — the analytical core behind the `trendline`
|
|
2333
|
+
* overlay. Dependency-free and deterministic so the same fit is computed in the
|
|
2334
|
+
* browser and headless. Mirrors the covariance math used by `pearson()` in
|
|
2335
|
+
* `./insights`, exposed here as a reusable line-of-best-fit.
|
|
2336
|
+
*/
|
|
2337
|
+
interface RegressionFit {
|
|
2338
|
+
/** Slope (dy/dx) of the fitted line. */
|
|
2339
|
+
slope: number;
|
|
2340
|
+
/** Y-intercept of the fitted line. */
|
|
2341
|
+
intercept: number;
|
|
2342
|
+
/** Coefficient of determination (R²), in [0, 1]. */
|
|
2343
|
+
r2: number;
|
|
2344
|
+
/** Number of finite (x, y) pairs the fit used. */
|
|
2345
|
+
n: number;
|
|
2346
|
+
/** Predict y for a given x along the fitted line. */
|
|
2347
|
+
predict(x: number): number;
|
|
2348
|
+
}
|
|
2349
|
+
/**
|
|
2350
|
+
* Ordinary-least-squares linear fit over paired numeric samples.
|
|
2351
|
+
*
|
|
2352
|
+
* Returns `null` when there are fewer than two points or the x values have no
|
|
2353
|
+
* spread (a vertical fit has an undefined slope). Non-finite pairs are ignored.
|
|
2354
|
+
*/
|
|
2355
|
+
declare function linearRegression(xs: readonly number[], ys: readonly number[]): RegressionFit | null;
|
|
2356
|
+
|
|
1506
2357
|
/** Environment helpers — safe in both browser and Node (SSR/test). */
|
|
1507
2358
|
declare const isBrowser: boolean;
|
|
1508
2359
|
/** Current device pixel ratio (defaults to 1 outside the browser). */
|
|
@@ -1535,10 +2386,88 @@ declare function createDiv(className?: string, style?: Partial<CSSStyleDeclarati
|
|
|
1535
2386
|
/** Absolute-position a layer to fill its positioned parent. */
|
|
1536
2387
|
declare const fillParentStyle: Partial<CSSStyleDeclaration>;
|
|
1537
2388
|
|
|
2389
|
+
/**
|
|
2390
|
+
* Canvas painting for chart "overlay" text (axis labels, titles, legends,
|
|
2391
|
+
* annotation labels). In the browser this text lives in a crisp, selectable
|
|
2392
|
+
* HTML overlay; headless (no DOM) there is no overlay, so the very same text is
|
|
2393
|
+
* painted onto the marks canvas with these helpers.
|
|
2394
|
+
*
|
|
2395
|
+
* The geometry is shared: call sites compute one set of positions and either
|
|
2396
|
+
* realise them as absolutely-positioned DOM nodes (browser) or feed them here
|
|
2397
|
+
* (headless). The transform/width vocabulary the DOM path uses
|
|
2398
|
+
* (`translateX(-50%)`, `translateY(-50%)`, `translate(-50%,-50%) rotate(±90deg)`,
|
|
2399
|
+
* box `width` + `align`) maps deterministically onto canvas
|
|
2400
|
+
* `textAlign`/`textBaseline`/rotation, so both paths land the same pixels.
|
|
2401
|
+
*/
|
|
2402
|
+
interface CanvasPillStyle {
|
|
2403
|
+
background: string;
|
|
2404
|
+
border?: string;
|
|
2405
|
+
radius?: number;
|
|
2406
|
+
padX?: number;
|
|
2407
|
+
padY?: number;
|
|
2408
|
+
}
|
|
2409
|
+
interface CanvasTextCmd {
|
|
2410
|
+
/** Anchor x (interpreted per `align`). */
|
|
2411
|
+
x: number;
|
|
2412
|
+
/** Anchor y (interpreted per `baseline`). */
|
|
2413
|
+
y: number;
|
|
2414
|
+
text: string;
|
|
2415
|
+
/** CSS font shorthand (authoritative — already encodes size + weight). */
|
|
2416
|
+
font: string;
|
|
2417
|
+
color: string;
|
|
2418
|
+
/** Font pixel size, used to size the optional pill. */
|
|
2419
|
+
size: number;
|
|
2420
|
+
align?: CanvasTextAlign;
|
|
2421
|
+
baseline?: CanvasTextBaseline;
|
|
2422
|
+
/** Rotation about (x, y), in radians. */
|
|
2423
|
+
rotate?: number;
|
|
2424
|
+
opacity?: number;
|
|
2425
|
+
/** Draw a rounded "pill"/badge behind the text (solid fill + hairline border). */
|
|
2426
|
+
pill?: CanvasPillStyle;
|
|
2427
|
+
}
|
|
2428
|
+
/** Paint a single text command onto a 2D context. Self-contained (save/restore). */
|
|
2429
|
+
declare function paintCanvasText(ctx: CanvasRenderingContext2D, c: CanvasTextCmd): void;
|
|
2430
|
+
/** Option shape shared by the DOM text helpers (axes + chrome). */
|
|
2431
|
+
interface OverlayTextOpts {
|
|
2432
|
+
left: number;
|
|
2433
|
+
top: number;
|
|
2434
|
+
width?: number;
|
|
2435
|
+
text: string;
|
|
2436
|
+
color: string;
|
|
2437
|
+
size: number;
|
|
2438
|
+
align?: 'left' | 'center' | 'right';
|
|
2439
|
+
transform?: string;
|
|
2440
|
+
opacity?: number;
|
|
2441
|
+
pill?: CanvasPillStyle;
|
|
2442
|
+
}
|
|
2443
|
+
/**
|
|
2444
|
+
* Translate an absolutely-positioned overlay text node (left/top/width/align +
|
|
2445
|
+
* a CSS `transform` from the known vocabulary) into the equivalent canvas
|
|
2446
|
+
* command. Keeps the headless output pixel-aligned with the browser overlay.
|
|
2447
|
+
*/
|
|
2448
|
+
declare function overlayTextToCanvasCmd(o: OverlayTextOpts, font: string): CanvasTextCmd;
|
|
2449
|
+
type LegendSymbol = 'square' | 'circle' | 'line';
|
|
2450
|
+
/** Total horizontal footprint of a legend swatch (square/circle = 11, line = 14). */
|
|
2451
|
+
declare function legendSwatchWidth(symbol: LegendSymbol | undefined, swatch?: number): number;
|
|
2452
|
+
/**
|
|
2453
|
+
* Paint a legend swatch onto canvas, vertically centered on `midY`. Mirrors the
|
|
2454
|
+
* DOM swatch (square/circle 11px, line 14×3px).
|
|
2455
|
+
*/
|
|
2456
|
+
declare function paintLegendSwatch(ctx: CanvasRenderingContext2D, x: number, midY: number, symbol: LegendSymbol | undefined, color: string, swatch?: number): void;
|
|
2457
|
+
|
|
1538
2458
|
/**
|
|
1539
2459
|
* Text measurement using a shared offscreen canvas context. Falls back to a
|
|
1540
|
-
* rough heuristic when no canvas is available (SSR/test).
|
|
2460
|
+
* rough heuristic when no canvas is available (SSR/test). In a non-DOM
|
|
2461
|
+
* environment (e.g. `@graphein/node`) a real 2D context can be injected via
|
|
2462
|
+
* {@link setMeasureContext} so layout uses true font metrics.
|
|
1541
2463
|
*/
|
|
2464
|
+
/**
|
|
2465
|
+
* Provide a 2D context used to measure text advance widths when no DOM is
|
|
2466
|
+
* available (headless rendering). Pass `null` to clear and fall back to the
|
|
2467
|
+
* DOM canvas / heuristic. The context's `font` is overwritten on each measure,
|
|
2468
|
+
* so use a dedicated measurement context rather than your drawing context.
|
|
2469
|
+
*/
|
|
2470
|
+
declare function setMeasureContext(ctx: CanvasRenderingContext2D | null): void;
|
|
1542
2471
|
interface TextMetricsLite {
|
|
1543
2472
|
width: number;
|
|
1544
2473
|
}
|
|
@@ -1685,6 +2614,12 @@ interface DashboardSpec {
|
|
|
1685
2614
|
*/
|
|
1686
2615
|
interactions?: 'auto' | 'none' | InteractionLink[];
|
|
1687
2616
|
}
|
|
2617
|
+
/**
|
|
2618
|
+
* Any top-level Graphein spec: a chart, a slicer, or a dashboard. This is the
|
|
2619
|
+
* root type the JSON Schema (`docs/chart-spec.schema.json`) is generated from,
|
|
2620
|
+
* and the broadest type `validateSpec` accepts.
|
|
2621
|
+
*/
|
|
2622
|
+
type AnySpec = ChartSpec | DashboardSpec;
|
|
1688
2623
|
|
|
1689
2624
|
/** Infer the channel type of a single value. */
|
|
1690
2625
|
declare function inferValueType(value: unknown): FieldType | undefined;
|
|
@@ -1696,10 +2631,65 @@ declare function inferFieldType(data: Datum[], field: string, sample?: number):
|
|
|
1696
2631
|
/** Infer types for every field present in the first rows of the dataset. */
|
|
1697
2632
|
declare function inferFieldTypes(data: Datum[]): Record<string, FieldType>;
|
|
1698
2633
|
|
|
2634
|
+
/**
|
|
2635
|
+
* Minimal, apply-only JSON Patch (RFC 6902) used by `repairSpec` to apply the
|
|
2636
|
+
* safe `fix` operations that `validateSpec` attaches to errors. Pure: returns a
|
|
2637
|
+
* new document, never mutates the input. Preserves `Date` values (specs may hold
|
|
2638
|
+
* `Date` objects for temporal fields), unlike a JSON round-trip clone.
|
|
2639
|
+
*/
|
|
2640
|
+
type JsonPatchOp = {
|
|
2641
|
+
op: 'add';
|
|
2642
|
+
path: string;
|
|
2643
|
+
value: unknown;
|
|
2644
|
+
} | {
|
|
2645
|
+
op: 'replace';
|
|
2646
|
+
path: string;
|
|
2647
|
+
value: unknown;
|
|
2648
|
+
} | {
|
|
2649
|
+
op: 'remove';
|
|
2650
|
+
path: string;
|
|
2651
|
+
};
|
|
2652
|
+
/**
|
|
2653
|
+
* Convert a dotted/bracketed validation path (`encoding.x.type`,
|
|
2654
|
+
* `transform[0].calculate`, `values[2].op`) into a JSON Pointer
|
|
2655
|
+
* (`/encoding/x/type`, `/transform/0/calculate`, `/values/2/op`). Authoring
|
|
2656
|
+
* fixes from the same `path` an error already reports keeps the two in sync.
|
|
2657
|
+
*/
|
|
2658
|
+
declare function toPointer(path: string): string;
|
|
2659
|
+
/** Apply an ordered list of patch ops to a deep clone of `doc`. */
|
|
2660
|
+
declare function applyPatch<T>(doc: T, ops: readonly JsonPatchOp[]): T;
|
|
2661
|
+
|
|
1699
2662
|
interface ValidationError {
|
|
1700
2663
|
/** JSON-path-ish location, e.g. "encoding.x.field". */
|
|
1701
2664
|
path: string;
|
|
1702
2665
|
message: string;
|
|
2666
|
+
/**
|
|
2667
|
+
* Stable rule id for lint findings (e.g. "pie-too-many-slices"), so agents can
|
|
2668
|
+
* recognize, suppress, or learn from a specific best-practice warning. Absent
|
|
2669
|
+
* on structural validation errors.
|
|
2670
|
+
*/
|
|
2671
|
+
rule?: string;
|
|
2672
|
+
/**
|
|
2673
|
+
* Severity of a lint finding. Structural problems are reported via `errors`
|
|
2674
|
+
* (implicitly 'error'); lint findings in `warnings` are 'warning' or 'info'.
|
|
2675
|
+
*/
|
|
2676
|
+
severity?: 'error' | 'warning' | 'info';
|
|
2677
|
+
/**
|
|
2678
|
+
* Safe, unambiguous JSON Patch (RFC 6902) operations that resolve this problem
|
|
2679
|
+
* — present only when a correction is clear (e.g. a misspelled enum or chart
|
|
2680
|
+
* type, or a temporal-looking field typed as a category). An agent can apply
|
|
2681
|
+
* these directly instead of regenerating; {@link repairSpec} applies them for
|
|
2682
|
+
* you. Absent when the right fix is ambiguous.
|
|
2683
|
+
*/
|
|
2684
|
+
fix?: JsonPatchOp[];
|
|
2685
|
+
/**
|
|
2686
|
+
* "Did you mean" candidates, nearest first, for an unrecognized value. `kind`
|
|
2687
|
+
* names what is being suggested so an agent can react appropriately.
|
|
2688
|
+
*/
|
|
2689
|
+
suggestion?: {
|
|
2690
|
+
kind: 'chartType' | 'enum' | 'field' | 'channel';
|
|
2691
|
+
candidates: string[];
|
|
2692
|
+
};
|
|
1703
2693
|
}
|
|
1704
2694
|
interface ValidationResult {
|
|
1705
2695
|
valid: boolean;
|
|
@@ -1720,6 +2710,57 @@ declare function validateSpec(spec: unknown): ValidationResult;
|
|
|
1720
2710
|
declare function validateDashboard(spec: Record<string, unknown>): ValidationResult;
|
|
1721
2711
|
declare function assertValidSpec(spec: unknown): ChartSpec;
|
|
1722
2712
|
|
|
2713
|
+
/**
|
|
2714
|
+
* Dataviz linter — best-practice rules that encode the visualization expertise an
|
|
2715
|
+
* agent may lack. Each rule is pure and returns findings with a stable `rule` id
|
|
2716
|
+
* and a `severity` ('warning' | 'info'), so an agent can recognize, suppress, or
|
|
2717
|
+
* learn from a specific issue. Findings are surfaced through `validateSpec`'s
|
|
2718
|
+
* `warnings`, and directly via {@link lintSpec}.
|
|
2719
|
+
*
|
|
2720
|
+
* Rules lint the *effective* data (after `transform`), so cardinality reflects
|
|
2721
|
+
* what actually renders (e.g. pie slices after an `aggregate`). The linter never
|
|
2722
|
+
* throws and never blocks rendering — it is advisory only.
|
|
2723
|
+
*/
|
|
2724
|
+
|
|
2725
|
+
/** A lint finding always carries a `rule` id and a non-error `severity`. */
|
|
2726
|
+
interface LintFinding extends ValidationError {
|
|
2727
|
+
rule: string;
|
|
2728
|
+
severity: 'warning' | 'info';
|
|
2729
|
+
}
|
|
2730
|
+
/**
|
|
2731
|
+
* Lint a (structurally valid) chart spec for best-practice issues. Returns an
|
|
2732
|
+
* empty array for slicers/dashboards or when no rule fires. Pure and total.
|
|
2733
|
+
*/
|
|
2734
|
+
declare function lintSpec(spec: ChartSpec): LintFinding[];
|
|
2735
|
+
|
|
2736
|
+
/**
|
|
2737
|
+
* Self-repairing validation. {@link repairSpec} applies the safe, unambiguous
|
|
2738
|
+
* JSON Patch fixes that {@link validateSpec} attaches to its findings, then
|
|
2739
|
+
* re-validates — turning common agent mistakes (a misspelled chart type or enum,
|
|
2740
|
+
* a temporal field typed as a category) into a one-step correction instead of a
|
|
2741
|
+
* full regenerate. Only fixes the validator deems unambiguous are applied; when
|
|
2742
|
+
* the right correction is unclear, the error is left for the agent to resolve.
|
|
2743
|
+
*/
|
|
2744
|
+
|
|
2745
|
+
interface RepairResult {
|
|
2746
|
+
/** The (possibly) corrected spec — a new object; the input is never mutated. */
|
|
2747
|
+
spec: unknown;
|
|
2748
|
+
/** Patch operations that were applied, in order. Empty when nothing changed. */
|
|
2749
|
+
applied: JsonPatchOp[];
|
|
2750
|
+
/**
|
|
2751
|
+
* Structural errors that remain after repair. `remaining.length === 0` means
|
|
2752
|
+
* the repaired spec is valid. Advisory lint warnings are not counted here.
|
|
2753
|
+
*/
|
|
2754
|
+
remaining: ValidationError[];
|
|
2755
|
+
}
|
|
2756
|
+
/**
|
|
2757
|
+
* Apply every safe auto-fix `validateSpec` proposes, iterating until the spec is
|
|
2758
|
+
* valid or no further progress can be made (a fix may unlock another — e.g.
|
|
2759
|
+
* correcting the chart `type` changes which channels are required). Pure: the
|
|
2760
|
+
* input spec is deep-cloned before any patch is applied.
|
|
2761
|
+
*/
|
|
2762
|
+
declare function repairSpec(spec: unknown): RepairResult;
|
|
2763
|
+
|
|
1723
2764
|
/**
|
|
1724
2765
|
* Resolve a spec's `sketch` option into concrete, fully-defaulted knobs for the
|
|
1725
2766
|
* rough engine. Returns `null` when sketching is off, which lets every chart
|
|
@@ -1840,6 +2881,9 @@ interface FrameInput {
|
|
|
1840
2881
|
height: number;
|
|
1841
2882
|
padding: Insets;
|
|
1842
2883
|
font: ThemeFont;
|
|
2884
|
+
/** Optional origin offset — lay the frame out within a sub-region (e.g. a facet cell). */
|
|
2885
|
+
originX?: number;
|
|
2886
|
+
originY?: number;
|
|
1843
2887
|
title?: TitleInput;
|
|
1844
2888
|
legend?: {
|
|
1845
2889
|
items: LegendItem[];
|
|
@@ -1848,10 +2892,15 @@ interface FrameInput {
|
|
|
1848
2892
|
/** Cartesian charts pass both axes; non-cartesian omit them. */
|
|
1849
2893
|
xAxis?: AxisInput;
|
|
1850
2894
|
yAxis?: AxisInput;
|
|
2895
|
+
/** Secondary (right) y-axis for dual-axis combo charts; reserves a right gutter. */
|
|
2896
|
+
y2Axis?: AxisInput;
|
|
1851
2897
|
}
|
|
1852
2898
|
interface Frame {
|
|
1853
2899
|
width: number;
|
|
1854
2900
|
height: number;
|
|
2901
|
+
/** Absolute origin offset of this frame within the surface (0 unless faceted). */
|
|
2902
|
+
originX: number;
|
|
2903
|
+
originY: number;
|
|
1855
2904
|
plot: Rect;
|
|
1856
2905
|
titleRect?: Rect;
|
|
1857
2906
|
subtitleRect?: Rect;
|
|
@@ -2007,6 +3056,22 @@ declare function resolveCurve(curve?: CurveType): Curve;
|
|
|
2007
3056
|
interface BuildOptions {
|
|
2008
3057
|
width: number;
|
|
2009
3058
|
height: number;
|
|
3059
|
+
/** Origin offset, so the model lays out within a sub-region (a facet cell). */
|
|
3060
|
+
originX?: number;
|
|
3061
|
+
originY?: number;
|
|
3062
|
+
/** Shared scale domains/colors, so faceted panels stay directly comparable. */
|
|
3063
|
+
shared?: SharedScales;
|
|
3064
|
+
}
|
|
3065
|
+
/** Scale state shared across a facet grid so every panel is comparable. */
|
|
3066
|
+
interface SharedScales {
|
|
3067
|
+
/** Band/point category domain (the full ordered category list). */
|
|
3068
|
+
categories?: string[];
|
|
3069
|
+
/** Continuous (linear) or temporal (epoch ms) x-domain. */
|
|
3070
|
+
xDomain?: [number, number];
|
|
3071
|
+
/** Linear y-domain (already accounting for any zero baseline). */
|
|
3072
|
+
yDomain?: [number, number];
|
|
3073
|
+
/** Series-key → color, so the same series keeps its color in every panel. */
|
|
3074
|
+
colorOf?: (key: string) => string;
|
|
2010
3075
|
}
|
|
2011
3076
|
declare function buildCartesianModel(spec: CartesianChartSpec, tokens: ThemeTokens, opts: BuildOptions): CartesianModel;
|
|
2012
3077
|
|
|
@@ -2023,6 +3088,8 @@ declare function buildCartesianModel(spec: CartesianChartSpec, tokens: ThemeToke
|
|
|
2023
3088
|
declare function drawAxesUnderlay(surface: Surface, model: CartesianModel): void;
|
|
2024
3089
|
/** Draw all overlay text: tick labels, axis titles, chart title, legend. */
|
|
2025
3090
|
declare function drawOverlay(surface: Surface, model: CartesianModel): void;
|
|
3091
|
+
declare function drawTitle(surface: Surface, frame: Frame, spec: CartesianModel['spec'], tokens: ThemeTokens): void;
|
|
3092
|
+
declare function drawLegend(surface: Surface, items: PositionedLegendItem[], model: CartesianModel): void;
|
|
2026
3093
|
|
|
2027
3094
|
/**
|
|
2028
3095
|
* SelectionStore — the dependency-free bus that links interactive visuals.
|
|
@@ -2054,6 +3121,51 @@ interface SelectionStore {
|
|
|
2054
3121
|
}
|
|
2055
3122
|
declare function createSelectionStore(initial?: Record<string, SelectionValue | null>): SelectionStore;
|
|
2056
3123
|
|
|
3124
|
+
/**
|
|
3125
|
+
* Reference annotations for cartesian charts — lines, bands, and threshold zones.
|
|
3126
|
+
*
|
|
3127
|
+
* A cross-cutting overlay primitive available to every cartesian chart via
|
|
3128
|
+
* `spec.annotations`. Marks (the rule strokes and band fills) are painted on the
|
|
3129
|
+
* marks canvas; labels live in the HTML overlay for crisp, selectable text,
|
|
3130
|
+
* mirroring how axes render. Geometry comes from the already-resolved
|
|
3131
|
+
* `CartesianModel` scales, so this module is pure presentation.
|
|
3132
|
+
*/
|
|
3133
|
+
|
|
3134
|
+
/**
|
|
3135
|
+
* Paint reference lines and band/zone fills on the marks canvas, clipped to the
|
|
3136
|
+
* plot. Call after the chart's data marks so reference lines sit on top.
|
|
3137
|
+
*/
|
|
3138
|
+
declare function drawAnnotations(surface: Surface, model: CartesianModel): void;
|
|
3139
|
+
/**
|
|
3140
|
+
* Append annotation labels to the HTML overlay. Call after `drawOverlay` so the
|
|
3141
|
+
* labels layer on top of axis text. No-op when there are no labeled annotations.
|
|
3142
|
+
*/
|
|
3143
|
+
declare function drawAnnotationLabels(surface: Surface, model: CartesianModel): void;
|
|
3144
|
+
|
|
3145
|
+
/**
|
|
3146
|
+
* Derived trendlines for cartesian charts — a linear line of best fit overlaid
|
|
3147
|
+
* on a scatter, line, or area plot via `spec.trendline`.
|
|
3148
|
+
*
|
|
3149
|
+
* The regression is computed from the already-resolved `CartesianModel` series
|
|
3150
|
+
* (one fit per group, or a single overall fit), and the fitted line is stroked
|
|
3151
|
+
* across each group's x-extent. Marks land on the marks canvas; optional `R²`
|
|
3152
|
+
* labels live in the HTML overlay (or are painted to canvas when headless),
|
|
3153
|
+
* mirroring how `annotations` render. Pure presentation — no data reshaping.
|
|
3154
|
+
*/
|
|
3155
|
+
|
|
3156
|
+
/**
|
|
3157
|
+
* Stroke the fitted line(s) on the marks canvas, clipped to the plot. Call after
|
|
3158
|
+
* the chart's data marks so the trendline sits on top. No-op unless the spec
|
|
3159
|
+
* opts in via `trendline` and the x-axis is continuous/temporal.
|
|
3160
|
+
*/
|
|
3161
|
+
declare function drawTrendlines(surface: Surface, model: CartesianModel): void;
|
|
3162
|
+
/**
|
|
3163
|
+
* Append `R²` labels for each fitted line to the HTML overlay (or paint them to
|
|
3164
|
+
* canvas when headless). Call after `drawAnnotationLabels`. No-op unless
|
|
3165
|
+
* `trendline.label` is set.
|
|
3166
|
+
*/
|
|
3167
|
+
declare function drawTrendlineLabels(surface: Surface, model: CartesianModel): void;
|
|
3168
|
+
|
|
2057
3169
|
/**
|
|
2058
3170
|
* Chart registry.
|
|
2059
3171
|
*
|
|
@@ -2248,6 +3360,257 @@ declare function resolveFilterValues(filter: FilterClause[] | undefined, store:
|
|
|
2248
3360
|
/** The set of param names a spec reacts to (for change-driven redraws). */
|
|
2249
3361
|
declare function dependentParams(highlight: HighlightConfig | HighlightConfig[] | undefined, filter: FilterClause[] | undefined, ownParams?: readonly string[]): Set<string>;
|
|
2250
3362
|
|
|
3363
|
+
/**
|
|
3364
|
+
* Combo / dual-axis model builder.
|
|
3365
|
+
*
|
|
3366
|
+
* A `combo` spec composes several cartesian layers (bar, line, area, scatter) over
|
|
3367
|
+
* a shared x axis, optionally split across a primary (left) and secondary (right)
|
|
3368
|
+
* y axis. This builder resolves one shared frame / plot / x-scale and, for every
|
|
3369
|
+
* layer, a fully-formed {@link CartesianModel} that the existing mark renderers
|
|
3370
|
+
* (`drawLine`, `drawBar`, …) consume unchanged. Two independent y-scales back the
|
|
3371
|
+
* left and right axes; bar layers are offset side-by-side so multiple bars group.
|
|
3372
|
+
*
|
|
3373
|
+
* The builder is deliberately self-contained (it reuses only the public scale /
|
|
3374
|
+
* tick / frame / color primitives) so the single-chart `buildCartesianModel` path
|
|
3375
|
+
* stays untouched.
|
|
3376
|
+
*/
|
|
3377
|
+
|
|
3378
|
+
type ComboSide = 'left' | 'right';
|
|
3379
|
+
interface ComboLayerModel {
|
|
3380
|
+
mark: ComboMark;
|
|
3381
|
+
side: ComboSide;
|
|
3382
|
+
color: string;
|
|
3383
|
+
name: string;
|
|
3384
|
+
/** A ready-to-draw cartesian model for this layer's mark renderer. */
|
|
3385
|
+
model: CartesianModel;
|
|
3386
|
+
}
|
|
3387
|
+
interface ComboAxisModel {
|
|
3388
|
+
show: boolean;
|
|
3389
|
+
ticks: Tick[];
|
|
3390
|
+
title?: string;
|
|
3391
|
+
}
|
|
3392
|
+
interface ComboModel {
|
|
3393
|
+
spec: ComboSpec;
|
|
3394
|
+
tokens: ThemeTokens;
|
|
3395
|
+
frame: Frame;
|
|
3396
|
+
plot: Rect;
|
|
3397
|
+
x: XModel;
|
|
3398
|
+
xTicks: Tick[];
|
|
3399
|
+
left: ComboAxisModel;
|
|
3400
|
+
right?: ComboAxisModel;
|
|
3401
|
+
layers: ComboLayerModel[];
|
|
3402
|
+
legendItems: LegendItem[];
|
|
3403
|
+
/** Primary-axis cartesian model reused for the axis underlay / overlay chrome. */
|
|
3404
|
+
base: CartesianModel;
|
|
3405
|
+
sketch: ResolvedSketch | null;
|
|
3406
|
+
emphasis?: Emphasis | null;
|
|
3407
|
+
}
|
|
3408
|
+
declare function buildComboModel(spec: ComboSpec, tokens: ThemeTokens, opts: BuildOptions): ComboModel;
|
|
3409
|
+
|
|
3410
|
+
/**
|
|
3411
|
+
* Histogram model builder.
|
|
3412
|
+
*
|
|
3413
|
+
* A `histogram` bins a single quantitative field (reusing the shared `bin`
|
|
3414
|
+
* transform's {@link computeBins}) and draws the per-bin frequency as gapless
|
|
3415
|
+
* bars on a continuous x-axis. Like the combo builder, it resolves a synthetic
|
|
3416
|
+
* `base` {@link CartesianModel} so the existing axis chrome (`drawAxesUnderlay` /
|
|
3417
|
+
* `drawOverlay`) renders the gridlines, ticks, labels and titles unchanged — the
|
|
3418
|
+
* bars themselves are painted by {@link drawHistogram}.
|
|
3419
|
+
*/
|
|
3420
|
+
|
|
3421
|
+
/** One resolved histogram bin (closed-open `[start, end)`). */
|
|
3422
|
+
interface HistogramBinDatum {
|
|
3423
|
+
start: number;
|
|
3424
|
+
end: number;
|
|
3425
|
+
mid: number;
|
|
3426
|
+
/** Raw observation count in the bin. */
|
|
3427
|
+
count: number;
|
|
3428
|
+
/** Plotted height: `count`, or a probability density when `density:true`. */
|
|
3429
|
+
value: number;
|
|
3430
|
+
}
|
|
3431
|
+
interface HistogramModel {
|
|
3432
|
+
spec: HistogramSpec;
|
|
3433
|
+
tokens: ThemeTokens;
|
|
3434
|
+
frame: Frame;
|
|
3435
|
+
plot: Rect;
|
|
3436
|
+
bins: HistogramBinDatum[];
|
|
3437
|
+
layout: BinLayout | null;
|
|
3438
|
+
color: string;
|
|
3439
|
+
/** Map a quantitative x value to a pixel. */
|
|
3440
|
+
xPixel: (v: number) => number;
|
|
3441
|
+
/** Map a bar height (count/density) to a pixel. */
|
|
3442
|
+
yPixel: (v: number) => number;
|
|
3443
|
+
/** Pixel of the y=0 baseline. */
|
|
3444
|
+
yBaseline: number;
|
|
3445
|
+
cornerRadius: number;
|
|
3446
|
+
/** Drives the shared axis underlay / overlay chrome. */
|
|
3447
|
+
base: CartesianModel;
|
|
3448
|
+
sketch: ResolvedSketch | null;
|
|
3449
|
+
}
|
|
3450
|
+
declare function buildHistogramModel(spec: HistogramSpec, tokens: ThemeTokens, opts: BuildOptions): HistogramModel;
|
|
3451
|
+
|
|
3452
|
+
/**
|
|
3453
|
+
* Render report / introspection API.
|
|
3454
|
+
*
|
|
3455
|
+
* After a chart draws, `buildRenderReport` derives a machine-readable set of
|
|
3456
|
+
* diagnostics from the *resolved* model (scales, plot rect, ticks, legend,
|
|
3457
|
+
* theme colors) — no pixels are read back. This lets an agent verify a chart
|
|
3458
|
+
* "looks right" without vision: it can see the mark count, whether axis labels
|
|
3459
|
+
* collide, whether the legend was truncated, whether marks fall outside the
|
|
3460
|
+
* plot, and whether colors clear contrast thresholds.
|
|
3461
|
+
*
|
|
3462
|
+
* The builder is pure and dependency-free so it runs identically in the browser
|
|
3463
|
+
* and headless (the server-side critique loop consumes the same report).
|
|
3464
|
+
*/
|
|
3465
|
+
|
|
3466
|
+
type ReportSeverity = 'error' | 'warning' | 'info';
|
|
3467
|
+
/** One machine-readable finding about the rendered chart. */
|
|
3468
|
+
interface RenderDiagnostic {
|
|
3469
|
+
/** Stable identifier an agent can match/suppress on (e.g. `axis-label-overlap`). */
|
|
3470
|
+
code: string;
|
|
3471
|
+
severity: ReportSeverity;
|
|
3472
|
+
/** Human- and agent-readable explanation. */
|
|
3473
|
+
message: string;
|
|
3474
|
+
/** The axis a layout diagnostic refers to, when applicable. */
|
|
3475
|
+
axis?: 'x' | 'y';
|
|
3476
|
+
/** Structured extras (counts, ratios) for programmatic consumers. */
|
|
3477
|
+
details?: Record<string, unknown>;
|
|
3478
|
+
}
|
|
3479
|
+
/** A post-render, vision-free description of what was drawn. */
|
|
3480
|
+
interface RenderReport {
|
|
3481
|
+
type: ChartType;
|
|
3482
|
+
/** Surface size in CSS pixels. */
|
|
3483
|
+
size: Size;
|
|
3484
|
+
/** Plot rectangle (cartesian-derived reports only). */
|
|
3485
|
+
plot?: Rect;
|
|
3486
|
+
/** Number of data marks the chart drew. */
|
|
3487
|
+
markCount: number;
|
|
3488
|
+
/** Number of distinct series. */
|
|
3489
|
+
seriesCount: number;
|
|
3490
|
+
/** Number of distinct colors used for series. */
|
|
3491
|
+
colorCount: number;
|
|
3492
|
+
/** True when no `error` or `warning` diagnostics were raised. */
|
|
3493
|
+
ok: boolean;
|
|
3494
|
+
/** All findings, ordered most-severe first. */
|
|
3495
|
+
diagnostics: RenderDiagnostic[];
|
|
3496
|
+
/**
|
|
3497
|
+
* Deterministic plain-English summary of what the data shows (alt-text without
|
|
3498
|
+
* an LLM). Absent for chart types that carry no summarizable trend.
|
|
3499
|
+
*/
|
|
3500
|
+
summary?: string;
|
|
3501
|
+
}
|
|
3502
|
+
/** Inputs for {@link buildRenderReport}. */
|
|
3503
|
+
interface ReportInput {
|
|
3504
|
+
type: ChartType;
|
|
3505
|
+
spec: ChartSpec;
|
|
3506
|
+
/** Effective (post-transform, post-filter) data that was rendered. */
|
|
3507
|
+
data: Datum[];
|
|
3508
|
+
tokens: ThemeTokens;
|
|
3509
|
+
size: Size;
|
|
3510
|
+
/** The resolved cartesian model, when the chart type is cartesian. */
|
|
3511
|
+
model?: CartesianModel;
|
|
3512
|
+
}
|
|
3513
|
+
/**
|
|
3514
|
+
* Build the render report for a freshly-drawn chart. Pure: it reads the
|
|
3515
|
+
* resolved model + theme, never the canvas bitmap.
|
|
3516
|
+
*/
|
|
3517
|
+
declare function buildRenderReport(input: ReportInput): RenderReport;
|
|
3518
|
+
|
|
3519
|
+
/**
|
|
3520
|
+
* Faceting / small multiples.
|
|
3521
|
+
*
|
|
3522
|
+
* A faceted chart splits into a trellis grid of panels — one per distinct value
|
|
3523
|
+
* of a field — all sharing identical x/y/color scales so the panels are directly
|
|
3524
|
+
* comparable. Each panel is a full {@link CartesianModel} laid out into its grid
|
|
3525
|
+
* cell (via the frame's origin offset), drawn with the very same cartesian
|
|
3526
|
+
* pipeline (underlay → marks → trendline → annotations → overlay) on a single
|
|
3527
|
+
* canvas. That means faceting works identically headless, preserving the
|
|
3528
|
+
* critique-loop moat.
|
|
3529
|
+
*
|
|
3530
|
+
* The shared scales are derived from a *reference model* built over the full
|
|
3531
|
+
* dataset: its domains and color map ARE the shared state every panel reuses, so
|
|
3532
|
+
* a series keeps its color and position in every panel even when a panel's subset
|
|
3533
|
+
* is missing some categories or series.
|
|
3534
|
+
*/
|
|
3535
|
+
|
|
3536
|
+
/** Cartesian chart kinds that can be split into a facet grid. */
|
|
3537
|
+
declare const FACETABLE_TYPES: ReadonlySet<string>;
|
|
3538
|
+
/** One panel of a facet grid: its facet value plus the resolved model. */
|
|
3539
|
+
interface FacetPanel {
|
|
3540
|
+
value: string;
|
|
3541
|
+
model: CartesianModel;
|
|
3542
|
+
}
|
|
3543
|
+
/** The resolved layout of a faceted chart — the header frame plus panel models. */
|
|
3544
|
+
interface FacetLayout {
|
|
3545
|
+
field: string;
|
|
3546
|
+
columns: number;
|
|
3547
|
+
rows: number;
|
|
3548
|
+
/** Outer frame: reserves the overall title + shared legend; its plot is the grid region. */
|
|
3549
|
+
outerFrame: Frame;
|
|
3550
|
+
panels: FacetPanel[];
|
|
3551
|
+
/** Positioned shared legend items (multi-series only). */
|
|
3552
|
+
legendItems?: PositionedLegendItem[];
|
|
3553
|
+
/** A representative panel model (panels[0]) for token/legend draw. */
|
|
3554
|
+
repModel: CartesianModel;
|
|
3555
|
+
}
|
|
3556
|
+
/** True when `spec` declares a usable facet on a facet-eligible cartesian type. */
|
|
3557
|
+
declare function isFaceted(spec: ChartSpec): boolean;
|
|
3558
|
+
/**
|
|
3559
|
+
* Resolve a faceted spec into a grid of panel models sharing one set of scales.
|
|
3560
|
+
* Returns `null` when there is nothing to facet (no rows / no distinct values),
|
|
3561
|
+
* so the caller can fall back to the normal single-chart path.
|
|
3562
|
+
*/
|
|
3563
|
+
declare function buildFacetModels(spec: ChartSpec, tokens: ThemeTokens, size: Size): FacetLayout | null;
|
|
3564
|
+
/**
|
|
3565
|
+
* Draw a faceted chart onto `surface`: the shared header (overall title + legend)
|
|
3566
|
+
* then every panel through the full cartesian pipeline. Static — no interaction
|
|
3567
|
+
* in v1. The background is assumed already painted by the caller.
|
|
3568
|
+
*/
|
|
3569
|
+
declare function drawFacet(surface: Surface, spec: ChartSpec, layout: FacetLayout, tokens: ThemeTokens): void;
|
|
3570
|
+
/**
|
|
3571
|
+
* Merge per-panel render reports into one report for the faceted chart: mark
|
|
3572
|
+
* counts sum, series/color counts take the panel maximum, diagnostics union by
|
|
3573
|
+
* code (most-severe first), and `ok` holds only if every panel is ok.
|
|
3574
|
+
*/
|
|
3575
|
+
declare function facetReport(spec: ChartSpec, layout: FacetLayout, tokens: ThemeTokens, size: Size): RenderReport;
|
|
3576
|
+
|
|
3577
|
+
/**
|
|
3578
|
+
* Headless rendering — paint a chart onto any caller-supplied 2D context
|
|
3579
|
+
* (e.g. `@napi-rs/canvas`, `node-canvas`, an `OffscreenCanvas`) with **no DOM**.
|
|
3580
|
+
*
|
|
3581
|
+
* This is the server-side half of the critique loop: it reuses the exact same
|
|
3582
|
+
* model build + mark renderers as the browser, but routes overlay text through
|
|
3583
|
+
* the canvas text path (see `render/overlayText.ts`) instead of the HTML overlay.
|
|
3584
|
+
* It is dependency-free — the caller owns canvas creation and PNG/SVG encoding,
|
|
3585
|
+
* so `graphein` itself stays zero-dependency. The companion `@graphein/node`
|
|
3586
|
+
* package wires this to `@napi-rs/canvas`.
|
|
3587
|
+
*
|
|
3588
|
+
* Returns the same {@link RenderReport} as `instance.report()`, so an agent can
|
|
3589
|
+
* generate → validate → render → critique entirely on the server.
|
|
3590
|
+
*/
|
|
3591
|
+
|
|
3592
|
+
/** A minimal 2D-context target. Pass `interaction` if any renderer needs it. */
|
|
3593
|
+
interface HeadlessTarget {
|
|
3594
|
+
/** The primary 2D context chart marks + text are painted onto. */
|
|
3595
|
+
marks: CanvasRenderingContext2D;
|
|
3596
|
+
/** Optional secondary context for hover layers (unused on the static path). */
|
|
3597
|
+
interaction?: CanvasRenderingContext2D;
|
|
3598
|
+
/** Logical (CSS-pixel) width to draw at. */
|
|
3599
|
+
width: number;
|
|
3600
|
+
/** Logical (CSS-pixel) height to draw at. */
|
|
3601
|
+
height: number;
|
|
3602
|
+
}
|
|
3603
|
+
/**
|
|
3604
|
+
* Paint `spec` onto `target.marks` (in CSS pixels — the caller sets up any
|
|
3605
|
+
* device-pixel-ratio scaling on the context beforehand) and return the render
|
|
3606
|
+
* report. No animation, no interactivity, no DOM.
|
|
3607
|
+
*
|
|
3608
|
+
* Supports every canvas-backed chart: line, area, bar, scatter, box, pie,
|
|
3609
|
+
* heatmap, sankey, choropleth, combo, histogram, funnel. DOM-only kinds
|
|
3610
|
+
* (kpi/table/matrix/slicers/dashboard) are unsupported headlessly.
|
|
3611
|
+
*/
|
|
3612
|
+
declare function renderToContext(target: HeadlessTarget, spec: ChartSpec): RenderReport;
|
|
3613
|
+
|
|
2251
3614
|
/**
|
|
2252
3615
|
* Chart runtime: the public `render(container, spec)` entry point.
|
|
2253
3616
|
*
|
|
@@ -2284,6 +3647,14 @@ interface ChartInstance {
|
|
|
2284
3647
|
readonly spec: ChartSpec;
|
|
2285
3648
|
/** The mounted surface (advanced/imperative use). */
|
|
2286
3649
|
readonly surface: Surface;
|
|
3650
|
+
/**
|
|
3651
|
+
* Machine-readable diagnostics from the most recent render: mark count,
|
|
3652
|
+
* clipped axis labels, legend overflow, low-contrast colors, degenerate axes,
|
|
3653
|
+
* and out-of-bounds marks. Lets an agent verify the chart "looks right"
|
|
3654
|
+
* without vision. Computed purely from the resolved model, so it works
|
|
3655
|
+
* identically in the browser and headless.
|
|
3656
|
+
*/
|
|
3657
|
+
report(): RenderReport;
|
|
2287
3658
|
/** The selection bus this chart is bound to (advanced/linking use). */
|
|
2288
3659
|
readonly store: SelectionStore;
|
|
2289
3660
|
/** Read a param's current value, or a snapshot of all params when omitted. */
|
|
@@ -2389,4 +3760,4 @@ declare function renderDashboard(target: HTMLElement | string, spec: DashboardSp
|
|
|
2389
3760
|
*/
|
|
2390
3761
|
declare const VERSION = "0.1.0";
|
|
2391
3762
|
|
|
2392
|
-
export { type AggOp, type AnimateOptions, type AnimationConfig, type AnimationHandle, type ArcOptions, type AreaOptions, type AreaPoint, type AreaSpec, type AxesConfig, type AxisConfig, type AxisInput, type BackingSize, type BandScale, type BandScaleOptions, type BarSpec, type BaseSlicerSpec, type BaseSpec, type BoxSpec, type BuildOptions, CARTESIAN_TYPES, CHART_TYPES, CanvasLayer, type CartesianChartSpec, type CartesianInteractionBuilder, type CartesianModel, type CartesianRenderer, type ChartInstance, type ChartSpec, type ChartSummary, type ChartType, type ChoroplethSpec, type ColorScale, type Comparable, type ConditionalFormat, type ContinuousScale, type ControllerSelect, type Curve, type CurveType, type CustomRenderer, DEFAULT_ENTRANCE_DURATION, DEFAULT_ROUGH_STYLE, DEFAULT_UPDATE_DURATION, DIM_ALPHA, type DashboardInstance, type DashboardLayout, type DashboardResponsiveSpan, type DashboardSection, type DashboardSpec, type DashboardView, type DateRangeSlicerSpec, type Datum, type DecimateOptions, type Dimensions, type DropdownSlicerSpec, type EasingFunction, type Emphasis, type Encoding, type EntranceContext, type Extent, type FieldDef, type FieldType, type FieldValue, type FillStyle, type FilterClause, type Frame, type FrameInput, type FunnelSpec, type GeoFeature, type GeoFeatureCollection, type GeoGeometry, type GeoMultiPolygon, type GeoPolygon, type GeoPosition, type GroupedMap, type HachureSegment, type HeatmapSpec, type HighlightConfig, type Hover, type IconRule, type Insets, InteractionController, type InteractionLink, type InteractionModel, type Interpolator, type KpiSpec, type LegendConfig, type LegendItem, type LegendPosition, type LineOptions, type LineSpec, type LinearScaleOptions, type ListSlicerSpec, type LiteralPredicate, type LogScaleOptions, type MapProjection, type MarkOptions, type MatrixSpec, type MatrixValueDef, type NumberFormatSpec, type OKLCH, type OKLab, type PathSink, type PieLabels, type PieSpec, type PivotCell, type PivotFlatRow, type PivotHeaderNode, type PivotOptions, type PivotResult, type PivotValueDef, type Point, type PointScale, type PointScaleOptions, type PointSelection, type PositionedLegendItem, type RGBA, type RangeSelection, type RangeSlicerSpec, type Rect, type RenderContext, type RenderDashboardOptions, type RenderOptions, type ResolvedEntrance, type ResolvedSeries, type ResolvedSketch, type Rng, type RoughContext, RoughPen, type RoughStyle, SKETCH_FONT_FAMILY, SKETCH_FONT_NAME, SLICER_TYPES, SR_ONLY_STYLE, type SankeySpec, type ScaleConfig, type ScaleType, type ScatterSpec, type SearchSlicerSpec, type SelectConfig, type SelectionChangeListener, type SelectionDef, type SelectionListener, type SelectionParam, type SelectionStore, type SelectionValue, type SetSelection, type Size, type SketchConfig, type SlicerSpec, type SlicerType, Surface, TICK_SIZE, type TableColumn, type TableSpec, type TextMetricsLite, type TextSelection, type ThemeColors, type ThemeFont, type ThemeInput, type ThemeTokens, type Tick, type TimeScaleOptions, type TitleConfig, type TitleInput, Tooltip, type TooltipConfig, type TooltipContent, type TooltipRow, type UpdateContext, VERSION, type ValidationError, type ValidationResult, type ValueRef, type ValueRule, type XKind, type XModel, type YModel, aggregateValues, animate, applyA11y, applyPick, arc, area, assertValidSpec, backOut, bandScale, bounceOut, buildCartesianInteraction, buildCartesianModel, buildDataTableFallback, cartesianInteractionBuilders, cartesianRenderers, categorical, chartTitleText, chartTypeLabel, clamp01, clamp255, computeBackingSize, computeFrame, contrastRatio, createDiv, createRoughPen, createSelectionStore, cubicIn, cubicInOut, cubicOut, curveCatmullRom, curveLinear, curveMonotoneX, curveStep, curveStepAfter, curveStepBefore, customRenderers, darkTheme, decimate, dependentParams, diverging, divergingColorScale, divergingSchemes, drawAxesUnderlay, drawOverlay, easings, elasticOut, ensureSketchFont, expoInOut, expoOut, fillParentStyle, filterRows, fontString, formatDate, formatNumber, formatValue, getDevicePixelRatio, groupBy, hashString, inferFieldType, inferFieldTypes, inferValueType, interpolateArray, interpolateNumber, interpolateNumberArray, interpolateObject, interpolateOklab, interpolateRgb, isBrowser, isEmptyValue, isParamClause, isSlicerType, keyFields, lightTheme, line, linear, linearScale, linearToSrgb, literalToValue, logScale, lttbRun, makeMatcher, matchesValue, measureText, monotoneXTangents, mulberry32, niceDomain, oklabToOklch, oklabToRgb, oklchToOklab, ordinalColorScale, parseColor, parseNumberFormat, pivot, pointScale, polygonHachureLines, prefersReducedMotion, prettyDate, quadIn, quadInOut, quadOut, rampFromStops, readableTextColor, relativeLuminance, render, renderDashboard, resolveCurve, resolveDashboardLayout, resolveDashboardSections, resolveEmphasis, resolveEntrance, resolveFilterValues, resolveSketch, resolveTheme, resolveUpdate, rgbToOklab, rgbaToCss, rotatePoint, roundedRect, sampleArc, sequential, sequentialColorScale, sequentialSchemes, setStyle, sinInOut, slicerParamName, smartDate, specFields, srgbToLinear, summarizeChart, themes, tickIncrement, tickStep, ticks, timeScale, timeTickFormat, timeTicks, toHex, tooltipEnabled, validateDashboard, validateSpec, wireViews, withAlpha, withSketchFont };
|
|
3763
|
+
export { type AggOp, type AggregateOp, type AggregateTransform, type AnimateOptions, type AnimationConfig, type AnimationHandle, type Annotation, type AnySpec, type ArcOptions, type AreaOptions, type AreaPoint, type AreaSpec, type AxesConfig, type AxisConfig, type AxisInput, type BackingSize, type BandScale, type BandScaleOptions, type BarSpec, type BaseSlicerSpec, type BaseSpec, type BinLayout, type BinTransform, type BoxSpec, type BuildOptions, type BulletSpec, CARTESIAN_TYPES, CHART_TYPES, type CalculateTransform, type CalendarHeatmapSpec, CanvasLayer, type CanvasPillStyle, type CanvasTextCmd, type CartesianChartSpec, type CartesianInteractionBuilder, type CartesianModel, type CartesianRenderer, type CategoryInsights, type ChartInsights, type ChartInstance, type ChartSpec, type ChartSummary, type ChartType, type ChoroplethSpec, type ColorScale, type ComboAxisModel, type ComboLayer, type ComboLayerModel, type ComboMark, type ComboModel, type ComboSide, type ComboSpec, type Comparable, type ConditionalFormat, type ContinuousScale, type ControllerSelect, type Curve, type CurveType, type CustomRenderer, DEFAULT_ENTRANCE_DURATION, DEFAULT_ROUGH_STYLE, DEFAULT_UPDATE_DURATION, DIM_ALPHA, type DashboardInstance, type DashboardLayout, type DashboardResponsiveSpan, type DashboardSection, type DashboardSpec, type DashboardView, type DateRangeSlicerSpec, type Datum, type DecimateOptions, type Dimensions, type DropdownSlicerSpec, type DumbbellSpec, type EasingFunction, type Emphasis, type Encoding, type EntranceContext, ExpressionError, type Extent, FACETABLE_TYPES, FUNCTION_NAMES, type FacetConfig, type FacetLayout, type FacetPanel, type FieldDef, type FieldType, type FieldValue, type FillStyle, type FilterClause, type FilterPredicate, type FilterTransform, type FoldTransform, type Frame, type FrameInput, type FunnelSpec, type GaugeSpec, type GeoFeature, type GeoFeatureCollection, type GeoGeometry, type GeoMultiPolygon, type GeoPolygon, type GeoPosition, type GroupedMap, type HachureSegment, type HeadlessTarget, type HeatmapSpec, type HighlightConfig, type HistogramBin, type HistogramBinDatum, type HistogramModel, type HistogramSpec, type Hover, type IconRule, type Insets, type InsightFamily, type InsightOptions, InteractionController, type InteractionLink, type InteractionModel, type Interpolator, type JsonPatchOp, type KpiSpec, type LegendConfig, type LegendItem, type LegendPosition, type LegendSymbol, type LineOptions, type LineSpec, type LinearScaleOptions, type LintFinding, type ListSlicerSpec, type LiteralPredicate, type LogScaleOptions, type MapProjection, type MarkOptions, type MatrixSpec, type MatrixValueDef, type NumberFormatSpec, type OKLCH, type OKLab, type OverlayTextOpts, type PathSink, type PieLabels, type PieSpec, type PivotCell, type PivotFlatRow, type PivotHeaderNode, type PivotOptions, type PivotResult, type PivotValueDef, type Point, type PointRef, type PointScale, type PointScaleOptions, type PointSelection, type PositionedLegendItem, type RGBA, type RangeSelection, type RangeSlicerSpec, type Rect, type RegressionFit, type RenderContext, type RenderDashboardOptions, type RenderDiagnostic, type RenderOptions, type RenderReport, type RepairResult, type ReportInput, type ReportSeverity, type ResolvedEntrance, type ResolvedSeries, type ResolvedSketch, type Rng, type RoughContext, RoughPen, type RoughStyle, SKETCH_FONT_FAMILY, SKETCH_FONT_NAME, SLICER_TYPES, SR_ONLY_STYLE, type SankeySpec, type ScaleConfig, type ScaleType, type ScatterInsights, type ScatterSpec, type SearchSlicerSpec, type SelectConfig, type SelectionChangeListener, type SelectionDef, type SelectionListener, type SelectionParam, type SelectionStore, type SelectionValue, type SeriesInsights, type SetSelection, type SharedScales, type Size, type SketchConfig, type SlicerSpec, type SlicerType, type SlopeSpec, Surface, TICK_SIZE, TIME_UNITS, TRANSFORM_KINDS, type TableColumn, type TableSpec, type TextMetricsLite, type TextSelection, type ThemeColors, type ThemeFont, type ThemeInput, type ThemeTokens, type Tick, type TimeScaleOptions, type TimeUnit, type TimeUnitTransform, type TitleConfig, type TitleInput, Tooltip, type TooltipConfig, type TooltipContent, type TooltipRow, type Transform, type TreemapSpec, type TrendlineConfig, type UpdateContext, VERSION, type ValidationError, type ValidationResult, type ValueInsights, type ValueRef, type ValueRule, type WaterfallSpec, type XKind, type XModel, type YModel, aggregateValues, analyzeChart, animate, applyA11y, applyAggregate, applyBin, applyCalculate, applyFilter, applyFold, applyPatch, applyPick, applyTimeUnit, applyTransform, applyTransforms, arc, area, assertValidSpec, autoInsightAnnotations, backOut, bandScale, bounceOut, buildCartesianInteraction, buildCartesianModel, buildComboModel, buildDataTableFallback, buildFacetModels, buildHistogramModel, buildRenderReport, cartesianInteractionBuilders, cartesianRenderers, categorical, chartTitleText, chartTypeLabel, checkExpression, clamp01, clamp255, compileExpression, compilePredicate, computeBackingSize, computeBins, computeFrame, computeSeriesInsights, contrastRatio, createDiv, createRoughPen, createSelectionStore, cubicIn, cubicInOut, cubicOut, curveCatmullRom, curveLinear, curveMonotoneX, curveStep, curveStepAfter, curveStepBefore, customRenderers, darkTheme, decimate, dependentParams, diverging, divergingColorScale, divergingSchemes, drawAnnotationLabels, drawAnnotations, drawAxesUnderlay, drawFacet, drawLegend, drawOverlay, drawTitle, drawTrendlineLabels, drawTrendlines, easings, elasticOut, ensureSketchFont, expoInOut, expoOut, facetReport, fillParentStyle, filterRows, fontString, formatDate, formatNumber, formatValue, getDevicePixelRatio, groupBy, hashString, inferFieldType, inferFieldTypes, inferValueType, interpolateArray, interpolateNumber, interpolateNumberArray, interpolateObject, interpolateOklab, interpolateRgb, isBrowser, isEmptyValue, isFaceted, isParamClause, isSlicerType, keyFields, legendSwatchWidth, lightTheme, line, linear, linearRegression, linearScale, linearToSrgb, lintSpec, literalToValue, logScale, lttbRun, makeMatcher, matchesValue, measureText, monotoneXTangents, mulberry32, niceDomain, oklabToOklch, oklabToRgb, oklchToOklab, ordinalColorScale, overlayTextToCanvasCmd, paintCanvasText, paintLegendSwatch, parseColor, parseNumberFormat, pivot, pointScale, polygonHachureLines, prefersReducedMotion, prettyDate, quadIn, quadInOut, quadOut, rampFromStops, readableTextColor, relativeLuminance, render, renderDashboard, renderToContext, repairSpec, resolveCurve, resolveDashboardLayout, resolveDashboardSections, resolveEmphasis, resolveEntrance, resolveFilterValues, resolveInsightOptions, resolveSketch, resolveTheme, resolveUpdate, rgbToOklab, rgbaToCss, rotatePoint, roundedRect, sampleArc, sequential, sequentialColorScale, sequentialSchemes, setMeasureContext, setStyle, sinInOut, slicerParamName, smartDate, specFields, srgbToLinear, summarize, summarizeChart, themes, tickIncrement, tickStep, ticks, timeScale, timeTickFormat, timeTicks, toHex, toPointer, tooltipEnabled, truncateTo, validateDashboard, validateSpec, wireViews, withAlpha, withSketchFont };
|