@opendata-ai/openchart-core 6.25.4 → 6.27.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/src/types/spec.ts CHANGED
@@ -240,6 +240,8 @@ export interface AxisConfig {
240
240
  labelPadding?: number;
241
241
  /** Color override for axis tick labels and title. Useful in dual-axis charts to match axis color to its series. */
242
242
  labelColor?: string;
243
+ /** Secondary data field to display alongside each tick label. Renders in lighter weight/color. Only effective on categorical y-axis labels (horizontal bar charts). */
244
+ labelField?: string;
243
245
  }
244
246
 
245
247
  /** Scale configuration for an encoding channel. */
@@ -805,6 +807,17 @@ export interface AnimationConfig {
805
807
  */
806
808
  export type AnimationSpec = boolean | AnimationConfig;
807
809
 
810
+ /**
811
+ * Chart display mode.
812
+ * - `'full'` (default): standard chart with chrome, axes, legend, padding.
813
+ * - `'sparkline'`: minimal inline mini-chart. Strips chrome, axes, legend,
814
+ * watermark, animation, and reduces margins to a tiny safety pad. The mark
815
+ * fills the container edge-to-edge. Best with `mark: 'line' | 'area' | 'bar'`.
816
+ * Explicit user fields (chrome, legend, encoding.x.axis, etc.) still render
817
+ * when set, so users can opt in to specific elements.
818
+ */
819
+ export type Display = 'full' | 'sparkline';
820
+
808
821
  /**
809
822
  * Breakpoint-conditional overrides for chart specs.
810
823
  *
@@ -823,6 +836,12 @@ export interface ChartSpecOverride {
823
836
  annotations?: Annotation[];
824
837
  /** Override animation at this breakpoint. */
825
838
  animation?: AnimationSpec;
839
+ /** Override display mode (`'full'` or `'sparkline'`) at this breakpoint. */
840
+ display?: Display;
841
+ /** Override watermark visibility at this breakpoint. */
842
+ watermark?: boolean;
843
+ /** Override crosshair behavior at this breakpoint. */
844
+ crosshair?: boolean;
826
845
  }
827
846
 
828
847
  /**
@@ -878,6 +897,28 @@ export interface ChartSpec {
878
897
  * - AnimationConfig: full control via enter/update/exit phases
879
898
  */
880
899
  animation?: AnimationSpec;
