Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(v2/column): extract common interval geometry #1391

Merged
merged 2 commits into from
Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions __tests__/unit/plots/column/index-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ describe('column', () => {
yField: 'sales',
});
expect(geometry.getAdjust('stack')).toBeUndefined();
expect(geometry.getAttribute('color')?.getFields()).toEqual(['series']);
});

it('grouped column /w groupField', () => {
Expand All @@ -112,6 +113,7 @@ describe('column', () => {
yField: 'sales',
});
expect(geometry.getAdjust('stack')).toBeUndefined();
expect(geometry.getAttribute('color')?.getFields()).toEqual(['series']);
});

it('grouped column /w seriesField', () => {
Expand All @@ -133,6 +135,7 @@ describe('column', () => {
yField: 'sales',
});
expect(geometry.getAdjust('stack')).toBeUndefined();
expect(geometry.getAttribute('color')?.getFields()).toEqual(['series']);
});

it('stacked column', () => {
Expand All @@ -154,6 +157,7 @@ describe('column', () => {
xField: 'area',
yField: 'sales',
});
expect(geometry.getAttribute('color')?.getFields()).toEqual(['series']);
});

it('stacked column /w stackField', () => {
Expand All @@ -175,6 +179,7 @@ describe('column', () => {
xField: 'area',
yField: 'sales',
});
expect(geometry.getAttribute('color')?.getFields()).toEqual(['series']);
});

it('stacked column /w seriesField', () => {
Expand All @@ -196,6 +201,7 @@ describe('column', () => {
xField: 'area',
yField: 'sales',
});
expect(geometry.getAttribute('color')?.getFields()).toEqual(['series']);
});

