@antv/g2plot
Version:
An interactive and responsive charting library
93 lines (88 loc) • 3.1 kB
text/typescript
import { groupBy } from '@antv/util';
import { Types } from '@antv/g2';
import { Datum } from '../../types';
import { BidirectionalBarOptions } from './types';
type TransformData = {
[key: string]: string | number;
}[];
/**
* bidirectional-bar 处理数据, 通过 SERIES_FIELD_KEY 字段分成左右数据
* @param xField
* @param yField
* @param data
*/
export function transformData(
xField: string,
yField: string[],
seriesField: string,
data: Datum,
reverse?: boolean
): Types.Data[] {
const hopeData: TransformData = [];
yField.forEach((d: string) => {
data.forEach((k: any) => {
const obj = {
[xField]: k[xField],
[seriesField]: d,
[d]: k[d],
};
hopeData.push(obj);
});
});
const groupData = Object.values(groupBy(hopeData, seriesField));
const [data1 = [], data2 = []] = groupData;
return reverse ? [data1.reverse(), data2.reverse()] : [data1, data2];
}
/**
* 是否横向,默认空为横向
* @param layout
*/
export function isHorizontal(layout: BidirectionalBarOptions['layout']) {
return layout !== 'vertical';
}
/**
* 多 view 进行同步 padding 的自定义逻辑
* @param chart
* @param views
* @param p
*/
export function syncViewPadding(chart: any, views: any, p: any) {
const [v1, v2] = views;
const p1 = v1.autoPadding;
const p2 = v2.autoPadding;
const { layout, position } = chart.__axisPosition;
// 目前只能根据布局的比例来判断 layout
if (isHorizontal(layout) && position === 'top') {
/**
* 保证 v1 的 left 和 v2 right 的间隔相等,因为 v1 有轴
* position top 即为 v1 左边,中间间距设置就为 0
*/
v1.autoPadding = p.instance(p1.top, 0, p1.bottom, p1.left);
v2.autoPadding = p.instance(p2.top, p1.left, p2.bottom, 0);
}
if (isHorizontal(layout) && position === 'bottom') {
/**
* 保证 v1 的 left 和 v2 right 的间隔相等,因为 v1 有轴
* position bottom 即为 v1 的右边,v1 right = right / 2 v2 left = right / 2
* + 5 是为了 让那个轴不要太贴近了,更好看
*/
v1.autoPadding = p.instance(p1.top, p1.right / 2 + 5, p1.bottom, p1.left);
v2.autoPadding = p.instance(p2.top, p2.right, p2.bottom, p1.right / 2 + 5);
}
if (!isHorizontal(layout) && position === 'bottom') {
/**
* 保证 v1 的 left 和 v2 left 的间隔相等 left 取最大值
* position bottom 即为 v1 下边,v1 bottom = bottom / 2 v2 top = bottom / 2
* + 5 是为了 让那个轴不要太贴近了,更好看
*/
const left = p1.left >= p2.left ? p1.left : p2.left;
v1.autoPadding = p.instance(p1.top, p1.right, p1.bottom / 2 + 5, left);
v2.autoPadding = p.instance(p1.bottom / 2 + 5, p2.right, p2.bottom, left);
}
// 垂直状态,不建议设置position 为 top, 还是做个兼容处理
if (!isHorizontal(layout) && position === 'top') {
const left = p1.left >= p2.left ? p1.left : p2.left;
v1.autoPadding = p.instance(p1.top, p1.right, 0, left);
v2.autoPadding = p.instance(0, p2.right, p1.top, left);
}
}