diff --git a/__tests__/integration/snapshots/static/peopleIntervalAreaDualAxis.png b/__tests__/integration/snapshots/static/peopleIntervalAreaDualAxis.png new file mode 100644 index 0000000000..3f43b395ed Binary files /dev/null and b/__tests__/integration/snapshots/static/peopleIntervalAreaDualAxis.png differ diff --git a/__tests__/plots/static/index.ts b/__tests__/plots/static/index.ts index 14d69ed96c..d037ebb756 100644 --- a/__tests__/plots/static/index.ts +++ b/__tests__/plots/static/index.ts @@ -100,6 +100,7 @@ export { monthIntervalFacetRect } from './month-interval-facet-rect'; export { monthIntervalRadialFacetRect } from './month-interval-radial-facet-rect'; export { weatherLineRepeatMatrixCol } from './weather-line-repeat-matrix-col'; export { weatherLineAreaDualAxis } from './weather-line-area-dual-axis'; +export { peopleIntervalAreaDualAxis } from './people-interval-area-dual-axis'; export { moviesIntervalMultipleMeasure } from './movies-interval-multiple-measure'; export { seattleWeatherCellSpaceFlex } from './seattle-weather-cell-space-flex'; export { salaryHeatmapScaleLinear } from './salary-heatmap-scale-linear'; diff --git a/__tests__/plots/static/people-interval-area-dual-axis.ts b/__tests__/plots/static/people-interval-area-dual-axis.ts new file mode 100644 index 0000000000..3e8bd84f55 --- /dev/null +++ b/__tests__/plots/static/people-interval-area-dual-axis.ts @@ -0,0 +1,62 @@ +import { G2Spec } from '../../../src'; + +export function peopleIntervalAreaDualAxis(): G2Spec { + return { + padding: 'auto', + type: 'view', + data: { + type: 'fetch', + value: 'data/population.csv', + transform: [ + { + type: 'filter', + callback: (d) => d.year === 2000, + }, + ], + }, + children: [ + { + type: 'area', + transform: [{ type: 'groupX', y: 'sum' }], + encode: { + x: 'age', + y: 'people', + }, + scale: { + y: { nice: true }, + }, + style: { + fill: '#85C5A6', + fillOpacity: 0.3, + }, + }, + { + type: 'interval', + encode: { + x: 'age', + y: (d) => (d.sex === 1 ? d.people : -d.people), + color: (d) => (d.sex === 1 ? 'male' : 'female'), + }, + scale: { + x: { type: 'band', padding: 0.7 }, + color: { + domain: ['male', 'female'], + range: ['#97e3d5', '#f47560'], + }, + }, + style: { + radius: 4, + }, + axis: { + y: { + grid: false, + title: 'People', + style: { + titleFill: 'steelblue', + }, + }, + }, + }, + ], + }; +} diff --git a/src/mark/area.ts b/src/mark/area.ts index 3e1adfee67..95ae13036c 100644 --- a/src/mark/area.ts +++ b/src/mark/area.ts @@ -39,20 +39,23 @@ export type AreaOptions = Omit; export const Area: MC = () => { return (index, scale, value, coordinate) => { const { x: X, y: Y, y1: Y1, series: S } = value; + const { x, y } = scale; // Group data by series field. const series = S ? Array.from(group(index, (i) => S[i]).values()) : [index]; const I = series.map((group) => group[0]).filter((i) => i !== undefined); // A group of data corresponds to one area. + const xoffset = (x?.getBandWidth?.() || 0) / 2; + const yoffset = (y?.getBandWidth?.() || 0) / 2; const P = Array.from(series, (SI) => { const l = SI.length; const points = new Array(l * 2); for (let idx = 0; idx < SI.length; idx++) { const i = SI[idx]; - points[idx] = coordinate.map([+X[i], +Y[i]]); // y1 - points[l + idx] = coordinate.map([+X[i], +Y1[i]]); // y0 + points[idx] = coordinate.map([+X[i] + xoffset, +Y[i] + yoffset]); // y1 + points[l + idx] = coordinate.map([+X[i] + xoffset, +Y1[i] + yoffset]); // y0 } return points;