Line data Source code
1 : import * as arrow from 'apache-arrow';
2 :
3 : import type { FieldType } from './chart_spec_paths.js';
4 :
5 : /// A column of the query result that the builder can encode
6 : export interface ChartColumn {
7 : name: string;
8 : /// The Vega-Lite type that the builder picks when the column is encoded
9 : type: FieldType;
10 : /// The spec encodes the column but the result has no such column
11 : missing?: boolean;
12 : }
13 :
14 : /// The Vega-Lite type of an Arrow type: numbers are quantitative, dates and times temporal, the rest nominal
15 1 : export function vegaLiteTypeOf(type: arrow.DataType): FieldType {
16 1 : switch (type.typeId) {
17 1 : case arrow.Type.Int:
18 1 : case arrow.Type.Int8:
19 1 : case arrow.Type.Int16:
20 1 : case arrow.Type.Int32:
21 1 : case arrow.Type.Int64:
22 1 : case arrow.Type.Uint8:
23 1 : case arrow.Type.Uint16:
24 1 : case arrow.Type.Uint32:
25 1 : case arrow.Type.Uint64:
26 1 : case arrow.Type.Float:
27 1 : case arrow.Type.Float16:
28 1 : case arrow.Type.Float32:
29 1 : case arrow.Type.Float64:
30 1 : case arrow.Type.Decimal:
31 1 : return 'quantitative';
32 1 : case arrow.Type.Date:
33 1 : case arrow.Type.DateDay:
34 1 : case arrow.Type.DateMillisecond:
35 1 : case arrow.Type.Timestamp:
36 1 : case arrow.Type.TimestampSecond:
37 1 : case arrow.Type.TimestampMillisecond:
38 1 : case arrow.Type.TimestampMicrosecond:
39 1 : case arrow.Type.TimestampNanosecond:
40 1 : case arrow.Type.Time:
41 1 : case arrow.Type.TimeSecond:
42 1 : case arrow.Type.TimeMillisecond:
43 1 : case arrow.Type.TimeMicrosecond:
44 1 : case arrow.Type.TimeNanosecond:
45 1 : return 'temporal';
46 1 : default:
47 1 : return 'nominal';
48 1 : }
49 1 : }
50 :
51 : /// The columns of the result, followed by the fields that the spec encodes but the result lacks.
52 : /// Columns of the system, e.g. the row numbers of the cross filter, are not in the result schema.
53 1 : export function chartColumns(schema: arrow.Schema | null, encodedFields: readonly string[]): ChartColumn[] {
54 1 : const columns: ChartColumn[] = (schema?.fields ?? []).map(field => ({ name: field.name, type: vegaLiteTypeOf(field.type) }));
55 : // Without a result, nothing is known to be missing
56 1 : if (schema == null) return encodedFields.map(name => ({ name, type: 'nominal' }));
57 1 : const names = new Set(columns.map(column => column.name));
58 1 : for (const name of encodedFields) {
59 1 : if (!names.has(name)) columns.push({ name, type: 'nominal', missing: true });
60 : }
61 1 : return columns;
62 1 : }
|