Skip to content

Commit

Permalink
feat: support images on maps (#7296)
Browse files Browse the repository at this point in the history
  • Loading branch information
domoritz authored Apr 16, 2021
1 parent ca47eb1 commit 1dc77d4
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 5 deletions.
17 changes: 14 additions & 3 deletions src/compile/mark/encode/position-range.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {pointPosition, pointPositionDefaultRef} from './position-point';
import * as ref from './valueref';

/**
* Utility for area/rule position, which can be either point or range. (One of the axes should be point and the other should be range.)
* Utility for area/rule position, which can be either point or range.
* (One of the axes should be point and the other should be range.)
*/
export function pointOrRangePosition(
channel: 'x' | 'y',
Expand Down Expand Up @@ -87,8 +88,18 @@ function pointPosition2OrSize(
: getOffset(baseChannel, model.markDef);

if (!channelDef && (channel === 'x2' || channel === 'y2') && (encoding.latitude || encoding.longitude)) {
// use geopoint output if there are lat2/long2 and there is no point position2 overriding lat2/long2.
return {[vgChannel]: {field: model.getName(channel)}};
const vgSizeChannel = getSizeChannel(channel);

const size = model.markDef[vgSizeChannel];
if (size != null) {
return {
[vgSizeChannel]: {value: size}
};
} else {
return {
[vgChannel]: {field: model.getName(channel)}
};
}
}

const valueRef = position2Ref({
Expand Down
3 changes: 1 addition & 2 deletions src/compile/mark/encode/position-rect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export function rectPosition(
config
});
} else if (((isFieldOrDatumDef(channelDef) && hasDiscreteDomain(scaleType)) || isBarBand) && !channelDef2) {
return positionAndSize(mark, channelDef, channel, model);
return positionAndSize(channelDef, channel, model);
} else {
return rangePosition(channel, model, {defaultPos: 'zeroOrMax', defaultPos2: 'zeroOrMin'});
}
Expand Down Expand Up @@ -121,7 +121,6 @@ function defaultSizeRef(
* Output position encoding and its size encoding for continuous, point, and band scales.
*/
function positionAndSize(
mark: 'bar' | 'rect' | 'image' | 'arc',
fieldDef: Encoding<string>['x' | 'y' | 'theta' | 'radius'],
channel: 'x' | 'y' | 'theta' | 'radius',
model: UnitModel
Expand Down
70 changes: 70 additions & 0 deletions test/compile/mark/encode/position-range.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {getSizeChannel, X, Y} from '../../../../src/channel';
import {rangePosition} from '../../../../src/compile/mark/encode';
import {parseUnitModelWithScaleAndLayoutSize} from '../../../util';

describe('compile/mark/encode/position-range', () => {
it('should return correct position for lat/lng with size', () => {
const model = parseUnitModelWithScaleAndLayoutSize({
data: {
url: 'data/zipcodes.csv'
},
mark: {
type: 'image',
width: 42,
height: 42
},
encoding: {
longitude: {
field: 'longitude',
type: 'quantitative'
},
latitude: {
field: 'latitude',
type: 'quantitative'
}
}
});

[X, Y].forEach(channel => {
const mixins = rangePosition(channel, model, {defaultPos: 'zeroOrMin', defaultPos2: 'zeroOrMin'});
expect(mixins[channel + 'c']['field']).toEqual(model.getName(channel));

const sizeChannel = getSizeChannel(channel);
expect(mixins[sizeChannel]).toEqual({value: 42});
});
});

it('should return correct position for lat/lng with without size', () => {
const model = parseUnitModelWithScaleAndLayoutSize({
data: {
values: [
{
latitude: 0,
longitude: 0,
latitude2: 30,
longitude2: 30
},
{
latitude: -10,
longitude: -10,
latitude2: 20,
longitude2: 20
}
]
},
mark: 'rect',
encoding: {
longitude: {field: 'longitude', type: 'quantitative'},
latitude: {field: 'latitude', type: 'quantitative'},
longitude2: {field: 'longitude2'},
latitude2: {field: 'latitude2'}
}
});

[X, Y].forEach(channel => {
const mixins = rangePosition(channel, model, {defaultPos: 'zeroOrMin', defaultPos2: 'zeroOrMin'});
expect(mixins[channel]['field']).toEqual(model.getName(channel));
expect(mixins[channel + '2']['field']).toEqual(model.getName(channel + '2'));
});
});
});

0 comments on commit 1dc77d4

Please sign in to comment.