Skip to content

Commit

Permalink
fix(#1870): when y are same in dual-axes, axis position is wrong (#1878)
Browse files Browse the repository at this point in the history
* fix(#1870): when y are same in dual-axes, axis position is wrong

* chore: update type define

* test: inc coverage

* fix: cr
  • Loading branch information
hustcc authored Nov 9, 2020
1 parent d88a3fa commit 4e7e022
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 69 deletions.
92 changes: 92 additions & 0 deletions __tests__/bugs/issue-1870-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { DualAxes } from '../../src';
import { createDiv } from '../utils/dom';

const uvBillData = [
{ time: '2019-03', value: 350, type: 'uv' },
{ time: '2019-04', value: 900, type: 'uv' },
{ time: '2019-05', value: 300, type: 'uv' },
{ time: '2019-06', value: 450, type: 'uv' },
{ time: '2019-07', value: 470, type: 'uv' },
{ time: '2019-03', value: 220, type: 'bill' },
{ time: '2019-04', value: 300, type: 'bill' },
{ time: '2019-05', value: 250, type: 'bill' },
{ time: '2019-06', value: 220, type: 'bill' },
{ time: '2019-07', value: 362, type: 'bill' },
];

const transformData = [
{ time: '2019-03', value: 800, name: 'a' },
{ time: '2019-04', value: 600, name: 'a' },
{ time: '2019-05', value: 400, name: 'a' },
{ time: '2019-06', value: 380, name: 'a' },
{ time: '2019-07', value: 220, name: 'a' },
{ time: '2019-03', value: 750, name: 'b' },
{ time: '2019-04', value: 650, name: 'b' },
{ time: '2019-05', value: 450, name: 'b' },
{ time: '2019-06', value: 400, name: 'b' },
{ time: '2019-07', value: 320, name: 'b' },
{ time: '2019-03', value: 900, name: 'c' },
{ time: '2019-04', value: 600, name: 'c' },
{ time: '2019-05', value: 450, name: 'c' },
{ time: '2019-06', value: 300, name: 'c' },
{ time: '2019-07', value: 200, name: 'c' },
];

describe('#1870', () => {
it('1870', () => {
const dualAxes = new DualAxes(createDiv(), {
data: [uvBillData, transformData],
xField: 'time',
yField: ['value', 'value'],
geometryOptions: [
{
geometry: 'column',
isGroup: true,
seriesField: 'type',
columnWidthRatio: 0.4,
color: ['#5B8FF9', '#5AD8A6'],
},
{
geometry: 'line',
seriesField: 'name',
color: ['#CDDDFD', '#CDF3E4', '#CED4DE'],
lineStyle: ({ name }) => {
if (name === 'a') {
return {
lineDash: [2, 2],
opacity: 1,
};
}
return {
opacity: 0.5,
};
},
},
],
});

dualAxes.render();

// @ts-ignore
expect(dualAxes.chart.views[0].getOptions().axes.value).toEqual({
label: {
autoHide: true,
autoRotate: false,
},
nice: true,
position: 'left',
});
// @ts-ignore
expect(dualAxes.chart.views[1].getOptions().axes.value).toEqual({
label: {
autoHide: true,
autoRotate: false,
},
nice: true,
grid: null,
position: 'right',
});

dualAxes.destroy();
});
});
73 changes: 46 additions & 27 deletions __tests__/unit/plots/dual-axes/util/option-spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { isLine, isColumn, getGeometryOption, getDefaultYAxis } from '../../../../../src/plots/dual-axes/util/option';

import {
isLine,
isColumn,
getGeometryOption,
getCompatibleYAxis,
getYAxisWithDefault,
} from '../../../../../src/plots/dual-axes/util/option';
import { AxisType } from '../../../../../src/plots/dual-axes/types';

const DEFAULT_LEFT_YAXIS_CONFIG = {
Expand Down Expand Up @@ -32,42 +37,56 @@ describe('DualAxes option', () => {
expect(isColumn({ geometry: 'column' })).toBe(true);
});

it('getDefaultYAxis', () => {
expect(getDefaultYAxis(['yField1', 'yField2'], undefined)).toEqual({
yField1: DEFAULT_LEFT_YAXIS_CONFIG,
yField2: DEFAULT_RIGHT_YAXIS_CONFIG,
it('getCompatibleYAxis', () => {
expect(getCompatibleYAxis(['yField1', 'yField2'], undefined)).toEqual({
yField1: undefined,
yField2: undefined,
});
});
it('yAxis option', () => {
expect(getDefaultYAxis(['yField1', 'yField2'], {})).toEqual({
yField1: DEFAULT_LEFT_YAXIS_CONFIG,
yField2: DEFAULT_RIGHT_YAXIS_CONFIG,

expect(getCompatibleYAxis(['yField1', 'yField2'], [{ nice: false }])).toEqual({
yField1: { nice: false },
yField2: undefined,
});

// @ts-ignore
expect(getDefaultYAxis(['yField1', 'yField2'], { yField1: { a: 1 }, yField2: false })).toEqual({
yField1: {
...DEFAULT_LEFT_YAXIS_CONFIG,
a: 1,
},
yField2: false,
expect(getCompatibleYAxis(['yField1', 'yField2'], [false])).toEqual({
yField1: false,
yField2: undefined,
});

expect(getDefaultYAxis(['yField1', 'yField2'], [])).toEqual({
yField1: DEFAULT_LEFT_YAXIS_CONFIG,
yField2: DEFAULT_RIGHT_YAXIS_CONFIG,
expect(getCompatibleYAxis(['yField1', 'yField2'], { yField1: { nice: true } })).toEqual({
yField1: { nice: true },
yField2: undefined,
});

// @ts-ignore
expect(getDefaultYAxis(['yField1', 'yField2'], [{ a: 1 }, false])).toEqual({
yField1: {
...DEFAULT_LEFT_YAXIS_CONFIG,
a: 1,
},
expect(getCompatibleYAxis(['yField1', 'yField2'], { yField1: { nice: true }, yField2: false })).toEqual({
yField1: { nice: true },
yField2: false,
});
});

it('getDefaultYAxis', () => {
expect(getYAxisWithDefault(undefined, AxisType.Left)).toEqual(DEFAULT_LEFT_YAXIS_CONFIG);
expect(getYAxisWithDefault({}, AxisType.Left)).toEqual(DEFAULT_LEFT_YAXIS_CONFIG);
expect(getYAxisWithDefault(false, AxisType.Left)).toBe(false);
expect(getYAxisWithDefault({ type: 'cat' }, AxisType.Left)).toEqual({ ...DEFAULT_LEFT_YAXIS_CONFIG, type: 'cat' });
expect(getYAxisWithDefault({ nice: false }, AxisType.Left)).toEqual({ ...DEFAULT_LEFT_YAXIS_CONFIG, nice: false });

expect(getYAxisWithDefault(undefined, AxisType.Right)).toEqual(DEFAULT_RIGHT_YAXIS_CONFIG);
expect(getYAxisWithDefault({}, AxisType.Right)).toEqual(DEFAULT_RIGHT_YAXIS_CONFIG);
expect(getYAxisWithDefault(false, AxisType.Right)).toBe(false);
expect(getYAxisWithDefault({ type: 'cat' }, AxisType.Right)).toEqual({
...DEFAULT_RIGHT_YAXIS_CONFIG,
type: 'cat',
});
expect(getYAxisWithDefault({ nice: false }, AxisType.Right)).toEqual({
...DEFAULT_RIGHT_YAXIS_CONFIG,
nice: false,
});

// @ts-ignore
expect(getYAxisWithDefault({ type: 'log' }, 'xxx')).toEqual({ type: 'log' });
});

it('getGeometryOption', () => {
expect(getGeometryOption('test', 'yField1', undefined, AxisType.Left)).toEqual({
geometry: 'line',
Expand Down
10 changes: 5 additions & 5 deletions src/plots/dual-axes/adaptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import {
} from '../../adaptor/common';
import { percent } from '../../utils/transform/percent';
import { Params } from '../../core/adaptor';
import { Datum } from '../../types';
import { flow, deepAssign } from '../../utils';
import { findViewById } from '../../utils/view';
import { Datum } from '../../types';
import { isColumn, getDefaultYAxis, getGeometryOption } from './util/option';
import { isColumn, getYAxisWithDefault, getGeometryOption, getCompatibleYAxis } from './util/option';
import { getViewLegendItems } from './util/legend';
import { drawSingleGeometry } from './util/geometry';
import { DualAxesOptions, AxisType, DualAxesGeometry } from './types';
Expand Down Expand Up @@ -55,7 +55,7 @@ export function transformOptions(params: Params<DualAxesOptions>): Params<DualAx
? [{ type: 'legend-visible-filter' }, { type: 'active-region' }]
: [{ type: 'legend-visible-filter' }],
// yAxis
yAxis: getDefaultYAxis(yField, options.yAxis),
yAxis: getCompatibleYAxis(yField, options.yAxis),
// geometryOptions
geometryOptions: [
getGeometryOption(xField, yField[0], geometryOptions[0], AxisType.Left),
Expand Down Expand Up @@ -152,11 +152,11 @@ export function axis(params: Params<DualAxesOptions>): Params<DualAxesOptions> {

// 左 View
leftView.axis(xField, xAxis);
leftView.axis(yField[0], yAxis[yField[0]]);
leftView.axis(yField[0], getYAxisWithDefault(yAxis[yField[0]], AxisType.Left));

// 右 Y 轴
rightView.axis(xField, false);
rightView.axis(yField[1], yAxis[yField[1]]);
rightView.axis(yField[1], getYAxisWithDefault(yAxis[yField[1]], AxisType.Right));

return params;
}
Expand Down
19 changes: 19 additions & 0 deletions src/plots/dual-axes/constant.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,21 @@
export const LEFT_AXES_VIEW = 'left-axes-view';
export const RIGHT_AXES_VIEW = 'right-axes-view';

export const DEFAULT_YAXIS_CONFIG = {
nice: true,
label: {
autoHide: true,
autoRotate: false,
},
};

export const DEFAULT_LEFT_YAXIS_CONFIG = {
...DEFAULT_YAXIS_CONFIG,
position: 'left',
};

export const DEFAULT_RIGHT_YAXIS_CONFIG = {
...DEFAULT_YAXIS_CONFIG,
position: 'right',
grid: null,
};
21 changes: 17 additions & 4 deletions src/plots/dual-axes/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,27 @@ export type GeometryColumnOption = Pick<
export type GeometryOption = GeometryColumnOption | GeometryLineOption;

export type DualAxesOptions = Omit<Options, 'data' | 'yAxis' | 'color'> & {
// 通用数据配置
/** 具体的数据 */
/**
* 具体的数据,左右两边的数据
*/
readonly data: Array<Record<string, any>[]>;

/**
* 双轴图的 x 字段,x 字段名称需要保持一致
*/
readonly xField: string;
/**
* 双轴图左右 y 字段,需要不一致
*/
readonly yField: string[];

readonly geometryOptions?: GeometryOption[];
/**
* 左右两边的 yAxis 配置,使用 object 的方式,key 为 y 字段名,或者数组分别表示左右
*/
readonly yAxis?: Options['yAxis'][] | Record<string, Options['yAxis']>;

readonly yAxis?: Record<string, Options['yAxis']> | Options['yAxis'][];
/**
* 左右两边的图形配置
*/
readonly geometryOptions?: GeometryOption[];
};
60 changes: 27 additions & 33 deletions src/plots/dual-axes/util/option.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { get, isArray } from '@antv/util';
import { Axis } from '../../../types/axis';
import { deepAssign } from '../../../utils';
import {
DualAxesOptions,
Expand All @@ -8,6 +9,7 @@ import {
GeometryColumnOption,
AxisType,
} from '../types';
import { DEFAULT_LEFT_YAXIS_CONFIG, DEFAULT_RIGHT_YAXIS_CONFIG } from '../constant';

/**
* 根据 GeometryOption 判断 geometry 是否为 line
Expand Down Expand Up @@ -58,43 +60,35 @@ export function getGeometryOption(
};
}

export function getDefaultYAxis(
/**
* 兼容 yAxis 为 arr 和 obj 的两种情况
* @param yField
* @param yAxis
*/
export function getCompatibleYAxis(
yField: DualAxesOptions['yField'],
yAxis: DualAxesOptions['yAxis']
yAxis: Record<string, Axis> | Axis[]
): DualAxesOptions['yAxis'] {
const DEFAULT_YAXIS_CONFIG = {
nice: true,
label: {
autoHide: true,
autoRotate: false,
},
};

const DEFAULT_LEFT_YAXIS_CONFIG = {
...DEFAULT_YAXIS_CONFIG,
position: 'left',
};

const DEFAULT_RIGHT_YAXIS_CONFIG = {
...DEFAULT_YAXIS_CONFIG,
position: 'right',
grid: null,
};

const [y1, y2] = yField;
if (isArray(yAxis)) {
console.warn('yAxis should be object.');
return {
[yField[0]]: yAxis[0] !== false ? deepAssign({}, DEFAULT_LEFT_YAXIS_CONFIG, yAxis[0]) : false,
[yField[1]]: yAxis[1] !== false ? deepAssign({}, DEFAULT_RIGHT_YAXIS_CONFIG, yAxis[1]) : false,
};
return { [y1]: yAxis[0], [y2]: yAxis[1] };
}

return deepAssign(
{},
{
[yField[0]]: DEFAULT_LEFT_YAXIS_CONFIG,
[yField[1]]: DEFAULT_RIGHT_YAXIS_CONFIG,
},
yAxis
);
// 追加默认值
return deepAssign({ [y1]: undefined, [y2]: undefined }, yAxis);
}

/**
* 获取默认值
* @param yAxis
* @param axisType
*/
export function getYAxisWithDefault(yAxis: Axis, axisType: AxisType): Axis {
if (axisType === AxisType.Left) {
return yAxis === false ? false : deepAssign({}, DEFAULT_LEFT_YAXIS_CONFIG, yAxis);
} else if (axisType === AxisType.Right) {
return yAxis === false ? false : deepAssign({}, DEFAULT_RIGHT_YAXIS_CONFIG, yAxis);
}
return yAxis;
}

0 comments on commit 4e7e022

Please sign in to comment.