From 209f41be57b675a0f9ab2c7b5c03c4bd1d6d2eba Mon Sep 17 00:00:00 2001 From: Kanit Wongsuphasawat Date: Thu, 6 Jul 2023 16:12:27 -0700 Subject: [PATCH] feat: support domainRaw so one may bind domainRaw to a parameter to build custom interaction --- ...nteractive_point_domainRaw_binding.vl.json | 40 +++++++++++++++++++ src/compile/scale/component.ts | 2 +- src/scale.ts | 10 +++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 examples/specs/interactive_point_domainRaw_binding.vl.json diff --git a/examples/specs/interactive_point_domainRaw_binding.vl.json b/examples/specs/interactive_point_domainRaw_binding.vl.json new file mode 100644 index 0000000000..1861553be8 --- /dev/null +++ b/examples/specs/interactive_point_domainRaw_binding.vl.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "data": {"url": "data/cars.json"}, + "params": [{ + "name": "min_x", + "value": 50, + "bind": { + "input": "range", + "min": 0, + "max": 300 + } + }, { + "name": "max_x", + "value": 250, + "bind": { + "input": "range", + "min": 0, + "max": 300 + } + },{ + "name": "use_custom_x", + "value": true, + "bind": { + "input": "checkbox" + } + }], + "mark": {"type": "circle", "clip": true}, + "encoding": { + "x": { + "field": "Horsepower", "type": "quantitative", + "scale": { + "domainRaw": {"expr": "use_custom_x ? [min_x, max_x] : null"} + } + }, + "y": { + "field": "Miles_per_Gallon", "type": "quantitative" + }, + "size": {"field": "Cylinders", "type": "quantitative"} + } +} diff --git a/src/compile/scale/component.ts b/src/compile/scale/component.ts index 62e5a9f16b..78ee720d63 100644 --- a/src/compile/scale/component.ts +++ b/src/compile/scale/component.ts @@ -11,7 +11,7 @@ import {Explicit, Split} from '../split'; * All VgDomain property except domain. * (We exclude domain as we have a special "domains" array that allow us merge them all at once in assemble.) */ -export type ScaleComponentProps = Omit & { +export type ScaleComponentProps = Omit & { domains: VgNonUnionDomain[]; selectionExtent?: ParameterExtent; reverse?: boolean | SignalRef; // Need override since Vega doesn't official support scale reverse yet (though it does in practice) diff --git a/src/scale.ts b/src/scale.ts index c90e7b1342..f97938c099 100644 --- a/src/scale.ts +++ b/src/scale.ts @@ -546,6 +546,13 @@ export interface Scale { | DomainUnionWith | ES; + /** + * An expression for an array of raw values that, if non-null, directly overrides the _domain_ property. + * This is useful for supporting interactions such as panning or zooming a scale. + * The scale may be initially determined using a data-driven domain, then modified in response to user input by setting the rawDomain value. + */ + domainRaw?: ES; + /** * Inserts a single mid-point value into a two-element domain. The mid-point value must lie between the domain minimum and maximum values. This property can be useful for setting a midpoint for [diverging color scales](https://vega.github.io/vega-lite/docs/scale.html#piecewise). The domainMid property is only intended for use with scales supporting continuous, piecewise domains. */ @@ -728,6 +735,7 @@ const SCALE_PROPERTY_INDEX: Flag> = { domainMax: 1, domainMin: 1, domainMid: 1, + domainRaw: 1, align: 1, range: 1, rangeMax: 1, @@ -785,6 +793,7 @@ export function scaleTypeSupportProperty(scaleType: ScaleType, propName: keyof S case 'domainMax': case 'domainMid': case 'domainMin': + case 'domainRaw': case 'clamp': return isContinuousToContinuous(scaleType); case 'nice': @@ -830,6 +839,7 @@ export function channelScalePropertyIncompatability(channel: Channel, propName: case 'domain': case 'domainMax': case 'domainMin': + case 'domainRaw': case 'range': case 'base': case 'exponent':