@antv/g2
Version:
the Grammar of Graphics in Javascript
155 lines (145 loc) • 4.16 kB
text/typescript
import { isArray, isNil } from '@antv/util';
import { IGroup, PathCommand } from '../../../dependents';
import { Point, ShapeInfo, ShapeMarkerCfg, ShapePoint } from '../../../interface';
import { registerShape } from '../base';
import { getStyle } from '../util/get-style';
function parseValue(value: number[]) {
const array = !isArray(value) ? [value] : value;
const min = array[0]; // 最小值
const max = array[array.length - 1]; // 最大值
const min1 = array.length > 1 ? array[1] : min;
const max1 = array.length > 3 ? array[3] : max;
const median = array.length > 2 ? array[2] : min1;
return {
min, // 最小值
max, // 最大值
min1,
max1,
median,
};
}
function getBoxPoints(x: number | number[], y: number | number[], size: number): Point[] {
const halfSize = size / 2;
let pointsArray;
if (isArray(y)) {
// 2维
const { min, max, median, min1, max1 } = parseValue(y);
const minX = (x as number) - halfSize;
const maxX = (x as number) + halfSize;
pointsArray = [
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
];
} else {
// 只有一个维度
y = isNil(y) ? 0.5 : y;
const { min, max, median, min1, max1 } = parseValue(x as number[]);
const minY = y - halfSize;
const maxY = y + halfSize;
pointsArray = [
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
];
}
return pointsArray.map((arr) => {
return {
x: arr[0],
y: arr[1],
};
});
}
function getBoxPath(points): PathCommand[] {
return [
['M', points[0].x, points[0].y],
['L', points[1].x, points[1].y],
['M', points[2].x, points[2].y],
['L', points[3].x, points[3].y],
['M', points[4].x, points[4].y],
['L', points[5].x, points[5].y],
['L', points[6].x, points[6].y],
['L', points[7].x, points[7].y],
['L', points[4].x, points[4].y], // 封闭 z
['Z'],
['M', points[8].x, points[8].y],
['L', points[9].x, points[9].y],
['M', points[10].x, points[10].y],
['L', points[11].x, points[11].y],
['M', points[12].x, points[12].y],
['L', points[13].x, points[13].y],
];
}
// box shape
registerShape('schema', 'box', {
getPoints(shapePoint: ShapePoint) {
const { x, y, size } = shapePoint;
return getBoxPoints(x as number, y as number[], size);
},
draw(cfg: ShapeInfo, container: IGroup) {
const style = getStyle(cfg, true, false);
const path = this.parsePath(getBoxPath(cfg.points));
const shape = container.addShape('path', {
attrs: {
...style,
path,
name: 'schema',
},
});
return shape;
},
getMarker(markerCfg: ShapeMarkerCfg) {
const { color } = markerCfg;
return {
symbol(x: number, y: number, r: number) {
const yValues = [y - 6, y - 3, y, y + 3, y + 6];
const points = getBoxPoints(x, yValues, r);
return [
['M', points[0].x + 1, points[0].y],
['L', points[1].x - 1, points[1].y],
['M', points[2].x, points[2].y],
['L', points[3].x, points[3].y],
['M', points[4].x, points[4].y],
['L', points[5].x, points[5].y],
['L', points[6].x, points[6].y],
['L', points[7].x, points[7].y],
['L', points[4].x, points[4].y],
['Z'],
['M', points[8].x, points[8].y],
['L', points[9].x, points[9].y],
['M', points[10].x + 1, points[10].y],
['L', points[11].x - 1, points[11].y],
['M', points[12].x, points[12].y],
['L', points[13].x, points[13].y],
];
},
style: {
r: 6,
lineWidth: 1,
stroke: color,
},
};
},
});