900
+ /**
901
+ * Show a vertical crosshair line that tracks the nearest data point on
902
+ * line and area charts. Only active when a voronoi overlay is present.
903
+ * Defaults to false. In sparkline display mode, defaults to false unless
904
+ * explicitly set.
905
+ */
906
+ crosshair?: boolean;
907
+ /**
908
+ * Display mode controlling how much chart chrome is rendered.
909
+ *
910
+ * - `'full'` (default): full publication chart with chrome, axes, legend, padding.
911
+ * - `'sparkline'`: inline mini-chart for dashboards/KPI cards. Strips chrome,
912
+ * axes, legend, watermark, animation, and crosshair. The mark fills the
913
+ * container edge-to-edge with a small safety margin. Best with
914
+ * `mark: 'line' | 'area' | 'bar' | 'point'`.
915
+ *
916
+ * **Override precedence:** explicit user fields always win, even in sparkline
917
+ * mode. Setting `chrome.title` on a sparkline still renders the title.
918
+ * Setting `legend: { show: true }` still renders the legend. This applies at
919
+ * top-level and per-breakpoint overrides.
920
+ */
921
+ display?: Display;
881
922
  /**
882
923
  * Render order within a LayerSpec. Higher values render on top.
883
924
  * When omitted, layers render in array order (later layers paint on top).
@@ -1120,6 +1161,58 @@ export interface SankeySpec {
1120
1161
  valueFormat?: string;
1121
1162
  }
1122
1163
 
1164
+ // ---------------------------------------------------------------------------
1165
+ // TileMap spec (US state tile grid map)
1166
+ // ---------------------------------------------------------------------------
1167
+
1168
+ /** Encoding channels specific to tile map visualizations. */
1169
+ export interface TileMapEncoding {
1170
+ /** State code field (required, nominal). Maps to US state abbreviations. */
1171
+ state: EncodingChannel;
1172
+ /** Value field (required, quantitative). Maps to the sequential color scale. */
1173
+ value: EncodingChannel;
1174
+ /** Tooltip encoding (optional). */
1175
+ tooltip?: EncodingChannel | EncodingChannel[];
1176
+ }
1177
+
1178
+ /** Sequential color palette names available for tile maps. */
1179
+ export type TileMapPalette = 'blue' | 'green' | 'orange' | 'purple';
1180
+
1181
+ export interface TileMapSpec {
1182
+ /** Discriminant: always "tilemap". */
1183
+ type: 'tilemap';
1184
+ /**
1185
+ * Data for the tile map. Accepts either:
1186
+ * - A record mapping state codes to numeric values: `{ "CA": 12000, "TX": 8500 }`
1187
+ * - Tabular data rows with state and value fields (requires encoding)
1188
+ */
1189
+ data: Record<string, number | null> | DataRow[];
1190
+ /**
1191
+ * Encoding channels mapping data fields to visual properties.
1192
+ * Required when data is DataRow[]. Auto-generated when data is a record map.
1193
+ */
1194
+ encoding?: TileMapEncoding;
1195
+ /** Sequential color palette. Defaults to 'blue'. */
1196
+ palette?: TileMapPalette;
1197
+ /** Editorial chrome (title, subtitle, source, byline, footer). */
1198
+ chrome?: Chrome;
1199
+ /** Legend display configuration. */
1200
+ legend?: LegendConfig;
1201
+ /** Theme configuration overrides. */
1202
+ theme?: ThemeConfig;
1203
+ /** Dark mode behavior. Defaults to "off". */
1204
+ darkMode?: DarkMode;
1205
+ /** Whether to show the tryOpenData.ai watermark. Defaults to true. */
1206
+ watermark?: boolean;
1207
+ /** Animation configuration for entrance animations. */
1208
+ animation?: AnimationSpec;
1209
+ /**
1210
+ * d3-format string applied to tile values, legend labels, and tooltips.
1211
+ * Examples: ".1f" for one decimal, "$,.0f" for currency, "~s" for SI.
1212
+ */
1213
+ valueFormat?: string;
1214
+ }
1215
+
1123
1216
  /**
1124
1217
  * Top-level visualization spec: union discriminated by structural shape.
1125
1218
  *
@@ -1128,8 +1221,9 @@ export interface SankeySpec {
1128
1221
  * - TableSpec: has `type: 'table'`
1129
1222
  * - GraphSpec: has `type: 'graph'`
1130
1223
  * - SankeySpec: has `type: 'sankey'`
1224
+ * - TileMapSpec: has `type: 'tilemap'`
1131
1225
  */
1132
- export type VizSpec = ChartSpec | LayerSpec | TableSpec | GraphSpec | SankeySpec;
1226
+ export type VizSpec = ChartSpec | LayerSpec | TableSpec | GraphSpec | SankeySpec | TileMapSpec;
1133
1227
 
1134
1228
  /** Chart spec without runtime data, for persistence/storage. */
1135
1229
  export type ChartSpecWithoutData = Omit<ChartSpec, 'data'>;
@@ -1139,12 +1233,15 @@ export type TableSpecWithoutData = Omit<TableSpec, 'data' | 'columns'>;
1139
1233
  export type GraphSpecWithoutData = Omit<GraphSpec, 'nodes' | 'edges'>;
1140
1234
  /** Sankey spec without runtime data, for persistence/storage. */
1141
1235
  export type SankeySpecWithoutData = Omit<SankeySpec, 'data'>;
1236
+ /** TileMap spec without runtime data, for persistence/storage. */
1237
+ export type TileMapSpecWithoutData = Omit<TileMapSpec, 'data'>;
1142
1238
  /** Union of data-stripped spec types for persistence/storage. */
1143
1239
  export type StoredVizSpec =
1144
1240
  | ChartSpecWithoutData
1145
1241
  | TableSpecWithoutData
1146
1242
  | GraphSpecWithoutData
1147
- | SankeySpecWithoutData;
1243
+ | SankeySpecWithoutData
1244
+ | TileMapSpecWithoutData;
1148
1245
 
1149
1246
  // ---------------------------------------------------------------------------
1150
1247
  // Transforms (Vega-Lite aligned)
