/* * Constants and utilities for data. */ import {Vector2} from 'vega'; import {FieldName} from './channeldef.js'; import {VgData} from './vega.schema.js'; import {hasProperty} from './util.js'; export type ParseValue = null | string | 'string' | 'boolean' | 'date' | 'number'; export interface Parse { [field: string]: ParseValue; } export interface DataFormatBase { /** * If set to `null`, disable type inference based on the spec and only use type inference based on the data. * Alternatively, a parsing directive object can be provided for explicit data types. Each property of the object corresponds to a field name, and the value to the desired data type (one of `"number"`, `"boolean"`, `"date"`, or null (do not parse the field)). * For example, `"parse": {"modified_on": "date"}` parses the `modified_on` field in each input record a Date value. * * For `"date"`, we parse data based using JavaScript's [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse). * For Specific date formats can be provided (e.g., `{foo: "date:'%m%d%Y'"}`), using the [d3-time-format syntax](https://github.com/d3/d3-time-format#locale_format). UTC date format parsing is supported similarly (e.g., `{foo: "utc:'%m%d%Y'"}`). See more about [UTC time](https://vega.github.io/vega-lite/docs/timeunit.html#utc) */ parse?: Parse | null; /** * Type of input data: `"json"`, `"csv"`, `"tsv"`, `"dsv"`. * * __Default value:__ The default format type is determined by the extension of the file URL. * If no extension is detected, `"json"` will be used by default. */ type?: 'csv' | 'tsv' | 'dsv' | 'json' | 'topojson'; } export interface CsvDataFormat extends DataFormatBase { type?: 'csv' | 'tsv'; } export interface DsvDataFormat extends DataFormatBase { type?: 'dsv'; /** * The delimiter between records. The delimiter must be a single character (i.e., a single 16-bit code unit); so, ASCII delimiters are fine, but emoji delimiters are not. * * @minLength 1 * @maxLength 1 */ delimiter: string; } export interface JsonDataFormat extends DataFormatBase { type?: 'json'; /** * The JSON property containing the desired data. * This parameter can be used when the loaded JSON file may have surrounding structure or meta-data. * For example `"property": "values.features"` is equivalent to retrieving `json.values.features` * from the loaded JSON object. */ property?: string; } export interface TopoDataFormat extends DataFormatBase { type?: 'topojson'; /** * The name of the TopoJSON object set to convert to a GeoJSON feature collection. * For example, in a map of the world, there may be an object set named `"countries"`. * Using the feature property, we can extract this set and generate a GeoJSON feature object for each country. */ feature?: string; /** * The name of the TopoJSON object set to convert to mesh. * Similar to the `feature` option, `mesh` extracts a named TopoJSON object set. * Unlike the `feature` option, the corresponding geo data is returned as a single, unified mesh instance, not as individual GeoJSON features. * Extracting a mesh is useful for more efficiently drawing borders or other geographic elements that you do not need to associate with specific regions such as individual countries, states or counties. */ mesh?: string; } export type DataFormat = CsvDataFormat | DsvDataFormat | JsonDataFormat | TopoDataFormat; export type DataFormatType = 'json' | 'csv' | 'tsv' | 'dsv' | 'topojson'; export type DataSource = UrlData | InlineData | NamedData; export type Data = DataSource | Generator; export type InlineDataset = number[] | string[] | boolean[] | object[] | string | object; export interface DataBase { /** * An object that specifies the format for parsing the data. */ format?: DataFormat; /** * Provide a placeholder name and bind data at runtime. */ name?: string; } export interface UrlData extends DataBase { /** * An URL from which to load the data set. Use the `format.type` property * to ensure the loaded data is correctly parsed. */ url: string; } export interface InlineData extends DataBase { /** * The full data set, included inline. This can be an array of objects or primitive values, an object, or a string. * Arrays of primitive values are ingested as objects with a `data` property. Strings are parsed according to the specified format type. */ values: InlineDataset; } export interface NamedData extends DataBase { /** * Provide a placeholder name and bind data at runtime. * * New data may change the layout but Vega does not always resize the chart. To update the layout when the data updates, set [autosize](https://vega.github.io/vega-lite/docs/size.html#autosize) or explicitly use [view.resize](https://vega.github.io/vega/docs/api/view/#view_resize). */ name: string; } export function isUrlData(data: Partial | Partial): data is UrlData { return hasProperty(data, 'url'); } export function isInlineData(data: Partial | Partial): data is InlineData { return hasProperty(data, 'values'); } export function isNamedData(data: Partial | Partial): data is NamedData { return hasProperty(data, 'name') && !isUrlData(data) && !isInlineData(data) && !isGenerator(data); } export function isGenerator(data: Partial | Partial): data is Generator { return data && (isSequenceGenerator(data) || isSphereGenerator(data) || isGraticuleGenerator(data)); } export function isSequenceGenerator(data: Partial | Partial): data is SequenceGenerator { return hasProperty(data, 'sequence'); } export function isSphereGenerator(data: Partial | Partial): data is SphereGenerator { return hasProperty(data, 'sphere'); } export function isGraticuleGenerator(data: Partial | Partial): data is GraticuleGenerator { return hasProperty(data, 'graticule'); } export enum DataSourceType { Raw, /** Main data source for marks */ Main, Row, Column, Lookup, /** Pre-filter-invalid data source for scale domains */ PreFilterInvalid, /** Post-filter-invalid data source for scale domains */ PostFilterInvalid, } export type Generator = SequenceGenerator | SphereGenerator | GraticuleGenerator; export interface GeneratorBase { /** * Provide a placeholder name and bind data at runtime. */ name?: string; } export interface SequenceGenerator extends GeneratorBase { /** * Generate a sequence of numbers. */ sequence: SequenceParams; } export interface SequenceParams { /** * The starting value of the sequence (inclusive). */ start: number; /** * The ending value of the sequence (exclusive). */ stop: number; /** * The step value between sequence entries. * * __Default value:__ `1` */ step?: number; /** * The name of the generated sequence field. * * __Default value:__ `"data"` */ as?: FieldName; } export interface SphereGenerator extends GeneratorBase { /** * Generate sphere GeoJSON data for the full globe. */ sphere: true | object; } export interface GraticuleGenerator extends GeneratorBase { /** * Generate graticule GeoJSON data for geographic reference lines. */ graticule: true | GraticuleParams; } export interface GraticuleParams { /** * The major extent of the graticule as a two-element array of coordinates. */ extentMajor?: Vector2>; /** * The minor extent of the graticule as a two-element array of coordinates. */ extentMinor?: Vector2>; /** * Sets both the major and minor extents to the same values. */ extent?: Vector2>; /** * The major step angles of the graticule. * * * __Default value:__ `[90, 360]` */ stepMajor?: Vector2; /** * The minor step angles of the graticule. * * __Default value:__ `[10, 10]` */ stepMinor?: Vector2; /** * Sets both the major and minor step angles to the same values. */ step?: Vector2; /** * The precision of the graticule in degrees. * * __Default value:__ `2.5` */ precision?: number; }