mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Chart builder: field-first shelf + value-or-field channels
This commit is contained in:
@@ -260,3 +260,81 @@ describe('createSnippet', () => {
|
||||
expect(useSnippetStore.getState().snippets).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('field-first assignment (assignField / focusChannel)', () => {
|
||||
test('a clicked field lands on the first empty channel that accepts it', () => {
|
||||
const id = seedDataset('Shop', [{ region: 'E', sales: 5, qty: 2 }]);
|
||||
cb().init(id); // region→X, count→Y (smart default for one category + measures)
|
||||
cb().setChannelColumn('x', null);
|
||||
cb().setChannelColumn('y', null);
|
||||
|
||||
cb().assignField('region'); // first empty channel is X
|
||||
expect(cb().config.encodings.x).toEqual({ field: 'region', type: 'nominal' });
|
||||
cb().assignField('sales'); // X taken → Y
|
||||
expect(cb().config.encodings.y).toEqual({ field: 'sales', type: 'quantitative' });
|
||||
});
|
||||
|
||||
test('the armed channel takes the field, then disarms', () => {
|
||||
const id = seedDataset('Shop', [{ region: 'E', sales: 5 }]);
|
||||
cb().init(id);
|
||||
cb().focusChannel('color');
|
||||
expect(cb().activeChannel).toBe('color');
|
||||
cb().assignField('region');
|
||||
expect(cb().config.encodings.color).toEqual({ field: 'region', type: 'nominal' });
|
||||
expect(cb().activeChannel).toBeNull(); // armed slot cleared after assignment
|
||||
});
|
||||
|
||||
test('skips a channel that cannot take the column (Size needs a measure)', () => {
|
||||
const id = seedDataset('Shop', [{ region: 'E', sales: 5 }]);
|
||||
cb().init(id);
|
||||
cb().focusChannel('size');
|
||||
cb().assignField('region'); // a category can't go on Size → falls through to an empty axis
|
||||
expect(cb().config.encodings.size ?? null).toBeNull();
|
||||
// It landed on the first axis that accepts it instead of being dropped.
|
||||
const onAxis =
|
||||
cb().config.encodings.x?.field === 'region' || cb().config.encodings.y?.field === 'region';
|
||||
expect(onAxis).toBe(true);
|
||||
});
|
||||
|
||||
test('Count of records assigns as a field-less count measure', () => {
|
||||
const id = seedDataset('Shop', [{ region: 'E', sales: 5 }]);
|
||||
cb().init(id);
|
||||
cb().setChannelColumn('x', null);
|
||||
cb().setChannelColumn('y', null);
|
||||
cb().focusChannel('y');
|
||||
cb().assignField(COUNT_FIELD);
|
||||
expect(cb().config.encodings.y).toEqual({ type: 'quantitative', aggregate: 'count' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('constant values (setChannelConstant — the Property model)', () => {
|
||||
test('sets a fixed colour on Color, emitted as a constant', () => {
|
||||
const id = seedDataset('Shop', [{ region: 'E', sales: 5 }]);
|
||||
cb().init(id);
|
||||
cb().setChannelConstant('color', '#c0392b');
|
||||
expect(cb().config.encodings.color).toMatchObject({ value: '#c0392b' });
|
||||
});
|
||||
|
||||
test('coerces a Size constant to a number', () => {
|
||||
const id = seedDataset('Shop', [{ region: 'E', sales: 5 }]);
|
||||
cb().init(id);
|
||||
cb().setChannelConstant('size', '120');
|
||||
expect(cb().config.encodings.size?.value).toBe(120);
|
||||
});
|
||||
|
||||
test('preserves the prior field type so toggling back to a field restores it', () => {
|
||||
const id = seedDataset('Shop', [{ region: 'E', sales: 5 }]);
|
||||
cb().init(id);
|
||||
cb().setChannelColumn('color', 'region'); // nominal field
|
||||
cb().setChannelConstant('color', '#000000');
|
||||
expect(cb().config.encodings.color).toEqual({ value: '#000000', type: 'nominal' });
|
||||
});
|
||||
|
||||
test('refuses a constant on a positional channel (X/Y stay field-only)', () => {
|
||||
const id = seedDataset('Shop', [{ region: 'E', sales: 5 }]);
|
||||
cb().init(id);
|
||||
const before = cb().config.encodings.x;
|
||||
cb().setChannelConstant('x', '50');
|
||||
expect(cb().config.encodings.x).toBe(before); // unchanged — no-op
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user