@@ -1165,6 +1262,13 @@ export interface LogicalNot<T> {
1165
1262
  not: T;
1166
1263
  }
1167
1264
 
1265
+ /** A relative-time reference that resolves against the data extent. */
1266
+ export interface RelativeTimeRef {
1267
+ anchor: 'max' | 'min';
1268
+ offset: number;
1269
+ unit: 'day' | 'week' | 'month' | 'quarter' | 'year';
1270
+ }
1271
+
1168
1272
  /** A predicate that tests a field value against a condition. */
1169
1273
  export interface FieldPredicate {
1170
1274
  /** Data field to test. */
@@ -1172,15 +1276,15 @@ export interface FieldPredicate {
1172
1276
  /** Equals comparison. */
1173
1277
  equal?: unknown;
1174
1278
  /** Less than. */
1175
- lt?: number;
1279
+ lt?: number | RelativeTimeRef;
1176
1280
  /** Less than or equal. */
1177
- lte?: number;
1281
+ lte?: number | RelativeTimeRef;
1178
1282
  /** Greater than. */
1179
- gt?: number;
1283
+ gt?: number | RelativeTimeRef;
1180
1284
  /** Greater than or equal. */
1181
- gte?: number;
1285
+ gte?: number | RelativeTimeRef;
1182
1286
  /** Inclusive range [min, max]. */
1183
- range?: [number, number];
1287
+ range?: [number | RelativeTimeRef, number | RelativeTimeRef];
1184
1288
  /** Value is one of these. */
1185
1289
  oneOf?: unknown[];
1186
1290
  /** Whether the value is valid (non-null, non-undefined, non-NaN). */
@@ -1286,6 +1390,33 @@ export interface FoldTransform {
1286
1390
  as?: [string, string];
1287
1391
  }
1288
1392
 
1393
+ /** Window operation types for computing values relative to other rows. */
1394
+ export type WindowOp = 'lag' | 'lead' | 'diff' | 'pct_change' | 'cumsum' | 'rank' | 'first_value';
1395
+
1396
+ /** Sort field definition for window transforms. */
1397
+ export interface WindowSortField {
1398
+ field: string;
1399
+ order?: 'ascending' | 'descending';
1400
+ }
1401
+
1402
+ /** Window field definition specifying which operation to compute. */
1403
+ export interface WindowFieldDef {
1404
+ op: WindowOp;
1405
+ field: string;
1406
+ /** Row offset for lag/lead/diff/pct_change. Defaults to 1. */
1407
+ offset?: number;
1408
+ as: string;
1409
+ }
1410
+
1411
+ /** Window transform: computes values relative to other rows in sort order within a partition. */
1412
+ export interface WindowTransform {
1413
+ window: WindowFieldDef[];
1414
+ /** Fields to sort by within each partition. */
1415
+ sort: WindowSortField[];
1416
+ /** Fields to partition (group) by. Each group is windowed independently. */
1417
+ groupby?: string[];
1418
+ }
1419
+
1289
1420
  /** Discriminated union of all transform types. */
1290
1421
  export type Transform =
1291
1422
  | FilterTransform
@@ -1293,7 +1424,8 @@ export type Transform =
1293
1424
  | CalculateTransform
1294
1425
  | TimeUnitTransform
1295
1426
  | AggregateTransform
1296
- | FoldTransform;
1427
+ | FoldTransform
1428
+ | WindowTransform;
1297
1429
 
1298
1430
  // ---------------------------------------------------------------------------
1299
1431
  // Conditional encoding (Vega-Lite aligned)
@@ -1412,6 +1544,11 @@ export function isSankeySpec(spec: VizSpec | Record<string, unknown>): spec is S
1412
1544
  return 'type' in spec && (spec as Record<string, unknown>).type === 'sankey';
1413
1545
  }
1414
1546
 
1547
+ /** Check if a spec is a TileMapSpec. */
1548
+ export function isTileMapSpec(spec: VizSpec | Record<string, unknown>): spec is TileMapSpec {
1549
+ return 'type' in spec && (spec as Record<string, unknown>).type === 'tilemap';
1550
+ }
1551
+
1415
1552
  // ---------------------------------------------------------------------------
1416
1553
  // Annotation type guards
1417
1554
  // ---------------------------------------------------------------------------