diff --git a/src/compile/mark/encode/nonposition.ts b/src/compile/mark/encode/nonposition.ts index df56da2fb2..aac6b2d447 100644 --- a/src/compile/mark/encode/nonposition.ts +++ b/src/compile/mark/encode/nonposition.ts @@ -6,6 +6,7 @@ import {getMarkPropOrConfig, signalOrValueRef} from '../../common'; import {UnitModel} from '../../unit'; import {wrapCondition} from './conditional'; import * as ref from './valueref'; +import {isRelativeBandSize} from '../../../mark'; /** * Return encode for non-positional channels with scales. (Text doesn't have scale.) @@ -24,11 +25,14 @@ export function nonPosition( let {defaultRef, defaultValue} = opt; if (defaultRef === undefined) { - // prettier-ignore - defaultValue ??= getMarkPropOrConfig(channel, markDef, config, {vgChannel, ignoreVgConfig: true}); + const markPropOrConfig = getMarkPropOrConfig(channel, markDef, config, {vgChannel, ignoreVgConfig: true}); + if (!isRelativeBandSize(markPropOrConfig)) { + // prettier-ignore + defaultValue ??= markPropOrConfig; - if (defaultValue !== undefined) { - defaultRef = signalOrValueRef(defaultValue); + if (defaultValue !== undefined) { + defaultRef = signalOrValueRef(defaultValue); + } } } diff --git a/src/compile/mark/encode/position-rect.ts b/src/compile/mark/encode/position-rect.ts index e34f54d62e..a2389d355e 100644 --- a/src/compile/mark/encode/position-rect.ts +++ b/src/compile/mark/encode/position-rect.ts @@ -18,7 +18,7 @@ import * as log from '../../../log'; import {BandSize, isRelativeBandSize} from '../../../mark'; import {hasDiscreteDomain} from '../../../scale'; import {isSignalRef, isVgRangeStep, VgEncodeEntry, VgValueRef} from '../../../vega.schema'; -import {getMarkConfig, getMarkPropOrConfig, signalOrStringValue, signalOrValueRef} from '../../common'; +import {getMarkConfig, getMarkPropOrConfig, signalOrStringValue} from '../../common'; import {ScaleComponent} from '../../scale/component'; import {UnitModel} from '../../unit'; import {nonPosition} from './nonposition'; @@ -158,18 +158,17 @@ function positionAndSize( : (orient === 'horizontal' && channel === 'y') || (orient === 'vertical' && channel === 'x'); // Use size encoding / mark property / config if it exists - let sizeMixins; - if (encoding.size || markDef.size) { + let sizeEncodingMixins; + + if (encoding.size) { if (useVlSizeChannel) { - sizeMixins = nonPosition('size', model, { - vgChannel: vgSizeChannel, - defaultRef: signalOrValueRef(markDef.size) + sizeEncodingMixins = nonPosition('size', model, { + vgChannel: vgSizeChannel }); } else { log.warn(log.message.cannotApplySizeToNonOrientedMark(markDef.type)); } } - const hasSizeFromMarkOrEncoding = !!sizeMixins; // Otherwise, apply default value const bandSize = getBandSize({ @@ -181,7 +180,7 @@ function positionAndSize( useVlSizeChannel }); - sizeMixins = sizeMixins || { + const sizeMixins = sizeEncodingMixins || { [vgSizeChannel]: defaultSizeRef( vgSizeChannel, offsetScaleName || scaleName, @@ -203,7 +202,7 @@ function positionAndSize( */ const defaultBandAlign = - (scale || offsetScale)?.get('type') === 'band' && isRelativeBandSize(bandSize) && !hasSizeFromMarkOrEncoding + (scale || offsetScale)?.get('type') === 'band' && isRelativeBandSize(bandSize) && !!sizeEncodingMixins ? 'top' : 'middle'; diff --git a/src/mark.ts b/src/mark.ts index f80f7b2ee7..ee1a8f457e 100644 --- a/src/mark.ts +++ b/src/mark.ts @@ -1,4 +1,14 @@ -import {Align, Color, Gradient, MarkConfig as VgMarkConfig, Orientation, SignalRef, TextBaseline} from 'vega'; +import { + Align, + Color, + Gradient, + MarkConfig as VgMarkConfig, + Orientation, + SignalRef, + TextBaseline, + LinearGradient, + RadialGradient +} from 'vega'; import {CompositeMark, CompositeMarkDef} from './compositemark'; import {ExprRef} from './expr'; import {Flag, keys} from './util'; @@ -128,7 +138,7 @@ export interface VLOnlyMarkConfig extends ColorM export interface MarkConfig extends VLOnlyMarkConfig, - MapExcludeValueRefAndReplaceSignalWith, ES> { + MapExcludeValueRefAndReplaceSignalWith, ES> { // ========== Overriding Vega ========== /** @@ -147,7 +157,7 @@ export interface MarkConfig /** * Default size for marks. * - For `point`/`circle`/`square`, this represents the pixel area of the marks. Note that this value sets the area of the symbol; the side lengths will increase with the square root of this value. - * - For `bar`, this represents the band size of the bar, in pixels. + * - For `bar`, this represents the band size of the bar, in pixels, or relative band size (e.g., `{"band": 0.5}` is half of the band). * - For `text`, this represents the font size, in pixels. * * __Default value:__ @@ -158,7 +168,7 @@ export interface MarkConfig * * @minimum 0 */ - size?: number | ES; // size works beyond symbol marks in VL + size?: number | ES | RelativeBandSize; // Unlike in VG where size is only for symbol marks (point in VL), size works beyond symbol marks in VL /** * X coordinates of the marks, or width of horizontal `"bar"` and `"area"` without specified `x2` or `width`. @@ -468,7 +478,9 @@ export interface RelativeBandSize { band: number; } -export function isRelativeBandSize(o: number | RelativeBandSize | ExprRef | SignalRef): o is RelativeBandSize { +export function isRelativeBandSize( + o: number | RelativeBandSize | ExprRef | SignalRef | string | LinearGradient | RadialGradient | number[] +): o is RelativeBandSize { return o && o['band'] != undefined; }