@antv/g2
Version:
the Grammar of Graphics in Javascript
129 lines (118 loc) • 4.39 kB
text/typescript
import { flatten, isString, valuesOfKey, isNil } from '@antv/util';
import { getXDimensionLength } from '../../util/coordinate';
// 已经排序后的数据查找距离最小的
function findMinDistance(arr, scale) {
const count = arr.length;
let sourceArr = arr;
if (isString(sourceArr[0])) {
// 日期类型的 values 经常上文本类型,所以需要转换一下
sourceArr = arr.map((v: string) => {
return scale.translate(v);
});
}
let distance = sourceArr[1] - sourceArr[0];
for (let i = 2; i < count; i++) {
const tmp = sourceArr[i] - sourceArr[i - 1];
if (distance > tmp) {
distance = tmp;
}
}
return distance;
}
function getDodgeCount(dataArray, dodgeBy) {
if (dodgeBy) {
const mergeData = flatten(dataArray);
const values = valuesOfKey(mergeData, dodgeBy);
return values.length;
}
return dataArray.length;
}
/** @ignore */
export function getDefaultSize(geometry): number {
const theme = geometry.theme;
const coordinate = geometry.coordinate;
const xScale = geometry.getXScale();
const xValues = xScale.values;
const dataArray = geometry.beforeMappingData;
let count: number = xValues.length;
const xDimensionLength = getXDimensionLength(geometry.coordinate);
// 获取柱宽相关配置项
const { intervalPadding, dodgePadding } = geometry;
// 兼容theme配置
const maxColumnWidth = geometry.maxColumnWidth || theme.maxColumnWidth;
const minColumnWidth = geometry.minColumnWidth || theme.minColumnWidth;
const columnWidthRatio = geometry.columnWidthRatio || theme.columnWidthRatio;
const multiplePieWidthRatio = geometry.multiplePieWidthRatio || theme.multiplePieWidthRatio;
const roseWidthRatio = geometry.roseWidthRatio || theme.roseWidthRatio;
// 线性情况下count值
if (xScale.isLinear && xValues.length > 1) {
// Linear 类型用户有可能设置了 min, max 范围所以需要根据数据最小区间计算 count
xValues.sort();
const interval = findMinDistance(xValues, xScale);
count = (xScale.max - xScale.min) / interval;
if (xValues.length > count) {
count = xValues.length;
}
}
const range = xScale.range;
let normalizedSize = 1 / count;
let wr = 1;
if (coordinate.isPolar) {
// 极坐标场景
if (coordinate.isTransposed && count > 1) {
// 极坐标下多层环图
wr = multiplePieWidthRatio;
} else {
wr = roseWidthRatio;
}
} else {
// 非极坐标场景
if (xScale.isLinear) {
normalizedSize *= range[1] - range[0];
}
wr = columnWidthRatio;
}
// 基础柱状图
if (!isNil(intervalPadding) && intervalPadding >= 0) {
// 配置组间距情况
const normalizedIntervalPadding = intervalPadding / xDimensionLength;
normalizedSize = (1 - (count - 1) * normalizedIntervalPadding) / count;
} else {
// 默认情况
normalizedSize *= wr;
}
// 分组柱状图
if (geometry.getAdjust('dodge')) {
const dodgeAdjust = geometry.getAdjust('dodge');
const dodgeBy = dodgeAdjust.dodgeBy;
const dodgeCount = getDodgeCount(dataArray, dodgeBy);
if (!isNil(dodgePadding) && dodgePadding >= 0) {
// 仅配置组内间距情况
const normalizedDodgePadding = dodgePadding / xDimensionLength;
normalizedSize = (normalizedSize - normalizedDodgePadding * (dodgeCount - 1)) / dodgeCount;
} else if (!isNil(intervalPadding) && intervalPadding >= 0) {
// 设置组间距但未设置组内间距情况,避免组间距过小导致图形重叠,需乘以wr
normalizedSize *= wr;
normalizedSize = normalizedSize / dodgeCount;
} else {
// 组间距和组内间距均未配置
normalizedSize = normalizedSize / dodgeCount;
}
normalizedSize = normalizedSize >= 0 ? normalizedSize : 0;
}
// 最大和最小限制
if (!isNil(maxColumnWidth) && maxColumnWidth >= 0) {
const normalizedMaxColumnWidth = maxColumnWidth / xDimensionLength;
if (normalizedSize > normalizedMaxColumnWidth) {
normalizedSize = normalizedMaxColumnWidth;
}
}
// minColumnWidth可能设置为0
if (!isNil(minColumnWidth) && minColumnWidth >= 0) {
const normalizedMinColumnWidth = minColumnWidth / xDimensionLength;
if (normalizedSize < normalizedMinColumnWidth) {
normalizedSize = normalizedMinColumnWidth;
}
}
return normalizedSize;
}