mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Chart builder: escape ./[/] in built field names
This commit is contained in:
@@ -27,6 +27,7 @@ import { DISTINCT_CAP } from './profile';
|
||||
import type { ColumnType } from './type-inference';
|
||||
import { VEGA_LITE_SCHEMA_URL } from './snippet';
|
||||
import { validateExpression } from './expr-validate';
|
||||
import { escapeVegaField } from './rendering';
|
||||
|
||||
/** The five mark types the builder offers, in selector order (spec §06). */
|
||||
export const MARK_TYPES = ['bar', 'line', 'point', 'area', 'circle'] as const;
|
||||
@@ -792,12 +793,12 @@ function coerceFilterValue(value: string, fieldType: FieldType): string | number
|
||||
* predicate in a `{ not }` (Vega-Lite has no bare inequality predicate).
|
||||
*/
|
||||
function predicateObject(filter: BuilderFilter): Record<string, unknown> | null {
|
||||
const { field, op } = filter;
|
||||
if (!field || !op) return null;
|
||||
// TODO: the data-derived column name reaches `field:` unescaped here, as it also
|
||||
// does in encodingObject. A column whose name contains `.`/`[`/`]` is then read as
|
||||
// a nested-property accessor rather than a literal field. core/rendering.ts exports
|
||||
// escapeVegaField for exactly this but nothing currently wires it into the builder.
|
||||
const { op } = filter;
|
||||
if (!filter.field || !op) return null;
|
||||
// Escape `.`/`[`/`]` so a column literally named e.g. `user.age` is read as that
|
||||
// field, not a nested-property accessor (same convention as encodingObject and the
|
||||
// renderer — docs/architecture/05 §4).
|
||||
const field = escapeVegaField(filter.field);
|
||||
const type = filter.fieldType ?? 'nominal';
|
||||
const value = filter.value ?? '';
|
||||
const coerce = (v: string) => coerceFilterValue(v, type);
|
||||
@@ -938,7 +939,9 @@ function encodingObject(mapping: ChannelMapping): Record<string, unknown> {
|
||||
return { aggregate: 'count', type: 'quantitative' };
|
||||
}
|
||||
const enc: Record<string, unknown> = {};
|
||||
if (mapping.field !== undefined) enc.field = mapping.field;
|
||||
// Escape `.`/`[`/`]` so a column literally named e.g. `user.age` is read as that
|
||||
// field, not a nested-property accessor (docs/architecture/05 §4).
|
||||
if (mapping.field !== undefined) enc.field = escapeVegaField(mapping.field);
|
||||
enc.type = mapping.type;
|
||||
if (mapping.aggregate) enc.aggregate = mapping.aggregate;
|
||||
if (mapping.bin) enc.bin = true;
|
||||
|
||||
Reference in New Issue
Block a user