it('grouped column columnWidthRatio/marginRatio', () => {
Expand Down
1 change: 1 addition & 0 deletions src/adaptor/geometries/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { area, AreaGeometryOptions } from './area';
export { line, LineGeometryOptions } from './line';
export { point, PointGeometryOptions } from './point';
export { interval, IntervalGeometryOptions } from './interval';
96 changes: 96 additions & 0 deletions src/adaptor/geometries/interval.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { isNil, isFunction } from '@antv/util';
import { Params } from '../../core/adaptor';
import { Options } from '../../types';
import { ShapeStyle } from '../../types/style';

export interface IntervalGeometryOptions extends Options {
/** x 轴字段 */
readonly xField: string;
/** y 轴字段 */
readonly yField: string;
/** 颜色字段,可选 */
readonly colorField?: string;
/** 拆分字段,在分组柱状图下同 groupField、colorField,在堆积柱状图下同 stackField、colorField */
readonly seriesField?: string;
/** 是否分组柱形图 */
readonly isGroup?: boolean;
/** 分组拆分字段 */
readonly groupField?: string;
/** 是否堆积柱状图 */
readonly isStack?: boolean;
/** 堆积拆分字段 */
readonly stackField?: string;
/** 柱子样式配置 */
readonly interval?: {
/** 柱状图宽度占比 [0-1] */
readonly widthRatio?: number;
/** 分组中柱子之间的间距 [0-1],仅对分组柱状图适用 */
readonly marginRatio?: number;
/** 柱子样式配置,可选 */
readonly style?: ShapeStyle | ((x: any, y: any, color?: any) => ShapeStyle);
};
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 可以把 interval 单独抽出成一个 type 吗,类似这种 https://github.com/antvis/G2Plot/blob/v2_feat_combo/src/adaptor/geometries/line.ts
  2. 这个配置应该是已经确定了吧,isGroup, groupField 等
  3. 其他的可以满足需求

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interval 就是一个单独的 geometry type 了,看48行

function getGroupField(params: Params<IntervalGeometryOptions>): string {
const { options } = params;
const { groupField, seriesField, colorField } = options;

return groupField || seriesField || colorField;
}

function getStackField(params: Params<IntervalGeometryOptions>): string {
const { options } = params;
const { stackField, seriesField, colorField } = options;

return stackField || seriesField || colorField;
}
Copy link
Member

@hustcc hustcc Aug 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这两个属于 util 方法,放到 plots/bar/ 中?如果外面不需要用,就不 export 出去,作为这个文件的内部方法

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

外部现在不需要,那去掉 export 了


export function interval<O extends IntervalGeometryOptions>(params: Params<O>): Params<O> {
const { chart, options } = params;
const { xField, yField, colorField, color, isGroup, isStack, interval } = options;
let realColorField = colorField;

if (interval) {
const { marginRatio, widthRatio, style } = interval;
const geometry = chart.interval().position(`${xField}*${yField}`);

// field
if (isGroup) {
realColorField = getGroupField(params);
geometry.color(realColorField, color);
geometry.adjust({
type: 'dodge',
marginRatio,
});
} else if (isStack) {
realColorField = getStackField(params);
geometry.color(getStackField(params), color);
geometry.adjust({
type: 'stack',
marginRatio,
});
} else {
if (colorField) {
geometry.color(colorField, color);
}
}

// widthRatio
if (!isNil(widthRatio)) {
chart.theme({
columnWidthRatio: widthRatio,
});
}

// style
if (style) {
if (isFunction(style)) {
geometry.style(`${xField}*${yField}*${realColorField}`, style);
} else {
geometry.style(style);
}
}
}

return params;
}
99 changes: 24 additions & 75 deletions src/plots/column/adaptor.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,33 @@
import { deepMix, isFunction, isNil } from '@antv/util';
import { deepMix } from '@antv/util';
import { Params } from '../../core/adaptor';
import { findGeometry } from '../../common/helper';
import { tooltip, interaction, animation, theme } from '../../adaptor/common';
import { interval } from '../../adaptor/geometries';
import { flow, pick } from '../../utils';
import { ColumnOptions } from './types';
import { AXIS_META_CONFIG_KEYS } from '../../constant';

export function getGroupField(params: Params<ColumnOptions>): string {
const { options } = params;
const { groupField, seriesField, colorField } = options;

return groupField || seriesField || colorField;
}

export function getStackField(params: Params<ColumnOptions>): string {
const { options } = params;
const { stackField, seriesField, colorField } = options;

return stackField || seriesField || colorField;
}

/**
* 字段
* @param params
*/
function field(params: Params<ColumnOptions>): Params<ColumnOptions> {
function geometry(params: Params<ColumnOptions>): Params<ColumnOptions> {
const { chart, options } = params;
const { data, xField, yField, colorField, color, isGroup, isStack, marginRatio } = options;
const { data, columnStyle, columnWidthRatio, marginRatio } = options;

chart.data(data);
const geometry = chart.interval().position(`${xField}*${yField}`);

if (isGroup) {
geometry.color(getGroupField(params), color);
geometry.adjust({
type: 'dodge',
marginRatio,
});
} else if (isStack) {
geometry.color(getStackField(params), color);
geometry.adjust({
type: 'stack',
marginRatio,
});
} else {
if (colorField) {
geometry.color(colorField, color);
}
}
flow(interval)(
deepMix({}, params, {
options: {
interval: {
marginRatio,
widthRatio: columnWidthRatio,
style: columnStyle,
},
},
})
);

return params;
}
Expand Down Expand Up @@ -100,31 +80,17 @@ function axis(params: Params<ColumnOptions>): Params<ColumnOptions> {
*/
function legend(params: Params<ColumnOptions>): Params<ColumnOptions> {
const { chart, options } = params;
const { legend, colorField } = options;

if (legend && colorField) {
chart.legend(colorField, legend);
}

return params;
}

/**
* 样式
* @param params
*/
function style(params: Params<ColumnOptions>): Params<ColumnOptions> {
const { chart, options } = params;
const { xField, yField, colorField, columnStyle } = options;

const { legend } = options;
const geometry = findGeometry(chart, 'interval');
if (columnStyle && geometry) {
if (isFunction(columnStyle)) {
geometry.style(`${xField}*${yField}*${colorField}`, columnStyle);
} else {
geometry.style(columnStyle);
const colorAttribute = geometry.getAttribute('color');

if (legend && colorAttribute) {
const colorFields = colorAttribute.getFields();
if (colorFields.length > 0) {
chart.legend(colorFields[0], legend);
}
}

return params;
}

Expand Down Expand Up @@ -152,27 +118,10 @@ function label(params: Params<ColumnOptions>): Params<ColumnOptions> {
return params;
}

/**
* 柱形图额外的主题设置
* @param params
*/
function columnTheme(params: Params<ColumnOptions>): Params<ColumnOptions> {
const { chart, options } = params;
const { columnWidthRatio } = options;

if (!isNil(columnWidthRatio)) {
chart.theme({
columnWidthRatio,
});
}

return params;
}

/**
* 柱形图适配器
* @param params
*/
export function adaptor(params: Params<ColumnOptions>) {
return flow(field, meta, axis, legend, tooltip, theme, columnTheme, style, label, interaction, animation)(params);
return flow(geometry, meta, axis, legend, tooltip, theme, label, interaction, animation)(params);
}